diff --git a/doc/dox_comments/header_files/asn_public.h b/doc/dox_comments/header_files/asn_public.h index 3407e9c24..de0c836c5 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_API int wc_CheckCertSigPubKey(const byte* cert, word32 certSz, + void* heap, const byte* pubKey, + word32 pubKeySz, int pubKeyOID); +*/ diff --git a/tests/api.c b/tests/api.c index 4336cc98e..7b8aa0563 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30515,6 +30515,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) && defined(HAVE_ECC) + 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 = (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, + 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); + AssertTrue(ret == ASN_PARSE_E || ret == BUFFER_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) && \ @@ -53447,6 +53522,7 @@ void ApiTest(void) test_wc_PubKeyPemToDer(); test_wc_PemPubKeyToDer(); test_wc_GetPubKeyDerFromCert(); + test_wc_CheckCertSigPubKey(); /*OCSP Stapling. */ AssertIntEQ(test_wolfSSL_UseOCSPStapling(), WOLFSSL_SUCCESS); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index bfb3bb92a..0db75a0cd 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..723b37c3a 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_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);