mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 16:30:49 +02:00
x509: fix malformed AKID extension from wolfSSL_X509_set_authority_key_id
This commit is contained in:
+27
-13
@@ -16333,6 +16333,9 @@ int wolfSSL_X509_set_subject_key_id_ex(WOLFSSL_X509* x509)
|
||||
#endif /* !NO_SHA */
|
||||
|
||||
/* Set Authority Key Identifier from raw bytes.
|
||||
* The bytes passed in are the keyIdentifier OCTET STRING contents only,
|
||||
* they must not be a pre-encoded AuthorityKeyIdentifier SEQUENCE.
|
||||
* The cert encoder wraps them in SEQUENCE { [0] keyIdentifier } at sign time.
|
||||
*
|
||||
* x509 - Certificate to modify
|
||||
* akid - Raw AKID bytes
|
||||
@@ -16343,27 +16346,38 @@ int wolfSSL_X509_set_subject_key_id_ex(WOLFSSL_X509* x509)
|
||||
int wolfSSL_X509_set_authority_key_id(WOLFSSL_X509* x509,
|
||||
const unsigned char* akid, int akidSz)
|
||||
{
|
||||
byte* newAkid = NULL;
|
||||
|
||||
WOLFSSL_ENTER("wolfSSL_X509_set_authority_key_id");
|
||||
|
||||
if (x509 == NULL || akid == NULL || akidSz <= 0) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
|
||||
/* Allocate/reallocate memory for authKeyIdSrc */
|
||||
if (x509->authKeyIdSrc == NULL || (int)x509->authKeyIdSrcSz < akidSz) {
|
||||
if (x509->authKeyIdSrc != NULL) {
|
||||
XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
|
||||
}
|
||||
x509->authKeyIdSrc = (byte*)XMALLOC((word32)akidSz, x509->heap,
|
||||
DYNAMIC_TYPE_X509_EXT);
|
||||
if (x509->authKeyIdSrc == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
/* Allocate new buffer up front so failure leaves prior state intact */
|
||||
newAkid = (byte*)XMALLOC((word32)akidSz, x509->heap, DYNAMIC_TYPE_X509_EXT);
|
||||
if (newAkid == NULL) {
|
||||
return WOLFSSL_FAILURE;
|
||||
}
|
||||
XMEMCPY(newAkid, akid, (word32)akidSz);
|
||||
|
||||
/* Free any prior storage. authKeyIdSrc may be populated from a prior
|
||||
* parse cert operation. authKeyId aliases inside that buffer, so
|
||||
* authKeyIdSrc must be freed first to avoid a dangling authKeyId. */
|
||||
if (x509->authKeyIdSrc != NULL) {
|
||||
XFREE(x509->authKeyIdSrc, x509->heap, DYNAMIC_TYPE_X509_EXT);
|
||||
x509->authKeyIdSrc = NULL;
|
||||
x509->authKeyIdSrcSz = 0;
|
||||
}
|
||||
else if (x509->authKeyId != NULL) {
|
||||
XFREE(x509->authKeyId, x509->heap, DYNAMIC_TYPE_X509_EXT);
|
||||
}
|
||||
|
||||
XMEMCPY(x509->authKeyIdSrc, akid, (word32)akidSz);
|
||||
x509->authKeyIdSrcSz = (word32)akidSz;
|
||||
x509->authKeyId = x509->authKeyIdSrc;
|
||||
/* Store newAkid as authKeyId only, do not populate authKeyIdSrc.
|
||||
* When authKeyIdSrc is non-NULL, the encoder writes those bytes without
|
||||
* SEQUENCE/[0] wrapper. authKeyIdSrc must be NULL here so encoder does
|
||||
* wrap them. */
|
||||
x509->authKeyId = newAkid;
|
||||
x509->authKeyIdSz = (word32)akidSz;
|
||||
x509->authKeyIdSet = 1;
|
||||
|
||||
|
||||
+416
@@ -19832,6 +19832,419 @@ static int test_wolfSSL_X509_set_extensions(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* Round trip test for wolfSSL_X509_set_authority_key_id() with a raw key ID.
|
||||
*
|
||||
* Builds a cert, calls the setter with a 20-byte raw keyId, signs the cert,
|
||||
* serializes to DER via wolfSSL_i2d_X509(), re-parses the DER, locates the
|
||||
* AKID extension, and asserts the OCTET STRING contents match the
|
||||
* AuthorityKeyIdentifier ASN.1 structure required by RFC 5280 4.2.1.1:
|
||||
*
|
||||
* SEQUENCE (0x30) length 22 (0x16)
|
||||
* [0] (0x80) length 20 (0x14)
|
||||
* <20 keyId bytes>
|
||||
*
|
||||
* The keyId bytes inside the [0] tag must equal the input passed the setter. */
|
||||
static int test_wolfSSL_X509_set_authority_key_id_roundtrip(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
|
||||
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) && \
|
||||
!defined(NO_RSA) && !defined(NO_FILESYSTEM) && !defined(NO_ASN_TIME)
|
||||
WOLFSSL_X509* src = NULL;
|
||||
WOLFSSL_X509* built = NULL;
|
||||
WOLFSSL_X509* parsed = NULL;
|
||||
WOLFSSL_EVP_PKEY* priv = NULL;
|
||||
WOLFSSL_EVP_PKEY* pub = NULL;
|
||||
WOLFSSL_ASN1_TIME* notBefore = NULL;
|
||||
WOLFSSL_ASN1_TIME* notAfter = NULL;
|
||||
WOLFSSL_X509_EXTENSION* ext = NULL;
|
||||
WOLFSSL_ASN1_STRING* extData = NULL;
|
||||
unsigned char* der = NULL;
|
||||
const unsigned char* derPtr = NULL;
|
||||
unsigned char* key = NULL;
|
||||
unsigned char* keyPt = NULL;
|
||||
char* name = NULL;
|
||||
char* header = NULL;
|
||||
long keySz = 0;
|
||||
int derSz = 0;
|
||||
int extIdx = -1;
|
||||
XFILE fp = XBADFILE;
|
||||
time_t t;
|
||||
|
||||
/* Raw 20-byte key identifier */
|
||||
byte akid[20] = {
|
||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
|
||||
0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23
|
||||
};
|
||||
|
||||
/* Load reference cert + key (RSA) */
|
||||
src = wolfSSL_X509_load_certificate_file(cliCertFile, WOLFSSL_FILETYPE_PEM);
|
||||
ExpectNotNull(src);
|
||||
|
||||
ExpectTrue((fp = XFOPEN(cliKeyFile, "rb")) != XBADFILE);
|
||||
ExpectIntEQ(wolfSSL_PEM_read(fp, &name, &header, &key, &keySz),
|
||||
WOLFSSL_SUCCESS);
|
||||
if (fp != XBADFILE) {
|
||||
XFCLOSE(fp);
|
||||
}
|
||||
keyPt = key;
|
||||
ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL,
|
||||
(const unsigned char**)&keyPt, keySz));
|
||||
|
||||
/* Build a v3 cert and copy fields from src */
|
||||
ExpectNotNull(built = wolfSSL_X509_new());
|
||||
ExpectIntEQ(wolfSSL_X509_set_version(built, 2), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_X509_set_subject_name(built,
|
||||
wolfSSL_X509_get_subject_name(src)), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_X509_set_issuer_name(built,
|
||||
wolfSSL_X509_get_issuer_name(src)), WOLFSSL_SUCCESS);
|
||||
ExpectNotNull(pub = wolfSSL_X509_get_pubkey(src));
|
||||
ExpectIntEQ(wolfSSL_X509_set_pubkey(built, pub), WOLFSSL_SUCCESS);
|
||||
|
||||
t = time(NULL);
|
||||
ExpectNotNull(notBefore = wolfSSL_ASN1_TIME_adj(NULL, t, 0, 0));
|
||||
ExpectNotNull(notAfter = wolfSSL_ASN1_TIME_adj(NULL, t, 365, 0));
|
||||
ExpectTrue(wolfSSL_X509_set_notBefore(built, notBefore));
|
||||
ExpectTrue(wolfSSL_X509_set_notAfter(built, notAfter));
|
||||
|
||||
/* Set AKID with a raw key identifier */
|
||||
ExpectIntEQ(wolfSSL_X509_set_authority_key_id(built, akid, sizeof(akid)),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
/* Sign and serialize. */
|
||||
ExpectIntGT(wolfSSL_X509_sign(built, priv, EVP_sha256()), 0);
|
||||
ExpectIntGT((derSz = wolfSSL_i2d_X509(built, &der)), 0);
|
||||
|
||||
/* Re-parse the DER we just produced */
|
||||
derPtr = der;
|
||||
ExpectNotNull(parsed = wolfSSL_d2i_X509(NULL, &derPtr, derSz));
|
||||
|
||||
/* Locate the AKID extension and pull out the OCTET STRING contents
|
||||
* (per RFC 5280 must be a SEQUENCE { [0] keyIdentifier ... }) */
|
||||
ExpectIntGE((extIdx = wolfSSL_X509_get_ext_by_NID(parsed,
|
||||
NID_authority_key_identifier, -1)), 0);
|
||||
ExpectNotNull(ext = wolfSSL_X509_get_ext(parsed, extIdx));
|
||||
ExpectNotNull(extData = wolfSSL_X509_EXTENSION_get_data(ext));
|
||||
|
||||
/* Encoded inner extension structure for a 20-byte keyId is 24 bytes:
|
||||
* SEQUENCE (0x30) length 22 (0x16)
|
||||
* [0] (0x80) length 20 (0x14)
|
||||
* <20 keyId bytes>
|
||||
*/
|
||||
ExpectIntEQ(extData->length, 24);
|
||||
if (extData != NULL && extData->data != NULL && extData->length == 24) {
|
||||
ExpectIntEQ((unsigned char)extData->data[0], 0x30);
|
||||
ExpectIntEQ((unsigned char)extData->data[1], 0x16);
|
||||
ExpectIntEQ((unsigned char)extData->data[2], 0x80);
|
||||
ExpectIntEQ((unsigned char)extData->data[3], 0x14);
|
||||
ExpectIntEQ(XMEMCMP((const byte*)extData->data + 4, akid,
|
||||
sizeof(akid)), 0);
|
||||
}
|
||||
|
||||
XFREE(der, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
|
||||
XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(name, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(header, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
wolfSSL_X509_free(src);
|
||||
wolfSSL_X509_free(built);
|
||||
wolfSSL_X509_free(parsed);
|
||||
|
||||
wolfSSL_EVP_PKEY_free(priv);
|
||||
wolfSSL_EVP_PKEY_free(pub);
|
||||
|
||||
wolfSSL_ASN1_TIME_free(notBefore);
|
||||
wolfSSL_ASN1_TIME_free(notAfter);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* Round trip test for wolfSSL_X509_set_authority_key_id_ex().
|
||||
*
|
||||
* Inserts a known SubjectKeyIdentifier on the issuer cert, calls the _ex
|
||||
* variant of the setter (which derives the AKID keyId from the issuer SKID,
|
||||
* or from SHA-1 of the issuer public key when no SKID is set), signs,
|
||||
* serializes to DER, re-parses, and asserts the AKID extension OCTET STRING
|
||||
* contents match the RFC 5280 4.2.1.1 structure
|
||||
*
|
||||
* SEQUENCE (0x30) length 22 (0x16)
|
||||
* [0] (0x80) length 20 (0x14)
|
||||
* <20 keyId bytes>
|
||||
*
|
||||
* with the embedded keyId equal to the issuer's SKID. */
|
||||
static int test_wolfSSL_X509_set_authority_key_id_ex_roundtrip(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
|
||||
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) && \
|
||||
!defined(NO_RSA) && !defined(NO_FILESYSTEM) && !defined(NO_ASN_TIME) && \
|
||||
!defined(NO_SHA)
|
||||
WOLFSSL_X509* issuer = NULL;
|
||||
WOLFSSL_X509* built = NULL;
|
||||
WOLFSSL_X509* parsed = NULL;
|
||||
WOLFSSL_EVP_PKEY* priv = NULL;
|
||||
WOLFSSL_EVP_PKEY* pub = NULL;
|
||||
WOLFSSL_ASN1_TIME* notBefore = NULL;
|
||||
WOLFSSL_ASN1_TIME* notAfter = NULL;
|
||||
WOLFSSL_X509_EXTENSION* ext = NULL;
|
||||
WOLFSSL_ASN1_STRING* extData = NULL;
|
||||
unsigned char* der = NULL;
|
||||
const unsigned char* derPtr = NULL;
|
||||
unsigned char* key = NULL;
|
||||
unsigned char* keyPt = NULL;
|
||||
char* name = NULL;
|
||||
char* header = NULL;
|
||||
long keySz = 0;
|
||||
int derSz = 0;
|
||||
int extIdx = -1;
|
||||
XFILE fp = XBADFILE;
|
||||
time_t t;
|
||||
|
||||
/* SKID on the issuer. The AKID on the built cert should match this. */
|
||||
byte issuerSkid[20] = {
|
||||
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
|
||||
0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43
|
||||
};
|
||||
|
||||
/* Load the cert to use as both issuer and the source of subject/key. */
|
||||
ExpectNotNull(issuer = wolfSSL_X509_load_certificate_file(cliCertFile,
|
||||
WOLFSSL_FILETYPE_PEM));
|
||||
|
||||
/* Stamp known SKID on the issuer so set_authority_key_id_ex has a
|
||||
* deterministic value to copy into the AKID. */
|
||||
ExpectIntEQ(wolfSSL_X509_set_subject_key_id(issuer, issuerSkid,
|
||||
sizeof(issuerSkid)), WOLFSSL_SUCCESS);
|
||||
|
||||
ExpectTrue((fp = XFOPEN(cliKeyFile, "rb")) != XBADFILE);
|
||||
ExpectIntEQ(wolfSSL_PEM_read(fp, &name, &header, &key, &keySz),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
if (fp != XBADFILE) {
|
||||
XFCLOSE(fp);
|
||||
}
|
||||
|
||||
keyPt = key;
|
||||
ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL,
|
||||
(const unsigned char**)&keyPt, keySz));
|
||||
|
||||
ExpectNotNull(built = wolfSSL_X509_new());
|
||||
ExpectIntEQ(wolfSSL_X509_set_version(built, 2), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_X509_set_subject_name(built,
|
||||
wolfSSL_X509_get_subject_name(issuer)), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_X509_set_issuer_name(built,
|
||||
wolfSSL_X509_get_subject_name(issuer)), WOLFSSL_SUCCESS);
|
||||
ExpectNotNull(pub = wolfSSL_X509_get_pubkey(issuer));
|
||||
ExpectIntEQ(wolfSSL_X509_set_pubkey(built, pub), WOLFSSL_SUCCESS);
|
||||
|
||||
t = time(NULL);
|
||||
ExpectNotNull(notBefore = wolfSSL_ASN1_TIME_adj(NULL, t, 0, 0));
|
||||
ExpectNotNull(notAfter = wolfSSL_ASN1_TIME_adj(NULL, t, 365, 0));
|
||||
ExpectTrue(wolfSSL_X509_set_notBefore(built, notBefore));
|
||||
ExpectTrue(wolfSSL_X509_set_notAfter(built, notAfter));
|
||||
|
||||
/* Derive AKID from the issuer's SKID */
|
||||
ExpectIntEQ(wolfSSL_X509_set_authority_key_id_ex(built, issuer),
|
||||
WOLFSSL_SUCCESS);
|
||||
|
||||
ExpectIntGT(wolfSSL_X509_sign(built, priv, EVP_sha256()), 0);
|
||||
ExpectIntGT((derSz = wolfSSL_i2d_X509(built, &der)), 0);
|
||||
|
||||
derPtr = der;
|
||||
ExpectNotNull(parsed = wolfSSL_d2i_X509(NULL, &derPtr, derSz));
|
||||
|
||||
ExpectIntGE((extIdx = wolfSSL_X509_get_ext_by_NID(parsed,
|
||||
NID_authority_key_identifier, -1)), 0);
|
||||
ExpectNotNull(ext = wolfSSL_X509_get_ext(parsed, extIdx));
|
||||
ExpectNotNull(extData = wolfSSL_X509_EXTENSION_get_data(ext));
|
||||
|
||||
/* AuthorityKeyIdentifier inner structure for a 20-byte keyId is 24 bytes:
|
||||
* SEQUENCE { [0] keyId }. keyId on built cert must equal issuer SKID. */
|
||||
ExpectIntEQ(extData->length, 24);
|
||||
if (extData != NULL && extData->data != NULL && extData->length == 24) {
|
||||
ExpectIntEQ((unsigned char)extData->data[0], 0x30);
|
||||
ExpectIntEQ((unsigned char)extData->data[1], 0x16);
|
||||
ExpectIntEQ((unsigned char)extData->data[2], 0x80);
|
||||
ExpectIntEQ((unsigned char)extData->data[3], 0x14);
|
||||
ExpectIntEQ(XMEMCMP((const byte*)extData->data + 4, issuerSkid,
|
||||
sizeof(issuerSkid)), 0);
|
||||
}
|
||||
|
||||
XFREE(der, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
|
||||
XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(name, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(header, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
wolfSSL_X509_free(issuer);
|
||||
wolfSSL_X509_free(built);
|
||||
wolfSSL_X509_free(parsed);
|
||||
|
||||
wolfSSL_EVP_PKEY_free(priv);
|
||||
wolfSSL_EVP_PKEY_free(pub);
|
||||
|
||||
wolfSSL_ASN1_TIME_free(notBefore);
|
||||
wolfSSL_ASN1_TIME_free(notAfter);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* Verifies that wolfSSL_X509_set_authority_key_id() correctly handles being
|
||||
* called on a WOLFSSL_X509 that already has AKID storage.
|
||||
*
|
||||
* Case 1: two consecutive setter calls on a fresh built cert. Calls setter
|
||||
* twice with different keyIds (second call should replace first AKID).
|
||||
* Case 2: setter called on an X509 loaded from a PEM file that already has
|
||||
* an AKID extension.
|
||||
*/
|
||||
static int test_wolfSSL_X509_set_authority_key_id_overwrite(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \
|
||||
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) && \
|
||||
!defined(NO_RSA) && !defined(NO_FILESYSTEM) && !defined(NO_ASN_TIME)
|
||||
WOLFSSL_X509* src = NULL;
|
||||
WOLFSSL_X509* built = NULL;
|
||||
WOLFSSL_X509* parsed = NULL;
|
||||
WOLFSSL_X509* loaded = NULL;
|
||||
WOLFSSL_EVP_PKEY* priv = NULL;
|
||||
WOLFSSL_EVP_PKEY* pub = NULL;
|
||||
WOLFSSL_ASN1_TIME* notBefore = NULL;
|
||||
WOLFSSL_ASN1_TIME* notAfter = NULL;
|
||||
WOLFSSL_X509_EXTENSION* ext = NULL;
|
||||
WOLFSSL_ASN1_STRING* extData = NULL;
|
||||
unsigned char* der = NULL;
|
||||
const unsigned char* derPtr = NULL;
|
||||
unsigned char* key = NULL;
|
||||
unsigned char* keyPt = NULL;
|
||||
char* name = NULL;
|
||||
char* header = NULL;
|
||||
long keySz = 0;
|
||||
int derSz = 0;
|
||||
int extIdx = -1;
|
||||
XFILE fp = XBADFILE;
|
||||
time_t t;
|
||||
|
||||
byte akid1[20] = {
|
||||
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,
|
||||
0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14
|
||||
};
|
||||
byte akid2[20] = {
|
||||
0xaa,0xbb,0xcc,0xdd,0xee,0xff,0x00,0x11,0x22,0x33,
|
||||
0x44,0x55,0x66,0x77,0x88,0x99,0xa0,0xb0,0xc0,0xd0
|
||||
};
|
||||
|
||||
/* Case 1: set twice on a fresh built cert */
|
||||
ExpectNotNull(src = wolfSSL_X509_load_certificate_file(cliCertFile,
|
||||
WOLFSSL_FILETYPE_PEM));
|
||||
ExpectTrue((fp = XFOPEN(cliKeyFile, "rb")) != XBADFILE);
|
||||
ExpectIntEQ(wolfSSL_PEM_read(fp, &name, &header, &key, &keySz),
|
||||
WOLFSSL_SUCCESS);
|
||||
if (fp != XBADFILE) {
|
||||
XFCLOSE(fp);
|
||||
}
|
||||
|
||||
keyPt = key;
|
||||
ExpectNotNull(priv = wolfSSL_d2i_PrivateKey(EVP_PKEY_RSA, NULL,
|
||||
(const unsigned char**)&keyPt, keySz));
|
||||
|
||||
ExpectNotNull(built = wolfSSL_X509_new());
|
||||
ExpectIntEQ(wolfSSL_X509_set_version(built, 2), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_X509_set_subject_name(built,
|
||||
wolfSSL_X509_get_subject_name(src)), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_X509_set_issuer_name(built,
|
||||
wolfSSL_X509_get_issuer_name(src)), WOLFSSL_SUCCESS);
|
||||
ExpectNotNull(pub = wolfSSL_X509_get_pubkey(src));
|
||||
ExpectIntEQ(wolfSSL_X509_set_pubkey(built, pub), WOLFSSL_SUCCESS);
|
||||
|
||||
t = time(NULL);
|
||||
ExpectNotNull(notBefore = wolfSSL_ASN1_TIME_adj(NULL, t, 0, 0));
|
||||
ExpectNotNull(notAfter = wolfSSL_ASN1_TIME_adj(NULL, t, 365, 0));
|
||||
ExpectTrue(wolfSSL_X509_set_notBefore(built, notBefore));
|
||||
ExpectTrue(wolfSSL_X509_set_notAfter(built, notAfter));
|
||||
|
||||
/* Two setter calls with distinct keyIds, no prior AKID on cert */
|
||||
ExpectIntEQ(wolfSSL_X509_set_authority_key_id(built, akid1,
|
||||
sizeof(akid1)), WOLFSSL_SUCCESS);
|
||||
ExpectIntEQ(wolfSSL_X509_set_authority_key_id(built, akid2,
|
||||
sizeof(akid2)), WOLFSSL_SUCCESS);
|
||||
|
||||
ExpectIntGT(wolfSSL_X509_sign(built, priv, EVP_sha256()), 0);
|
||||
ExpectIntGT((derSz = wolfSSL_i2d_X509(built, &der)), 0);
|
||||
|
||||
derPtr = der;
|
||||
ExpectNotNull(parsed = wolfSSL_d2i_X509(NULL, &derPtr, derSz));
|
||||
|
||||
ExpectIntGE((extIdx = wolfSSL_X509_get_ext_by_NID(parsed,
|
||||
NID_authority_key_identifier, -1)), 0);
|
||||
ExpectNotNull(ext = wolfSSL_X509_get_ext(parsed, extIdx));
|
||||
ExpectNotNull(extData = wolfSSL_X509_EXTENSION_get_data(ext));
|
||||
/* AKID extension must hold akid2, wrapped in:
|
||||
* SEQUENCE { [0] keyId } (24 bytes for a 20-byte keyId) */
|
||||
ExpectIntEQ(extData->length, 24);
|
||||
if (extData != NULL && extData->data != NULL && extData->length == 24) {
|
||||
ExpectIntEQ((unsigned char)extData->data[0], 0x30);
|
||||
ExpectIntEQ((unsigned char)extData->data[2], 0x80);
|
||||
ExpectIntEQ((unsigned char)extData->data[3], 0x14);
|
||||
ExpectIntEQ(XMEMCMP((const byte*)extData->data + 4, akid2,
|
||||
sizeof(akid2)), 0);
|
||||
}
|
||||
|
||||
/* Free DER/parsed cert so Case 2 can reuse the variables. */
|
||||
XFREE(der, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
|
||||
der = NULL;
|
||||
derSz = 0;
|
||||
wolfSSL_X509_free(parsed);
|
||||
parsed = NULL;
|
||||
|
||||
/* Case 2: set on cert loaded from PEM file that already has an AKID. */
|
||||
ExpectNotNull(loaded = wolfSSL_X509_load_certificate_file(cliCertFile,
|
||||
WOLFSSL_FILETYPE_PEM));
|
||||
ExpectIntEQ(wolfSSL_X509_set_authority_key_id(loaded, akid1,
|
||||
sizeof(akid1)), WOLFSSL_SUCCESS);
|
||||
|
||||
/* Re-sign with priv and re-encode so we can inspect the freshly
|
||||
* encoded AKID. Signature/issuer binding correctness is not part of
|
||||
* this test; only the DER round-trip of the AKID extension is. */
|
||||
ExpectIntGT(wolfSSL_X509_sign(loaded, priv, EVP_sha256()), 0);
|
||||
ExpectIntGT((derSz = wolfSSL_i2d_X509(loaded, &der)), 0);
|
||||
|
||||
derPtr = der;
|
||||
ExpectNotNull(parsed = wolfSSL_d2i_X509(NULL, &derPtr, derSz));
|
||||
|
||||
extIdx = -1;
|
||||
ExpectIntGE((extIdx = wolfSSL_X509_get_ext_by_NID(parsed,
|
||||
NID_authority_key_identifier, -1)), 0);
|
||||
ExpectNotNull(ext = wolfSSL_X509_get_ext(parsed, extIdx));
|
||||
ExpectNotNull(extData = wolfSSL_X509_EXTENSION_get_data(ext));
|
||||
/* AKID extension must hold akid1 wrapped in SEQUENCE { [0] keyId }
|
||||
* (24 bytes for 20-byte keyId), not the original parsed-cert AKID. */
|
||||
ExpectIntEQ(extData->length, 24);
|
||||
if (extData != NULL && extData->data != NULL && extData->length == 24) {
|
||||
ExpectIntEQ((unsigned char)extData->data[0], 0x30);
|
||||
ExpectIntEQ((unsigned char)extData->data[2], 0x80);
|
||||
ExpectIntEQ((unsigned char)extData->data[3], 0x14);
|
||||
ExpectIntEQ(XMEMCMP((const byte*)extData->data + 4, akid1,
|
||||
sizeof(akid1)), 0);
|
||||
}
|
||||
|
||||
XFREE(der, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
|
||||
XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(name, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
XFREE(header, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
wolfSSL_X509_free(src);
|
||||
wolfSSL_X509_free(built);
|
||||
wolfSSL_X509_free(parsed);
|
||||
wolfSSL_X509_free(loaded);
|
||||
|
||||
wolfSSL_EVP_PKEY_free(priv);
|
||||
wolfSSL_EVP_PKEY_free(pub);
|
||||
|
||||
wolfSSL_ASN1_TIME_free(notBefore);
|
||||
wolfSSL_ASN1_TIME_free(notAfter);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
static int test_wolfSSL_OpenSSL_add_all_algorithms(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
@@ -37213,6 +37626,9 @@ TEST_CASE testCases[] = {
|
||||
TEST_DECL(test_wolfSSL_X509_ALGOR_get0),
|
||||
TEST_DECL(test_wolfSSL_X509_SEP),
|
||||
TEST_DECL(test_wolfSSL_X509_set_extensions),
|
||||
TEST_DECL(test_wolfSSL_X509_set_authority_key_id_roundtrip),
|
||||
TEST_DECL(test_wolfSSL_X509_set_authority_key_id_ex_roundtrip),
|
||||
TEST_DECL(test_wolfSSL_X509_set_authority_key_id_overwrite),
|
||||
TEST_DECL(test_wolfSSL_X509_CRL),
|
||||
#ifndef NO_BIO
|
||||
TEST_DECL(test_wolfSSL_X509_print),
|
||||
|
||||
Reference in New Issue
Block a user