2013年3月17日

摘要: 写下这篇实践总结,一方面用于笔者存档备忘,另一方面也希望对读到此文的人有所启发。这里所说的问题一般指必现问题,即可以找到让问题必然出现的条件。对于非必现问题的处理,后面将简单讨论。一、RTFSC ---- 不明白?请 google不用说,这是老生长谈。通常大部分情况下用这种方式都可以快速找到导致问题的原因,前提是你要足够熟悉代码。 如果你刚接手出问题的代码,请硬着头皮把代码看下去 :-)二、查看输出的错误信息或中间调试信息通常嵌入式设备自带的调试定位手段相对缺乏,不比 PC,代码出了问题,可以很容易起调试器定位。这时就要靠运行的代码自身来帮忙了。比如,可以在函数的失败返回处输出错误信息(如文件 阅读全文
posted @ 2013-03-17 23:51 efzju 阅读(1019) 评论(0) 推荐(0) 编辑
 

2012年9月7日

摘要: 尾声上节中我们已经找到问题的罪魁祸首: ASN1 对 INTEGER 类型的编解码出现问题google 一下,查到一篇文件《ASN.1/BER/DER 编码子集入门指南》,其中关于 INTEGER 的部分,综述如下INTEGER 类型表示任意的整数。INTEGER 值可以为正数、负数或 0,具有任意大小,采用简单定长编码在 X.509 证书中 INTEGER 类型用于表示证书的版本号和序列号具体编码上,INTEGER 的内容 V 用补码表示(记得TLV格式吗),并使用最少的字节,例如数值 0 编码为一个字节: 0x00其完整的 ASN1 编码就是 02 01 00,共 3 个字节(TLV)在我 阅读全文
posted @ 2012-09-07 23:42 efzju 阅读(1960) 评论(2) 推荐(1) 编辑
 
摘要: 上节,我们利用函数运行树对错误进行了初步定位读者可能会问: VC 的调试功能很强大,为什么不利用单步跟踪来定位?这是因为,对现有代码单步跟踪时,函数帧栈会发生意想不到的变化乍一听很不可思议,那就让我们在函数 ASN1_item_ex_d2i 调用 asn1_template_ex_d2i 的地方(case ASN1_ITYPE_SEQUENCE 分支)下断点, F5 启动,程序在中断处的调用栈为> openssl-0.9.8e.exe!ASN1_item_ex_d2i openssl-0.9.8e.exe!ASN1_item_d2i openssl-0.9.8e.exe!d2i_X509 阅读全文
posted @ 2012-09-07 01:13 efzju 阅读(2062) 评论(0) 推荐(0) 编辑
 

2012年8月30日

摘要: 真相已经不远了。首先我们查看函数 d2i_X509, 前已述及,该函数将 ASN1 格式(DER 编码)的 X509 证书内容转换为内部数据格式(X509 结构),其定义如下X509 *d2i_X509(X509 **a, const unsigned char **in, long len) { return (X509 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, (X509_it()));}d2i_X509 在内部调用 ASN1_item_d2i(并传入一个 ASN1_ITEM 结构地址), 后者在内部调用函数 ASN1_item_ex_d2i(将 阅读全文
posted @ 2012-08-30 01:41 efzju 阅读(2497) 评论(0) 推荐(0) 编辑
 

2012年8月23日

摘要: 上节末尾,我们提到 d2i_X509 函数,该函数在证书验证过程中的一个调用栈是 d2i_X509 d2i_X509_AUX PEM_ASN1_read_bio PEM_read_bio_X509_AUX load_cert check这是上节中提到的证书验证步骤(1) -- 将证书内容转换为内部结构 -- 的必经之路,但是我们在原始代码中找不到 d2i_X509 的实现过程。事实上,包括它在内的一大群函数(最著名的是 d2i/i2d 系列)都在 OpenSSL 中找不到函数定义的源码,下面是双击函数调用栈中 d2i_X509 函数的截图上图告诉我们, d2i_X509 函数定义在宏 IMPL 阅读全文
posted @ 2012-08-23 08:22 efzju 阅读(4013) 评论(0) 推荐(0) 编辑
 

2012年8月15日

摘要: 本节中我们快速浏览一下证书验证的主干代码。读者可以采用上节中生成的VC工程进行验证。下面列出关键部分代码,为方便阅读,仅保留与证书验证强相关的代码,去掉了诸如变量定义、错误处理、资源释放等非主要代码,并修改了排版格式。View Code // 初始入口为 apps\verify.c 中的 MAIN 函数// 为利于代码阅读,下面尝试将相关代码放在一起(采用函数调用栈的形式,被调用函数的代码排版缩进一层),希望能讲得更为清楚int MAIN(int argc, char **argv){ X509_STORE *cert_ctx=NULL; X509_LOOKUP *lookup=N... 阅读全文
posted @ 2012-08-15 22:31 efzju 阅读(4466) 评论(1) 推荐(0) 编辑
 

2012年8月14日

摘要: 为了解OpenSSL完整的证书验证流程,从本节起我们不再进行逆向调试,而是顺着代码执行逻辑进行真正意义上的走读,并在过程中进行查看和问题定位。在这之前,我们先来解决前面章节中提到的问题:利用脚本(半自动)生成一个OpenSSL的VC工程。实现思路如下:1、想得到VC的工程文件.vcproj(*.sln文件中无关键内容)2、观察到.vcproj是XML(文本)格式3、观察到.vcproj中编译相关的部分<Files>...</Files>为目录结构4、联想到Perl强大的文本处理功能,考虑根据文件的编译参数(来自正常编译输出结果)构造出此目录结构下面以 Visual St 阅读全文
posted @ 2012-08-14 00:22 efzju 阅读(2017) 评论(0) 推荐(0) 编辑
 

2012年4月12日

摘要: 上次我们停在inl = ASN1_item_i2d(asn, &buf_in, it);调用处(注意是第2次中断),此时的调用栈为>openssl.exe!ASN1_item_verifyopenssl.exe!X509_verifyopenssl.exe!internal_verifyopenssl.exe!X509_verify_certopenssl.exe!checkopenssl.exe!verify_mainopenssl.exe!do_cmdopenssl.exe!main我们目标锁定在函数唯一的入参asn上,只有它才可能引起返回参数错误查看上一层函数栈,代码上下文 阅读全文
posted @ 2012-04-12 09:12 efzju 阅读(2660) 评论(0) 推荐(0) 编辑
 

2012年4月8日

摘要: 继续上节,我们追踪到函数ASN1_item_i2d调用处,并推测buf_in作为函数出参,是证书的tbsCertificate字段,而inl作为函数返回值,是tbsCertificate部分的长度。但是在查看buf_in内容时,却得到inl两次不同的值。这是为什么,难道两次查看的内容确实不同?索性就一探究竟,看下这次返回的buf_in吧,下面是buf_in的部分内存DUMP30 82 02 2b a0 03 02 01 02 02 09 00 9d a2 42 4a 0?.+?.......??BJa2 6a 51 de 30 0d 06 09 2a 86 48 86 f7 0d 01 01 阅读全文
posted @ 2012-04-08 13:55 efzju 阅读(2022) 评论(0) 推荐(0) 编辑
 

2012年3月15日

摘要: 本节我们开始查看OpenSSL代码,我们的目标仅限于找出证书验证失败的原因而不是把整套代码完全弄懂或精读,故采用走读代码的方式。所用的版本是OpenSSL 0.9.8e从哪里下手呢?就从其输出的错误信息开始吧。5840:error:04077068:rsa routines:RSA_verify:bad signature:.\crypto\rsa\rsa_sign.c:235打开VC工程,在rsa_sign.c文件的235行处下断点,并设置好命令参数和工作目录,按F5,程序中断View Code 1 int RSA_verify(int dtype, const unsigned cha.. 阅读全文
posted @ 2012-03-15 09:10 efzju 阅读(4458) 评论(0) 推荐(0) 编辑