JSSE: add Android non-standard checkServerTrusted() in X509TrustManager

pull/288/head
Chris Conlon 2025-09-23 14:23:41 -06:00
parent 7650f518e7
commit 37eaa1215b
10 changed files with 1773 additions and 56 deletions

View File

@ -0,0 +1,184 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=info@wolfssl.com
Validity
Not Before: Nov 13 20:41:34 2025 GMT
Not After : Aug 9 20:41:34 2028 GMT
Subject: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL intermediate CA 1, emailAddress=info@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:de:b4:c8:5c:77:e0:2d:b1:f5:b9:ad:16:47:35:
a0:35:65:65:c6:e1:40:ab:1e:b4:b9:13:b7:cb:8c:
bb:77:a5:76:da:6d:87:87:f6:4a:4d:13:e4:26:3e:
27:87:ee:5b:c7:6a:3f:45:30:61:55:5c:f6:35:d1:
65:fa:98:11:a3:a7:55:d5:be:91:82:4b:fc:be:90:
d6:50:53:63:9a:2c:22:e1:35:11:dc:78:02:97:8a:
e4:46:92:9c:53:08:76:de:1f:53:b6:b8:ca:77:3e:
79:6e:bc:d0:e3:0d:30:5b:4c:f6:94:0d:30:29:64:
9f:04:e5:db:fb:89:60:67:bb:af:26:83:51:77:24:
2f:2b:0b:a1:94:81:10:98:e8:eb:26:a8:1e:7c:e4:
c4:6c:67:06:95:55:4a:dd:52:f4:f2:60:6d:01:2b:
19:91:35:6d:a4:08:47:06:71:24:00:d9:de:c6:56:
f3:8b:53:2c:e2:9a:96:a5:f3:62:e5:c4:e3:23:f2:
d2:fc:21:ea:0f:62:76:8d:d5:99:48:ce:dc:58:c4:
bb:7f:da:94:2c:80:74:83:c5:e0:b0:15:7e:41:fd:
0e:f2:f4:f0:78:76:7b:ad:26:0d:aa:48:96:17:2f:
21:e3:95:2b:26:37:f9:aa:80:2f:fe:de:f6:5e:bc:
97:7f
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:TRUE
X509v3 Subject Key Identifier:
83:C6:3A:89:2C:81:F4:02:D7:9D:4C:E2:2A:C0:71:82:64:44:DA:0E
X509v3 Authority Key Identifier:
keyid:73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21
DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=info@wolfssl.com
serial:63
X509v3 Key Usage:
Certificate Sign, CRL Sign
Authority Information Access:
OCSP - URI:http://127.0.0.1:22220
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
77:ec:89:37:d4:35:2e:24:fd:d2:de:d9:98:87:be:52:ae:b5:
d4:f6:13:34:12:2c:f0:78:98:07:9f:f7:e4:76:df:6e:eb:97:
c7:03:a3:e6:15:6e:e2:94:16:6b:ed:59:a9:4a:10:a0:cc:c2:
61:78:c7:fb:1c:04:4a:20:c1:fc:94:c6:99:b0:3a:8c:2f:2b:
7d:15:30:53:c7:9b:73:54:6f:4d:16:a6:ab:2d:8a:51:70:1f:
1b:8e:60:0b:56:8b:f2:94:01:fd:81:5f:73:cb:ed:5e:cc:4a:
71:c1:a9:1a:d7:c7:2b:5a:66:02:77:da:10:e8:45:42:a0:7c:
ef:78:ff:dd:08:f6:84:2f:41:f5:18:c9:a2:48:d1:5d:b6:a4:
4d:32:af:83:5d:b9:64:ec:40:e9:62:38:ef:1b:d1:8e:c9:e8:
fd:b3:e8:e1:a1:da:16:1e:26:3c:82:36:cb:8d:80:67:33:ca:
30:bf:93:03:c8:9c:be:a2:6f:aa:7c:76:24:3d:06:99:ab:a7:
fe:12:f3:db:fd:a0:8a:b5:0d:c1:9c:90:b7:ca:7e:6d:fb:ff:
2a:c3:fe:7c:9f:41:e8:c2:7f:4f:fa:4b:49:c4:a0:d0:bc:fd:
38:34:22:ff:d5:83:79:70:7f:6c:30:8d:ad:93:fb:b8:77:01:
34:af:cc:0e
-----BEGIN CERTIFICATE-----
MIIE8DCCA9igAwIBAgIBATANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMCVVMx
EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM
B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NM
IHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjUx
MTEzMjA0MTM0WhcNMjgwODA5MjA0MTM0WjCBoTELMAkGA1UEBhMCVVMxEzARBgNV
BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZT
U0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMSIwIAYDVQQDDBl3b2xmU1NMIGludGVy
bWVkaWF0ZSBDQSAxMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3rTIXHfgLbH1ua0WRzWgNWVl
xuFAqx60uRO3y4y7d6V22m2Hh/ZKTRPkJj4nh+5bx2o/RTBhVVz2NdFl+pgRo6dV
1b6Rgkv8vpDWUFNjmiwi4TUR3HgCl4rkRpKcUwh23h9TtrjKdz55brzQ4w0wW0z2
lA0wKWSfBOXb+4lgZ7uvJoNRdyQvKwuhlIEQmOjrJqgefOTEbGcGlVVK3VL08mBt
ASsZkTVtpAhHBnEkANnexlbzi1Ms4pqWpfNi5cTjI/LS/CHqD2J2jdWZSM7cWMS7
f9qULIB0g8XgsBV+Qf0O8vTweHZ7rSYNqkiWFy8h45UrJjf5qoAv/t72XryXfwID
AQABo4IBOTCCATUwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUg8Y6iSyB9ALXnUzi
KsBxgmRE2g4wgcQGA1UdIwSBvDCBuYAUc7AcpC+Cy89HpTjXsASCOn5yFSGhgZ2k
gZowgZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQH
DAdTZWF0dGxlMRAwDgYDVQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtFbmdpbmVlcmlu
ZzEYMBYGA1UEAwwPd29sZlNTTCByb290IENBMR8wHQYJKoZIhvcNAQkBFhBpbmZv
QHdvbGZzc2wuY29tggFjMAsGA1UdDwQEAwIBBjAyBggrBgEFBQcBAQQmMCQwIgYI
KwYBBQUHMAGGFmh0dHA6Ly8xMjcuMC4wLjE6MjIyMjAwDQYJKoZIhvcNAQELBQAD
ggEBAHfsiTfUNS4k/dLe2ZiHvlKutdT2EzQSLPB4mAef9+R2327rl8cDo+YVbuKU
FmvtWalKEKDMwmF4x/scBEogwfyUxpmwOowvK30VMFPHm3NUb00WpqstilFwHxuO
YAtWi/KUAf2BX3PL7V7MSnHBqRrXxytaZgJ32hDoRUKgfO94/90I9oQvQfUYyaJI
0V22pE0yr4NduWTsQOliOO8b0Y7J6P2z6OGh2hYeJjyCNsuNgGczyjC/kwPInL6i
b6p8diQ9Bpmrp/4S89v9oIq1DcGckLfKfm37/yrD/nyfQejCf0/6S0nEoNC8/Tg0
Iv/Vg3lwf2wwja2T+7h3ATSvzA4=
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 99 (0x63)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=info@wolfssl.com
Validity
Not Before: Nov 13 20:41:34 2025 GMT
Not After : Aug 9 20:41:34 2028 GMT
Subject: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=info@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:ab:2c:b4:2f:1d:06:09:ef:4e:29:86:84:7e:cc:
bf:a6:79:7c:f0:c0:c1:64:25:8c:75:b7:10:05:ca:
48:27:0c:0e:32:1c:b0:fe:99:85:39:b6:b9:a2:f7:
27:ff:6d:3c:8c:16:73:29:21:7f:8b:a6:54:71:90:
ad:cc:05:b9:9f:15:c7:0a:3f:5f:69:f4:0a:5f:8c:
71:b5:2c:bf:66:e2:03:9a:32:f4:d2:ec:2a:89:4b:
f9:35:88:14:33:47:4e:2e:05:79:01:ed:64:36:76:
b9:f8:85:cd:01:88:ac:c5:b2:b1:59:b8:cd:5a:f4:
09:09:38:9b:da:5a:cf:ce:78:99:1f:49:3d:41:d6:
06:7c:52:99:c8:97:d1:b3:80:3a:a2:4f:36:c4:c5:
96:30:77:31:38:c8:70:cc:e1:67:06:b3:2b:2f:93:
b5:69:cf:83:7e:88:53:9b:0f:46:21:4c:d6:05:36:
44:99:60:68:47:e5:32:01:12:d4:10:73:ae:9a:34:
94:fa:6e:b8:58:4f:7b:5b:8a:92:97:ad:fd:97:b9:
75:ca:c2:d4:45:7d:17:6b:cd:2f:f3:63:7a:0e:30:
b5:0b:a9:d9:a6:7c:74:60:9d:cc:09:03:43:f1:0f:
90:d3:b7:fe:6c:9f:d9:cd:78:4b:15:ae:8c:5b:f9:
99:81
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:TRUE
X509v3 Subject Key Identifier:
73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21
X509v3 Authority Key Identifier:
keyid:73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21
DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=info@wolfssl.com
serial:63
X509v3 Key Usage:
Certificate Sign, CRL Sign
Authority Information Access:
OCSP - URI:http://127.0.0.1:22220
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
58:41:01:e5:1b:ce:bc:51:0c:23:b2:66:df:39:d9:1e:b1:bd:
9a:db:fa:da:16:83:26:6e:7e:2e:f9:5d:46:9a:52:a0:09:6f:
f2:c0:96:ba:49:ad:29:54:06:e9:21:d6:36:5e:d5:43:07:2c:
5d:4e:b7:bf:7c:e5:91:75:ea:0d:56:7c:a3:fd:82:d8:2e:70:
fa:fc:ab:36:36:d5:ba:63:d5:42:da:21:b4:50:9a:86:8a:df:
21:26:03:e8:ca:6f:c7:51:50:6c:cc:40:da:4e:8f:06:15:c0:
9a:0d:7a:80:2c:95:aa:5a:ad:e2:66:b0:32:d6:74:87:ea:7a:
b2:46:d5:2c:cf:fa:18:8a:2f:e0:3a:ae:17:6a:f2:ce:75:8d:
e4:4d:74:8f:e7:c6:21:29:65:5d:41:07:fb:29:d9:be:ea:b2:
e3:80:07:8c:14:8d:a3:7d:d1:51:af:26:9d:cd:01:d5:80:af:
68:12:41:2b:eb:94:cc:45:d1:c7:66:f3:f9:15:72:be:94:e3:
21:6d:f1:08:78:b6:5a:ee:73:09:4b:f4:1a:5e:02:2a:25:f0:
3d:d2:03:f2:22:15:4b:3d:aa:35:ea:90:ca:44:4e:61:77:db:
b4:94:46:77:c6:8c:33:09:b6:84:3c:4e:ac:ad:9d:e0:2f:22:
5a:be:25:19
-----BEGIN CERTIFICATE-----
MIIE5jCCA86gAwIBAgIBYzANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMCVVMx
EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM
B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NM
IHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjUx
MTEzMjA0MTM0WhcNMjgwODA5MjA0MTM0WjCBlzELMAkGA1UEBhMCVVMxEzARBgNV
BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZT
U0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NMIHJvb3Qg
Q0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQCrLLQvHQYJ704phoR+zL+meXzwwMFkJYx1txAF
ykgnDA4yHLD+mYU5trmi9yf/bTyMFnMpIX+LplRxkK3MBbmfFccKP19p9ApfjHG1
LL9m4gOaMvTS7CqJS/k1iBQzR04uBXkB7WQ2drn4hc0BiKzFsrFZuM1a9AkJOJva
Ws/OeJkfST1B1gZ8UpnIl9GzgDqiTzbExZYwdzE4yHDM4WcGsysvk7Vpz4N+iFOb
D0YhTNYFNkSZYGhH5TIBEtQQc66aNJT6brhYT3tbipKXrf2XuXXKwtRFfRdrzS/z
Y3oOMLULqdmmfHRgncwJA0PxD5DTt/5sn9nNeEsVroxb+ZmBAgMBAAGjggE5MIIB
NTAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRzsBykL4LLz0elONewBII6fnIVITCB
xAYDVR0jBIG8MIG5gBRzsBykL4LLz0elONewBII6fnIVIaGBnaSBmjCBlzELMAkG
A1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx
EDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQD
DA93b2xmU1NMIHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5j
b22CAWMwCwYDVR0PBAQDAgEGMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYW
aHR0cDovLzEyNy4wLjAuMToyMjIyMDANBgkqhkiG9w0BAQsFAAOCAQEAWEEB5RvO
vFEMI7Jm3znZHrG9mtv62haDJm5+LvldRppSoAlv8sCWukmtKVQG6SHWNl7VQwcs
XU63v3zlkXXqDVZ8o/2C2C5w+vyrNjbVumPVQtohtFCahorfISYD6Mpvx1FQbMxA
2k6PBhXAmg16gCyVqlqt4mawMtZ0h+p6skbVLM/6GIov4DquF2ryznWN5E10j+fG
ISllXUEH+ynZvuqy44AHjBSNo33RUa8mnc0B1YCvaBJBK+uUzEXRx2bz+RVyvpTj
IW3xCHi2Wu5zCUv0Gl4CKiXwPdID8iIVSz2qNeqQykROYXfbtJRGd8aMMwm2hDxO
rK2d4C8iWr4lGQ==
-----END CERTIFICATE-----

