diff --git a/certs/test/cert-ext-ia.cfg b/certs/test/cert-ext-ia.cfg index 8721916b3..44be1126a 100644 --- a/certs/test/cert-ext-ia.cfg +++ b/certs/test/cert-ext-ia.cfg @@ -10,7 +10,7 @@ L = Brisbane O = wolfSSL Inc OU = Engineering CN = www.wolfssl.com -emailAddress = support@www.wolfsssl.com +emailAddress = support@wolfsssl.com [ v3_ca ] inhibitAnyPolicy = critical,1 diff --git a/certs/test/cert-ext-ia.der b/certs/test/cert-ext-ia.der index 73ea7c0a8..1099fa986 100644 Binary files a/certs/test/cert-ext-ia.der and b/certs/test/cert-ext-ia.der differ diff --git a/certs/test/cert-ext-nc.cfg b/certs/test/cert-ext-nc.cfg index b27f3f4fe..9e8ff6be5 100644 --- a/certs/test/cert-ext-nc.cfg +++ b/certs/test/cert-ext-nc.cfg @@ -10,9 +10,13 @@ L = Brisbane O = wolfSSL Inc OU = Engineering CN = www.wolfssl.com -emailAddress = support@www.wolfsssl.com +emailAddress = support@wolfsssl.com [ v3_ca ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, digitalSignature, cRLSign, keyCertSign nameConstraints = critical,permitted;email:.wolfssl.com nsComment = "Testing name constraints" diff --git a/certs/test/cert-ext-nc.der b/certs/test/cert-ext-nc.der index ff944476d..ffb2c1338 100644 Binary files a/certs/test/cert-ext-nc.der and b/certs/test/cert-ext-nc.der differ diff --git a/certs/test/gen-ext-certs.sh b/certs/test/gen-ext-certs.sh old mode 100644 new mode 100755 index 20b61e9c9..1d5d9b784 --- a/certs/test/gen-ext-certs.sh +++ b/certs/test/gen-ext-certs.sh @@ -33,9 +33,13 @@ L = Brisbane O = wolfSSL Inc OU = Engineering CN = www.wolfssl.com -emailAddress = support@www.wolfsssl.com +emailAddress = support@wolfsssl.com [ v3_ca ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer +basicConstraints = critical, CA:true, pathlen:0 +keyUsage = critical, digitalSignature, cRLSign, keyCertSign nameConstraints = critical,permitted;email:.wolfssl.com nsComment = "Testing name constraints" @@ -58,7 +62,7 @@ L = Brisbane O = wolfSSL Inc OU = Engineering CN = www.wolfssl.com -emailAddress = support@www.wolfsssl.com +emailAddress = support@wolfsssl.com [ v3_ca ] inhibitAnyPolicy = critical,1 diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c old mode 100644 new mode 100755 index f5870169a..85cc90a4d --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -34,6 +34,8 @@ ASN Options: * ASN_DUMP_OID: Allows dump of OID information for debugging. * RSA_DECODE_EXTRA: Decodes extra information in RSA public key. * WOLFSSL_CERT_GEN: Cert generation. Saves extra certificate info in GetName. + * WOLFSSL_NO_ASN_STRICT: Disable strict RFC compliance checks to + restore 3.13.0 behavior. * WOLFSSL_NO_OCSP_OPTIONAL_CERTS: Skip optional OCSP certs (responder issuer must still be trusted) * WOLFSSL_NO_TRUSTED_CERTS_VERIFY: Workaround for situation where entire cert @@ -48,11 +50,6 @@ ASN Options: #ifndef NO_ASN -#ifdef HAVE_RTP_SYS - #include "os.h" /* dc_rtc_api needs */ - #include "dc_rtc_api.h" /* to get current time */ -#endif - #include #include #include @@ -5436,6 +5433,16 @@ static int DecodeAltNames(byte* input, int sz, DecodedCert* cert) } length -= (idx - lenStartIdx); + #ifndef WOLFSSL_NO_ASN_STRICT + /* Verify RFC 5280 Sec 4.2.1.6 rule: + "The name MUST NOT be a relative URI" */ + + if (XSTRNCMP((const char*)&input[idx], "://", strLen + 1) != 0) { + WOLFSSL_MSG("\tAlt Name must be absolute URI"); + return ASN_ALT_NAME_E; + } + #endif + uriEntry = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap, DYNAMIC_TYPE_ALTNAME); if (uriEntry == NULL) { @@ -6168,13 +6175,27 @@ int DecodePolicyOID(char *out, word32 outSz, byte *in, word32 inSz) } #endif /* WOLFSSL_SEP */ +/* Macro to check if bit is set, if not sets and return success. + Otherwise returns failure */ +/* Macro required here because bit-field operation */ +#ifndef WOLFSSL_NO_ASN_STRICT + #define VERIFY_AND_SET_OID(bit) \ + if (bit == 0) \ + bit = 1; \ + else \ + return ASN_OBJECT_ID_E; +#else + /* With no strict defined, the verify is skipped */ +#define VERIFY_AND_SET_OID(bit) bit = 1; +#endif + static int DecodeCertExtensions(DecodedCert* cert) /* * Processing the Certificate Extensions. This does not modify the current * index. It is works starting with the recorded extensions pointer. */ { - int ret; + int ret = 0; word32 idx = 0; int sz = cert->extensionsSz; byte* input = cert->extensions; @@ -6236,8 +6257,8 @@ static int DecodeCertExtensions(DecodedCert* cert) switch (oid) { case BASIC_CA_OID: + VERIFY_AND_SET_OID(cert->extBasicConstSet); #ifdef OPENSSL_EXTRA - cert->extBasicConstSet = 1; cert->extBasicConstCrit = critical; #endif if (DecodeBasicCaConstraint(&input[idx], length, cert) < 0) @@ -6245,8 +6266,8 @@ static int DecodeCertExtensions(DecodedCert* cert) break; case CRL_DIST_OID: + VERIFY_AND_SET_OID(cert->extCRLdistSet); #ifdef OPENSSL_EXTRA - cert->extCRLdistSet = 1; cert->extCRLdistCrit = critical; #endif if (DecodeCrlDist(&input[idx], length, cert) < 0) @@ -6254,8 +6275,8 @@ static int DecodeCertExtensions(DecodedCert* cert) break; case AUTH_INFO_OID: + VERIFY_AND_SET_OID(cert->extAuthInfoSet); #ifdef OPENSSL_EXTRA - cert->extAuthInfoSet = 1; cert->extAuthInfoCrit = critical; #endif if (DecodeAuthInfo(&input[idx], length, cert) < 0) @@ -6263,16 +6284,17 @@ static int DecodeCertExtensions(DecodedCert* cert) break; case ALT_NAMES_OID: + VERIFY_AND_SET_OID(cert->extSubjAltNameSet); #ifdef OPENSSL_EXTRA - cert->extSubjAltNameSet = 1; cert->extSubjAltNameCrit = critical; #endif - if (DecodeAltNames(&input[idx], length, cert) < 0) - return ASN_PARSE_E; + ret = DecodeAltNames(&input[idx], length, cert); + if (ret < 0) + return ret; break; case AUTH_KEY_OID: - cert->extAuthKeyIdSet = 1; + VERIFY_AND_SET_OID(cert->extAuthKeyIdSet); #ifdef OPENSSL_EXTRA cert->extAuthKeyIdCrit = critical; #endif @@ -6281,7 +6303,7 @@ static int DecodeCertExtensions(DecodedCert* cert) break; case SUBJ_KEY_OID: - cert->extSubjKeyIdSet = 1; + VERIFY_AND_SET_OID(cert->extSubjKeyIdSet); #ifdef OPENSSL_EXTRA cert->extSubjKeyIdCrit = critical; #endif @@ -6303,8 +6325,8 @@ static int DecodeCertExtensions(DecodedCert* cert) case CERT_POLICY_OID: #ifdef WOLFSSL_SEP + VERIFY_AND_SET_OID(cert->extCertPolicySet); #ifdef OPENSSL_EXTRA - cert->extCertPolicySet = 1; cert->extCertPolicyCrit = critical; #endif #endif @@ -6318,7 +6340,7 @@ static int DecodeCertExtensions(DecodedCert* cert) break; case KEY_USAGE_OID: - cert->extKeyUsageSet = 1; + VERIFY_AND_SET_OID(cert->extKeyUsageSet); #ifdef OPENSSL_EXTRA cert->extKeyUsageCrit = critical; #endif @@ -6327,7 +6349,7 @@ static int DecodeCertExtensions(DecodedCert* cert) break; case EXT_KEY_USAGE_OID: - cert->extExtKeyUsageSet = 1; + VERIFY_AND_SET_OID(cert->extExtKeyUsageSet); #ifdef OPENSSL_EXTRA cert->extExtKeyUsageCrit = critical; #endif @@ -6337,7 +6359,16 @@ static int DecodeCertExtensions(DecodedCert* cert) #ifndef IGNORE_NAME_CONSTRAINTS case NAME_CONS_OID: - cert->extNameConstraintSet = 1; + #ifndef WOLFSSL_NO_ASN_STRICT + /* Verify RFC 5280 Sec 4.2.1.10 rule: + "The name constraints extension, + which MUST be used only in a CA certificate" */ + if (!cert->isCA) { + WOLFSSL_MSG("Name constraints allowed only for CA certs"); + return ASN_NAME_INVALID_E; + } + #endif + VERIFY_AND_SET_OID(cert->extNameConstraintSet); #ifdef OPENSSL_EXTRA cert->extNameConstraintCrit = critical; #endif @@ -6347,6 +6378,7 @@ static int DecodeCertExtensions(DecodedCert* cert) #endif /* IGNORE_NAME_CONSTRAINTS */ case INHIBIT_ANY_OID: + VERIFY_AND_SET_OID(cert->inhibitAnyOidSet); WOLFSSL_MSG("Inhibit anyPolicy extension not supported yet."); break; diff --git a/wolfcrypt/src/error.c b/wolfcrypt/src/error.c index add4f6458..7b52791c9 100644 --- a/wolfcrypt/src/error.c +++ b/wolfcrypt/src/error.c @@ -206,6 +206,9 @@ const char* wc_GetErrorString(int error) case ASN_CRIT_EXT_E: return "X.509 Critical extension ignored or invalid"; + case ASN_ALT_NAME_E: + return "ASN alternate name error"; + case ECC_BAD_ARG_E : return "ECC input argument wrong type, invalid input"; diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index c9bf6d87b..acbd675db 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -38,11 +38,11 @@ /* IPP header files for library initialization */ #ifdef HAVE_FAST_RSA -#include -#include + #include + #include #endif -#if defined(FREESCALE_LTC_TFM) +#ifdef FREESCALE_LTC_TFM #include #endif diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index f61f456f4..59daa1dc1 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -1034,7 +1034,7 @@ int error_test(void) int j = 0; /* Values that are not or no longer error codes. */ int missing[] = { -122, -123, -124, -127, -128, -129, - -161, -162, -163, -164, -165, -166, -167, -168, -169, + -162, -163, -164, -165, -166, -167, -168, -169, -179, -233, 0 }; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 7496c463b..1b3017221 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -549,7 +549,6 @@ struct DecodedCert { char* subjectCN; /* CommonName */ int subjectCNLen; /* CommonName Length */ char subjectCNEnc; /* CommonName Encoding */ - int subjectCNStored; /* have we saved a copy we own */ char issuer[ASN_NAME_MAX]; /* full name including common name */ char subject[ASN_NAME_MAX]; /* full name including common name */ int verify; /* Default to yes, but could be off */ @@ -567,36 +566,12 @@ struct DecodedCert { byte* extCrlInfo; /* CRL Distribution Points */ int extCrlInfoSz; /* length of the URI */ byte extSubjKeyId[KEYID_SIZE]; /* Subject Key ID */ - byte extSubjKeyIdSet; /* Set when the SKID was read from cert */ byte extAuthKeyId[KEYID_SIZE]; /* Authority Key ID */ - byte extAuthKeyIdSet; /* Set when the AKID was read from cert */ -#ifndef IGNORE_NAME_CONSTRAINTS - byte extNameConstraintSet; -#endif /* IGNORE_NAME_CONSTRAINTS */ - byte isCA; /* CA basic constraint true */ - byte pathLengthSet; /* CA basic const path length set */ byte pathLength; /* CA basic constraint path length */ - byte weOwnAltNames; /* altNames haven't been given to copy */ - byte extKeyUsageSet; word16 extKeyUsage; /* Key usage bitfield */ - byte extExtKeyUsageSet; /* Extended Key Usage */ byte extExtKeyUsage; /* Extended Key usage bitfield */ + #ifdef OPENSSL_EXTRA - byte extCRLdistSet; - byte extCRLdistCrit; - byte extAuthInfoSet; - byte extAuthInfoCrit; - byte extBasicConstSet; - byte extBasicConstCrit; - byte extSubjAltNameSet; - byte extSubjAltNameCrit; - byte extAuthKeyIdCrit; -#ifndef IGNORE_NAME_CONSTRAINTS - byte extNameConstraintCrit; -#endif /* IGNORE_NAME_CONSTRAINTS */ - byte extSubjKeyIdCrit; - byte extKeyUsageCrit; - byte extExtKeyUsageCrit; byte* extExtKeyUsageSrc; word32 extExtKeyUsageSz; word32 extExtKeyUsageCount; @@ -605,6 +580,7 @@ struct DecodedCert { byte* extSubjKeyIdSrc; word32 extSubjKeyIdSz; #endif + #if defined(HAVE_ECC) || defined(HAVE_ED25519) word32 pkCurveOID; /* Public Key's curve OID */ #endif /* HAVE_ECC */ @@ -620,7 +596,7 @@ struct DecodedCert { byte* subjectRaw; /* pointer to subject inside source */ int subjectRawLen; #endif -#if defined(WOLFSSL_CERT_GEN) +#ifdef WOLFSSL_CERT_GEN /* easy access to subject info for other sign */ char* subjectSN; int subjectSNLen; @@ -654,10 +630,6 @@ struct DecodedCert { byte* hwType; int hwSerialNumSz; byte* hwSerialNum; - #ifdef OPENSSL_EXTRA - byte extCertPolicySet; - byte extCertPolicyCrit; - #endif /* OPENSSL_EXTRA */ #endif /* WOLFSSL_SEP */ #ifdef WOLFSSL_CERT_EXT char extCertPolicies[MAX_CERTPOL_NB][MAX_CERTPOL_SZ]; @@ -666,6 +638,44 @@ struct DecodedCert { Signer* ca; SignatureCtx sigCtx; + + /* Option Bits */ + byte subjectCNStored : 1; /* have we saved a copy we own */ + byte extSubjKeyIdSet : 1; /* Set when the SKID was read from cert */ + byte extAuthKeyIdSet : 1; /* Set when the AKID was read from cert */ +#ifndef IGNORE_NAME_CONSTRAINTS + byte extNameConstraintSet : 1; +#endif + byte isCA : 1; /* CA basic constraint true */ + byte pathLengthSet : 1; /* CA basic const path length set */ + byte weOwnAltNames : 1; /* altNames haven't been given to copy */ + byte extKeyUsageSet : 1; + byte extExtKeyUsageSet : 1; /* Extended Key Usage set */ + byte extCRLdistSet : 1; + byte extAuthInfoSet : 1; + byte extBasicConstSet : 1; + byte extSubjAltNameSet : 1; + byte inhibitAnyOidSet : 1; +#ifdef WOLFSSL_SEP + byte extCertPolicySet : 1; +#endif +#ifdef OPENSSL_EXTRA + byte extCRLdistCrit : 1; + byte extAuthInfoCrit : 1; + byte extBasicConstCrit : 1; + byte extSubjAltNameCrit : 1; + byte extAuthKeyIdCrit : 1; + #ifndef IGNORE_NAME_CONSTRAINTS + byte extNameConstraintCrit : 1; + #endif + byte extSubjKeyIdCrit : 1; + byte extKeyUsageCrit : 1; + byte extExtKeyUsageCrit : 1; +#endif /* OPENSSL_EXTRA */ +#ifdef WOLFSSL_SEP + byte extCertPolicyCrit : 1; +#endif + }; diff --git a/wolfssl/wolfcrypt/error-crypt.h b/wolfssl/wolfcrypt/error-crypt.h index 9ca0c1a2b..c047dfec9 100644 --- a/wolfssl/wolfcrypt/error-crypt.h +++ b/wolfssl/wolfcrypt/error-crypt.h @@ -97,6 +97,7 @@ enum { ASN_DH_KEY_E = -158, /* ASN key init error, invalid input */ ASN_NTRU_KEY_E = -159, /* ASN ntru key decode error, invalid input */ ASN_CRIT_EXT_E = -160, /* ASN unsupported critical extension */ + ASN_ALT_NAME_E = -161, /* ASN alternate name error */ ECC_BAD_ARG_E = -170, /* ECC input argument of wrong type */ ASN_ECC_KEY_E = -171, /* ASN ECC bad input */ diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 2445f91c3..4924517be 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -357,6 +357,9 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #define NEED_TMP_TIME #elif defined(HAVE_RTP_SYS) + #include "os.h" /* dc_rtc_api needs */ + #include "dc_rtc_api.h" /* to get current time */ + /* uses parital structures */ #define XTIME(tl) (0) #define XGMTIME(c, t) rtpsys_gmtime((c))