Compare commits

...

32 Commits

Author SHA1 Message Date
toddouska
02079a2f79 c++ cast fix 2012-05-25 13:38:44 -07:00
toddouska
82a56daaaf ecc crls 2012-05-25 13:26:28 -07:00
toddouska
a1bb4e3f93 gcc-lots-o-warnings fixes 2012-05-25 13:09:27 -07:00
toddouska
6a62623c64 verify suite validity before server picks 2012-05-25 12:18:18 -07:00
toddouska
7332b4843c remove hard tabs, bad sublime setting 2012-05-24 20:10:38 -07:00
toddouska
3f35c86520 crl signature check, be sure to load CAs first 2012-05-24 15:49:38 -07:00
John Safranek
0a31dc3a37 renumbered new error codes and dynamic data types 2012-05-24 14:36:40 -07:00
John Safranek
e8e575fd58 public OCSP functions are available, just return errors when OCSP not compiled in 2012-05-24 14:12:28 -07:00
toddouska
baddc07300 check next crl date status 2012-05-24 14:07:59 -07:00
John Safranek
f2110487b6 added dynamic types for OCSP data 2012-05-24 14:07:11 -07:00
toddouska
73ddd32539 add crl checkall processing 2012-05-24 12:45:10 -07:00
toddouska
db7773aa54 linux crl dir monitoring fixes 2012-05-23 16:55:26 -07:00
toddouska
0aea2607b5 don't install example certs and keys 2012-05-23 10:28:02 -07:00
toddouska
2b48f248c4 crl dir monitoring for linux and mac 2012-05-22 17:25:15 -07:00
John Safranek
97042d8661 OCSP use URL from cert as appropriate 2012-05-22 15:54:27 -07:00
John Safranek
708f38ac8d added OCSP error codes 2012-05-22 15:52:08 -07:00
John Safranek
09e24d5469 OCSP set option bug fix 2012-05-22 15:38:12 -07:00
John Safranek
e48f5a31d6 Merge branch 'master' of github.com:cyassl/cyassl 2012-05-21 14:21:34 -07:00
Chris Conlon
4c79ac1f88 windows build fix 2012-05-21 15:13:11 -06:00
John Safranek
2ed143bee0 Merge branch 'master' of github.com:cyassl/cyassl 2012-05-20 14:53:07 -07:00
toddouska
2b6044c6ee add dump file option to snifftest, along with keyfile, optional server and port arguments 2012-05-20 12:46:50 -07:00
toddouska
ba6d956d02 fix sniffer resumption for new sessionId flag in 2.2.0 2012-05-19 14:37:26 -07:00
John Safranek
387d9400b9 Merge branch 'master' of github.com:cyassl/cyassl 2012-05-18 17:06:09 -07:00
toddouska
5b5b7e231d fix crl dist and dev build 2012-05-18 16:35:19 -07:00
toddouska
86408406fd add metatdata to crls 2012-05-18 16:29:57 -07:00
toddouska
3d67caa353 normal crl doesn't revoke test certs, crl.revoked revokes test server 2012-05-18 16:24:23 -07:00
toddouska
ecef0e38d5 fix configure sha-512 message 2012-05-18 16:18:53 -07:00
toddouska
ddb5c3a2aa crl potential memory leak fix 2012-05-18 16:01:21 -07:00
John Safranek
8bf2d13f89 Merge branch 'master' of github.com:cyassl/cyassl 2012-05-18 15:33:54 -07:00
John Safranek
a3e94f335b fixed merge conflict 2012-05-18 10:25:16 -07:00
John Safranek
4b3a362705 adding OcspRequest data, check OCSP nonce extension, made ConfirmSignature generic, bug fixes 2012-05-18 10:18:56 -07:00
John Safranek
a697a60bfd fixed a bounds check error 2012-05-18 10:06:06 -07:00
26 changed files with 1580 additions and 522 deletions

View File

@@ -21,10 +21,6 @@ exampledir = $(docdir)/@PACKAGE@/example
example_DATA=
EXTRA_DIST+= $(example_DATA)
certsdir = $(sysconfdir)/ssl/certs
certs_DATA=
EXTRA_DIST+= $(certs_DATA)
EXTRA_DIST+= $(doc_DATA)
ACLOCAL_AMFLAGS= -I m4 --install

39
certs/crl/cliCrl.pem Normal file
View File

@@ -0,0 +1,39 @@
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: /C=US/ST=Oregon/L=Portland/O=yaSSL/OU=Programming/CN=www.yassl.com/emailAddress=info@yassl.com
Last Update: May 18 17:37:23 2012 GMT
Next Update: Jun 17 17:37:23 2012 GMT
CRL extensions:
X509v3 CRL Number:
1
No Revoked Certificates.
Signature Algorithm: sha1WithRSAEncryption
6b:d7:b2:9e:21:8a:04:e7:43:68:46:a7:36:eb:4e:6e:23:91:
f9:e9:1f:f1:7f:48:79:64:cd:ea:86:1c:36:63:f8:aa:8c:b3:
62:34:bb:18:28:5a:42:f7:8a:64:3e:7f:36:05:49:a2:29:38:
71:e8:54:da:87:05:53:55:c3:0b:ae:10:0a:f0:5d:f0:6e:5c:
26:8b:55:4f:8f:d2:08:41:42:21:8d:b7:f1:6d:22:d1:a0:04:
9e:67:cb:43:51:55:e6:00:41:d0:cd:82:e8:03:42:29:88:49:
e1:f4:8d:1e:e5:ad:18:8b:3a:60:aa:dc:47:33:9d:ce:79:41:
0c:81:a9:cc:a7:a4:d9:07:3a:eb:df:41:34:ca:a6:b9:93:47:
72:1d:c4:71:71:69:4b:4b:74:e4:2c:ff:91:f3:47:77:de:da:
05:ab:de:05:57:6a:89:d6:f8:b2:f7:69:9b:a6:c6:e9:cd:c3:
60:4a:79:66:62:3b:a1:f2:e2:44:9b:f2:31:44:94:46:f0:96:
ab:b5:04:97:6b:09:82:64:8b:68:b0:73:46:ae:25:fa:33:ca:
f4:ce:cb:35:7e:e2:23:a1:df:5f:70:40:b5:1d:cd:dd:b0:ff:
20:6a:23:a1:ed:95:11:16:69:a0:ca:7e:90:c3:ed:be:5e:56:
0a:da:04:e3
-----BEGIN X509 CRL-----
MIIB6DCB0QIBATANBgkqhkiG9w0BAQUFADCBjjELMAkGA1UEBhMCVVMxDzANBgNV
BAgTBk9yZWdvbjERMA8GA1UEBxMIUG9ydGxhbmQxDjAMBgNVBAoTBXlhU1NMMRQw
EgYDVQQLEwtQcm9ncmFtbWluZzEWMBQGA1UEAxMNd3d3Lnlhc3NsLmNvbTEdMBsG
CSqGSIb3DQEJARYOaW5mb0B5YXNzbC5jb20XDTEyMDUxODE3MzcyM1oXDTEyMDYx
NzE3MzcyM1qgDjAMMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBBQUAA4IBAQBr17Ke
IYoE50NoRqc2605uI5H56R/xf0h5ZM3qhhw2Y/iqjLNiNLsYKFpC94pkPn82BUmi
KThx6FTahwVTVcMLrhAK8F3wblwmi1VPj9IIQUIhjbfxbSLRoASeZ8tDUVXmAEHQ
zYLoA0IpiEnh9I0e5a0YizpgqtxHM53OeUEMganMp6TZBzrr30E0yqa5k0dyHcRx
cWlLS3TkLP+R80d33toFq94FV2qJ1viy92mbpsbpzcNgSnlmYjuh8uJEm/IxRJRG
8JartQSXawmCZItosHNGriX6M8r0zss1fuIjod9fcEC1Hc3dsP8gaiOh7ZURFmmg
yn6Qw+2+XlYK2gTj
-----END X509 CRL-----

View File

@@ -2,40 +2,38 @@ Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: /C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.yassl.com/emailAddress=info@yassl.com
Last Update: May 15 23:51:25 2012 GMT
Next Update: Jun 14 23:51:25 2012 GMT
Last Update: May 18 23:22:13 2012 GMT
Next Update: Jun 17 23:22:13 2012 GMT
CRL extensions:
X509v3 CRL Number:
4
Revoked Certificates:
Serial Number: 02
Revocation Date: May 4 17:06:05 2012 GMT
5
No Revoked Certificates.
Signature Algorithm: sha1WithRSAEncryption
aa:e4:44:9b:6b:c9:0b:d3:6f:ba:09:3d:90:93:ae:96:86:73:
f6:90:28:ba:93:3b:95:0c:91:c9:10:53:f1:15:fd:43:9a:ba:
4e:dc:8e:e8:10:4d:d8:8b:be:a8:a2:12:4c:19:c1:13:9f:3c:
fe:54:60:32:b7:45:77:17:2a:40:f2:16:52:9e:68:fe:be:03:
99:9c:b1:d3:4b:be:87:5b:f4:12:3c:9e:3d:59:c8:b9:a2:2c:
78:94:9c:cd:b0:17:d0:b3:bd:86:99:2b:1d:38:b5:03:d8:d1:
0d:8f:1a:8c:97:ff:87:01:4f:91:22:30:c2:a5:10:bb:e3:fb:
31:b7:44:8a:5a:82:e1:e5:30:69:84:d1:4b:c2:d3:07:bf:21:
d5:33:2d:ad:4b:e4:6f:83:c1:66:16:74:31:7d:f9:d6:1e:10:
66:fd:7d:ad:66:3c:32:cc:a3:98:75:63:16:5c:df:e1:37:3d:
e9:08:d2:7b:05:dd:4c:31:92:53:0c:f1:ea:8e:be:31:d1:eb:
ac:37:a8:cd:c4:30:c5:91:cc:38:a3:55:4a:51:01:39:cf:7d:
50:57:d2:f2:47:4a:1d:7f:3a:32:16:89:e8:5a:1b:f8:64:33:
48:e5:b8:ef:ba:2e:f3:52:7e:ba:28:0e:9b:f7:07:b8:b6:38:
f9:d0:dd:78
aa:c2:16:c6:7c:cf:4e:ee:f4:44:af:cf:66:ce:b9:af:89:1b:
83:e4:0b:cf:67:68:95:32:9f:ee:80:60:1e:93:82:4c:c6:d3:
93:90:c7:cd:7c:31:90:d0:f3:4f:4a:db:d2:ad:99:d5:38:fb:
ba:a6:3d:52:79:ce:6c:15:e5:dc:c0:57:43:f8:56:13:39:b9:
c1:af:e3:a3:fb:79:18:82:e7:b6:99:5a:4f:5f:88:b8:9e:5c:
54:ef:87:06:a7:bb:c7:64:08:b0:9a:32:f7:12:88:b7:f2:af:
35:5c:10:89:43:52:36:4e:90:55:25:c7:0e:5d:13:45:73:b5:
22:79:9f:62:b7:15:a6:2f:9a:02:a6:95:fc:a5:1d:bb:e3:c1:
fc:6a:49:db:21:fb:d5:19:68:9c:bc:08:af:bf:4f:58:87:bc:
34:fb:46:7a:60:e4:5c:8f:cf:da:a9:23:ab:f5:e1:e8:18:41:
fb:d0:5d:2d:b1:8c:80:1b:67:0f:eb:77:7d:53:39:9b:f4:e7:
a9:49:ff:94:39:8f:e4:5e:4b:a9:46:62:b6:17:28:1d:8f:30:
1c:19:5e:99:d3:4f:56:0d:5a:73:03:52:45:f4:5f:0d:af:e1:
dd:e1:f3:6f:6b:d9:94:48:4d:7e:6e:9d:f2:98:57:2c:03:56:
cb:5a:b5:3a
-----BEGIN X509 CRL-----
MIICADCB6QIBATANBgkqhkiG9w0BAQUFADCBkDELMAkGA1UEBhMCVVMxEDAOBgNV
MIIB6jCB0wIBATANBgkqhkiG9w0BAQUFADCBkDELMAkGA1UEBhMCVVMxEDAOBgNV
BAgTB01vbnRhbmExEDAOBgNVBAcTB0JvemVtYW4xETAPBgNVBAoTCFNhd3Rvb3Ro
MRMwEQYDVQQLEwpDb25zdWx0aW5nMRYwFAYDVQQDEw13d3cueWFzc2wuY29tMR0w
GwYJKoZIhvcNAQkBFg5pbmZvQHlhc3NsLmNvbRcNMTIwNTE1MjM1MTI1WhcNMTIw
NjE0MjM1MTI1WjAUMBICAQIXDTEyMDUwNDE3MDYwNVqgDjAMMAoGA1UdFAQDAgEE
MA0GCSqGSIb3DQEBBQUAA4IBAQCq5ESba8kL02+6CT2Qk66WhnP2kCi6kzuVDJHJ
EFPxFf1DmrpO3I7oEE3Yi76oohJMGcETnzz+VGAyt0V3FypA8hZSnmj+vgOZnLHT
S76HW/QSPJ49Wci5oix4lJzNsBfQs72GmSsdOLUD2NENjxqMl/+HAU+RIjDCpRC7
4/sxt0SKWoLh5TBphNFLwtMHvyHVMy2tS+Rvg8FmFnQxffnWHhBm/X2tZjwyzKOY
dWMWXN/hNz3pCNJ7Bd1MMZJTDPHqjr4x0eusN6jNxDDFkcw4o1VKUQE5z31QV9Ly
R0odfzoyFonoWhv4ZDNI5bjvui7zUn66KA6b9we4tjj50N14
GwYJKoZIhvcNAQkBFg5pbmZvQHlhc3NsLmNvbRcNMTIwNTE4MjMyMjEzWhcNMTIw
NjE3MjMyMjEzWqAOMAwwCgYDVR0UBAMCAQUwDQYJKoZIhvcNAQEFBQADggEBAKrC
FsZ8z07u9ESvz2bOua+JG4PkC89naJUyn+6AYB6TgkzG05OQx818MZDQ809K29Kt
mdU4+7qmPVJ5zmwV5dzAV0P4VhM5ucGv46P7eRiC57aZWk9fiLieXFTvhwanu8dk
CLCaMvcSiLfyrzVcEIlDUjZOkFUlxw5dE0VztSJ5n2K3FaYvmgKmlfylHbvjwfxq
Sdsh+9UZaJy8CK+/T1iHvDT7Rnpg5FyPz9qpI6v14egYQfvQXS2xjIAbZw/rd31T
OZv056lJ/5Q5j+ReS6lGYrYXKB2PMBwZXpnTT1YNWnMDUkX0Xw2v4d3h829r2ZRI
TX5unfKYVywDVstatTo=
-----END X509 CRL-----

