diff --git a/mozilla/security/nss/lib/libpkix/include/pkix_pl_pki.h b/mozilla/security/nss/lib/libpkix/include/pkix_pl_pki.h index 8da25b88d58..1157916f5f0 100755 --- a/mozilla/security/nss/lib/libpkix/include/pkix_pl_pki.h +++ b/mozilla/security/nss/lib/libpkix/include/pkix_pl_pki.h @@ -1488,6 +1488,32 @@ PKIX_PL_Cert_VerifySignature( PKIX_PL_PublicKey *pubKey, void *plContext); +/* A set of flags to indicate how explicitly configured trust anchors should be + * handled by PKIX_PL_Cert_IsCertTrusted + */ +typedef enum PKIX_PL_TrustAnchorModeEnum { + /* Indicates trust anchors should be ignored; only the underlying + * platform's trust settings should be used. + */ + PKIX_PL_TrustAnchorMode_Ignore, + + /* Indicates that explicitly configured trust anchors may be considered + * trustworthy, if present. + * Note: If the underlying platform supports marking a certificate as + * explicitly untrustworthy, explicitly configured trust anchors + * MAY be ignored/rejected. + */ + PKIX_PL_TrustAnchorMode_Additive, + + /* Indicates that ONLY trust anchors should be considered as + * trustworthy. + * Note: If the underlying platform supports marking a certificate as + * explicitly untrustworthy, explicitly configured trust anchors + * MAY be ignored/rejected. + */ + PKIX_PL_TrustAnchorMode_Exclusive, +} PKIX_PL_TrustAnchorMode; + /* * FUNCTION: PKIX_PL_Cert_IsCertTrusted * DESCRIPTION: @@ -1509,8 +1535,9 @@ PKIX_PL_Cert_VerifySignature( * "cert" * Address of Cert whose trustworthiness is to be determined. Must be * non-NULL. - * "trustOnlyUserAnchors" - * States that we can only trust explicitly defined user trust anchors. + * "trustAnchorMode" + * A PKIX_PL_TrustAnchorMode that indicates how explicitly defined user + * trust anchors should be handled. * "pTrusted" * Address where the Boolean value will be stored. Must be non-NULL. * "plContext" @@ -1525,7 +1552,7 @@ PKIX_PL_Cert_VerifySignature( PKIX_Error * PKIX_PL_Cert_IsCertTrusted( PKIX_PL_Cert *cert, - PKIX_Boolean trustOnlyUserAnchors, + PKIX_PL_TrustAnchorMode trustAnchorMode, PKIX_Boolean *pTrusted, void *plContext); diff --git a/mozilla/security/nss/lib/libpkix/pkix/top/pkix_build.c b/mozilla/security/nss/lib/libpkix/pkix/top/pkix_build.c index 574fcfbbfc9..71fa2e984bc 100755 --- a/mozilla/security/nss/lib/libpkix/pkix/top/pkix_build.c +++ b/mozilla/security/nss/lib/libpkix/pkix/top/pkix_build.c @@ -836,7 +836,8 @@ pkix_Build_VerifyCertificate( PKIX_PL_PublicKey *candidatePubKey = NULL; PKIX_CertChainChecker *userChecker = NULL; PKIX_CertChainChecker_CheckCallback checkerCheck = NULL; - PKIX_Boolean trustOnlyUserAnchors = PKIX_FALSE; + PKIX_PL_TrustAnchorMode trustAnchorMode = + PKIX_PL_TrustAnchorMode_Ignore; void *nbioContext = NULL; PKIX_ENTER(BUILD, "pkix_Build_VerifyCertificate"); @@ -850,12 +851,17 @@ pkix_Build_VerifyCertificate( candidateCert = state->candidateCert; if (state->buildConstants.numAnchors) { - trustOnlyUserAnchors = state->buildConstants.trustOnlyUserAnchors; + if (state->buildConstants.trustOnlyUserAnchors) { + trustAnchorMode = PKIX_PL_TrustAnchorMode_Exclusive; + } else { + trustAnchorMode = PKIX_PL_TrustAnchorMode_Additive; + } + } else { + trustAnchorMode = PKIX_PL_TrustAnchorMode_Ignore; } PKIX_CHECK( - PKIX_PL_Cert_IsCertTrusted(candidateCert, - trustOnlyUserAnchors, + PKIX_PL_Cert_IsCertTrusted(candidateCert, trustAnchorMode, &trusted, plContext), PKIX_CERTISCERTTRUSTEDFAILED); @@ -3041,19 +3047,27 @@ pkix_Build_CheckInCache( (matchingAnchor, &trustedCert, plContext), PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED); - if (state->buildConstants.anchors && - state->buildConstants.anchors->length) { + if (anchors && state->buildConstants.numAnchors) { /* Check if it is one of the trust anchors */ PKIX_CHECK( - pkix_List_Contains(state->buildConstants.anchors, + pkix_List_Contains(anchors, (PKIX_PL_Object *)matchingAnchor, &trusted, plContext), PKIX_LISTCONTAINSFAILED); - } else { - PKIX_CHECK(PKIX_PL_Cert_IsCertTrusted - (trustedCert, PKIX_FALSE, &trusted, plContext), - PKIX_CERTISCERTTRUSTEDFAILED); + } + + if ((!trusted && !state->buildConstants.trustOnlyUserAnchors) || + !state->buildConstants.numAnchors) { + /* If it is not one of the trust anchors and the trust anchors + * are supplemental, or if there are no trust anchors, then check + * if the cert is trusted directly. + */ + PKIX_CHECK( + PKIX_PL_Cert_IsCertTrusted(trustedCert, + PKIX_PL_TrustAnchorMode_Ignore, + &trusted, plContext), + PKIX_CERTISCERTTRUSTEDFAILED); } if (!trusted) { diff --git a/mozilla/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c b/mozilla/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c index 147e03de2c1..f13c835699e 100644 --- a/mozilla/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c +++ b/mozilla/security/nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c @@ -3294,7 +3294,7 @@ pkix_pl_Cert_GetTrusted(void *plContext, PKIX_Error * PKIX_PL_Cert_IsCertTrusted( PKIX_PL_Cert *cert, - PKIX_Boolean trustOnlyUserAnchors, + PKIX_PL_TrustAnchorMode trustAnchorMode, PKIX_Boolean *pTrusted, void *plContext) { @@ -3315,8 +3315,10 @@ PKIX_PL_Cert_IsCertTrusted( PKIX_ERROR(PKIX_CERTISCERTTRUSTEDFAILED); } - if (trustOnlyUserAnchors || cert->isUserTrustAnchor) { - /* discard our |trusted| value since we are using the anchors */ + if (trustAnchorMode == PKIX_PL_TrustAnchorMode_Exclusive || + (trustAnchorMode == PKIX_PL_TrustAnchorMode_Additive && + cert->isUserTrustAnchor)) { + /* Use the trust anchor's |trusted| value */ *pTrusted = cert->isUserTrustAnchor; goto cleanup; }