mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-04 13:14:45 +02:00
Merge pull request #8758 from bigbrett/exportx509pubkey-api
Added new ASN X509 API: `wc_GetSubjectPubKeyInfoDerFromCert`
This commit is contained in:
146
tests/api.c
146
tests/api.c
@@ -22755,6 +22755,151 @@ static int test_wc_GetPubKeyDerFromCert(void)
|
|||||||
return EXPECT_RESULT();
|
return EXPECT_RESULT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_wc_GetSubjectPubKeyInfoDerFromCert(void)
|
||||||
|
{
|
||||||
|
EXPECT_DECLS;
|
||||||
|
#if !defined(NO_RSA) || defined(HAVE_ECC)
|
||||||
|
int ret;
|
||||||
|
word32 idx = 0;
|
||||||
|
byte keyDer[TWOK_BUF]; /* large enough for up to RSA 2048 */
|
||||||
|
word32 keyDerSz = (word32)sizeof(keyDer);
|
||||||
|
#if !defined(NO_RSA) && defined(WOLFSSL_CERT_REQ) && !defined(NO_FILESYSTEM)
|
||||||
|
byte certBuf[6000]; /* for PEM and CSR, client-cert.pem is 5-6kB */
|
||||||
|
word32 certBufSz = sizeof(certBuf);
|
||||||
|
#endif
|
||||||
|
#if ((!defined(USE_CERT_BUFFERS_2048) && !defined(USE_CERT_BUFFERS_1024)) || \
|
||||||
|
defined(WOLFSSL_CERT_REQ)) && !defined(NO_RSA) && !defined(NO_FILESYSTEM)
|
||||||
|
XFILE fp = XBADFILE;
|
||||||
|
#endif
|
||||||
|
#ifndef NO_RSA
|
||||||
|
RsaKey rsaKey;
|
||||||
|
#if defined(USE_CERT_BUFFERS_2048)
|
||||||
|
byte* rsaCertDer = (byte*)client_cert_der_2048;
|
||||||
|
word32 rsaCertDerSz = sizeof_client_cert_der_2048;
|
||||||
|
#elif defined(USE_CERT_BUFFERS_1024)
|
||||||
|
byte* rsaCertDer = (byte*)client_cert_der_1024;
|
||||||
|
word32 rsaCertDerSz = sizeof_client_cert_der_1024;
|
||||||
|
#else
|
||||||
|
unsigned char rsaCertDer[TWOK_BUF];
|
||||||
|
word32 rsaCertDerSz;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
ecc_key eccKey;
|
||||||
|
#if defined(USE_CERT_BUFFERS_256)
|
||||||
|
byte* eccCert = (byte*)cliecc_cert_der_256;
|
||||||
|
word32 eccCertSz = sizeof_cliecc_cert_der_256;
|
||||||
|
#else
|
||||||
|
unsigned char eccCert[ONEK_BUF];
|
||||||
|
word32 eccCertSz;
|
||||||
|
XFILE fp2 = XBADFILE;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NO_RSA
|
||||||
|
|
||||||
|
#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048)
|
||||||
|
ExpectTrue((fp = XFOPEN("./certs/1024/client-cert.der", "rb")) != XBADFILE);
|
||||||
|
ExpectIntGT(rsaCertDerSz = (word32)XFREAD(rsaCertDer, 1, sizeof(rsaCertDer),
|
||||||
|
fp), 0);
|
||||||
|
if (fp != XBADFILE) {
|
||||||
|
XFCLOSE(fp);
|
||||||
|
fp = XBADFILE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* good test case - RSA DER cert */
|
||||||
|
ExpectIntEQ(wc_GetSubjectPubKeyInfoDerFromCert(rsaCertDer, rsaCertDerSz,
|
||||||
|
keyDer, &keyDerSz), 0);
|
||||||
|
ExpectIntGT(keyDerSz, 0);
|
||||||
|
|
||||||
|
/* sanity check, verify we can import DER public key */
|
||||||
|
ret = wc_InitRsaKey(&rsaKey, HEAP_HINT);
|
||||||
|
ExpectIntEQ(ret, 0);
|
||||||
|
ExpectIntEQ(wc_RsaPublicKeyDecode(keyDer, &idx, &rsaKey, keyDerSz), 0);
|
||||||
|
if (ret == 0) {
|
||||||
|
wc_FreeRsaKey(&rsaKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bad args: certDer */
|
||||||
|
keyDerSz = (word32)sizeof(keyDer);
|
||||||
|
ExpectIntEQ(wc_GetSubjectPubKeyInfoDerFromCert(NULL, rsaCertDerSz, keyDer,
|
||||||
|
&keyDerSz),
|
||||||
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||||
|
|
||||||
|
/* bad args: 0 sized certSz */
|
||||||
|
keyDerSz = (word32)sizeof(keyDer);
|
||||||
|
ExpectIntEQ(wc_GetSubjectPubKeyInfoDerFromCert(rsaCertDer, 0, keyDer,
|
||||||
|
&keyDerSz),
|
||||||
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||||
|
|
||||||
|
/* bad args: NULL inout size */
|
||||||
|
ExpectIntEQ(ret = wc_GetSubjectPubKeyInfoDerFromCert(rsaCertDer,
|
||||||
|
rsaCertDerSz, keyDer,
|
||||||
|
NULL),
|
||||||
|
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||||
|
|
||||||
|
/* Certificate Request Tests */
|
||||||
|
#if defined(WOLFSSL_CERT_REQ) && !defined(NO_FILESYSTEM)
|
||||||
|
{
|
||||||
|
XMEMSET(certBuf, 0, sizeof(certBuf));
|
||||||
|
ExpectTrue((fp = XFOPEN("./certs/csr.signed.der", "rb")) != XBADFILE);
|
||||||
|
ExpectIntGT(certBufSz = (word32)XFREAD(certBuf, 1, certBufSz, fp), 0);
|
||||||
|
if (fp != XBADFILE) {
|
||||||
|
XFCLOSE(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* good test case - RSA DER certificate request */
|
||||||
|
keyDerSz = sizeof(keyDer);
|
||||||
|
ExpectIntEQ(ret = wc_GetSubjectPubKeyInfoDerFromCert(rsaCertDer,
|
||||||
|
rsaCertDerSz,
|
||||||
|
keyDer,
|
||||||
|
&keyDerSz), 0);
|
||||||
|
ExpectIntGT(keyDerSz, 0);
|
||||||
|
|
||||||
|
/* sanity check, verify we can import DER public key */
|
||||||
|
ret = wc_InitRsaKey(&rsaKey, HEAP_HINT);
|
||||||
|
ExpectIntEQ(ret, 0);
|
||||||
|
idx = 0;
|
||||||
|
ExpectIntEQ(wc_RsaPublicKeyDecode(keyDer, &idx, &rsaKey, keyDerSz), 0);
|
||||||
|
if (ret == 0) {
|
||||||
|
wc_FreeRsaKey(&rsaKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* WOLFSSL_CERT_REQ */
|
||||||
|
#endif /* NO_RSA */
|
||||||
|
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
#ifndef USE_CERT_BUFFERS_256
|
||||||
|
ExpectTrue((fp2 = XFOPEN("./certs/client-ecc-cert.der", "rb")) !=
|
||||||
|
XBADFILE);
|
||||||
|
ExpectIntGT(eccCertSz = (word32)XFREAD(eccCert, 1, ONEK_BUF, fp2), 0);
|
||||||
|
if (fp2 != XBADFILE) {
|
||||||
|
XFCLOSE(fp2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* good test case - ECC */
|
||||||
|
XMEMSET(keyDer, 0, sizeof(keyDer));
|
||||||
|
keyDerSz = sizeof(keyDer);
|
||||||
|
ExpectIntEQ(wc_GetSubjectPubKeyInfoDerFromCert(eccCert, eccCertSz, keyDer,
|
||||||
|
&keyDerSz), 0);
|
||||||
|
ExpectIntGT(keyDerSz, 0);
|
||||||
|
|
||||||
|
/* sanity check, verify we can import DER public key */
|
||||||
|
ret = wc_ecc_init(&eccKey);
|
||||||
|
ExpectIntEQ(ret, 0);
|
||||||
|
idx = 0; /* reset idx to 0, used above in RSA case */
|
||||||
|
ExpectIntEQ(wc_EccPublicKeyDecode(keyDer, &idx, &eccKey, keyDerSz), 0);
|
||||||
|
if (ret == 0) {
|
||||||
|
wc_ecc_free(&eccKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif /* !NO_RSA || HAVE_ECC */
|
||||||
|
return EXPECT_RESULT();
|
||||||
|
}
|
||||||
|
|
||||||
static int test_wc_CheckCertSigPubKey(void)
|
static int test_wc_CheckCertSigPubKey(void)
|
||||||
{
|
{
|
||||||
EXPECT_DECLS;
|
EXPECT_DECLS;
|
||||||
@@ -66846,6 +66991,7 @@ TEST_CASE testCases[] = {
|
|||||||
TEST_DECL(test_wc_PubKeyPemToDer),
|
TEST_DECL(test_wc_PubKeyPemToDer),
|
||||||
TEST_DECL(test_wc_PemPubKeyToDer),
|
TEST_DECL(test_wc_PemPubKeyToDer),
|
||||||
TEST_DECL(test_wc_GetPubKeyDerFromCert),
|
TEST_DECL(test_wc_GetPubKeyDerFromCert),
|
||||||
|
TEST_DECL(test_wc_GetSubjectPubKeyInfoDerFromCert),
|
||||||
TEST_DECL(test_wc_CheckCertSigPubKey),
|
TEST_DECL(test_wc_CheckCertSigPubKey),
|
||||||
|
|
||||||
/* wolfCrypt ASN tests */
|
/* wolfCrypt ASN tests */
|
||||||
|
@@ -23030,7 +23030,8 @@ static int CheckDate(ASNGetData *dataASN, int dateType)
|
|||||||
* @param [out] badDateRet Bad date return code.
|
* @param [out] badDateRet Bad date return code.
|
||||||
* @param [in] stopAtPubKey Stop parsing before subjectPublicKeyInfo.
|
* @param [in] stopAtPubKey Stop parsing before subjectPublicKeyInfo.
|
||||||
* @param [in] stopAfterPubKey Stop parsing after subjectPublicKeyInfo.
|
* @param [in] stopAfterPubKey Stop parsing after subjectPublicKeyInfo.
|
||||||
* @return 0 on success.
|
* @return 0 on success if of the stop arguments is not set, otherwise set to
|
||||||
|
* the corresponding byte offset at which the parsing stopped.
|
||||||
* @return ASN_CRIT_EXT_E when a critical extension was not recognized.
|
* @return ASN_CRIT_EXT_E when a critical extension was not recognized.
|
||||||
* @return ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
|
* @return ASN_TIME_E when date BER tag is nor UTC or GENERALIZED time.
|
||||||
* @return ASN_DATE_SZ_E when time data is not supported.
|
* @return ASN_DATE_SZ_E when time data is not supported.
|
||||||
@@ -24657,6 +24658,82 @@ int wc_CertGetPubKey(const byte* cert, word32 certSz,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Export the SubjectPublicKeyInfo from an X.509 certificate
|
||||||
|
*
|
||||||
|
* This function extracts the SubjectPublicKeyInfo (SPKI) section from an X.509
|
||||||
|
* certificate in DER format. The SPKI contains the public key algorithm and
|
||||||
|
* the public key itself.
|
||||||
|
*
|
||||||
|
* @param certDer [in] Pointer to the DER encoded certificate
|
||||||
|
* @param certSz [in] Size of the DER encoded certificate
|
||||||
|
* @param pubKeyDer [out] Buffer to hold the extracted SPKI (can be NULL to
|
||||||
|
* get size)
|
||||||
|
* @param pubKeyDerSz [in,out] On input, size of pubKeyDer buffer
|
||||||
|
* On output, actual size of the SPKI
|
||||||
|
*
|
||||||
|
* @return 0 on success, negative on error
|
||||||
|
* @return BAD_FUNC_ARG if certDer is NULL, certSz is 0, or pubKeyDerSz is NULL
|
||||||
|
* @return BUFFER_E if the provided buffer is too small
|
||||||
|
*/
|
||||||
|
WOLFSSL_API int wc_GetSubjectPubKeyInfoDerFromCert(const byte* certDer,
|
||||||
|
word32 certDerSz,
|
||||||
|
byte* pubKeyDer,
|
||||||
|
word32* pubKeyDerSz)
|
||||||
|
{
|
||||||
|
DecodedCert cert;
|
||||||
|
int ret;
|
||||||
|
word32 startIdx;
|
||||||
|
word32 idx;
|
||||||
|
word32 length;
|
||||||
|
int badDate;
|
||||||
|
|
||||||
|
if (certDer == NULL || certDerSz == 0 || pubKeyDerSz == NULL) {
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
length = 0;
|
||||||
|
badDate = 0;
|
||||||
|
|
||||||
|
wc_InitDecodedCert(&cert, certDer, certDerSz, NULL);
|
||||||
|
|
||||||
|
/* Parse up to the SubjectPublicKeyInfo */
|
||||||
|
ret = wc_GetPubX509(&cert, 0, &badDate);
|
||||||
|
if (ret >= 0) {
|
||||||
|
/* Save the starting index of SubjectPublicKeyInfo */
|
||||||
|
startIdx = cert.srcIdx;
|
||||||
|
|
||||||
|
/* Get the length of the SubjectPublicKeyInfo sequence */
|
||||||
|
idx = startIdx;
|
||||||
|
ret = GetSequence(certDer, &idx, (int*)&length, certDerSz);
|
||||||
|
if (ret >= 0) {
|
||||||
|
/* Calculate total length including sequence header */
|
||||||
|
length += (idx - startIdx);
|
||||||
|
|
||||||
|
/* Copy the SubjectPublicKeyInfo if buffer provided */
|
||||||
|
if (pubKeyDer != NULL) {
|
||||||
|
if (*pubKeyDerSz < (word32)length) {
|
||||||
|
ret = BUFFER_E;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
XMEMCPY(pubKeyDer, &certDer[startIdx], length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret >= 0) {
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pubKeyDerSz = length;
|
||||||
|
wc_FreeDecodedCert(&cert);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_OCSP
|
#ifdef HAVE_OCSP
|
||||||
Signer* findSignerByKeyHash(Signer *list, byte *hash)
|
Signer* findSignerByKeyHash(Signer *list, byte *hash)
|
||||||
{
|
{
|
||||||
|
@@ -862,6 +862,10 @@ WOLFSSL_API int wc_ParseCert(
|
|||||||
|
|
||||||
WOLFSSL_API int wc_GetPubKeyDerFromCert(struct DecodedCert* cert,
|
WOLFSSL_API int wc_GetPubKeyDerFromCert(struct DecodedCert* cert,
|
||||||
byte* derKey, word32* derKeySz);
|
byte* derKey, word32* derKeySz);
|
||||||
|
WOLFSSL_API int wc_GetSubjectPubKeyInfoDerFromCert(const byte* certDer,
|
||||||
|
word32 certDerSz,
|
||||||
|
byte* pubKeyDer,
|
||||||
|
word32* pubKeyDerSz);
|
||||||
|
|
||||||
#ifdef WOLFSSL_FPKI
|
#ifdef WOLFSSL_FPKI
|
||||||
WOLFSSL_API int wc_GetUUIDFromCert(struct DecodedCert* cert,
|
WOLFSSL_API int wc_GetUUIDFromCert(struct DecodedCert* cert,
|
||||||
|
Reference in New Issue
Block a user