OpenSSL_Certificate 证书解析API初探

下载编译安装OpenSSL

下载

  1. 访问 https://ftp.openssl.org/source/
    OpenSSL 官方下载

编译:

为了方便 GDB 调试, 使用-g 添加符号信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[root@localhost openssl_build]# ../config --debug  no-shared --prefix=/opt/openssl && make && make install


看一看 编译完成后, 都生成了些什么
[root@localhost code]# ll /opt/openssl/bin/
-rwxr-xr-x. 1 root root 6191 Dec 11 19:35 c_rehash
-rwxr-xr-x. 1 root root 3896184 Dec 11 19:35 openssl

[root@localhost code]# ls /opt/openssl/include/openssl/
aes.h bio.h cmac.h cryptoerr.h dsa.h engine.h kdf.h objects.h pemerr.h rand.h seed.h stack.h uierr.h
asn1err.h blowfish.h cmserr.h crypto.h dtls1.h e_os2.h lhash.h obj_mac.h pem.h rc2.h sha.h storeerr.h ui.h
asn1.h bnerr.h cms.h cterr.h ebcdic.h err.h md2.h ocsperr.h pkcs12err.h rc4.h srp.h store.h whrlpool.h
asn1_mac.h bn.h comperr.h ct.h ecdh.h evperr.h md4.h ocsp.h pkcs12.h rc5.h srtp.h symhacks.h x509err.h
asn1t.h buffererr.h comp.h des.h ecdsa.h evp.h md5.h opensslconf.h pkcs7err.h ripemd.h ssl2.h tls1.h x509.h
asyncerr.h buffer.h conf_api.h dherr.h ecerr.h hmac.h mdc2.h opensslv.h pkcs7.h rsaerr.h ssl3.h tserr.h x509v3err.h
async.h camellia.h conferr.h dh.h ec.h idea.h modes.h ossl_typ.h rand_drbg.h rsa.h sslerr.h ts.h x509v3.h
bioerr.h cast.h conf.h dsaerr.h engineerr.h kdferr.h objectserr.h pem2.h randerr.h safestack.h ssl.h txt_db.h x509_vfy.h

[root@localhost code]# ll /opt/openssl/lib/
total 6496
drwxr-xr-x. 2 root root 6 Dec 11 19:35 engines-1.1
-rw-r--r--. 1 root root 5626786 Dec 11 19:35 libcrypto.a
-rw-r--r--. 1 root root 1022208 Dec 11 19:35 libssl.a
drwxr-xr-x. 2 root root 61 Dec 11 19:35 pkgconfig
[root@localhost code]#

获取 X509 证书 示例

  1. 首先打开 Wireshark, 监听连接互联网的网卡
  2. 然后访问任何一个SSL的网站

  3. 输入Wireshark过滤类型, 在这里只关心Certificate报文

  4. 保存Certificate

  5. 使用Windows查看证书信息

使用OpenSSL 查看证书 示例

查看ECC类型公钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
[root@localhost openssl_devel_lib]# ./openssl.orogin x509 -in certificate/1.1.cer -inform DER -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 5418637886287414121 (0x4b32de72caa28369)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = Google Trust Services, CN = Google Internet Authority G3
Validity
Not Before: Jun 19 11:33:36 2018 GMT
Not After : Aug 28 11:31:00 2018 GMT
Subject: C = US, ST = California, L = Mountain View, O = Google LLC, CN = *.googleapis.com
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:14:3f:0d:43:6e:a6:db:5e:74:9b:b1:15:36:89:
85:c9:2e:e7:97:44:85:f1:4b:ca:bb:07:e1:cb:b5:
d9:b1:d6:b4:97:49:6f:1b:18:b2:e9:d0:d0:78:d8:
6c:f2:d6:d2:ca:e2:c5:0f:66:4f:f1:3c:7d:96:ae:
8e:38:8c:15:ff
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Key Usage: critical
Digital Signature
X509v3 Subject Alternative Name:
DNS:*.googleapis.com, DNS:*.clients6.google.com, DNS:*.cloudendpointsapis.com, DNS:cloudendpointsapis.com, DNS:googleapis.com
Authority Information Access:
CA Issuers - URI:http://pki.goog/gsr2/GTSGIAG3.crt
OCSP - URI:http://ocsp.pki.goog/GTSGIAG3

X509v3 Subject Key Identifier:
07:BA:20:2D:80:B9:04:AD:68:5A:2D:7E:22:6F:40:CA:00:6C:BF:CD
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Authority Key Identifier:
keyid:77:C2:B8:50:9A:67:76:76:B1:2D:C2:86:D0:83:A0:7E:A6:7E:BA:4B

X509v3 Certificate Policies:
Policy: 1.3.6.1.4.1.11129.2.5.3
Policy: 2.23.140.1.2.2

X509v3 CRL Distribution Points:

Full Name:
URI:http://crl.pki.goog/GTSGIAG3.crl

