diff --git a/.gitignore b/.gitignore index 9e3b4639de..7ea896eb2c 100644 --- a/.gitignore +++ b/.gitignore @@ -249,6 +249,7 @@ linuxkm/patches/src linuxkm/libwolfssl-user-build linuxkm/linuxkm-fips-hash *.nds +/certs/.rnd # Generated during FreeBSD kernel module build. bsdkm/export_syms diff --git a/certs/include.am b/certs/include.am index b19881d31f..5bc9fad9a9 100644 --- a/certs/include.am +++ b/certs/include.am @@ -90,7 +90,8 @@ EXTRA_DIST += \ EXTRA_DIST += \ certs/aia/ca-issuers-cert.pem \ certs/aia/multi-aia-cert.pem \ - certs/aia/overflow-aia-cert.pem + certs/aia/overflow-aia-cert.pem \ + certs/sia/timestamping-sia-cert.pem EXTRA_DIST += \ certs/ca-key.der \ diff --git a/certs/renewcerts.sh b/certs/renewcerts.sh index 78be54efe3..deb7cbc861 100755 --- a/certs/renewcerts.sh +++ b/certs/renewcerts.sh @@ -38,6 +38,7 @@ # aia/ca-issuers-cert.pem # aia/multi-aia-cert.pem # aia/overflow-aia-cert.pem +# sia/timestamping-sia-cert.pem # updates the following crls: # crl/cliCrl.pem # crl/crl.pem @@ -354,6 +355,31 @@ run_renewcerts(){ echo "End of section" echo "---------------------------------------------------------------------" ############################################################ + ########## update SIA test certs ########################### + ############################################################ + echo "Updating SIA test certs" + echo "" + mkdir -p sia + + # Cert with a subjectInfoAccess extension that does not contain an + # id-ad-caRepository entry. RFC 5280 4.2.2.2 only requires the SIA + # sequence be non-empty; it does not mandate any specific access method. + echo "Updating sia/timestamping-sia-cert.pem" + echo "" + openssl req -new -newkey rsa:2048 -nodes -keyout sia/timestamping-sia-key.pem -subj "/CN=wolfssl-sia-timestamping-test" -out sia/timestamping-sia-cert.csr + check_result $? "Step SIA-1" + + openssl x509 -req -in sia/timestamping-sia-cert.csr -days 3650 -extfile wolfssl.cnf -extensions sia_timestamping -signkey sia/timestamping-sia-key.pem -out sia/timestamping-sia-cert.pem + check_result $? "Step SIA-2" + rm sia/timestamping-sia-cert.csr + + openssl x509 -in sia/timestamping-sia-cert.pem -text > tmp.pem + check_result $? "Step SIA-3" + mv tmp.pem sia/timestamping-sia-cert.pem + rm sia/timestamping-sia-key.pem + echo "End of section" + echo "---------------------------------------------------------------------" + ############################################################ ########## update the self-signed ca-cert-chain.der ######## ############################################################ echo "Updating ca-cert-chain.der" @@ -1039,7 +1065,6 @@ EOF echo "Performing final steps, cleaning up the file system..." echo "" - rm ../wolfssl.cnf echo "End of Updates. Everything was successfully updated!" echo "---------------------------------------------------------------------" } @@ -1048,8 +1073,8 @@ EOF ##################### THE EXECUTABLE BODY ##################################### ############################################################################### -#start in root. -cd ../ || exit 1 +#start in root, regardless of the caller's working directory. +cd "$(dirname "${BASH_SOURCE[0]}")/.." || exit 1 if [ ! -z "$1" ]; then echo "No arguments expected" @@ -1065,6 +1090,7 @@ touch certs/.rnd || exit 1 run_renewcerts cd ../ || exit 1 -rm ./certs/wolfssl.cnf +rm -f ./certs/wolfssl.cnf +rm -f certs/.rnd exit 0 diff --git a/certs/renewcerts/wolfssl.cnf b/certs/renewcerts/wolfssl.cnf index f02081d143..70453f9369 100644 --- a/certs/renewcerts/wolfssl.cnf +++ b/certs/renewcerts/wolfssl.cnf @@ -360,6 +360,15 @@ OCSP;URI.6=http://127.0.0.1:22226 OCSP;URI.7=http://127.0.0.1:22227 OCSP;URI.8=http://127.0.0.1:22228 +# SIA test cert: subjectInfoAccess present but without id-ad-caRepository. +[ sia_timestamping ] +subjectKeyIdentifier=hash +basicConstraints=CA:false +subjectInfoAccess=@sia_timestamping_info + +[ sia_timestamping_info ] +timeStamping;URI.0=http://example.com/tsa + #tsa default [ tsa ] default_tsa = tsa_config1 diff --git a/certs/sia/timestamping-sia-cert.pem b/certs/sia/timestamping-sia-cert.pem new file mode 100644 index 0000000000..303eb1595e --- /dev/null +++ b/certs/sia/timestamping-sia-cert.pem @@ -0,0 +1,78 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 74:60:0d:21:cd:a1:31:68:9f:54:85:93:7e:2e:80:e5:4f:c3:2a:1a + Signature Algorithm: sha256WithRSAEncryption + Issuer: CN=wolfssl-sia-timestamping-test + Validity + Not Before: Apr 30 19:19:06 2026 GMT + Not After : Apr 27 19:19:06 2036 GMT + Subject: CN=wolfssl-sia-timestamping-test + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:a1:60:e1:c3:1b:0d:ff:21:da:6b:a7:eb:36:bb: + cb:b6:6f:ed:29:91:f5:46:23:0d:a2:f7:7e:8f:05: + c8:1a:df:e7:74:cf:a6:1f:64:8d:21:5c:14:41:4f: + a7:c2:67:46:53:e3:fd:11:cc:db:55:12:42:4e:37: + d8:2f:22:5c:94:83:bc:7c:0a:c4:e0:86:61:17:e1: + d0:f5:36:97:40:77:f4:a4:a7:47:94:34:73:6f:06: + 1f:fa:43:ff:25:57:3f:65:8b:fb:26:40:bc:a5:3e: + ef:04:59:a6:4c:1a:a0:2c:43:f6:b2:2b:11:e3:09: + d5:c5:a0:59:5d:97:12:ae:c7:b9:03:b8:57:d3:21: + 45:e2:07:e3:66:60:45:d6:b2:ca:a5:06:75:85:ef: + c9:fc:9b:c9:3e:8a:f9:27:0b:93:d1:f9:57:90:d4: + 1c:b3:6e:40:8a:c4:c9:05:16:7c:aa:eb:c9:09:7a: + 67:3a:cf:6b:b4:ea:19:e4:70:47:23:5b:a7:e4:eb: + 6c:25:07:a6:46:03:4f:10:18:12:aa:c0:15:9b:6f: + 79:bb:0c:d0:7b:9a:66:e8:71:b0:c9:5c:0d:bb:89: + 4b:1c:36:e0:ce:6e:aa:e4:1b:07:b7:f6:80:c0:07: + 3b:16:a5:22:b8:20:4d:03:2e:ca:cc:54:f5:06:cf: + 70:71 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + F5:6A:74:86:5F:56:54:64:F6:29:D0:5F:38:74:04:C1:13:81:61:EE + X509v3 Basic Constraints: + CA:FALSE + Subject Information Access: + Time Stamping - URI:http://example.com/tsa + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 99:4f:71:53:6a:44:f1:cc:61:86:5d:11:70:1a:c4:1c:e7:42: + cc:15:eb:6c:5a:1f:cf:ab:2a:a6:61:10:41:e7:96:21:c8:e4: + 06:78:ef:0c:49:e8:0a:2a:7b:51:a9:76:29:fb:2f:51:0a:b0: + b7:a6:bb:08:cd:44:14:7f:e1:2d:fe:84:7d:72:87:d6:32:06: + 96:58:2b:98:cf:67:02:53:35:01:81:7d:e5:45:87:8b:db:3f: + 90:e6:a8:45:19:3d:55:fd:9d:cf:d9:51:2a:b0:e2:60:a7:f7: + c9:e8:80:7e:98:20:10:74:78:e0:fb:45:e5:a1:e4:e8:2d:73: + e2:fe:07:57:aa:6a:42:9d:00:03:bf:99:51:6a:e1:2d:5a:7b: + 24:2d:f5:07:05:2e:63:54:86:1b:2e:dc:77:10:42:80:9e:c6: + ef:2e:c3:3f:e9:99:03:9f:d4:2a:21:69:47:04:bb:b5:b0:e0: + 79:4d:0c:f8:e4:42:58:90:95:25:6b:d9:1f:76:10:9d:b3:2d: + da:13:d3:55:af:b3:0c:8a:db:02:c5:76:d5:92:c1:a6:3e:fe: + 0a:14:ef:5d:a7:72:4f:4f:3a:ae:0b:75:7d:e8:99:c4:82:d6: + ad:ce:4e:4f:86:e6:5f:2e:ea:e2:63:3a:0a:bb:47:8e:a1:da: + b5:45:5c:0f +-----BEGIN CERTIFICATE----- +MIIDPjCCAiagAwIBAgIUdGANIc2hMWifVIWTfi6A5U/DKhowDQYJKoZIhvcNAQEL +BQAwKDEmMCQGA1UEAwwdd29sZnNzbC1zaWEtdGltZXN0YW1waW5nLXRlc3QwHhcN +MjYwNDMwMTkxOTA2WhcNMzYwNDI3MTkxOTA2WjAoMSYwJAYDVQQDDB13b2xmc3Ns +LXNpYS10aW1lc3RhbXBpbmctdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAKFg4cMbDf8h2mun6za7y7Zv7SmR9UYjDaL3fo8FyBrf53TPph9kjSFc +FEFPp8JnRlPj/RHM21USQk432C8iXJSDvHwKxOCGYRfh0PU2l0B39KSnR5Q0c28G +H/pD/yVXP2WL+yZAvKU+7wRZpkwaoCxD9rIrEeMJ1cWgWV2XEq7HuQO4V9MhReIH +42ZgRdayyqUGdYXvyfybyT6K+ScLk9H5V5DUHLNuQIrEyQUWfKrryQl6ZzrPa7Tq +GeRwRyNbp+TrbCUHpkYDTxAYEqrAFZtvebsM0HuaZuhxsMlcDbuJSxw24M5uquQb +B7f2gMAHOxalIrggTQMuysxU9QbPcHECAwEAAaNgMF4wHQYDVR0OBBYEFPVqdIZf +VlRk9inQXzh0BMETgWHuMAkGA1UdEwQCMAAwMgYIKwYBBQUHAQsEJjAkMCIGCCsG +AQUFBwMIhhZodHRwOi8vZXhhbXBsZS5jb20vdHNhMA0GCSqGSIb3DQEBCwUAA4IB +AQCZT3FTakTxzGGGXRFwGsQc50LMFetsWh/PqyqmYRBB55YhyOQGeO8MSegKKntR +qXYp+y9RCrC3prsIzUQUf+Et/oR9cofWMgaWWCuYz2cCUzUBgX3lRYeL2z+Q5qhF +GT1V/Z3P2VEqsOJgp/fJ6IB+mCAQdHjg+0XloeToLXPi/gdXqmpCnQADv5lRauEt +WnskLfUHBS5jVIYbLtx3EEKAnsbvLsM/6ZkDn9QqIWlHBLu1sOB5TQz45EJYkJUl +a9kfdhCdsy3aE9NVr7MMitsCxXbVksGmPv4KFO9dp3JPTzquC3V96JnEgtatzk5P +huZfLuriYzoKu0eOodq1RVwP +-----END CERTIFICATE----- diff --git a/tests/api.c b/tests/api.c index b3193c5ad0..1458948c1f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -21215,6 +21215,50 @@ static int test_wolfSSL_X509_get1_aia_overflow(void) return EXPECT_RESULT(); } +/* Parse a certificate whose subjectInfoAccess extension is present but does + * not contain an id-ad-caRepository entry. RFC 5280 4.2.2.2 only requires + * the SIA sequence be non-empty; previously wolfSSL incorrectly rejected + * such certificates with ASN_PARSE_E. */ +static int test_wolfSSL_SubjectInfoAccess_no_caRepository(void) +{ + EXPECT_DECLS; +#if defined(WOLFSSL_SUBJ_INFO_ACC) && !defined(NO_RSA) && \ + !defined(NO_FILESYSTEM) && defined(WOLFSSL_PEM_TO_DER) + const char* siaCert = "./certs/sia/timestamping-sia-cert.pem"; + byte* pemBuf = NULL; + size_t pemSz = 0; + byte* derBuf = NULL; + word32 derSz = 0; + DecodedCert cert; + int ret = 0; + + ExpectIntEQ(load_file(siaCert, &pemBuf, &pemSz), 0); + derSz = (word32)pemSz; /* DER will be smaller than PEM */ + ExpectNotNull(derBuf = (byte*)malloc(derSz)); + ExpectIntGE(ret = wc_CertPemToDer(pemBuf, (int)pemSz, derBuf, (int)derSz, + CERT_TYPE), 0); + + if (ret > 0) + { + derSz = (word32)ret; + wc_InitDecodedCert(&cert, derBuf, derSz, NULL); + ExpectIntEQ(wc_ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL), 0); + + /* SIA was present and decoded successfully. */ + ExpectIntEQ(cert.extSubjInfoAccSet, 1); + /* No id-ad-caRepository entry exists in this cert's SIA. */ + ExpectNull(cert.extSubjInfoAccCaRepo); + ExpectIntEQ((int)cert.extSubjInfoAccCaRepoSz, 0); + + wc_FreeDecodedCert(&cert); + } + + free(derBuf); + XFREE(pemBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return EXPECT_RESULT(); +} + static int test_no_op_functions(void) { EXPECT_DECLS; @@ -37318,6 +37362,7 @@ TEST_CASE testCases[] = { TEST_DECL(test_wolfSSL_X509_get1_ca_issuers), TEST_DECL(test_wolfSSL_X509_get1_aia_multi), TEST_DECL(test_wolfSSL_X509_get1_aia_overflow), + TEST_DECL(test_wolfSSL_SubjectInfoAccess_no_caRepository), TEST_DECL(test_wolfSSL_PEM_read), diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 90b964c217..b234d31af8 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -19775,15 +19775,9 @@ static int DecodeSubjInfoAcc(const byte* input, word32 sz, DecodedCert* cert) { word32 idx = 0; int length = 0; - int ret = 0; WOLFSSL_ENTER("DecodeSubjInfoAcc"); -#ifdef OPENSSL_ALL - cert->extSubjAltNameSrc = input; - cert->extSubjAltNameSz = sz; -#endif /* OPENSSL_ALL */ - /* Unwrap SubjectInfoAccessSyntax, the list of AccessDescriptions */ if (GetSequence(input, &idx, &length, sz) < 0) return ASN_PARSE_E; @@ -19796,12 +19790,11 @@ static int DecodeSubjInfoAcc(const byte* input, word32 sz, DecodedCert* cert) return ASN_PARSE_E; } - /* Per fpkx-x509-cert-profile-common... section 5.3. - * [The] subjectInfoAccess extension must contain at least one - * instance of the id-ad-caRepository access method containing a - * publicly accessible HTTP URI which returns as certs-only - * CMS. - */ + /* RFC 5280 specifies that at least one entry must be present but does not + * specify any particular OID must be present. For certificates following + * fpki-x509-cert-profile-common, we extract the id-ad-caRepository caRepo + * entry to cert->extSubjInfoAccCaRepo / cert->extSubjInfoAccCaRepoSz for + * convenient user access. */ while (idx < (word32)sz) { word32 oid = 0; @@ -19831,14 +19824,8 @@ static int DecodeSubjInfoAcc(const byte* input, word32 sz, DecodedCert* cert) idx += (word32)length; } - if (cert->extSubjInfoAccCaRepo == NULL || - cert->extSubjInfoAccCaRepoSz == 0) { - WOLFSSL_MSG("SubjectInfoAccess missing an URL."); - ret = ASN_PARSE_E; - } - - WOLFSSL_LEAVE("DecodeSubjInfoAcc", ret); - return ret; + WOLFSSL_LEAVE("DecodeSubjInfoAcc", 0); + return 0; } #endif /* WOLFSSL_SUBJ_INFO_ACC */