Changeset 52537 in vbox
- Timestamp:
- Aug 31, 2014 7:28:17 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/asn1.h
r52533 r52537 1252 1252 typedef enum RTASN1TYPE 1253 1253 { 1254 /** Invalid zero value. */1255 RTASN1TYPE_INVALID = 0,1256 1254 /** Not present. */ 1257 RTASN1TYPE_NOT_PRESENT ,1255 RTASN1TYPE_NOT_PRESENT = 0, 1258 1256 /** Generic ASN.1 for unknown tag/class. */ 1259 1257 RTASN1TYPE_CORE, -
trunk/include/iprt/crypto/pkcs7.h
r52503 r52537 174 174 #define RTCR_PKCS9_ID_COUNTER_SIGNATURE_OID "1.2.840.113549.1.9.6" 175 175 /** @} */ 176 177 /** 178 * Get the (next) signing time attribute from the specfied SignerInfo or one of 179 * the immediate counter signatures. 180 * 181 * @returns Pointer to the signing time if found, NULL if not. 182 * @param pThis The SignerInfo to search. 183 * @param ppSignerInfo Pointer to variable keeping track of the 184 * enumeration, optional. 185 * 186 * If specified the input value is taken to the be 187 * SignerInfo of the previously returned signing 188 * time. The value pointed to is NULL, the 189 * search/enum restarts. 190 * 191 * On successful return this is set to the 192 * SignerInfo which we found the signing time in. 193 */ 194 RTDECL(PCRTASN1TIME) RTCrPkcs7SignerInfo_GetSigningTime(PCRTCRPKCS7SIGNERINFO pThis, PCRTCRPKCS7SIGNERINFO *ppSignerInfo); 195 176 196 177 197 … … 302 322 * This is NIL_RTCRX509CERTPATHS if the certificate 303 323 * is directly trusted. 324 * @param fFlags Mix of the RTCRPKCS7VCC_F_XXX flags. 304 325 * @param pvUser The user argument. 305 326 * @param pErrInfo Optional error info buffer. 306 327 */ 307 typedef DECLCALLBACK(int) RTCRPKCS7VERIFYCERTCALLBACK(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, 308 void *pvUser, PRTERRINFO pErrInfo); 309 /** Pointer to a RTCRPKCS7VERIFYCERTCALLBACK callback. */ 310 typedef RTCRPKCS7VERIFYCERTCALLBACK *PRTCRPKCS7VERIFYCERTCALLBACK; 328 typedef DECLCALLBACK(int) FNRTCRPKCS7VERIFYCERTCALLBACK(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, 329 uint32_t fFlags, void *pvUser, PRTERRINFO pErrInfo); 330 /** Pointer to a FNRTCRPKCS7VERIFYCERTCALLBACK callback. */ 331 typedef FNRTCRPKCS7VERIFYCERTCALLBACK *PFNRTCRPKCS7VERIFYCERTCALLBACK; 332 333 /** @name RTCRPKCS7VCC_F_XXX - Flags for FNRTCRPKCS7VERIFYCERTCALLBACK. 334 * @{ */ 335 /** Normal callback for a direct signatory of the signed data. */ 336 #define RTCRPKCS7VCC_F_SIGNED_DATA RT_BIT_32(0) 337 /** Check that the signatory can be trusted for timestamps. */ 338 #define RTCRPKCS7VCC_F_TIMESTAMP RT_BIT_32(1) 339 /** @} */ 311 340 312 341 /** … … 314 343 * Default implementation that checks for the DigitalSignature KeyUsage bit.} 315 344 */ 316 RTDECL(int) RTCrPkcs7VerifyCertCallbackDefault(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, 345 RTDECL(int) RTCrPkcs7VerifyCertCallbackDefault(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags, 317 346 void *pvUser, PRTERRINFO pErrInfo); 318 347 … … 321 350 * Standard code signing. Use this for Microsoft SPC.} 322 351 */ 323 RTDECL(int) RTCrPkcs7VerifyCertCallbackCodeSigning(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, 352 RTDECL(int) RTCrPkcs7VerifyCertCallbackCodeSigning(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags, 324 353 void *pvUser, PRTERRINFO pErrInfo); 325 354 … … 337 366 * @param hTrustedCerts Store containing trusted certificates. 338 367 * @param pValidationTime The time we're supposed to validate the 339 * certificates chains at. 368 * certificates chains at. Ignored for signatures 369 * with valid signing time attributes. 340 370 * @param pfnVerifyCert Callback for checking that a certificate used 341 371 * for signing the data is suitable. … … 345 375 RTDECL(int) RTCrPkcs7VerifySignedData(PCRTCRPKCS7CONTENTINFO pContentInfo, uint32_t fFlags, 346 376 RTCRSTORE hAdditionalCerts, RTCRSTORE hTrustedCerts, 347 PCRTTIMESPEC pValidationTime, P RTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, void *pvUser,377 PCRTTIMESPEC pValidationTime, PFNRTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, void *pvUser, 348 378 PRTERRINFO pErrInfo); 349 379 350 380 /** @name RTCRPKCS7VERIFY_SD_F_XXX - Flags for RTCrPkcs7VerifySignedData 351 381 * @{ */ 382 /** Always use the signing time attribute if present, requiring it to be 383 * verified as valid. The default behavior is to ignore unverifiable 384 * signing time attributes and use the @a pValidationTime instead. */ 385 #define RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT RT_BIT_32(0) 386 /** Only use signging time attributes from counter signatures. */ 387 #define RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY RT_BIT_32(1) 388 /** Don't validate the counter signature containing the signing time, just use 389 * it unverified. This is useful if we don't necessarily have the root 390 * certificates for the timestamp server handy, but use with great care. */ 391 #define RTCRPKCS7VERIFY_SD_F_USE_SIGNING_TIME_UNVERIFIED RT_BIT_32(2) 392 /** Indicates internally that we're validating a counter signature and should 393 * use different rules when checking out the authenticated attributes. 394 * @internal */ 395 #define RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE RT_BIT_32(31) 352 396 /** @} */ 353 397 -
trunk/include/iprt/crypto/x509.h
r51856 r52537 801 801 #define RTCRX509CERT_EKU_F_IPSEC_TUNNEL RT_BIT_64(6) 802 802 #define RTCRX509CERT_EKU_F_IPSEC_USER RT_BIT_64(7) 803 #define RTCRX509CERT_EKU_F_TIME _STAMPINGRT_BIT_64(8)803 #define RTCRX509CERT_EKU_F_TIMESTAMPING RT_BIT_64(8) 804 804 #define RTCRX509CERT_EKU_F_OCSP_SIGNING RT_BIT_64(9) 805 805 #define RTCRX509CERT_EKU_F_DVCS RT_BIT_64(10) … … 835 835 #define RTCRX509_ID_KP_IPSEC_TUNNEL_OID "1.3.6.1.5.5.7.3.6" 836 836 #define RTCRX509_ID_KP_IPSEC_USER_OID "1.3.6.1.5.5.7.3.7" 837 #define RTCRX509_ID_KP_TIME _STAMPING_OID"1.3.6.1.5.5.7.3.8"837 #define RTCRX509_ID_KP_TIMESTAMPING_OID "1.3.6.1.5.5.7.3.8" 838 838 #define RTCRX509_ID_KP_OCSP_SIGNING_OID "1.3.6.1.5.5.7.3.9" 839 839 #define RTCRX509_ID_KP_DVCS_OID "1.3.6.1.5.5.7.3.10" … … 876 876 /** @} */ 877 877 878 /** @name Microsoftextended key usage OIDs878 /** @name Apple extended key usage OIDs 879 879 * @{ */ 880 880 #define RTCRX509_APPLE_EKU_APPLE_EXTENDED_KEY_USAGE_OID "1.2.840.113635.100.4" -
trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp
r52529 r52537 874 874 */ 875 875 static DECLCALLBACK(int) supHardNtViCertVerifyCallback(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, 876 void *pvUser, PRTERRINFO pErrInfo)876 uint32_t fFlags, void *pvUser, PRTERRINFO pErrInfo) 877 877 { 878 878 PSUPHNTVIRDR pNtViRdr = (PSUPHNTVIRDR)pvUser; … … 894 894 * Standard code signing capabilites required. 895 895 */ 896 int rc = RTCrPkcs7VerifyCertCallbackCodeSigning(pCert, hCertPaths, NULL, pErrInfo); 897 if (RT_SUCCESS(rc)) 896 int rc = RTCrPkcs7VerifyCertCallbackCodeSigning(pCert, hCertPaths, fFlags, NULL, pErrInfo); 897 if ( RT_SUCCESS(rc) 898 && (fFlags & RTCRPKCS7VCC_F_SIGNED_DATA)) 898 899 { 899 900 /* … … 992 993 993 994 /* 994 * Verify the signature. 995 * Verify the signature. We instruct the verifier to use the signing time 996 * counter signature present when present, falling back on the timestamp 997 * planted by the linker when absent. In ring-0 we don't have all the 998 * necessary timestamp server root certificate info, so we have to allow 999 * using counter signatures unverified there. 995 1000 */ 996 1001 RTTIMESPEC ValidationTime; 997 1002 RTTimeSpecSetSeconds(&ValidationTime, pNtViRdr->uTimestamp); 998 1003 999 return RTCrPkcs7VerifySignedData(pContentInfo, 0, g_hSpcAndNtKernelSuppStore, g_hSpcAndNtKernelRootStore, &ValidationTime, 1000 supHardNtViCertVerifyCallback, pNtViRdr, pErrInfo); 1004 uint32_t fFlags = RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT 1005 | RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY; 1006 #ifdef IN_RING0 1007 fFlags |= RTCRPKCS7VERIFY_SD_F_USE_SIGNING_TIME_UNVERIFIED; 1008 #endif 1009 return RTCrPkcs7VerifySignedData(pContentInfo, fFlags, g_hSpcAndNtKernelSuppStore, g_hSpcAndNtKernelRootStore, 1010 &ValidationTime, supHardNtViCertVerifyCallback, pNtViRdr, pErrInfo); 1001 1011 } 1002 1012 -
trunk/src/VBox/Runtime/common/crypto/pkcs7-core.cpp
r51770 r52537 39 39 40 40 /* 41 * PCKS #7 SignerInfo 42 */ 43 44 RTDECL(PCRTASN1TIME) RTCrPkcs7SignerInfo_GetSigningTime(PCRTCRPKCS7SIGNERINFO pThis, PCRTCRPKCS7SIGNERINFO *ppSignerInfo) 45 { 46 /* 47 * Check the immediate level, unless we're continuing a previous search. 48 * Note! We ASSUME a single signing time attribute, which simplifies the interface. 49 */ 50 uint32_t cAttrsLeft; 51 PCRTCRPKCS7ATTRIBUTE pAttr; 52 if (!ppSignerInfo || *ppSignerInfo == NULL) 53 { 54 cAttrsLeft = pThis->AuthenticatedAttributes.cItems; 55 pAttr = pThis->AuthenticatedAttributes.paItems; 56 while (cAttrsLeft-- > 0) 57 { 58 if ( pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_SIGNING_TIME 59 && pAttr->uValues.pSigningTime->cItems > 0) 60 { 61 if (ppSignerInfo) 62 *ppSignerInfo = pThis; 63 return &pAttr->uValues.pSigningTime->paItems[0]; 64 } 65 pAttr++; 66 } 67 } 68 else if (*ppSignerInfo == pThis) 69 *ppSignerInfo = NULL; 70 71 /* 72 * Check counter signatures. 73 */ 74 cAttrsLeft = pThis->UnauthenticatedAttributes.cItems; 75 pAttr = pThis->UnauthenticatedAttributes.paItems; 76 while (cAttrsLeft-- > 0) 77 { 78 if (pAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_COUNTER_SIGNATURES) 79 { 80 uint32_t cSignatures = pAttr->uValues.pCounterSignatures->cItems; 81 PCRTCRPKCS7SIGNERINFO pSignature = pAttr->uValues.pCounterSignatures->paItems; 82 83 /* Skip past the previous counter signature. */ 84 if (ppSignerInfo && *ppSignerInfo != NULL) 85 while (cSignatures > 0) 86 { 87 cSignatures--; 88 if (pSignature == *ppSignerInfo) 89 { 90 *ppSignerInfo = NULL; 91 pSignature++; 92 break; 93 } 94 pSignature++; 95 } 96 97 /* Search the counter signatures (if any remaining). */ 98 while (cSignatures-- > 0) 99 { 100 uint32_t cCounterAttrsLeft = pSignature->AuthenticatedAttributes.cItems; 101 PCRTCRPKCS7ATTRIBUTE pCounterAttr = pSignature->AuthenticatedAttributes.paItems; 102 while (cCounterAttrsLeft-- > 0) 103 { 104 if ( pCounterAttr->enmType == RTCRPKCS7ATTRIBUTETYPE_SIGNING_TIME 105 && pCounterAttr->uValues.pSigningTime->cItems > 0) 106 { 107 if (ppSignerInfo) 108 *ppSignerInfo = pSignature; 109 return &pCounterAttr->uValues.pSigningTime->paItems[0]; 110 } 111 pCounterAttr++; 112 } 113 pSignature++; 114 } 115 } 116 pAttr++; 117 } 118 119 /* 120 * No signing timestamp found. 121 */ 122 if (ppSignerInfo) 123 *ppSignerInfo = NULL; 124 125 return NULL; 126 } 127 128 129 /* 41 130 * PCKS #7 ContentInfo. 42 131 */ -
trunk/src/VBox/Runtime/common/crypto/pkcs7-verify.cpp
r51776 r52537 117 117 118 118 119 /** 120 * @callback_method_impl{RTCRPKCS7VERIFYCERTCALLBACK, 121 * Default implementation that checks for the DigitalSignature KeyUsage bit.} 122 */ 123 RTDECL(int) RTCrPkcs7VerifyCertCallbackDefault(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, 124 void *pvUser, PRTERRINFO pErrInfo) 125 { 126 /* 127 * Check for the digital signature key usage. 128 */ 119 120 static int rtCrPkcs7VerifyCertUsageTimstamping(PCRTCRX509CERTIFICATE pCert, PRTERRINFO pErrInfo) 121 { 122 if (!(pCert->TbsCertificate.T3.fFlags & RTCRX509TBSCERTIFICATE_F_PRESENT_EXT_KEY_USAGE)) 123 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_KEY_USAGE_MISMATCH, "No extended key usage certificate attribute."); 124 if (!(pCert->TbsCertificate.T3.fExtKeyUsage & (RTCRX509CERT_EKU_F_TIMESTAMPING | RTCRX509CERT_EKU_F_MS_TIMESTAMP_SIGNING))) 125 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_KEY_USAGE_MISMATCH, "fExtKeyUsage=%#x, missing %#x (time stamping)", 126 pCert->TbsCertificate.T3.fExtKeyUsage, 127 RTCRX509CERT_EKU_F_TIMESTAMPING | RTCRX509CERT_EKU_F_MS_TIMESTAMP_SIGNING); 128 return VINF_SUCCESS; 129 } 130 131 132 static int rtCrPkcs7VerifyCertUsageDigitalSignature(PCRTCRX509CERTIFICATE pCert, PRTERRINFO pErrInfo) 133 { 129 134 if ( (pCert->TbsCertificate.T3.fFlags & RTCRX509TBSCERTIFICATE_F_PRESENT_KEY_USAGE) 130 135 && !(pCert->TbsCertificate.T3.fKeyUsage & RTCRX509CERT_KEY_USAGE_F_DIGITAL_SIGNATURE)) … … 137 142 /** 138 143 * @callback_method_impl{RTCRPKCS7VERIFYCERTCALLBACK, 144 * Default implementation that checks for the DigitalSignature KeyUsage bit.} 145 */ 146 RTDECL(int) RTCrPkcs7VerifyCertCallbackDefault(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags, 147 void *pvUser, PRTERRINFO pErrInfo) 148 { 149 int rc = VINF_SUCCESS; 150 151 if (fFlags & RTCRPKCS7VCC_F_SIGNED_DATA) 152 rc = rtCrPkcs7VerifyCertUsageDigitalSignature(pCert, pErrInfo); 153 154 if ( (fFlags & RTCRPKCS7VCC_F_TIMESTAMP) 155 && RT_SUCCESS(rc)) 156 rc = rtCrPkcs7VerifyCertUsageTimstamping(pCert, pErrInfo); 157 158 return rc; 159 } 160 161 162 /** 163 * @callback_method_impl{RTCRPKCS7VERIFYCERTCALLBACK, 139 164 * Standard code signing. Use this for Microsoft SPC.} 140 165 */ 141 RTDECL(int) RTCrPkcs7VerifyCertCallbackCodeSigning(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, 166 RTDECL(int) RTCrPkcs7VerifyCertCallbackCodeSigning(PCRTCRX509CERTIFICATE pCert, RTCRX509CERTPATHS hCertPaths, uint32_t fFlags, 142 167 void *pvUser, PRTERRINFO pErrInfo) 143 168 { 144 /* 145 * Check for the digital signature key usage. Not required to be present. 146 */ 147 if (pCert->TbsCertificate.T3.fFlags & RTCRX509TBSCERTIFICATE_F_PRESENT_KEY_USAGE) 148 { 149 if (!(pCert->TbsCertificate.T3.fKeyUsage & RTCRX509CERT_KEY_USAGE_F_DIGITAL_SIGNATURE)) 150 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_KEY_USAGE_MISMATCH, "fKeyUsage=%#x, missing %#x", 151 pCert->TbsCertificate.T3.fKeyUsage, RTCRX509CERT_KEY_USAGE_F_DIGITAL_SIGNATURE); 152 } 153 154 /* 155 * Check the extended key usage bits if present. 156 */ 157 if (!(pCert->TbsCertificate.T3.fFlags & RTCRX509TBSCERTIFICATE_F_PRESENT_EXT_KEY_USAGE)) 158 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_KEY_USAGE_MISMATCH, "No extended key usage certificate attribute."); 159 if (!(pCert->TbsCertificate.T3.fExtKeyUsage & RTCRX509CERT_EKU_F_CODE_SIGNING)) 160 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_KEY_USAGE_MISMATCH, "fExtKeyUsage=%#x, missing %#x", 161 pCert->TbsCertificate.T3.fExtKeyUsage, RTCRX509CERT_EKU_F_CODE_SIGNING); 162 return VINF_SUCCESS; 169 int rc = VINF_SUCCESS; 170 if (fFlags & RTCRPKCS7VCC_F_SIGNED_DATA) 171 { 172 /* 173 * If KeyUsage is present it must include digital signature. 174 */ 175 rc = rtCrPkcs7VerifyCertUsageDigitalSignature(pCert, pErrInfo); 176 if (RT_SUCCESS(rc)) 177 { 178 /* 179 * The extended usage 'code signing' must be present. 180 */ 181 if (!(pCert->TbsCertificate.T3.fFlags & RTCRX509TBSCERTIFICATE_F_PRESENT_EXT_KEY_USAGE)) 182 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_KEY_USAGE_MISMATCH, "No extended key usage certificate attribute."); 183 if (!(pCert->TbsCertificate.T3.fExtKeyUsage & RTCRX509CERT_EKU_F_CODE_SIGNING)) 184 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_KEY_USAGE_MISMATCH, "fExtKeyUsage=%#x, missing %#x", 185 pCert->TbsCertificate.T3.fExtKeyUsage, RTCRX509CERT_EKU_F_CODE_SIGNING); 186 } 187 } 188 189 /* 190 * Timestamping too? 191 */ 192 if ( (fFlags & RTCRPKCS7VCC_F_TIMESTAMP) 193 && RT_SUCCESS(rc)) 194 rc = rtCrPkcs7VerifyCertUsageTimstamping(pCert, pErrInfo); 195 196 return rc; 163 197 } 164 198 … … 206 240 AssertReturn(pAttrib->uValues.pObjIds->cItems == 1, VERR_CR_PKCS7_INTERNAL_ERROR); 207 241 208 if (RTAsn1ObjId_Compare(&pAttrib->uValues.pObjIds->paItems[0], &pSignedData->ContentInfo.ContentType) != 0) 209 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_CONTENT_TYPE_ATTRIB_MISMATCH, 210 "Expected content-type %s, found %s", 211 &pAttrib->uValues.pObjIds->paItems[0], pSignedData->ContentInfo.ContentType.szObjId); 242 if ( !(fFlags & RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE) /* See note about microsoft below. */ 243 && RTAsn1ObjId_Compare(&pAttrib->uValues.pObjIds->paItems[0], &pSignedData->ContentInfo.ContentType) != 0) 244 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_CONTENT_TYPE_ATTRIB_MISMATCH, 245 "Expected content-type %s, found %s", 246 &pAttrib->uValues.pObjIds->paItems[0], pSignedData->ContentInfo.ContentType.szObjId); 212 247 cContentTypes++; 213 248 } … … 239 274 } 240 275 241 AssertReturn(cContentTypes == 1, VERR_CR_PKCS7_INTERNAL_ERROR); 242 AssertReturn(cMessageDigests == 1, VERR_CR_PKCS7_INTERNAL_ERROR); 276 /* 277 * Full error reporting here as we don't currently extensively santiy check 278 * counter signatures. 279 * Note! Microsoft includes content info in their timestamp counter signatures, 280 * at least for vista, despite the RFC-3852 stating counter signatures 281 * "MUST NOT contain a content-type". 282 */ 283 if (RT_UNLIKELY( cContentTypes != 1 284 && !(fFlags & RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE))) 285 return RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_MISSING_CONTENT_TYPE_ATTRIB, 286 "Missing authenticated content-type attribute."); 287 if (RT_UNLIKELY(cMessageDigests != 1)) 288 return RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_MISSING_MESSAGE_DIGEST_ATTRIB, 289 "Missing authenticated message-digest attribute."); 243 290 244 291 /* … … 272 319 273 320 /** 321 * Find the handle to the digest given by the specified SignerInfo. 322 * 323 * @returns IPRT status code 324 * @param phDigest Where to return a referenced digest handle on 325 * success. 326 * @param pSignedData The signed data structure. 327 * @param pSignerInfo The signer info. 328 * @param pahDigests Array of content digests that runs parallel to 329 * pSignedData->DigestAlgorithms. 330 * @param pErrInfo Where to store additional error details, 331 * optional. 332 */ 333 static int rtCrPkcs7VerifyFindDigest(PRTCRDIGEST phDigest, PCRTCRPKCS7SIGNEDDATA pSignedData, 334 PCRTCRPKCS7SIGNERINFO pSignerInfo, PRTCRDIGEST pahDigests, PRTERRINFO pErrInfo) 335 { 336 uint32_t iDigest = pSignedData->DigestAlgorithms.cItems; 337 while (iDigest-- > 0) 338 if (RTCrX509AlgorithmIdentifier_Compare(&pSignedData->DigestAlgorithms.paItems[iDigest], 339 &pSignerInfo->DigestAlgorithm) == 0) 340 { 341 RTCRDIGEST hDigest = pahDigests[iDigest]; 342 uint32_t cRefs = RTCrDigestRetain(hDigest); 343 AssertReturn(cRefs != UINT32_MAX, VERR_CR_PKCS7_INTERNAL_ERROR); 344 *phDigest = hDigest; 345 return VINF_SUCCESS; 346 } 347 348 return RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_DIGEST_ALGO_NOT_FOUND_IN_LIST, 349 "SignerInfo.DigestAlgorithm %s not found.", 350 pSignerInfo->DigestAlgorithm.Algorithm.szObjId); 351 } 352 353 354 /** 274 355 * Verifies one signature on a PKCS \#7 SignedData. 275 356 * … … 277 358 * @param pSignerInfo The signature. 278 359 * @param pSignedData The SignedData. 279 * @param pahDigests Array of content digests that runs parallelto280 * pSigne dData->DigestAlgorithms.360 * @param hDigests The digest corresponding to 361 * pSignerInfo->DigestAlgorithm. 281 362 * @param fFlags Verficiation flags. 282 363 * @param hAdditionalCerts Store containing optional certificates, … … 286 367 * certificates chains at. 287 368 * @param pfnVerifyCert Signing certificate verification callback. 369 * @param fVccFlags Signing certificate verification callback flags. 288 370 * @param pvUser Callback parameter. 289 371 * @param pErrInfo Where to store additional error details, … … 291 373 */ 292 374 static int rtCrPkcs7VerifySignerInfo(PCRTCRPKCS7SIGNERINFO pSignerInfo, PCRTCRPKCS7SIGNEDDATA pSignedData, 293 PRTCRDIGEST pahDigests, uint32_t fFlags, RTCRSTORE hAdditionalCerts, RTCRSTORE hTrustedCerts, 294 PCRTTIMESPEC pValidationTime, RTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, void *pvUser, 295 PRTERRINFO pErrInfo) 296 { 297 /* 298 * Check for counter signatures with timestamp. Verify the signature for 299 * the current time if not present. 300 */ 301 /** @todo timestamp counter signatures. */ 302 375 RTCRDIGEST hDigest, uint32_t fFlags, RTCRSTORE hAdditionalCerts, RTCRSTORE hTrustedCerts, 376 PCRTTIMESPEC pValidationTime, PFNRTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, 377 uint32_t fVccFlags, void *pvUser, PRTERRINFO pErrInfo) 378 { 303 379 /* 304 380 * Locate the certificate used for signing. … … 364 440 */ 365 441 if (RT_SUCCESS(rc)) 366 rc = pfnVerifyCert(pSignerCert, hCertPaths, pvUser, pErrInfo);442 rc = pfnVerifyCert(pSignerCert, hCertPaths, fVccFlags, pvUser, pErrInfo); 367 443 } 368 444 else … … 375 451 */ 376 452 else 377 rc = pfnVerifyCert(pSignerCert, NIL_RTCRX509CERTPATHS, pvUser, pErrInfo); 378 379 /* 380 * Find the digest that is signed and reference it so we can replace it 381 * below if necessary. 382 */ 383 RTCRDIGEST hDigest = NIL_RTCRDIGEST; 384 uint32_t iDigest = pSignedData->DigestAlgorithms.cItems; 385 while (iDigest-- > 0) 386 if (RTCrX509AlgorithmIdentifier_Compare(&pSignedData->DigestAlgorithms.paItems[iDigest], 387 &pSignerInfo->DigestAlgorithm) == 0) 388 { 389 hDigest = pahDigests[iDigest]; 390 uint32_t cRefs = RTCrDigestRetain(hDigest); 391 AssertStmt(cRefs != UINT32_MAX, cRefs = NIL_RTCRDIGEST; rc = VERR_CR_PKCS7_INTERNAL_ERROR); 392 break; 393 } 394 if (hDigest == NIL_RTCRDIGEST && RT_SUCCESS(rc)) 395 rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_DIGEST_ALGO_NOT_FOUND_IN_LIST, 396 "SignerInfo.DigestAlgorithm %s not found.", 397 pSignerInfo->DigestAlgorithm.Algorithm.szObjId); 398 399 /* 400 * If there are authenticated attributes, we've got more work before we 401 * can verify the signature. 453 rc = pfnVerifyCert(pSignerCert, NIL_RTCRX509CERTPATHS, fVccFlags, pvUser, pErrInfo); 454 455 /* 456 * Reference the digest so we can safely replace with one on the 457 * authenticated attributes below. 402 458 */ 403 459 if ( RT_SUCCESS(rc) 404 && RTCrPkcs7Attributes_IsPresent(&pSignerInfo->AuthenticatedAttributes)) 405 rc = rtCrPkcs7VerifySignerInfoAuthAttribs(pSignerInfo, pSignedData, &hDigest, fFlags, pErrInfo); 406 407 /* 408 * Verify the signature. 409 */ 410 if (RT_SUCCESS(rc)) 411 { 412 RTCRPKIXSIGNATURE hSignature; 413 rc = RTCrPkixSignatureCreateByObjId(&hSignature, 414 &pSignerCert->TbsCertificate.SubjectPublicKeyInfo.Algorithm.Algorithm, 415 false /*fSigning*/, 416 &pSignerCert->TbsCertificate.SubjectPublicKeyInfo.SubjectPublicKey, 417 &pSignerInfo->DigestEncryptionAlgorithm.Parameters); 460 && RTCrDigestRetain(hDigest) != UINT32_MAX) 461 { 462 /* 463 * If there are authenticated attributes, we've got more work before we 464 * can verify the signature. 465 */ 466 if ( RT_SUCCESS(rc) 467 && RTCrPkcs7Attributes_IsPresent(&pSignerInfo->AuthenticatedAttributes)) 468 rc = rtCrPkcs7VerifySignerInfoAuthAttribs(pSignerInfo, pSignedData, &hDigest, fFlags, pErrInfo); 469 470 /* 471 * Verify the signature. 472 */ 418 473 if (RT_SUCCESS(rc)) 419 474 { 420 /** @todo Check that DigestEncryptionAlgorithm is compatible with hSignature 421 * (this is not vital). */ 422 rc = RTCrPkixSignatureVerifyOctetString(hSignature, hDigest, &pSignerInfo->EncryptedDigest); 423 if (RT_FAILURE(rc)) 424 rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_SIGNATURE_VERIFICATION_FAILED, 425 "Signature verficiation failed: %Rrc", rc); 426 RTCrPkixSignatureRelease(hSignature); 427 } 428 else 429 rc = RTErrInfoSetF(pErrInfo, rc, "Failure to instantiate public key algorithm [IPRT]: %s (%s)", 430 pSignerCert->TbsCertificate.SubjectPublicKeyInfo.Algorithm.Algorithm.szObjId, 431 pSignerInfo->DigestEncryptionAlgorithm.Algorithm.szObjId); 432 } 433 434 RTCrDigestRelease(hDigest); 475 RTCRPKIXSIGNATURE hSignature; 476 rc = RTCrPkixSignatureCreateByObjId(&hSignature, 477 &pSignerCert->TbsCertificate.SubjectPublicKeyInfo.Algorithm.Algorithm, 478 false /*fSigning*/, 479 &pSignerCert->TbsCertificate.SubjectPublicKeyInfo.SubjectPublicKey, 480 &pSignerInfo->DigestEncryptionAlgorithm.Parameters); 481 if (RT_SUCCESS(rc)) 482 { 483 /** @todo Check that DigestEncryptionAlgorithm is compatible with hSignature 484 * (this is not vital). */ 485 rc = RTCrPkixSignatureVerifyOctetString(hSignature, hDigest, &pSignerInfo->EncryptedDigest); 486 if (RT_FAILURE(rc)) 487 rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_SIGNATURE_VERIFICATION_FAILED, 488 "Signature verficiation failed: %Rrc", rc); 489 RTCrPkixSignatureRelease(hSignature); 490 } 491 else 492 rc = RTErrInfoSetF(pErrInfo, rc, "Failure to instantiate public key algorithm [IPRT]: %s (%s)", 493 pSignerCert->TbsCertificate.SubjectPublicKeyInfo.Algorithm.Algorithm.szObjId, 494 pSignerInfo->DigestEncryptionAlgorithm.Algorithm.szObjId); 495 } 496 497 RTCrDigestRelease(hDigest); 498 } 499 else if (RT_SUCCESS(rc)) 500 rc = VERR_CR_PKCS7_INTERNAL_ERROR; 435 501 RTCrCertCtxRelease(pSignerCertCtx); 436 502 return rc; … … 438 504 439 505 506 /** 507 * Verifies a counter signature. 508 * 509 * @returns IPRT status code. 510 * @param pCounterSignerInfo The counter signature. 511 * @param pPrimarySignerInfo The primary signature (can be a counter 512 * signature too if nested). 513 * @param pSignedData The SignedData. 514 * @param fFlags Verficiation flags. 515 * @param hAdditionalCerts Store containing optional certificates, 516 * optional. 517 * @param hTrustedCerts Store containing trusted certificates, required. 518 * @param pValidationTime The time we're supposed to validate the 519 * certificates chains at. 520 * @param pfnVerifyCert Signing certificate verification callback. 521 * @param fVccFlags Signing certificate verification callback flags. 522 * @param pvUser Callback parameter. 523 * @param pErrInfo Where to store additional error details, 524 * optional. 525 */ 526 static int rtCrPkcs7VerifyCounterSignerInfo(PCRTCRPKCS7SIGNERINFO pCounterSignerInfo, PCRTCRPKCS7SIGNERINFO pPrimarySignerInfo, 527 PCRTCRPKCS7SIGNEDDATA pSignedData, uint32_t fFlags, 528 RTCRSTORE hAdditionalCerts, RTCRSTORE hTrustedCerts, PCRTTIMESPEC pValidationTime, 529 PFNRTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, uint32_t fVccFlags, 530 void *pvUser, PRTERRINFO pErrInfo) 531 { 532 /* 533 * Calculate the digest we need to verify. 534 */ 535 RTCRDIGEST hDigest; 536 int rc = RTCrDigestCreateByObjId(&hDigest, &pCounterSignerInfo->DigestAlgorithm.Algorithm); 537 if (RT_SUCCESS(rc)) 538 { 539 rc = RTCrDigestUpdate(hDigest, 540 pPrimarySignerInfo->EncryptedDigest.Asn1Core.uData.pv, 541 pPrimarySignerInfo->EncryptedDigest.Asn1Core.cb); 542 if (RT_SUCCESS(rc)) 543 rc = RTCrDigestFinal(hDigest, NULL, 0); 544 if (RT_SUCCESS(rc)) 545 { 546 /* 547 * Pass it on to the common SignerInfo verifier function. 548 */ 549 rc = rtCrPkcs7VerifySignerInfo(pCounterSignerInfo, pSignedData, hDigest, 550 fFlags | RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE, 551 hAdditionalCerts, hTrustedCerts, pValidationTime, 552 pfnVerifyCert, fVccFlags, pvUser, pErrInfo); 553 554 } 555 else 556 rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_DIGEST_CALC_ERROR, 557 "Hashing for counter signature failed unexpectedly: %Rrc", rc); 558 RTCrDigestRelease(hDigest); 559 } 560 else 561 rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKCS7_DIGEST_CREATE_ERROR, "Error creating digest for '%s': %Rrc", 562 pCounterSignerInfo->DigestAlgorithm.Algorithm.szObjId, rc); 563 564 return rc; 565 } 566 567 440 568 RTDECL(int) RTCrPkcs7VerifySignedData(PCRTCRPKCS7CONTENTINFO pContentInfo, uint32_t fFlags, 441 569 RTCRSTORE hAdditionalCerts, RTCRSTORE hTrustedCerts, 442 PCRTTIMESPEC pValidationTime, P RTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, void *pvUser,570 PCRTTIMESPEC pValidationTime, PFNRTCRPKCS7VERIFYCERTCALLBACK pfnVerifyCert, void *pvUser, 443 571 PRTERRINFO pErrInfo) 444 572 { … … 458 586 return rc; 459 587 588 AssertReturn(!(fFlags & RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE), VERR_INVALID_FLAGS); 589 460 590 /* 461 591 * Hash the content info. … … 513 643 for (i = 0; i < pSignedData->SignerInfos.cItems; i++) 514 644 { 515 rc = rtCrPkcs7VerifySignerInfo(&pSignedData->SignerInfos.paItems[i], pSignedData, ahDigests, 516 fFlags, hAdditionalCerts, hTrustedCerts, pValidationTime, 517 pfnVerifyCert, pvUser, pErrInfo); 645 PCRTCRPKCS7SIGNERINFO pSignerInfo = &pSignedData->SignerInfos.paItems[i]; 646 RTCRDIGEST hThisDigest; 647 rc = rtCrPkcs7VerifyFindDigest(&hThisDigest, pSignedData, pSignerInfo, ahDigests, pErrInfo); 648 if (RT_FAILURE(rc)) 649 break; 650 651 /* 652 * See if we can find a trusted signing time. 653 */ 654 bool fDone = false; 655 PCRTCRPKCS7SIGNERINFO pSigningTimeSigner = NULL; 656 PCRTASN1TIME pSignedTime; 657 while ( !fDone 658 && (pSignedTime = RTCrPkcs7SignerInfo_GetSigningTime(pSignerInfo, &pSigningTimeSigner)) != NULL) 659 { 660 RTTIMESPEC ThisValidationTime; 661 if (RT_LIKELY(RTTimeImplode(&ThisValidationTime, &pSignedTime->Time))) 662 { 663 if (pSigningTimeSigner == pSignerInfo) 664 { 665 if (fFlags & RTCRPKCS7VERIFY_SD_F_COUNTER_SIGNATURE_SIGNING_TIME_ONLY) 666 continue; 667 rc = rtCrPkcs7VerifySignerInfo(pSignerInfo, pSignedData, hThisDigest, fFlags, 668 hAdditionalCerts, hTrustedCerts, &ThisValidationTime, 669 pfnVerifyCert, RTCRPKCS7VCC_F_SIGNED_DATA | RTCRPKCS7VCC_F_TIMESTAMP, 670 pvUser, pErrInfo); 671 } 672 else 673 { 674 rc = VINF_SUCCESS; 675 if (!(fFlags & RTCRPKCS7VERIFY_SD_F_USE_SIGNING_TIME_UNVERIFIED)) 676 rc = rtCrPkcs7VerifyCounterSignerInfo(pSigningTimeSigner, pSignerInfo, pSignedData, fFlags, 677 hAdditionalCerts, hTrustedCerts, &ThisValidationTime, 678 pfnVerifyCert, RTCRPKCS7VCC_F_TIMESTAMP, pvUser, pErrInfo); 679 if (RT_SUCCESS(rc)) 680 rc = rtCrPkcs7VerifySignerInfo(pSignerInfo, pSignedData, hThisDigest, fFlags, hAdditionalCerts, 681 hTrustedCerts, &ThisValidationTime, 682 pfnVerifyCert, RTCRPKCS7VCC_F_SIGNED_DATA, pvUser, pErrInfo); 683 } 684 fDone = RT_SUCCESS(rc) 685 || (fFlags & RTCRPKCS7VERIFY_SD_F_ALWAYS_USE_SIGNING_TIME_IF_PRESENT); 686 } 687 else 688 { 689 rc = RTErrInfoSet(pErrInfo, VERR_INTERNAL_ERROR_3, "RTTimeImplode failed"); 690 fDone = true; 691 } 692 } 693 694 /* 695 * No valid signing time found, use the one specified instead. 696 */ 697 if (!fDone) 698 rc = rtCrPkcs7VerifySignerInfo(pSignerInfo, pSignedData, hThisDigest, fFlags, hAdditionalCerts, hTrustedCerts, 699 pValidationTime, pfnVerifyCert, RTCRPKCS7VCC_F_SIGNED_DATA, pvUser, pErrInfo); 700 RTCrDigestRelease(hThisDigest); 518 701 if (RT_FAILURE(rc)) 519 702 break; -
trunk/src/VBox/Runtime/common/crypto/pkix-signature-rsa.cpp
r51770 r52537 227 227 * @param hDigest The digest which hash to turn into a signature. 228 228 * @param cbEncodedMsg The desired encoded message length. 229 * @param fNoDigestInfo If true, skip the DigestInfo and encode the digest 230 * without any prefix like described in v1.5 (RFC-2313) 231 * and observed with RSA+MD5 signed timestamps. If 232 * false, include the prefix like v2.0 (RFC-2437) 233 * describes in step in section 9.2.1 234 * (EMSA-PKCS1-v1_5) 229 235 */ 230 static int rtCrPkixSignatureRsa_EmsaPkcs1V15Encode(PRTCRPKIXSIGNATURERSA pThis, RTCRDIGEST hDigest, size_t cbEncodedMsg) 236 static int rtCrPkixSignatureRsa_EmsaPkcs1V15Encode(PRTCRPKIXSIGNATURERSA pThis, RTCRDIGEST hDigest, size_t cbEncodedMsg, 237 bool fNoDigestInfo) 231 238 { 232 239 AssertReturn(cbEncodedMsg * 2 <= sizeof(pThis->Scratch), VERR_CR_PKIX_INTERNAL_ERROR); … … 257 264 AssertReturn(cbHash == pbDigestInfoStart[cbDigestInfoStart - 1], VERR_CR_PKIX_INTERNAL_ERROR); 258 265 266 if (fNoDigestInfo) 267 cbDigestInfoStart = 0; 268 259 269 if (cbDigestInfoStart + cbHash + 11 > cbEncodedMsg) 260 270 return VERR_CR_PKIX_HASH_TOO_LONG_FOR_KEY; … … 265 275 uint8_t *pbDst = &pThis->Scratch.abSignature[0]; 266 276 pbDst[0] = 0x00; 267 pbDst[1] = 0x01; 277 pbDst[1] = 0x01; /* BT - block type, see RFC-2313. */ 268 278 size_t cbFFs = cbEncodedMsg - cbHash - cbDigestInfoStart - 3; 269 279 memset(&pbDst[2], 0xff, cbFFs); … … 279 289 return VINF_SUCCESS; 280 290 } 291 281 292 282 293 … … 327 338 * 8.2.2.3 - Build a hopefully identical signature using hDigest. 328 339 */ 329 rc = rtCrPkixSignatureRsa_EmsaPkcs1V15Encode(pThis, hDigest, cbDecrypted );340 rc = rtCrPkixSignatureRsa_EmsaPkcs1V15Encode(pThis, hDigest, cbDecrypted, false /* fNoDigestInfo */); 330 341 if (RT_SUCCESS(rc)) 331 342 { … … 336 347 rc = VINF_SUCCESS; 337 348 else 338 rc = VERR_CR_PKIX_SIGNATURE_MISMATCH; 349 { 350 /* 351 * Try again without digestinfo. This style signing has been 352 * observed in Vista timestamp counter signatures (Thawte). 353 */ 354 rc = rtCrPkixSignatureRsa_EmsaPkcs1V15Encode(pThis, hDigest, cbDecrypted, 355 true /* fNoDigestInfo */); 356 if (RT_SUCCESS(rc)) 357 { 358 if (memcmp(&pThis->Scratch.abSignature[0], pbDecrypted, cbDecrypted) == 0) 359 rc = VINF_SUCCESS; 360 else 361 rc = VERR_CR_PKIX_SIGNATURE_MISMATCH; 362 } 363 } 339 364 } 340 365 } -
trunk/src/VBox/Runtime/common/crypto/x509-core.cpp
r52206 r52537 1278 1278 case 6: pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_IPSEC_TUNNEL; break; 1279 1279 case 7: pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_IPSEC_USER; break; 1280 case 8: pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_TIME _STAMPING; break;1280 case 8: pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_TIMESTAMPING; break; 1281 1281 case 9: pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_OCSP_SIGNING; break; 1282 1282 case 10: pThis->T3.fExtKeyUsage |= RTCRX509CERT_EKU_F_DVCS; break;
Note:
See TracChangeset
for help on using the changeset viewer.