Signature Algorithm: sha256WithRSAEncryption
4a:9c:07:4c:15:53:0e:e6:dd:77:28:91:c9:73:b9:5b:32:e3:
2d:24:79:07:13:17:4f:5d:44:22:4b:82:01:46:bf:52:93:b0:
3c:2c:fa:7c:96:16:e9:52:14:09:66:3e:02:3a:6a:07:85:7e:
23:ba:03:86:d6:0d:82:59:8a:c0:24:d3:ef:6b:3b:ed:3f:fc:
29:96:ac:af:1b:0b:f2:61:19:c7:5b:6a:72:e1:36:cb:f5:7a:
78:5a:e7:df:10:72:de:98:d3:e4:f0:69:fe:fc:38:7c:f5:cc:
98:ab:3e:86:ec:f7:fc:8e:b1:4a:b6:80:66:81:48:a7:67:f9:
e3:a9:dc:35:a4:37:99:29:d7:db:0b:f1:80:27:2d:46:39:3f:
c7:e1:95:e1:9c:62:98:ad:24:fe:8c:0d:6e:3c:c3:b3:e0:48:
ad:d2:37:61:ba:40:84:ee:50:cc:0c:ec:10:2a:cd:9d:8b:52:
f6:4c:77:d9:6a:e3:46:b5:91:0a:f0:84:f5:7a:a7:89:e8:07:
ff:d3:66:6b:e2:60:18:d8:c2:40:1b:c7:69:46:0c:03:be:1d:
96:43:c9:8f:74:b6:59:9c:60:83:ec:74:78:39:a8:4b:6e:de:
0b:ff:2b:fa:fb:e9:51:52:29:48:24:94:01:c2:20:81:23:6c:
d8:b2:5a:4d
-----BEGIN CERTIFICATE-----
MIIEJDCCAwygAwIBAgIISzLecsqig2kwDQYJKoZIhvcNAQELBQAwVDELMAkGA1UE
BhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczElMCMGA1UEAxMc
R29vZ2xlIEludGVybmV0IEF1dGhvcml0eSBHMzAeFw0xODA2MTkxMTMzMzZaFw0x
ODA4MjgxMTMxMDBaMGoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKDApHb29nbGUgTExDMRkw
FwYDVQQDDBAqLmdvb2dsZWFwaXMuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD
QgAEFD8NQ26m2150m7EVNomFyS7nl0SF8UvKuwfhy7XZsda0l0lvGxiy6dDQeNhs
8tbSyuLFD2ZP8Tx9lq6OOIwV/6OCAa0wggGpMBMGA1UdJQQMMAoGCCsGAQUFBwMB
MA4GA1UdDwEB/wQEAwIHgDB0BgNVHREEbTBrghAqLmdvb2dsZWFwaXMuY29tghUq
LmNsaWVudHM2Lmdvb2dsZS5jb22CGCouY2xvdWRlbmRwb2ludHNhcGlzLmNvbYIW
Y2xvdWRlbmRwb2ludHNhcGlzLmNvbYIOZ29vZ2xlYXBpcy5jb20waAYIKwYBBQUH
AQEEXDBaMC0GCCsGAQUFBzAChiFodHRwOi8vcGtpLmdvb2cvZ3NyMi9HVFNHSUFH
My5jcnQwKQYIKwYBBQUHMAGGHWh0dHA6Ly9vY3NwLnBraS5nb29nL0dUU0dJQUcz
MB0GA1UdDgQWBBQHuiAtgLkErWhaLX4ib0DKAGy/zTAMBgNVHRMBAf8EAjAAMB8G
A1UdIwQYMBaAFHfCuFCaZ3Z2sS3ChtCDoH6mfrpLMCEGA1UdIAQaMBgwDAYKKwYB
BAHWeQIFAzAIBgZngQwBAgIwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovL2NybC5w
a2kuZ29vZy9HVFNHSUFHMy5jcmwwDQYJKoZIhvcNAQELBQADggEBAEqcB0wVUw7m
3XcokclzuVsy4y0keQcTF09dRCJLggFGv1KTsDws+nyWFulSFAlmPgI6ageFfiO6
A4bWDYJZisAk0+9rO+0//CmWrK8bC/JhGcdbanLhNsv1enha598Qct6Y0+Twaf78
OHz1zJirPobs9/yOsUq2gGaBSKdn+eOp3DWkN5kp19sL8YAnLUY5P8fhleGcYpit
JP6MDW48w7PgSK3SN2G6QITuUMwM7BAqzZ2LUvZMd9lq40a1kQrwhPV6p4noB//T
ZmviYBjYwkAbx2lGDAO+HZZDyY90tlmcYIPsdHg5qEtu3gv/K/r76VFSKUgklAHC
IIEjbNiyWk0=
-----END CERTIFICATE-----
[root@localhost openssl_devel_lib]#

查看 RSA 类型公钥证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