View File

@ -0,0 +1,92 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 99 (0x63)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=info@wolfssl.com
Validity
Not Before: Nov 13 20:41:34 2025 GMT
Not After : Aug 9 20:41:34 2028 GMT
Subject: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=info@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:ab:2c:b4:2f:1d:06:09:ef:4e:29:86:84:7e:cc:
bf:a6:79:7c:f0:c0:c1:64:25:8c:75:b7:10:05:ca:
48:27:0c:0e:32:1c:b0:fe:99:85:39:b6:b9:a2:f7:
27:ff:6d:3c:8c:16:73:29:21:7f:8b:a6:54:71:90:
ad:cc:05:b9:9f:15:c7:0a:3f:5f:69:f4:0a:5f:8c:
71:b5:2c:bf:66:e2:03:9a:32:f4:d2:ec:2a:89:4b:
f9:35:88:14:33:47:4e:2e:05:79:01:ed:64:36:76:
b9:f8:85:cd:01:88:ac:c5:b2:b1:59:b8:cd:5a:f4:
09:09:38:9b:da:5a:cf:ce:78:99:1f:49:3d:41:d6:
06:7c:52:99:c8:97:d1:b3:80:3a:a2:4f:36:c4:c5:
96:30:77:31:38:c8:70:cc:e1:67:06:b3:2b:2f:93:
b5:69:cf:83:7e:88:53:9b:0f:46:21:4c:d6:05:36:
44:99:60:68:47:e5:32:01:12:d4:10:73:ae:9a:34:
94:fa:6e:b8:58:4f:7b:5b:8a:92:97:ad:fd:97:b9:
75:ca:c2:d4:45:7d:17:6b:cd:2f:f3:63:7a:0e:30:
b5:0b:a9:d9:a6:7c:74:60:9d:cc:09:03:43:f1:0f:
90:d3:b7:fe:6c:9f:d9:cd:78:4b:15:ae:8c:5b:f9:
99:81
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:TRUE
X509v3 Subject Key Identifier:
73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21
X509v3 Authority Key Identifier:
keyid:73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21
DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=info@wolfssl.com
serial:63
X509v3 Key Usage:
Certificate Sign, CRL Sign
Authority Information Access:
OCSP - URI:http://127.0.0.1:22220
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
58:41:01:e5:1b:ce:bc:51:0c:23:b2:66:df:39:d9:1e:b1:bd:
9a:db:fa:da:16:83:26:6e:7e:2e:f9:5d:46:9a:52:a0:09:6f:
f2:c0:96:ba:49:ad:29:54:06:e9:21:d6:36:5e:d5:43:07:2c:
5d:4e:b7:bf:7c:e5:91:75:ea:0d:56:7c:a3:fd:82:d8:2e:70:
fa:fc:ab:36:36:d5:ba:63:d5:42:da:21:b4:50:9a:86:8a:df:
21:26:03:e8:ca:6f:c7:51:50:6c:cc:40:da:4e:8f:06:15:c0:
9a:0d:7a:80:2c:95:aa:5a:ad:e2:66:b0:32:d6:74:87:ea:7a:
b2:46:d5:2c:cf:fa:18:8a:2f:e0:3a:ae:17:6a:f2:ce:75:8d:
e4:4d:74:8f:e7:c6:21:29:65:5d:41:07:fb:29:d9:be:ea:b2:
e3:80:07:8c:14:8d:a3:7d:d1:51:af:26:9d:cd:01:d5:80:af:
68:12:41:2b:eb:94:cc:45:d1:c7:66:f3:f9:15:72:be:94:e3:
21:6d:f1:08:78:b6:5a:ee:73:09:4b:f4:1a:5e:02:2a:25:f0:
3d:d2:03:f2:22:15:4b:3d:aa:35:ea:90:ca:44:4e:61:77:db:
b4:94:46:77:c6:8c:33:09:b6:84:3c:4e:ac:ad:9d:e0:2f:22:
5a:be:25:19
-----BEGIN CERTIFICATE-----
MIIE5jCCA86gAwIBAgIBYzANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMCVVMx
EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM
B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NM
IHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjUx
MTEzMjA0MTM0WhcNMjgwODA5MjA0MTM0WjCBlzELMAkGA1UEBhMCVVMxEzARBgNV
BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZT
U0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NMIHJvb3Qg
Q0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQCrLLQvHQYJ704phoR+zL+meXzwwMFkJYx1txAF
ykgnDA4yHLD+mYU5trmi9yf/bTyMFnMpIX+LplRxkK3MBbmfFccKP19p9ApfjHG1
LL9m4gOaMvTS7CqJS/k1iBQzR04uBXkB7WQ2drn4hc0BiKzFsrFZuM1a9AkJOJva
Ws/OeJkfST1B1gZ8UpnIl9GzgDqiTzbExZYwdzE4yHDM4WcGsysvk7Vpz4N+iFOb
D0YhTNYFNkSZYGhH5TIBEtQQc66aNJT6brhYT3tbipKXrf2XuXXKwtRFfRdrzS/z
Y3oOMLULqdmmfHRgncwJA0PxD5DTt/5sn9nNeEsVroxb+ZmBAgMBAAGjggE5MIIB
NTAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRzsBykL4LLz0elONewBII6fnIVITCB
xAYDVR0jBIG8MIG5gBRzsBykL4LLz0elONewBII6fnIVIaGBnaSBmjCBlzELMAkG
A1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx
EDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQD
DA93b2xmU1NMIHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5j
b22CAWMwCwYDVR0PBAQDAgEGMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYW
aHR0cDovLzEyNy4wLjAuMToyMjIyMDANBgkqhkiG9w0BAQsFAAOCAQEAWEEB5RvO
vFEMI7Jm3znZHrG9mtv62haDJm5+LvldRppSoAlv8sCWukmtKVQG6SHWNl7VQwcs
XU63v3zlkXXqDVZ8o/2C2C5w+vyrNjbVumPVQtohtFCahorfISYD6Mpvx1FQbMxA
2k6PBhXAmg16gCyVqlqt4mawMtZ0h+p6skbVLM/6GIov4DquF2ryznWN5E10j+fG
ISllXUEH+ynZvuqy44AHjBSNo33RUa8mnc0B1YCvaBJBK+uUzEXRx2bz+RVyvpTj
IW3xCHi2Wu5zCUv0Gl4CKiXwPdID8iIVSz2qNeqQykROYXfbtJRGd8aMMwm2hDxO
rK2d4C8iWr4lGQ==
-----END CERTIFICATE-----

View File

@ -70,6 +70,21 @@ do
fi
done
# Copy OCSP certs (stored flat, not in subdirectory)
printf "Updating: ocsp-root-ca-cert.pem\n"
cp $CERT_LOCATION/ocsp/root-ca-cert.pem ./ocsp-root-ca-cert.pem
if [ $? -ne 0 ]; then
printf "Failed to copy cert: ocsp/root-ca-cert.pem\n"
exit 1
fi
printf "Updating: ocsp-intermediate1-ca-cert.pem\n"
cp $CERT_LOCATION/ocsp/intermediate1-ca-cert.pem ./ocsp-intermediate1-ca-cert.pem
if [ $? -ne 0 ]; then
printf "Failed to copy cert: ocsp/intermediate1-ca-cert.pem\n"
exit 1
fi
# Generate ca-keyPkcs8.der, used by examples/X509CertificateGeneration.java
openssl pkcs8 -topk8 -inform DER -outform DER -in ca-key.der -out ca-keyPkcs8.der -nocrypt
if [ $? -ne 0 ]; then

View File

@ -29,6 +29,8 @@
#endif
#include <wolfssl/ssl.h>
#include <wolfssl/error-ssl.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/ocsp.h>
#include "com_wolfssl_globals.h"
#include "com_wolfssl_WolfSSLCertManager.h"
@ -145,3 +147,178 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertManager_CertManagerVerifyBuff
return (jint)ret;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertManager_CertManagerCheckOCSPResponse
(JNIEnv* jenv, jclass jcl, jlong cmPtr, jbyteArray response,
jbyteArray cert, jbyteArray issuerCert)
{
#ifdef HAVE_OCSP
int ret = 0;
int decodedCertInit = 0;
int decodedIssuerInit = 0;
jint certSz = 0;
jint responseSz = 0;
jint issuerCertSz = 0;
byte* certBuffer = NULL;
byte* responseBuffer = NULL;
byte* issuerCertBuffer = NULL;
OcspEntry ocspEntry;
CertStatus certStatus;
DecodedCert decodedCert;
DecodedCert decodedIssuer;
OcspRequest* ocspRequest = NULL;
WOLFSSL_CERT_MANAGER* cm = (WOLFSSL_CERT_MANAGER*)(uintptr_t)cmPtr;
(void)jcl;
XMEMSET(&decodedCert, 0, sizeof(DecodedCert));
XMEMSET(&decodedIssuer, 0, sizeof(DecodedCert));
XMEMSET(&certStatus, 0, sizeof(CertStatus));
XMEMSET(&ocspEntry, 0, sizeof(OcspEntry));
if (jenv == NULL || response == NULL || cert == NULL || cm == NULL) {
ret = BAD_FUNC_ARG;
}
/* Get OCSP response buffer */
if (ret == 0) {
responseSz = (*jenv)->GetArrayLength(jenv, response);
responseBuffer = (byte*)(*jenv)->GetByteArrayElements(jenv,
response, NULL);
if (responseBuffer == NULL) {
ret = MEMORY_E;
}
}
/* Get certificate buffer */
if (ret == 0) {
certSz = (*jenv)->GetArrayLength(jenv, cert);
certBuffer = (byte*)(*jenv)->GetByteArrayElements(jenv, cert, NULL);
if (certBuffer == NULL) {
ret = MEMORY_E;
}
}
/* Get issuer certificate buffer if provided */
if (ret == 0 && issuerCert != NULL) {
issuerCertSz = (*jenv)->GetArrayLength(jenv, issuerCert);
issuerCertBuffer = (byte*)(*jenv)->GetByteArrayElements(jenv,
issuerCert, NULL);
if (issuerCertBuffer == NULL) {
ret = MEMORY_E;
}
}
/* Parse DER certificate into DecodedCert */
if (ret == 0) {
InitDecodedCert(&decodedCert, certBuffer, certSz, NULL);
decodedCertInit = 1;
ret = ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL);
}
/* Parse issuer cert DER if provided, needed for OCSP request init
* with issuer key hash */
if (ret == 0 && issuerCertBuffer != NULL) {
InitDecodedCert(&decodedIssuer, issuerCertBuffer, issuerCertSz, NULL);
decodedIssuerInit = 1;
ret = ParseCert(&decodedIssuer, CERT_TYPE, NO_VERIFY, NULL);
}
/* Enable OCSP in CertManager */
if (ret == 0) {
ret = wolfSSL_CertManagerEnableOCSP(cm, 0);
if (ret != WOLFSSL_SUCCESS) {
ret = WOLFSSL_FAILURE;
}
else {
ret = 0;
}
}
/* Create OCSP request and populate with cert info. */
if (ret == 0) {
ocspRequest = wolfSSL_OCSP_REQUEST_new();
if (ocspRequest == NULL) {
ret = MEMORY_E;
}
}
/* Copy certificate info to OCSP request for matching, needs
* issuerHash, issuerKeyHash, and serial number. */
if (ret == 0) {
/* Copy issuer name hash */
XMEMCPY(ocspRequest->issuerHash, decodedCert.issuerHash, KEYID_SIZE);
/* Copy issuer key hash: use issuer cert if provided, otherwise
* try to use the one from the cert being validated */
if (decodedIssuerInit) {
XMEMCPY(ocspRequest->issuerKeyHash, decodedIssuer.subjectKeyHash,
KEYID_SIZE);
}
else {
XMEMCPY(ocspRequest->issuerKeyHash, decodedCert.issuerKeyHash,
KEYID_SIZE);
}
/* Copy serial number, OcspRequest owns it */
ocspRequest->serial = (byte*)XMALLOC(decodedCert.serialSz, NULL,
DYNAMIC_TYPE_OCSP_REQUEST);
if (ocspRequest->serial == NULL) {
ret = MEMORY_E;
}
else {
XMEMCPY(ocspRequest->serial, decodedCert.serial,
decodedCert.serialSz);
ocspRequest->serialSz = decodedCert.serialSz;
}
}
/* Check OCSP response */
if (ret == 0) {
ret = wolfSSL_CertManagerCheckOCSPResponse(cm, responseBuffer,
responseSz, NULL, &certStatus, &ocspEntry, ocspRequest);
}
/* Check certificate status from OCSP response */
if (ret == WOLFSSL_SUCCESS) {
/* certStatus.status: 0 = good, 1 = revoked, 2 = unknown */
if (certStatus.status == 1) {
ret = OCSP_CERT_REVOKED;
}
else if (certStatus.status == 2) {
ret = OCSP_CERT_UNKNOWN;
}
}
if (ocspRequest != NULL) {
wolfSSL_OCSP_REQUEST_free(ocspRequest);
}
if (decodedIssuerInit) {
FreeDecodedCert(&decodedIssuer);
}
if (decodedCertInit) {
FreeDecodedCert(&decodedCert);
}
if (issuerCertBuffer != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, issuerCert,
(jbyte*)issuerCertBuffer, JNI_ABORT);
}
if (certBuffer != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, cert,
(jbyte*)certBuffer, JNI_ABORT);
}
if (responseBuffer != NULL) {
(*jenv)->ReleaseByteArrayElements(jenv, response,
(jbyte*)responseBuffer, JNI_ABORT);
}
return (jint)ret;
#else
(void)jenv;
(void)jcl;
(void)cmPtr;
(void)response;
(void)cert;
(void)issuerCert;
return (jint)NOT_COMPILED_IN;
#endif
}