41
certs/crl/crl.revoked Normal file
View File

@@ -0,0 +1,41 @@
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha1WithRSAEncryption
Issuer: /C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.yassl.com/emailAddress=info@yassl.com
Last Update: May 15 23:51:25 2012 GMT
Next Update: Jun 14 23:51:25 2012 GMT
CRL extensions:
X509v3 CRL Number:
4
Revoked Certificates:
Serial Number: 02
Revocation Date: May 4 17:06:05 2012 GMT
Signature Algorithm: sha1WithRSAEncryption
aa:e4:44:9b:6b:c9:0b:d3:6f:ba:09:3d:90:93:ae:96:86:73:
f6:90:28:ba:93:3b:95:0c:91:c9:10:53:f1:15:fd:43:9a:ba:
4e:dc:8e:e8:10:4d:d8:8b:be:a8:a2:12:4c:19:c1:13:9f:3c:
fe:54:60:32:b7:45:77:17:2a:40:f2:16:52:9e:68:fe:be:03:
99:9c:b1:d3:4b:be:87:5b:f4:12:3c:9e:3d:59:c8:b9:a2:2c:
78:94:9c:cd:b0:17:d0:b3:bd:86:99:2b:1d:38:b5:03:d8:d1:
0d:8f:1a:8c:97:ff:87:01:4f:91:22:30:c2:a5:10:bb:e3:fb:
31:b7:44:8a:5a:82:e1:e5:30:69:84:d1:4b:c2:d3:07:bf:21:
d5:33:2d:ad:4b:e4:6f:83:c1:66:16:74:31:7d:f9:d6:1e:10:
66:fd:7d:ad:66:3c:32:cc:a3:98:75:63:16:5c:df:e1:37:3d:
e9:08:d2:7b:05:dd:4c:31:92:53:0c:f1:ea:8e:be:31:d1:eb:
ac:37:a8:cd:c4:30:c5:91:cc:38:a3:55:4a:51:01:39:cf:7d:
50:57:d2:f2:47:4a:1d:7f:3a:32:16:89:e8:5a:1b:f8:64:33:
48:e5:b8:ef:ba:2e:f3:52:7e:ba:28:0e:9b:f7:07:b8:b6:38:
f9:d0:dd:78
-----BEGIN X509 CRL-----
MIICADCB6QIBATANBgkqhkiG9w0BAQUFADCBkDELMAkGA1UEBhMCVVMxEDAOBgNV
BAgTB01vbnRhbmExEDAOBgNVBAcTB0JvemVtYW4xETAPBgNVBAoTCFNhd3Rvb3Ro
MRMwEQYDVQQLEwpDb25zdWx0aW5nMRYwFAYDVQQDEw13d3cueWFzc2wuY29tMR0w
GwYJKoZIhvcNAQkBFg5pbmZvQHlhc3NsLmNvbRcNMTIwNTE1MjM1MTI1WhcNMTIw
NjE0MjM1MTI1WjAUMBICAQIXDTEyMDUwNDE3MDYwNVqgDjAMMAoGA1UdFAQDAgEE
MA0GCSqGSIb3DQEBBQUAA4IBAQCq5ESba8kL02+6CT2Qk66WhnP2kCi6kzuVDJHJ
EFPxFf1DmrpO3I7oEE3Yi76oohJMGcETnzz+VGAyt0V3FypA8hZSnmj+vgOZnLHT
S76HW/QSPJ49Wci5oix4lJzNsBfQs72GmSsdOLUD2NENjxqMl/+HAU+RIjDCpRC7
4/sxt0SKWoLh5TBphNFLwtMHvyHVMy2tS+Rvg8FmFnQxffnWHhBm/X2tZjwyzKOY
dWMWXN/hNz3pCNJ7Bd1MMZJTDPHqjr4x0eusN6jNxDDFkcw4o1VKUQE5z31QV9Ly
R0odfzoyFonoWhv4ZDNI5bjvui7zUn66KA6b9we4tjj50N14
-----END X509 CRL-----

24
certs/crl/eccCliCRL.pem Normal file
View File

@@ -0,0 +1,24 @@
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: ecdsa-with-SHA1
Issuer: /C=US/ST=Oregon/L=Salem/O=Client ECC/OU=Fast/CN=www.yassl.com/emailAddress=info@yassl.com
Last Update: May 25 20:21:43 2012 GMT
Next Update: Jun 24 20:21:43 2012 GMT
CRL extensions:
X509v3 CRL Number:
1
No Revoked Certificates.
Signature Algorithm: ecdsa-with-SHA1
30:45:02:21:00:c8:82:17:00:62:02:ae:73:f8:80:57:3d:19:
df:f3:36:5a:4c:12:89:d5:d6:b4:aa:29:b6:c8:7d:f2:1d:2f:
55:02:20:18:f4:ad:18:1a:c5:df:39:81:ad:0d:3e:45:14:3d:
07:44:31:21:bd:ed:13:32:7b:32:03:41:a1:0f:fd:1a:67
-----BEGIN X509 CRL-----
MIIBIDCByAIBATAJBgcqhkjOPQQBMIGJMQswCQYDVQQGEwJVUzEPMA0GA1UECBMG
T3JlZ29uMQ4wDAYDVQQHEwVTYWxlbTETMBEGA1UEChMKQ2xpZW50IEVDQzENMAsG
A1UECxMERmFzdDEWMBQGA1UEAxMNd3d3Lnlhc3NsLmNvbTEdMBsGCSqGSIb3DQEJ
ARYOaW5mb0B5YXNzbC5jb20XDTEyMDUyNTIwMjE0M1oXDTEyMDYyNDIwMjE0M1qg
DjAMMAoGA1UdFAQDAgEBMAkGByqGSM49BAEDSAAwRQIhAMiCFwBiAq5z+IBXPRnf
8zZaTBKJ1da0qim2yH3yHS9VAiAY9K0YGsXfOYGtDT5FFD0HRDEhve0TMnsyA0Gh
D/0aZw==
-----END X509 CRL-----

24
certs/crl/eccSrvCRL.pem Normal file
View File

@@ -0,0 +1,24 @@
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: ecdsa-with-SHA1
Issuer: /C=US/ST=Washington/L=Seattle/O=Eliptic/OU=ECC/CN=www.yassl.com/emailAddress=info@yassl.com
Last Update: May 25 20:15:31 2012 GMT
Next Update: Jun 24 20:15:31 2012 GMT
CRL extensions:
X509v3 CRL Number:
1
No Revoked Certificates.
Signature Algorithm: ecdsa-with-SHA1
30:46:02:21:00:d3:e3:d6:58:f7:92:c6:93:e3:c2:b9:81:dd:
b2:3f:e8:c9:4d:61:b1:ed:25:d2:1d:49:da:bd:15:ab:c7:21:
9f:02:21:00:e6:8f:20:2a:10:e7:85:26:6b:31:6e:c4:c2:08:
b5:c3:fa:d0:fa:ca:34:8c:2a:85:6c:18:94:84:18:46:96:a7
-----BEGIN X509 CRL-----
MIIBIzCBygIBATAJBgcqhkjOPQQBMIGLMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
V2FzaGluZ3RvbjEQMA4GA1UEBxMHU2VhdHRsZTEQMA4GA1UEChMHRWxpcHRpYzEM
MAoGA1UECxMDRUNDMRYwFAYDVQQDEw13d3cueWFzc2wuY29tMR0wGwYJKoZIhvcN
AQkBFg5pbmZvQHlhc3NsLmNvbRcNMTIwNTI1MjAxNTMxWhcNMTIwNjI0MjAxNTMx
WqAOMAwwCgYDVR0UBAMCAQEwCQYHKoZIzj0EAQNJADBGAiEA0+PWWPeSxpPjwrmB
3bI/6MlNYbHtJdIdSdq9FavHIZ8CIQDmjyAqEOeFJmsxbsTCCLXD+tD6yjSMKoVs
GJSEGEaWpw==
-----END X509 CRL-----

View File

@@ -2,8 +2,13 @@
# All paths should be given relative to the root
#
certs_DATA+= \
certs/crl/crl.pem
EXTRA_DIST += \
certs/crl/crl.pem \
certs/crl/cliCrl.pem \
certs/crl/eccSrvCRL.pem \
certs/crl/eccCliCRL.pem
EXTRA_DIST += \
certs/crl/crl.revoked
EXTRA_DIST+= ${certs_DATA}

View File

@@ -2,7 +2,7 @@
# All paths should be given relative to the root
#
certs_DATA+= \
EXTRA_DIST += \
certs/ca-cert.pem \
certs/ca-key.pem \
certs/client-cert.pem \
@@ -23,7 +23,7 @@ certs_DATA+= \
certs/server-keyPkcs8Enc.pem \
certs/server-keyPkcs8.pem
certs_DATA+= \
EXTRA_DIST += \
certs/ca-key.der \
certs/client-cert.der \
certs/client-key.der \
@@ -32,7 +32,6 @@ certs_DATA+= \
certs/dsa2048.der \
certs/ecc-key.der
EXTRA_DIST+= ${certs_DATA}
doc_DATA+= certs/taoCert.txt

View File