[root@localhost openssl_devel_lib]# ./openssl.orogin x509 -in certificate/2.1.cer -inform DER -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 6893292185868816116 (0x5fa9e4b887afcef4)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = Google Trust Services, CN = Google Internet Authority G3
Validity
Not Before: Jun 19 11:32:59 2018 GMT
Not After : Aug 28 11:31:00 2018 GMT
Subject: C = US, ST = California, L = Mountain View, O = Google LLC, CN = accounts.google.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:a1:15:c2:34:2f:c4:8f:a4:84:25:a6:e0:20:24:
e0:aa:f0:ac:42:3c:34:79:4a:82:95:33:b7:81:7a:
4b:63:7f:09:a9:a5:a6:0e:ab:13:f4:fd:f6:de:83:
65:b0:f9:07:1e:39:9d:c3:52:2a:84:b1:5d:61:76:
47:50:74:9d:da:19:69:00:8f:d6:33:02:11:44:ee:
00:3c:26:cd:25:ec:5c:46:0c:6a:b5:c5:a0:01:13:
59:8b:da:88:85:bc:15:f7:f1:61:a6:f9:9e:ec:a2:
55:22:3b:09:9c:68:d3:3f:ad:6e:99:f7:0e:28:10:
15:72:c1:a5:63:df:cb:0c:7c:ba:61:11:0e:4d:eb:
29:9c:0f:3d:a1:17:5e:aa:ec:89:de:f2:ef:99:87:
24:b9:d4:d4:bf:a3:2c:83:f2:77:73:f5:47:8b:36:
bf:6b:7f:ee:8c:9d:aa:6a:07:cd:e5:89:3b:2e:0c:
6e:af:62:05:a7:86:e2:3e:d9:f9:a2:ad:ca:56:f1:
d1:43:e3:c8:5c:d0:58:94:91:4a:55:20:13:89:b5:
f6:e4:20:4e:9c:77:17:28:e2:45:a5:f8:b4:db:8d:
0b:bf:41:60:82:99:df:af:16:ad:da:e5:84:de:7c:
39:15:65:ea:23:43:6d:ec:25:41:53:41:8a:d1:42:
4f:7b
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:accounts.google.com, DNS:*.accounts.goog, DNS:*.partner.android.com
Authority Information Access:
CA Issuers - URI:http://pki.goog/gsr2/GTSGIAG3.crt
OCSP - URI:http://ocsp.pki.goog/GTSGIAG3

X509v3 Subject Key Identifier:
0F:26:83:EE:15:EB:77:16:E5:03:02:7A:5D:B8:1F:7C:01:06:60:BD
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Authority Key Identifier:
keyid:77:C2:B8:50:9A:67:76:76:B1:2D:C2:86:D0:83:A0:7E:A6:7E:BA:4B

X509v3 Certificate Policies:
Policy: 1.3.6.1.4.1.11129.2.5.3
Policy: 2.23.140.1.2.2

X509v3 CRL Distribution Points:

Full Name:
URI:http://crl.pki.goog/GTSGIAG3.crl

Signature Algorithm: sha256WithRSAEncryption
3b:03:e9:96:60:d9:67:54:7c:a2:bd:63:d8:54:f4:22:63:25:
35:ea:31:79:78:05:5a:87:a8:1a:a0:f7:55:19:3a:57:a4:4b:
0e:18:30:9b:51:fa:c8:5e:7b:7e:75:17:07:fa:16:d2:ce:f5:
c1:15:a4:fc:3a:eb:75:85:47:69:db:45:4b:f4:cd:ce:8b:32:
ff:e6:fc:aa:fc:61:ac:3d:4e:71:82:93:8a:d4:da:32:b4:cc:
be:60:f4:1c:40:89:0d:7e:83:7d:93:ff:5e:b6:0b:cd:b2:32:
33:65:30:a3:51:41:34:9e:4b:3b:29:16:28:ce:31:d8:b8:10:
ca:5c:7f:af:18:34:22:aa:7b:66:cb:00:84:d8:2c:85:83:e6:
75:e5:af:7d:0c:7a:78:df:43:48:ab:70:43:73:bf:87:0d:9a:
21:cd:48:c9:5e:20:a1:40:67:70:07:40:1b:67:29:5b:ee:34:
ab:8c:1c:73:01:e7:19:42:c7:12:7a:92:69:9d:7e:bc:f6:48:
cd:37:b0:19:38:e3:94:b5:a8:c3:9b:e3:82:03:f7:92:ab:4b:
54:2e:5a:3d:7b:ec:e8:93:b1:53:2d:f2:1c:bf:6c:1f:aa:c4:
95:10:e8:df:b0:29:f0:8e:69:9b:02:1b:15:29:51:04:71:f4:
b6:df:fc:94
-----BEGIN CERTIFICATE-----
MIIEtDCCA5ygAwIBAgIIX6nkuIevzvQwDQYJKoZIhvcNAQELBQAwVDELMAkGA1UE
BhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczElMCMGA1UEAxMc
R29vZ2xlIEludGVybmV0IEF1dGhvcml0eSBHMzAeFw0xODA2MTkxMTMyNTlaFw0x
ODA4MjgxMTMxMDBaMG0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh
MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKDApHb29nbGUgTExDMRww
GgYDVQQDDBNhY2NvdW50cy5nb29nbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEAoRXCNC/Ej6SEJabgICTgqvCsQjw0eUqClTO3gXpLY38JqaWm
DqsT9P323oNlsPkHHjmdw1IqhLFdYXZHUHSd2hlpAI/WMwIRRO4APCbNJexcRgxq
tcWgARNZi9qIhbwV9/Fhpvme7KJVIjsJnGjTP61umfcOKBAVcsGlY9/LDHy6YREO
TespnA89oRdequyJ3vLvmYckudTUv6Msg/J3c/VHiza/a3/ujJ2qagfN5Yk7Lgxu
r2IFp4biPtn5oq3KVvHRQ+PIXNBYlJFKVSATibX25CBOnHcXKOJFpfi0240Lv0Fg
gpnfrxat2uWE3nw5FWXqI0Nt7CVBU0GK0UJPewIDAQABo4IBbzCCAWswEwYDVR0l
BAwwCgYIKwYBBQUHAwEwRgYDVR0RBD8wPYITYWNjb3VudHMuZ29vZ2xlLmNvbYIP
Ki5hY2NvdW50cy5nb29nghUqLnBhcnRuZXIuYW5kcm9pZC5jb20waAYIKwYBBQUH
AQEEXDBaMC0GCCsGAQUFBzAChiFodHRwOi8vcGtpLmdvb2cvZ3NyMi9HVFNHSUFH
My5jcnQwKQYIKwYBBQUHMAGGHWh0dHA6Ly9vY3NwLnBraS5nb29nL0dUU0dJQUcz
MB0GA1UdDgQWBBQPJoPuFet3FuUDAnpduB98AQZgvTAMBgNVHRMBAf8EAjAAMB8G
A1UdIwQYMBaAFHfCuFCaZ3Z2sS3ChtCDoH6mfrpLMCEGA1UdIAQaMBgwDAYKKwYB
BAHWeQIFAzAIBgZngQwBAgIwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovL2NybC5w
a2kuZ29vZy9HVFNHSUFHMy5jcmwwDQYJKoZIhvcNAQELBQADggEBADsD6ZZg2WdU
fKK9Y9hU9CJjJTXqMXl4BVqHqBqg91UZOlekSw4YMJtR+shee351Fwf6FtLO9cEV
pPw663WFR2nbRUv0zc6LMv/m/Kr8Yaw9TnGCk4rU2jK0zL5g9BxAiQ1+g32T/162
C82yMjNlMKNRQTSeSzspFijOMdi4EMpcf68YNCKqe2bLAITYLIWD5nXlr30Menjf
Q0ircENzv4cNmiHNSMleIKFAZ3AHQBtnKVvuNKuMHHMB5xlCxxJ6kmmdfrz2SM03
sBk445S1qMOb44ID95KrS1QuWj177OiTsVMt8hy/bB+qxJUQ6N+wKfCOaZsCGxUp
UQRx9Lbf/JQ=
-----END CERTIFICATE-----
[root@localhost openssl_devel_lib]#