View File

@ -55,6 +55,14 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertManager_CertManagerUnloadCAs
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertManager_CertManagerVerifyBuffer
(JNIEnv *, jclass, jlong, jbyteArray, jlong, jint);
/*
* Class: com_wolfssl_WolfSSLCertManager
* Method: CertManagerCheckOCSPResponse
* Signature: (J[B[B[B)I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertManager_CertManagerCheckOCSPResponse
(JNIEnv *, jclass, jlong, jbyteArray, jbyteArray, jbyteArray);
#ifdef __cplusplus
}
#endif

View File

@ -49,10 +49,12 @@ public class WolfSSLCertManager {
static native void CertManagerFree(long cm);
static native int CertManagerLoadCA(long cm, String f, String d);
static native int CertManagerLoadCABuffer(long cm, byte[] in, long sz,
int format);
int format);
static native int CertManagerUnloadCAs(long cm);
static native int CertManagerVerifyBuffer(long cm, byte[] in, long sz,
int format);
int format);
static native int CertManagerCheckOCSPResponse(long cm,
byte[] response, byte[] cert, byte[] issuerCert);
/**
* Create new WolfSSLCertManager object
@ -246,6 +248,65 @@ public class WolfSSLCertManager {
}
}
/**
* Check OCSP response for revocation status.
*
* This method validates that the OCSP response is signed by a trusted
* OCSP responder, contains a status for the specified certificate (matches
* serial number and issuer), and checks that the certificate is neither
* revoked nor reported with an unknown status by the OCSP responder.
* Certificates with an unknown status in the OCSP response cause this
* method to fail and return a specific negative OCSP error code.
*
* @param response DER-encoded OCSP response data
* @param cert DER-encoded certificate to check against the OCSP response
* @param issuerCert DER-encoded issuer certificate (optional)
*
* @return WolfSSL.SSL_SUCCESS on success, or a negative error code on
* failure. This includes specific OCSP error codes indicating
* revoked or unknown certificate status as reported by the OCSP
* responder.
*
* @throws IllegalStateException if WolfSSLCertManager has been freed
* @throws IllegalArgumentException if response or cert is null/empty
* @throws WolfSSLException if OCSP is not compiled in
*/
public synchronized int CertManagerCheckOCSPResponse(
byte[] response, byte[] cert, byte[] issuerCert)
throws IllegalStateException, WolfSSLException {
int ret;
confirmObjectIsActive();
if (response == null || response.length == 0) {
throw new IllegalArgumentException(
"OCSP response data is null or invalid size");
}
if (cert == null || cert.length == 0) {
throw new IllegalArgumentException(
"Certificate data is null or invalid size");
}
synchronized (cmLock) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
WolfSSLDebug.INFO, this.cmPtr,
() -> "entered CertManagerCheckOCSPResponse(" +
"responseSz: " + response.length + ", certSz: " +
cert.length + ", issuerCertSz: " +
(issuerCert != null ? issuerCert.length : 0) + ")");
ret = CertManagerCheckOCSPResponse(this.cmPtr, response, cert,
issuerCert);
if (ret == WolfSSL.NOT_COMPILED_IN) {
throw new WolfSSLException(
"OCSP support not compiled into wolfSSL");
}
return ret;
}
}
/**
* Frees CertManager object
* @see WolfSSLSession#freeSSL()

View File

@ -25,6 +25,7 @@ import com.wolfssl.WolfSSL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Arrays;
@ -1018,6 +1019,123 @@ public final class WolfSSLTrustX509 extends X509ExtendedTrustManager {
return certList;
}
/**
* Verifies a specified certificate chain.
* Non standard API, this is called/needed by Android.
*
* Android expects this method signature for OCSP stapling support.
* Native wolfSSL supports OCSP response processing via
* wolfSSL_CertManagerCheckOCSPResponse(). The ocspData parameter
* contains DER-encoded OCSP response data that is processed for
* certificate revocation checking.
*
* @param chain Certificate chain to validate
* @param ocspData OCSP response data (DER-encoded), may be null
* @param tlsSctData TLS SCT data (unused, wolfSSL does not support SCT)
* @param authType Authentication type
* @param host Hostname of the server
*
* @return Certificate chain used for verification, ordered with leaf/peer
* cert first, root CA cert last
*
* @throws CertificateException if chain does not verify properly
*/
public List<X509Certificate> checkServerTrusted(X509Certificate[] chain,
byte[] ocspData, byte[] tlsSctData, String authType, String host)
throws CertificateException {
int ret;
WolfSSLCertManager cm = null;
byte[] leafCertDer = null;
byte[] issuerCertDer = null;
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "entered checkServerTrusted(chain, ocspData, tlsSctData, " +
"authType, host)");
/* First verify the cert chain normally, throws if chain invalid
* including checks that chain != null and chain.length > 0 */
List<X509Certificate> certList =
checkServerTrusted(chain, authType, host);
/* Verify OCSP response data if provided */
if (ocspData != null && ocspData.length > 0) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "Verifying OCSP response data (" +
ocspData.length + " bytes)");
try {
cm = new WolfSSLCertManager();
/* Load trusted CAs that were used for cert verification */
ret = cm.CertManagerLoadCAKeyStore(this.store);
if (ret != WolfSSL.SSL_SUCCESS) {
throw new CertificateException(
"Failed to load trusted CAs for OCSP verification, " +
"ret = " + ret);
}
/* Get DER-encoded leaf certificate from chain */
leafCertDer = chain[0].getEncoded();
/* Get issuer certificate if available in chain. Issuer
* needed to compute issuer key hash for OCSP matching. */
if (chain.length > 1) {
issuerCertDer = chain[1].getEncoded();
}
/* Check OCSP response against the specific certificate */
ret = cm.CertManagerCheckOCSPResponse(ocspData, leafCertDer,
issuerCertDer);
if (ret != WolfSSL.SSL_SUCCESS) {
throw new CertificateException(
"OCSP response validation failed: " + ret);
}
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "OCSP response validation successful");
} catch (WolfSSLException e) {
String msg = e.getMessage();
if (msg != null && msg.contains("not compiled")) {
/* OCSP not available, log and continue */
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "OCSP support not available, skipping " +
"OCSP validation");
} else {
throw new CertificateException("OCSP validation error", e);
}
} catch (CertificateEncodingException e) {
throw new CertificateException(
"Failed to encode certificate for OCSP verification", e);
} finally {
if (cm != null) {
cm.free();
}
}
} else {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "No OCSP data provided, not doing OCSP validation");
}
/* Ignore TLS SCT data as wolfSSL doesn't support it */
if (tlsSctData != null && tlsSctData.length > 0) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "TLS SCT data provided (" + tlsSctData.length +
" bytes), currently not processed");
}
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
() -> "leaving checkServerTrusted(chain, ocspData, tlsSctData, " +
"authType, host), success");
return certList;
}
/**
* Returns an array of certificate authorities which are trusted for
* authenticating peers.

View File

@ -22,7 +22,9 @@ package com.wolfssl.provider.jsse.test;
import com.wolfssl.WolfSSL;
import com.wolfssl.WolfSSLException;
import com.wolfssl.WolfSSLCertManager;
import com.wolfssl.provider.jsse.WolfSSLProvider;
import com.wolfssl.test.WolfSSLCertManagerTest;
import com.wolfssl.provider.jsse.WolfSSLTrustX509;
import java.util.List;
@ -35,6 +37,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.time.Instant;
import java.security.KeyStore;
import java.security.KeyStoreException;
@ -529,7 +532,8 @@ public class WolfSSLTrustX509Test {
stream.close();
try {
x509tm.checkServerTrusted(new X509Certificate[] {
(X509Certificate)ks.getCertificate("server-rsapss") }, "RSASSA-PSS");
(X509Certificate)ks.getCertificate("server-rsapss") },
"RSASSA-PSS");
}
catch (Exception e) {
e.printStackTrace();
@ -678,12 +682,14 @@ public class WolfSSLTrustX509Test {
System.out.print("\tcheckServerTrusted() bad int");
String rsaServerCert = "examples/certs/intermediate/server-int-cert.pem";
String rsaServerCert =
"examples/certs/intermediate/server-int-cert.pem";
/* wrong/bad CA as intermediate, should not verify. Using int CA
* from ECC chain but correct one is from RSA chain. */
String rsaInt1CertWrong =
"examples/certs/intermediate/ca-int2-ecc-cert.pem";
String rsaInt2Cert = "examples/certs/intermediate/ca-int2-cert.pem";
String rsaInt2Cert =
"examples/certs/intermediate/ca-int2-cert.pem";
String eccServerCert =
"examples/certs/intermediate/server-int-ecc-cert.pem";
@ -691,7 +697,8 @@ public class WolfSSLTrustX509Test {
* from RSA chain but correct one is from ECC chain. */
String eccInt1CertWrong =
"examples/certs/intermediate/ca-int-cert.pem";
String eccInt2Cert = "examples/certs/intermediate/ca-int2-ecc-cert.pem";
String eccInt2Cert =
"examples/certs/intermediate/ca-int2-ecc-cert.pem";
if (WolfSSLTestFactory.isAndroid()) {
rsaServerCert = "/sdcard/" + rsaServerCert;
@ -936,13 +943,16 @@ public class WolfSSLTrustX509Test {
System.out.print("\tcheckServerTrusted() miss chain");
/* RSA chain, missing intermediate CA 1 */
String rsaServerCert = "examples/certs/intermediate/server-int-cert.pem";
String rsaInt2Cert = "examples/certs/intermediate/ca-int2-cert.pem";
String rsaServerCert =
"examples/certs/intermediate/server-int-cert.pem";
String rsaInt2Cert =
"examples/certs/intermediate/ca-int2-cert.pem";
/* ECC chain, missing intermediate CA 1 */
String eccServerCert =
"examples/certs/intermediate/server-int-ecc-cert.pem";
String eccInt2Cert = "examples/certs/intermediate/ca-int2-ecc-cert.pem";
String eccInt2Cert =
"examples/certs/intermediate/ca-int2-ecc-cert.pem";
if (WolfSSLTestFactory.isAndroid()) {
rsaServerCert = "/sdcard/" + rsaServerCert;
@ -1041,14 +1051,20 @@ public class WolfSSLTrustX509Test {
System.out.print("\tcheckServerTrusted() ooo chain");
/* RSA chain, out of order intermediate CAs */
String rsaServerCert = "examples/certs/intermediate/server-int-cert.pem";
String rsaInt1Cert = "examples/certs/intermediate/ca-int-cert.pem";
String rsaInt2Cert = "examples/certs/intermediate/ca-int2-cert.pem";
String rsaServerCert =
"examples/certs/intermediate/server-int-cert.pem";
String rsaInt1Cert =
"examples/certs/intermediate/ca-int-cert.pem";
String rsaInt2Cert =
"examples/certs/intermediate/ca-int2-cert.pem";
/* ECC chain, out of order intermediate CAs */
String eccServerCert = "examples/certs/intermediate/server-int-ecc-cert.pem";
String eccInt1Cert = "examples/certs/intermediate/ca-int-ecc-cert.pem";
String eccInt2Cert = "examples/certs/intermediate/ca-int2-ecc-cert.pem";
String eccServerCert =
"examples/certs/intermediate/server-int-ecc-cert.pem";
String eccInt1Cert =
"examples/certs/intermediate/ca-int-ecc-cert.pem";
String eccInt2Cert =
"examples/certs/intermediate/ca-int2-ecc-cert.pem";
if (WolfSSLTestFactory.isAndroid()) {
rsaServerCert = "/sdcard/" + rsaServerCert;
@ -1508,6 +1524,141 @@ public class WolfSSLTrustX509Test {
pass("\t... passed");
}
/**
* Test Android-specific checkServerTrusted method with OCSP and
* SCT parameters.
*/
@Test
public void testCheckServerTrustedAndroid()
throws Exception {
WolfSSLTrustX509 wolfX509tm = null;
TrustManagerFactory tmf;
TrustManager[] tm;
KeyStore caJKS;
CertificateFactory cf = CertificateFactory.getInstance("X.509");
List<X509Certificate> retChain = null;
byte[] dummyOcspData = new byte[] { 0x01, 0x02, 0x03 };
byte[] dummySctData = new byte[] { 0x04, 0x05, 0x06 };
String rsaServerCert =
"examples/certs/intermediate/server-int-cert.pem";
String intCACert1 =
"examples/certs/intermediate/ca-int2-cert.pem";
String intCACert2 =
"examples/certs/intermediate/ca-int-cert.pem";
System.out.print("\tcheckServerTrusted() Android");
try {
X509Certificate serverCert;
X509Certificate intCert1;
X509Certificate intCert2;
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(rsaServerCert))) {
serverCert = (X509Certificate)cf.generateCertificate(bis);
}
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(intCACert1))) {
intCert1 = (X509Certificate)cf.generateCertificate(bis);
}
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(intCACert2))) {
intCert2 = (X509Certificate)cf.generateCertificate(bis);
}
X509Certificate[] certArray = new X509Certificate[] {
serverCert, intCert1, intCert2 };
caJKS = KeyStore.getInstance("JKS");
try (FileInputStream stream = new FileInputStream(tf.caJKS)) {
caJKS.load(stream, "wolfSSL test".toCharArray());
}
tmf = TrustManagerFactory.getInstance("X509", "wolfJSSE");
tmf.init(caJKS);
tm = tmf.getTrustManagers();
if (tm.length != 1) {
error("\t... failed");
fail("TrustManagerFactory did not return single TrustManager");
}
wolfX509tm = (WolfSSLTrustX509)tm[0];
/* Test with null OCSP and SCT data, should behave identically to
* the 3-parameter method. */
try {
retChain = wolfX509tm.checkServerTrusted(certArray,
null, null, "RSA", "localhost");
} catch (CertificateException e) {
error("\t... failed");
fail("checkServerTrusted failed: " + e.getMessage());
}
if (retChain == null) {
error("\t... failed");
fail("checkServerTrusted() did not return expected " +
"List of certs");
}
/* cert chain returned should include peer, ints, and root */
if (retChain.size() != 4) {
error("\t... failed");
fail("checkServerTrusted() didn't return expected " +
"number of certs, got: " + retChain.size());
}
/* Test with invalid OCSP data, should fail, SCT data is currently
* ignored (not supported in native wolfSSL, so dummy SCT is ok. */
try {
retChain = wolfX509tm.checkServerTrusted(certArray,
dummyOcspData, dummySctData, "RSA", "localhost");
error("\t... failed");
fail("checkServerTrusted with invalid OCSP data " +
"should have thrown CertificateException");
} catch (CertificateException e) {
/* Expected */
}
/* Test with null OCSP data (a valid use case) */
try {
retChain = wolfX509tm.checkServerTrusted(certArray,
null, dummySctData, "RSA", "localhost");
} catch (CertificateException e) {
error("\t... failed");
fail("checkServerTrusted with null OCSP failed: " +
e.getMessage());
}
if (retChain == null) {
error("\t... failed");
fail("checkServerTrusted() with null OCSP did not " +
"return expected List of certs");
}
if (retChain.size() != 4) {
error("\t... failed");
fail("checkServerTrusted() with null OCSP didn't " +
"return expected number of certs, got: " +
retChain.size());
}
} catch (Exception e) {
error("\t... failed");
fail("checkServerTrusted test failed with: " +
e.getMessage());
}
pass("\t... passed");
}
@Test
public void testUsingRsaPssCert()
throws Exception {
@ -1569,58 +1720,58 @@ public class WolfSSLTrustX509Test {
}
@Test
public void testX509ExtendedTrustManagerInternal()
public void testX509ExtTrustMgrInternal()
throws CertificateException, IOException, Exception {
System.out.print("\tX509ExtendedTrustManager int");
/* Basic SSLSocket success case, SNI matches server cert CN */
testX509ExtendedTrustManagerSSLSocketBasicSuccess();
testX509ExtTrustMgrSSLSocketBasicSuccess();
/* Basic SSLSocket success case, SNI matches server cert CN,
* do not call startHandshake(), should still succeed */
testX509ExtendedTrustManagerSSLSocketNoStartHandshakeSuccess();
testX509ExtendedTrustManagerSSLSocketNoClientStartHandshakeSuccess();
testX509ExtendedTrustManagerSSLSocketNoServerStartHandshakeSuccess();
testX509ExtTrustMgrSSLSocketNoStartHandshakeSuccess();
testX509ExtTrustMgrSSLSocketNoClientStartHandshakeSuccess();
testX509ExtTrustMgrSSLSocketNoServerStartHandshakeSuccess();
/* Basic SSLSocket fail case, SNI does not match server cert CN */
testX509ExtendedTrustManagerSSLSocketBasicFail();
testX509ExtTrustMgrSSLSocketBasicFail();
/* SSLSocket should fail if trying to use bad endoint alg */
testX509ExtendedTrustManagerSSLSocketEndpointAlgFail();
testX509ExtTrustMgrSSLSocketEndpointAlgFail();
/* SSLSocket should succeed if server cert changes after resume */
testX509ExtendedTrustManagerSSLSocketCertChangeSuccess();
testX509ExtTrustMgrSSLSocketCertChangeSuccess();
/* Basic SSLEngine success case, HTTPS hostname verification,
* SNI matches server cert CN */
testX509ExtendedTrustManagerSSLEngineBasicSuccess();
testX509ExtTrustMgrSSLEngineBasicSuccess();
/* Basic SSLEngine success case, LDAPS hostname verification,
* SNI matches server cert CN */
testX509ExtendedTrustManagerSSLEngineBasicSuccessLDAPS();
testX509ExtTrustMgrSSLEngineBasicSuccessLDAPS();
/* Basic SSLEngine fail case, HTTPS hostname verification,
* SNI does not match server cert CN */
testX509ExtendedTrustManagerSSLEngineBasicFail();
testX509ExtTrustMgrSSLEngineBasicFail();
/* Basic SSLEngine fail case, LDAPS hostname verification,
* SNI does not match server cert CN */
testX509ExtendedTrustManagerSSLEngineBasicFailLDAPS();
testX509ExtTrustMgrSSLEngineBasicFailLDAPS();
/* LDAPS hostname verification test, wildcard failures */
testX509ExtendedTrustManagerSSLEngineWildcardFailLDAPS();
testX509ExtTrustMgrSSLEngineWildcardFailLDAPS();
/* LDAPS hostname verification test, wildcard success */
testX509ExtendedTrustManagerSSLEngineWildcardSuccessLDAPS();
testX509ExtTrustMgrSSLEngineWildcardSuccessLDAPS();
/* SSLEngine should fail if trying to use bad endoint alg */
testX509ExtendedTrustManagerSSLEngineEndpointAlgFail();
testX509ExtTrustMgrSSLEngineEndpointAlgFail();
pass("\t... passed");
}
private void testX509ExtendedTrustManagerSSLSocketBasicSuccess()
private void testX509ExtTrustMgrSSLSocketBasicSuccess()
throws CertificateException, IOException, Exception {
SSLContext srvCtx = tf.createSSLContext("TLSv1.2", provider,
@ -1672,7 +1823,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLSocketNoStartHandshakeSuccess()
private void testX509ExtTrustMgrSSLSocketNoStartHandshakeSuccess()
throws CertificateException, IOException, Exception {
SSLContext srvCtx = tf.createSSLContext("TLSv1.2", provider,
@ -1724,7 +1875,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLSocketNoClientStartHandshakeSuccess()
private void testX509ExtTrustMgrSSLSocketNoClientStartHandshakeSuccess()
throws CertificateException, IOException, Exception {
SSLContext srvCtx = tf.createSSLContext("TLSv1.2", provider,
@ -1776,7 +1927,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLSocketNoServerStartHandshakeSuccess()
private void testX509ExtTrustMgrSSLSocketNoServerStartHandshakeSuccess()
throws CertificateException, IOException, Exception {
SSLContext srvCtx = tf.createSSLContext("TLSv1.2", provider,
@ -1828,7 +1979,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLSocketBasicFail()
private void testX509ExtTrustMgrSSLSocketBasicFail()
throws CertificateException, IOException, Exception {
SSLContext srvCtx = tf.createSSLContext("TLSv1.2", provider,
@ -1872,7 +2023,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLSocketEndpointAlgFail()
private void testX509ExtTrustMgrSSLSocketEndpointAlgFail()
throws CertificateException, IOException, Exception {
SSLContext srvCtx = tf.createSSLContext("TLSv1.2", provider,
@ -1918,7 +2069,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLEngineBasicSuccess()
private void testX509ExtTrustMgrSSLEngineBasicSuccess()
throws CertificateException, IOException, Exception {
int ret;
@ -1954,7 +2105,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLEngineBasicSuccessLDAPS()
private void testX509ExtTrustMgrSSLEngineBasicSuccessLDAPS()
throws CertificateException, IOException, Exception {
int ret;
@ -1987,7 +2138,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLEngineBasicFail()
private void testX509ExtTrustMgrSSLEngineBasicFail()
throws CertificateException, IOException, Exception {
int ret;
@ -2024,7 +2175,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLEngineBasicFailLDAPS()
private void testX509ExtTrustMgrSSLEngineBasicFailLDAPS()
throws CertificateException, IOException, Exception {
int ret;
@ -2054,7 +2205,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLEngineWildcardFailLDAPS()
private void testX509ExtTrustMgrSSLEngineWildcardFailLDAPS()
throws CertificateException, IOException, Exception {
int ret;
@ -2162,7 +2313,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLEngineWildcardSuccessLDAPS()
private void testX509ExtTrustMgrSSLEngineWildcardSuccessLDAPS()
throws CertificateException, IOException, Exception {
int ret;
@ -2213,7 +2364,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLEngineEndpointAlgFail()
private void testX509ExtTrustMgrSSLEngineEndpointAlgFail()
throws CertificateException, IOException, Exception {
int ret;
@ -2313,7 +2464,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLSocketCertChangeSuccess()
private void testX509ExtTrustMgrSSLSocketCertChangeSuccess()
throws CertificateException, IOException, Exception {
int serverPort = 0;
@ -2467,24 +2618,24 @@ public class WolfSSLTrustX509Test {
}
@Test
public void testX509ExtendedTrustManagerExternal()
public void testX509ExtTrustMgrExternal()
throws CertificateException, IOException, Exception {
System.out.print("\tX509ExtendedTrustManager ext");
/* Basic SSLSocket success case, SNI matches server cert CN */
testX509ExtendedTrustManagerSSLSocketBasicExtSuccess();
testX509ExtTrustMgrSSLSocketBasicExtSuccess();
/* Basic SSLSocket fail case, custom X509ExtendedTrustManager that
* verifies no certificates */
testX509ExtendedTrustManagerSSLSocketBasicExtFail();
testX509ExtTrustMgrSSLSocketBasicExtFail();
/* Basic SSLSocket success case, SNI matches server cert CN,
* do not call startHandshake(), should still succeed. Custom
* X509ExtendedTrustManager used that verifies all certs. */
testX509ExtendedTrustManagerSSLSocketExtNoStartHandshakeSuccess();
testX509ExtendedTrustManagerSSLSocketExtNoClientStartHandshakeSuccess();
testX509ExtendedTrustManagerSSLSocketExtNoServerStartHandshakeSuccess();
testX509ExtTrustMgrSSLSocketExtNoStartHandshakeSuccess();
testX509ExtTrustMgrSSLSocketExtNoClientStartHandshakeSuccess();
testX509ExtTrustMgrSSLSocketExtNoServerStartHandshakeSuccess();
pass("\t... passed");
}
@ -2600,6 +2751,283 @@ public class WolfSSLTrustX509Test {
System.out.println("\t... passed");
}
/**
* Test Android-specific checkServerTrusted method with OCSP data.
* OCSP validation requires the cert to be in the OCSP response.
* We test with both null OCSP data (should succeed) and invalid OCSP
* data (should either fail or log gracefully if OCSP not compiled in).
*/
@Test
public void testCheckServerTrustedWithOCSPData()
throws CertificateException, IOException, Exception {
WolfSSLTrustX509 wolfX509tm = null;
TrustManagerFactory tmf;
TrustManager[] tm;
KeyStore caJKS;
CertificateFactory cf = CertificateFactory.getInstance("X.509");
List<X509Certificate> retChain = null;
System.out.print("\tcheckServerTrusted() OCSP data");
String rsaServerCert =
"examples/certs/intermediate/server-int-cert.pem";
String intCACert1 =
"examples/certs/intermediate/ca-int2-cert.pem";
String intCACert2 =
"examples/certs/intermediate/ca-int-cert.pem";
try {
X509Certificate serverCert;
X509Certificate intCert1;
X509Certificate intCert2;
/* Load test certificates */
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(rsaServerCert))) {
serverCert = (X509Certificate)cf.generateCertificate(bis);
}
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(intCACert1))) {
intCert1 = (X509Certificate)cf.generateCertificate(bis);
}
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(intCACert2))) {
intCert2 = (X509Certificate)cf.generateCertificate(bis);
}
X509Certificate[] certArray = new X509Certificate[] {
serverCert, intCert1, intCert2 };
/* Load cacerts.jks into KeyStore */
caJKS = KeyStore.getInstance("JKS");
try (FileInputStream stream =
new FileInputStream("examples/provider/cacerts.jks")) {
caJKS.load(stream, "wolfSSL test".toCharArray());
}
/* Get X509TrustManager */
tmf = TrustManagerFactory.getInstance("X509", "wolfJSSE");
tmf.init(caJKS);
tm = tmf.getTrustManagers();
wolfX509tm = (WolfSSLTrustX509)tm[0];
/* Test with null OCSP data - should succeed */
try {
retChain = wolfX509tm.checkServerTrusted(certArray,
null, null, "RSA", "localhost");
if (retChain == null || retChain.size() == 0) {
error("\t... failed");
fail("checkServerTrusted with null OCSP failed");
}
} catch (CertificateException e) {
error("\t... failed");
fail("checkServerTrusted with null OCSP failed: " +
e.getMessage());
}
/* Test invalid OCSP data */
byte[] invalidOcspData = new byte[] { 0x01, 0x02, 0x03 };
try {
retChain = wolfX509tm.checkServerTrusted(certArray,
invalidOcspData, null, "RSA", "localhost");
} catch (CertificateException e) {
/* Expected if OCSP is compiled in and invalid data provided */
String msg = e.getMessage();
if (msg != null && !msg.contains("OCSP")) {
/* Re-throw if it's not an OCSP-related error */
throw e;
}
}
} catch (Exception e) {
error("\t... failed");
fail("checkServerTrusted with OCSP test failed: " +
e.getMessage());
}
pass("\t... passed");
}
/**
* This test uses valid OCSP response data from wolfSSL test suite
* to validate the Android-specific checkServerTrusted method with
* proper OCSP handling.
*
* The OCSP response is for a certificate signed by the wolfSSL OCSP
* root CA. We load both the regular cacerts.jks and add the wolfSSL
* OCSP root CA so that both the certificate chain verification and
* OCSP response verification can succeed.
*/
@Test
public void testCheckServerTrustedWithValidOCSPData()
throws Exception {
System.out.print("\tcheckServerTrusted() valid OCSP");
try {
/* Load basic cacerts trust store */
KeyStore caJKS = KeyStore.getInstance("JKS");
try (FileInputStream stream =
new FileInputStream("examples/provider/cacerts.jks")) {
caJKS.load(stream, "wolfSSL test".toCharArray());
}
/* Add the wolfSSL OCSP root CA to the KeyStore so we can
* verify the OCSP response signature. The OCSP response is
* signed by the wolfSSL OCSP Responder which chains to this
* root CA. */
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate ocspRootCa;
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(
"examples/certs/ocsp-root-ca-cert.pem"))) {
ocspRootCa = (X509Certificate)cf.generateCertificate(bis);
}
caJKS.setCertificateEntry("ocsp-root-ca", ocspRootCa);
/* Set up TrustManager with OCSP support */
TrustManagerFactory tmf =
TrustManagerFactory.getInstance("X509", "wolfJSSE");
tmf.init(caJKS);
TrustManager[] tm = tmf.getTrustManagers();
WolfSSLTrustX509 wolfX509tm = (WolfSSLTrustX509)tm[0];
/* Create certificate chain with intermediate1-ca-cert.pem, which
* matches the OCSP response (response is for serial 01, which is
* intermediate1-ca-cert.pem signed by wolfSSL OCSP root CA).
* Include the issuer (root CA) in the chain so issuerKeyHash
* can be properly computed for OCSP matching. */
X509Certificate intermediate1Cert;
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(
"examples/certs/ocsp-intermediate1-ca-cert.pem"))) {
intermediate1Cert =
(X509Certificate)cf.generateCertificate(bis);
}
X509Certificate[] certArray =
new X509Certificate[] { intermediate1Cert, ocspRootCa };
/* Test checkServerTrusted method with valid OCSP data that
* matches the certificate being validated. */
List<X509Certificate> retChain = null;
retChain = wolfX509tm.checkServerTrusted(certArray,
WolfSSLCertManagerTest.validOcspResponse,
null, "RSA", "localhost");
/* Verify return value is valid */
if (retChain == null || retChain.size() == 0) {
error("\t... failed");
fail("checkServerTrusted with valid OCSP returned null or " +
"empty chain");
}
/* Should return at least the certs we passed in */
if (retChain.size() < certArray.length) {
error("\t... failed");
fail("checkServerTrusted with valid OCSP returned fewer " +
"certs than expected, got: " + retChain.size());
}
} catch (Exception e) {
error("\t... failed");
fail("checkServerTrusted with valid OCSP test failed: " +
e.getMessage());
}
pass("\t... passed");
}
/**
* Test that Android specific checkServerTrusted(chain, ocspData, ...)
* fails when OCSP response doesn't match the certificate chain.
*/
@Test
public void testCheckServerTrustedWithMismatchedOCSPData()
throws Exception {
KeyStore caJKS = null;
CertificateFactory cf = null;
X509Certificate ocspRootCa = null;
X509Certificate serverCert = null;
X509Certificate[] certArray = null;
TrustManagerFactory tmf = null;
TrustManager[] tm = null;
WolfSSLTrustX509 wolfX509tm = null;
System.out.print("\tmismatched OCSP response");
try {
/* Load basic cacerts trust store */
caJKS = KeyStore.getInstance("JKS");
try (FileInputStream stream =
new FileInputStream("examples/provider/cacerts.jks")) {
caJKS.load(stream, "wolfSSL test".toCharArray());
}
/* Add wolfSSL OCSP root CA to the KeyStore so we can verify the
* OCSP response signature. */
cf = CertificateFactory.getInstance("X.509");
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream(
"examples/certs/ocsp-root-ca-cert.pem"))) {
ocspRootCa = (X509Certificate)cf.generateCertificate(bis);
}
caJKS.setCertificateEntry("ocsp-root-ca", ocspRootCa);
/* Set up TrustManager with OCSP support */
tmf = TrustManagerFactory.getInstance("X509", "wolfJSSE");
tmf.init(caJKS);
tm = tmf.getTrustManagers();
wolfX509tm = (WolfSSLTrustX509)tm[0];
/* Create certificate chain with server-cert.pem, which does not
* match the OCSP response (response is for serial 01 which is
* intermediate1-ca-cert.pem, not server-cert.pem). */
try (BufferedInputStream bis = new BufferedInputStream(
new FileInputStream("examples/certs/server-cert.pem"))) {
serverCert = (X509Certificate)cf.generateCertificate(bis);
}
certArray = new X509Certificate[] { serverCert };
/* Test checkServerTrusted method with valid OCSP data that does
* not match the certificate being validated. This should fail
* because the OCSP response is for a different certificate. */
try {
List<X509Certificate> retChain = null;
retChain = wolfX509tm.checkServerTrusted(certArray,
WolfSSLCertManagerTest.validOcspResponse,
null, "RSA", "localhost");
error("\t... failed");
fail("checkServerTrusted should have thrown " +
"CertificateException for mismatched OCSP response");
} catch (CertificateException e) {
/* Expected */
}
} catch (Exception e) {
/* Check if OCSP is not compiled in */
if (e.getMessage() != null &&
e.getMessage().contains("not compiled")) {
System.out.println("\t... skipped (OCSP not compiled in)");
return;
}
error("\t... failed");
fail("checkServerTrusted with mismatched OCSP test failed: " +
e.getMessage());
}
pass("\t... passed");
}
/* TrustManager that trusts all certificates */
TrustManager[] trustAllCerts = {
new X509ExtendedTrustManager() {
@ -2660,7 +3088,7 @@ public class WolfSSLTrustX509Test {
}
};
private void testX509ExtendedTrustManagerSSLSocketBasicExtSuccess()
private void testX509ExtTrustMgrSSLSocketBasicExtSuccess()
throws CertificateException, IOException, Exception {
SSLContext srvCtx = tf.createSSLContext("TLSv1.2", provider,
@ -2712,7 +3140,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLSocketBasicExtFail()
private void testX509ExtTrustMgrSSLSocketBasicExtFail()
throws CertificateException, IOException, Exception {
SSLContext srvCtx = tf.createSSLContext("TLSv1.2", provider,
@ -2755,7 +3183,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLSocketExtNoStartHandshakeSuccess()
private void testX509ExtTrustMgrSSLSocketExtNoStartHandshakeSuccess()
throws CertificateException, IOException, Exception {
SSLContext srvCtx = tf.createSSLContext("TLSv1.2", provider,
@ -2808,7 +3236,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLSocketExtNoClientStartHandshakeSuccess()
private void testX509ExtTrustMgrSSLSocketExtNoClientStartHandshakeSuccess()
throws CertificateException, IOException, Exception {
SSLContext srvCtx = tf.createSSLContext("TLSv1.2", provider,
@ -2861,7 +3289,7 @@ public class WolfSSLTrustX509Test {
}
}
private void testX509ExtendedTrustManagerSSLSocketExtNoServerStartHandshakeSuccess()
private void testX509ExtTrustMgrSSLSocketExtNoServerStartHandshakeSuccess()
throws CertificateException, IOException, Exception {
SSLContext srvCtx = tf.createSSLContext("TLSv1.2", provider,

View File

@ -0,0 +1,633 @@
/* WolfSSLCertManagerTest.java
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
package com.wolfssl.test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import org.junit.Test;
import org.junit.BeforeClass;
import static org.junit.Assert.*;
import com.wolfssl.WolfSSL;
import com.wolfssl.WolfSSLCertificate;
import com.wolfssl.WolfSSLCertManager;
import com.wolfssl.WolfSSLException;
/**
* JUnit tests for WolfSSLCertManager JNI wrapper class.
*
* @author wolfSSL
*/
public class WolfSSLCertManagerTest {
private static String ocspRootCaCert =
"examples/certs/ocsp-root-ca-cert.pem";
private static String ocspIntermediate1Cert =
"examples/certs/ocsp-intermediate1-ca-cert.pem";
private static String serverCert =
"examples/certs/server-cert.pem";
/*
* Valid OCSP response from wolfSSL test suite
* (tests/api/test_ocsp_test_blobs.h - resp[])
* This OCSP response is for intermediate1-ca-cert.pem (serial 01)
* signed by wolfSSL root CA. The response status is "good".
*/
public static final byte[] validOcspResponse = {
(byte)0x30, (byte)0x82, (byte)0x07, (byte)0x04,
(byte)0x0a, (byte)0x01, (byte)0x00, (byte)0xa0,
(byte)0x82, (byte)0x06, (byte)0xfd, (byte)0x30,
(byte)0x82, (byte)0x06, (byte)0xf9, (byte)0x06,
(byte)0x09, (byte)0x2b, (byte)0x06, (byte)0x01,
(byte)0x05, (byte)0x05, (byte)0x07, (byte)0x30,
(byte)0x01, (byte)0x01, (byte)0x04, (byte)0x82,
(byte)0x06, (byte)0xea, (byte)0x30, (byte)0x82,
(byte)0x06, (byte)0xe6, (byte)0x30, (byte)0x82,
(byte)0x01, (byte)0x06, (byte)0xa1, (byte)0x81,
(byte)0xa1, (byte)0x30, (byte)0x81, (byte)0x9e,
(byte)0x31, (byte)0x0b, (byte)0x30, (byte)0x09,
(byte)0x06, (byte)0x03, (byte)0x55, (byte)0x04,
(byte)0x06, (byte)0x13, (byte)0x02, (byte)0x55,
(byte)0x53, (byte)0x31, (byte)0x13, (byte)0x30,
(byte)0x11, (byte)0x06, (byte)0x03, (byte)0x55,
(byte)0x04, (byte)0x08, (byte)0x0c, (byte)0x0a,
(byte)0x57, (byte)0x61, (byte)0x73, (byte)0x68,
(byte)0x69, (byte)0x6e, (byte)0x67, (byte)0x74,
(byte)0x6f, (byte)0x6e, (byte)0x31, (byte)0x10,
(byte)0x30, (byte)0x0e, (byte)0x06, (byte)0x03,
(byte)0x55, (byte)0x04, (byte)0x07, (byte)0x0c,
(byte)0x07, (byte)0x53, (byte)0x65, (byte)0x61,
(byte)0x74, (byte)0x74, (byte)0x6c, (byte)0x65,
(byte)0x31, (byte)0x10, (byte)0x30, (byte)0x0e,
(byte)0x06, (byte)0x03, (byte)0x55, (byte)0x04,
(byte)0x0a, (byte)0x0c, (byte)0x07, (byte)0x77,
(byte)0x6f, (byte)0x6c, (byte)0x66, (byte)0x53,
(byte)0x53, (byte)0x4c, (byte)0x31, (byte)0x14,
(byte)0x30, (byte)0x12, (byte)0x06, (byte)0x03,
(byte)0x55, (byte)0x04, (byte)0x0b, (byte)0x0c,
(byte)0x0b, (byte)0x45, (byte)0x6e, (byte)0x67,
(byte)0x69, (byte)0x6e, (byte)0x65, (byte)0x65,
(byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x67,
(byte)0x31, (byte)0x1f, (byte)0x30, (byte)0x1d,
(byte)0x06, (byte)0x03, (byte)0x55, (byte)0x04,
(byte)0x03, (byte)0x0c, (byte)0x16, (byte)0x77,
(byte)0x6f, (byte)0x6c, (byte)0x66, (byte)0x53,
(byte)0x53, (byte)0x4c, (byte)0x20, (byte)0x4f,
(byte)0x43, (byte)0x53, (byte)0x50, (byte)0x20,
(byte)0x52, (byte)0x65, (byte)0x73, (byte)0x70,
(byte)0x6f, (byte)0x6e, (byte)0x64, (byte)0x65,
(byte)0x72, (byte)0x31, (byte)0x1f, (byte)0x30,
(byte)0x1d, (byte)0x06, (byte)0x09, (byte)0x2a,
(byte)0x86, (byte)0x48, (byte)0x86, (byte)0xf7,
(byte)0x0d, (byte)0x01, (byte)0x09, (byte)0x01,
(byte)0x16, (byte)0x10, (byte)0x69, (byte)0x6e,
(byte)0x66, (byte)0x6f, (byte)0x40, (byte)0x77,
(byte)0x6f, (byte)0x6c, (byte)0x66, (byte)0x73,
(byte)0x73, (byte)0x6c, (byte)0x2e, (byte)0x63,
(byte)0x6f, (byte)0x6d, (byte)0x18, (byte)0x0f,
(byte)0x32, (byte)0x30, (byte)0x32, (byte)0x35,
(byte)0x31, (byte)0x31, (byte)0x31, (byte)0x32,
(byte)0x31, (byte)0x33, (byte)0x34, (byte)0x35,
(byte)0x31, (byte)0x31, (byte)0x5a, (byte)0x30,
(byte)0x4f, (byte)0x30, (byte)0x4d, (byte)0x30,
(byte)0x38, (byte)0x30, (byte)0x07, (byte)0x06,
(byte)0x05, (byte)0x2b, (byte)0x0e, (byte)0x03,
(byte)0x02, (byte)0x1a, (byte)0x04, (byte)0x14,
(byte)0x44, (byte)0xa8, (byte)0xdb, (byte)0xd1,
(byte)0xbc, (byte)0x97, (byte)0x0a, (byte)0x83,
(byte)0x3b, (byte)0x5b, (byte)0x31, (byte)0x9a,
(byte)0x4c, (byte)0xb8, (byte)0xd2, (byte)0x52,
(byte)0x37, (byte)0x15, (byte)0x8a, (byte)0x88,
(byte)0x04, (byte)0x14, (byte)0x73, (byte)0xb0,
(byte)0x1c, (byte)0xa4, (byte)0x2f, (byte)0x82,
(byte)0xcb, (byte)0xcf, (byte)0x47, (byte)0xa5,
(byte)0x38, (byte)0xd7, (byte)0xb0, (byte)0x04,
(byte)0x82, (byte)0x3a, (byte)0x7e, (byte)0x72,
(byte)0x15, (byte)0x21, (byte)0x02, (byte)0x01,
(byte)0x01, (byte)0x80, (byte)0x00, (byte)0x18,
(byte)0x0f, (byte)0x32, (byte)0x30, (byte)0x32,
(byte)0x35, (byte)0x31, (byte)0x31, (byte)0x31,
(byte)0x32, (byte)0x31, (byte)0x33, (byte)0x34,
(byte)0x35, (byte)0x31, (byte)0x31, (byte)0x5a,
(byte)0x30, (byte)0x0b, (byte)0x06, (byte)0x09,
(byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86,
(byte)0xf7, (byte)0x0d, (byte)0x01, (byte)0x01,
(byte)0x0b, (byte)0x03, (byte)0x82, (byte)0x01,
(byte)0x01, (byte)0x00, (byte)0x77, (byte)0xa3,
(byte)0x5a, (byte)0x2a, (byte)0x99, (byte)0x67,
(byte)0x53, (byte)0x05, (byte)0x9a, (byte)0x78,
(byte)0x1d, (byte)0x37, (byte)0x22, (byte)0x63,
(byte)0x0d, (byte)0x59, (byte)0x9e, (byte)0x41,
(byte)0x38, (byte)0xef, (byte)0xc2, (byte)0x2a,
(byte)0x6e, (byte)0x6e, (byte)0xad, (byte)0x35,
(byte)0xd4, (byte)0x4d, (byte)0xa9, (byte)0x91,
(byte)0x33, (byte)0xf8, (byte)0x74, (byte)0xef,
(byte)0xf9, (byte)0xaa, (byte)0x18, (byte)0xb7,
(byte)0x29, (byte)0xf8, (byte)0x3b, (byte)0xe0,
(byte)0x49, (byte)0xe8, (byte)0x50, (byte)0x3c,
(byte)0x38, (byte)0xd8, (byte)0xee, (byte)0x53,
(byte)0xd9, (byte)0xb6, (byte)0xe2, (byte)0xda,
(byte)0x63, (byte)0x84, (byte)0xef, (byte)0xe3,
(byte)0xa8, (byte)0xbc, (byte)0x7c, (byte)0x6d,
(byte)0x65, (byte)0x9b, (byte)0x97, (byte)0x13,
(byte)0x3f, (byte)0x25, (byte)0x82, (byte)0x48,
(byte)0x61, (byte)0x9b, (byte)0x28, (byte)0xdc,
(byte)0xae, (byte)0xad, (byte)0xa3, (byte)0xb1,
(byte)0x56, (byte)0x42, (byte)0xb8, (byte)0x78,
(byte)0x10, (byte)0x53, (byte)0x03, (byte)0x77,
(byte)0x51, (byte)0x28, (byte)0xd5, (byte)0x7d,
(byte)0x4d, (byte)0x88, (byte)0x9c, (byte)0x15,
(byte)0xee, (byte)0x7c, (byte)0xac, (byte)0x54,
(byte)0x86, (byte)0x6b, (byte)0xc2, (byte)0x5e,
(byte)0x2d, (byte)0x64, (byte)0xfb, (byte)0xd9,
(byte)0x35, (byte)0xfd, (byte)0x18, (byte)0x7e,
(byte)0xc3, (byte)0x89, (byte)0x3c, (byte)0x72,
(byte)0x8e, (byte)0x22, (byte)0xd0, (byte)0x31,
(byte)0xb5, (byte)0x5f, (byte)0xc9, (byte)0x2b,
(byte)0xed, (byte)0x89, (byte)0xec, (byte)0xff,
(byte)0x4b, (byte)0xba, (byte)0xde, (byte)0x1a,
(byte)0x9e, (byte)0xed, (byte)0x61, (byte)0x79,
(byte)0x4f, (byte)0x85, (byte)0xbc, (byte)0x5c,
(byte)0xc5, (byte)0x50, (byte)0xe3, (byte)0x8a,
(byte)0xb1, (byte)0x28, (byte)0x45, (byte)0x75,
(byte)0xb5, (byte)0x65, (byte)0x0b, (byte)0xb9,
(byte)0xb3, (byte)0x6f, (byte)0xd4, (byte)0x4b,
(byte)0x4f, (byte)0x6d, (byte)0x45, (byte)0x0a,
(byte)0x8f, (byte)0xbf, (byte)0xe5, (byte)0xdf,
(byte)0x87, (byte)0x33, (byte)0xd2, (byte)0xaf,
(byte)0x09, (byte)0x8a, (byte)0x19, (byte)0x5b,
(byte)0x3b, (byte)0x4e, (byte)0xad, (byte)0xb3,
(byte)0x6f, (byte)0xdd, (byte)0xf3, (byte)0xf4,
(byte)0x4f, (byte)0xd3, (byte)0x68, (byte)0xc5,
(byte)0x70, (byte)0x74, (byte)0x7c, (byte)0xa0,
(byte)0x77, (byte)0xa8, (byte)0x88, (byte)0x73,
(byte)0x05, (byte)0x6c, (byte)0xe8, (byte)0x56,
(byte)0x43, (byte)0xa4, (byte)0xe3, (byte)0x9f,
(byte)0x66, (byte)0xa1, (byte)0xbb, (byte)0x3e,
(byte)0xbf, (byte)0xbb, (byte)0x49, (byte)0xaf,
(byte)0x13, (byte)0xa7, (byte)0x13, (byte)0x09,
(byte)0x04, (byte)0x52, (byte)0x87, (byte)0xdd,
(byte)0x0a, (byte)0x72, (byte)0x7b, (byte)0x69,
(byte)0xd9, (byte)0x5b, (byte)0xa9, (byte)0xfc,
(byte)0xa5, (byte)0x5a, (byte)0x33, (byte)0xad,
(byte)0xc6, (byte)0x95, (byte)0x26, (byte)0x2c,
(byte)0x64, (byte)0x3d, (byte)0x6c, (byte)0x47,
(byte)0x3d, (byte)0x88, (byte)0xcb, (byte)0x8b,
(byte)0x5b, (byte)0x73, (byte)0xf4, (byte)0x93,
(byte)0x57, (byte)0x70, (byte)0x3e, (byte)0xc1,
(byte)0xbf, (byte)0xfc, (byte)0x54, (byte)0xd1,
(byte)0xfb, (byte)0xe3, (byte)0x1f, (byte)0x73,
(byte)0x9d, (byte)0x47, (byte)0xa0, (byte)0x82,
(byte)0x04, (byte)0xc6, (byte)0x30, (byte)0x82,
(byte)0x04, (byte)0xc2, (byte)0x30, (byte)0x82,
(byte)0x04, (byte)0xbe, (byte)0x30, (byte)0x82,
(byte)0x03, (byte)0xa6, (byte)0xa0, (byte)0x03,
(byte)0x02, (byte)0x01, (byte)0x02, (byte)0x02,
(byte)0x01, (byte)0x04, (byte)0x30, (byte)0x0d,
(byte)0x06, (byte)0x09, (byte)0x2a, (byte)0x86,
(byte)0x48, (byte)0x86, (byte)0xf7, (byte)0x0d,
(byte)0x01, (byte)0x01, (byte)0x0b, (byte)0x05,
(byte)0x00, (byte)0x30, (byte)0x81, (byte)0x97,
(byte)0x31, (byte)0x0b, (byte)0x30, (byte)0x09,
(byte)0x06, (byte)0x03, (byte)0x55, (byte)0x04,
(byte)0x06, (byte)0x13, (byte)0x02, (byte)0x55,
(byte)0x53, (byte)0x31, (byte)0x13, (byte)0x30,
(byte)0x11, (byte)0x06, (byte)0x03, (byte)0x55,
(byte)0x04, (byte)0x08, (byte)0x0c, (byte)0x0a,
(byte)0x57, (byte)0x61, (byte)0x73, (byte)0x68,
(byte)0x69, (byte)0x6e, (byte)0x67, (byte)0x74,
(byte)0x6f, (byte)0x6e, (byte)0x31, (byte)0x10,
(byte)0x30, (byte)0x0e, (byte)0x06, (byte)0x03,
(byte)0x55, (byte)0x04, (byte)0x07, (byte)0x0c,
(byte)0x07, (byte)0x53, (byte)0x65, (byte)0x61,
(byte)0x74, (byte)0x74, (byte)0x6c, (byte)0x65,
(byte)0x31, (byte)0x10, (byte)0x30, (byte)0x0e,
(byte)0x06, (byte)0x03, (byte)0x55, (byte)0x04,
(byte)0x0a, (byte)0x0c, (byte)0x07, (byte)0x77,
(byte)0x6f, (byte)0x6c, (byte)0x66, (byte)0x53,
(byte)0x53, (byte)0x4c, (byte)0x31, (byte)0x14,
(byte)0x30, (byte)0x12, (byte)0x06, (byte)0x03,
(byte)0x55, (byte)0x04, (byte)0x0b, (byte)0x0c,
(byte)0x0b, (byte)0x45, (byte)0x6e, (byte)0x67,
(byte)0x69, (byte)0x6e, (byte)0x65, (byte)0x65,
(byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x67,
(byte)0x31, (byte)0x18, (byte)0x30, (byte)0x16,
(byte)0x06, (byte)0x03, (byte)0x55, (byte)0x04,
(byte)0x03, (byte)0x0c, (byte)0x0f, (byte)0x77,
(byte)0x6f, (byte)0x6c, (byte)0x66, (byte)0x53,
(byte)0x53, (byte)0x4c, (byte)0x20, (byte)0x72,
(byte)0x6f, (byte)0x6f, (byte)0x74, (byte)0x20,
(byte)0x43, (byte)0x41, (byte)0x31, (byte)0x1f,
(byte)0x30, (byte)0x1d, (byte)0x06, (byte)0x09,
(byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86,
(byte)0xf7, (byte)0x0d, (byte)0x01, (byte)0x09,
(byte)0x01, (byte)0x16, (byte)0x10, (byte)0x69,
(byte)0x6e, (byte)0x66, (byte)0x6f, (byte)0x40,
(byte)0x77, (byte)0x6f, (byte)0x6c, (byte)0x66,
(byte)0x73, (byte)0x73, (byte)0x6c, (byte)0x2e,
(byte)0x63, (byte)0x6f, (byte)0x6d, (byte)0x30,
(byte)0x1e, (byte)0x17, (byte)0x0d, (byte)0x32,
(byte)0x35, (byte)0x31, (byte)0x31, (byte)0x31,
(byte)0x33, (byte)0x32, (byte)0x30, (byte)0x34,
(byte)0x31, (byte)0x33, (byte)0x35, (byte)0x5a,
(byte)0x17, (byte)0x0d, (byte)0x32, (byte)0x38,
(byte)0x30, (byte)0x38, (byte)0x30, (byte)0x39,
(byte)0x32, (byte)0x30, (byte)0x34, (byte)0x31,
(byte)0x33, (byte)0x35, (byte)0x5a, (byte)0x30,
(byte)0x81, (byte)0x9e, (byte)0x31, (byte)0x0b,
(byte)0x30, (byte)0x09, (byte)0x06, (byte)0x03,
(byte)0x55, (byte)0x04, (byte)0x06, (byte)0x13,
(byte)0x02, (byte)0x55, (byte)0x53, (byte)0x31,
(byte)0x13, (byte)0x30, (byte)0x11, (byte)0x06,
(byte)0x03, (byte)0x55, (byte)0x04, (byte)0x08,
(byte)0x0c, (byte)0x0a, (byte)0x57, (byte)0x61,
(byte)0x73, (byte)0x68, (byte)0x69, (byte)0x6e,
(byte)0x67, (byte)0x74, (byte)0x6f, (byte)0x6e,
(byte)0x31, (byte)0x10, (byte)0x30, (byte)0x0e,
(byte)0x06, (byte)0x03, (byte)0x55, (byte)0x04,
(byte)0x07, (byte)0x0c, (byte)0x07, (byte)0x53,
(byte)0x65, (byte)0x61, (byte)0x74, (byte)0x74,
(byte)0x6c, (byte)0x65, (byte)0x31, (byte)0x10,
(byte)0x30, (byte)0x0e, (byte)0x06, (byte)0x03,
(byte)0x55, (byte)0x04, (byte)0x0a, (byte)0x0c,
(byte)0x07, (byte)0x77, (byte)0x6f, (byte)0x6c,
(byte)0x66, (byte)0x53, (byte)0x53, (byte)0x4c,
(byte)0x31, (byte)0x14, (byte)0x30, (byte)0x12,
(byte)0x06, (byte)0x03, (byte)0x55, (byte)0x04,
(byte)0x0b, (byte)0x0c, (byte)0x0b, (byte)0x45,
(byte)0x6e, (byte)0x67, (byte)0x69, (byte)0x6e,
(byte)0x65, (byte)0x65, (byte)0x72, (byte)0x69,
(byte)0x6e, (byte)0x67, (byte)0x31, (byte)0x1f,
(byte)0x30, (byte)0x1d, (byte)0x06, (byte)0x03,
(byte)0x55, (byte)0x04, (byte)0x03, (byte)0x0c,
(byte)0x16, (byte)0x77, (byte)0x6f, (byte)0x6c,
(byte)0x66, (byte)0x53, (byte)0x53, (byte)0x4c,
(byte)0x20, (byte)0x4f, (byte)0x43, (byte)0x53,
(byte)0x50, (byte)0x20, (byte)0x52, (byte)0x65,
(byte)0x73, (byte)0x70, (byte)0x6f, (byte)0x6e,
(byte)0x64, (byte)0x65, (byte)0x72, (byte)0x31,
(byte)0x1f, (byte)0x30, (byte)0x1d, (byte)0x06,
(byte)0x09, (byte)0x2a, (byte)0x86, (byte)0x48,
(byte)0x86, (byte)0xf7, (byte)0x0d, (byte)0x01,
(byte)0x09, (byte)0x01, (byte)0x16, (byte)0x10,
(byte)0x69, (byte)0x6e, (byte)0x66, (byte)0x6f,
(byte)0x40, (byte)0x77, (byte)0x6f, (byte)0x6c,
(byte)0x66, (byte)0x73, (byte)0x73, (byte)0x6c,
(byte)0x2e, (byte)0x63, (byte)0x6f, (byte)0x6d,
(byte)0x30, (byte)0x82, (byte)0x01, (byte)0x22,
(byte)0x30, (byte)0x0d, (byte)0x06, (byte)0x09,
(byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86,
(byte)0xf7, (byte)0x0d, (byte)0x01, (byte)0x01,
(byte)0x01, (byte)0x05, (byte)0x00, (byte)0x03,
(byte)0x82, (byte)0x01, (byte)0x0f, (byte)0x00,
(byte)0x30, (byte)0x82, (byte)0x01, (byte)0x0a,
(byte)0x02, (byte)0x82, (byte)0x01, (byte)0x01,
(byte)0x00, (byte)0xb8, (byte)0xba, (byte)0x23,
(byte)0xb4, (byte)0xf6, (byte)0xc3, (byte)0x7b,
(byte)0x14, (byte)0xc3, (byte)0xa4, (byte)0xf5,
(byte)0x1d, (byte)0x61, (byte)0xa1, (byte)0xf5,
(byte)0x1e, (byte)0x63, (byte)0xb9, (byte)0x85,
(byte)0x23, (byte)0x34, (byte)0x50, (byte)0x6d,
(byte)0xf8, (byte)0x7c, (byte)0xa2, (byte)0x8a,
(byte)0x04, (byte)0x8b, (byte)0xd5, (byte)0x75,
(byte)0x5c, (byte)0x2d, (byte)0xf7, (byte)0x63,
(byte)0x88, (byte)0xd1, (byte)0x07, (byte)0x7a,
(byte)0xea, (byte)0x0b, (byte)0x45, (byte)0x35,
(byte)0x2b, (byte)0xeb, (byte)0x1f, (byte)0xb1,
(byte)0x22, (byte)0xb4, (byte)0x94, (byte)0x41,
(byte)0x38, (byte)0xe2, (byte)0x9d, (byte)0x74,
(byte)0xd6, (byte)0x8b, (byte)0x30, (byte)0x22,
(byte)0x10, (byte)0x51, (byte)0xc5, (byte)0xdb,
(byte)0xca, (byte)0x3f, (byte)0x46, (byte)0x2b,
(byte)0xfe, (byte)0xe5, (byte)0x5a, (byte)0x3f,
(byte)0x41, (byte)0x74, (byte)0x67, (byte)0x75,
(byte)0x95, (byte)0xa9, (byte)0x94, (byte)0xd5,
(byte)0xc3, (byte)0xee, (byte)0x42, (byte)0xf8,
(byte)0x8d, (byte)0xeb, (byte)0x92, (byte)0x95,
(byte)0xe1, (byte)0xd9, (byte)0x65, (byte)0xb7,
(byte)0x43, (byte)0xc4, (byte)0x18, (byte)0xde,
(byte)0x16, (byte)0x80, (byte)0x90, (byte)0xce,
(byte)0x24, (byte)0x35, (byte)0x21, (byte)0xc4,
(byte)0x55, (byte)0xac, (byte)0x5a, (byte)0x51,
(byte)0xe0, (byte)0x2e, (byte)0x2d, (byte)0xb3,
(byte)0x0a, (byte)0x5a, (byte)0x4f, (byte)0x4a,
(byte)0x73, (byte)0x31, (byte)0x50, (byte)0xee,
(byte)0x4a, (byte)0x16, (byte)0xbd, (byte)0x39,
(byte)0x8b, (byte)0xad, (byte)0x05, (byte)0x48,
(byte)0x87, (byte)0xb1, (byte)0x99, (byte)0xe2,
(byte)0x10, (byte)0xa7, (byte)0x06, (byte)0x72,
(byte)0x67, (byte)0xca, (byte)0x5c, (byte)0xd1,
(byte)0x97, (byte)0xbd, (byte)0xc8, (byte)0xf1,
(byte)0x76, (byte)0xf8, (byte)0xe0, (byte)0x4a,
(byte)0xec, (byte)0xbc, (byte)0x93, (byte)0xf4,
(byte)0x66, (byte)0x4c, (byte)0x28, (byte)0x71,
(byte)0xd1, (byte)0xd8, (byte)0x66, (byte)0x03,
(byte)0xb4, (byte)0x90, (byte)0x30, (byte)0xbb,
(byte)0x17, (byte)0xb0, (byte)0xfe, (byte)0x97,
(byte)0xf5, (byte)0x1e, (byte)0xe8, (byte)0xc7,
(byte)0x5d, (byte)0x9b, (byte)0x8b, (byte)0x11,
(byte)0x19, (byte)0x12, (byte)0x3c, (byte)0xab,
(byte)0x82, (byte)0x71, (byte)0x78, (byte)0xff,
(byte)0xae, (byte)0x3f, (byte)0x32, (byte)0xb2,
(byte)0x08, (byte)0x71, (byte)0xb2, (byte)0x1b,
(byte)0x8c, (byte)0x27, (byte)0xac, (byte)0x11,
(byte)0xb8, (byte)0xd8, (byte)0x43, (byte)0x49,
(byte)0xcf, (byte)0xb0, (byte)0x70, (byte)0xb1,
(byte)0xf0, (byte)0x8c, (byte)0xae, (byte)0xda,
(byte)0x24, (byte)0x87, (byte)0x17, (byte)0x3b,
(byte)0xd8, (byte)0x04, (byte)0x65, (byte)0x6c,
(byte)0x00, (byte)0x76, (byte)0x50, (byte)0xef,
(byte)0x15, (byte)0x08, (byte)0xd7, (byte)0xb4,
(byte)0x73, (byte)0x68, (byte)0x26, (byte)0x14,
(byte)0x87, (byte)0x95, (byte)0xc3, (byte)0x5f,
(byte)0x6e, (byte)0x61, (byte)0xb8, (byte)0x87,
(byte)0x84, (byte)0xfa, (byte)0x80, (byte)0x1a,
(byte)0x0a, (byte)0x8b, (byte)0x98, (byte)0xf3,
(byte)0xe3, (byte)0xff, (byte)0x4e, (byte)0x44,
(byte)0x1c, (byte)0x65, (byte)0x74, (byte)0x7c,
(byte)0x71, (byte)0x54, (byte)0x65, (byte)0xe5,
(byte)0x39, (byte)0x02, (byte)0x03, (byte)0x01,
(byte)0x00, (byte)0x01, (byte)0xa3, (byte)0x82,
(byte)0x01, (byte)0x0a, (byte)0x30, (byte)0x82,
(byte)0x01, (byte)0x06, (byte)0x30, (byte)0x09,
(byte)0x06, (byte)0x03, (byte)0x55, (byte)0x1d,
(byte)0x13, (byte)0x04, (byte)0x02, (byte)0x30,
(byte)0x00, (byte)0x30, (byte)0x1d, (byte)0x06,
(byte)0x03, (byte)0x55, (byte)0x1d, (byte)0x0e,
(byte)0x04, (byte)0x16, (byte)0x04, (byte)0x14,
(byte)0x32, (byte)0x67, (byte)0xe1, (byte)0xb1,
(byte)0x79, (byte)0xd2, (byte)0x81, (byte)0xfc,
(byte)0x9f, (byte)0x23, (byte)0x0c, (byte)0x70,
(byte)0x40, (byte)0x50, (byte)0xb5, (byte)0x46,
(byte)0x56, (byte)0xb8, (byte)0x30, (byte)0x36,
(byte)0x30, (byte)0x81, (byte)0xc4, (byte)0x06,
(byte)0x03, (byte)0x55, (byte)0x1d, (byte)0x23,
(byte)0x04, (byte)0x81, (byte)0xbc, (byte)0x30,
(byte)0x81, (byte)0xb9, (byte)0x80, (byte)0x14,
(byte)0x73, (byte)0xb0, (byte)0x1c, (byte)0xa4,
(byte)0x2f, (byte)0x82, (byte)0xcb, (byte)0xcf,
(byte)0x47, (byte)0xa5, (byte)0x38, (byte)0xd7,
(byte)0xb0, (byte)0x04, (byte)0x82, (byte)0x3a,
(byte)0x7e, (byte)0x72, (byte)0x15, (byte)0x21,
(byte)0xa1, (byte)0x81, (byte)0x9d, (byte)0xa4,
(byte)0x81, (byte)0x9a, (byte)0x30, (byte)0x81,
(byte)0x97, (byte)0x31, (byte)0x0b, (byte)0x30,
(byte)0x09, (byte)0x06, (byte)0x03, (byte)0x55,
(byte)0x04, (byte)0x06, (byte)0x13, (byte)0x02,
(byte)0x55, (byte)0x53, (byte)0x31, (byte)0x13,
(byte)0x30, (byte)0x11, (byte)0x06, (byte)0x03,
(byte)0x55, (byte)0x04, (byte)0x08, (byte)0x0c,
(byte)0x0a, (byte)0x57, (byte)0x61, (byte)0x73,
(byte)0x68, (byte)0x69, (byte)0x6e, (byte)0x67,
(byte)0x74, (byte)0x6f, (byte)0x6e, (byte)0x31,
(byte)0x10, (byte)0x30, (byte)0x0e, (byte)0x06,
(byte)0x03, (byte)0x55, (byte)0x04, (byte)0x07,
(byte)0x0c, (byte)0x07, (byte)0x53, (byte)0x65,
(byte)0x61, (byte)0x74, (byte)0x74, (byte)0x6c,
(byte)0x65, (byte)0x31, (byte)0x10, (byte)0x30,
(byte)0x0e, (byte)0x06, (byte)0x03, (byte)0x55,
(byte)0x04, (byte)0x0a, (byte)0x0c, (byte)0x07,
(byte)0x77, (byte)0x6f, (byte)0x6c, (byte)0x66,
(byte)0x53, (byte)0x53, (byte)0x4c, (byte)0x31,
(byte)0x14, (byte)0x30, (byte)0x12, (byte)0x06,
(byte)0x03, (byte)0x55, (byte)0x04, (byte)0x0b,
(byte)0x0c, (byte)0x0b, (byte)0x45, (byte)0x6e,
(byte)0x67, (byte)0x69, (byte)0x6e, (byte)0x65,
(byte)0x65, (byte)0x72, (byte)0x69, (byte)0x6e,
(byte)0x67, (byte)0x31, (byte)0x18, (byte)0x30,
(byte)0x16, (byte)0x06, (byte)0x03, (byte)0x55,
(byte)0x04, (byte)0x03, (byte)0x0c, (byte)0x0f,
(byte)0x77, (byte)0x6f, (byte)0x6c, (byte)0x66,
(byte)0x53, (byte)0x53, (byte)0x4c, (byte)0x20,
(byte)0x72, (byte)0x6f, (byte)0x6f, (byte)0x74,
(byte)0x20, (byte)0x43, (byte)0x41, (byte)0x31,
(byte)0x1f, (byte)0x30, (byte)0x1d, (byte)0x06,
(byte)0x09, (byte)0x2a, (byte)0x86, (byte)0x48,
(byte)0x86, (byte)0xf7, (byte)0x0d, (byte)0x01,
(byte)0x09, (byte)0x01, (byte)0x16, (byte)0x10,
(byte)0x69, (byte)0x6e, (byte)0x66, (byte)0x6f,
(byte)0x40, (byte)0x77, (byte)0x6f, (byte)0x6c,
(byte)0x66, (byte)0x73, (byte)0x73, (byte)0x6c,
(byte)0x2e, (byte)0x63, (byte)0x6f, (byte)0x6d,
(byte)0x82, (byte)0x01, (byte)0x63, (byte)0x30,
(byte)0x13, (byte)0x06, (byte)0x03, (byte)0x55,
(byte)0x1d, (byte)0x25, (byte)0x04, (byte)0x0c,
(byte)0x30, (byte)0x0a, (byte)0x06, (byte)0x08,
(byte)0x2b, (byte)0x06, (byte)0x01, (byte)0x05,
(byte)0x05, (byte)0x07, (byte)0x03, (byte)0x09,
(byte)0x30, (byte)0x0d, (byte)0x06, (byte)0x09,
(byte)0x2a, (byte)0x86, (byte)0x48, (byte)0x86,
(byte)0xf7, (byte)0x0d, (byte)0x01, (byte)0x01,
(byte)0x0b, (byte)0x05, (byte)0x00, (byte)0x03,
(byte)0x82, (byte)0x01, (byte)0x01, (byte)0x00,
(byte)0x22, (byte)0xcf, (byte)0xe2, (byte)0xc4,
(byte)0x3c, (byte)0x0e, (byte)0xcf, (byte)0x43,
(byte)0xc2, (byte)0x2b, (byte)0x77, (byte)0xd9,
(byte)0x53, (byte)0xbb, (byte)0xbf, (byte)0x46,
(byte)0x5a, (byte)0x67, (byte)0x26, (byte)0x1f,
(byte)0xd6, (byte)0x8c, (byte)0xe2, (byte)0xae,
(byte)0xd3, (byte)0x6b, (byte)0xda, (byte)0x7c,
(byte)0xa5, (byte)0xb4, (byte)0x79, (byte)0x29,
(byte)0x0f, (byte)0xb8, (byte)0xf0, (byte)0x14,
(byte)0x71, (byte)0x90, (byte)0x21, (byte)0x7c,
(byte)0x3c, (byte)0x23, (byte)0x2e, (byte)0x5b,
(byte)0xb6, (byte)0xb6, (byte)0x66, (byte)0xb5,
(byte)0xd2, (byte)0xfd, (byte)0x96, (byte)0x21,
(byte)0x4c, (byte)0x7c, (byte)0x9d, (byte)0x9f,
(byte)0x85, (byte)0x69, (byte)0x8c, (byte)0xd8,
(byte)0xc2, (byte)0xbf, (byte)0x3b, (byte)0x1f,
(byte)0x7b, (byte)0xaf, (byte)0x27, (byte)0xb9,
(byte)0x30, (byte)0x5b, (byte)0x51, (byte)0x4a,
(byte)0x16, (byte)0x07, (byte)0xa0, (byte)0x14,
(byte)0x80, (byte)0x47, (byte)0x31, (byte)0x45,
(byte)0xf0, (byte)0x31, (byte)0x35, (byte)0xb9,
(byte)0x93, (byte)0x39, (byte)0x77, (byte)0x32,
(byte)0x51, (byte)0xa0, (byte)0x8b, (byte)0x93,
(byte)0x91, (byte)0x96, (byte)0x77, (byte)0x41,
(byte)0x1a, (byte)0x30, (byte)0x15, (byte)0xb8,
(byte)0xe6, (byte)0xeb, (byte)0x49, (byte)0x8e,
(byte)0x3c, (byte)0xa5, (byte)0x11, (byte)0x46,
(byte)0x68, (byte)0x13, (byte)0xf5, (byte)0x61,
(byte)0x07, (byte)0xac, (byte)0x42, (byte)0x3e,
(byte)0x69, (byte)0xf3, (byte)0x9f, (byte)0x6b,
(byte)0x64, (byte)0xd5, (byte)0xe4, (byte)0x42,
(byte)0x1d, (byte)0xed, (byte)0x6c, (byte)0xb7,
(byte)0x3b, (byte)0xb1, (byte)0x78, (byte)0xc6,
(byte)0x9a, (byte)0xb0, (byte)0x38, (byte)0xe2,
(byte)0xe6, (byte)0xfe, (byte)0x5b, (byte)0xc3,
(byte)0x87, (byte)0x11, (byte)0x49, (byte)0x1e,
(byte)0x48, (byte)0x73, (byte)0x5a, (byte)0x88,
(byte)0x77, (byte)0x89, (byte)0xfb, (byte)0xc7,
(byte)0x87, (byte)0xef, (byte)0x87, (byte)0xe1,
(byte)0x17, (byte)0x8b, (byte)0x66, (byte)0x16,
(byte)0x44, (byte)0x7c, (byte)0x6e, (byte)0x5f,
(byte)0x2d, (byte)0x5a, (byte)0x2f, (byte)0xd0,
(byte)0xbe, (byte)0x76, (byte)0x69, (byte)0x84,
(byte)0xda, (byte)0x3c, (byte)0xa3, (byte)0x4f,
(byte)0xbf, (byte)0x00, (byte)0xff, (byte)0xcc,
(byte)0x67, (byte)0x06, (byte)0x16, (byte)0x40,
(byte)0x0f, (byte)0x75, (byte)0xdc, (byte)0xe3,
(byte)0x20, (byte)0xd6, (byte)0x7b, (byte)0x99,
(byte)0xc7, (byte)0xbf, (byte)0x38, (byte)0x21,
(byte)0x51, (byte)0x30, (byte)0x4a, (byte)0x4b,
(byte)0x77, (byte)0xd7, (byte)0x39, (byte)0xd3,
(byte)0xe2, (byte)0x4d, (byte)0x67, (byte)0x68,
(byte)0x0e, (byte)0x7c, (byte)0x95, (byte)0xc4,
(byte)0x51, (byte)0x22, (byte)0xc4, (byte)0x0f,
(byte)0x74, (byte)0xa5, (byte)0xdd, (byte)0xf5,
(byte)0xac, (byte)0xa8, (byte)0xf5, (byte)0x8c,
(byte)0xfb, (byte)0x90, (byte)0xba, (byte)0xff,
(byte)0x5e, (byte)0x3e, (byte)0x1f, (byte)0xaa,
(byte)0x7d, (byte)0x61, (byte)0xbb, (byte)0xa4,
(byte)0x22, (byte)0x35, (byte)0x16, (byte)0x64,
(byte)0xfc, (byte)0x42, (byte)0x27, (byte)0x0b,
(byte)0xc9, (byte)0xe3, (byte)0xba, (byte)0x21,
(byte)0xad, (byte)0x7b, (byte)0x24, (byte)0x2a,
(byte)0xa5, (byte)0x25, (byte)0xb7, (byte)0xc4
};
@BeforeClass
public static void loadLibrary() throws WolfSSLException {
System.out.println("WolfSSLCertManager Class");
try {
WolfSSL.loadLibrary();
} catch (UnsatisfiedLinkError ule) {
fail("failed to load native JNI library");
}
ocspRootCaCert = WolfSSLTestCommon.getPath(ocspRootCaCert);
ocspIntermediate1Cert =
WolfSSLTestCommon.getPath(ocspIntermediate1Cert);
serverCert = WolfSSLTestCommon.getPath(serverCert);
}
@Test
public void testCertManagerCheckOCSPResponse()
throws Exception {
int ret = 0;
byte[] caCertPem = null;
byte[] caCertDer = null;
byte[] certToCheckDer = null;
byte[] wrongCertDer = null;
WolfSSLCertManager cm = null;
WolfSSLCertificate cert = null;
System.out.print("\tOCSP response for cert validation");
try {
cm = new WolfSSLCertManager();
/* Load the wolfSSL OCSP root CA so we can verify the OCSP
* responder certificate chain embedded in the response. */
caCertPem = Files.readAllBytes(new File(ocspRootCaCert).toPath());
ret = cm.CertManagerLoadCABuffer(
caCertPem, caCertPem.length, WolfSSL.SSL_FILETYPE_PEM);
if (ret != WolfSSL.SSL_SUCCESS) {
System.out.println("\t... failed");
fail("Failed to load OCSP root CA, ret = " + ret);
}
/* Load the CA cert as DER for passing to OCSP check */
cert = new WolfSSLCertificate(ocspRootCaCert,
WolfSSL.SSL_FILETYPE_PEM);
caCertDer = cert.getDer();
cert.free();
/* Load the certificate that matches the OCSP response
* (intermediate1-ca-cert.pem, serial 01) as DER. */
cert = new WolfSSLCertificate(ocspIntermediate1Cert,
WolfSSL.SSL_FILETYPE_PEM);
certToCheckDer = cert.getDer();
cert.free();
/* Test with valid OCSP response and matching certificate.
* Should succeed since the OCSP response is for this cert. */
ret = cm.CertManagerCheckOCSPResponse(
validOcspResponse, certToCheckDer, caCertDer);
if (ret != WolfSSL.SSL_SUCCESS) {
System.out.println("\t... failed");
fail("CertManagerCheckOCSPResponse failed with valid " +
"OCSP and matching cert, ret = " + ret);
}
/* Load a different cert that does NOT match the OCSP response
* (server-cert.pem has different serial number) as DER. */
cert = new WolfSSLCertificate(serverCert,
WolfSSL.SSL_FILETYPE_PEM);
wrongCertDer = cert.getDer();
cert.free();
/* Test with valid OCSP response but mismatched certificate.
* Should fail since the OCSP response is not for server-cert. */
ret = cm.CertManagerCheckOCSPResponse(
validOcspResponse, wrongCertDer, null);
if (ret == WolfSSL.SSL_SUCCESS) {
System.out.println("\t... failed");
fail("CertManagerCheckOCSPResponse should have failed " +
"with mismatched certificate, but returned success");
}
/* Test with null certificate - should throw
* IllegalArgumentException from Java wrapper. */
try {
cm.CertManagerCheckOCSPResponse(
validOcspResponse, null, null);
System.out.println("\t... failed");
fail("Expected IllegalArgumentException for null cert");
} catch (IllegalArgumentException e) {
/* Expected */
}
} catch (WolfSSLException e) {
if (e.getMessage() != null &&
e.getMessage().contains("not compiled")) {
/* OCSP not compiled in, skip test */
System.out.println("\t... skipped (OCSP not compiled in)");
return;
}
System.out.println("\t... failed");
fail("CertManagerCheckOCSPResponse test failed: " +
e.getMessage());
} catch (Exception e) {
System.out.println("\t... failed");
fail("CertManagerCheckOCSPResponse test failed: " +
e.getMessage());
} finally {
if (cm != null) {
cm.free();
cm = null;
}
}
System.out.println("\t... passed");
}
}

View File

@ -32,7 +32,8 @@ import org.junit.runners.Suite;
WolfCryptRSATest.class,
WolfCryptECCTest.class,
WolfSSLCertificateTest.class,
WolfSSLCertRequestTest.class
WolfSSLCertRequestTest.class,
WolfSSLCertManagerTest.class
})