- Timestamp:
- May 19, 2020 7:40:54 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/crypto/x509-certpaths.cpp
r82968 r84379 287 287 /** @name RTCRX509CERTPATHSINT_F_XXX - Certificate path build flags. 288 288 * @{ */ 289 #define RTCRX509CERTPATHSINT_F_VALID_TIME RT_BIT_32(0) 290 #define RTCRX509CERTPATHSINT_F_ELIMINATE_UNTRUSTED_PATHS RT_BIT_32(1) 291 #define RTCRX509CERTPATHSINT_F_VALID_MASK UINT32_C(0x00000003) 289 #define RTCRX509CERTPATHSINT_F_VALID_TIME RT_BIT_32(0) 290 #define RTCRX509CERTPATHSINT_F_ELIMINATE_UNTRUSTED_PATHS RT_BIT_32(1) 291 /** Whether checking the trust anchor signature (if self signed) and 292 * that it is valid at the verification time, also require it to be a CA if not 293 * leaf node. */ 294 #define RTCRX509CERTPATHSINT_F_CHECK_TRUST_ANCHOR RT_BIT_32(2) 295 #define RTCRX509CERTPATHSINT_F_VALID_MASK UINT32_C(0x00000007) 292 296 /** @} */ 293 297 … … 495 499 else 496 500 pThis->fFlags &= ~RTCRX509CERTPATHSINT_F_VALID_TIME; 501 return VINF_SUCCESS; 502 } 503 504 505 RTDECL(int) RTCrX509CertPathsSetTrustAnchorChecks(RTCRX509CERTPATHS hCertPaths, bool fEnable) 506 { 507 PRTCRX509CERTPATHSINT pThis = hCertPaths; 508 AssertPtrReturn(pThis, VERR_INVALID_HANDLE); 509 AssertReturn(pThis->u32Magic == RTCRX509CERTPATHSINT_MAGIC, VERR_INVALID_HANDLE); 510 511 if (fEnable) 512 pThis->fFlags |= RTCRX509CERTPATHSINT_F_CHECK_TRUST_ANCHOR; 513 else 514 pThis->fFlags &= ~RTCRX509CERTPATHSINT_F_CHECK_TRUST_ANCHOR; 497 515 return VINF_SUCCESS; 498 516 } … … 611 629 if ( pTmpNode->pCert == pCert 612 630 || RTCrX509Certificate_Compare(pTmpNode->pCert, pCert) == 0) 631 { 632 /* If target and the source it trusted, upgrade the source so we can successfully verify single node 'paths'. */ 633 if ( RTCRX509CERTPATHNODE_SRC_IS_TRUSTED(uSrc) 634 && pTmpNode == pParent 635 && pTmpNode->uSrc == RTCRX509CERTPATHNODE_SRC_TARGET) 636 { 637 AssertReturnVoid(!pTmpNode->pParent); 638 pTmpNode->uSrc = uSrc; 639 } 613 640 return; 641 } 614 642 pTmpNode = pTmpNode->pParent; 615 643 } … … 1939 1967 1940 1968 1941 1942 1969 /** 1943 1970 * Initializes the state. … … 2014 2041 || pThis->v.pWorkingPublicKeyParameters->enmType == RTASN1TYPE_NULL) 2015 2042 pThis->v.pWorkingPublicKeyParameters = NULL; 2043 } 2044 2045 2046 /** 2047 * This does basic trust anchor checks (similar to 6.1.3.a) before starting on 2048 * the RFC-5280 algorithm. 2049 */ 2050 static bool rtCrX509CpvMaybeCheckTrustAnchor(PRTCRX509CERTPATHSINT pThis, PRTCRX509CERTPATHNODE pTrustAnchor) 2051 { 2052 /* 2053 * This is optional (not part of RFC-5280) and we need a full certificate 2054 * structure to do it. 2055 */ 2056 if (!(pThis->fFlags & RTCRX509CERTPATHSINT_F_CHECK_TRUST_ANCHOR)) 2057 return true; 2058 2059 PCRTCRX509CERTIFICATE const pCert = pTrustAnchor->pCert; 2060 if (!pCert) 2061 return true; 2062 2063 /* 2064 * Verify the certificate signature if self-signed. 2065 */ 2066 if (RTCrX509Certificate_IsSelfSigned(pCert)) 2067 { 2068 int rc = RTCrX509Certificate_VerifySignature(pCert, pThis->v.pWorkingPublicKeyAlgorithm, 2069 pThis->v.pWorkingPublicKeyParameters, pThis->v.pWorkingPublicKey, 2070 pThis->pErrInfo); 2071 if (RT_FAILURE(rc)) 2072 { 2073 pThis->rc = rc; 2074 return false; 2075 } 2076 } 2077 2078 /* 2079 * Verify that the certificate is valid at the specified time. 2080 */ 2081 AssertCompile(sizeof(pThis->szTmp) >= 36 * 3); 2082 if ( (pThis->fFlags & RTCRX509CERTPATHSINT_F_VALID_TIME) 2083 && !RTCrX509Validity_IsValidAtTimeSpec(&pCert->TbsCertificate.Validity, &pThis->ValidTime)) 2084 return rtCrX509CpvFailed(pThis, VERR_CR_X509_CPV_NOT_VALID_AT_TIME, 2085 "Certificate is not valid (ValidTime=%s Validity=[%s...%s])", 2086 RTTimeSpecToString(&pThis->ValidTime, &pThis->szTmp[0], 36), 2087 RTTimeToString(&pCert->TbsCertificate.Validity.NotBefore.Time, &pThis->szTmp[36], 36), 2088 RTTimeToString(&pCert->TbsCertificate.Validity.NotAfter.Time, &pThis->szTmp[2*36], 36) ); 2089 2090 /* 2091 * Verified that the certficiate is not revoked. 2092 */ 2093 /** @todo rainy day. */ 2094 2095 /* 2096 * If non-leaf certificate CA must be set, if basic constraints are present. 2097 */ 2098 if (pTrustAnchor->pParent) 2099 { 2100 if (RTAsn1Integer_UnsignedCompareWithU32(&pTrustAnchor->pCert->TbsCertificate.T0.Version, RTCRX509TBSCERTIFICATE_V3) != 0) 2101 return rtCrX509CpvFailed(pThis, VERR_CR_X509_CPV_NOT_V3_CERT, 2102 "Only version 3 TA certificates are supported (Version=%llu)", 2103 pTrustAnchor->pCert->TbsCertificate.T0.Version.uValue); 2104 PCRTCRX509BASICCONSTRAINTS pBasicConstraints = pTrustAnchor->pCert->TbsCertificate.T3.pBasicConstraints; 2105 if (pBasicConstraints && !pBasicConstraints->CA.fValue) 2106 return rtCrX509CpvFailed(pThis, VERR_CR_X509_CPV_NOT_CA_CERT, 2107 "Trust anchor certificate is not marked as a CA"); 2108 } 2109 2110 return true; 2016 2111 } 2017 2112 … … 2533 2628 { 2534 2629 /* 2535 * Special case, target certificate is trusted. 2536 */ 2537 if (!pTrustAnchor->pParent) 2538 return rtCrX509CpvFailed(pThis, VERR_CR_X509_CERTPATHS_INTERNAL_ERROR, "Target certificate is trusted."); 2539 2540 /* 2541 * Normal processing. 2630 * Init. 2542 2631 */ 2543 2632 rtCrX509CpvInit(pThis, pTrustAnchor); 2544 2633 if (RT_SUCCESS(pThis->rc)) 2545 2634 { 2635 /* 2636 * Maybe do some trust anchor checks. 2637 */ 2638 if (!rtCrX509CpvMaybeCheckTrustAnchor(pThis, pTrustAnchor)) 2639 { 2640 AssertStmt(RT_FAILURE_NP(pThis->rc), pThis->rc = VERR_CR_X509_CERTPATHS_INTERNAL_ERROR); 2641 return false; 2642 } 2643 2644 /* 2645 * Special case, target certificate is trusted. 2646 */ 2647 if (!pTrustAnchor->pParent) 2648 return true; /* rtCrX509CpvWrapUp should not be needed here. */ 2649 2650 /* 2651 * Normal processing. 2652 */ 2546 2653 PRTCRX509CERTPATHNODE pNode = pTrustAnchor->pParent; 2547 2654 uint32_t iNode = pThis->v.iNode = 1; /* We count to cNode (inclusive). Same a validation tree depth. */
Note:
See TracChangeset
for help on using the changeset viewer.