mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 15:50:51 +02:00
Merge pull request #9631 from padelsbach/crl-generation
Add CRL generation code
This commit is contained in:
@@ -107,6 +107,10 @@ ecc-key.der
|
||||
ecc-key.pem
|
||||
certreq.der
|
||||
certreq.pem
|
||||
crlRsaOut.pem
|
||||
crlRsaOut.der
|
||||
crlEccOut.pem
|
||||
crlEccOut.der
|
||||
pkcs7cert.der
|
||||
pkcs7authEnvelopedDataAES128GCM.der
|
||||
pkcs7authEnvelopedDataAES128GCM_ECDH_SHA1KDF.der
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,92 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 4661 (0x1235)
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Issuer: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
|
||||
Validity
|
||||
Not Before: Jan 24 20:31:13 2026 GMT
|
||||
Not After : Oct 20 20:31:13 2028 GMT
|
||||
Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_2048, OU = Programming-2048, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (2048 bit)
|
||||
Modulus:
|
||||
00:c3:03:d1:2b:fe:39:a4:32:45:3b:53:c8:84:2b:
|
||||
2a:7c:74:9a:bd:aa:2a:52:07:47:d6:a6:36:b2:07:
|
||||
32:8e:d0:ba:69:7b:c6:c3:44:9e:d4:81:48:fd:2d:
|
||||
68:a2:8b:67:bb:a1:75:c8:36:2c:4a:d2:1b:f7:8b:
|
||||
ba:cf:0d:f9:ef:ec:f1:81:1e:7b:9b:03:47:9a:bf:
|
||||
65:cc:7f:65:24:69:a6:e8:14:89:5b:e4:34:f7:c5:
|
||||
b0:14:93:f5:67:7b:3a:7a:78:e1:01:56:56:91:a6:
|
||||
13:42:8d:d2:3c:40:9c:4c:ef:d1:86:df:37:51:1b:
|
||||
0c:a1:3b:f5:f1:a3:4a:35:e4:e1:ce:96:df:1b:7e:
|
||||
bf:4e:97:d0:10:e8:a8:08:30:81:af:20:0b:43:14:
|
||||
c5:74:67:b4:32:82:6f:8d:86:c2:88:40:99:36:83:
|
||||
ba:1e:40:72:22:17:d7:52:65:24:73:b0:ce:ef:19:
|
||||
cd:ae:ff:78:6c:7b:c0:12:03:d4:4e:72:0d:50:6d:
|
||||
3b:a3:3b:a3:99:5e:9d:c8:d9:0c:85:b3:d9:8a:d9:
|
||||
54:26:db:6d:fa:ac:bb:ff:25:4c:c4:d1:79:f4:71:
|
||||
d3:86:40:18:13:b0:63:b5:72:4e:30:c4:97:84:86:
|
||||
2d:56:2f:d7:15:f7:7f:c0:ae:f5:fc:5b:e5:fb:a1:
|
||||
ba:d3
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints: critical
|
||||
CA:FALSE
|
||||
X509v3 Key Usage: critical
|
||||
Digital Signature, Key Encipherment
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Client Authentication
|
||||
X509v3 Subject Key Identifier:
|
||||
33:D8:45:66:D7:68:87:18:7E:54:0D:70:27:91:C7:26:D7:85:65:C0
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:27:8E:67:11:74:C3:26:1D:3F:ED:33:63:B3:A4:D8:1D:30:E5:E8:D5
|
||||
DirName:/C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
|
||||
serial:3F:29:11:20:57:71:E7:8E:F9:18:0D:CA:70:4D:5B:15:2A:43:D6:24
|
||||
Signature Algorithm: sha256WithRSAEncryption
|
||||
Signature Value:
|
||||
7f:71:41:b2:72:c1:a9:ba:c9:52:40:ea:6d:3d:3d:c0:ae:1e:
|
||||
44:cd:f9:a5:d6:ac:34:5f:8b:ed:cd:91:81:0f:05:0f:5e:4b:
|
||||
b3:18:bf:33:7a:61:a5:25:f1:91:55:c1:12:66:b7:26:3b:9c:
|
||||
bb:21:1a:0c:72:78:88:57:fa:49:22:e7:80:2f:c1:40:01:66:
|
||||
3d:20:63:e7:e3:38:a9:54:39:52:42:d2:b6:38:6b:08:7d:45:
|
||||
49:1a:de:b5:64:70:c9:65:ce:0b:94:24:ee:b4:46:67:3c:74:
|
||||
f0:2a:61:4d:b2:fc:6e:ca:c0:36:a9:b0:d3:5a:e2:15:72:f5:
|
||||
a4:90:73:b2:37:58:b4:10:39:d3:85:5f:56:91:7e:cf:54:5d:
|
||||
c6:a7:40:36:bd:ed:f2:af:e5:ce:b6:ea:38:be:47:32:6f:ed:
|
||||
d2:ba:9d:70:e1:74:2e:f0:27:e4:72:53:75:43:ce:0a:07:b4:
|
||||
7e:74:17:00:55:b5:d1:92:e4:42:39:ca:84:51:84:f8:23:a6:
|
||||
41:27:fb:20:e2:43:e3:74:d3:ce:95:4e:1f:06:de:65:5e:e3:
|
||||
38:e2:eb:f1:a6:ca:6b:7c:56:51:c0:02:1e:6e:3f:51:c1:d5:
|
||||
04:c0:3d:57:56:15:65:76:a4:f4:eb:43:27:2c:c3:58:29:5c:
|
||||
18:da:e8:fd
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIE3zCCA8egAwIBAgICEjUwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVT
|
||||
MRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMREwDwYDVQQKDAhT
|
||||
YXd0b290aDETMBEGA1UECwwKQ29uc3VsdGluZzEYMBYGA1UEAwwPd3d3LndvbGZz
|
||||
c2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMB4XDTI2MDEy
|
||||
NDIwMzExM1oXDTI4MTAyMDIwMzExM1owgZ4xCzAJBgNVBAYTAlVTMRAwDgYDVQQI
|
||||
DAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMRUwEwYDVQQKDAx3b2xmU1NMXzIw
|
||||
NDgxGTAXBgNVBAsMEFByb2dyYW1taW5nLTIwNDgxGDAWBgNVBAMMD3d3dy53b2xm
|
||||
c3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTCCASIwDQYJ
|
||||
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMMD0Sv+OaQyRTtTyIQrKnx0mr2qKlIH
|
||||
R9amNrIHMo7Quml7xsNEntSBSP0taKKLZ7uhdcg2LErSG/eLus8N+e/s8YEee5sD
|
||||
R5q/Zcx/ZSRppugUiVvkNPfFsBST9Wd7Onp44QFWVpGmE0KN0jxAnEzv0YbfN1Eb
|
||||
DKE79fGjSjXk4c6W3xt+v06X0BDoqAgwga8gC0MUxXRntDKCb42GwohAmTaDuh5A
|
||||
ciIX11JlJHOwzu8Zza7/eGx7wBID1E5yDVBtO6M7o5lencjZDIWz2YrZVCbbbfqs
|
||||
u/8lTMTRefRx04ZAGBOwY7VyTjDEl4SGLVYv1xX3f8Cu9fxb5fuhutMCAwEAAaOC
|
||||
AS0wggEpMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoG
|
||||
CCsGAQUFBwMCMB0GA1UdDgQWBBQz2EVm12iHGH5UDXAnkccm14VlwDCB1AYDVR0j
|
||||
BIHMMIHJgBQnjmcRdMMmHT/tM2OzpNgdMOXo1aGBmqSBlzCBlDELMAkGA1UEBhMC
|
||||
VVMxEDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoM
|
||||
CFNhd3Rvb3RoMRMwEQYDVQQLDApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29s
|
||||
ZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb22CFD8pESBX
|
||||
ceeO+RgNynBNWxUqQ9YkMA0GCSqGSIb3DQEBCwUAA4IBAQB/cUGycsGpuslSQOpt
|
||||
PT3Arh5Ezfml1qw0X4vtzZGBDwUPXkuzGL8zemGlJfGRVcESZrcmO5y7IRoMcniI
|
||||
V/pJIueAL8FAAWY9IGPn4zipVDlSQtK2OGsIfUVJGt61ZHDJZc4LlCTutEZnPHTw
|
||||
KmFNsvxuysA2qbDTWuIVcvWkkHOyN1i0EDnThV9WkX7PVF3Gp0A2ve3yr+XOtuo4
|
||||
vkcyb+3Sup1w4XQu8CfkclN1Q84KB7R+dBcAVbXRkuRCOcqEUYT4I6ZBJ/sg4kPj
|
||||
dNPOlU4fBt5lXuM44uvxpsprfFZRwAIebj9RwdUEwD1XVhVldqT060MnLMNYKVwY
|
||||
2uj9
|
||||
-----END CERTIFICATE-----
|
||||
Binary file not shown.
@@ -0,0 +1,54 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 4660 (0x1234)
|
||||
Signature Algorithm: ecdsa-with-SHA256
|
||||
Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Development, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
|
||||
Validity
|
||||
Not Before: Jan 24 20:12:22 2026 GMT
|
||||
Not After : Oct 20 20:12:22 2028 GMT
|
||||
Subject: C = US, ST = Oregon, L = Salem, O = Client ECC, OU = Fast, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: id-ecPublicKey
|
||||
Public-Key: (256 bit)
|
||||
pub:
|
||||
04:55:bf:f4:0f:44:50:9a:3d:ce:9b:b7:f0:c5:4d:
|
||||
f5:70:7b:d4:ec:24:8e:19:80:ec:5a:4c:a2:24:03:
|
||||
62:2c:9b:da:ef:a2:35:12:43:84:76:16:c6:56:95:
|
||||
06:cc:01:a9:bd:f6:75:1a:42:f7:bd:a9:b2:36:22:
|
||||
5f:c7:5d:7f:b4
|
||||
ASN1 OID: prime256v1
|
||||
NIST CURVE: P-256
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Key Identifier:
|
||||
EB:D4:4B:59:6B:95:61:3F:51:57:B6:04:4D:89:41:88:44:5C:AB:F2
|
||||
X509v3 Authority Key Identifier:
|
||||
56:8E:9A:C3:F0:42:DE:18:B9:45:55:6E:F9:93:CF:EA:C3:F3:A5:21
|
||||
X509v3 Basic Constraints: critical
|
||||
CA:FALSE
|
||||
X509v3 Key Usage: critical
|
||||
Digital Signature, Key Encipherment, Key Agreement
|
||||
X509v3 Extended Key Usage:
|
||||
TLS Web Client Authentication
|
||||
Signature Algorithm: ecdsa-with-SHA256
|
||||
Signature Value:
|
||||
30:45:02:21:00:9d:4d:72:4a:fb:f7:19:96:e3:d3:c2:75:ed:
|
||||
b5:39:18:44:e7:61:7d:5e:31:d0:3c:eb:45:b3:6f:38:68:f9:
|
||||
1d:02:20:57:c1:19:e8:c8:8a:14:e7:37:d1:93:b3:46:f5:eb:
|
||||
8f:24:31:6c:78:d7:cd:b7:c9:8e:09:54:6e:4d:3b:7b:7b
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICizCCAjGgAwIBAgICEjQwCgYIKoZIzj0EAwIwgZcxCzAJBgNVBAYTAlVTMRMw
|
||||
EQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRAwDgYDVQQKDAd3
|
||||
b2xmU1NMMRQwEgYDVQQLDAtEZXZlbG9wbWVudDEYMBYGA1UEAwwPd3d3LndvbGZz
|
||||
c2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMB4XDTI2MDEy
|
||||
NDIwMTIyMloXDTI4MTAyMDIwMTIyMlowgY0xCzAJBgNVBAYTAlVTMQ8wDQYDVQQI
|
||||
DAZPcmVnb24xDjAMBgNVBAcMBVNhbGVtMRMwEQYDVQQKDApDbGllbnQgRUNDMQ0w
|
||||
CwYDVQQLDARGYXN0MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG
|
||||
9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
|
||||
AARVv/QPRFCaPc6bt/DFTfVwe9TsJI4ZgOxaTKIkA2Ism9rvojUSQ4R2FsZWlQbM
|
||||
Aam99nUaQve9qbI2Il/HXX+0o3UwczAdBgNVHQ4EFgQU69RLWWuVYT9RV7YETYlB
|
||||
iERcq/IwHwYDVR0jBBgwFoAUVo6aw/BC3hi5RVVu+ZPP6sPzpSEwDAYDVR0TAQH/
|
||||
BAIwADAOBgNVHQ8BAf8EBAMCA6gwEwYDVR0lBAwwCgYIKwYBBQUHAwIwCgYIKoZI
|
||||
zj0EAwIDSAAwRQIhAJ1Nckr79xmW49PCde21ORhE52F9XjHQPOtFs284aPkdAiBX
|
||||
wRnoyIoU5zfRk7NG9euPJDFseNfNt8mOCVRuTTt7ew==
|
||||
-----END CERTIFICATE-----
|
||||
Binary file not shown.
@@ -1,10 +0,0 @@
|
||||
-----BEGIN X509 CRL-----
|
||||
MIIBdDCCARkCAQEwCgYIKoZIzj0EAwIwgZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
|
||||
DApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRAwDgYDVQQKDAd3b2xmU1NM
|
||||
MRQwEgYDVQQLDAtEZXZlbG9wbWVudDEYMBYGA1UEAwwPd3d3LndvbGZzc2wuY29t
|
||||
MR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tFw0yNjAyMDQwMzU0Mjla
|
||||
Fw0yNjAzMDYwMzU0MjlaMFAwEgIBAhcNMjYwMjA0MDM1NDI5WjASAgEDFw0yNjAy
|
||||
MDQwMzU0MjlaMBICAQQXDTI2MDIwNDAzNTQyOVowEgIBAxcNMjYwMjA0MDM1NDI5
|
||||
WjAKBggqhkjOPQQDAgNJADBGAiEA6xz109x9tZwaxxs3iLvW65h9AGL8+e1gTnbr
|
||||
GoEsXaQCIQDzxO4LU1d6seHETQDKjUEXivHuvC6f0Nq5uARmWX0DOA==
|
||||
-----END X509 CRL-----
|
||||
Binary file not shown.
@@ -1,14 +0,0 @@
|
||||
-----BEGIN X509 CRL-----
|
||||
MIICMTCCARkCAQEwDQYJKoZIhvcNAQELBQAwgZQxCzAJBgNVBAYTAlVTMRAwDgYD
|
||||
VQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMREwDwYDVQQKDAhTYXd0b290
|
||||
aDETMBEGA1UECwwKQ29uc3VsdGluZzEYMBYGA1UEAwwPd3d3LndvbGZzc2wuY29t
|
||||
MR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tFw0yNjAyMDQwMzU0Mjla
|
||||
Fw0yNjAzMDYwMzU0MjlaMFAwEgIBAhcNMjYwMjA0MDM1NDI5WjASAgEDFw0yNjAy
|
||||
MDQwMzU0MjlaMBICAQQXDTI2MDIwNDAzNTQyOVowEgIBARcNMjYwMjA0MDM1NDI5
|
||||
WjANBgkqhkiG9w0BAQsFAAOCAQEAid2CDa/invAbnAJaeVVkS8mRjI/kR0aPHwt1
|
||||
/Sz6w+j163+KZnBwUNgrMmLSMbssm8oxQ8i8zNvBeYd6u1x2N/jw/cwH2rxhZ3zQ
|
||||
bOkDQKKe2eRYXMykAl1uj2VwCeu8/ivqbimYReq7iloEHo8PUiizs1Pj6zJ59I1u
|
||||
LRZDDlS9wiY+VVkKx28dxyClsqtJNCvz5ezNB8GeH+gekaJ1tJVbd3TujBajPPAx
|
||||
R6FobbOOavCZPyGkeZlU/T9S5FwIi07qga5Zuq/9Dy7YwiVya3sAZ/nTYY++HKDQ
|
||||
DL0Bs3/05Lf8BLaf2CX2vGvan4JCQv9CMdnlYBifwvQCeUToyQ==
|
||||
-----END X509 CRL-----
|
||||
@@ -32,7 +32,9 @@ EXTRA_DIST += \
|
||||
certs/ecc-client-keyPub.pem \
|
||||
certs/empty-issuer-cert.pem \
|
||||
certs/client-ecc-cert.pem \
|
||||
certs/client-ecc-ca-cert.pem \
|
||||
certs/client-ca.pem \
|
||||
certs/client-ca-cert.pem \
|
||||
certs/dh2048.pem \
|
||||
certs/server-cert.pem \
|
||||
certs/server-ecc.pem \
|
||||
@@ -96,6 +98,8 @@ EXTRA_DIST += \
|
||||
certs/client-cert.der \
|
||||
certs/client-key.der \
|
||||
certs/client-ecc-cert.der \
|
||||
certs/client-ecc-ca-cert.der \
|
||||
certs/client-ca-cert.der \
|
||||
certs/client-keyPub.der \
|
||||
certs/client-keyPub.pem \
|
||||
certs/dh2048.der \
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
# 1024/client-cert.pem
|
||||
# server-ecc-comp.pem
|
||||
# client-ca.pem
|
||||
# client-ca-cert.der
|
||||
# client-ca-cert.pem
|
||||
# client-ecc-ca-cert.der
|
||||
# client-ecc-ca-cert.pem
|
||||
# test/digsigku.pem
|
||||
# ecc-privOnlyCert.pem
|
||||
# client-uri-cert.pem
|
||||
@@ -953,6 +957,73 @@ run_renewcerts(){
|
||||
echo "End of section"
|
||||
echo "---------------------------------------------------------------------"
|
||||
|
||||
############################################################
|
||||
########## update and sign client-ca-cert.pem ##############
|
||||
############################################################
|
||||
echo "Updating client-ca-cert.pem"
|
||||
echo ""
|
||||
cat > client-ca-ext.cnf <<'EOF'
|
||||
[ client_ca ]
|
||||
subjectKeyIdentifier=hash
|
||||
authorityKeyIdentifier=keyid:always,issuer:always
|
||||
basicConstraints=critical, CA:FALSE
|
||||
keyUsage=critical, digitalSignature, keyEncipherment
|
||||
extendedKeyUsage=clientAuth
|
||||
EOF
|
||||
check_result $? "Step 1"
|
||||
|
||||
#pipe the following arguments to openssl req...
|
||||
echo -e "US\\nMontana\\nBozeman\\nwolfSSL_2048\\nProgramming-2048\\n" \
|
||||
"www.wolfssl.com\\ninfo@wolfssl.com\\n.\\n.\\n" | \
|
||||
openssl req -new -key client-key.pem -config ./wolfssl.cnf -nodes \
|
||||
> client-ca-cert-req.pem
|
||||
check_result $? "Step 2"
|
||||
|
||||
openssl x509 -req -in client-ca-cert-req.pem -extfile client-ca-ext.cnf \
|
||||
-extensions client_ca -days 1000 -CA ca-cert.pem -CAkey ca-key.pem \
|
||||
-set_serial 0x1235 > client-ca-cert.pem
|
||||
check_result $? "Step 3"
|
||||
rm client-ca-cert-req.pem
|
||||
|
||||
openssl x509 -in client-ca-cert.pem -text > tmp.pem
|
||||
check_result $? "Step 4"
|
||||
mv tmp.pem client-ca-cert.pem
|
||||
|
||||
openssl x509 -inform PEM -in client-ca-cert.pem -outform DER \
|
||||
-out client-ca-cert.der
|
||||
check_result $? "Step 5"
|
||||
rm client-ca-ext.cnf
|
||||
echo "End of section"
|
||||
echo "---------------------------------------------------------------------"
|
||||
|
||||
############################################################
|
||||
####### update and sign client-ecc-ca-cert.pem #############
|
||||
############################################################
|
||||
echo "Updating client-ecc-ca-cert.pem"
|
||||
echo ""
|
||||
#pipe the following arguments to openssl req...
|
||||
echo -e "US\\nOregon\\nSalem\\nClient ECC\\nFast\\nwww.wolfssl.com\\n" \
|
||||
"info@wolfssl.com\\n.\\n.\\n" | \
|
||||
openssl req -new -key ecc-client-key.pem -config ./wolfssl.cnf -nodes \
|
||||
> client-ecc-ca-cert-req.pem
|
||||
check_result $? "Step 1"
|
||||
|
||||
openssl x509 -req -in client-ecc-ca-cert-req.pem -extfile wolfssl.cnf \
|
||||
-extensions client_ecc -days 1000 -CA ca-ecc-cert.pem \
|
||||
-CAkey ca-ecc-key.pem -set_serial 0x1234 > client-ecc-ca-cert.pem
|
||||
check_result $? "Step 2"
|
||||
rm client-ecc-ca-cert-req.pem
|
||||
|
||||
openssl x509 -in client-ecc-ca-cert.pem -text > tmp.pem
|
||||
check_result $? "Step 3"
|
||||
mv tmp.pem client-ecc-ca-cert.pem
|
||||
|
||||
openssl x509 -inform PEM -in client-ecc-ca-cert.pem -outform DER \
|
||||
-out client-ecc-ca-cert.der
|
||||
check_result $? "Step 4"
|
||||
echo "End of section"
|
||||
echo "---------------------------------------------------------------------"
|
||||
|
||||
#cleanup the file system now that we're done
|
||||
echo "Performing final steps, cleaning up the file system..."
|
||||
echo ""
|
||||
|
||||
Executable
+146
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Verifies CRLs generated by the C API unit tests (tests/api.c).
|
||||
# Uses OpenSSL to validate CRL structure, signature, and revocation behavior.
|
||||
# RSA: ca-cert.pem + server-cert.pem (revoked) + client-ca-cert.pem (good).
|
||||
# ECC: ca-ecc-cert.pem + server-ecc.pem (revoked) + client-ecc-ca-cert.pem
|
||||
# (good).
|
||||
|
||||
OPENSSL=${OPENSSL:-openssl}
|
||||
|
||||
if ! command -v "$OPENSSL" >/dev/null 2>&1; then
|
||||
echo "skipping crl-gen-openssl.test: openssl not found"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
normalize_dn() {
|
||||
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' \
|
||||
-e 's/^issuer=//' -e 's/^subject=//' \
|
||||
-e 's/[[:space:]]*=[[:space:]]*/=/g' \
|
||||
-e 's/[[:space:]]*,[[:space:]]*/,/g'
|
||||
}
|
||||
|
||||
check_crl() {
|
||||
local crl="$1"
|
||||
local ca_cert="$2"
|
||||
local revoked_cert="$3"
|
||||
local good_cert="$4"
|
||||
local label="$5"
|
||||
|
||||
echo "Checking $label CRL: $crl"
|
||||
|
||||
local issuer subject
|
||||
issuer=$("$OPENSSL" crl -in "$crl" -noout -issuer | normalize_dn)
|
||||
subject=$("$OPENSSL" x509 -in "$ca_cert" -noout -subject | normalize_dn)
|
||||
if [ "$issuer" != "$subject" ]; then
|
||||
echo "issuer mismatch for $label CRL"
|
||||
echo "issuer : $issuer"
|
||||
echo "subject: $subject"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local last_update next_update
|
||||
last_update=$("$OPENSSL" crl -in "$crl" -noout -lastupdate)
|
||||
next_update=$("$OPENSSL" crl -in "$crl" -noout -nextupdate)
|
||||
if [ -z "$last_update" ] || [ -z "$next_update" ]; then
|
||||
echo "missing lastUpdate/nextUpdate for $label CRL"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! "$OPENSSL" crl -in "$crl" -noout -verify -CAfile "$ca_cert" \
|
||||
>/dev/null 2>&1; then
|
||||
echo "CRL signature verification failed for $label"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local revoked_count
|
||||
revoked_count=$("$OPENSSL" crl -in "$crl" -text -noout | \
|
||||
grep -c "Serial Number" || true)
|
||||
if [ "$revoked_count" -ne 4 ]; then
|
||||
echo "unexpected revoked count for $label CRL: $revoked_count " \
|
||||
"(expected 4)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local serial found
|
||||
serial=$("$OPENSSL" x509 -in "$revoked_cert" -noout -serial | cut -d= -f2 \
|
||||
| tr 'A-F' 'a-f' | tr -d ':' | sed 's/^0*//')
|
||||
if [ -z "$serial" ]; then
|
||||
serial=0
|
||||
fi
|
||||
|
||||
found=0
|
||||
while IFS= read -r s; do
|
||||
s=$(printf '%s' "$s" | tr 'A-F' 'a-f' | tr -d '[:space:]:' \
|
||||
| sed 's/^0*//')
|
||||
if [ -z "$s" ]; then
|
||||
s=0
|
||||
fi
|
||||
if [ "$s" = "$serial" ]; then
|
||||
found=1
|
||||
break
|
||||
fi
|
||||
done < <("$OPENSSL" crl -in "$crl" -text -noout | \
|
||||
awk -F: '/Serial Number/ {print $2}')
|
||||
|
||||
if [ "$found" -ne 1 ]; then
|
||||
echo "revoked serial not found in $label CRL: $serial"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local verify_out verify_rc verify_out_norm
|
||||
verify_out=$("$OPENSSL" verify -CAfile "$ca_cert" -crl_check \
|
||||
-CRLfile "$crl" \
|
||||
"$revoked_cert" 2>&1) || verify_rc=$?
|
||||
verify_rc=${verify_rc:-0}
|
||||
# Normalize to avoid case/CR differences and accept common OpenSSL error
|
||||
# formats (some builds report only an error code).
|
||||
verify_out_norm=$(printf '%s' "$verify_out" | tr '[:upper:]' '[:lower:]' | \
|
||||
tr -d '\r')
|
||||
if ! echo "$verify_out_norm" | grep -q "revoked" && \
|
||||
! echo "$verify_out_norm" | grep -q "error 23"; then
|
||||
echo "expected revoked verification failure for $label CRL"
|
||||
echo "$verify_out"
|
||||
return 1
|
||||
fi
|
||||
if [ "$verify_rc" -eq 0 ]; then
|
||||
# Some OpenSSL builds return success even when reporting revocation.
|
||||
# Treat revoked output as authoritative.
|
||||
:
|
||||
fi
|
||||
|
||||
if [ -n "$good_cert" ]; then
|
||||
if ! "$OPENSSL" verify -CAfile "$ca_cert" -crl_check -CRLfile "$crl" \
|
||||
"$good_cert" >/dev/null 2>&1; then
|
||||
echo "expected successful verification for $label CRL with " \
|
||||
"$good_cert"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
crl_rsa="certs/crl/crlRsaOut.pem"
|
||||
crl_ecc="certs/crl/crlEccOut.pem"
|
||||
|
||||
if [ ! -f "$crl_rsa" ] && [ ! -f "$crl_ecc" ]; then
|
||||
echo "skipping crl-gen-openssl.test: CRL outputs not found"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if [ -f "$crl_rsa" ]; then
|
||||
ca_rsa="certs/ca-cert.pem"
|
||||
revoked_rsa="certs/server-cert.pem"
|
||||
good_rsa="certs/client-ca-cert.pem"
|
||||
check_crl "$crl_rsa" "$ca_rsa" "$revoked_rsa" "$good_rsa" "RSA"
|
||||
fi
|
||||
|
||||
if [ -f "$crl_ecc" ]; then
|
||||
ca_ecc="certs/ca-ecc-cert.pem"
|
||||
revoked_ecc="certs/server-ecc.pem"
|
||||
good_ecc="certs/client-ecc-ca-cert.pem"
|
||||
check_crl "$crl_ecc" "$ca_ecc" "$revoked_ecc" "${good_ecc:-}" "ECC"
|
||||
fi
|
||||
|
||||
echo "crl-gen-openssl.test: OK"
|
||||
@@ -18,7 +18,9 @@ if BUILD_RSA
|
||||
if BUILD_CRL
|
||||
# make revoked test rely on completion of resume test
|
||||
dist_noinst_SCRIPTS+= scripts/crl-revoked.test
|
||||
dist_noinst_SCRIPTS+= scripts/crl-gen-openssl.test
|
||||
scripts/crl-revoked.log: scripts/resume.log
|
||||
scripts/crl-gen-openssl.log: scripts/crl-revoked.log
|
||||
endif
|
||||
|
||||
# arrange to serialize ocsp.test, ocsp-stapling.test, ocsp-stapling-with-ca-as-responder.test, ocsp-stapling2.test, and testsuite,
|
||||
|
||||
@@ -40,6 +40,8 @@ CRL Options:
|
||||
#include <wolfssl/internal.h>
|
||||
#include <wolfssl/error-ssl.h>
|
||||
#include <wolfssl/wolfcrypt/logging.h>
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
#include <wolfssl/wolfcrypt/rsa.h>
|
||||
|
||||
#ifndef NO_STRING_H
|
||||
#include <string.h>
|
||||
@@ -817,6 +819,227 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type,
|
||||
return ret ? ret : WOLFSSL_SUCCESS; /* convert 0 to WOLFSSL_SUCCESS */
|
||||
}
|
||||
|
||||
/* Store CRL into a buffer in DER or PEM format.
|
||||
* If buff is NULL, updates inOutSz with required size and returns success.
|
||||
* Returns WOLFSSL_SUCCESS on success, negative on failure.
|
||||
*/
|
||||
int BufferStoreCRL(WOLFSSL_CRL* crl, byte* buff, long* inOutSz, int type)
|
||||
{
|
||||
CRL_Entry* ent = NULL;
|
||||
const byte* tbs = NULL;
|
||||
word32 tbsSz = 0;
|
||||
const byte* sig = NULL;
|
||||
word32 sigSz = 0;
|
||||
word32 sigOID = 0;
|
||||
#ifdef WC_RSA_PSS
|
||||
const byte* sigParams = NULL;
|
||||
word32 sigParamsSz = 0;
|
||||
#endif
|
||||
word32 algoLen = 0;
|
||||
word32 bitHdrLen = 0;
|
||||
word32 totalContentLen = 0;
|
||||
word32 outerHdrLen = 0;
|
||||
word32 derNeeded = 0;
|
||||
long outSz = 0;
|
||||
|
||||
WOLFSSL_ENTER("BufferStoreCRL");
|
||||
|
||||
if (crl == NULL || inOutSz == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
outSz = *inOutSz;
|
||||
|
||||
/* Access the first CRL entry. */
|
||||
if (wc_LockRwLock_Rd(&crl->crlLock) != 0) {
|
||||
WOLFSSL_MSG("wc_LockRwLock_Rd failed");
|
||||
return BAD_MUTEX_E;
|
||||
}
|
||||
ent = crl->crlList;
|
||||
if (ent != NULL) {
|
||||
tbs = ent->toBeSigned;
|
||||
tbsSz = ent->tbsSz;
|
||||
sig = ent->signature;
|
||||
sigSz = ent->signatureSz;
|
||||
sigOID = ent->signatureOID;
|
||||
#ifdef WC_RSA_PSS
|
||||
sigParams = ent->sigParams;
|
||||
sigParamsSz = ent->sigParamsSz;
|
||||
#endif
|
||||
}
|
||||
wc_UnLockRwLock(&crl->crlLock);
|
||||
|
||||
if (ent == NULL || tbs == NULL || tbsSz == 0 || sig == NULL || sigSz == 0) {
|
||||
WOLFSSL_MSG("CRL entry missing toBeSigned/signature data");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Calculate encoded lengths for AlgorithmIdentifier. */
|
||||
#ifdef WC_RSA_PSS
|
||||
if (sigParams != NULL && sigParamsSz > 0) {
|
||||
/* OID + explicit parameters inside SEQUENCE */
|
||||
word32 oidSz = 0;
|
||||
word32 idLen;
|
||||
const byte* oid = OidFromId(sigOID, oidSigType, &oidSz);
|
||||
if (oid == NULL) {
|
||||
WOLFSSL_MSG("Unknown signature OID for CRL");
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
/* OBJECT IDENTIFIER header */
|
||||
idLen = (word32)SetObjectId((int)oidSz, NULL);
|
||||
algoLen = SetSequence(idLen + oidSz + sigParamsSz, NULL)
|
||||
+ idLen + oidSz + sigParamsSz;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
algoLen = SetAlgoID((int)sigOID, NULL, oidSigType, 0);
|
||||
if (algoLen == 0) {
|
||||
WOLFSSL_MSG("SetAlgoID failed");
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* BIT STRING header for signature */
|
||||
bitHdrLen = SetBitString(sigSz, 0, NULL);
|
||||
|
||||
/* Compute total DER size. */
|
||||
totalContentLen = tbsSz + algoLen + bitHdrLen + sigSz;
|
||||
outerHdrLen = SetSequence(totalContentLen, NULL);
|
||||
derNeeded = outerHdrLen + totalContentLen;
|
||||
|
||||
if (type == WOLFSSL_FILETYPE_ASN1) {
|
||||
if (buff == NULL) {
|
||||
*inOutSz = (long)derNeeded;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
if ((long)derNeeded > outSz) {
|
||||
WOLFSSL_MSG("Output buffer too small for DER CRL");
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
/* Encode DER CRL directly into caller buffer. */
|
||||
{
|
||||
word32 pos = 0;
|
||||
#ifdef WC_RSA_PSS
|
||||
word32 oidSz = 0;
|
||||
const byte* oid = NULL;
|
||||
#endif
|
||||
/* Outer SEQUENCE header */
|
||||
pos += SetSequence(totalContentLen, buff + pos);
|
||||
/* tbsCertList */
|
||||
XMEMCPY(buff + pos, tbs, tbsSz);
|
||||
pos += tbsSz;
|
||||
|
||||
/* signatureAlgorithm AlgorithmIdentifier */
|
||||
#ifdef WC_RSA_PSS
|
||||
if (sigParams != NULL && sigParamsSz > 0) {
|
||||
/* Lookup OID bytes for signature algorithm. */
|
||||
oid = OidFromId(sigOID, oidSigType, &oidSz);
|
||||
if (oid == NULL) {
|
||||
WOLFSSL_MSG("Unknown signature OID for CRL");
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
/* SEQUENCE header for AlgorithmIdentifier */
|
||||
pos += SetSequence((word32)SetObjectId((int)oidSz, NULL) +
|
||||
oidSz + sigParamsSz, buff + pos);
|
||||
/* OBJECT IDENTIFIER header and content */
|
||||
pos += (word32)SetObjectId((int)oidSz, buff + pos);
|
||||
XMEMCPY(buff + pos, oid, oidSz);
|
||||
pos += oidSz;
|
||||
/* Parameters as captured (already DER encoded) */
|
||||
XMEMCPY(buff + pos, sigParams, sigParamsSz);
|
||||
pos += sigParamsSz;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
pos += SetAlgoID((int)sigOID, buff + pos, oidSigType, 0);
|
||||
}
|
||||
|
||||
/* signature BIT STRING and bytes */
|
||||
pos += SetBitString(sigSz, 0, buff + pos);
|
||||
XMEMCPY(buff + pos, sig, sigSz);
|
||||
(void)pos; /* pos not used after this point */
|
||||
}
|
||||
|
||||
*inOutSz = (long)derNeeded;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#ifdef WOLFSSL_DER_TO_PEM
|
||||
else if (type == WOLFSSL_FILETYPE_PEM) {
|
||||
byte* derTmp = NULL;
|
||||
int pemSz;
|
||||
/* Build DER first in a temporary buffer. */
|
||||
derTmp = (byte*)XMALLOC(derNeeded, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (derTmp == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
/* Encode DER CRL into temporary buffer. */
|
||||
{
|
||||
word32 pos = 0;
|
||||
#ifdef WC_RSA_PSS
|
||||
word32 oidSz = 0;
|
||||
const byte* oid = NULL;
|
||||
#endif
|
||||
pos += SetSequence(totalContentLen, derTmp + pos);
|
||||
XMEMCPY(derTmp + pos, tbs, tbsSz);
|
||||
pos += tbsSz;
|
||||
#ifdef WC_RSA_PSS
|
||||
if (sigParams != NULL && sigParamsSz > 0) {
|
||||
oid = OidFromId(sigOID, oidSigType, &oidSz);
|
||||
if (oid == NULL) {
|
||||
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
pos += SetSequence((word32)SetObjectId((int)oidSz, NULL) +
|
||||
oidSz + sigParamsSz, derTmp + pos);
|
||||
pos += (word32)SetObjectId((int)oidSz, derTmp + pos);
|
||||
XMEMCPY(derTmp + pos, oid, oidSz);
|
||||
pos += oidSz;
|
||||
XMEMCPY(derTmp + pos, sigParams, sigParamsSz);
|
||||
pos += sigParamsSz;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
pos += SetAlgoID((int)sigOID, derTmp + pos, oidSigType, 0);
|
||||
}
|
||||
pos += SetBitString(sigSz, 0, derTmp + pos);
|
||||
XMEMCPY(derTmp + pos, sig, sigSz);
|
||||
(void)pos; /* pos not used after this point */
|
||||
}
|
||||
|
||||
/* Determine required PEM size. */
|
||||
pemSz = wc_DerToPemEx(derTmp, derNeeded, NULL, 0, NULL, CRL_TYPE);
|
||||
if (pemSz < 0) {
|
||||
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
if (buff == NULL) {
|
||||
*inOutSz = pemSz;
|
||||
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
if (outSz < pemSz) {
|
||||
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
WOLFSSL_MSG("Output buffer too small for PEM CRL");
|
||||
return BUFFER_E;
|
||||
}
|
||||
if (wc_DerToPemEx(derTmp, derNeeded, buff, (word32)pemSz, NULL,
|
||||
CRL_TYPE) < 0) {
|
||||
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
*inOutSz = pemSz;
|
||||
XFREE(derTmp, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
#endif /* WOLFSSL_DER_TO_PEM */
|
||||
else {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_CRL_UPDATE_CB
|
||||
/* Fill out CRL info structure, WOLFSSL_SUCCESS on ok */
|
||||
@@ -1894,5 +2117,732 @@ int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor)
|
||||
}
|
||||
#endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
|
||||
|
||||
#ifndef NO_FILESYSTEM
|
||||
/* Store CRL to a file in DER or PEM format.
|
||||
* Returns WOLFSSL_SUCCESS on success, negative on failure.
|
||||
* @param [in] crl CRL object.
|
||||
* @param [in] path Path to the file to store the CRL.
|
||||
* @param [in] type Format of encoding. Valid values:
|
||||
* WOLFSSL_FILETYPE_ASN1, WOLFSSL_FILETYPE_PEM.
|
||||
* @return WOLFSSL_SUCCESS on success, or negative on failure.
|
||||
*/
|
||||
int StoreCRL(WOLFSSL_CRL* crl, const char* path, int type)
|
||||
{
|
||||
XFILE fp = XBADFILE;
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
long sz = 0;
|
||||
byte* mem = NULL;
|
||||
|
||||
WOLFSSL_ENTER("StoreCRL");
|
||||
|
||||
if (crl == NULL || path == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* Determine required size. */
|
||||
ret = BufferStoreCRL(crl, NULL, &sz, type);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Allocate temporary buffer. */
|
||||
mem = (byte*)XMALLOC((size_t)sz, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (mem == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
/* Encode CRL into buffer. */
|
||||
ret = BufferStoreCRL(crl, mem, &sz, type);
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
/* Open destination file for writing. */
|
||||
fp = XFOPEN(path, "wb");
|
||||
if (fp == XBADFILE) {
|
||||
ret = WOLFSSL_BAD_FILE;
|
||||
}
|
||||
else {
|
||||
size_t wrote = XFWRITE(mem, 1, (size_t)sz, fp);
|
||||
if (wrote != (size_t)sz) {
|
||||
WOLFSSL_MSG("CRL file write failed");
|
||||
ret = FWRITE_ERROR;
|
||||
}
|
||||
XFCLOSE(fp);
|
||||
}
|
||||
}
|
||||
|
||||
XFREE(mem, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
int StoreCRL(WOLFSSL_CRL* crl, const char* file, int type)
|
||||
{
|
||||
(void)crl;
|
||||
(void)file;
|
||||
(void)type;
|
||||
return NOT_COMPILED_IN;
|
||||
}
|
||||
#endif /* NO_FILESYSTEM */
|
||||
|
||||
#if defined(OPENSSL_EXTRA)
|
||||
/* Create a new empty CRL object for generation.
|
||||
* Version is set to 2 by default. Use wolfSSL_X509_CRL_set_version() to
|
||||
* change it.
|
||||
* lastUpdate set to current time, nextUpdate set to 500 days from now.
|
||||
* Returns a new CRL or NULL on failure.
|
||||
*/
|
||||
WOLFSSL_X509_CRL* wolfSSL_X509_CRL_new(void)
|
||||
{
|
||||
WOLFSSL_X509_CRL* crl;
|
||||
CRL_Entry* entry;
|
||||
WOLFSSL_ASN1_TIME asnTime;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_X509_CRL_new");
|
||||
|
||||
crl = (WOLFSSL_X509_CRL*)XMALLOC(sizeof(WOLFSSL_X509_CRL), NULL,
|
||||
DYNAMIC_TYPE_CRL);
|
||||
if (crl == NULL) {
|
||||
WOLFSSL_MSG("Memory allocation failed for CRL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (InitCRL(crl, NULL) < 0) {
|
||||
WOLFSSL_MSG("Init CRL failed");
|
||||
XFREE(crl, NULL, DYNAMIC_TYPE_CRL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate empty CRL entry for setting fields */
|
||||
entry = (CRL_Entry*)XMALLOC(sizeof(CRL_Entry), NULL,
|
||||
DYNAMIC_TYPE_CRL_ENTRY);
|
||||
if (entry == NULL) {
|
||||
WOLFSSL_MSG("Memory allocation failed for CRL entry");
|
||||
FreeCRL(crl, 1);
|
||||
return NULL;
|
||||
}
|
||||
XMEMSET(entry, 0, sizeof(CRL_Entry));
|
||||
|
||||
if (wc_InitMutex(&entry->verifyMutex) != 0) {
|
||||
XFREE(entry, NULL, DYNAMIC_TYPE_CRL_ENTRY);
|
||||
FreeCRL(crl, 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
crl->crlList = entry;
|
||||
|
||||
/* Set thisUpdate to current time */
|
||||
if (wolfSSL_ASN1_TIME_adj(&asnTime, XTIME(NULL), 0, 0) == NULL) {
|
||||
WOLFSSL_MSG("Failed to get current time");
|
||||
FreeCRL(crl, 1);
|
||||
return NULL;
|
||||
}
|
||||
if (wolfSSL_X509_CRL_set_lastUpdate(crl, &asnTime) != WOLFSSL_SUCCESS) {
|
||||
WOLFSSL_MSG("Failed to set last update");
|
||||
FreeCRL(crl, 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set next update date to 500 days from now,
|
||||
* following convention from wc_InitCert() */
|
||||
if (wolfSSL_ASN1_TIME_adj(&asnTime, XTIME(NULL), 500, 0) == NULL) {
|
||||
WOLFSSL_MSG("Failed to get next update time");
|
||||
FreeCRL(crl, 1);
|
||||
return NULL;
|
||||
}
|
||||
if (wolfSSL_X509_CRL_set_nextUpdate(crl, &asnTime) != WOLFSSL_SUCCESS) {
|
||||
WOLFSSL_MSG("Failed to set next update");
|
||||
FreeCRL(crl, 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set default version to v2 (required for extensions) */
|
||||
entry->version = 2;
|
||||
|
||||
return crl;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_CERT_GEN
|
||||
/* Add a revoked certificate entry to CRL.
|
||||
* crl: target CRL
|
||||
* rev: serial number of revoked certificate
|
||||
* Returns WOLFSSL_SUCCESS on success.
|
||||
* TODO: support other fields for OpenSSL compatibility: revocationDate,
|
||||
* extensions, issuer, etc.
|
||||
*/
|
||||
int wolfSSL_X509_CRL_add_revoked(WOLFSSL_X509_CRL* crl,
|
||||
WOLFSSL_X509_REVOKED* rev)
|
||||
{
|
||||
CRL_Entry* entry;
|
||||
RevokedCert* rc;
|
||||
RevokedCert* curr;
|
||||
WOLFSSL_ASN1_TIME revDate;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_X509_CRL_add_revoked");
|
||||
|
||||
if (crl == NULL || rev == NULL || rev->serialNumber == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
entry = crl->crlList;
|
||||
if (entry == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Set the revocation date to the current time */
|
||||
XMEMSET(&revDate, 0, sizeof(revDate));
|
||||
if (wolfSSL_ASN1_TIME_adj(&revDate, XTIME(NULL), 0, 0) == NULL) {
|
||||
WOLFSSL_MSG("Failed to get current time");
|
||||
return BAD_STATE_E;
|
||||
}
|
||||
|
||||
{
|
||||
const byte* serial = rev->serialNumber->data;
|
||||
int serialSz = rev->serialNumber->length;
|
||||
int i;
|
||||
int allZero = 1;
|
||||
|
||||
if (serial == NULL || serialSz <= 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (serialSz > EXTERNAL_SERIAL_SIZE) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* All zero serial numbers are invalid per rfc5280 and not supported */
|
||||
for (i = 0; i < serialSz; i++) {
|
||||
if (serial[i] != 0) {
|
||||
allZero = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allZero) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
rc = (RevokedCert*)XMALLOC(sizeof(RevokedCert), crl->heap,
|
||||
DYNAMIC_TYPE_REVOKED);
|
||||
if (rc == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(rc, 0, sizeof(RevokedCert));
|
||||
|
||||
XMEMCPY(rc->serialNumber, serial, (size_t)serialSz);
|
||||
rc->serialSz = serialSz;
|
||||
}
|
||||
|
||||
XMEMCPY(rc->revDate, revDate.data, revDate.length);
|
||||
rc->revDateFormat = (byte)revDate.type;
|
||||
rc->next = NULL;
|
||||
|
||||
/* Add to end of list */
|
||||
if (entry->certs == NULL) {
|
||||
entry->certs = rc;
|
||||
}
|
||||
else {
|
||||
for (curr = entry->certs; curr->next != NULL; curr = curr->next)
|
||||
;
|
||||
curr->next = rc;
|
||||
}
|
||||
entry->totalCerts++;
|
||||
|
||||
WOLFSSL_LEAVE("wolfSSL_X509_CRL_add_revoked", WOLFSSL_SUCCESS);
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
/* Add a revoked certificate entry to CRL by parsing a certificate buffer.
|
||||
* crl: target CRL
|
||||
* certBuf: DER-encoded certificate buffer
|
||||
* certSz: size of certificate buffer
|
||||
* revDate: revocation date (ASN.1 format), or NULL for
|
||||
* current time
|
||||
* revDateFmt: date format (ASN_UTC_TIME or ASN_GENERALIZED_TIME), ignored if
|
||||
* revDate is NULL
|
||||
* Returns WOLFSSL_SUCCESS on success.
|
||||
* Note: this function is only available when WOLFSSL_CERT_GEN is defined.
|
||||
*/
|
||||
int wolfSSL_X509_CRL_add_revoked_cert(WOLFSSL_X509_CRL* crl,
|
||||
const unsigned char* certBuf, int certSz)
|
||||
{
|
||||
int ret;
|
||||
DecodedCert* cert = NULL;
|
||||
WOLFSSL_X509_REVOKED revoked;
|
||||
WOLFSSL_ASN1_INTEGER* serialInt = NULL;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_X509_CRL_add_revoked_cert");
|
||||
|
||||
if (crl == NULL || certBuf == NULL || certSz <= 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT);
|
||||
if (cert == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
/* Initialize and parse the certificate */
|
||||
InitDecodedCert(cert, certBuf, (word32)certSz, NULL);
|
||||
ret = ParseCertRelative(cert, CERT_TYPE, NO_VERIFY, NULL, NULL);
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("Failed to parse certificate");
|
||||
FreeDecodedCert(cert);
|
||||
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
serialInt = wolfSSL_ASN1_INTEGER_new();
|
||||
if (serialInt == NULL) {
|
||||
FreeDecodedCert(cert);
|
||||
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
|
||||
return MEMORY_E;
|
||||
}
|
||||
|
||||
if (cert->serialSz > WOLFSSL_ASN1_INTEGER_MAX) {
|
||||
serialInt->data = (unsigned char*)XMALLOC(cert->serialSz, NULL,
|
||||
DYNAMIC_TYPE_OPENSSL);
|
||||
if (serialInt->data == NULL) {
|
||||
wolfSSL_ASN1_INTEGER_free(serialInt);
|
||||
FreeDecodedCert(cert);
|
||||
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
|
||||
return MEMORY_E;
|
||||
}
|
||||
serialInt->dataMax = (unsigned int)cert->serialSz;
|
||||
serialInt->isDynamic = 1;
|
||||
}
|
||||
else {
|
||||
serialInt->data = serialInt->intData;
|
||||
serialInt->dataMax = WOLFSSL_ASN1_INTEGER_MAX;
|
||||
}
|
||||
|
||||
XMEMCPY(serialInt->data, cert->serial, cert->serialSz);
|
||||
serialInt->length = cert->serialSz;
|
||||
|
||||
revoked.serialNumber = serialInt;
|
||||
|
||||
/* Add the revoked certificate entry */
|
||||
ret = wolfSSL_X509_CRL_add_revoked(crl, &revoked);
|
||||
|
||||
FreeDecodedCert(cert);
|
||||
XFREE(cert, NULL, DYNAMIC_TYPE_DCERT);
|
||||
wolfSSL_ASN1_INTEGER_free(serialInt);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int GetCrlSignBufSz(int tbsSz, int sigType, RsaKey* rsaKey,
|
||||
ecc_key* eccKey)
|
||||
{
|
||||
int sigSz = 0;
|
||||
int ret;
|
||||
byte sigDummy = 0;
|
||||
|
||||
if (tbsSz <= 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifndef NO_RSA
|
||||
if (rsaKey != NULL) {
|
||||
sigSz = wc_RsaEncryptSize(rsaKey);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
if (sigSz <= 0 && eccKey != NULL) {
|
||||
sigSz = wc_ecc_sig_size(eccKey);
|
||||
}
|
||||
#endif
|
||||
if (sigSz <= 0) {
|
||||
/* Fallback for unexpected key sizes */
|
||||
sigSz = 1024;
|
||||
}
|
||||
|
||||
/* Estimate total CRL size by asking AddSignature for the DER wrapper
|
||||
* size (sequence + algo OID + BIT STRING headers). If it fails (e.g.,
|
||||
* unknown sigType), fall back to a conservative headroom of 64 bytes for
|
||||
* those headers. This is defensive (size-estimate only); the real sign
|
||||
* path will still report any unsupported sigType. */
|
||||
ret = AddSignature(NULL, tbsSz, &sigDummy, sigSz, sigType);
|
||||
if (ret < 0) {
|
||||
ret = tbsSz + sigSz + 64;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Sign a CRL with a private key, rebuilding TBS from fields.
|
||||
* crl: CRL with fields set via setter functions
|
||||
* pkey: private key for signing
|
||||
* md: digest algorithm (e.g., EVP_sha256())
|
||||
* Note: only one entry is supported in the CRL list.
|
||||
* Returns WOLFSSL_SUCCESS on success.
|
||||
*/
|
||||
int wolfSSL_X509_CRL_sign(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* pkey,
|
||||
const WOLFSSL_EVP_MD* md)
|
||||
{
|
||||
int ret = WOLFSSL_SUCCESS;
|
||||
CRL_Entry* entry;
|
||||
byte* issuerDer = NULL;
|
||||
int issuerSz = 0;
|
||||
int sigType;
|
||||
int tbsSz = 0;
|
||||
int totalSz = 0;
|
||||
byte* buf = NULL;
|
||||
int bufSz = 0;
|
||||
RsaKey* rsaKey = NULL;
|
||||
ecc_key* eccKey = NULL;
|
||||
WC_RNG rng;
|
||||
int rngInit = 0;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_X509_CRL_sign");
|
||||
|
||||
if (crl == NULL || pkey == NULL || md == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Fetch only the first entry in the CRL list */
|
||||
entry = crl->crlList;
|
||||
if (entry == NULL) {
|
||||
WOLFSSL_MSG("CRL has no entry");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Determine signature type from digest and key type */
|
||||
#ifndef NO_RSA
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (pkey->type == WC_EVP_PKEY_RSA) {
|
||||
if (md == wolfSSL_EVP_sha256()) {
|
||||
sigType = CTC_SHA256wRSA;
|
||||
}
|
||||
#ifdef WOLFSSL_SHA384
|
||||
else if (md == wolfSSL_EVP_sha384()) {
|
||||
sigType = CTC_SHA384wRSA;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
else if (md == wolfSSL_EVP_sha512()) {
|
||||
sigType = CTC_SHA512wRSA;
|
||||
}
|
||||
#endif
|
||||
else if (md == wolfSSL_EVP_sha1()) {
|
||||
sigType = CTC_SHAwRSA;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("Unsupported digest for RSA");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
rsaKey = (RsaKey*)pkey->rsa->internal;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
if (pkey->type == WC_EVP_PKEY_EC) {
|
||||
if (md == wolfSSL_EVP_sha256()) {
|
||||
sigType = CTC_SHA256wECDSA;
|
||||
}
|
||||
#ifdef WOLFSSL_SHA384
|
||||
else if (md == wolfSSL_EVP_sha384()) {
|
||||
sigType = CTC_SHA384wECDSA;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
else if (md == wolfSSL_EVP_sha512()) {
|
||||
sigType = CTC_SHA512wECDSA;
|
||||
}
|
||||
#endif
|
||||
else if (md == wolfSSL_EVP_sha1()) {
|
||||
sigType = CTC_SHAwECDSA;
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("Unsupported digest for ECDSA");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
eccKey = (ecc_key*)pkey->ecc->internal;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
WOLFSSL_MSG("Unsupported key type");
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get issuer name DER */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (entry->issuer != NULL) {
|
||||
/* Retrieve the issuer in two passes so we can avoid making
|
||||
* assumptions about the heap that is used, as we must free
|
||||
* this buffer later. */
|
||||
issuerSz = wolfSSL_i2d_X509_NAME(entry->issuer, NULL);
|
||||
if (issuerSz <= 0) {
|
||||
WOLFSSL_MSG("Failed to encode issuer name");
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
else {
|
||||
issuerDer = (byte*)XMALLOC((size_t)issuerSz, crl->heap,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (issuerDer == NULL) {
|
||||
WOLFSSL_MSG("Memory allocation failed for issuer DER");
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
else {
|
||||
/* i2d moves the pointer, so use a temp */
|
||||
byte* tempPtr = issuerDer;
|
||||
if (wolfSSL_i2d_X509_NAME(entry->issuer, &tempPtr) <= 0) {
|
||||
WOLFSSL_MSG("Failed to encode issuer name");
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
WOLFSSL_MSG("CRL has no issuer set");
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy dates from ASN1 time structures to raw fields if needed */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (entry->lastDateAsn1.length > 0 && entry->lastDateFormat == 0) {
|
||||
XMEMCPY(entry->lastDate, entry->lastDateAsn1.data,
|
||||
(size_t)entry->lastDateAsn1.length);
|
||||
entry->lastDateFormat = (byte)entry->lastDateAsn1.type;
|
||||
}
|
||||
if (entry->nextDateAsn1.length > 0 && entry->nextDateFormat == 0) {
|
||||
XMEMCPY(entry->nextDate, entry->nextDateAsn1.data,
|
||||
(size_t)entry->nextDateAsn1.length);
|
||||
entry->nextDateFormat = (byte)entry->nextDateAsn1.type;
|
||||
}
|
||||
}
|
||||
|
||||
/* Verify we have valid dates */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (entry->lastDateFormat == 0) {
|
||||
WOLFSSL_MSG("CRL has no lastUpdate date set");
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize RNG */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (wc_InitRng(&rng) != 0) {
|
||||
WOLFSSL_MSG("RNG init failed");
|
||||
ret = WOLFSSL_FAILURE;
|
||||
}
|
||||
else {
|
||||
rngInit = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
const byte* crlNumber = NULL;
|
||||
word32 crlNumberSz = 0;
|
||||
|
||||
if (entry->crlNumberSet) {
|
||||
crlNumber = (const byte*)entry->crlNumber;
|
||||
crlNumberSz = CRL_MAX_NUM_SZ;
|
||||
}
|
||||
|
||||
/* Determine TBS size, but this does not include the outer signature
|
||||
* wrapper (AlgorithmIdentifier, BIT STRING and outer SEQUENCE) */
|
||||
bufSz = wc_MakeCRL_ex(issuerDer, (word32)issuerSz,
|
||||
entry->lastDate, entry->lastDateFormat,
|
||||
entry->nextDate, entry->nextDateFormat,
|
||||
entry->certs, crlNumber, crlNumberSz,
|
||||
sigType, entry->version, NULL, 0);
|
||||
if (bufSz < 0) {
|
||||
WOLFSSL_MSG("wc_MakeCRL_ex size check failed");
|
||||
ret = bufSz;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
bufSz = GetCrlSignBufSz(bufSz, sigType, rsaKey, eccKey);
|
||||
if (bufSz <= 0) {
|
||||
WOLFSSL_MSG("CRL buffer size calc failed");
|
||||
ret = bufSz;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate working buffer for TBS + signature */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
buf = (byte*)XMALLOC(bufSz, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (buf == NULL) {
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
}
|
||||
|
||||
/* Build to-be-signed (TBS) portion of the CRL buffer.
|
||||
* Note that we pass the fields rather than the CRL_entry struct so
|
||||
* wolfcrypt need not know about the openSSL-compatible CRL_entry struct.
|
||||
*/
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
const byte* crlNumber = NULL;
|
||||
word32 crlNumberSz = 0;
|
||||
|
||||
if (entry->crlNumberSet) {
|
||||
crlNumber = (const byte*)entry->crlNumber;
|
||||
crlNumberSz = CRL_MAX_NUM_SZ;
|
||||
}
|
||||
|
||||
tbsSz = wc_MakeCRL_ex(issuerDer, (word32)issuerSz,
|
||||
entry->lastDate, entry->lastDateFormat,
|
||||
entry->nextDate, entry->nextDateFormat,
|
||||
entry->certs, crlNumber, crlNumberSz,
|
||||
sigType,
|
||||
entry->version, buf, bufSz);
|
||||
if (tbsSz < 0) {
|
||||
WOLFSSL_MSG("wc_MakeCRL_ex failed");
|
||||
ret = tbsSz;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sign and complete CRL. Note that the output buffer is the same as the
|
||||
* input buffer. The signature is added to the end of the buffer.
|
||||
*/
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
totalSz = wc_SignCRL_ex(buf, tbsSz, sigType, buf, bufSz,
|
||||
rsaKey, eccKey, &rng);
|
||||
if (totalSz < 0) {
|
||||
WOLFSSL_MSG("wc_SignCRL_ex failed");
|
||||
ret = totalSz;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update CRL entry with new toBeSigned and signature. Build the new
|
||||
* buffers first and only commit to entry on full success. */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
byte* newToBeSigned = NULL;
|
||||
byte* newSignature = NULL;
|
||||
word32 newTbsSz = 0;
|
||||
word32 newSignatureSz = 0;
|
||||
word32 newSignatureOid = 0;
|
||||
|
||||
/* Extract TBS and signature from the complete CRL buffer.
|
||||
* After AddSignature, the buffer layout is:
|
||||
* [outer SEQUENCE header][TBS][AlgorithmIdentifier][BIT STRING sig]
|
||||
*/
|
||||
{
|
||||
word32 idx = 0;
|
||||
int len;
|
||||
word32 tbsStart = 0;
|
||||
word32 tbsLen = 0;
|
||||
int sigLen;
|
||||
|
||||
/* Parse outer SEQUENCE */
|
||||
if (GetSequence(buf, &idx, &len, (word32)totalSz) < 0) {
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
|
||||
/* TBS starts here */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
tbsStart = idx;
|
||||
}
|
||||
|
||||
/* Parse TBS SEQUENCE to get its length */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (GetSequence(buf, &idx, &len, (word32)totalSz) < 0) {
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
}
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
tbsLen = idx + (word32)len - tbsStart;
|
||||
idx = tbsStart + tbsLen; /* Move past TBS */
|
||||
}
|
||||
|
||||
/* Allocate and copy TBS */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
newToBeSigned = (byte*)XMALLOC(tbsLen, crl->heap,
|
||||
DYNAMIC_TYPE_CRL_ENTRY);
|
||||
if (newToBeSigned == NULL) {
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
}
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
XMEMCPY(newToBeSigned, buf + tbsStart, tbsLen);
|
||||
newTbsSz = tbsLen;
|
||||
}
|
||||
|
||||
/* Skip AlgorithmIdentifier */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (GetAlgoId(buf, &idx, (word32*)&len, oidSigType,
|
||||
(word32)totalSz) < 0) {
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get BIT STRING */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (GetASNHeader(buf, ASN_BIT_STRING, &idx, &sigLen,
|
||||
(word32)totalSz) < 0) {
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip unused bits byte */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (idx >= (word32)totalSz || sigLen <= 0 || buf[idx] != 0) {
|
||||
ret = ASN_PARSE_E;
|
||||
}
|
||||
}
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
idx++;
|
||||
sigLen--;
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
newSignature = (byte*)XMALLOC((word32)sigLen, crl->heap,
|
||||
DYNAMIC_TYPE_CRL_ENTRY);
|
||||
if (newSignature == NULL) {
|
||||
ret = MEMORY_E;
|
||||
}
|
||||
}
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
XMEMCPY(newSignature, buf + idx, (size_t)sigLen);
|
||||
newSignatureSz = (word32)sigLen;
|
||||
newSignatureOid = (word32)sigType;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (entry->toBeSigned != NULL) {
|
||||
XFREE(entry->toBeSigned, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
|
||||
entry->toBeSigned = NULL;
|
||||
}
|
||||
if (entry->signature != NULL) {
|
||||
XFREE(entry->signature, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
|
||||
entry->signature = NULL;
|
||||
}
|
||||
|
||||
entry->toBeSigned = newToBeSigned;
|
||||
entry->tbsSz = newTbsSz;
|
||||
entry->signature = newSignature;
|
||||
entry->signatureSz = newSignatureSz;
|
||||
entry->signatureOID = newSignatureOid;
|
||||
}
|
||||
else {
|
||||
if (newToBeSigned != NULL) {
|
||||
XFREE(newToBeSigned, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
|
||||
}
|
||||
if (newSignature != NULL) {
|
||||
XFREE(newSignature, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark the CRL as verified/signed for future reference. */
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
entry->verified = 1;
|
||||
}
|
||||
|
||||
if (issuerDer) {
|
||||
XFREE(issuerDer, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (buf) {
|
||||
XFREE(buf, crl->heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
}
|
||||
if (rngInit) {
|
||||
wc_FreeRng(&rng);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_CERT_GEN */
|
||||
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
|
||||
#endif /* HAVE_CRL */
|
||||
#endif /* !WOLFCRYPT_ONLY */
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
#define ASN_LEN_SIZE(l) \
|
||||
(((l) < 128) ? 1 : (((l) < 256) ? 2 : 3))
|
||||
|
||||
#if defined(OPENSSL_EXTRA)
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
|
||||
#ifndef NO_ASN
|
||||
|
||||
@@ -112,7 +112,7 @@ static int pem_mem_to_der(const char* pem, int pemSz, wc_pem_password_cb* cb,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(NO_RSA) || !defined(WOLFCRYPT_ONLY)
|
||||
#if defined(OPENSSL_EXTRA) && (!defined(NO_RSA) || !defined(WOLFCRYPT_ONLY))
|
||||
#ifndef NO_BIO
|
||||
/* Read PEM data from a BIO and decode to DER in a new buffer.
|
||||
*
|
||||
@@ -291,9 +291,10 @@ static int der_write_to_bio_as_pem(const unsigned char* der, int derSz,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) || \
|
||||
#if defined(OPENSSL_EXTRA) && \
|
||||
((!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) || \
|
||||
(!defined(NO_DH) && defined(WOLFSSL_DH_EXTRA)) || \
|
||||
(defined(HAVE_ECC) && defined(WOLFSSL_KEY_GEN))
|
||||
(defined(HAVE_ECC) && defined(WOLFSSL_KEY_GEN)))
|
||||
#if !defined(NO_FILESYSTEM)
|
||||
/* Write the DER data as PEM into file pointer.
|
||||
*
|
||||
@@ -327,7 +328,8 @@ static int der_write_to_file_as_pem(const unsigned char* der, int derSz,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_KEY_GEN) && defined(WOLFSSL_PEM_TO_DER)
|
||||
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && \
|
||||
defined(WOLFSSL_PEM_TO_DER)
|
||||
/* Encrypt private key into PEM format.
|
||||
*
|
||||
* DER is encrypted in place.
|
||||
@@ -449,10 +451,10 @@ int EncryptDerKey(byte *der, int *derSz, const WOLFSSL_EVP_CIPHER* cipher,
|
||||
WC_FREE_VAR_EX(info, NULL, DYNAMIC_TYPE_ENCRYPTEDINFO);
|
||||
return ret == 0;
|
||||
}
|
||||
#endif /* WOLFSSL_KEY_GEN || WOLFSSL_PEM_TO_DER */
|
||||
#endif /* OPENSSL_EXTRA && WOLFSSL_KEY_GEN && WOLFSSL_PEM_TO_DER */
|
||||
|
||||
|
||||
#if defined(WOLFSSL_KEY_GEN) && \
|
||||
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_KEY_GEN) && \
|
||||
(defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)) && \
|
||||
(!defined(NO_RSA) || defined(HAVE_ECC))
|
||||
/* Encrypt the DER in PEM format.
|
||||
@@ -681,7 +683,8 @@ static int pk_bn_field_print_fp(XFILE fp, int indent, const char* field,
|
||||
#endif /* !NO_CERTS && XFPRINTF && !NO_FILESYSTEM && !NO_STDIO_FILESYSTEM &&
|
||||
* (!NO_DSA || !NO_RSA || HAVE_ECC) */
|
||||
|
||||
#if defined(XSNPRINTF) && !defined(NO_BIO) && !defined(NO_RSA)
|
||||
#if defined(OPENSSL_EXTRA) && defined(XSNPRINTF) && !defined(NO_BIO) && \
|
||||
!defined(NO_RSA)
|
||||
/* snprintf() must be available */
|
||||
|
||||
/* Maximum number of extra indent spaces on each line. */
|
||||
@@ -890,7 +893,7 @@ static int wolfssl_print_number(WOLFSSL_BIO* bio, mp_int* num, const char* name,
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* XSNPRINTF && !NO_BIO && !NO_RSA */
|
||||
#endif /* OPENSSL_EXTRA && XSNPRINTF && !NO_BIO && !NO_RSA */
|
||||
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
|
||||
@@ -7306,4 +7309,3 @@ int wolfSSL_PEM_write_PKCS8PrivateKey(XFILE f, WOLFSSL_EVP_PKEY* pkey,
|
||||
******************************************************************************/
|
||||
|
||||
#endif /* !WOLFSSL_PK_INCLUDED */
|
||||
|
||||
|
||||
@@ -17272,6 +17272,10 @@ int wolfSSL_set_alpn_protos(WOLFSSL* ssl,
|
||||
#include "src/bio.c"
|
||||
#endif
|
||||
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
|
||||
word32 nid2oid(int nid, int grp)
|
||||
{
|
||||
/* get OID type */
|
||||
@@ -18039,6 +18043,10 @@ int oid2nid(word32 oid, int grp)
|
||||
return WOLFSSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
|
||||
|
||||
#if defined(OPENSSL_EXTRA)
|
||||
|
||||
/* frees all nodes in the current threads error queue
|
||||
*
|
||||
* id thread id. ERR_remove_state is depreciated and id is ignored. The
|
||||
|
||||
+13
-6
@@ -722,7 +722,8 @@ void* wolfSSL_ASN1_item_d2i(void** dst, const byte **src, long len,
|
||||
* ASN1_BIT_STRING APIs
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
|
||||
defined(WOLFSSL_WPAS_SMALL)
|
||||
/* Create a new ASN.1 BIT_STRING object.
|
||||
*
|
||||
* @return ASN.1 BIT_STRING object on success.
|
||||
@@ -4551,7 +4552,8 @@ int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a)
|
||||
* ASN1_TYPE APIs
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
|
||||
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
|
||||
defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_WPAS_SMALL)
|
||||
|
||||
/**
|
||||
* Allocate a new ASN.1 TYPE object.
|
||||
@@ -4625,6 +4627,11 @@ void wolfSSL_ASN1_TYPE_free(WOLFSSL_ASN1_TYPE* at)
|
||||
XFREE(at, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL ||
|
||||
WOLFSSL_WPAS_SMALL */
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
|
||||
|
||||
int wolfSSL_i2d_ASN1_TYPE(WOLFSSL_ASN1_TYPE* at, unsigned char** pp)
|
||||
{
|
||||
int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
|
||||
@@ -4662,8 +4669,8 @@ int wolfSSL_i2d_ASN1_TYPE(WOLFSSL_ASN1_TYPE* at, unsigned char** pp)
|
||||
|
||||
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
|
||||
|
||||
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS) || \
|
||||
defined(WOLFSSL_WPAS_SMALL)
|
||||
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
|
||||
defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_WPAS_SMALL)
|
||||
/**
|
||||
* Set ASN.1 TYPE object with a type and value.
|
||||
*
|
||||
@@ -4727,9 +4734,9 @@ int wolfSSL_ASN1_TYPE_get(const WOLFSSL_ASN1_TYPE *a)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || WOLFSSL_WPAS */
|
||||
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL ||
|
||||
WOLFSSL_WPAS_SMALL */
|
||||
|
||||
#endif /* !NO_ASN */
|
||||
|
||||
#endif /* !WOLFSSL_SSL_ASN1_INCLUDED */
|
||||
|
||||
|
||||
+247
-26
@@ -9292,7 +9292,7 @@ WOLFSSL_X509_CRL* wolfSSL_d2i_X509_CRL(WOLFSSL_X509_CRL** crl,
|
||||
* return X509_NAME* on success
|
||||
* return NULL on failure
|
||||
*/
|
||||
WOLFSSL_X509_NAME* wolfSSL_X509_CRL_get_issuer_name(WOLFSSL_X509_CRL* crl)
|
||||
WOLFSSL_X509_NAME* wolfSSL_X509_CRL_get_issuer_name(const WOLFSSL_X509_CRL* crl)
|
||||
{
|
||||
if (crl == NULL || crl->crlList == NULL)
|
||||
return NULL;
|
||||
@@ -9300,6 +9300,31 @@ WOLFSSL_X509_NAME* wolfSSL_X509_CRL_get_issuer_name(WOLFSSL_X509_CRL* crl)
|
||||
return crl->crlList->issuer;
|
||||
}
|
||||
|
||||
/* Set issuer name of CRL
|
||||
* return WOLFSSL_SUCCESS on success
|
||||
* return WOLFSSL_FAILURE on failure
|
||||
*/
|
||||
int wolfSSL_X509_CRL_set_issuer_name(WOLFSSL_X509_CRL* crl,
|
||||
const WOLFSSL_X509_NAME* name)
|
||||
{
|
||||
WOLFSSL_X509_NAME* newName;
|
||||
|
||||
if (crl == NULL || crl->crlList == NULL || name == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
newName = wolfSSL_X509_NAME_dup(name);
|
||||
if (newName == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
if (crl->crlList->issuer != NULL) {
|
||||
FreeX509Name(crl->crlList->issuer);
|
||||
XFREE(crl->crlList->issuer, crl->heap, DYNAMIC_TYPE_X509);
|
||||
}
|
||||
crl->crlList->issuer = newName;
|
||||
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
/* Retrieve version from CRL
|
||||
* return version on success
|
||||
* return 0 on failure
|
||||
@@ -9312,6 +9337,27 @@ int wolfSSL_X509_CRL_version(WOLFSSL_X509_CRL* crl)
|
||||
return crl->crlList->version;
|
||||
}
|
||||
|
||||
/* Set version of CRL
|
||||
* Caller passes the RFC 5280 value: 0 for v1, 1 for v2.
|
||||
* Internally wolfSSL stores version + 1 (v1 = 1, v2 = 2) to match
|
||||
* what ParseCRL produces, so apply the same normalization here.
|
||||
* return WOLFSSL_SUCCESS on success
|
||||
* return WOLFSSL_FAILURE on failure
|
||||
*/
|
||||
int wolfSSL_X509_CRL_set_version(WOLFSSL_X509_CRL* crl, long version)
|
||||
{
|
||||
if (crl == NULL || crl->crlList == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
/* Only v1 (0) and v2 (1) are defined by RFC 5280. */
|
||||
if (version < 0 || version > 1)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
/* Store as version + 1 to match internal convention. */
|
||||
crl->crlList->version = (int)version + 1;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
/* Retrieve sig OID from CRL
|
||||
* return OID on success
|
||||
* return 0 on failure
|
||||
@@ -9324,6 +9370,20 @@ int wolfSSL_X509_CRL_get_signature_type(WOLFSSL_X509_CRL* crl)
|
||||
return crl->crlList->signatureOID;
|
||||
}
|
||||
|
||||
/* Set signature type of CRL
|
||||
* return WOLFSSL_SUCCESS on success
|
||||
* return WOLFSSL_FAILURE on failure
|
||||
*/
|
||||
int wolfSSL_X509_CRL_set_signature_type(WOLFSSL_X509_CRL* crl,
|
||||
int signatureType)
|
||||
{
|
||||
if (crl == NULL || crl->crlList == NULL)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
crl->crlList->signatureOID = signatureType;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
/* Retrieve sig NID from CRL
|
||||
* return NID on success
|
||||
* return 0 on failure
|
||||
@@ -9336,6 +9396,19 @@ int wolfSSL_X509_CRL_get_signature_nid(const WOLFSSL_X509_CRL* crl)
|
||||
return oid2nid(crl->crlList->signatureOID, oidSigType);
|
||||
}
|
||||
|
||||
/* Set signature NID of CRL
|
||||
* return OID on success
|
||||
* return negative value on failure
|
||||
*/
|
||||
int wolfSSL_X509_CRL_set_signature_nid(WOLFSSL_X509_CRL* crl, int nid)
|
||||
{
|
||||
if (crl == NULL || crl->crlList == NULL || nid <= 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
crl->crlList->signatureOID = nid2oid(nid, oidSigType);
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
/* Retrieve signature from CRL
|
||||
* return WOLFSSL_SUCCESS on success and negative values on failure
|
||||
*/
|
||||
@@ -9362,6 +9435,45 @@ int wolfSSL_X509_CRL_get_signature(WOLFSSL_X509_CRL* crl,
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
int wolfSSL_X509_CRL_set_signature(WOLFSSL_X509_CRL* crl,
|
||||
unsigned char* buf, int bufSz)
|
||||
{
|
||||
byte* newSig;
|
||||
|
||||
if (crl == NULL || crl->crlList == NULL || buf == NULL || bufSz <= 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Ensure signature buffer is allocated and large enough. */
|
||||
if (crl->crlList->signature == NULL) {
|
||||
crl->crlList->signature = (byte*)XMALLOC((word32)bufSz, crl->heap,
|
||||
DYNAMIC_TYPE_CRL_ENTRY);
|
||||
if (crl->crlList->signature == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
crl->crlList->signatureSz = (word32)bufSz;
|
||||
}
|
||||
else if ((word32)bufSz > crl->crlList->signatureSz) {
|
||||
newSig = (byte*)XMALLOC((word32)bufSz, crl->heap,
|
||||
DYNAMIC_TYPE_CRL_ENTRY);
|
||||
if (newSig == NULL) {
|
||||
return MEMORY_E;
|
||||
}
|
||||
XFREE(crl->crlList->signature, crl->heap, DYNAMIC_TYPE_CRL_ENTRY);
|
||||
crl->crlList->signature = newSig;
|
||||
crl->crlList->signatureSz = (word32)bufSz;
|
||||
}
|
||||
else {
|
||||
/* Reuse existing buffer, clear contents in case new signature
|
||||
* is smaller. Note that we do not shrink the buffer. */
|
||||
XMEMSET(crl->crlList->signature, 0, crl->crlList->signatureSz);
|
||||
}
|
||||
|
||||
XMEMCPY(crl->crlList->signature, buf, bufSz);
|
||||
crl->crlList->signatureSz = (word32)bufSz;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
|
||||
/* Retrieve serial number from RevokedCert
|
||||
* return WOLFSSL_SUCCESS on success and negative values on failure
|
||||
*/
|
||||
@@ -9843,8 +9955,17 @@ WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl)
|
||||
(crl->crlList->lastDateAsn1.data[0] != 0)) {
|
||||
return &crl->crlList->lastDateAsn1;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int wolfSSL_X509_CRL_set_lastUpdate(WOLFSSL_X509_CRL* crl,
|
||||
const WOLFSSL_ASN1_TIME* time)
|
||||
{
|
||||
if (crl != NULL && crl->crlList != NULL && time != NULL) {
|
||||
crl->crlList->lastDateAsn1 = *time;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
|
||||
@@ -9853,8 +9974,17 @@ WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl)
|
||||
(crl->crlList->nextDateAsn1.data[0] != 0)) {
|
||||
return &crl->crlList->nextDateAsn1;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int wolfSSL_X509_CRL_set_nextUpdate(WOLFSSL_X509_CRL* crl,
|
||||
const WOLFSSL_ASN1_TIME* time)
|
||||
{
|
||||
if (crl != NULL && crl->crlList != NULL && time != NULL) {
|
||||
crl->crlList->nextDateAsn1 = *time;
|
||||
return WOLFSSL_SUCCESS;
|
||||
}
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
#ifndef NO_WOLFSSL_STUB
|
||||
@@ -9866,6 +9996,70 @@ int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* key)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Encode CRL to DER format in memory.
|
||||
*
|
||||
* If *out is NULL, allocates memory and returns it via *out.
|
||||
* If *out is not NULL, writes DER data starting at *out.
|
||||
*
|
||||
* @param crl CRL to encode
|
||||
* @param out Pointer to output buffer pointer
|
||||
* @return Size of DER encoding on success, negative on failure
|
||||
*/
|
||||
int wolfSSL_i2d_X509_CRL(WOLFSSL_X509_CRL* crl, unsigned char** out)
|
||||
{
|
||||
int ret;
|
||||
long derSz = 0;
|
||||
byte* der = NULL;
|
||||
int alloced = 0;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_i2d_X509_CRL");
|
||||
|
||||
if (crl == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* Get required size */
|
||||
ret = BufferStoreCRL(crl, NULL, &derSz, WOLFSSL_FILETYPE_ASN1);
|
||||
if (ret != WOLFSSL_SUCCESS || derSz <= 0) {
|
||||
WOLFSSL_MSG("BufferStoreCRL failed to get size");
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (out == NULL) {
|
||||
/* Just return size */
|
||||
return (int)derSz;
|
||||
}
|
||||
|
||||
if (*out == NULL) {
|
||||
/* Allocate output buffer */
|
||||
der = (byte*)XMALLOC((size_t)derSz, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
if (der == NULL) {
|
||||
WOLFSSL_MSG("Memory allocation failed");
|
||||
return MEMORY_E;
|
||||
}
|
||||
alloced = 1;
|
||||
}
|
||||
else {
|
||||
der = *out;
|
||||
}
|
||||
|
||||
/* Encode CRL to DER */
|
||||
ret = BufferStoreCRL(crl, der, &derSz, WOLFSSL_FILETYPE_ASN1);
|
||||
if (ret != WOLFSSL_SUCCESS) {
|
||||
WOLFSSL_MSG("BufferStoreCRL failed to encode");
|
||||
if (alloced) {
|
||||
XFREE(der, NULL, DYNAMIC_TYPE_OPENSSL);
|
||||
}
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
if (alloced) {
|
||||
*out = der;
|
||||
}
|
||||
|
||||
return (int)derSz;
|
||||
}
|
||||
#endif /* HAVE_CRL && OPENSSL_EXTRA */
|
||||
|
||||
#ifdef OPENSSL_EXTRA
|
||||
@@ -10446,10 +10640,11 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
|
||||
|
||||
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
|
||||
|
||||
#ifdef OPENSSL_EXTRA
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
|
||||
|
||||
#if defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD) \
|
||||
|| defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS)
|
||||
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
|
||||
defined(WOLFSSL_APACHE_HTTPD) || defined(WOLFSSL_HAPROXY) || \
|
||||
defined(WOLFSSL_WPAS)
|
||||
WOLFSSL_X509_ALGOR* wolfSSL_X509_ALGOR_new(void)
|
||||
{
|
||||
WOLFSSL_X509_ALGOR* ret;
|
||||
@@ -10864,10 +11059,11 @@ error:
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
#endif /* OPENSSL_ALL || WOLFSSL_APACHE_HTTPD || WOLFSSL_HAPROXY ||
|
||||
* WOLFSSL_WPAS */
|
||||
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || WOLFSSL_APACHE_HTTPD ||
|
||||
* WOLFSSL_HAPROXY || WOLFSSL_WPAS */
|
||||
|
||||
#if !defined(NO_CERTS) && !defined(NO_ASN) && !defined(NO_PWDBASED)
|
||||
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_ASN) && \
|
||||
!defined(NO_PWDBASED)
|
||||
|
||||
int wolfSSL_i2d_X509_PUBKEY(WOLFSSL_X509_PUBKEY* x509_PubKey,
|
||||
unsigned char** der)
|
||||
@@ -10877,9 +11073,9 @@ int wolfSSL_i2d_X509_PUBKEY(WOLFSSL_X509_PUBKEY* x509_PubKey,
|
||||
return wolfSSL_i2d_PublicKey(x509_PubKey->pkey, der);
|
||||
}
|
||||
|
||||
#endif /* !NO_CERTS && !NO_ASN && !NO_PWDBASED */
|
||||
#endif /* OPENSSL_EXTRA && !NO_CERTS && !NO_ASN && !NO_PWDBASED */
|
||||
|
||||
#endif /* OPENSSL_EXTRA */
|
||||
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
|
||||
WOLFSSL_BASIC_CONSTRAINTS* wolfSSL_BASIC_CONSTRAINTS_new(void)
|
||||
@@ -11030,7 +11226,7 @@ WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_sk_X509_OBJECT_deep_copy(
|
||||
|
||||
/* Creates a duplicate of a WOLFSSL_X509_NAME structure.
|
||||
Returns a new WOLFSSL_X509_NAME structure or NULL on failure */
|
||||
WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME *name)
|
||||
WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(const WOLFSSL_X509_NAME *name)
|
||||
{
|
||||
WOLFSSL_X509_NAME* copy = NULL;
|
||||
|
||||
@@ -12909,6 +13105,19 @@ WOLFSSL_X509_CRL* wolfSSL_PEM_read_X509_CRL(XFILE fp,
|
||||
return (WOLFSSL_X509_CRL* )wolfSSL_PEM_read_X509_ex(fp, (void **)crl, cb, u,
|
||||
CRL_TYPE);
|
||||
}
|
||||
|
||||
/* Convert CRL to DER or PEM format.
|
||||
* Returns WOLFSSL_SUCCESS on success, negative on failure.
|
||||
* The caller is responsible for freeing the buffer using XFREE.
|
||||
*/
|
||||
int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl, const char* path, int type)
|
||||
{
|
||||
int ret;
|
||||
WOLFSSL_ENTER("wolfSSL_write_X509_CRL");
|
||||
ret = StoreCRL(crl, path, type);
|
||||
WOLFSSL_LEAVE("wolfSSL_write_X509_CRL", ret);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_CERT_GEN
|
||||
@@ -13593,7 +13802,7 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object(
|
||||
else {
|
||||
/* iterate through and find first open spot */
|
||||
for (i = 0; i < MAX_NAME_ENTRIES; i++) {
|
||||
if (name->entry[i].set != 1) { /* not set so overwritten */
|
||||
if (name->entry[i].set == 0) { /* not set so overwritten */
|
||||
WOLFSSL_MSG("Found place for name entry");
|
||||
break;
|
||||
}
|
||||
@@ -13636,6 +13845,15 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object(
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_PYTHON
|
||||
/* Set name index for OpenSSL stack index position and so Python can
|
||||
* generate tuples/sets from the list. */
|
||||
for (i = 0; i < MAX_NAME_ENTRIES; i++) {
|
||||
if (name->entry[i].set != 0)
|
||||
name->entry[i].set = i + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (RebuildFullName(name) != 0)
|
||||
return WOLFSSL_FAILURE;
|
||||
|
||||
@@ -13707,6 +13925,17 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object(
|
||||
return NULL;
|
||||
}
|
||||
name->entry[loc].set = 0;
|
||||
#ifdef WOLFSSL_PYTHON
|
||||
{
|
||||
int i;
|
||||
/* Set name index for OpenSSL stack index position and so Python can
|
||||
* generate tuples/sets from the list. */
|
||||
for (i = 0; i < MAX_NAME_ENTRIES; i++) {
|
||||
if (name->entry[i].set != 0)
|
||||
name->entry[i].set = i + 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -13757,7 +13986,7 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object(
|
||||
/* returns a pointer to the internal entry at location 'loc' on success,
|
||||
* a null pointer is returned in fail cases */
|
||||
WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(
|
||||
WOLFSSL_X509_NAME *name, int loc)
|
||||
const WOLFSSL_X509_NAME *name, int loc)
|
||||
{
|
||||
#ifdef WOLFSSL_DEBUG_OPENSSL
|
||||
WOLFSSL_ENTER("wolfSSL_X509_NAME_get_entry");
|
||||
@@ -13773,15 +14002,7 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object(
|
||||
}
|
||||
|
||||
if (name->entry[loc].set) {
|
||||
#ifdef WOLFSSL_PYTHON
|
||||
/* "set" is not only flag use, but also stack index position use in
|
||||
* OpenSSL. Python makes tuple based on this number. Therefore,
|
||||
* updating "set" by position + 1. "plus 1" means to avoid "not set"
|
||||
* zero.
|
||||
*/
|
||||
name->entry[loc].set = loc + 1;
|
||||
#endif
|
||||
return &name->entry[loc];
|
||||
return (WOLFSSL_X509_NAME_ENTRY*)&name->entry[loc];
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
@@ -15247,7 +15468,7 @@ int wolfSSL_sk_X509_OBJECT_push(WOLFSSL_STACK* sk, WOLFSSL_X509_OBJECT* obj)
|
||||
/* unlike wolfSSL_X509_NAME_dup this does not malloc a duplicate, only deep
|
||||
* copy. "to" is expected to be a fresh blank name, if not pointers could be
|
||||
* lost */
|
||||
int wolfSSL_X509_NAME_copy(WOLFSSL_X509_NAME* from, WOLFSSL_X509_NAME* to)
|
||||
int wolfSSL_X509_NAME_copy(const WOLFSSL_X509_NAME* from, WOLFSSL_X509_NAME* to)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
+379
-18
@@ -20481,11 +20481,11 @@ static int test_sk_X509(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
static int test_sk_X509_CRL(void)
|
||||
static int test_sk_X509_CRL_decode(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(OPENSSL_ALL) && !defined(NO_CERTS) && defined(HAVE_CRL) && \
|
||||
!defined(NO_RSA)
|
||||
#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && !defined(NO_CERTS) && \
|
||||
defined(HAVE_CRL) && !defined(NO_RSA)
|
||||
X509_CRL* crl = NULL;
|
||||
XFILE fp = XBADFILE;
|
||||
STACK_OF(X509_CRL)* s = NULL;
|
||||
@@ -20577,11 +20577,17 @@ static int test_sk_X509_CRL(void)
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature_type(&empty), 0);
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature_nid(NULL), 0);
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature_nid(&empty), 0);
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(NULL, NULL, NULL), BAD_FUNC_ARG);
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(crl , NULL, NULL), BAD_FUNC_ARG);
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(NULL, NULL, &len), BAD_FUNC_ARG);
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(&empty, NULL, &len),
|
||||
BAD_FUNC_ARG);
|
||||
{
|
||||
int sigSz = 0;
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(NULL, NULL, NULL),
|
||||
BAD_FUNC_ARG);
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(crl, NULL, NULL),
|
||||
BAD_FUNC_ARG);
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(NULL, NULL, &sigSz),
|
||||
BAD_FUNC_ARG);
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(&empty, NULL, &sigSz),
|
||||
BAD_FUNC_ARG);
|
||||
}
|
||||
ExpectIntEQ(wolfSSL_X509_REVOKED_get_serial_number(NULL, NULL, NULL),
|
||||
BAD_FUNC_ARG);
|
||||
ExpectIntEQ(wolfSSL_X509_REVOKED_get_serial_number(rev , NULL, NULL),
|
||||
@@ -20598,15 +20604,12 @@ static int test_sk_X509_CRL(void)
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature_type(crl), CTC_SHA256wRSA);
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature_nid(crl),
|
||||
WC_NID_sha256WithRSAEncryption);
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(crl, NULL, &len),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(len, 256);
|
||||
len--;
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(crl, buff, &len), BUFFER_E);
|
||||
len += 2;
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(crl, buff, &len),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(len, 256);
|
||||
{
|
||||
int sigSz = 0;
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_get_signature(crl, NULL, &sigSz),
|
||||
WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(sigSz, 256);
|
||||
}
|
||||
ExpectNotNull(wolfSSL_X509_CRL_get_lastUpdate(crl));
|
||||
ExpectNotNull(wolfSSL_X509_CRL_get_nextUpdate(crl));
|
||||
|
||||
@@ -20676,6 +20679,362 @@ static int test_sk_X509_CRL(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && !defined(NO_CERTS) && \
|
||||
defined(HAVE_CRL) && !defined(NO_FILESYSTEM) && \
|
||||
!defined(NO_STDIO_FILESYSTEM) && defined(WOLFSSL_CERT_GEN)
|
||||
/* Helper function to create, sign, and write a CRL */
|
||||
static int generate_crl_test(const char* keyFile, const char* certFile,
|
||||
const char* derFile, const char* pemFile,
|
||||
const char* certToRevokePath)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
X509_NAME* issuer = NULL;
|
||||
X509_NAME* decodedIssuer = NULL;
|
||||
WOLFSSL_X509* cert = NULL;
|
||||
WOLFSSL_ASN1_TIME asnTime;
|
||||
XFILE fp = XBADFILE;
|
||||
WOLFSSL_X509_CRL* crl = NULL;
|
||||
WOLFSSL_X509_CRL* decodedCrl = NULL;
|
||||
WOLFSSL_EVP_PKEY* pkey = NULL;
|
||||
int i = 0;
|
||||
int revokedCount = 0;
|
||||
byte certSerial[EXTERNAL_SERIAL_SIZE];
|
||||
int certSerialSz = 0;
|
||||
byte serialsToRevokeBytes[][1] = { { 0x02 }, { 0x03 }, { 0x04 } };
|
||||
static const int numSerials =
|
||||
(int)(sizeof(serialsToRevokeBytes) /
|
||||
sizeof(serialsToRevokeBytes[0]));
|
||||
WOLFSSL_ASN1_INTEGER serialsToRevoke[3] = {
|
||||
{ .intData = {0}, .negative = 0,
|
||||
.data = serialsToRevokeBytes[0],
|
||||
.dataMax = sizeof(serialsToRevokeBytes[0]),
|
||||
.isDynamic = 0,
|
||||
.length = sizeof(serialsToRevokeBytes[0]),
|
||||
.type = 0 },
|
||||
{ .intData = {0}, .negative = 0,
|
||||
.data = serialsToRevokeBytes[1],
|
||||
.dataMax = sizeof(serialsToRevokeBytes[1]),
|
||||
.isDynamic = 0,
|
||||
.length = sizeof(serialsToRevokeBytes[1]),
|
||||
.type = 0 },
|
||||
{ .intData = {0}, .negative = 0,
|
||||
.data = serialsToRevokeBytes[2],
|
||||
.dataMax = sizeof(serialsToRevokeBytes[2]),
|
||||
.isDynamic = 0,
|
||||
.length = sizeof(serialsToRevokeBytes[2]),
|
||||
.type = 0 }
|
||||
};
|
||||
WOLFSSL_X509_REVOKED revoked[3] = {
|
||||
{ .serialNumber = &serialsToRevoke[0] },
|
||||
{ .serialNumber = &serialsToRevoke[1] },
|
||||
{ .serialNumber = &serialsToRevoke[2] }
|
||||
};
|
||||
WOLFSSL_X509* certToRevoke = NULL;
|
||||
|
||||
/* Load certificate to get issuer name (CRL issuer = cert subject) */
|
||||
ExpectTrue((fp = XFOPEN(certFile, "rb")) != XBADFILE);
|
||||
if (fp != XBADFILE) {
|
||||
ExpectNotNull(cert = PEM_read_X509(fp, NULL, NULL, NULL));
|
||||
XFCLOSE(fp);
|
||||
fp = XBADFILE;
|
||||
}
|
||||
|
||||
/* Create a new empty CRL */
|
||||
ExpectNotNull(crl = wolfSSL_X509_CRL_new());
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_version(crl), 2);
|
||||
|
||||
/* Set issuer name, must match certificate subject for verification */
|
||||
ExpectNotNull(issuer = X509_get_subject_name(cert));
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_set_issuer_name(crl, issuer), WOLFSSL_SUCCESS);
|
||||
|
||||
/* Set thisUpdate to current time */
|
||||
XMEMSET(&asnTime, 0, sizeof(asnTime));
|
||||
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&asnTime, XTIME(NULL), 0, 0));
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_set_lastUpdate(crl, &asnTime),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
/* Set nextUpdate to 30 days from now */
|
||||
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&asnTime, XTIME(NULL), 30, 0));
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_set_nextUpdate(crl, &asnTime),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
/* Add revoked certificates based on serial numbers */
|
||||
for (i = 0; i < numSerials; i++) {
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_add_revoked(crl, &revoked[i]),
|
||||
WOLFSSL_SUCCESS);
|
||||
}
|
||||
|
||||
/* Add a revoked certificate entry to CRL by parsing a different
|
||||
* certificate buffer */
|
||||
ExpectTrue((fp = XFOPEN(certToRevokePath, "rb")) != XBADFILE);
|
||||
if (fp != XBADFILE) {
|
||||
ExpectNotNull(certToRevoke = PEM_read_X509(fp, NULL, NULL, NULL));
|
||||
XFCLOSE(fp);
|
||||
fp = XBADFILE;
|
||||
}
|
||||
{
|
||||
const byte* certDer = NULL;
|
||||
int certDerSz = 0;
|
||||
|
||||
ExpectNotNull(certDer =
|
||||
wolfSSL_X509_get_der(certToRevoke, &certDerSz));
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_add_revoked_cert(crl, certDer, certDerSz),
|
||||
WOLFSSL_SUCCESS);
|
||||
}
|
||||
|
||||
/* Save cert serial for verification after round-trip */
|
||||
certSerialSz = (int)sizeof(certSerial);
|
||||
ExpectIntEQ(wolfSSL_X509_get_serial_number(certToRevoke, certSerial,
|
||||
&certSerialSz), WOLFSSL_SUCCESS);
|
||||
|
||||
wolfSSL_X509_free(certToRevoke);
|
||||
certToRevoke = NULL;
|
||||
|
||||
/* Count revoked certificates - should be 'numSerials' + 1 */
|
||||
revokedCount = 0;
|
||||
if (EXPECT_SUCCESS() && crl != NULL && crl->crlList != NULL) {
|
||||
RevokedCert* rev = crl->crlList->certs;
|
||||
while (rev != NULL) {
|
||||
revokedCount++;
|
||||
rev = rev->next;
|
||||
}
|
||||
}
|
||||
ExpectIntEQ(revokedCount, numSerials + 1);
|
||||
|
||||
/* Load private key for signing */
|
||||
ExpectTrue((fp = XFOPEN(keyFile, "rb")) != XBADFILE);
|
||||
if (fp != XBADFILE) {
|
||||
ExpectNotNull(pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL));
|
||||
XFCLOSE(fp);
|
||||
fp = XBADFILE;
|
||||
}
|
||||
|
||||
/* Sign the CRL */
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_sign(crl, pkey, wolfSSL_EVP_sha256()),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
/* Encode CRL to DER */
|
||||
ExpectIntEQ(wolfSSL_write_X509_CRL(crl, derFile, WOLFSSL_FILETYPE_ASN1),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
/* Encode CRL to PEM */
|
||||
ExpectIntEQ(wolfSSL_write_X509_CRL(crl, pemFile, WOLFSSL_FILETYPE_PEM),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
/* ===== Validate encoded DER CRL by decoding and checking contents ===== */
|
||||
ExpectTrue((fp = XFOPEN(derFile, "rb")) != XBADFILE);
|
||||
if (fp != XBADFILE) {
|
||||
ExpectNotNull(decodedCrl = d2i_X509_CRL_fp(fp, NULL));
|
||||
XFCLOSE(fp);
|
||||
fp = XBADFILE;
|
||||
}
|
||||
|
||||
/* Verify CRL version is v2 */
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_version(decodedCrl), 2);
|
||||
|
||||
/* Verify issuer name matches */
|
||||
ExpectNotNull(decodedIssuer = wolfSSL_X509_CRL_get_issuer_name(decodedCrl));
|
||||
ExpectIntEQ(X509_NAME_cmp(issuer, decodedIssuer), 0);
|
||||
|
||||
/* Verify signature type is SHA256 with RSA or ECDSA */
|
||||
ExpectIntNE(wolfSSL_X509_CRL_get_signature_type(decodedCrl), 0);
|
||||
|
||||
/* Verify lastUpdate and nextUpdate are set */
|
||||
ExpectNotNull(wolfSSL_X509_CRL_get_lastUpdate(decodedCrl));
|
||||
ExpectNotNull(wolfSSL_X509_CRL_get_nextUpdate(decodedCrl));
|
||||
|
||||
/* Count revoked certificates and verify serial values.
|
||||
* CRL parsing prepends entries, so decoded list is in reverse order. */
|
||||
revokedCount = 0;
|
||||
if (EXPECT_SUCCESS() && decodedCrl != NULL && decodedCrl->crlList != NULL) {
|
||||
RevokedCert* rev = decodedCrl->crlList->certs;
|
||||
while (rev != NULL) {
|
||||
if (revokedCount == 0) {
|
||||
/* Last added (cert serial) appears first in decoded list */
|
||||
ExpectIntEQ(rev->serialSz, certSerialSz);
|
||||
ExpectIntEQ(XMEMCMP(rev->serialNumber, certSerial,
|
||||
rev->serialSz), 0);
|
||||
}
|
||||
else {
|
||||
/* Remaining serials in reverse: index numSerials-revokedCount */
|
||||
int idx = numSerials - revokedCount;
|
||||
ExpectIntEQ(rev->serialSz,
|
||||
(int)sizeof(serialsToRevokeBytes[0]));
|
||||
ExpectIntEQ(XMEMCMP(rev->serialNumber,
|
||||
serialsToRevokeBytes[idx], rev->serialSz), 0);
|
||||
}
|
||||
revokedCount++;
|
||||
rev = rev->next;
|
||||
}
|
||||
}
|
||||
ExpectIntEQ(revokedCount, numSerials + 1);
|
||||
|
||||
wolfSSL_X509_CRL_free(decodedCrl);
|
||||
decodedCrl = NULL;
|
||||
|
||||
/* ===== Validate encoded PEM CRL by decoding and checking contents ===== */
|
||||
ExpectTrue((fp = XFOPEN(pemFile, "rb")) != XBADFILE);
|
||||
if (fp != XBADFILE) {
|
||||
ExpectNotNull(decodedCrl = (X509_CRL*)PEM_read_X509_CRL(fp, NULL,
|
||||
NULL, NULL));
|
||||
XFCLOSE(fp);
|
||||
fp = XBADFILE;
|
||||
}
|
||||
|
||||
/* Verify CRL version is v2 */
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_version(decodedCrl), 2);
|
||||
|
||||
/* Verify issuer name matches */
|
||||
ExpectNotNull(decodedIssuer = wolfSSL_X509_CRL_get_issuer_name(decodedCrl));
|
||||
ExpectIntEQ(X509_NAME_cmp(issuer, decodedIssuer), 0);
|
||||
|
||||
/* Count revoked certificates from PEM and verify serial values.
|
||||
* CRL parsing prepends entries, so decoded list is in reverse order. */
|
||||
revokedCount = 0;
|
||||
if (EXPECT_SUCCESS() && decodedCrl != NULL && decodedCrl->crlList != NULL) {
|
||||
RevokedCert* rev = decodedCrl->crlList->certs;
|
||||
while (rev != NULL) {
|
||||
if (revokedCount == 0) {
|
||||
ExpectIntEQ(rev->serialSz, certSerialSz);
|
||||
ExpectIntEQ(XMEMCMP(rev->serialNumber, certSerial,
|
||||
rev->serialSz), 0);
|
||||
}
|
||||
else {
|
||||
int idx = numSerials - revokedCount;
|
||||
ExpectIntEQ(rev->serialSz,
|
||||
(int)sizeof(serialsToRevokeBytes[0]));
|
||||
ExpectIntEQ(XMEMCMP(rev->serialNumber,
|
||||
serialsToRevokeBytes[idx], rev->serialSz), 0);
|
||||
}
|
||||
revokedCount++;
|
||||
rev = rev->next;
|
||||
}
|
||||
}
|
||||
ExpectIntEQ(revokedCount, numSerials + 1);
|
||||
|
||||
wolfSSL_X509_CRL_free(decodedCrl);
|
||||
|
||||
wolfSSL_EVP_PKEY_free(pkey);
|
||||
wolfSSL_X509_CRL_free(crl);
|
||||
wolfSSL_X509_free(cert);
|
||||
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
#endif
|
||||
|
||||
static int test_sk_X509_CRL_encode(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && !defined(NO_CERTS) && \
|
||||
defined(HAVE_CRL) && !defined(NO_FILESYSTEM) && \
|
||||
!defined(NO_STDIO_FILESYSTEM) && defined(WOLFSSL_CERT_GEN)
|
||||
#ifndef NO_RSA
|
||||
static const char* crlRsaPemFile = "./certs/crl/crlRsaOut.pem";
|
||||
static const char* crlRsaDerFile = "./certs/crl/crlRsaOut.der";
|
||||
static const char* testRsaKeyFile = "./certs/ca-key.pem";
|
||||
/* Use ca-cert.pem to match ca-key.pem for proper CRL verification */
|
||||
static const char* testRsaCertFile = "./certs/ca-cert.pem";
|
||||
static const char* revokeRsaCertFile = "./certs/server-cert.pem";
|
||||
#endif
|
||||
#ifdef HAVE_ECC
|
||||
static const char* crlEccPemFile = "./certs/crl/crlEccOut.pem";
|
||||
static const char* crlEccDerFile = "./certs/crl/crlEccOut.der";
|
||||
static const char* testEccKeyFile = "./certs/ca-ecc-key.pem";
|
||||
/* Use ca-ecc-cert.pem to match ca-ecc-key.pem for proper CRL
|
||||
* verification */
|
||||
static const char* testEccCertFile = "./certs/ca-ecc-cert.pem";
|
||||
static const char* revokeEccCertFile = "./certs/server-ecc.pem";
|
||||
#endif
|
||||
|
||||
#ifndef NO_RSA
|
||||
/* Generate RSA-signed CRL (PEM and DER) */
|
||||
ExpectIntEQ(generate_crl_test(testRsaKeyFile, testRsaCertFile,
|
||||
crlRsaDerFile, crlRsaPemFile, revokeRsaCertFile), TEST_SUCCESS);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
/* Generate ECC-signed CRL (PEM and DER) */
|
||||
ExpectIntEQ(generate_crl_test(testEccKeyFile, testEccCertFile,
|
||||
crlEccDerFile, crlEccPemFile, revokeEccCertFile), TEST_SUCCESS);
|
||||
#endif
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
static int test_wolfSSL_X509_CRL_sign_large(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if (defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA)) && !defined(NO_CERTS) && \
|
||||
defined(HAVE_CRL) && !defined(NO_FILESYSTEM) && \
|
||||
!defined(NO_STDIO_FILESYSTEM) && defined(WOLFSSL_CERT_GEN)
|
||||
#ifndef NO_RSA
|
||||
static const char* testRsaKeyFile = "./certs/ca-key.pem";
|
||||
static const char* testRsaCertFile = "./certs/ca-cert.pem";
|
||||
X509_NAME* issuer = NULL;
|
||||
WOLFSSL_X509* cert = NULL;
|
||||
WOLFSSL_X509_CRL* crl = NULL;
|
||||
WOLFSSL_EVP_PKEY* pkey = NULL;
|
||||
WOLFSSL_ASN1_TIME asnTime;
|
||||
WOLFSSL_X509_REVOKED revoked;
|
||||
XFILE fp = XBADFILE;
|
||||
int i;
|
||||
byte serial[4];
|
||||
|
||||
ExpectTrue((fp = XFOPEN(testRsaCertFile, "rb")) != XBADFILE);
|
||||
if (fp != XBADFILE) {
|
||||
ExpectNotNull(cert = PEM_read_X509(fp, NULL, NULL, NULL));
|
||||
XFCLOSE(fp);
|
||||
fp = XBADFILE;
|
||||
}
|
||||
|
||||
ExpectNotNull(crl = wolfSSL_X509_CRL_new());
|
||||
ExpectNotNull(issuer = X509_get_subject_name(cert));
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_set_issuer_name(crl, issuer), WOLFSSL_SUCCESS);
|
||||
|
||||
XMEMSET(&asnTime, 0, sizeof(asnTime));
|
||||
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&asnTime, XTIME(NULL), 0, 0));
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_set_lastUpdate(crl, &asnTime),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
ExpectNotNull(wolfSSL_ASN1_TIME_adj(&asnTime, XTIME(NULL), 30, 0));
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_set_nextUpdate(crl, &asnTime),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
revoked.serialNumber = wolfSSL_ASN1_INTEGER_new();
|
||||
revoked.serialNumber->data = serial;
|
||||
revoked.serialNumber->length = (int)sizeof(serial);
|
||||
|
||||
for (i = 1; i <= 1024; i++) {
|
||||
serial[0] = (byte)(i & 0xff);
|
||||
serial[1] = (byte)((i >> 8) & 0xff);
|
||||
serial[2] = (byte)((i >> 16) & 0xff);
|
||||
serial[3] = (byte)((i >> 24) & 0xff);
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_add_revoked(crl, &revoked),
|
||||
WOLFSSL_SUCCESS);
|
||||
}
|
||||
|
||||
ExpectTrue((fp = XFOPEN(testRsaKeyFile, "rb")) != XBADFILE);
|
||||
if (fp != XBADFILE) {
|
||||
ExpectNotNull(pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL));
|
||||
XFCLOSE(fp);
|
||||
fp = XBADFILE;
|
||||
}
|
||||
|
||||
ExpectIntEQ(wolfSSL_X509_CRL_sign(crl, pkey, wolfSSL_EVP_sha256()),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
revoked.serialNumber->data = NULL;
|
||||
wolfSSL_ASN1_INTEGER_free(revoked.serialNumber);
|
||||
revoked.serialNumber = NULL;
|
||||
|
||||
wolfSSL_EVP_PKEY_free(pkey);
|
||||
wolfSSL_X509_CRL_free(crl);
|
||||
wolfSSL_X509_free(cert);
|
||||
#endif /* !NO_RSA */
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
static int test_X509_REQ(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
@@ -31966,7 +32325,9 @@ TEST_CASE testCases[] = {
|
||||
/* OpenSSL sk_X509 API test */
|
||||
TEST_DECL(test_sk_X509),
|
||||
/* OpenSSL sk_X509_CRL API test */
|
||||
TEST_DECL(test_sk_X509_CRL),
|
||||
TEST_DECL(test_sk_X509_CRL_decode),
|
||||
TEST_DECL(test_sk_X509_CRL_encode),
|
||||
TEST_DECL(test_wolfSSL_X509_CRL_sign_large),
|
||||
|
||||
/* OpenSSL X509 REQ API test */
|
||||
TEST_DECL(test_wolfSSL_d2i_X509_REQ),
|
||||
|
||||
+416
-4
@@ -631,6 +631,7 @@ static word32 SizeASNLength(word32 length)
|
||||
#define ASNIntMSBSet(asn, data_a, i) \
|
||||
(((asn)[i].tag == ASN_INTEGER) && \
|
||||
((data_a)[i].data.buffer.data != NULL && \
|
||||
((data_a)[i].data.buffer.length > 0) && \
|
||||
((data_a)[i].data.buffer.data[0] & 0x80) == 0x80))
|
||||
|
||||
|
||||
@@ -3131,11 +3132,10 @@ const char* GetSigName(int oid) {
|
||||
|
||||
|
||||
#if !defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS7) || \
|
||||
defined(OPENSSL_EXTRA)
|
||||
defined(OPENSSL_EXTRA) || defined(WOLFSSL_CERT_GEN)
|
||||
#if !defined(NO_DSA) || defined(HAVE_ECC) || !defined(NO_CERTS) || \
|
||||
(!defined(NO_RSA) && \
|
||||
(defined(WOLFSSL_CERT_GEN) || \
|
||||
((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)))))
|
||||
defined(WOLFSSL_CERT_GEN) || \
|
||||
(!defined(NO_RSA) && (defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)))
|
||||
/* Set the DER/BER encoding of the ASN.1 INTEGER header.
|
||||
*
|
||||
* When output is NULL, calculate the header length only.
|
||||
@@ -41833,6 +41833,418 @@ end:
|
||||
#endif /* WOLFSSL_ASN_TEMPLATE */
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_CERT_GEN
|
||||
/* Encode a date as ASN.1 (UTC or GeneralizedTime).
|
||||
* Returns length written to output (including tag and length bytes).
|
||||
* If output is NULL, just returns the required size.
|
||||
*/
|
||||
static word32 EncodeCrlDate(byte* output, const byte* date, byte format)
|
||||
{
|
||||
word32 idx = 0;
|
||||
word32 dateLen;
|
||||
|
||||
/* Determine date length based on format */
|
||||
if (format == ASN_UTC_TIME) {
|
||||
dateLen = ASN_UTC_TIME_SIZE - 1; /* exclude null terminator */
|
||||
}
|
||||
else if (format == ASN_GENERALIZED_TIME) {
|
||||
dateLen = ASN_GENERALIZED_TIME_SIZE - 1;
|
||||
}
|
||||
else {
|
||||
return 0; /* unsupported format */
|
||||
}
|
||||
|
||||
if (output != NULL) {
|
||||
output[idx] = format;
|
||||
}
|
||||
idx++;
|
||||
|
||||
if (output != NULL) {
|
||||
idx += SetLength(dateLen, output + idx);
|
||||
XMEMCPY(output + idx, date, dateLen);
|
||||
}
|
||||
else {
|
||||
idx += SetLength(dateLen, NULL);
|
||||
}
|
||||
idx += dateLen;
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/* Encode a serial number as ASN.1 INTEGER.
|
||||
* Similar to SetSerialNumber but always available.
|
||||
*/
|
||||
static int EncodeCrlSerial(const byte* sn, word32 snSz, byte* output,
|
||||
word32 outputSz)
|
||||
{
|
||||
int i;
|
||||
int snSzInt = (int)snSz;
|
||||
const byte* snPtr = sn;
|
||||
|
||||
if (sn == NULL || snSzInt < 0)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* remove leading zeros */
|
||||
while (snSzInt > 0 && snPtr[0] == 0) {
|
||||
snSzInt--;
|
||||
snPtr++;
|
||||
}
|
||||
/* Serial numbers must be non-negative; allow zero for tolerance */
|
||||
if (snSzInt == 0) {
|
||||
i = SetASNInt(1, 0x00, output);
|
||||
if (1 > (int)outputSz - i) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
if (output != NULL) {
|
||||
output[i] = 0x00;
|
||||
}
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
i = SetASNInt(snSzInt, snPtr[0], NULL);
|
||||
/* sanity check number of bytes to copy */
|
||||
if (snSzInt > (int)outputSz - i || snSzInt <= 0) {
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
if (output != NULL) {
|
||||
/* write out ASN.1 Integer */
|
||||
(void)SetASNInt(snSzInt, snPtr[0], output);
|
||||
XMEMCPY(output + i, snPtr, (size_t)snSzInt);
|
||||
}
|
||||
|
||||
return i + snSzInt;
|
||||
}
|
||||
|
||||
/* Encode a single revoked certificate entry.
|
||||
* Returns length written to output.
|
||||
*/
|
||||
static word32 EncodeRevokedCert(byte* output, const RevokedCert* rc)
|
||||
{
|
||||
word32 idx = 0;
|
||||
word32 snSz, dateSz, seqSz;
|
||||
byte snBuf[MAX_SN_SZ];
|
||||
byte dateBuf[MAX_DATE_SIZE + 2]; /* tag + length + data */
|
||||
byte seqBuf[MAX_SEQ_SZ];
|
||||
|
||||
/* Encode serial number */
|
||||
snSz = (word32)EncodeCrlSerial(rc->serialNumber, (word32)rc->serialSz,
|
||||
snBuf, sizeof(snBuf));
|
||||
if ((int)snSz < 0)
|
||||
return 0;
|
||||
|
||||
/* Encode revocation date */
|
||||
dateSz = EncodeCrlDate(dateBuf, rc->revDate, rc->revDateFormat);
|
||||
if (dateSz == 0)
|
||||
return 0;
|
||||
|
||||
/* Wrap in SEQUENCE */
|
||||
seqSz = SetSequence(snSz + dateSz, seqBuf);
|
||||
|
||||
if (output != NULL) {
|
||||
XMEMCPY(output + idx, seqBuf, seqSz);
|
||||
idx += seqSz;
|
||||
XMEMCPY(output + idx, snBuf, snSz);
|
||||
idx += snSz;
|
||||
XMEMCPY(output + idx, dateBuf, dateSz);
|
||||
idx += dateSz;
|
||||
}
|
||||
else {
|
||||
idx = seqSz + snSz + dateSz;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/* Encode the CRL Number extension.
|
||||
* Returns length written to output.
|
||||
*/
|
||||
static word32 EncodeCrlNumberExt(byte* output, const byte* crlNum,
|
||||
word32 crlNumSz)
|
||||
{
|
||||
word32 idx = 0;
|
||||
word32 oidSz, intSz, octetSz, seqSz;
|
||||
byte seqBuf[MAX_SEQ_SZ];
|
||||
byte octetBuf[MAX_OCTET_STR_SZ];
|
||||
byte intBuf[MAX_SN_SZ];
|
||||
|
||||
/* CRL Number OID: 2.5.29.20 */
|
||||
static const byte crlNumOid[] = { 0x06, 0x03, 0x55, 0x1d, 0x14 };
|
||||
oidSz = sizeof(crlNumOid);
|
||||
|
||||
/* Encode the INTEGER for CRL number */
|
||||
intSz = (word32)EncodeCrlSerial(crlNum, crlNumSz, intBuf, sizeof(intBuf));
|
||||
if ((int)intSz < 0)
|
||||
return 0;
|
||||
|
||||
/* Wrap INTEGER in OCTET STRING */
|
||||
octetSz = SetOctetString(intSz, octetBuf);
|
||||
|
||||
/* Wrap in extension SEQUENCE */
|
||||
seqSz = SetSequence(oidSz + octetSz + intSz, seqBuf);
|
||||
|
||||
if (output != NULL) {
|
||||
XMEMCPY(output + idx, seqBuf, seqSz);
|
||||
idx += seqSz;
|
||||
XMEMCPY(output + idx, crlNumOid, oidSz);
|
||||
idx += oidSz;
|
||||
XMEMCPY(output + idx, octetBuf, octetSz);
|
||||
idx += octetSz;
|
||||
XMEMCPY(output + idx, intBuf, intSz);
|
||||
idx += intSz;
|
||||
}
|
||||
else {
|
||||
idx = seqSz + oidSz + octetSz + intSz;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
/* Build CRL TBSCertList from fields.
|
||||
* issuerDer: DER-encoded issuer Name
|
||||
* issuerSz: size of issuer DER
|
||||
* lastDate/lastDateFmt: thisUpdate time and format
|
||||
* nextDate/nextDateFmt: nextUpdate time and format
|
||||
* certs: linked list of revoked certificates (may be NULL)
|
||||
* crlNumber/crlNumberSz: CRL number extension data (may be NULL)
|
||||
* sigType: signature algorithm type (e.g., CTC_SHA256wRSA)
|
||||
* version: CRL version (1 or 2; 2 required for extensions)
|
||||
* output: buffer to write TBS (NULL to calculate size)
|
||||
* outputSz: size of output buffer
|
||||
*
|
||||
* Returns: size of TBS on success, negative error code on failure
|
||||
*/
|
||||
int wc_MakeCRL_ex(const byte* issuerDer, word32 issuerSz,
|
||||
const byte* lastDate, byte lastDateFmt,
|
||||
const byte* nextDate, byte nextDateFmt,
|
||||
RevokedCert* certs, const byte* crlNumber, word32 crlNumberSz,
|
||||
int sigType, int version, byte* output, word32 outputSz)
|
||||
{
|
||||
word32 idx = 0;
|
||||
word32 tbsContentSz = 0;
|
||||
word32 versionSz = 0, algoSz = 0, lastDateSz = 0, nextDateSz = 0;
|
||||
word32 revokedSz = 0, extSz = 0, extSeqSz = 0, extCtxSz = 0;
|
||||
word32 tbsSeqSz;
|
||||
byte tbsSeqBuf[MAX_SEQ_SZ];
|
||||
byte versionBuf[MAX_VERSION_SZ];
|
||||
byte algoBuf[MAX_ALGO_SZ];
|
||||
byte lastDateBuf[MAX_DATE_SIZE + 2];
|
||||
byte nextDateBuf[MAX_DATE_SIZE + 2];
|
||||
byte revokedSeqBuf[MAX_SEQ_SZ];
|
||||
byte extSeqBuf[MAX_SEQ_SZ];
|
||||
byte extCtxBuf[MAX_SEQ_SZ + 1]; /* context tag + length */
|
||||
RevokedCert* rc;
|
||||
|
||||
if (issuerDer == NULL || issuerSz == 0 || lastDate == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* Version: only include if v2 (version = 2 means value 1 in ASN.1) */
|
||||
if (version >= 2) {
|
||||
versionSz = (word32)SetMyVersion(version - 1, versionBuf, FALSE);
|
||||
}
|
||||
|
||||
/* Signature AlgorithmIdentifier */
|
||||
algoSz = SetAlgoID(sigType, algoBuf, oidSigType, 0);
|
||||
if (algoSz == 0)
|
||||
return ALGO_ID_E;
|
||||
|
||||
/* thisUpdate */
|
||||
lastDateSz = EncodeCrlDate(lastDateBuf, lastDate, lastDateFmt);
|
||||
if (lastDateSz == 0)
|
||||
return ASN_DATE_SZ_E;
|
||||
|
||||
/* nextUpdate (optional) */
|
||||
if (nextDate != NULL && nextDateFmt != 0) {
|
||||
nextDateSz = EncodeCrlDate(nextDateBuf, nextDate, nextDateFmt);
|
||||
}
|
||||
|
||||
/* revokedCertificates (optional) */
|
||||
if (certs != NULL) {
|
||||
word32 contentSz = 0;
|
||||
/* First pass: calculate size */
|
||||
for (rc = certs; rc != NULL; rc = rc->next) {
|
||||
word32 entrySz = EncodeRevokedCert(NULL, rc);
|
||||
if (entrySz == 0)
|
||||
return ASN_PARSE_E;
|
||||
contentSz += entrySz;
|
||||
}
|
||||
revokedSz = SetSequence(contentSz, revokedSeqBuf) + contentSz;
|
||||
}
|
||||
|
||||
/* crlExtensions (optional) - CRL Number */
|
||||
if (crlNumber != NULL && crlNumberSz > 0 && version >= 2) {
|
||||
word32 crlNumExtSz = EncodeCrlNumberExt(NULL, crlNumber, crlNumberSz);
|
||||
if (crlNumExtSz > 0) {
|
||||
extSeqSz = SetSequence(crlNumExtSz, extSeqBuf);
|
||||
/* Context tag [0] EXPLICIT */
|
||||
extCtxBuf[0] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0);
|
||||
extCtxSz = 1 + SetLength(extSeqSz + crlNumExtSz, extCtxBuf + 1);
|
||||
extSz = extCtxSz + extSeqSz + crlNumExtSz;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate total TBS content size */
|
||||
tbsContentSz = versionSz + algoSz + issuerSz + lastDateSz + nextDateSz +
|
||||
revokedSz + extSz;
|
||||
|
||||
/* TBS SEQUENCE header */
|
||||
tbsSeqSz = SetSequence(tbsContentSz, tbsSeqBuf);
|
||||
|
||||
/* Check buffer size */
|
||||
if (output != NULL && (tbsSeqSz + tbsContentSz > outputSz))
|
||||
return BUFFER_E;
|
||||
|
||||
/* If output is NULL, just return required size */
|
||||
if (output == NULL)
|
||||
return (int)(tbsSeqSz + tbsContentSz);
|
||||
|
||||
/* Encode TBS */
|
||||
idx = 0;
|
||||
|
||||
/* TBS SEQUENCE header */
|
||||
XMEMCPY(output + idx, tbsSeqBuf, tbsSeqSz);
|
||||
idx += tbsSeqSz;
|
||||
|
||||
/* Version (optional) */
|
||||
if (versionSz > 0) {
|
||||
XMEMCPY(output + idx, versionBuf, versionSz);
|
||||
idx += versionSz;
|
||||
}
|
||||
|
||||
/* Signature AlgorithmIdentifier */
|
||||
XMEMCPY(output + idx, algoBuf, algoSz);
|
||||
idx += algoSz;
|
||||
|
||||
/* Issuer Name */
|
||||
XMEMCPY(output + idx, issuerDer, issuerSz);
|
||||
idx += issuerSz;
|
||||
|
||||
/* thisUpdate */
|
||||
XMEMCPY(output + idx, lastDateBuf, lastDateSz);
|
||||
idx += lastDateSz;
|
||||
|
||||
/* nextUpdate (optional) */
|
||||
if (nextDateSz > 0) {
|
||||
XMEMCPY(output + idx, nextDateBuf, nextDateSz);
|
||||
idx += nextDateSz;
|
||||
}
|
||||
|
||||
/* revokedCertificates (optional) */
|
||||
if (revokedSz > 0) {
|
||||
word32 contentSz = 0;
|
||||
for (rc = certs; rc != NULL; rc = rc->next) {
|
||||
contentSz += EncodeRevokedCert(NULL, rc);
|
||||
}
|
||||
idx += SetSequence(contentSz, output + idx);
|
||||
for (rc = certs; rc != NULL; rc = rc->next) {
|
||||
idx += EncodeRevokedCert(output + idx, rc);
|
||||
}
|
||||
}
|
||||
|
||||
/* crlExtensions (optional) */
|
||||
if (extSz > 0) {
|
||||
word32 crlNumExtSz = EncodeCrlNumberExt(NULL, crlNumber, crlNumberSz);
|
||||
/* Context tag [0] */
|
||||
output[idx++] = (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0);
|
||||
idx += SetLength(extSeqSz + crlNumExtSz, output + idx);
|
||||
/* Extensions SEQUENCE */
|
||||
idx += SetSequence(crlNumExtSz, output + idx);
|
||||
/* CRL Number extension */
|
||||
idx += EncodeCrlNumberExt(output + idx, crlNumber, crlNumberSz);
|
||||
}
|
||||
|
||||
return (int)idx;
|
||||
}
|
||||
|
||||
/* Sign a CRL TBS and produce complete CRL DER.
|
||||
* tbsBuf: contains the TBS at the beginning
|
||||
* tbsSz: size of TBS in tbsBuf
|
||||
* sType: signature type (e.g., CTC_SHA256wRSA)
|
||||
* buf: output buffer for complete CRL. May be the same as tbsBuf.
|
||||
* bufSz: size of output buffer
|
||||
* rsaKey/eccKey: signing key (one must be non-NULL)
|
||||
* rng: random number generator
|
||||
*
|
||||
* Returns: size of complete CRL on success, negative error on failure
|
||||
*/
|
||||
int wc_SignCRL_ex(const byte* tbsBuf, int tbsSz, int sType,
|
||||
byte* buf, word32 bufSz,
|
||||
RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng)
|
||||
{
|
||||
int ret;
|
||||
int sigSz;
|
||||
CertSignCtx certSignCtx_lcl;
|
||||
CertSignCtx* certSignCtx = &certSignCtx_lcl;
|
||||
void* heap = NULL;
|
||||
|
||||
if (tbsBuf == NULL || tbsSz <= 0 || buf == NULL || rng == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
if (rsaKey == NULL && eccKey == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
XMEMSET(certSignCtx, 0, sizeof(*certSignCtx));
|
||||
|
||||
if (rsaKey != NULL) {
|
||||
heap = rsaKey->heap;
|
||||
}
|
||||
#ifdef HAVE_ECC
|
||||
else if (eccKey != NULL) {
|
||||
heap = eccKey->heap;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Copy TBS to output buffer first */
|
||||
if ((word32)tbsSz > bufSz)
|
||||
return BUFFER_E;
|
||||
XMEMCPY(buf, tbsBuf, (size_t)tbsSz);
|
||||
|
||||
#ifndef WOLFSSL_NO_MALLOC
|
||||
certSignCtx->sig = (byte*)XMALLOC(MAX_ENCODED_SIG_SZ, heap,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (certSignCtx->sig == NULL)
|
||||
return MEMORY_E;
|
||||
/* Initialize first byte to avoid static analysis warnings about using
|
||||
* uninitialized memory if MakeSignature fails before writing sig. */
|
||||
certSignCtx->sig[0] = 0;
|
||||
#endif
|
||||
|
||||
/* Create signature */
|
||||
sigSz = MakeSignature(certSignCtx, buf, (word32)tbsSz, certSignCtx->sig,
|
||||
MAX_ENCODED_SIG_SZ, rsaKey, eccKey, NULL, NULL, NULL,
|
||||
NULL, NULL, rng, (word32)sType, heap);
|
||||
if (sigSz < 0) {
|
||||
#ifndef WOLFSSL_NO_MALLOC
|
||||
XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return sigSz;
|
||||
}
|
||||
|
||||
/* Ensure output buffer is large enough for signature wrapper */
|
||||
ret = AddSignature(NULL, tbsSz, certSignCtx->sig, sigSz, sType);
|
||||
if (ret < 0) {
|
||||
#ifndef WOLFSSL_NO_MALLOC
|
||||
XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
if ((word32)ret > bufSz) {
|
||||
#ifndef WOLFSSL_NO_MALLOC
|
||||
XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
/* Add signature algorithm and signature to buffer */
|
||||
ret = AddSignature(buf, tbsSz, certSignCtx->sig, sigSz, sType);
|
||||
|
||||
#ifndef WOLFSSL_NO_MALLOC
|
||||
XFREE(certSignCtx->sig, heap, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_CERT_GEN */
|
||||
|
||||
#endif /* HAVE_CRL */
|
||||
|
||||
|
||||
|
||||
+2
-1
@@ -28,7 +28,8 @@
|
||||
#elif defined(WOLFCRYPT_ONLY)
|
||||
#else
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
|
||||
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \
|
||||
defined(HAVE_CURL)
|
||||
|
||||
#if !defined(HAVE_PKCS7) && \
|
||||
((defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \
|
||||
|
||||
@@ -39,8 +39,11 @@ WOLFSSL_LOCAL void FreeCRL(WOLFSSL_CRL* crl, int dynamic);
|
||||
|
||||
WOLFSSL_LOCAL int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type,
|
||||
int monitor);
|
||||
WOLFSSL_LOCAL int StoreCRL(WOLFSSL_CRL* crl, const char* file, int type);
|
||||
WOLFSSL_LOCAL int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz,
|
||||
int type, int verify);
|
||||
WOLFSSL_LOCAL int BufferStoreCRL(WOLFSSL_CRL* crl, byte* buff, long* inOutSz,
|
||||
int type);
|
||||
WOLFSSL_LOCAL int CheckCertCRL(WOLFSSL_CRL* crl, DecodedCert* cert);
|
||||
WOLFSSL_LOCAL int CheckCertCRL_ex(WOLFSSL_CRL* crl, byte* issuerHash,
|
||||
byte* serial, int serialSz, byte* serialHash, const byte* extCrlInfo,
|
||||
|
||||
+3
-1
@@ -5481,7 +5481,9 @@ struct WOLFSSL_X509 {
|
||||
#endif /* WOLFSSL_CERT_REQ || WOLFSSL_CERT_GEN */
|
||||
WOLFSSL_X509_NAME issuer;
|
||||
WOLFSSL_X509_NAME subject;
|
||||
#if defined(OPENSSL_ALL) || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS)
|
||||
#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \
|
||||
defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_APACHE_HTTPD) || \
|
||||
defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_WPAS)
|
||||
WOLFSSL_X509_ALGOR algor;
|
||||
WOLFSSL_X509_PUBKEY key;
|
||||
#endif
|
||||
|
||||
@@ -804,10 +804,13 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_
|
||||
|
||||
#define d2i_X509_CRL wolfSSL_d2i_X509_CRL
|
||||
#define d2i_X509_CRL_fp wolfSSL_d2i_X509_CRL_fp
|
||||
#define i2d_X509_CRL wolfSSL_i2d_X509_CRL
|
||||
#define PEM_read_X509_CRL wolfSSL_PEM_read_X509_CRL
|
||||
|
||||
#define X509_CRL_new wolfSSL_X509_CRL_new
|
||||
#define X509_CRL_dup wolfSSL_X509_CRL_dup
|
||||
#define X509_CRL_free wolfSSL_X509_CRL_free
|
||||
#define X509_CRL_sign wolfSSL_X509_CRL_sign
|
||||
#define X509_CRL_get_lastUpdate wolfSSL_X509_CRL_get_lastUpdate
|
||||
#define X509_CRL_get0_lastUpdate wolfSSL_X509_CRL_get_lastUpdate
|
||||
#define X509_CRL_get_nextUpdate wolfSSL_X509_CRL_get_nextUpdate
|
||||
@@ -817,6 +820,14 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_
|
||||
#define X509_CRL_get_issuer wolfSSL_X509_CRL_get_issuer_name
|
||||
#define X509_CRL_get_signature_nid wolfSSL_X509_CRL_get_signature_nid
|
||||
#define X509_CRL_get_version wolfSSL_X509_CRL_version
|
||||
#define X509_CRL_set_lastUpdate wolfSSL_X509_CRL_set_lastUpdate
|
||||
#define X509_CRL_set1_lastUpdate wolfSSL_X509_CRL_set_lastUpdate
|
||||
#define X509_CRL_set_nextUpdate wolfSSL_X509_CRL_set_nextUpdate
|
||||
#define X509_CRL_set1_nextUpdate wolfSSL_X509_CRL_set_nextUpdate
|
||||
#define X509_CRL_set_issuer_name wolfSSL_X509_CRL_set_issuer_name
|
||||
#define X509_CRL_set_version wolfSSL_X509_CRL_set_version
|
||||
#define X509_CRL_get0_signature wolfSSL_X509_CRL_get_signature
|
||||
#define X509_CRL_get_signature_nid wolfSSL_X509_CRL_get_signature_nid
|
||||
#define X509_load_crl_file wolfSSL_X509_load_crl_file
|
||||
|
||||
#define X509_ACERT_new wolfSSL_X509_ACERT_new
|
||||
|
||||
+44
-7
@@ -886,6 +886,9 @@ struct WOLFSSL_X509_VERIFY_PARAM {
|
||||
|
||||
typedef struct WOLFSSL_X509_REVOKED {
|
||||
WOLFSSL_ASN1_INTEGER* serialNumber; /* stunnel dereference */
|
||||
/* TODO: add other fields to match OpenSSL's X509_REVOKED
|
||||
* (struct x509_revoked_st) such as revocationDate, extensions, etc.
|
||||
* Then update wolfSSL_X509_CRL_add_revoked to handle those fields. */
|
||||
} WOLFSSL_X509_REVOKED;
|
||||
|
||||
typedef enum {
|
||||
@@ -2373,8 +2376,11 @@ WOLFSSL_API void wolfSSL_X509_STORE_CTX_trusted_stack(WOLFSSL_X509_STORE_CTX *ct
|
||||
WOLF_STACK_OF(WOLFSSL_X509) *sk);
|
||||
|
||||
WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_lastUpdate(WOLFSSL_X509_CRL* crl);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_set_lastUpdate(WOLFSSL_X509_CRL* crl,
|
||||
const WOLFSSL_ASN1_TIME* time);
|
||||
WOLFSSL_API WOLFSSL_ASN1_TIME* wolfSSL_X509_CRL_get_nextUpdate(WOLFSSL_X509_CRL* crl);
|
||||
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_set_nextUpdate(WOLFSSL_X509_CRL* crl,
|
||||
const WOLFSSL_ASN1_TIME* time);
|
||||
WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_verify(WOLFSSL_X509_CRL* crl, WOLFSSL_EVP_PKEY* pkey);
|
||||
WOLFSSL_API void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj);
|
||||
@@ -3469,15 +3475,25 @@ WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_fp(XFILE file, WOLFSSL_X509_C
|
||||
WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_d2i_X509_CRL_bio(WOLFSSL_BIO *bp,
|
||||
WOLFSSL_X509_CRL **crl);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_version(WOLFSSL_X509_CRL *crl);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_set_version(WOLFSSL_X509_CRL* crl,
|
||||
long version);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_get_signature_type(WOLFSSL_X509_CRL* crl);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_set_signature_type(WOLFSSL_X509_CRL* crl,
|
||||
int signatureType);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_get_signature_nid(
|
||||
const WOLFSSL_X509_CRL* crl);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_set_signature_nid(WOLFSSL_X509_CRL* crl,
|
||||
int nid);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_get_signature(WOLFSSL_X509_CRL* crl,
|
||||
unsigned char* buf, int* bufSz);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_set_signature(WOLFSSL_X509_CRL* crl,
|
||||
unsigned char* buf, int bufSz);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_print(WOLFSSL_BIO* bio,
|
||||
WOLFSSL_X509_CRL* crl);
|
||||
WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_CRL_get_issuer_name(
|
||||
WOLFSSL_X509_CRL *crl);
|
||||
const WOLFSSL_X509_CRL *crl);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_set_issuer_name(WOLFSSL_X509_CRL* crl,
|
||||
const WOLFSSL_X509_NAME* name);
|
||||
WOLFSSL_API int wolfSSL_X509_REVOKED_get_serial_number(RevokedCert* rev,
|
||||
byte* in, int* inOutSz);
|
||||
#endif
|
||||
@@ -3485,6 +3501,20 @@ WOLFSSL_API int wolfSSL_X509_REVOKED_get_serial_number(RevokedCert* rev,
|
||||
WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_X509_CRL_dup(const WOLFSSL_X509_CRL* crl);
|
||||
WOLFSSL_API void wolfSSL_X509_CRL_free(WOLFSSL_X509_CRL *crl);
|
||||
#endif
|
||||
#if defined(HAVE_CRL) && defined(OPENSSL_EXTRA)
|
||||
WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_X509_CRL_new(void);
|
||||
#ifdef WOLFSSL_CERT_GEN
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_add_revoked(WOLFSSL_X509_CRL* crl,
|
||||
WOLFSSL_X509_REVOKED* revoked);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_add_revoked_cert(WOLFSSL_X509_CRL* crl,
|
||||
const unsigned char* certBuf, int certSz);
|
||||
WOLFSSL_API int wolfSSL_X509_CRL_sign(WOLFSSL_X509_CRL* crl,
|
||||
WOLFSSL_EVP_PKEY* pkey,
|
||||
const WOLFSSL_EVP_MD* md);
|
||||
#endif /* WOLFSSL_CERT_GEN */
|
||||
WOLFSSL_API int wolfSSL_i2d_X509_CRL(WOLFSSL_X509_CRL* crl,
|
||||
unsigned char** out);
|
||||
#endif /* HAVE_CRL && OPENSSL_EXTRA */
|
||||
|
||||
#if defined(WOLFSSL_ACERT) && \
|
||||
(defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA))
|
||||
@@ -5055,8 +5085,10 @@ WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new(void);
|
||||
#ifndef wolfSSL_X509_NAME_new_ex
|
||||
WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_NAME_new_ex(void *heap);
|
||||
#endif
|
||||
WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(WOLFSSL_X509_NAME* name);
|
||||
WOLFSSL_API int wolfSSL_X509_NAME_copy(WOLFSSL_X509_NAME* from, WOLFSSL_X509_NAME* to);
|
||||
WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_NAME_dup(
|
||||
const WOLFSSL_X509_NAME* name);
|
||||
WOLFSSL_API int wolfSSL_X509_NAME_copy(const WOLFSSL_X509_NAME* from,
|
||||
WOLFSSL_X509_NAME* to);
|
||||
WOLFSSL_API int wolfSSL_check_private_key(const WOLFSSL* ssl);
|
||||
#endif /* !NO_CERTS */
|
||||
#endif /* OPENSSL_ALL || OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
|
||||
@@ -5231,6 +5263,8 @@ WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_INFO)* wolfSSL_PEM_X509_INFO_read_bio(
|
||||
#ifndef NO_FILESYSTEM
|
||||
WOLFSSL_API WOLFSSL_X509_CRL *wolfSSL_PEM_read_X509_CRL(XFILE fp,
|
||||
WOLFSSL_X509_CRL **x, wc_pem_password_cb *cb, void *u);
|
||||
WOLFSSL_API int wolfSSL_write_X509_CRL(WOLFSSL_X509_CRL* crl,
|
||||
const char* path, int type);
|
||||
#endif
|
||||
WOLFSSL_API int wolfSSL_PEM_get_EVP_CIPHER_INFO(const char* header,
|
||||
EncryptedInfo* cipher);
|
||||
@@ -5256,7 +5290,8 @@ struct WOLFSSL_CONF_CTX {
|
||||
WOLFSSL* ssl;
|
||||
};
|
||||
|
||||
WOLFSSL_API WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(WOLFSSL_X509_NAME *name, int loc);
|
||||
WOLFSSL_API WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(
|
||||
const WOLFSSL_X509_NAME *name, int loc);
|
||||
WOLFSSL_API int wolfSSL_X509_NAME_ENTRY_set(const WOLFSSL_X509_NAME_ENTRY *ne);
|
||||
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
|
||||
|
||||
@@ -5492,7 +5527,8 @@ WOLFSSL_API int wolfSSL_sk_CONF_VALUE_push(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk
|
||||
WOLFSSL_CONF_VALUE* val);
|
||||
#endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA || HAVE_LIGHTY */
|
||||
|
||||
#if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL)
|
||||
#if !defined(NO_ASN) && (defined(OPENSSL_EXTRA) || \
|
||||
defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_WPAS_SMALL))
|
||||
WOLFSSL_API WOLFSSL_ASN1_BIT_STRING* wolfSSL_ASN1_BIT_STRING_new(void);
|
||||
WOLFSSL_API void wolfSSL_ASN1_BIT_STRING_free(WOLFSSL_ASN1_BIT_STRING* str);
|
||||
WOLFSSL_API WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr(
|
||||
@@ -5505,7 +5541,8 @@ WOLFSSL_API int wolfSSL_i2d_ASN1_BIT_STRING(const WOLFSSL_ASN1_BIT_STRING* bstr,
|
||||
unsigned char** pp);
|
||||
WOLFSSL_API WOLFSSL_ASN1_BIT_STRING* wolfSSL_d2i_ASN1_BIT_STRING(
|
||||
WOLFSSL_ASN1_BIT_STRING** out, const byte** src, long len);
|
||||
#endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */
|
||||
#endif /* !NO_ASN && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL ||
|
||||
WOLFSSL_WPAS_SMALL) */
|
||||
|
||||
WOLFSSL_API int wolfSSL_version(WOLFSSL* ssl);
|
||||
|
||||
|
||||
@@ -639,6 +639,20 @@ WOLFSSL_API int wc_SetCustomExtension(Cert *cert, int critical, const char *oid,
|
||||
|
||||
#endif /* WOLFSSL_CERT_EXT */
|
||||
|
||||
#if defined(WOLFSSL_CERT_GEN) && defined(HAVE_CRL)
|
||||
/* CRL Generation functions */
|
||||
struct RevokedCert; /* forward declaration */
|
||||
WOLFSSL_API int wc_MakeCRL_ex(const byte* issuerDer, word32 issuerSz,
|
||||
const byte* lastDate, byte lastDateFmt,
|
||||
const byte* nextDate, byte nextDateFmt,
|
||||
struct RevokedCert* certs, const byte* crlNumber,
|
||||
word32 crlNumberSz, int sigType, int version,
|
||||
byte* output, word32 outputSz);
|
||||
WOLFSSL_API int wc_SignCRL_ex(const byte* tbsBuf, int tbsSz, int sType,
|
||||
byte* buf, word32 bufSz,
|
||||
RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng);
|
||||
#endif /* WOLFSSL_CERT_GEN && HAVE_CRL */
|
||||
|
||||
WOLFSSL_API int wc_GetDateInfo(const byte* certDate, int certDateSz,
|
||||
const byte** date, byte* format, int* length);
|
||||
#ifndef NO_ASN_TIME
|
||||
|
||||
Reference in New Issue
Block a user