OpenSSL C API 解析证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
// 本示例采用 openssl-1.1.1a 版本 [2018.12.12 最新版]
// OpenSSL 版本不同API接口会有变动, 使用时请注意库的版本

#include <string.h>

#include <openssl/x509v3.h>

int X509V3_EXT_info_access(const X509V3_EXT_METHOD *method, void *ext_str)
{
printf("精细的数据: NID_info_access\n");
AUTHORITY_INFO_ACCESS *ainfo = ext_str;
STACK_OF(CONF_VALUE) *result = NULL;

/** 将数据全部存入 CONF_VALUE **/
for (int i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++)
{
ACCESS_DESCRIPTION *desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
result = i2v_GENERAL_NAME((X509V3_EXT_METHOD *)method, desc->location, result);
}
if (result == NULL)
{
printf("ERROR: [%s][%s][%d]\n", __FILE__, __func__, __LINE__);
return -1;
}

/** 打印数据 **/
for (int i = 0; i < sk_CONF_VALUE_num(result); i++)
{
CONF_VALUE *nval = sk_CONF_VALUE_value(result, i);
if (NULL != nval && NULL != nval->name && NULL != nval->value)
{
printf("Name=[%s], Value=[%s]\n", nval->name, nval->value);
}
}
sk_CONF_VALUE_pop_free(result, X509V3_conf_free);
return 0;
}


int X509V3_EXT_subject_alt_name(const X509V3_EXT_METHOD *method, void *ext_str)
{
int i;
GENERAL_NAMES *gens = ext_str;
STACK_OF(CONF_VALUE) *result = NULL;

/** 将数据全部存入 CONF_VALUE **/
for (i = 0; i < sk_GENERAL_NAME_num(gens); i++)
{
GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i);
result = i2v_GENERAL_NAME((X509V3_EXT_METHOD *)method, gen, result);
}

if(NULL == result)
{
printf("ERROR: [%s][%s][%d]\n", __FILE__, __func__, __LINE__);
return -1;
}

/** 打印数据 **/
printf("精细的数据: NID_subject_alt_name\n");
for (i = 0; i < sk_CONF_VALUE_num(result); i++)
{
CONF_VALUE *nval = sk_CONF_VALUE_value(result, i);
if (NULL != nval && NULL != nval->name && NULL != nval->value)
{
printf("Name=[%s], Value=[%s]\n", nval->name, nval->value);
}
}

sk_CONF_VALUE_pop_free(result, X509V3_conf_free);
return 0;
}


