diff --git a/src/internal.c b/src/internal.c index aa9387267..dc80d01d7 100644 --- a/src/internal.c +++ b/src/internal.c @@ -13476,8 +13476,10 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) x509->altNamesNext = x509->altNames; /* index hint */ x509->isCa = dCert->isCA; + x509->basicConstCrit = dCert->extBasicConstCrit; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) x509->pathLength = dCert->pathLength; + x509->pathLengthSet = dCert->pathLengthSet; x509->keyUsage = dCert->extKeyUsage; x509->CRLdistSet = dCert->extCRLdistSet; @@ -13531,7 +13533,6 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) } #endif x509->basicConstSet = dCert->extBasicConstSet; - x509->basicConstCrit = dCert->extBasicConstCrit; x509->basicConstPlSet = dCert->pathLengthSet; x509->subjAltNameSet = dCert->extSubjAltNameSet; x509->subjAltNameCrit = dCert->extSubjAltNameCrit; @@ -13644,6 +13645,7 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) if (x509->sapkiDer != NULL) { XMEMCPY(x509->sapkiDer, dCert->sapkiDer, dCert->sapkiLen); x509->sapkiLen = dCert->sapkiLen; + x509->sapkiCrit = dCert->extSapkiCrit; } else { ret = MEMORY_E; @@ -13656,6 +13658,7 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) XMEMCPY(x509->altSigAlgDer, dCert->altSigAlgDer, dCert->altSigAlgLen); x509->altSigAlgLen = dCert->altSigAlgLen; + x509->altSigAlgCrit = dCert->extAltSigAlgCrit; } else { ret = MEMORY_E; @@ -13668,6 +13671,7 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) XMEMCPY(x509->altSigValDer, dCert->altSigValDer, dCert->altSigValLen); x509->altSigValLen = dCert->altSigValLen; + x509->altSigValCrit = dCert->extAltSigValCrit; } else { ret = MEMORY_E; diff --git a/src/x509.c b/src/x509.c index fec65d621..bd4d09464 100644 --- a/src/x509.c +++ b/src/x509.c @@ -10674,7 +10674,10 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509) cert->sigType = wolfSSL_X509_get_signature_type(x509); cert->keyType = x509->pubKeyOID; cert->isCA = wolfSSL_X509_get_isCA(x509); + cert->basicConstCrit = x509->basicConstCrit; cert->basicConstSet = x509->basicConstSet; + cert->pathLen = x509->pathLength; + cert->pathLenSet = x509->pathLengthSet; #ifdef WOLFSSL_CERT_EXT if (x509->subjKeyIdSz <= CTC_MAX_SKID_SIZE) { @@ -10741,10 +10744,13 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509) /* We point to instance in x509 so DON'T need to be free'd. */ cert->sapkiDer = x509->sapkiDer; cert->sapkiLen = x509->sapkiLen; + cert->sapkiCrit = x509->sapkiCrit; cert->altSigAlgDer = x509->altSigAlgDer; - cert->altSigAlgLen = x509->altSigAlgLen; + cert->altSigAlgLen = x509->altSigAlgLen; + cert->altSigAlgCrit = x509->altSigAlgCrit; cert->altSigValDer = x509->altSigValDer; cert->altSigValLen = x509->altSigValLen; + cert->altSigValCrit = x509->altSigValCrit; #endif /* WOLFSSL_DUAL_ALG_CERTS */ #endif /* WOLFSSL_CERT_EXT */ diff --git a/tests/api.c b/tests/api.c index 6b6596bcf..ae9440458 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1033,6 +1033,7 @@ static int do_dual_alg_root_certgen(byte **out, char *caKeyFile, XMEMSET(scratchBuf, 0, scratchSz); ExpectIntGT(scratchSz = wc_MakeSelfCert(&newCert, scratchBuf, scratchSz, &caKey, &rng), 0); + wc_InitDecodedCert(&preTBS, scratchBuf, scratchSz, 0); ExpectIntEQ(wc_ParseCert(&preTBS, CERT_TYPE, NO_VERIFY, NULL), 0); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ebb0a8369..647813449 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -21320,6 +21320,7 @@ static int DecodeExtensionType(const byte* input, word32 length, word32 oid, case BASIC_CA_OID: VERIFY_AND_SET_OID(cert->extBasicConstSet); cert->extBasicConstCrit = critical ? 1 : 0; + cert->extBasicConstCrit = critical ? 1 : 0; if (DecodeBasicCaConstraint(input, (int)length, cert) < 0) { ret = ASN_PARSE_E; } @@ -21509,16 +21510,19 @@ static int DecodeExtensionType(const byte* input, word32 length, word32 oid, #ifdef WOLFSSL_DUAL_ALG_CERTS case SUBJ_ALT_PUB_KEY_INFO_OID: VERIFY_AND_SET_OID(cert->extSapkiSet); + cert->extSapkiCrit = critical ? 1 : 0; if (DecodeSubjAltPubKeyInfo(&input[idx], length, cert) < 0) return ASN_PARSE_E; break; case ALT_SIG_ALG_OID: VERIFY_AND_SET_OID(cert->extAltSigAlgSet); + cert->extAltSigAlgCrit = critical ? 1 : 0; if (DecodeAltSigAlg(&input[idx], length, cert) < 0) return ASN_PARSE_E; break; case ALT_SIG_VAL_OID: VERIFY_AND_SET_OID(cert->extAltSigValSet); + cert->extAltSigValCrit = critical ? 1 : 0; if (DecodeAltSigVal(&input[idx], length, cert) < 0) return ASN_PARSE_E; break; @@ -28982,6 +28986,7 @@ static const ASNItem static_certExtsASN[] = { /* Basic Constraints Extension - 4.2.1.9 */ /* BC_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 }, /* BC_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* BC_CRIT */ { 1, ASN_BOOLEAN, 0, 0, 0 }, /* BC_STR */ { 1, ASN_OCTET_STRING, 0, 1, 0 }, /* BC_STR_SEQ */ { 2, ASN_SEQUENCE, 1, 1, 0 }, /* cA */ @@ -29030,12 +29035,15 @@ static const ASNItem static_certExtsASN[] = { #ifdef WOLFSSL_DUAL_ALG_CERTS /* SAPKI_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 }, /* SAPKI_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* SAPKI_CRIT */ { 1, ASN_BOOLEAN, 0, 0, 0 }, /* SAPKI_STR */ { 1, ASN_OCTET_STRING, 0, 0, 0 }, /* ALTSIGALG_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 }, /* ALTSIGALG_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* ALTSIGALG_CRIT*/ { 1, ASN_BOOLEAN, 0, 0, 0 }, /* ALTSIGALG_STR */ { 1, ASN_OCTET_STRING, 0, 0, 0 }, /* ALTSIGVAL_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 }, /* ALTSIGVAL_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* ALTSIGVAL_CRIT*/ { 1, ASN_BOOLEAN, 0, 0, 0 }, /* ALTSIGVAL_STR */ { 1, ASN_OCTET_STRING, 0, 0, 0 }, #endif /* WOLFSSL_DUAL_ALG_CERTS */ /* CUSTOM_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 }, @@ -29045,6 +29053,7 @@ static const ASNItem static_certExtsASN[] = { enum { CERTEXTSASN_IDX_BC_SEQ = 0, CERTEXTSASN_IDX_BC_OID, + CERTEXTSASN_IDX_BC_CRIT, CERTEXTSASN_IDX_BC_STR, CERTEXTSASN_IDX_BC_STR_SEQ, CERTEXTSASN_IDX_BC_CA, @@ -29084,12 +29093,15 @@ enum { #ifdef WOLFSSL_DUAL_ALG_CERTS CERTEXTSASN_IDX_SAPKI_SEQ, CERTEXTSASN_IDX_SAPKI_OID, + CERTEXTSASN_IDX_SAPKI_CRIT, CERTEXTSASN_IDX_SAPKI_STR, CERTEXTSASN_IDX_ALTSIGALG_SEQ, CERTEXTSASN_IDX_ALTSIGALG_OID, + CERTEXTSASN_IDX_ALTSIGALG_CRIT, CERTEXTSASN_IDX_ALTSIGALG_STR, CERTEXTSASN_IDX_ALTSIGVAL_SEQ, CERTEXTSASN_IDX_ALTSIGVAL_OID, + CERTEXTSASN_IDX_ALTSIGVAL_CRIT, CERTEXTSASN_IDX_ALTSIGVAL_STR, #endif /* WOLFSSL_DUAL_ALG_CERTS */ CERTEXTSASN_IDX_CUSTOM_SEQ, @@ -29181,6 +29193,12 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, /* Set Basic Constraints to be a Certificate Authority. */ SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CA], 1); SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID)); + if (cert->basicConstCrit) { + SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CRIT], 1); + } + else { + dataASN[CERTEXTSASN_IDX_BC_CRIT].noOut = 1; + } if (cert->pathLenSet #ifdef WOLFSSL_CERT_EXT && ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage)) @@ -29197,12 +29215,24 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, else if (cert->isCaSet) { SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CA], 0); SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID)); + if (cert->basicConstCrit) { + SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CRIT], 1); + } + else { + dataASN[CERTEXTSASN_IDX_BC_CRIT].noOut = 1; + } dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1; } #endif else if (cert->basicConstSet) { /* Set Basic Constraints to be a non Certificate Authority. */ SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID)); + if (cert->basicConstCrit) { + SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CRIT], 1); + } + else { + dataASN[CERTEXTSASN_IDX_BC_CRIT].noOut = 1; + } dataASN[CERTEXTSASN_IDX_BC_CA].noOut = 1; dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1; } @@ -29369,9 +29399,16 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, #ifdef WOLFSSL_DUAL_ALG_CERTS if (cert->sapkiDer != NULL) { - /* Set subject alternative public key info OID and data. */ + /* Set subject alternative public key info OID, criticality and + * data. */ SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAPKI_OID], sapkiOID, sizeof(sapkiOID)); + if (cert->sapkiCrit) { + SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_SAPKI_CRIT], 1); + } + else { + dataASN[CERTEXTSASN_IDX_SAPKI_CRIT].noOut = 1; + } SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAPKI_STR], cert->sapkiDer, cert->sapkiLen); } @@ -29382,9 +29419,15 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, } if (cert->altSigAlgDer != NULL) { - /* Set alternative signature algorithm OID and data. */ + /* Set alternative signature algorithm OID, criticality and data. */ SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_ALTSIGALG_OID], altSigAlgOID, sizeof(altSigAlgOID)); + if (cert->altSigAlgCrit) { + SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_ALTSIGALG_CRIT], 1); + } + else { + dataASN[CERTEXTSASN_IDX_ALTSIGALG_CRIT].noOut = 1; + } SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_ALTSIGALG_STR], cert->altSigAlgDer, cert->altSigAlgLen); } @@ -29395,9 +29438,15 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, } if (cert->altSigValDer != NULL) { - /* Set alternative signature value OID and data. */ + /* Set alternative signature value OID, criticality and data. */ SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_ALTSIGVAL_OID], altSigValOID, sizeof(altSigValOID)); + if (cert->altSigValCrit) { + SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_ALTSIGVAL_CRIT], 1); + } + else { + dataASN[CERTEXTSASN_IDX_ALTSIGVAL_CRIT].noOut = 1; + } SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_ALTSIGVAL_STR], cert->altSigValDer, cert->altSigValLen); } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 09f218d33..87275d3df 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -5405,6 +5405,7 @@ struct WOLFSSL_X509 { byte keyUsageCrit:1; byte extKeyUsageCrit:1; byte subjKeyIdSet:1; + byte pathLengthSet:1; byte subjKeyIdCrit:1; byte basicConstSet:1; @@ -5457,6 +5458,10 @@ struct WOLFSSL_X509 { /* Alternative Signature Value */ byte *altSigValDer; int altSigValLen; + + byte sapkiCrit:1; + byte altSigAlgCrit:1; + byte altSigValCrit:1; #endif /* WOLFSSL_DUAL_ALG_CERTS */ }; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 15efecd5a..e5ac2d0af 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -2133,11 +2133,6 @@ struct DecodedCert { #ifdef WOLFSSL_SUBJ_INFO_ACC WC_BITFIELD extSubjInfoAccSet:1; #endif -#ifdef WOLFSSL_DUAL_ALG_CERTS - WC_BITFIELD extSapkiSet:1; - WC_BITFIELD extAltSigAlgSet:1; - WC_BITFIELD extAltSigValSet:1; -#endif /* WOLFSSL_DUAL_ALG_CERTS */ #ifdef WOLFSSL_SEP WC_BITFIELD extCertPolicyCrit:1; #endif @@ -2164,6 +2159,13 @@ struct DecodedCert { /* Alternative Signature Value */ byte *altSigValDer; int altSigValLen; + + WC_BITFIELD extSapkiSet:1; + WC_BITFIELD extAltSigAlgSet:1; + WC_BITFIELD extAltSigValSet:1; + WC_BITFIELD extSapkiCrit:1; + WC_BITFIELD extAltSigAlgCrit:1; + WC_BITFIELD extAltSigValCrit:1; #endif /* WOLFSSL_DUAL_ALG_CERTS */ }; diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index db4f272a8..08d9cc938 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -527,12 +527,15 @@ typedef struct Cert { /* Subject Alternative Public Key Info */ byte *sapkiDer; int sapkiLen; + byte sapkiCrit; /* Alternative Signature Algorithm */ byte *altSigAlgDer; int altSigAlgLen; + byte altSigAlgCrit; /* Alternative Signature Value */ byte *altSigValDer; int altSigValLen; + byte altSigValCrit; #endif /* WOLFSSL_DUAL_ALG_CERTS */ #ifdef WOLFSSL_CERT_REQ char challengePw[CTC_NAME_SIZE]; @@ -551,6 +554,7 @@ typedef struct Cert { byte* der; /* Pointer to buffer of current DecodedCert cache */ void* heap; /* heap hint */ WC_BITFIELD basicConstSet:1; /* Indicator for when Basic Constraint is set */ + byte basicConstCrit; /* Indicator of criticality of Basic Constraints extension */ #ifdef WOLFSSL_ALLOW_ENCODING_CA_FALSE WC_BITFIELD isCaSet:1; /* Indicator for when isCA is set */ #endif