项目中遇到使用Openssl验证证书链的问题,在网上找了很长时间,发现这方面的资料很少,通过多方努力,总算实现了基本功能,为了给大家提供一下参考,本人实现了一个验证证书链的类,以供参考,由于本人也是刚刚接触Openssl,如果有不正确的地方,请大家多多指导

1. /************************************************************************/  
2. /*                          VerifyDCChain.h                             */  
3. /************************************************************************/  
4. #ifndef VERIFYDCCHAIN_H_  
5. #define VERIFYDCCHAIN_H_  
6.   
7. #include <openssl/bio.h>  
8. #include <openssl/err.h>  
9. #include <openssl/x509.h>  
10. #include <openssl/x509v3.h>  
11. #include <openssl/pem.h>  
12. #include <openssl/crypto.h>  
13. #include <string>  
14. #include <iostream>  
15. using namespace std;  
16.   
17. class VerifyDCChain  
18. {  
19. public:  
20.     VerifyDCChain();  
21.     ~VerifyDCChain();  
22.   
23. /* 
24.     * 初始化证书链堆栈m_chain 
25.     * @param[in] certChains 证书链中各个证书文件名数组 
26.     * @param[in] num 证书链中证书个数 
27.     */  
28. int Init(const string* certChains, const int num);  
29.   
30. /* 
31.     * 使用给定的证书链验证叶子证书 
32.     * @param[in] certFile 需要验证的叶子证书文件名 
33.     */  
34. int verify(const char* certFile);  
35. private:  
36.   
37. /* 
38.     * 加载证书文件 
39.     * @param[in] certFile 需要加载的证书文件名 
40.     */  
41. const char* certFile);  
42. private:  
43.     X509* m_leaf;  
44.     STACK_OF(X509)* m_chain;      
45. };  
46.   
47. #endif  
48.   
49. /************************************************************************/  
50. /*                          VerifyDCChain.cpp                           */  
51. /************************************************************************/  
52.   
53. #include "VerifyDCChain.h"  
54.   
55. VerifyDCChain::VerifyDCChain():m_leaf(NULL), m_chain(NULL)  
56. {  
57.     CRYPTO_malloc_init();   
58.     OpenSSL_add_all_algorithms();  
59. }  
60.   
61. VerifyDCChain::~VerifyDCChain()  
62. {  
63. if(m_leaf != NULL)   
64.     {  
65.         X509_free(m_leaf);  
66.     }  
67. if (m_chain !=NULL)  
68.     {  
69.         sk_X509_free(m_chain);  
70.     }  
71. }  
72.   
73. int VerifyDCChain::Init(const string* certChains, const int num)  
74. {  
75. int ret = 0;  
76. new X509;  
77.     m_chain = sk_X509_new_null();  
78.   
79. // 注意此处加载证书链中证书的顺序没有要求,因为  
80. // 在X509_verify_cert()函数中会对证书链中的证书  
81. // 进行排序  
82. for (int i = 0; i < num; i++)  
83.     {  
84.         temp = load_certfile(certChains[i].c_str());  
85.         sk_X509_push(m_chain, temp);  
86.     }  
87. return 1;  
88. }  
89.   
90. int VerifyDCChain::verify(const char* certFile)  
91. {  
92. int ret = 0;  
93.     X509_STORE *store=NULL;  
94.     X509_STORE_CTX ctx;  
95. new X509();  
96.   
97. //创建X509_store对象,用来存储证书、撤销列表等  
98.     store=X509_STORE_new();  
99.   
100. // 载入叶子证书  
101.     m_leaf = load_certfile(certFile);  
102.   
103. //设置验证标记 都验证那些项 X509_V_FLAG_CRL_CHECK_ALL表示全部验证  
104.     X509_STORE_set_flags(store,X509_V_FLAG_CRL_CHECK_ALL);  
105. //初始化CTX 这个类就是所谓的上下文 该类收集完必要的信息数据 可以进行验证  
106. // 此处X509_STORE_CTX_init最后一个参数为NULL,表示不加载证书撤销列表CPL  
107. if(!X509_STORE_CTX_init(&ctx,store ,m_leaf,NULL))  
108.     {  
109.         ret = 0;  
110. goto end;  
111.     }  
112.   
113. if(m_chain == NULL)  
114.     {  
115. "加载证书链失败!\n"<<endl;  
116.         ret = 0;  
117. goto end;  
118.     }  
119. else  
120.     {  
121. //将证书链存入CTX  
122.         X509_STORE_CTX_trusted_stack(&ctx, m_chain);  
123.     }  
124.   
125. //证书链式验证  
126. if(1 == X509_verify_cert(&ctx))  
127.         ret = 1;  
128. else  
129.         ret = 0;  
130. end:  
131.     X509_STORE_CTX_cleanup(&ctx);  
132. if(store)X509_STORE_free(store);  
133. return ret;  
134. }  
135.   
136. X509* VerifyDCChain::load_certfile(const char* certFile)  
137. {  
138.     X509* cert = NULL;  
139.     BIO* in = NULL;  
140.   
141. if(certFile==NULL)  
142. goto end;  
143. "r");  
144. if(in==NULL)  
145. goto end;  
146. //将IO中数据以PEM格式读入到X509对象  
147.     cert = PEM_read_bio_X509(in,NULL,NULL,NULL);  
148. if(cert == NULL)  
149. goto end;  
150. end:  
151. if(in)BIO_free(in);  
152. return cert;  
153. }  
154.   
155. /************************************************************************/  
156. /*                                 test.cpp                             */  
157. /************************************************************************/  
158.   
159. #include "VerifyDCChain.h"  
160. #include <iostream>  
161. using namespace std;  
162.   
163. void main(void)  
164. {  
165.     VerifyDCChain m_check;  
166.   
167. // 注意此处加载证书链中证书文件名的顺序没有要求,  
168. // 因为在X509_verify_cert()函数中会对证书链中的  
169. // 证书进行排序  
170. "5.crt", "4.crt", "3.crt", "2.crt"};  
171.     m_check.Init(certChains, 4);  
172.   
173. if (1 == m_check.verify("1.crt"))  
174.     {  
175. "OK!"<<endl;  
176.     }  
177. else  
178.     {  
179. "ERROR!"<<endl;  
180.     }     
181. }