小型CA系统
作者:王雪松 下载本文示例源代码
前些天在网上看到了一些关于OPENSSL的介绍,觉得很有意思,于是做了一个程序,基本实现了数字证书的制作、SSL安全通讯、加解密操作等功能,秉承OPENSSL开放的原则,拿出来共享,主要实现写在了两个DLL中。水平有限,请勿见笑。 首先感谢中国OPENSSL论坛(http://www.openssl.cn/)的几位斑竹,感谢他们的辛勤劳动和默默付出。 程序是在一个电子钥匙管理程序的基础上作的,原来电子钥匙的部分还保留着,需要电子钥匙的支持。 代码较多,笔者只介绍认为重要的三点。
程序要点: (1)RA客户端与服务器程序采用了ACCESS数据库,SSL连接、非阻塞套接字,基本原理是客户端发送命令请求,服务器查询数据库,然后查询结果发给客户端。非阻塞套接字是很灵活的,运用不当会事倍功半,这个程序而言:AsyncSelect函数是个关键。 林军鼐的Winsock编程宝典中这样写道: 【FD_WRITE 事件】 系统会通知我们 FD_WRITE 事件的讯息,只有下列几种情况: (1)呼叫 WSAAsyncSelect() 来设定 FD_WRITE 事件时,Socket 已经可以传送资料(TCP scoket 已经和对方连接成功了,或 UDP socket 已建立完成),且目前 output buffer 仍有空间可写入资料。 (2)呼叫 WSAAsyncSelect() 来设定 FD_WRITE 事件时,Socket 尚不能传送资料,不过一旦 Socket 与对方连接成功,马上就会收到 FD_WRITE 的通知。 (3)呼叫 send() 或 sendto() 传送资料时,系统告知错误,且错误码为10035 WSAEWOULDBLOCK (呼叫 WSAGetLastError() 得知这项错误),这时表示 output buffer 已经满了,无法再写入任何资料(此时即令呼叫再多次的 send() 也都一定失败);一旦系统将部份资料成功送抵对方,空出 output buffer 後,便会送一个 FD_WRITE 给使用者,告知可继续传送资料了。换句话说,读者在呼叫 send() 传送资料时,只要不是返回错误 10035 的话,便可一直继续呼叫 send() 来传送资料;一旦 send() 回返错误 10035,那麽便不要再呼叫 send() 传送资料,而须等收到 FD_WRITE 後,再继续传送资料。 【FD_READ 事件】 我们会收到 FD_READ 事件通知我们去读取资料的情况有 : (1)呼叫 WSAAsyncSelect 函式来对此 Socket 设定 FD_READ 事件时,input buffer 中已有资料。 (2)原先系统的 input buffer 是空的,当系统再收到资料时,会通知我们。 (3)使用者呼叫 recv 或 recvfrom 函式,从 input buffer 读取资料,但是并没有一次将资料读光,此时会再驱动一个 FD_READ 事件,表示仍有资料在 input buffer 中。 读者必须注意:如果我们收到 FD_READ 事件通知的讯息,但是我们故意不呼叫 recv 或 recvfrom 来读取资料的话,尔後系统又收到资料时,并不会再次通知我们,一定要等我们呼叫了 recv 或 recvfrom 後,才有可能再收到FD_READ 的事件通知。(林军鼐) (2)因为有些基本操作写在动态库中,动态库中长时间操作(加解密)的进展情况,应该在主程序中体现出来,这样比较友好。本程序采用了回调函数机制解决这个问题。
static void DrawProg(int i); void CUsbEvpPage::DrawProg(int i) { ((CUsbEvpPage *)((CPropertySheet *)AfxGetMainWnd())->GetPage(8))-> m_Progress.SetPos(i);//没有引入this,因为这个函数在动态库中调用。 }
动态库在一定条件下调用了这个函数,指示了操作的进度。
(3)程序做完了,如果用一些诸如SMARTCHK的工具检查一下,说不定会有收获。 程序BUG: 1、 不能再同一个程序中用SSL客户端连接SSL服务器,否则…… 2、 由于对OPENSSL掌握的有限,部分代码存在内存泄漏。 3、 SSL客户端连接SSL服务器,显示乱码是因为没有处理半个汉字;如果用IE连接就没有这个问题。 因为程序代码较多,不再一一介绍,具体实现请参看源代码。代码中存在的错误请指出,以便在下一个版本中修正。 一些头文件和lib采用了绝对路径,需要重新配置。 CA和EVP动态库的源代码问题还很多,因此没有发布,待完善了再拿出来献丑。 关于数字证书和SSL的应用,可以在网络上找一些介绍,这里不再赘述。 程序在win2000 + vc6+ACCESS2000下面测试过。如有问题与我联系。