项目中遇到使用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. }