int X509V3_EXT_detial_print(int nid, X509_EXTENSION *x509_ext)
{
/** 专项 细致化 处理 **/
ASN1_OCTET_STRING *extoct = X509_EXTENSION_get_data(x509_ext);
const unsigned char *p = ASN1_STRING_get0_data(extoct);
int extlen = ASN1_STRING_length(extoct);
const X509V3_EXT_METHOD *method = method = X509V3_EXT_get(x509_ext);
void *ext_str = ASN1_item_d2i(NULL, &p, extlen, ASN1_ITEM_ptr(method->it));
if(NULL == method || NULL == ext_str)
{
printf("ERROR: [%s][%s][%d]\n", __FILE__, __func__, __LINE__);
return -1;
}

switch(nid)
{
case NID_subject_alt_name:
X509V3_EXT_subject_alt_name(method, ext_str);
break;

case NID_info_access:
X509V3_EXT_info_access(method, ext_str);
break;
}
ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it));
return 0;
}




void GET_X509_EXTENSION(X509 *x509)
{
int loop = X509_get_ext_count(x509);
printf("X509 证书扩展项个数 [%d]\n", loop);
for(int i = 0; i < loop; i++)
{
X509_EXTENSION *x509_ext = X509_get_ext(x509, i);
if(NULL == x509_ext)
{
printf("FAIL: X509_get_ext \n");
exit(-1);
}

ASN1_OBJECT *obj = X509_EXTENSION_get_object(x509_ext);

BIO *ext_bio = BIO_new(BIO_s_mem());
X509V3_EXT_print(ext_bio, x509_ext, 0, 0);

BUF_MEM *bptr = NULL;
BIO_get_mem_ptr(ext_bio, &bptr);


unsigned nid = OBJ_obj2nid(obj);
if (nid == NID_undef)
{
printf("UnKnown nid[%d]\n", nid);
return;
}
ASN1_OBJECT_free(obj);
printf("[%02d] nid=[%04d] TYPE=[%s]\n", i, nid, OBJ_nid2ln(nid));

{
/** 全部处理 **/
printf(" ");
char buf[4096];
memset(buf, 0, 4096);
memcpy(buf, bptr->data, bptr->length);
printf("len=[%zu], value=[%s]\n", bptr->length, buf);
}
BIO_free(ext_bio);
X509V3_EXT_detial_print(nid, x509_ext);
printf("\n");

}
}

int X509_Public_Print(X509 *x509)
{
EVP_PKEY *pkey = X509_get0_pubkey(x509);
if(NULL == pkey)
{
printf("FAIL X509_get0_pubkey\n");
exit(1);
}

// 7.1 获取公钥的加密算法
char Algorithm[80] = {0};
int Len_Algorithm = sizeof(Algorithm);
ASN1_OBJECT *xpoid;
X509_PUBKEY *xpkey = X509_get_X509_PUBKEY(x509);
X509_PUBKEY_get0_param(&xpoid, NULL, NULL, NULL, xpkey);
Len_Algorithm = i2t_ASN1_OBJECT(Algorithm, Len_Algorithm, xpoid);
printf("公钥算法:[%s]\n", Algorithm);

// 7.2 判断证书的类型 DSA/RSA/ECC
int keyid = EVP_PKEY_id(pkey);
printf("证书类型:%d\n", keyid);
if (keyid == EVP_PKEY_EC)
{
struct ec_key_st *eckey = EVP_PKEY_get0_EC_KEY(pkey);
if(NULL == eckey)
{
printf("ERROR EVP_PKEY_get0_EC_KEY\n");
exit(1);
}

const EC_GROUP *group = EC_KEY_get0_group(eckey);
printf("加密级别:%d bit\n", EC_GROUP_order_bits(group));

size_t publen = 0;
unsigned char *pub = NULL;
publen = EC_KEY_key2buf(eckey, EC_KEY_get_conv_form(eckey), &pub, NULL);
if (publen == 0)
{
printf("ERROR: EC_KEY_key2buf\n");
}
printf("公钥长度=[%zd]\n", publen);
for(int i=0; i<publen; i++)
{
printf("%02X ", pub[i]);
if(i%8 == 7)
printf(" ");
if(i%32 == 31)
printf("\n");
}
printf("\n");
OPENSSL_free(pub);
}
else if(keyid == NID_rsaEncryption)
{
const RSA *rsa = EVP_PKEY_get0_RSA(pkey);
if (rsa != NULL)
printf("加密级别:%d bit \n", BN_num_bits(RSA_get0_n(rsa)));

int buflen = BN_num_bytes(RSA_get0_n(rsa)) + 1;
printf("RSA公钥长度:%d Byte\n", buflen);
unsigned char *buf = OPENSSL_malloc(buflen);
if (buf == NULL)
{
printf("ERROR: OPENSSL_malloc\n");
return -1;
}

buf[0]=0;
buflen = BN_bn2bin(RSA_get0_n(rsa), buf+1);
if (buf[1] & 0x80)
buflen++;

printf("len=%d\n", buflen);

/** 打印公钥 **/
for(int i=0; i<buflen; i++)
{
printf("%02X ", (unsigned char)buf[i]);
if(i%8==7)
printf(" ");
if(i%32==31)
printf("\n");
}
printf("\n");
OPENSSL_free(buf);
}
EVP_PKEY_free(pkey);

return 0;
}