@@ -6,7 +6,7 @@
#
#
AC_INIT([cyassl],[2.2.0],[http://www.yassl.com])
AC_INIT([cyassl],[2.2.2],[http://www.yassl.com])
AC_CONFIG_AUX_DIR(config)
@@ -326,7 +326,7 @@ AM_CONDITIONAL([BUILD_RIPEMD], [test "x$ENABLED_RIPEMD" = "xyes"])
# SHA512
AC_ARG_ENABLE(sha512,
[ --enable-sha512 Enable CyaSSL SHA-160 support (default: disabled)],
[ --enable-sha512 Enable CyaSSL SHA-512 support (default: disabled)],
[ ENABLED_SHA512=$enableval ],
[ ENABLED_SHA512=no ]
)
@@ -500,7 +500,7 @@ AC_ARG_ENABLE(crl,
if test "$ENABLED_CRL" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DHAVE_CRL"
AM_CFLAGS="$AM_CFLAGS -DHAVE_CRL -DHAVE_CRL_MONITOR"
fi
AM_CONDITIONAL([BUILD_CRL], [test "x$ENABLED_CRL" = "xyes"])

View File

@@ -38,6 +38,7 @@
#include <cyassl/ctaocrypt/sha256.h>
#include <cyassl/ctaocrypt/sha512.h>
#include <cyassl/ctaocrypt/logging.h>
#include <cyassl/ctaocrypt/random.h>
#ifdef HAVE_NTRU
#include "crypto_ntru.h"
@@ -1537,7 +1538,7 @@ static INLINE int DateLessThan(const struct tm* a, const struct tm* b)
/* like atoi but only use first byte */
/* Make sure before and after dates are valid */
static int ValidateDate(const byte* date, byte format, int dateType)
int ValidateDate(const byte* date, byte format, int dateType)
{
time_t ltime;
struct tm certTime;
@@ -1912,8 +1913,10 @@ word32 EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID)
/* return true (1) for Confirmation */
static int ConfirmSignature(DecodedCert* cert, const byte* key, word32 keySz,
word32 keyOID)
static int ConfirmSignature(const byte* buf, word32 bufSz,
const byte* key, word32 keySz, word32 keyOID,
const byte* sig, word32 sigSz, word32 sigOID,
void* heap)
{
#ifdef CYASSL_SHA512
byte digest[SHA512_DIGEST_SIZE]; /* max size */
@@ -1924,57 +1927,52 @@ static int ConfirmSignature(DecodedCert* cert, const byte* key, word32 keySz,
#endif
int typeH, digestSz, ret;
if (cert->signatureOID == CTC_MD5wRSA) {
if (sigOID == CTC_MD5wRSA) {
Md5 md5;
InitMd5(&md5);
Md5Update(&md5, cert->source + cert->certBegin,
cert->sigIndex - cert->certBegin);
Md5Update(&md5, buf, bufSz);
Md5Final(&md5, digest);
typeH = MD5h;
digestSz = MD5_DIGEST_SIZE;
}
else if (cert->signatureOID == CTC_SHAwRSA ||
cert->signatureOID == CTC_SHAwDSA ||
cert->signatureOID == CTC_SHAwECDSA) {
else if (sigOID == CTC_SHAwRSA ||
sigOID == CTC_SHAwDSA ||
sigOID == CTC_SHAwECDSA) {
Sha sha;
InitSha(&sha);
ShaUpdate(&sha, cert->source + cert->certBegin,
cert->sigIndex - cert->certBegin);
ShaUpdate(&sha, buf, bufSz);
ShaFinal(&sha, digest);
typeH = SHAh;
digestSz = SHA_DIGEST_SIZE;
}
#ifndef NO_SHA256
else if (cert->signatureOID == CTC_SHA256wRSA ||
cert->signatureOID == CTC_SHA256wECDSA) {
else if (sigOID == CTC_SHA256wRSA ||
sigOID == CTC_SHA256wECDSA) {
Sha256 sha256;
InitSha256(&sha256);
Sha256Update(&sha256, cert->source + cert->certBegin,
cert->sigIndex - cert->certBegin);
Sha256Update(&sha256, buf, bufSz);
Sha256Final(&sha256, digest);
typeH = SHA256h;
digestSz = SHA256_DIGEST_SIZE;
}
#endif
#ifdef CYASSL_SHA512
else if (cert->signatureOID == CTC_SHA512wRSA ||
cert->signatureOID == CTC_SHA512wECDSA) {
else if (sigOID == CTC_SHA512wRSA ||
sigOID == CTC_SHA512wECDSA) {
Sha512 sha512;
InitSha512(&sha512);
Sha512Update(&sha512, cert->source + cert->certBegin,
cert->sigIndex - cert->certBegin);
Sha512Update(&sha512, buf, bufSz);
Sha512Final(&sha512, digest);
typeH = SHA512h;
digestSz = SHA512_DIGEST_SIZE;
}
#endif
#ifdef CYASSL_SHA384
else if (cert->signatureOID == CTC_SHA384wRSA ||
cert->signatureOID == CTC_SHA384wECDSA) {
else if (sigOID == CTC_SHA384wRSA ||
sigOID == CTC_SHA384wECDSA) {
Sha384 sha384;
InitSha384(&sha384);
Sha384Update(&sha384, cert->source + cert->certBegin,
cert->sigIndex - cert->certBegin);
Sha384Update(&sha384, buf, bufSz);
Sha384Final(&sha384, digest);
typeH = SHA384h;
digestSz = SHA384_DIGEST_SIZE;
@@ -1990,30 +1988,32 @@ static int ConfirmSignature(DecodedCert* cert, const byte* key, word32 keySz,
byte encodedSig[MAX_ENCODED_SIG_SZ];
byte plain[MAX_ENCODED_SIG_SZ];
word32 idx = 0;
int sigSz, verifySz;
int encodedSigSz, verifySz;
byte* out;
if (cert->sigLength > MAX_ENCODED_SIG_SZ) {
if (sigSz > MAX_ENCODED_SIG_SZ) {
CYASSL_MSG("Verify Signautre is too big");
return 0;
}
InitRsaKey(&pubKey, cert->heap);
InitRsaKey(&pubKey, heap);
if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0) {
CYASSL_MSG("ASN Key decode error RSA");
ret = 0;
}
else {
XMEMCPY(plain, cert->signature, cert->sigLength);
if ( (verifySz = RsaSSL_VerifyInline(plain, cert->sigLength, &out,
XMEMCPY(plain, sig, sigSz);
if ( (verifySz = RsaSSL_VerifyInline(plain, sigSz, &out,
&pubKey)) < 0) {
CYASSL_MSG("Rsa SSL verify error");
ret = 0;
}
else {
/* make sure we're right justified */
sigSz = EncodeSignature(encodedSig, digest, digestSz, typeH);
if (sigSz != verifySz || XMEMCMP(out, encodedSig, sigSz) != 0){
encodedSigSz =
EncodeSignature(encodedSig, digest, digestSz, typeH);
if (encodedSigSz != verifySz ||
XMEMCMP(out, encodedSig, encodedSigSz) != 0) {
CYASSL_MSG("Rsa SSL verify match encode error");
ret = 0;
}
@@ -2054,8 +2054,7 @@ static int ConfirmSignature(DecodedCert* cert, const byte* key, word32 keySz,
return 0;
}
ret = ecc_verify_hash(cert->signature, cert->sigLength, digest,
digestSz, &verify, &pubKey);
ret = ecc_verify_hash(sig, sigSz, digest, digestSz, &verify, &pubKey);
ecc_free(&pubKey);
if (ret == 0 && verify == 1)
return 1; /* match */
@@ -2237,7 +2236,7 @@ static void DecodeCertExtensions(DecodedCert* cert)
if (input == NULL || sz == 0) return;
if (input[idx++] != ASN_EXTENSIONS)return;
if (input[idx++] != ASN_EXTENSIONS) return;
if (GetLength(input, &idx, &length, sz) < 0) return;
@@ -2390,8 +2389,11 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm)
}
#endif /* HAVE_OCSP */
/* try to confirm/verify signature */
if (!ConfirmSignature(cert, ca->publicKey,
ca->pubKeySize, ca->keyOID)) {
if (!ConfirmSignature(cert->source + cert->certBegin,
cert->sigIndex - cert->certBegin,
ca->publicKey, ca->pubKeySize, ca->keyOID,
cert->signature, cert->sigLength, cert->signatureOID,
cert->heap)) {
CYASSL_MSG("Confirm signature failed");
return ASN_SIG_CONFIRM_E;
}
@@ -4103,165 +4105,230 @@ static int GetEnumerated(const byte* input, word32* inOutIdx, int *value)
static int DecodeSingleResponse(byte* source,
word32* ioIndex, OcspResponse* resp, word32 size)
{
word32 index = *ioIndex, prevIndex, oid, mpi_len;
word32 idx = *ioIndex, prevIndex, oid;
int length, remainder, qty = 0;
mp_int mpi;
byte serialTmp[EXTERNAL_SERIAL_SIZE];
/* Outer wrapper of the SEQUENCE OF Single Responses. */
if (GetSequence(source, &index, &length, size) < 0)
if (GetSequence(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
remainder = length;
/* First Single Response */
while (remainder != 0 && qty < STATUS_LIST_SIZE)
{
prevIndex = index;
prevIndex = idx;
/* Wrapper around the Single Response */
if (GetSequence(source, &index, &length, size) < 0)
if (GetSequence(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
/* Wrapper around the CertID */
if (GetSequence(source, &index, &length, size) < 0)
if (GetSequence(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
/* Skip the hash algorithm */
if (GetAlgoId(source, &index, &oid, size) < 0)
if (GetAlgoId(source, &idx, &oid, size) < 0)
return ASN_PARSE_E;
/* Skip the hash of CN */
if (source[index++] != ASN_OCTET_STRING)
if (source[idx++] != ASN_OCTET_STRING)
return ASN_PARSE_E;
if (GetLength(source, &index, &length, size) < 0)
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
index += length;
idx += length;
/* Skip the hash of the issuer public key */
if (source[index++] != ASN_OCTET_STRING)
if (source[idx++] != ASN_OCTET_STRING)
return ASN_PARSE_E;
if (GetLength(source, &index, &length, size) < 0)
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
index += length;
idx += length;
/* Read the serial number */
if (GetInt(&mpi, source, &index, size) < 0)
/* Read the serial number, it is handled as a string, not as a
* proper number. Just XMEMCPY the data over, rather than load it
* as an mp_int. */
if (source[idx++] != ASN_INTEGER)
return ASN_PARSE_E;
mpi_len = mp_unsigned_bin_size(&mpi);
if (mpi_len < (int)sizeof(serialTmp)) {
if (mp_to_unsigned_bin(&mpi, serialTmp) == MP_OKAY) {
if (mpi_len > EXTERNAL_SERIAL_SIZE)
mpi_len = EXTERNAL_SERIAL_SIZE;
XMEMCPY(resp->certSN[qty], serialTmp, mpi_len);
resp->certSNsz[qty] = mpi_len;
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
if (length <= EXTERNAL_SERIAL_SIZE) {
if (source[idx] == 0) {
idx++;
length--;
}
XMEMCPY(resp->certSN[qty], source + idx, length);
resp->certSNsz[qty] = length;
} else {
return ASN_GETINT_E;
}
mp_clear(&mpi);
idx += length;
/* CertStatus */
switch (source[index++])
switch (source[idx++])
{
case (ASN_CONTEXT_SPECIFIC | CERT_GOOD):
resp->certStatus[qty] = CERT_GOOD;
index++;
idx++;
break;
case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_REVOKED):
resp->certStatus[qty] = CERT_REVOKED;
GetLength(source, &index, &length, size);
index += length;
GetLength(source, &idx, &length, size);
idx += length;
break;
case (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | CERT_UNKNOWN):
case (ASN_CONTEXT_SPECIFIC | CERT_UNKNOWN):
resp->certStatus[qty] = CERT_UNKNOWN;
index++;
idx++;
break;
default:
return ASN_PARSE_E;
}
if (source[index++] != ASN_GENERALIZED_TIME)
if (source[idx++] != ASN_GENERALIZED_TIME)
return ASN_PARSE_E;
if (GetLength(source, &index, &length, size) < 0)
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
index += length;
resp->thisUpdate = source + idx;
idx += length;
remainder = remainder + prevIndex - index;
remainder = remainder + prevIndex - idx;
qty++;
}
resp->certStatusCount = qty;
*ioIndex = index;
*ioIndex = idx;
return 0;
}
static int DecodeOcspRespExtensions(byte* source,
word32* ioIndex, OcspResponse* resp, word32 sz)
{
word32 idx = *ioIndex;
int length;
int ext_bound; /* boundary index for the sequence of extensions */
word32 oid;
CYASSL_ENTER("DecodeOcspRespExtensions");
if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1))
return ASN_PARSE_E;
if (GetLength(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
if (GetSequence(source, &idx, &length, sz) < 0) return ASN_PARSE_E;
ext_bound = idx + length;
while (idx < (word32)ext_bound) {
if (GetSequence(source, &idx, &length, sz) < 0) {
CYASSL_MSG("\tfail: should be a SEQUENCE");
return ASN_PARSE_E;
}
oid = 0;
if (GetObjectId(source, &idx, &oid, sz) < 0) {
CYASSL_MSG("\tfail: OBJECT ID");
return ASN_PARSE_E;
}
/* check for critical flag */
if (source[idx] == ASN_BOOLEAN) {
CYASSL_MSG("\tfound optional critical flag, moving past");
idx += (ASN_BOOL_SIZE + 1);
}
/* process the extension based on the OID */
if (source[idx++] != ASN_OCTET_STRING) {
CYASSL_MSG("\tfail: should be an OCTET STRING");
return ASN_PARSE_E;
}
if (GetLength(source, &idx, &length, sz) < 0) {
CYASSL_MSG("\tfail: extension data length");
return ASN_PARSE_E;
}
if (oid == OCSP_NONCE_OID) {
resp->nonce = source + idx;
resp->nonceSz = length;
}
idx += length;
}
*ioIndex = idx;
return 0;
}
static int DecodeResponseData(byte* source,
word32* ioIndex, OcspResponse* resp, word32 size)
{
word32 index = *ioIndex;
int length, result;
word32 idx = *ioIndex;
int length;
int version;
word32 responderId = 0;
if (GetSequence(source, &index, &length, size) < 0)
if (GetSequence(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
resp->respBegin = index;
resp->respBegin = idx;
resp->respLength = length;
/* Get version. It is an EXPLICIT[0] DEFAULT(0) value. If this
* item isn't an EXPLICIT[0], then set version to zero and move
* onto the next item.
*/
if (source[index] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
if (source[idx] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED))
{
index += 2; /* Eat the value and length */
if (GetMyVersion(source, &index, &version) < 0)
idx += 2; /* Eat the value and length */
if (GetMyVersion(source, &idx, &version) < 0)
return ASN_PARSE_E;
} else
version = 0;
responderId = source[index++];
responderId = source[idx++];
if ((responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) ||
(responderId == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)))
{
if (GetLength(source, &index, &length, size) < 0)
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
index += length;
idx += length;
}
else
return ASN_PARSE_E;
/* Skip GeneralizedTime */
if (source[index++] != ASN_GENERALIZED_TIME)
/* save pointer to the producedAt time */
if (source[idx++] != ASN_GENERALIZED_TIME)
return ASN_PARSE_E;
if (GetLength(source, &index, &length, size) < 0)
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
index += length;
resp->producedAt = source + idx;
idx += length;
if (DecodeSingleResponse(source, &index, resp, size) < 0)
if (DecodeSingleResponse(source, &idx, resp, size) < 0)
return ASN_PARSE_E;
/* Skip the extensions */
if (source[index++] == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1))
{
if (GetLength(source, &index, &length, size) < 0)
return ASN_PARSE_E;
index += length;
}
if (DecodeOcspRespExtensions(source, &idx, resp, size) < 0)
return ASN_PARSE_E;
*ioIndex = index;
*ioIndex = idx;
return 0;
}
static int DecodeCerts(byte* source,
word32* ioIndex, OcspResponse* resp, word32 size)
{
word32 index = *ioIndex;
if (source[index++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
word32 idx = *ioIndex;
(void)resp;
if (source[idx++] == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
{
int length;
if (GetLength(source, &index, &length, size) < 0)
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
index += length;
idx += length;
}
*ioIndex = index;
*ioIndex = idx;
return 0;
}
@@ -4269,42 +4336,42 @@ static int DecodeBasicOcspResponse(byte* source,
word32* ioIndex, OcspResponse* resp, word32 size)
{
int length;
word32 index = *ioIndex;
word32 idx = *ioIndex;
word32 end_index;
if (GetSequence(source, &index, &length, size) < 0)
if (GetSequence(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
if (index + length > size)
if (idx + length > size)
return ASN_INPUT_E;
end_index = index + length;
end_index = idx + length;
if (DecodeResponseData(source, &index, resp, size) < 0)
if (DecodeResponseData(source, &idx, resp, size) < 0)
return ASN_PARSE_E;
/* Get the signature algorithm */
if (GetAlgoId(source, &index, &resp->sigOID, size) < 0)
if (GetAlgoId(source, &idx, &resp->sigOID, size) < 0)
return ASN_PARSE_E;
/* Obtain pointer to the start of the signature, and save the size */
if (source[index++] == ASN_BIT_STRING)
if (source[idx++] == ASN_BIT_STRING)
{
int sigLength = 0;
if (GetLength(source, &index, &sigLength, size) < 0)
if (GetLength(source, &idx, &sigLength, size) < 0)
return ASN_PARSE_E;
resp->sigLength = sigLength;
resp->sigIndex = index;
index += sigLength;
resp->sigIndex = idx;
idx += sigLength;
}
/*
* Check the length of the BasicOcspResponse against the current index to
* see if there are certificates, they are optional.
*/
if (index < end_index)
return DecodeCerts(source, &index, resp, size);
if (idx < end_index)
return DecodeCerts(source, &idx, resp, size);
*ioIndex = index;
*ioIndex = idx;
return 0;
}
@@ -4318,52 +4385,55 @@ void InitOcspResponse(OcspResponse* resp, byte* source, word32 inSz, void* heap)
}
void FreeOcspResponse(OcspResponse* resp) {}
void FreeOcspResponse(OcspResponse* resp)
{
(void)resp;
}
int OcspResponseDecode(OcspResponse* resp)
{
int length = 0;
word32 index = 0;
word32 idx = 0;
byte* source = resp->source;
word32 size = resp->maxIdx;
word32 oid;
/* peel the outer SEQUENCE wrapper */
if (GetSequence(source, &index, &length, size) < 0)
if (GetSequence(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
/* First get the responseStatus, an ENUMERATED */
if (GetEnumerated(source, &index, &resp->responseStatus) < 0)
if (GetEnumerated(source, &idx, &resp->responseStatus) < 0)
return ASN_PARSE_E;
if (resp->responseStatus != OCSP_SUCCESSFUL)
return 0;
/* Next is an EXPLICIT record called ResponseBytes, OPTIONAL */
if (index >= size)
if (idx >= size)
return ASN_INPUT_E;
if (source[index++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
if (source[idx++] != (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC))
return ASN_PARSE_E;
if (GetLength(source, &index, &length, size) < 0)
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
/* Get the responseBytes SEQUENCE */
if (GetSequence(source, &index, &length, size) < 0)
if (GetSequence(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
/* Check ObjectID for the resposeBytes */
if (GetObjectId(source, &index, &oid, size) < 0)
if (GetObjectId(source, &idx, &oid, size) < 0)
return ASN_PARSE_E;
if (oid != OCSP_BASIC_OID)
return ASN_PARSE_E;
if (source[index++] != ASN_OCTET_STRING)
if (source[idx++] != ASN_OCTET_STRING)
return ASN_PARSE_E;
if (GetLength(source, &index, &length, size) < 0)
if (GetLength(source, &idx, &length, size) < 0)
return ASN_PARSE_E;
if (DecodeBasicOcspResponse(source, &index, resp, size) < 0)
if (DecodeBasicOcspResponse(source, &idx, resp, size) < 0)
return ASN_PARSE_E;
return 0;
@@ -4385,6 +4455,57 @@ static int SetSerialNumber(const byte* sn, word32 snSz, byte* output)
}
static word32 SetOcspReqExtensions(word32 extSz, byte* output,
const byte* nonce, word32 nonceSz)
{
static const byte NonceObjId[] = { 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
0x30, 0x01, 0x02 };
byte seqArray[5][MAX_SEQ_SZ];
word32 seqSz[5], totalSz;
if (nonce == NULL || nonceSz == 0) return 0;
seqArray[0][0] = ASN_OCTET_STRING;
seqSz[0] = 1 + SetLength(nonceSz, &seqArray[0][1]);
seqArray[1][0] = ASN_OBJECT_ID;
seqSz[1] = 1 + SetLength(sizeof(NonceObjId), &seqArray[1][1]);
totalSz = seqSz[0] + seqSz[1] + nonceSz + sizeof(NonceObjId);
seqSz[2] = SetSequence(totalSz, seqArray[2]);
totalSz += seqSz[2];
seqSz[3] = SetSequence(totalSz, seqArray[3]);
totalSz += seqSz[3];
seqArray[4][0] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 2);
seqSz[4] = 1 + SetLength(totalSz, &seqArray[4][1]);
totalSz += seqSz[4];
if (totalSz < extSz)
{
totalSz = 0;
XMEMCPY(output + totalSz, seqArray[4], seqSz[4]);
totalSz += seqSz[4];
XMEMCPY(output + totalSz, seqArray[3], seqSz[3]);
totalSz += seqSz[3];
XMEMCPY(output + totalSz, seqArray[2], seqSz[2]);
totalSz += seqSz[2];
XMEMCPY(output + totalSz, seqArray[1], seqSz[1]);
totalSz += seqSz[1];
XMEMCPY(output + totalSz, NonceObjId, sizeof(NonceObjId));
totalSz += sizeof(NonceObjId);
XMEMCPY(output + totalSz, seqArray[0], seqSz[0]);
totalSz += seqSz[0];
XMEMCPY(output + totalSz, nonce, nonceSz);
totalSz += nonceSz;
}
return totalSz;
}
int EncodeOcspRequest(DecodedCert* cert, byte* output, word32 outputSz)
{
byte seqArray[5][MAX_SEQ_SZ];
@@ -4393,20 +4514,38 @@ int EncodeOcspRequest(DecodedCert* cert, byte* output, word32 outputSz)
byte issuerArray[MAX_ENCODED_DIG_SZ];
byte issuerKeyArray[MAX_ENCODED_DIG_SZ];
byte snArray[MAX_SN_SZ];
word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, totalSz;
byte extArray[MAX_OCSP_EXT_SZ];
byte nonceArray[MAX_OCSP_NONCE_SZ];
RNG rng;
word32 seqSz[5], algoSz, issuerSz, issuerKeySz, snSz, nonceSz,
extSz, totalSz;
int i;
(void)outputSz;
CYASSL_ENTER("EncodeOcspRequest");
algoSz = SetAlgoID(SHAh, algoArray, hashType);
issuerSz = SetDigest(cert->issuerHash, SHA_SIZE, issuerArray);
issuerKeySz = SetDigest(cert->issuerKeyHash, SHA_SIZE, issuerKeyArray);
snSz = SetSerialNumber(cert->serial, cert->serialSz, snArray);
if (InitRng(&rng) != 0) {
CYASSL_MSG("\tCannot initialize RNG. Skipping the OSCP Nonce.");
nonceSz = 0;
extSz = 0;
} else {
nonceSz = MAX_OCSP_NONCE_SZ;
RNG_GenerateBlock(&rng, nonceArray, nonceSz);
extSz = SetOcspReqExtensions(MAX_OCSP_EXT_SZ, extArray,
nonceArray, nonceSz);
}
totalSz = algoSz + issuerSz + issuerKeySz + snSz;
for (i = 4; i >= 0; i--) {
seqSz[i] = SetSequence(totalSz, seqArray[i]);
totalSz += seqSz[i];
if (i == 2) totalSz += extSz;
}
totalSz = 0;
for (i = 0; i < 5; i++) {
@@ -4421,10 +4560,40 @@ int EncodeOcspRequest(DecodedCert* cert, byte* output, word32 outputSz)
totalSz += issuerKeySz;
XMEMCPY(output + totalSz, snArray, snSz);
totalSz += snSz;
if (extSz != 0) {
XMEMCPY(output + totalSz, extArray, extSz);
totalSz += extSz;
}
return totalSz;
}
void InitOcspRequest(OcspRequest* req, byte* dest, word32 destSz, void* heap)
{
XMEMSET(req, 0, sizeof(*req));
req->dest = dest;
req->destSz = destSz;
req->heap = heap;
}
int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp)
{
int cmp;
if (req == NULL) return -1;
if (resp == NULL) return 1;
cmp = req->nonceSz - resp->nonceSz;
if (cmp != 0) return cmp;
cmp = XMEMCMP(req->nonce, resp->nonce, req->nonceSz);
if (cmp != 0) return cmp;
return 0;
}
#endif
@@ -4491,15 +4660,16 @@ static int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx)
/* Get raw Date only, no processing, 0 on success */
static int GetBasicDate(const byte* source, word32* idx, byte* date, int maxIdx)
static int GetBasicDate(const byte* source, word32* idx, byte* date,
byte* format, int maxIdx)
{
int length;
byte b = source[*idx];
CYASSL_ENTER("GetBasicDate");
*format = source[*idx];
*idx += 1;
if (b != ASN_UTC_TIME && b != ASN_GENERALIZED_TIME)
if (*format != ASN_UTC_TIME && *format != ASN_GENERALIZED_TIME)
return ASN_TIME_E;
if (GetLength(source, idx, &length, maxIdx) < 0)
@@ -4548,7 +4718,7 @@ static int GetRevoked(const byte* buff, word32* idx, DecodedCRL* dcrl,
return ASN_PARSE_E;
}
rc = XMALLOC(sizeof(RevokedCert), NULL, DYNAMIC_TYPE_CRL);
rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), NULL, DYNAMIC_TYPE_CRL);
if (rc == NULL) {
CYASSL_MSG("Alloc Revoked Cert failed");
return MEMORY_E;
@@ -4620,11 +4790,12 @@ static int GetCRL_Signature(const byte* source, word32* idx, DecodedCRL* dcrl,
/* prase crl buffer into decoded state, 0 on success */
int ParseCRL(DecodedCRL* dcrl, const byte* buff, long sz)
int ParseCRL(DecodedCRL* dcrl, const byte* buff, long sz, void* cm)
{
int version, len;
word32 oid, idx = 0;
Md5 md5;
int version, len;
word32 oid, idx = 0;
Md5 md5;
Signer* ca;
CYASSL_MSG("ParseCRL");
@@ -4654,12 +4825,17 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, long sz)
if (GetNameHash(buff, &idx, dcrl->issuerHash, sz) < 0)
return ASN_PARSE_E;
if (GetBasicDate(buff, &idx, dcrl->lastDate, sz) < 0)
if (GetBasicDate(buff, &idx, dcrl->lastDate, &dcrl->lastDateFormat, sz) < 0)
return ASN_PARSE_E;
if (GetBasicDate(buff, &idx, dcrl->nextDate, sz) < 0)
if (GetBasicDate(buff, &idx, dcrl->nextDate, &dcrl->nextDateFormat, sz) < 0)
return ASN_PARSE_E;
if (!XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, AFTER)) {
CYASSL_MSG("CRL after date is no longer valid");
return ASN_AFTER_DATE_E;
}
if (idx != dcrl->sigIndex && buff[idx] != CRL_EXTENSIONS) {
if (GetSequence(buff, &idx, &len, sz) < 0)
return ASN_PARSE_E;
@@ -4681,6 +4857,25 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, long sz)
if (GetCRL_Signature(buff, &idx, dcrl, sz) < 0)
return ASN_PARSE_E;
ca = GetCA(cm, dcrl->issuerHash);
CYASSL_MSG("About to verify CRL signature");
if (ca) {
CYASSL_MSG("Found CRL issuer CA");
/* try to confirm/verify signature */
if (!ConfirmSignature(buff + dcrl->certBegin,
dcrl->sigIndex - dcrl->certBegin,
ca->publicKey, ca->pubKeySize, ca->keyOID,
dcrl->signature, dcrl->sigLength, dcrl->signatureOID, NULL)) {
CYASSL_MSG("CRL Confirm signature failed");
return ASN_SIG_CONFIRM_E;
}
}
else {
CYASSL_MSG("Did NOT find CRL issuer CA");
return ASN_SIG_CONFIRM_E;
}
return 0;
}

View File

@@ -138,6 +138,8 @@ enum Misc_ASN {
#endif
/* Max total extensions, id + len + others */
#endif
MAX_OCSP_EXT_SZ = 58, /* Max OCSP Extension length */
MAX_OCSP_NONCE_SZ = 18, /* OCSP Nonce size */
MAX_PUBLIC_KEY_SZ = MAX_NTRU_ENC_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2
/* use bigger NTRU size */
};
@@ -295,6 +297,7 @@ CYASSL_LOCAL void FreeSigners(Signer*, void*);
CYASSL_LOCAL int ToTraditional(byte* buffer, word32 length);
CYASSL_LOCAL int ToTraditionalEnc(byte* buffer, word32 length,const char*, int);
CYASSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType);
#ifdef HAVE_ECC
/* ASN sig helpers */
@@ -341,13 +344,15 @@ enum Ocsp_Cert_Status {
enum Ocsp_Sums {
OCSP_BASIC_OID = 117
OCSP_BASIC_OID = 117,
OCSP_NONCE_OID = 118
};
#define STATUS_LIST_SIZE 5
typedef struct OcspRequest OcspRequest;
typedef struct OcspResponse OcspResponse;
@@ -359,6 +364,10 @@ struct OcspResponse {
int version; /* Response version number */
byte* thisUpdate; /* Time at which this status was set */
byte* nextUpdate; /* Time for next update */
byte* producedAt; /* Time at which this response was signed */
word32 sigIndex; /* Index into source for start of sig */
word32 sigLength; /* Length in octets for the sig */
word32 sigOID; /* OID for hash used for sig */
@@ -372,17 +381,35 @@ struct OcspResponse {
word32 certStatus[STATUS_LIST_SIZE];
/* Certificate status array */
byte* nonce;
int nonceSz;
byte* source; /* pointer to source buffer, not owned */
word32 maxIdx; /* max offset based on init size */
void* heap; /* for user memory overrides */
};
struct OcspRequest {
byte* nonce;
int nonceSz;
byte* dest;
word32 destSz;
void* heap;
};
CYASSL_LOCAL void InitOcspResponse(OcspResponse*, byte*, word32, void*);
CYASSL_LOCAL void FreeOcspResponse(OcspResponse*);
CYASSL_LOCAL int OcspResponseDecode(OcspResponse*);
CYASSL_LOCAL void InitOcspRequest(OcspRequest*, byte*, word32, void*);
CYASSL_LOCAL void FreeOcspRequest(OcspRequest*);
CYASSL_LOCAL int EncodeOcspRequest(DecodedCert*, byte*, word32);
CYASSL_LOCAL int CompareOcspReqResp(OcspRequest*, OcspResponse*);
#endif /* HAVE_OCSP */
@@ -410,12 +437,14 @@ struct DecodedCRL {
byte crlHash[MD5_DIGEST_SIZE]; /* raw crl data hash */
byte lastDate[MAX_DATE_SIZE]; /* last date updated */
byte nextDate[MAX_DATE_SIZE]; /* next update date */
byte lastDateFormat; /* format of last date */
byte nextDateFormat; /* format of next date */
RevokedCert* certs; /* revoked cert list */
int totalCerts; /* number on list */
};
CYASSL_LOCAL void InitDecodedCRL(DecodedCRL*);
CYASSL_LOCAL int ParseCRL(DecodedCRL*, const byte* buff, long sz);
CYASSL_LOCAL int ParseCRL(DecodedCRL*, const byte* buff, long sz, void* cm);
CYASSL_LOCAL void FreeDecodedCRL(DecodedCRL*);

View File

@@ -205,7 +205,10 @@ enum {
DYNAMIC_TYPE_CRL = 22,
DYNAMIC_TYPE_REVOKED = 23,
DYNAMIC_TYPE_CRL_ENTRY = 24,
DYNAMIC_TYPE_CERT_MANAGER = 25
DYNAMIC_TYPE_CERT_MANAGER = 25,
DYNAMIC_TYPE_CRL_MONITOR = 26,
DYNAMIC_TYPE_OCSP_STATUS = 27,
DYNAMIC_TYPE_OCSP_ENTRY = 28
};
/* stack protection */

View File

@@ -92,9 +92,14 @@ enum CyaSSL_ErrorCodes {
NOT_CA_ERROR = -257, /* Not a CA cert error */
BAD_PATH_ERROR = -258, /* Bad path for opendir */
BAD_CERT_MANAGER_ERROR = -259, /* Bad Cert Manager */
OCSP_CERT_REVOKED = -260,
OCSP_CERT_REVOKED = -260, /* OCSP Certificate revoked */
CRL_CERT_REVOKED = -261, /* CRL Certificate revoked */
CRL_MISSING = -262, /* CRL Not loaded */
MONITOR_RUNNING_E = -263, /* CRL Monitor already running */
THREAD_CREATE_E = -264, /* Thread Create Error */
OCSP_NEED_URL = -265, /* OCSP need an URL for lookup */
OCSP_CERT_UNKNOWN = -266, /* OCSP responder doesn't know */
OCSP_LOOKUP_FAIL = -267, /* OCSP lookup not successful */
/* add strings to SetErrorString !!!!! */
/* begin negotiation parameter errors */

View File

@@ -633,16 +633,31 @@ struct CRL_Entry {
byte crlHash[MD5_DIGEST_SIZE]; /* raw crl data hash */
byte lastDate[MAX_DATE_SIZE]; /* last date updated */
byte nextDate[MAX_DATE_SIZE]; /* next update date */
byte lastDateFormat; /* last date format */
byte nextDateFormat; /* next date format */
RevokedCert* certs; /* revoked cert list */
int totalCerts; /* number on list */
};
typedef struct CRL_Monitor CRL_Monitor;
/* CRL directory monitor */
struct CRL_Monitor {
char* path; /* full dir path, if valid pointer we're using */
int type; /* PEM or ASN1 type */
};
/* CyaSSL CRL controller */
struct CYASSL_CRL {
CYASSL_CERT_MANAGER* cm; /* pointer back to cert manager */
CRL_Entry* crlList; /* our CRL list */
CyaSSL_Mutex crlLock; /* CRL list lock */
CRL_Monitor monitors[2]; /* PEM and DER possible */
#ifdef HAVE_CRL_MONITOR
pthread_t tid; /* monitoring thread */
#endif
};
@@ -745,7 +760,7 @@ typedef struct CipherSpecs {
/* Supported Ciphers from page 43 */
enum BulkCipherAlgorithm {
cipher_null,
cipher_null = 0,
rc4,
rc2,
des,
@@ -760,7 +775,7 @@ enum BulkCipherAlgorithm {
/* Supported Message Authentication Codes from page 43 */
enum MACAlgorithm {
no_mac = 0,
no_mac = 10,
md5_mac,
sha_mac,
sha224_mac,
@@ -773,19 +788,20 @@ enum MACAlgorithm {
/* Supported Key Exchange Protocols */
enum KeyExchangeAlgorithm {
no_kea = 0,
no_kea = 20,
rsa_kea,
diffie_hellman_kea,
fortezza_kea,
psk_kea,
ntru_kea,
ecc_diffie_hellman_kea
ecc_diffie_hellman_kea,
ecc_static_diffie_hellman_kea /* for verify suite only */
};
/* Supported Authentication Schemes */
enum SignatureAlgorithm {
anonymous_sa_algo = 0,
anonymous_sa_algo = 30,
rsa_sa_algo,
dsa_sa_algo,
ecc_dsa_sa_algo

View File

@@ -37,8 +37,6 @@
#ifdef _WIN32
/* wincrypt.h clashes */
#undef X509_NAME
#undef OCSP_REQUEST
#undef OCSP_RESPONSE
#endif

View File

@@ -43,6 +43,12 @@
#define CYASSL_VERSION LIBCYASSL_VERSION_STRING
#endif
#ifdef _WIN32
/* wincrypt.h clashes */
#undef OCSP_REQUEST
#undef OCSP_RESPONSE
#endif
#ifdef __cplusplus
@@ -801,7 +807,8 @@ CYASSL_API int CyaSSL_CTX_DisableCRL(CYASSL_CTX* ctx);
CYASSL_API int CyaSSL_CTX_LoadCRL(CYASSL_CTX*, const char*, int, int);
CYASSL_API int CyaSSL_CTX_SetCRL_Cb(CYASSL_CTX*, CbMissingCRL);
#define CYASSL_CRL_MONITOR 0x01 /* monitor this dir flag */
#define CYASSL_CRL_START_MON 0x02 /* start monitoring flag */
#ifdef CYASSL_CALLBACKS

View File

@@ -577,7 +577,7 @@ static int myVerify(int preverify, CYASSL_X509_STORE_CTX* store)
#ifdef HAVE_CRL
static void CRL_CallBack(char* url)
static void CRL_CallBack(const char* url)
{
printf("CRL callback url = %s\n", url);
}

View File

@@ -208,7 +208,7 @@ void client_test(void* args)
ssl = CyaSSL_new(ctx);
CyaSSL_set_fd(ssl, sockfd);
#ifdef HAVE_CRL
CyaSSL_EnableCRL(ssl, 0);
CyaSSL_EnableCRL(ssl, CYASSL_CRL_CHECKALL);
CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, 0);
CyaSSL_SetCRL_Cb(ssl, CRL_CallBack);
#endif

View File

@@ -147,6 +147,12 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args)
#endif /* NO_FILESYSTEM */
ssl = SSL_new(ctx);
#ifdef HAVE_CRL
CyaSSL_EnableCRL(ssl, 0);
CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR |
CYASSL_CRL_START_MON);
CyaSSL_SetCRL_Cb(ssl, CRL_CallBack);
#endif
tcp_accept(&sockfd, &clientfd, (func_args*)args);
#ifndef CYASSL_DTLS
CloseSocket(sockfd);

606
src/crl.c
View File

@@ -36,41 +36,48 @@
/* Initialze CRL members */
int InitCRL(CYASSL_CRL* crl, CYASSL_CERT_MANAGER* cm)
{
CYASSL_ENTER("InitCRL");
CYASSL_ENTER("InitCRL");
crl->cm = cm;
crl->crlList = NULL;
if (InitMutex(&crl->crlLock) != 0)
return BAD_MUTEX_ERROR;
crl->cm = cm;
crl->crlList = NULL;
crl->monitors[0].path = NULL;
crl->monitors[1].path = NULL;
#ifdef HAVE_CRL_MONITOR
crl->tid = 0;
#endif
if (InitMutex(&crl->crlLock) != 0)
return BAD_MUTEX_ERROR;
return 0;
return 0;
}
/* Initialze CRL Entry */
static int InitCRL_Entry(CRL_Entry* crle, DecodedCRL* dcrl)
{
CYASSL_ENTER("FreeCRL_Entry");
CYASSL_ENTER("FreeCRL_Entry");
XMEMCPY(crle->issuerHash, dcrl->issuerHash, SHA_DIGEST_SIZE);
XMEMCPY(crle->crlHash, dcrl->crlHash, MD5_DIGEST_SIZE);
XMEMCPY(crle->lastDate, dcrl->lastDate, MAX_DATE_SIZE);
XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE);
XMEMCPY(crle->issuerHash, dcrl->issuerHash, SHA_DIGEST_SIZE);
XMEMCPY(crle->crlHash, dcrl->crlHash, MD5_DIGEST_SIZE);
XMEMCPY(crle->lastDate, dcrl->lastDate, MAX_DATE_SIZE);
XMEMCPY(crle->nextDate, dcrl->nextDate, MAX_DATE_SIZE);
crle->lastDateFormat = dcrl->lastDateFormat;
crle->nextDateFormat = dcrl->nextDateFormat;
crle->certs = dcrl->certs; /* take ownsership */
dcrl->certs = NULL;
crle->totalCerts = dcrl->totalCerts;
crle->certs = dcrl->certs; /* take ownsership */
dcrl->certs = NULL;
crle->totalCerts = dcrl->totalCerts;
return 0;
return 0;
}
/* Free all CRL Entry resources */
static void FreeCRL_Entry(CRL_Entry* crle)
{
RevokedCert* tmp = crle->certs;
RevokedCert* tmp = crle->certs;
CYASSL_ENTER("FreeCRL_Entry");
CYASSL_ENTER("FreeCRL_Entry");
while(tmp) {
RevokedCert* next = tmp->next;
@@ -84,9 +91,15 @@ static void FreeCRL_Entry(CRL_Entry* crle)
/* Free all CRL resources */
void FreeCRL(CYASSL_CRL* crl)
{
CRL_Entry* tmp = crl->crlList;
CRL_Entry* tmp = crl->crlList;
CYASSL_ENTER("FreeCRL");
CYASSL_ENTER("FreeCRL");
if (crl->monitors[0].path)
XFREE(crl->monitors[0].path, NULL, DYNAMIC_TYPE_CRL_MONITOR);
if (crl->monitors[1].path)
XFREE(crl->monitors[1].path, NULL, DYNAMIC_TYPE_CRL_MONITOR);
while(tmp) {
CRL_Entry* next = tmp->next;
@@ -95,6 +108,12 @@ void FreeCRL(CYASSL_CRL* crl)
tmp = next;
}
#ifdef HAVE_CRL_MONITOR
if (crl->tid != 0) {
CYASSL_MSG("Canceling monitor thread");
pthread_cancel(crl->tid);
}
#endif
FreeMutex(&crl->crlLock);
}
@@ -102,202 +121,453 @@ void FreeCRL(CYASSL_CRL* crl)
/* Is the cert ok with CRL, return 0 on success */
int CheckCertCRL(CYASSL_CRL* crl, DecodedCert* cert)
{
CRL_Entry* crle;
int foundEntry = 0;
int revoked = 0;
int ret = 0;
CRL_Entry* crle;
int foundEntry = 0;
int revoked = 0;
int ret = 0;
CYASSL_ENTER("CheckCertCRL");
CYASSL_ENTER("CheckCertCRL");
if (LockMutex(&crl->crlLock) != 0) {
CYASSL_MSG("LockMutex failed");
return BAD_MUTEX_ERROR;
}
if (LockMutex(&crl->crlLock) != 0) {
CYASSL_MSG("LockMutex failed");
return BAD_MUTEX_ERROR;
}
crle = crl->crlList;
crle = crl->crlList;
while (crle) {
if (XMEMCMP(crle->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0) {
CYASSL_MSG("Found CRL Entry on list");
foundEntry = 1;
break;
}
crle = crle->next;
}
while (crle) {
if (XMEMCMP(crle->issuerHash, cert->issuerHash, SHA_DIGEST_SIZE) == 0) {
CYASSL_MSG("Found CRL Entry on list");
CYASSL_MSG("Checking next date validity");
if (foundEntry) {
RevokedCert* rc = crle->certs;
while (rc) {
if (XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) {
CYASSL_MSG("Cert revoked");
revoked = 1;
ret = CRL_CERT_REVOKED;
break;
}
rc = rc->next;
}
}
UnLockMutex(&crl->crlLock);
if (foundEntry == 0) {
CYASSL_MSG("Couldn't find CRL for status check");
ret = CRL_MISSING;
if (crl->cm->cbMissingCRL) {
char url[256];
CYASSL_MSG("Issuing missing CRL callback");
url[0] = '\0';
if (cert->extCrlInfoSz < (int)sizeof(url) -1 ) {
XMEMCPY(url, cert->extCrlInfo, cert->extCrlInfoSz);
url[cert->extCrlInfoSz] = '\0';
}
else {
CYASSL_MSG("CRL url too long");
if (!ValidateDate(crle->nextDate, crle->nextDateFormat, AFTER)) {
CYASSL_MSG("CRL next date is no longer valid");
ret = ASN_AFTER_DATE_E;
}
crl->cm->cbMissingCRL(url);
}
}
else
foundEntry = 1;
break;
}
crle = crle->next;
}
if (foundEntry) {
RevokedCert* rc = crle->certs;
while (rc) {
if (XMEMCMP(rc->serialNumber, cert->serial, rc->serialSz) == 0) {
CYASSL_MSG("Cert revoked");
revoked = 1;
ret = CRL_CERT_REVOKED;
break;
}
rc = rc->next;
}
}
UnLockMutex(&crl->crlLock);
if (foundEntry == 0) {
CYASSL_MSG("Couldn't find CRL for status check");
ret = CRL_MISSING;
if (crl->cm->cbMissingCRL) {
char url[256];
CYASSL_MSG("Issuing missing CRL callback");
url[0] = '\0';
if (cert->extCrlInfoSz < (int)sizeof(url) -1 ) {
XMEMCPY(url, cert->extCrlInfo, cert->extCrlInfoSz);
url[cert->extCrlInfoSz] = '\0';
}
else {
CYASSL_MSG("CRL url too long");
}
crl->cm->cbMissingCRL(url);
}
}
return ret;
return ret;
}
/* Add Decoded CRL, 0 on success */
static int AddCRL(CYASSL_CRL* crl, DecodedCRL* dcrl)
{
CRL_Entry* crle;
CRL_Entry* crle;
CYASSL_ENTER("AddCRL");
CYASSL_ENTER("AddCRL");
crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), NULL, DYNAMIC_TYPE_CRL_ENTRY);
if (crle == NULL) {
CYASSL_MSG("alloc CRL Entry failed");
return -1;
}
crle = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), NULL, DYNAMIC_TYPE_CRL_ENTRY);
if (crle == NULL) {
CYASSL_MSG("alloc CRL Entry failed");
return -1;
}
if (InitCRL_Entry(crle, dcrl) < 0) {
CYASSL_MSG("Init CRL Entry failed");
return -1;
}
if (InitCRL_Entry(crle, dcrl) < 0) {
CYASSL_MSG("Init CRL Entry failed");
XFREE(crle, NULL, DYNAMIC_TYPE_CRL_ENTRY);
return -1;
}
if (LockMutex(&crl->crlLock) != 0) {
CYASSL_MSG("LockMutex failed");
FreeCRL_Entry(crle);
return BAD_MUTEX_ERROR;
}
crle->next = crl->crlList;
crl->crlList = crle;
UnLockMutex(&crl->crlLock);
if (LockMutex(&crl->crlLock) != 0) {
CYASSL_MSG("LockMutex failed");
FreeCRL_Entry(crle);
XFREE(crle, NULL, DYNAMIC_TYPE_CRL_ENTRY);
return BAD_MUTEX_ERROR;
}
crle->next = crl->crlList;
crl->crlList = crle;
UnLockMutex(&crl->crlLock);
return 0;
return 0;
}
/* Load CRL File of type, SSL_SUCCESS on ok */
int BufferLoadCRL(CYASSL_CRL* crl, const byte* buff, long sz, int type)
{
int ret = SSL_SUCCESS;
const byte* myBuffer = buff; /* if DER ok, otherwise switch */
buffer der;
DecodedCRL dcrl;
int ret = SSL_SUCCESS;
const byte* myBuffer = buff; /* if DER ok, otherwise switch */
buffer der;
DecodedCRL dcrl;
der.buffer = NULL;
der.buffer = NULL;
CYASSL_ENTER("BufferLoadCRL");
CYASSL_ENTER("BufferLoadCRL");
if (crl == NULL || buff == NULL || sz == 0)
return BAD_FUNC_ARG;
if (crl == NULL || buff == NULL || sz == 0)
return BAD_FUNC_ARG;
if (type == SSL_FILETYPE_PEM) {
int eccKey = 0; /* not used */
EncryptedInfo info;
info.ctx = NULL;
if (type == SSL_FILETYPE_PEM) {
int eccKey = 0; /* not used */
EncryptedInfo info;
info.ctx = NULL;
ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, &info, &eccKey);
if (ret == 0) {
myBuffer = der.buffer;
sz = der.length;
}
else {
CYASSL_MSG("Pem to Der failed");
return -1;
}
}
InitDecodedCRL(&dcrl);
ret = ParseCRL(&dcrl, myBuffer, sz);
if (ret != 0) {
CYASSL_MSG("ParseCRL error");
}
else {
ret = AddCRL(crl, &dcrl);
if (ret != 0) {
CYASSL_MSG("AddCRL error");
ret = PemToDer(buff, sz, CRL_TYPE, &der, NULL, &info, &eccKey);
if (ret == 0) {
myBuffer = der.buffer;
sz = der.length;
}
}
FreeDecodedCRL(&dcrl);
else {
CYASSL_MSG("Pem to Der failed");
return -1;
}
}
if (der.buffer)
XFREE(der.buffer, NULL, DYNAMIC_TYPE_CRL);
InitDecodedCRL(&dcrl);
ret = ParseCRL(&dcrl, myBuffer, sz, crl->cm);
if (ret != 0) {
CYASSL_MSG("ParseCRL error");
}
else {
ret = AddCRL(crl, &dcrl);
if (ret != 0) {
CYASSL_MSG("AddCRL error");
}
}
FreeDecodedCRL(&dcrl);
if (ret == 0)
return SSL_SUCCESS; /* convert */
return ret;
if (der.buffer)
XFREE(der.buffer, NULL, DYNAMIC_TYPE_CRL);
if (ret == 0)
return SSL_SUCCESS; /* convert */
return ret;
}
#ifdef HAVE_CRL_MONITOR
/* read in new CRL entries and save new list */
static int SwapLists(CYASSL_CRL* crl)
{
int ret;
CYASSL_CRL tmp;
CRL_Entry* newList;
if (InitCRL(&tmp, crl->cm) < 0) {
CYASSL_MSG("Init tmp CRL failed");
return -1;
}
if (crl->monitors[0].path) {
ret = LoadCRL(&tmp, crl->monitors[0].path, SSL_FILETYPE_PEM, 0);
if (ret != SSL_SUCCESS) {
CYASSL_MSG("PEM LoadCRL on dir change failed");
FreeCRL(&tmp);
return -1;
}
}
if (crl->monitors[1].path) {
ret = LoadCRL(&tmp, crl->monitors[1].path, SSL_FILETYPE_ASN1, 0);
if (ret != SSL_SUCCESS) {
CYASSL_MSG("DER LoadCRL on dir change failed");
FreeCRL(&tmp);
return -1;
}
}
if (LockMutex(&crl->crlLock) != 0) {
CYASSL_MSG("LockMutex failed");
FreeCRL(&tmp);
return -1;
}
newList = tmp.crlList;
/* swap lists */
tmp.crlList = crl->crlList;
crl->crlList = newList;
UnLockMutex(&crl->crlLock);
FreeCRL(&tmp);
return 0;
}
#ifdef __MACH__
#include <sys/event.h>
#include <sys/time.h>
#include <fcntl.h>
/* OS X monitoring */
static void* DoMonitor(void* arg)
{
int fPEM, fDER, kq;
struct kevent change;
CYASSL_CRL* crl = (CYASSL_CRL*)arg;
CYASSL_ENTER("DoMonitor");
kq = kqueue();
if (kq == -1) {
CYASSL_MSG("kqueue failed");
return NULL;
}
fPEM = -1;
fDER = -1;
if (crl->monitors[0].path) {
fPEM = open(crl->monitors[0].path, O_EVTONLY);
if (fPEM == -1) {
CYASSL_MSG("PEM event dir open failed");
return NULL;
}
}
if (crl->monitors[1].path) {
fDER = open(crl->monitors[1].path, O_EVTONLY);
if (fDER == -1) {
CYASSL_MSG("DER event dir open failed");
return NULL;
}
}
if (fPEM != -1)
EV_SET(&change, fPEM, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
if (fDER != -1)
EV_SET(&change, fDER, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_ONESHOT,
NOTE_DELETE | NOTE_EXTEND | NOTE_WRITE | NOTE_ATTRIB, 0, 0);
for (;;) {
struct kevent event;
int numEvents = kevent(kq, &change, 1, &event, 1, NULL);
CYASSL_MSG("Got kevent");
if (numEvents == -1) {
CYASSL_MSG("kevent problem, continue");
continue;
}
if (SwapLists(crl) < 0) {
CYASSL_MSG("SwapLists problem, continue");
}
}
return NULL;
}
#elif __linux__
#include <sys/types.h>
#include <sys/inotify.h>
#include <unistd.h>
/* linux monitoring */
static void* DoMonitor(void* arg)
{
int notifyFd;
int wd;
CYASSL_CRL* crl = (CYASSL_CRL*)arg;
CYASSL_ENTER("DoMonitor");
notifyFd = inotify_init();
if (notifyFd < 0) {
CYASSL_MSG("inotify failed");
return NULL;
}
if (crl->monitors[0].path) {
wd = inotify_add_watch(notifyFd, crl->monitors[0].path, IN_CLOSE_WRITE |
IN_DELETE);
if (wd < 0) {
CYASSL_MSG("PEM notify add watch failed");
return NULL;
}
}
if (crl->monitors[1].path) {
wd = inotify_add_watch(notifyFd, crl->monitors[1].path, IN_CLOSE_WRITE |
IN_DELETE);
if (wd < 0) {
CYASSL_MSG("DER notify add watch failed");
return NULL;
}
}
for (;;) {
char buffer[8192];
int length = read(notifyFd, buffer, sizeof(buffer));
CYASSL_MSG("Got notify event");
if (length < 0) {
CYASSL_MSG("notify read problem, continue");
continue;
}
if (SwapLists(crl) < 0) {
CYASSL_MSG("SwapLists problem, continue");
}
}
return NULL;
}
#endif /* MACH or linux */
/* Start Monitoring the CRL path(s) in a thread */
static int StartMonitorCRL(CYASSL_CRL* crl)
{
pthread_attr_t attr;
CYASSL_ENTER("StartMonitorCRL");
if (crl == NULL)
return BAD_FUNC_ARG;
if (crl->tid != 0) {
CYASSL_MSG("Monitor thread already running");
return MONITOR_RUNNING_E;
}
pthread_attr_init(&attr);
if (pthread_create(&crl->tid, &attr, DoMonitor, crl) != 0) {
CYASSL_MSG("Thread creation error");
return THREAD_CREATE_E;
}
return SSL_SUCCESS;
}
#else /* HAVE_CRL_MONITOR */
static int StartMonitorCRL(CYASSL_CRL* crl)
{
return NOT_COMPILED_IN;
}
#endif /* HAVE_CRL_MONITOR */
/* Load CRL path files of type, SSL_SUCCESS on ok */
int LoadCRL(CYASSL_CRL* crl, const char* path, int type, int monitor)
{
struct dirent* entry;
DIR* dir;
int ret = SSL_SUCCESS;
struct dirent* entry;
DIR* dir;
int ret = SSL_SUCCESS;
CYASSL_ENTER("LoadCRL");
if (crl == NULL)
return BAD_FUNC_ARG;
CYASSL_ENTER("LoadCRL");
if (crl == NULL)
return BAD_FUNC_ARG;
dir = opendir(path);
if (dir == NULL) {
CYASSL_MSG("opendir path crl load failed");
return BAD_PATH_ERROR;
}
while ( ret == SSL_SUCCESS && (entry = readdir(dir)) != NULL) {
if (entry->d_type & DT_REG) {
char name[MAX_FILENAME_SZ];
dir = opendir(path);
if (dir == NULL) {
CYASSL_MSG("opendir path crl load failed");
return BAD_PATH_ERROR;
}
while ( (entry = readdir(dir)) != NULL) {
if (entry->d_type & DT_REG) {
char name[MAX_FILENAME_SZ];
if (type == SSL_FILETYPE_PEM) {
if (strstr(entry->d_name, ".pem") == NULL) {
CYASSL_MSG("not .pem file, skipping");
continue;
}
}
else {
if (strstr(entry->d_name, ".der") == NULL &&
strstr(entry->d_name, ".crl") == NULL) {
if (type == SSL_FILETYPE_PEM) {
if (strstr(entry->d_name, ".pem") == NULL) {
CYASSL_MSG("not .pem file, skipping");
continue;
}
}
else {
if (strstr(entry->d_name, ".der") == NULL &&
strstr(entry->d_name, ".crl") == NULL) {
CYASSL_MSG("not .der or .crl file, skipping");
continue;
}
}
CYASSL_MSG("not .der or .crl file, skipping");
continue;
}
}
XMEMSET(name, 0, sizeof(name));
XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
XSTRNCAT(name, "/", 1);
XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
XMEMSET(name, 0, sizeof(name));
XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
XSTRNCAT(name, "/", 1);
XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
ret = ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl);
}
}
if (monitor) {
CYASSL_MSG("monitor path requested");
if (ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl)
!= SSL_SUCCESS) {
CYASSL_MSG("CRL file load failed, continuing");
}
}
}
return SSL_SUCCESS;
if (monitor & CYASSL_CRL_MONITOR) {
CYASSL_MSG("monitor path requested");
if (type == SSL_FILETYPE_PEM) {
crl->monitors[0].path = strdup(path);
crl->monitors[0].type = SSL_FILETYPE_PEM;
if (crl->monitors[0].path == NULL)
ret = MEMORY_E;
} else {
crl->monitors[1].path = strdup(path);
crl->monitors[1].type = SSL_FILETYPE_ASN1;
if (crl->monitors[1].path == NULL)
ret = MEMORY_E;
}
if (monitor & CYASSL_CRL_START_MON) {
CYASSL_MSG("start monitoring requested");
ret = StartMonitorCRL(crl);
}
}
return ret;
}
#endif /* HAVE_CRL */

View File

@@ -72,5 +72,7 @@ endif
if BUILD_CRL
src_libcyassl_la_SOURCES += src/crl.c
src_libcyassl_la_CFLAGS += $(PTHREAD_CFLAGS)
src_libcyassl_la_LIBADD += $(PTHREAD_LIBS)
endif

View File

@@ -1628,11 +1628,9 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
ssl->ctx->cm);
if (ret == 0 && dCert.isCA == 0) {
CYASSL_MSG("Chain cert is not a CA, not adding as one");
(void)ret;
}
else if (ret == 0 && ssl->options.verifyNone) {
CYASSL_MSG("Chain cert not verified by option, not adding as CA");
(void)ret;
}
else if (ret == 0 && !AlreadySigner(ssl->ctx->cm, dCert.subjectHash)) {
buffer add;
@@ -1651,13 +1649,22 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
}
else if (ret != 0) {
CYASSL_MSG("Failed to verify CA from chain");
(void)ret;
}
else {
CYASSL_MSG("Verified CA from chain and already had it");
(void)ret;
}
#ifdef HAVE_CRL
if (ret == 0 && ssl->ctx->cm->crlEnabled && ssl->ctx->cm->crlCheckAll) {
CYASSL_MSG("Doing Non Leaf CRL check");
ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert);
if (ret != 0) {
CYASSL_MSG("\tCRL check not ok");
}
}
#endif /* HAVE_CRL */
if (ret != 0 && anyError == 0)
anyError = ret; /* save error from last time */
@@ -1697,15 +1704,16 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
}
#ifdef HAVE_OCSP
if (CyaSSL_OCSP_Lookup_Cert(&ssl->ctx->ocsp, &dCert) == CERT_REVOKED) {
CYASSL_MSG("\tOCSP Lookup returned revoked");
ret = OCSP_CERT_REVOKED;
ret = CyaSSL_OCSP_Lookup_Cert(&ssl->ctx->ocsp, &dCert);
if (ret != 0) {
CYASSL_MSG("\tOCSP Lookup not ok");
fatal = 0;
}
#endif
#ifdef HAVE_CRL
if (ssl->ctx->cm->crlEnabled) {
if (fatal == 0 && ssl->ctx->cm->crlEnabled) {
CYASSL_MSG("Doing Leaf CRL check");
ret = CheckCertCRL(ssl->ctx->cm->crl, &dCert);
if (ret != 0) {
@@ -3530,6 +3538,26 @@ void SetErrorString(int error, char* str)
XSTRNCPY(str, "CRL missing, not loaded", max);
break;
case MONITOR_RUNNING_E:
XSTRNCPY(str, "CRL monitor already running", max);
break;
case THREAD_CREATE_E:
XSTRNCPY(str, "Thread creation problem", max);
break;
case OCSP_NEED_URL:
XSTRNCPY(str, "OCSP need URL", max);
break;
case OCSP_CERT_UNKNOWN:
XSTRNCPY(str, "OCSP Cert unknown", max);
break;
case OCSP_LOOKUP_FAIL:
XSTRNCPY(str, "OCSP Responder lookup fail", max);
break;
default :
XSTRNCPY(str, "unknown error number", max);
}
@@ -5429,10 +5457,309 @@ int SetCipherList(Suites* s, const char* list)
}
/* Does this cipher suite (first, second) have the requirement
an ephemeral key exchange will still require the key for signing
the key exchange so ECHDE_RSA requires an rsa key thus rsa_kea */
static int CipherRequires(byte first, byte second, int requirement)
{
/* ECC extensions */
if (first == ECC_BYTE) {
switch (second) {
case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA :
if (requirement == rsa_kea)
return 1;
break;
case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA :
if (requirement == ecc_static_diffie_hellman_kea)
return 1;
break;
case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA :
if (requirement == rsa_kea)
return 1;
break;
case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA :
if (requirement == ecc_static_diffie_hellman_kea)
return 1;
break;
case TLS_ECDHE_RSA_WITH_RC4_128_SHA :
if (requirement == rsa_kea)
return 1;
break;
case TLS_ECDH_RSA_WITH_RC4_128_SHA :
if (requirement == ecc_static_diffie_hellman_kea)
return 1;
break;
case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA :
if (requirement == ecc_dsa_sa_algo)
return 1;
break;
case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA :
if (requirement == ecc_static_diffie_hellman_kea)
return 1;
break;
case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA :
if (requirement == ecc_dsa_sa_algo)
return 1;
break;
case TLS_ECDH_ECDSA_WITH_RC4_128_SHA :
if (requirement == ecc_static_diffie_hellman_kea)
return 1;
break;
case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA :
if (requirement == rsa_kea)
return 1;
break;
case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA :
if (requirement == ecc_static_diffie_hellman_kea)
return 1;
break;
case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA :
if (requirement == ecc_dsa_sa_algo)
return 1;
break;
case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA :
if (requirement == ecc_static_diffie_hellman_kea)
return 1;
break;
case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA :
if (requirement == ecc_dsa_sa_algo)
return 1;
break;
case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA :
if (requirement == ecc_static_diffie_hellman_kea)
return 1;
break;
default:
CYASSL_MSG("Unsupported cipher suite, CipherRequires ECC");
return 0;
} /* switch */
} /* if */
if (first != ECC_BYTE) { /* normal suites */
switch (second) {
case SSL_RSA_WITH_RC4_128_SHA :
if (requirement == rsa_kea)
return 1;
break;
case TLS_NTRU_RSA_WITH_RC4_128_SHA :
if (requirement == ntru_kea)
return 1;
break;
case SSL_RSA_WITH_RC4_128_MD5 :
if (requirement == rsa_kea)
return 1;
break;
case SSL_RSA_WITH_3DES_EDE_CBC_SHA :
if (requirement == rsa_kea)
return 1;
break;
case TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA :
if (requirement == ntru_kea)
return 1;
break;
case TLS_RSA_WITH_AES_128_CBC_SHA :
if (requirement == rsa_kea)
return 1;
break;
case TLS_RSA_WITH_AES_128_CBC_SHA256 :
if (requirement == rsa_kea)
return 1;
break;
case TLS_NTRU_RSA_WITH_AES_128_CBC_SHA :
if (requirement == ntru_kea)
return 1;
break;
case TLS_RSA_WITH_AES_256_CBC_SHA :
if (requirement == rsa_kea)
return 1;
break;
case TLS_RSA_WITH_AES_256_CBC_SHA256 :
if (requirement == rsa_kea)
return 1;
break;
case TLS_NTRU_RSA_WITH_AES_256_CBC_SHA :
if (requirement == ntru_kea)
return 1;
break;
case TLS_PSK_WITH_AES_128_CBC_SHA :
if (requirement == psk_kea)
return 1;
break;
case TLS_PSK_WITH_AES_256_CBC_SHA :
if (requirement == psk_kea)
return 1;
break;
case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 :
if (requirement == rsa_kea)
return 1;
if (requirement == diffie_hellman_kea)
return 1;
break;
case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 :
if (requirement == rsa_kea)
return 1;
if (requirement == diffie_hellman_kea)
return 1;
break;
case TLS_DHE_RSA_WITH_AES_128_CBC_SHA :
if (requirement == rsa_kea)
return 1;
if (requirement == diffie_hellman_kea)
return 1;
break;
case TLS_DHE_RSA_WITH_AES_256_CBC_SHA :
if (requirement == rsa_kea)
return 1;
if (requirement == diffie_hellman_kea)
return 1;
break;
case TLS_RSA_WITH_HC_128_CBC_MD5 :
if (requirement == rsa_kea)
return 1;
break;
case TLS_RSA_WITH_HC_128_CBC_SHA :
if (requirement == rsa_kea)
return 1;
break;
case TLS_RSA_WITH_RABBIT_CBC_SHA :
if (requirement == rsa_kea)
return 1;
break;
default:
CYASSL_MSG("Unsupported cipher suite, CipherRequires");
return 0;
} /* switch */
} /* if ECC / Normal suites else */
return 0;
}
/* Make sure cert/key are valid for this suite, true on success */
static int VerifySuite(CYASSL* ssl, word16 idx)
{
int haveRSA = !ssl->options.haveECDSA;
int havePSK = 0;
byte first = ssl->suites.suites[idx];
byte second = ssl->suites.suites[idx+1];
CYASSL_ENTER("VerifySuite");
#ifndef NO_PSK
havePSK = ssl->options.havePSK;
#endif
if (ssl->options.haveNTRU)
haveRSA = 0;
if (CipherRequires(first, second, rsa_kea)) {
CYASSL_MSG("Requires RSA");
if (haveRSA == 0) {
CYASSL_MSG("Don't have RSA");
return 0;
}
return 1;
}
if (CipherRequires(first, second, diffie_hellman_kea)) {
CYASSL_MSG("Requires DHE");
if (ssl->options.haveDH == 0) {
CYASSL_MSG("Don't have DHE");
return 0;
}
return 1;
}
if (CipherRequires(first, second, ecc_dsa_sa_algo)) {
CYASSL_MSG("Requires ECCDSA");
if (ssl->options.haveECDSA == 0) {
CYASSL_MSG("Don't have ECCDSA");
return 0;
}
return 1;
}
if (CipherRequires(first, second, ecc_static_diffie_hellman_kea)) {
CYASSL_MSG("Requires static ECC");
if (ssl->options.haveStaticECC == 0) {
CYASSL_MSG("Don't have static ECC");
return 0;
}
return 1;
}
if (CipherRequires(first, second, psk_kea)) {
CYASSL_MSG("Requires PSK");
if (havePSK == 0) {
CYASSL_MSG("Don't have PSK");
return 0;
}
return 1;
}
if (CipherRequires(first, second, ntru_kea)) {
CYASSL_MSG("Requires NTRU");
if (ssl->options.haveNTRU == 0) {
CYASSL_MSG("Don't have NTRU");
return 0;
}
return 1;
}
/* ECCDHE is always supported if ECC on */
return 1;
}
static int MatchSuite(CYASSL* ssl, Suites* peerSuites)
{
word16 i, j;
CYASSL_ENTER("MatchSuite");
/* & 0x1 equivalent % 2 */
if (peerSuites->suiteSz == 0 || peerSuites->suiteSz & 0x1)
return MATCH_SUITE_ERROR;
@@ -5443,9 +5770,15 @@ int SetCipherList(Suites* s, const char* list)
if (ssl->suites.suites[i] == peerSuites->suites[j] &&
ssl->suites.suites[i+1] == peerSuites->suites[j+1] ) {
ssl->options.cipherSuite0 = ssl->suites.suites[i];
ssl->options.cipherSuite = ssl->suites.suites[i+1];
return SetCipherSpecs(ssl);
if (VerifySuite(ssl, i)) {
CYASSL_MSG("Verified suite validity");
ssl->options.cipherSuite0 = ssl->suites.suites[i];
ssl->options.cipherSuite = ssl->suites.suites[i+1];
return SetCipherSpecs(ssl);
}
else {
CYASSL_MSG("Coult not verify suite validity, continue");
}
}
return MATCH_SUITE_ERROR;

View File

@@ -91,56 +91,77 @@ void CyaSSL_OCSP_Cleanup(CYASSL_OCSP* ocsp)
}
static int decode_url(const char* url, int urlSz,
char* outName, char* outPath, int* outPort)
{
if (outName != NULL && outPath != NULL && outPort != NULL)
{
if (url == NULL || urlSz == 0)
{
*outName = 0;
*outPath = 0;
*outPort = 0;
}
else
{
int i, cur;
/* need to break the url down into scheme, address, and port */
/* "http://example.com:8080/" */
if (XSTRNCMP(url, "http://", 7) == 0) {
cur = 7;
} else cur = 0;
i = 0;
while (url[cur] != 0 && url[cur] != ':' && url[cur] != '/') {
outName[i++] = url[cur++];
}
outName[i] = 0;
/* Need to pick out the path after the domain name */
if (cur < urlSz && url[cur] == ':') {
char port[6];
int j;
i = 0;
cur++;
while (cur < urlSz && url[cur] != 0 && url[cur] != '/' &&
i < 6) {
port[i++] = url[cur++];
}
*outPort = 0;
for (j = 0; j < i; j++) {
if (port[j] < '0' || port[j] > '9') return -1;
*outPort = (*outPort * 10) + (port[j] - '0');
}
}
else
*outPort = 80;
if (cur < urlSz && url[cur] == '/') {
i = 0;
while (cur < urlSz && url[cur] != 0 && i < 80) {
outPath[i++] = url[cur++];
}
outPath[i] = 0;
}
else {
outPath[0] = '/';
outPath[1] = 0;
}
}
}
return 0;
}
int CyaSSL_OCSP_set_override_url(CYASSL_OCSP* ocsp, const char* url)
{
if (ocsp != NULL && url != NULL) {
int i, cur, hostname;
/* need to break the url down into scheme, address, and port */
/* "http://example.com:8080/" */
if (XSTRNCMP(url, "http://", 7) == 0) {
cur = 7;
} else cur = 0;
i = 0;
while (url[cur] != 0 && url[cur] != ':' && url[cur] != '/') {
ocsp->overrideName[i++] = url[cur++];
}
ocsp->overrideName[i] = 0;
/* Need to pick out the path after the domain name */
if (url[cur] == ':') {
char port[6];
int j;
i = 0;
cur++;
while (url[cur] != 0 && url[cur] != '/' && i < 6) {
port[i++] = url[cur++];
}
ocsp->overridePort = 0;
for (j = 0; j < i; j++) {
if (port[j] < '0' || port[j] > '9') return -1;
ocsp->overridePort =
(ocsp->overridePort * 10) + (port[j] - '0');
}
}
else
ocsp->overridePort = 80;
if (url[cur] == '/') {
i = 0;
while (url[cur] != 0 && i < 80) {
ocsp->overridePath[i++] = url[cur++];
}
ocsp->overridePath[i] = 0;
}
else {
ocsp->overridePath[0] = '/';
ocsp->overridePath[1] = 0;
}
if (ocsp != NULL) {
int urlSz = strlen(url);
decode_url(url, urlSz,
ocsp->overrideName, ocsp->overridePath, &ocsp->overridePort);
return 1;
}
@@ -164,8 +185,9 @@ static INLINE void tcp_socket(SOCKET_T* sockfd, SOCKADDR_IN_T* addr,
entry->h_length);
host = inet_ntoa(tmp.sin_addr);
}
else
else {
CYASSL_MSG("no entry for host");
}
}
*sockfd = socket(AF_INET_V, SOCK_STREAM, 0);
@@ -185,13 +207,14 @@ static INLINE void tcp_connect(SOCKET_T* sockfd, const char* ip, word16 port)
SOCKADDR_IN_T addr;
tcp_socket(sockfd, &addr, ip, port);
if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0)
if (connect(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) {
CYASSL_MSG("tcp connect failed");
}
}
static int build_http_request(CYASSL_OCSP* ocsp, int ocspReqSz,
byte* buf, int bufSize)
static int build_http_request(const char* domainName, const char* path,
int ocspReqSz, byte* buf, int bufSize)
{
return snprintf((char*)buf, bufSize,
"POST %s HTTP/1.1\r\n"
@@ -199,29 +222,9 @@ static int build_http_request(CYASSL_OCSP* ocsp, int ocspReqSz,
"Content-Length: %d\r\n"
"Content-Type: application/ocsp-request\r\n"
"\r\n",
ocsp->overridePath, ocsp->overrideName, ocspReqSz);
path, domainName, ocspReqSz);
}
#if 0
static const char foo[] = \
"\x30\x81\xB7\x30\x81\xB4\x30\x81\x8C\x30\x44\x30\x42\x30\x09\x06\x05\x2B\x0E\x03" \
"\x02\x1A\x05\x00\x04\x14\x49\x2D\x52\x83\x4B\x40\x37\xF5\xA9\x9E\x26\xA2\x3E\x48" \
"\x2F\x2E\x37\x34\xC9\x54\x04\x14\x21\xA2\x25\xEE\x57\x38\x34\x5A\x24\x9D\xF3\x7C" \
"\x18\x60\x59\x7A\x04\x3D\xF5\x69\x02\x09\x00\x89\x5A\xA2\xBD\xFE\x26\x8B\xEE\x30" \
"\x44\x30\x42\x30\x09\x06\x05\x2B\x0E\x03\x02\x1A\x05\x00\x04\x14\x49\x2D\x52\x83" \
"\x4B\x40\x37\xF5\xA9\x9E\x26\xA2\x3E\x48\x2F\x2E\x37\x34\xC9\x54\x04\x14\x21\xA2" \
"\x25\xEE\x57\x38\x34\x5A\x24\x9D\xF3\x7C\x18\x60\x59\x7A\x04\x3D\xF5\x69\x02\x09" \
"\x00\x89\x5A\xA2\xBD\xFE\x26\x8B\xEF\xA2\x23\x30\x21\x30\x1F\x06\x09\x2B\x06\x01" \
"\x05\x05\x07\x30\x01\x02\x04\x12\x04\x10\x20\x56\x47\x19\x65\x33\xB6\xB5\xAD\x39" \
"\x1F\x21\x65\xE0\x44\x1E";
static int build_ocsp_request(CYASSL_OCSP* ocsp, byte* buf, int bufSz)
{
memcpy(buf, foo, sizeof(foo));
return sizeof(foo) - 1;
}
#endif
static byte* decode_http_response(byte* httpBuf, int httpBufSz, int* ocspRespSz)
{
@@ -229,7 +232,6 @@ static byte* decode_http_response(byte* httpBuf, int httpBufSz, int* ocspRespSz)
int stop = 0;
byte* contentType = NULL;
byte* contentLength = NULL;
byte* content = NULL;
char* buf = (char*)httpBuf; /* kludge so I'm not constantly casting */
if (strncasecmp(buf, "HTTP/1", 6) != 0)
@@ -261,7 +263,7 @@ static byte* decode_http_response(byte* httpBuf, int httpBufSz, int* ocspRespSz)
int len = 0;
idx += 15;
if (buf[idx] == ' ') idx++;
while (buf[idx] > '0' && buf[idx] < '9' && idx < httpBufSz) {
while (buf[idx] >= '0' && buf[idx] <= '9' && idx < httpBufSz) {
len = (len * 10) + (buf[idx] - '0');
idx++;
}
@@ -290,20 +292,28 @@ int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
byte* ocspReqBuf = &buf[httpBufSz];
int ocspReqSz = SCRATCH_BUFFER_SIZE - httpBufSz;
OcspResponse ocspResponse;
int result = CERT_UNKNOWN;
int result = 0;
char domainName[80], path[80];
int port;
/* If OCSP lookups are disabled, return success. */
if (!ocsp->enabled) {
CYASSL_MSG("OCSP lookup disabled, assuming CERT_GOOD");
return CERT_GOOD;
return 0;
}
/* If OCSP lookups are enabled, but URL Override is disabled, return
** a failure. Need to have an override URL for right now. */
if (!ocsp->useOverrideUrl || cert == NULL) {
CYASSL_MSG("OCSP lookup enabled, but URL Override disabled");
return CERT_UNKNOWN;
}
if (ocsp->useOverrideUrl || cert->extAuthInfo == NULL) {
if (ocsp->overrideName != NULL) {
XMEMCPY(domainName, ocsp->overrideName, 80);
XMEMCPY(path, ocsp->overridePath, 80);
port = ocsp->overridePort;
} else
return OCSP_NEED_URL;
} else {
if (!decode_url((const char*)cert->extAuthInfo, cert->extAuthInfoSz,
domainName, path, &port))
return OCSP_NEED_URL;
}
XMEMCPY(ocsp->status[0].issuerHash, cert->issuerHash, SHA_SIZE);
XMEMCPY(ocsp->status[0].issuerKeyHash, cert->issuerKeyHash, SHA_SIZE);
@@ -311,11 +321,11 @@ int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
ocsp->status[0].serialSz = cert->serialSz;
ocsp->statusLen = 1;
/*ocspReqSz = build_ocsp_request(ocsp, ocspReqBuf, ocspReqSz);*/
ocspReqSz = EncodeOcspRequest(cert, ocspReqBuf, ocspReqSz);
httpBufSz = build_http_request(ocsp, ocspReqSz, httpBuf, httpBufSz);
httpBufSz = build_http_request(domainName, path, ocspReqSz,
httpBuf, httpBufSz);
tcp_connect(&sfd, ocsp->overrideName, ocsp->overridePort);
tcp_connect(&sfd, domainName, port);
if (sfd > 0) {
int written;
written = write(sfd, httpBuf, httpBufSz);
@@ -332,19 +342,31 @@ int CyaSSL_OCSP_Lookup_Cert(CYASSL_OCSP* ocsp, DecodedCert* cert)
close(sfd);
if (ocspReqBuf == NULL) {
CYASSL_MSG("HTTP response was not OK, no OCSP response");
return CERT_UNKNOWN;
return OCSP_LOOKUP_FAIL;
}
} else {
CYASSL_MSG("OCSP Responder connection failed");
return CERT_UNKNOWN;
return OCSP_LOOKUP_FAIL;
}
InitOcspResponse(&ocspResponse, ocspReqBuf, ocspReqSz, NULL);
OcspResponseDecode(&ocspResponse);
if (ocspResponse.responseStatus != OCSP_SUCCESSFUL) {
CYASSL_MSG("OCSP Responder failure");
result = OCSP_LOOKUP_FAIL;
} else {
result = ocspResponse.certStatus[0];
switch (ocspResponse.certStatus[0]) {
case CERT_GOOD:
result = 0;
break;
case CERT_REVOKED:
result = OCSP_CERT_REVOKED;
break;
default:
result = OCSP_CERT_UNKNOWN;
break;
}
}
FreeOcspResponse(&ocspResponse);

View File

@@ -1110,6 +1110,8 @@ static int ProcessServerHello(const byte* input, int* sslBytes,
XMEMCPY(session->sslServer->arrays.sessionID, input, ID_LEN);
input += b;
*sslBytes -= b;
if (b)
session->sslServer->options.haveSessionId = 1;
(void)*input++; /* eat first byte, always 0 */
b = *input++;
@@ -1117,8 +1119,9 @@ static int ProcessServerHello(const byte* input, int* sslBytes,
session->sslClient->options.cipherSuite = b;
*sslBytes -= SUITE_LEN;
if (XMEMCMP(session->sslServer->arrays.sessionID,
session->sslClient->arrays.sessionID, ID_LEN) == 0) {
if (session->sslServer->options.haveSessionId &&
XMEMCMP(session->sslServer->arrays.sessionID,
session->sslClient->arrays.sessionID, ID_LEN) == 0) {
/* resuming */
SSL_SESSION* resume = GetSession(session->sslServer,
session->sslServer->arrays.masterSecret);
@@ -1271,6 +1274,7 @@ static int DoHandShake(const byte* input, int* sslBytes,
ret = DoFinished(ssl, input, &inOutIdx, SNIFF);
if (ret == 0 && session->flags.cached == 0) {
session->sslServer->options.haveSessionId = 1;
AddSession(session->sslServer);
session->flags.cached = 1;
}

View File

@@ -1474,7 +1474,7 @@ int CyaSSL_CertManagerCheckCRL(CYASSL_CERT_MANAGER* cm, byte* der, int sz)
int CyaSSL_CertManagerSetCRL_Cb(CYASSL_CERT_MANAGER* cm, CbMissingCRL cb)
{
CYASSL_ENTER("CyaSSL_CertManagerLoadCRL");
CYASSL_ENTER("CyaSSL_CertManagerSetCRL_Cb");
if (cm == NULL)
return BAD_FUNC_ARG;
@@ -7695,25 +7695,34 @@ const byte* CyaSSL_get_sessionID(const CYASSL_SESSION* session)
#endif /* SESSION_CERTS */
#ifdef HAVE_OCSP
long CyaSSL_CTX_OCSP_set_options(CYASSL_CTX* ctx, long options)
{
CYASSL_ENTER("CyaSSL_CTX_OCSP_set_options");
#ifdef HAVE_OCSP
if (ctx != NULL) {
ctx->ocsp.enabled = (options && CYASSL_OCSP_ENABLE) != 0;
ctx->ocsp.useOverrideUrl = (options && CYASSL_OCSP_URL_OVERRIDE) != 0;
ctx->ocsp.enabled = (options & CYASSL_OCSP_ENABLE) != 0;
ctx->ocsp.useOverrideUrl = (options & CYASSL_OCSP_URL_OVERRIDE) != 0;
return 1;
}
return 0;
#else
(void)ctx;
(void)options;
return NOT_COMPILED_IN;
#endif
}
int CyaSSL_CTX_OCSP_set_override_url(CYASSL_CTX* ctx, const char* url)
{
CYASSL_ENTER("CyaSSL_CTX_OCSP_set_override_url");
#ifdef HAVE_OCSP
return CyaSSL_OCSP_set_override_url(&ctx->ocsp, url);
#else
(void)ctx;
(void)url;
return NOT_COMPILED_IN;
#endif
}
#endif

View File

@@ -128,80 +128,113 @@ int main(int argc, char** argv)
#endif
ssl_Trace("./tracefile.txt", err);
if (pcap_findalldevs(&alldevs, err) == -1)
err_sys("Error in pcap_findalldevs");
if (argc == 1) {
/* normal case, user chooses device and port */
for (d = alldevs; d; d=d->next) {
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if (pcap_findalldevs(&alldevs, err) == -1)
err_sys("Error in pcap_findalldevs");
if (i == 0)
err_sys("No interfaces found! Make sure pcap or WinPcap is installed "
"correctly and you have sufficient permissions");
for (d = alldevs; d; d=d->next) {
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
printf("Enter the interface number (1-%d): ", i);
scanf("%d", &inum);
if (i == 0)
err_sys("No interfaces found! Make sure pcap or WinPcap is"
" installed correctly and you have sufficient permissions");
if (inum < 1 || inum > i)
err_sys("Interface number out of range");
printf("Enter the interface number (1-%d): ", i);
scanf("%d", &inum);
/* Jump to the selected adapter */
for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
if (inum < 1 || inum > i)
err_sys("Interface number out of range");
pcap = pcap_create(d->name, err);
/* Jump to the selected adapter */
for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);
if (pcap == NULL) printf("pcap_create failed %s\n", err);
pcap = pcap_create(d->name, err);
if (d->flags & PCAP_IF_LOOPBACK)
loopback = 1;
if (pcap == NULL) printf("pcap_create failed %s\n", err);
/* get an IPv4 address */
for (a = d->addresses; a; a = a->next) {
switch(a->addr->sa_family)
{
case AF_INET:
server =iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr);
printf("server = %s\n", server);
break;
}
}
if (server == NULL)
err_sys("Unable to get device IPv4 address");
if (d->flags & PCAP_IF_LOOPBACK)
loopback = 1;
ret = pcap_set_snaplen(pcap, 65536);
if (ret != 0) printf("pcap_set_snaplen failed %s\n", pcap_geterr(pcap));
/* get an IPv4 address */
for (a = d->addresses; a; a = a->next) {
switch(a->addr->sa_family)
{
case AF_INET:
server =
iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr);
printf("server = %s\n", server);
break;
}
}
if (server == NULL)
err_sys("Unable to get device IPv4 address");
ret = pcap_set_timeout(pcap, 1000);
if (ret != 0) printf("pcap_set_timeout failed %s\n", pcap_geterr(pcap));
ret = pcap_set_snaplen(pcap, 65536);
if (ret != 0) printf("pcap_set_snaplen failed %s\n", pcap_geterr(pcap));
ret = pcap_set_buffer_size(pcap, 1000000);
if (ret != 0)
printf("pcap_set_buffer_size failed %s\n", pcap_geterr(pcap));
ret = pcap_set_timeout(pcap, 1000);
if (ret != 0) printf("pcap_set_timeout failed %s\n", pcap_geterr(pcap));
ret = pcap_set_promisc(pcap, 1);
if (ret != 0) printf("pcap_set_promisc failed %s\n", pcap_geterr(pcap));
ret = pcap_set_buffer_size(pcap, 1000000);
if (ret != 0)
printf("pcap_set_buffer_size failed %s\n", pcap_geterr(pcap));
ret = pcap_set_promisc(pcap, 1);
if (ret != 0) printf("pcap_set_promisc failed %s\n", pcap_geterr(pcap));
ret = pcap_activate(pcap);
if (ret != 0) printf("pcap_activate failed %s\n", pcap_geterr(pcap));
ret = pcap_activate(pcap);
if (ret != 0) printf("pcap_activate failed %s\n", pcap_geterr(pcap));
printf("Enter the port to scan: ");
scanf("%d", &port);
printf("Enter the port to scan: ");
scanf("%d", &port);
SNPRINTF(filter, sizeof(filter), "tcp and port %d", port);
SNPRINTF(filter, sizeof(filter), "tcp and port %d", port);
ret = pcap_compile(pcap, &fp, filter, 0, 0);
if (ret != 0) printf("pcap_compile failed %s\n", pcap_geterr(pcap));
ret = pcap_compile(pcap, &fp, filter, 0, 0);
if (ret != 0) printf("pcap_compile failed %s\n", pcap_geterr(pcap));
ret = pcap_setfilter(pcap, &fp);
if (ret != 0) printf("pcap_setfilter failed %s\n", pcap_geterr(pcap));
ret = pcap_setfilter(pcap, &fp);
if (ret != 0) printf("pcap_setfilter failed %s\n", pcap_geterr(pcap));
ret = ssl_SetPrivateKey(server, port, "../../certs/server-key.pem",
FILETYPE_PEM, NULL, err);
}
else if (argc >= 3) {
pcap = pcap_open_offline(argv[1], err);
if (pcap == NULL) {
printf("pcap_open_offline failed %s\n", err);
ret = -1;
}
else {
/* defaults for server and port */
port = 443;
server = "127.0.0.1";
if (argc >= 4)
server = argv[3];
if (argc >= 5)
port = atoi(argv[4]);
ret = ssl_SetPrivateKey(server, port, argv[2],
FILETYPE_PEM, NULL, err);
}
}
else {
/* usage error */
printf(
"usage: ./snifftest or ./snifftest dump pemKey [server] [port]\n");
exit(EXIT_FAILURE);
}
ret = ssl_SetPrivateKey(server, port, "../../certs/server-key.pem",
FILETYPE_PEM, NULL, err);
if (ret != 0)
err_sys(err);