From edea6428d9f66fb8d03f43f358d080988dd8dba7 Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Fri, 1 Apr 2022 11:40:25 -0400 Subject: [PATCH 1/6] Add new public API wc_CheckCertSigPubKey() --- doc/dox_comments/header_files/asn_public.h | 22 ++++++++++++++++++++++ wolfcrypt/src/asn.c | 8 ++++++++ wolfssl/wolfcrypt/asn.h | 6 ++++++ 3 files changed, 36 insertions(+) diff --git a/doc/dox_comments/header_files/asn_public.h b/doc/dox_comments/header_files/asn_public.h index 3407e9c24..f0c071ee7 100644 --- a/doc/dox_comments/header_files/asn_public.h +++ b/doc/dox_comments/header_files/asn_public.h @@ -2037,3 +2037,25 @@ WOLFSSL_API int wc_SetCustomExtension(Cert *cert, int critical, const char *oid, */ WOLFSSL_ASN_API int wc_SetUnknownExtCallback(DecodedCert* cert, wc_UnknownExtCallback cb); +/*! + \ingroup ASN + + \brief This function verifies the signature in the der form of an X.509 + certificate against a public key. The public key is expected to be the full + subject public key info in der form. + + \return 0 Returned on success. + \return Other negative values on failure. + + \param cert The der encoding of the X.509 certificate. + \param certSz The size in bytes of cert. + \param heap A pointer to the heap used for dynamic allocation. Can be NULL. + \param pubKey The der encoding of the public key. + \param pubKeySz The size in bytes of pubKey. + \param pubKeyOID OID identifying the algorithm of the public key. + (ie: ECDSAk, DSAk or RSAk) + +WOLFSSL_ASN_API int wc_CheckCertSigPubKey(const byte* cert, word32 certSz, + void* heap, const byte* pubKey, + word32 pubKeySz, int pubKeyOID); +*/ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 6964957bc..b770ac122 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -18400,6 +18400,14 @@ int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap, return CheckCertSignature_ex(cert, certSz, heap, NULL, pubKey, pubKeySz, pubKeyOID, 0); } + +int wc_CheckCertSigPubKey(const byte* cert, word32 certSz, void* heap, + const byte* pubKey, word32 pubKeySz, int pubKeyOID) +{ + return CheckCertSignaturePubKey(cert, certSz, heap, pubKey, pubKeySz, + pubKeyOID); +} + #ifdef WOLFSSL_CERT_REQ int CheckCSRSignaturePubKey(const byte* cert, word32 certSz, void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID) diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 108a5ede2..517b56123 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1836,6 +1836,12 @@ WOLFSSL_LOCAL int EncodePolicyOID(byte *out, word32 *outSz, WOLFSSL_API int CheckCertSignature(const byte*,word32,void*,void* cm); WOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID); +#ifdef OPENSSL_EXTRA +WOLFSSL_ASN_API int wc_CheckCertSigPubKey(const byte* cert, word32 certSz, + void* heap, const byte* pubKey, + word32 pubKeySz, int pubKeyOID); +#endif + #ifdef WOLFSSL_CERT_REQ WOLFSSL_LOCAL int CheckCSRSignaturePubKey(const byte* cert, word32 certSz, void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID); From 211007fb4411d35dc6df4d1bd29bb5112b33b772 Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Fri, 1 Apr 2022 15:24:40 -0400 Subject: [PATCH 2/6] WOLFSSL_ASN_API ---> WOLFSSL_API --- doc/dox_comments/header_files/asn_public.h | 6 +++--- wolfssl/wolfcrypt/asn.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/dox_comments/header_files/asn_public.h b/doc/dox_comments/header_files/asn_public.h index f0c071ee7..de0c836c5 100644 --- a/doc/dox_comments/header_files/asn_public.h +++ b/doc/dox_comments/header_files/asn_public.h @@ -2055,7 +2055,7 @@ WOLFSSL_ASN_API int wc_SetUnknownExtCallback(DecodedCert* cert, \param pubKeyOID OID identifying the algorithm of the public key. (ie: ECDSAk, DSAk or RSAk) -WOLFSSL_ASN_API int wc_CheckCertSigPubKey(const byte* cert, word32 certSz, - void* heap, const byte* pubKey, - word32 pubKeySz, int pubKeyOID); +WOLFSSL_API int wc_CheckCertSigPubKey(const byte* cert, word32 certSz, + void* heap, const byte* pubKey, + word32 pubKeySz, int pubKeyOID); */ diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 517b56123..723b37c3a 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1837,9 +1837,9 @@ WOLFSSL_API int CheckCertSignature(const byte*,word32,void*,void* cm); WOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz, void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID); #ifdef OPENSSL_EXTRA -WOLFSSL_ASN_API int wc_CheckCertSigPubKey(const byte* cert, word32 certSz, - void* heap, const byte* pubKey, - word32 pubKeySz, int pubKeyOID); +WOLFSSL_API int wc_CheckCertSigPubKey(const byte* cert, word32 certSz, + void* heap, const byte* pubKey, + word32 pubKeySz, int pubKeyOID); #endif #ifdef WOLFSSL_CERT_REQ From c522baa75ef76ad72f87b3b177e9739cd36b6671 Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Fri, 1 Apr 2022 18:34:21 -0400 Subject: [PATCH 3/6] Unit tests. --- tests/api.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/tests/api.c b/tests/api.c index b5080609b..0ed8639b3 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30457,6 +30457,81 @@ static void test_wc_GetPubKeyDerFromCert(void) #endif /* !NO_RSA || HAVE_ECC */ } +static void test_wc_CheckCertSigPubKey(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \ + !defined(NO_RSA) && defined(WOLFSSL_PEM_TO_DER) + int ret; + const char* ca_cert = "./certs/ca-cert.pem"; + byte* cert_buf = NULL; + size_t cert_sz = 0; + byte* cert_der = NULL; + word32 cert_dersz = 0; + byte keyDer[TWOK_BUF]; /* large enough for up to RSA 2048 */ + word32 keyDerSz = (word32)sizeof(keyDer); + DecodedCert decoded; + + printf(testingFmt, "wc_CheckCertSigPubKey()"); + + ret = load_file(ca_cert, &cert_buf, &cert_sz); + if (ret == 0) { + cert_dersz = cert_sz; /* DER will be smaller than PEM */ + cert_der = (byte*)malloc(cert_dersz); + if (cert_der) { + ret = wc_CertPemToDer(cert_buf, (int)cert_sz, + cert_der, (int)cert_dersz, CERT_TYPE); + AssertIntGE(ret, 0); + } + } + + wc_InitDecodedCert(&decoded, cert_der, cert_dersz, NULL); + ret = wc_ParseCert(&decoded, CERT_TYPE, NO_VERIFY, NULL); + AssertIntEQ(ret, 0); + + ret = wc_GetPubKeyDerFromCert(&decoded, keyDer, &keyDerSz); + AssertIntEQ(ret, 0); + AssertIntGT(keyDerSz, 0); + + /* Good test case. */ + ret = wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, keyDer, keyDerSz, + RSAk); + AssertIntEQ(ret, 0); + + /* No certificate. */ + ret = wc_CheckCertSigPubKey(NULL, cert_dersz, NULL, keyDer, keyDerSz, + ECDSAk); + AssertIntEQ(ret, BAD_FUNC_ARG); + + /* Bad cert size. */ + ret = wc_CheckCertSigPubKey(cert_der, 0, NULL, keyDer, keyDerSz, + RSAk); + AssertIntEQ(ret, ASN_PARSE_E); + + /* No public key. */ + ret = wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, NULL, keyDerSz, + RSAk); + AssertIntEQ(ret, ASN_NO_SIGNER_E); + + /* Bad public key size. */ + ret = wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, keyDer, 0, + RSAk); + AssertIntEQ(ret, BAD_FUNC_ARG); + + /* Wrong aglo. */ + ret = wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, keyDer, keyDerSz, + ECDSAk); + AssertIntEQ(ret, ASN_PARSE_E); + + wc_FreeDecodedCert(&decoded); + if (cert_der) + free(cert_der); + if (cert_buf) + free(cert_buf); + + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_certs(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \ @@ -53312,6 +53387,7 @@ void ApiTest(void) test_wc_PubKeyPemToDer(); test_wc_PemPubKeyToDer(); test_wc_GetPubKeyDerFromCert(); + test_wc_CheckCertSigPubKey(); /*OCSP Stapling. */ AssertIntEQ(test_wolfSSL_UseOCSPStapling(), WOLFSSL_SUCCESS); From ae9926cc420c1f4a36a6a32eb3fd83637072caa8 Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Mon, 4 Apr 2022 12:39:10 -0400 Subject: [PATCH 4/6] Missing flag in unit test. --- tests/api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index 0ed8639b3..74480fe5c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30460,7 +30460,7 @@ static void test_wc_GetPubKeyDerFromCert(void) static void test_wc_CheckCertSigPubKey(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM) && \ - !defined(NO_RSA) && defined(WOLFSSL_PEM_TO_DER) + !defined(NO_RSA) && defined(WOLFSSL_PEM_TO_DER) && defined(HAVE_ECC) int ret; const char* ca_cert = "./certs/ca-cert.pem"; byte* cert_buf = NULL; From 400c7238ef989c5f4b5397a5d46f3b33dce6d531 Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Mon, 4 Apr 2022 13:43:06 -0400 Subject: [PATCH 5/6] Test fixup. --- tests/api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index 74480fe5c..853c46507 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30505,7 +30505,7 @@ static void test_wc_CheckCertSigPubKey(void) /* Bad cert size. */ ret = wc_CheckCertSigPubKey(cert_der, 0, NULL, keyDer, keyDerSz, RSAk); - AssertIntEQ(ret, ASN_PARSE_E); + AssertTrue(ret == ASN_PARSE_E || ret == BUFFER_E); /* No public key. */ ret = wc_CheckCertSigPubKey(cert_der, cert_dersz, NULL, NULL, keyDerSz, From fc6e10ff429a67c50acbe02c22b4f2340beea5ee Mon Sep 17 00:00:00 2001 From: Anthony Hu Date: Mon, 4 Apr 2022 17:42:25 -0400 Subject: [PATCH 6/6] Another test fixup. --- tests/api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index 853c46507..125c7b6d7 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30475,7 +30475,7 @@ static void test_wc_CheckCertSigPubKey(void) ret = load_file(ca_cert, &cert_buf, &cert_sz); if (ret == 0) { - cert_dersz = cert_sz; /* DER will be smaller than PEM */ + cert_dersz = (word32)cert_sz; /* DER will be smaller than PEM */ cert_der = (byte*)malloc(cert_dersz); if (cert_der) { ret = wc_CertPemToDer(cert_buf, (int)cert_sz,