int main (int num, char**list)
{
if(num <2)
{
printf("need a DER file\n");
exit(-1);
}
printf("File name %s\n", list[1]);


BIO *bio_file = BIO_new_file(list[1], "rb");
if(NULL == bio_file)
{
printf("FAIL: BIO_new_file \n");
exit(-1);
}

X509 *x509 = d2i_X509_bio(bio_file, NULL);
if(NULL == x509)
{
printf("FAIL: d2i_X509_bio \n");
exit(-1);
}

/** 1 Version **/
printf("1. Certificate Version=[%ld]\n", X509_get_version(x509));

/** 2 Serial Number **/
ASN1_INTEGER* serial = X509_get_serialNumber(x509);
char buf[2048];
memset(buf, 0, 2048);
memcpy(buf, ASN1_STRING_get0_data(serial), ASN1_STRING_length(serial) );
printf("2. Certificate Serial len=[%d] Serial:", ASN1_STRING_length(serial));
for(int i=0; i < ASN1_STRING_length(serial); i++)
{
printf("%02X", (unsigned char)buf[i]);
}
printf("\n");

/** 3 signature **/
const X509_ALGOR *tsig_alg = X509_get0_tbs_sigalg(x509);
const int sig_nid = OBJ_obj2nid(tsig_alg->algorithm);
if (sig_nid != NID_undef)
{
printf("3. signature=[%s][%s]\n", OBJ_nid2sn(sig_nid), OBJ_nid2ln(sig_nid));
}

/** 4 证书签发者, issuer_name **/
const X509_NAME *X509_issuer_name = X509_get_issuer_name(x509);
char *issuer_name = X509_NAME_oneline(X509_issuer_name, NULL, 0);
printf("4. issuer_name=[%s]\n", issuer_name);
OPENSSL_free(issuer_name);

/** 5 Valid time **/
const ASN1_TIME *ASN1_time;
struct tm Certificate_time;
printf("5. Certificate time\n");
ASN1_time = X509_get0_notBefore(x509);
if(ASN1_TIME_to_tm(ASN1_time, &Certificate_time) > 0)
{
printf("%4sFrom: %s"," ", asctime(&Certificate_time));
}

ASN1_time = X509_get0_notAfter(x509);
if(ASN1_TIME_to_tm(ASN1_time, &Certificate_time) > 0)
{
printf("%4sTo : %s", " ",asctime(&Certificate_time));
}

/** 6 证书持有者 Subject **/
const X509_NAME *X509_subject_name = X509_get_subject_name(x509);
char *subject_name = X509_NAME_oneline(X509_subject_name, NULL, 0);
int subject_number = X509_NAME_entry_count(X509_subject_name);
printf("6. subject num=[%d][%s]\n", subject_number, subject_name);
OPENSSL_free(subject_name);


/** 7 Subject PublicKey **/
printf("7. Subject PublicKey\n");
X509_Public_Print(x509);


printf("扩展学习1:如何精细的获取 证书接受者的数据?\n");
{
X509_NAME *subj = X509_get_subject_name(x509);
printf("subject_name_num=[%d]\n", X509_NAME_entry_count(subj));
for (int i = 0; i < X509_NAME_entry_count(subj); i++)
{
X509_NAME_ENTRY *e = X509_NAME_get_entry(subj, i);
ASN1_STRING *type = (ASN1_STRING *)X509_NAME_ENTRY_get_object(e);
ASN1_STRING *value = X509_NAME_ENTRY_get_data(e);
const unsigned char *str1 = ASN1_STRING_get0_data(type);
const unsigned char *str2 = ASN1_STRING_get0_data(value);
printf("[%02d][%s]=[%s]\n", i, str1, str2);
}
}

printf("扩展学习2:如何精细的获取 证书签发着的数据?\n");
{
X509_NAME *subj = X509_get_issuer_name(x509);
printf("subject_name_num=[%d]\n", X509_NAME_entry_count(subj));
for (int i = 0; i < X509_NAME_entry_count(subj); i++)
{
X509_NAME_ENTRY *e = X509_NAME_get_entry(subj, i);
ASN1_STRING *type = (ASN1_STRING *)X509_NAME_ENTRY_get_object(e);
ASN1_STRING *value = X509_NAME_ENTRY_get_data(e);
const unsigned char *str1 = ASN1_STRING_get0_data(type);
const unsigned char *str2 = ASN1_STRING_get0_data(value);
printf("[%02d][%s]=[%s]\n", i, str1, str2);
}
}

printf("X509 扩展处理 \n");
GET_X509_EXTENSION(x509);

BIO_free_all(bio_file);
X509_free(x509);
printf("********************************************************\n");

}

编译运行

1
2
3
gcc -Wall -std=c99 -g -I include/ x509_TEST.c -L lib/ -lcrypto -lssl -lpthread -ldl -o My_x509

find /root/openssl_devel_lib/certificate/ -iname "*.cer"| xargs -n1 My_x509

内存泄漏检查

使用了别人的开发库,内存的申请或释放 都要严格检查一下
说实话, 这个示例程序, 我检查内存泄漏用了3个小时。
苦苦寻找,到底是哪个API GET了内存? 哪个API可以FREE内存, 相关API Double_FREE 更是让我烦不胜烦。

1
2
3
4
5
6
7
8
9
10
11
12
13
可以看到, 我有6张证书
[root@localhost 05_编码]# find /root/openssl_devel_lib/certificate/ -iname "*.cer"| wc -l
6

使用示例程序, 运行每个证书, 可以看见,没有内存泄漏。
[root@localhost 05_编码]# find /root/openssl_devel_lib/certificate/ -iname "*.cer"| xargs -n1 valgrind --tool=memcheck ./a.out 2>&1 | grep 'All heap blocks'
==33286== All heap blocks were freed -- no leaks are possible
==33287== All heap blocks were freed -- no leaks are possible
==33288== All heap blocks were freed -- no leaks are possible
==33289== All heap blocks were freed -- no leaks are possible
==33290== All heap blocks were freed -- no leaks are possible
==33291== All heap blocks were freed -- no leaks are possible
[root@localhost 05_编码]# find /root/openssl_devel_lib/certificate/ -iname "*.cer"| wc -l

验证效果

ECC椭圆曲线公钥效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
[root@localhost 05_编码]# ./My_x509 /root/openssl_devel_lib/certificate/1.1.cer
File name /root/openssl_devel_lib/certificate/1.1.cer
1. Certificate Version=[2]
2. Certificate Serial len=[8] Serial:4B32DE72CAA28369
3. signature=[RSA-SHA256][sha256WithRSAEncryption]
4. issuer_name=[/C=US/O=Google Trust Services/CN=Google Internet Authority G3]
5. Certificate time
From: Tue Jun 19 11:33:36 2018
To : Tue Aug 28 11:31:00 2018
6. subject num=[5][/C=US/ST=California/L=Mountain View/O=Google LLC/CN=*.googleapis.com]
7. Subject PublicKey
公钥算法:[id-ecPublicKey]
证书类型:408
加密级别:256 bit
公钥长度=[65]
04 14 3F 0D 43 6E A6 DB 5E 74 9B B1 15 36 89 85 C9 2E E7 97 44 85 F1 4B CA BB 07 E1 CB B5 D9 B1
D6 B4 97 49 6F 1B 18 B2 E9 D0 D0 78 D8 6C F2 D6 D2 CA E2 C5 0F 66 4F F1 3C 7D 96 AE 8E 38 8C 15
FF
扩展学习1:如何精细的获取 证书接受者的数据?
subject_name_num=[5]
[00][countryName]=[US]
[01][stateOrProvinceName]=[California]
[02][localityName]=[Mountain View]
[03][organizationName]=[Google LLC]
[04][commonName]=[*.googleapis.com]
扩展学习2:如何精细的获取 证书签发着的数据?
subject_name_num=[3]
[00][countryName]=[US]
[01][organizationName]=[Google Trust Services]
[02][commonName]=[Google Internet Authority G3]
X509 扩展处理
X509 证书扩展项个数 [9]
[00] nid=[0126] TYPE=[X509v3 Extended Key Usage]
len=[29], value=[TLS Web Server Authentication]

[01] nid=[0083] TYPE=[X509v3 Key Usage]
len=[17], value=[Digital Signature]

[02] nid=[0085] TYPE=[X509v3 Subject Alternative Name]
len=[125], value=[DNS:*.googleapis.com, DNS:*.clients6.google.com, DNS:*.cloudendpointsapis.com, DNS:cloudendpointsapis.com, DNS:googleapis.com]
精细的数据: NID_subject_alt_name
Name=[DNS], Value=[*.googleapis.com]
Name=[DNS], Value=[*.clients6.google.com]
Name=[DNS], Value=[*.cloudendpointsapis.com]
Name=[DNS], Value=[cloudendpointsapis.com]
Name=[DNS], Value=[googleapis.com]

[03] nid=[0177] TYPE=[Authority Information Access]
len=[92], value=[CA Issuers - URI:http://pki.goog/gsr2/GTSGIAG3.crt
OCSP - URI:http://ocsp.pki.goog/GTSGIAG3
]
精细的数据: NID_info_access
Name=[URI], Value=[http://pki.goog/gsr2/GTSGIAG3.crt]
Name=[URI], Value=[http://ocsp.pki.goog/GTSGIAG3]

[04] nid=[0082] TYPE=[X509v3 Subject Key Identifier]
len=[59], value=[07:BA:20:2D:80:B9:04:AD:68:5A:2D:7E:22:6F:40:CA:00:6C:BF:CD]

[05] nid=[0087] TYPE=[X509v3 Basic Constraints]
len=[8], value=[CA:FALSE]

[06] nid=[0090] TYPE=[X509v3 Authority Key Identifier]
len=[66], value=[keyid:77:C2:B8:50:9A:67:76:76:B1:2D:C2:86:D0:83:A0:7E:A6:7E:BA:4B
]

[07] nid=[0089] TYPE=[X509v3 Certificate Policies]
len=[55], value=[Policy: 1.3.6.1.4.1.11129.2.5.3
Policy: 2.23.140.1.2.2
]

[08] nid=[0103] TYPE=[X509v3 CRL Distribution Points]
len=[51], value=[
Full Name:
URI:http://crl.pki.goog/GTSGIAG3.crl
]

********************************************************
[root@localhost 05_编码]#

RSA 公钥效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
[root@localhost 05_编码]# ./My_x509 /root/openssl_devel_lib/certificate/2.1.cer
File name /root/openssl_devel_lib/certificate/2.1.cer
1. Certificate Version=[2]
2. Certificate Serial len=[8] Serial:5FA9E4B887AFCEF4
3. signature=[RSA-SHA256][sha256WithRSAEncryption]
4. issuer_name=[/C=US/O=Google Trust Services/CN=Google Internet Authority G3]
5. Certificate time
From: Tue Jun 19 11:32:59 2018
To : Tue Aug 28 11:31:00 2018
6. subject num=[5][/C=US/ST=California/L=Mountain View/O=Google LLC/CN=accounts.google.com]
7. Subject PublicKey
公钥算法:[rsaEncryption]
证书类型:6
加密级别:2048 bit
RSA公钥长度:257 Byte
len=257
00 A1 15 C2 34 2F C4 8F A4 84 25 A6 E0 20 24 E0 AA F0 AC 42 3C 34 79 4A 82 95 33 B7 81 7A 4B 63
7F 09 A9 A5 A6 0E AB 13 F4 FD F6 DE 83 65 B0 F9 07 1E 39 9D C3 52 2A 84 B1 5D 61 76 47 50 74 9D
DA 19 69 00 8F D6 33 02 11 44 EE 00 3C 26 CD 25 EC 5C 46 0C 6A B5 C5 A0 01 13 59 8B DA 88 85 BC
15 F7 F1 61 A6 F9 9E EC A2 55 22 3B 09 9C 68 D3 3F AD 6E 99 F7 0E 28 10 15 72 C1 A5 63 DF CB 0C
7C BA 61 11 0E 4D EB 29 9C 0F 3D A1 17 5E AA EC 89 DE F2 EF 99 87 24 B9 D4 D4 BF A3 2C 83 F2 77
73 F5 47 8B 36 BF 6B 7F EE 8C 9D AA 6A 07 CD E5 89 3B 2E 0C 6E AF 62 05 A7 86 E2 3E D9 F9 A2 AD
CA 56 F1 D1 43 E3 C8 5C D0 58 94 91 4A 55 20 13 89 B5 F6 E4 20 4E 9C 77 17 28 E2 45 A5 F8 B4 DB
8D 0B BF 41 60 82 99 DF AF 16 AD DA E5 84 DE 7C 39 15 65 EA 23 43 6D EC 25 41 53 41 8A D1 42 4F
7B
扩展学习1:如何精细的获取 证书接受者的数据?
subject_name_num=[5]
[00][countryName]=[US]
[01][stateOrProvinceName]=[California]
[02][localityName]=[Mountain View]
[03][organizationName]=[Google LLC]
[04][commonName]=[accounts.google.com]
扩展学习2:如何精细的获取 证书签发着的数据?
subject_name_num=[3]
[00][countryName]=[US]
[01][organizationName]=[Google Trust Services]
[02][commonName]=[Google Internet Authority G3]
X509 扩展处理
X509 证书扩展项个数 [8]
[00] nid=[0126] TYPE=[X509v3 Extended Key Usage]
len=[29], value=[TLS Web Server Authentication]

[01] nid=[0085] TYPE=[X509v3 Subject Alternative Name]
len=[71], value=[DNS:accounts.google.com, DNS:*.accounts.goog, DNS:*.partner.android.com]
精细的数据: NID_subject_alt_name
Name=[DNS], Value=[accounts.google.com]
Name=[DNS], Value=[*.accounts.goog]
Name=[DNS], Value=[*.partner.android.com]

[02] nid=[0177] TYPE=[Authority Information Access]
len=[92], value=[CA Issuers - URI:http://pki.goog/gsr2/GTSGIAG3.crt
OCSP - URI:http://ocsp.pki.goog/GTSGIAG3
]
精细的数据: NID_info_access
Name=[URI], Value=[http://pki.goog/gsr2/GTSGIAG3.crt]
Name=[URI], Value=[http://ocsp.pki.goog/GTSGIAG3]

[03] nid=[0082] TYPE=[X509v3 Subject Key Identifier]
len=[59], value=[0F:26:83:EE:15:EB:77:16:E5:03:02:7A:5D:B8:1F:7C:01:06:60:BD]

[04] nid=[0087] TYPE=[X509v3 Basic Constraints]
len=[8], value=[CA:FALSE]

[05] nid=[0090] TYPE=[X509v3 Authority Key Identifier]
len=[66], value=[keyid:77:C2:B8:50:9A:67:76:76:B1:2D:C2:86:D0:83:A0:7E:A6:7E:BA:4B
]

[06] nid=[0089] TYPE=[X509v3 Certificate Policies]
len=[55], value=[Policy: 1.3.6.1.4.1.11129.2.5.3
Policy: 2.23.140.1.2.2
]

[07] nid=[0103] TYPE=[X509v3 CRL Distribution Points]
len=[51], value=[
Full Name:
URI:http://crl.pki.goog/GTSGIAG3.crl
]

********************************************************
[root@localhost 05_编码]#

结束语

OpenSSL 源码里面, 使用了大量的宏, 堪称’宏地狱’
1大量的宏,对于一个想快速上手的同学来说,非常难受。
1.1. 大量的宏 字符拼接,简直就是在玩字符的魔术拼接一样, 使得源码不再便于阅读理解。
1.2. 结构体宏, GDB 调试时, 看不见数据的内部结构, 神烦!