Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencrl.c
Go to the documentation of this file.
00001 /* 00002 * Copyright 2006 Juan Lang 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00017 * 00018 */ 00019 00020 #include <assert.h> 00021 #include <stdarg.h> 00022 #define NONAMELESSUNION 00023 #include "windef.h" 00024 #include "winbase.h" 00025 #include "wincrypt.h" 00026 #include "wine/debug.h" 00027 #include "wine/unicode.h" 00028 #include "crypt32_private.h" 00029 00030 WINE_DEFAULT_DEBUG_CHANNEL(crypt); 00031 00032 PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType, 00033 const BYTE* pbCrlEncoded, DWORD cbCrlEncoded) 00034 { 00035 PCRL_CONTEXT crl = NULL; 00036 BOOL ret; 00037 PCRL_INFO crlInfo = NULL; 00038 DWORD size = 0; 00039 00040 TRACE("(%08x, %p, %d)\n", dwCertEncodingType, pbCrlEncoded, 00041 cbCrlEncoded); 00042 00043 if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING) 00044 { 00045 SetLastError(E_INVALIDARG); 00046 return NULL; 00047 } 00048 ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED, 00049 pbCrlEncoded, cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, 00050 &crlInfo, &size); 00051 if (ret) 00052 { 00053 BYTE *data = NULL; 00054 00055 crl = Context_CreateDataContext(sizeof(CRL_CONTEXT)); 00056 if (!crl) 00057 goto end; 00058 data = CryptMemAlloc(cbCrlEncoded); 00059 if (!data) 00060 { 00061 CertFreeCRLContext(crl); 00062 crl = NULL; 00063 goto end; 00064 } 00065 memcpy(data, pbCrlEncoded, cbCrlEncoded); 00066 crl->dwCertEncodingType = dwCertEncodingType; 00067 crl->pbCrlEncoded = data; 00068 crl->cbCrlEncoded = cbCrlEncoded; 00069 crl->pCrlInfo = crlInfo; 00070 crl->hCertStore = 0; 00071 } 00072 00073 end: 00074 return crl; 00075 } 00076 00077 BOOL WINAPI CertAddEncodedCRLToStore(HCERTSTORE hCertStore, 00078 DWORD dwCertEncodingType, const BYTE *pbCrlEncoded, DWORD cbCrlEncoded, 00079 DWORD dwAddDisposition, PCCRL_CONTEXT *ppCrlContext) 00080 { 00081 PCCRL_CONTEXT crl = CertCreateCRLContext(dwCertEncodingType, 00082 pbCrlEncoded, cbCrlEncoded); 00083 BOOL ret; 00084 00085 TRACE("(%p, %08x, %p, %d, %08x, %p)\n", hCertStore, dwCertEncodingType, 00086 pbCrlEncoded, cbCrlEncoded, dwAddDisposition, ppCrlContext); 00087 00088 if (crl) 00089 { 00090 ret = CertAddCRLContextToStore(hCertStore, crl, dwAddDisposition, 00091 ppCrlContext); 00092 CertFreeCRLContext(crl); 00093 } 00094 else 00095 ret = FALSE; 00096 return ret; 00097 } 00098 00099 typedef BOOL (*CrlCompareFunc)(PCCRL_CONTEXT pCrlContext, DWORD dwType, 00100 DWORD dwFlags, const void *pvPara); 00101 00102 static BOOL compare_crl_any(PCCRL_CONTEXT pCrlContext, DWORD dwType, 00103 DWORD dwFlags, const void *pvPara) 00104 { 00105 return TRUE; 00106 } 00107 00108 static BOOL compare_crl_issued_by(PCCRL_CONTEXT pCrlContext, DWORD dwType, 00109 DWORD dwFlags, const void *pvPara) 00110 { 00111 BOOL ret; 00112 00113 if (pvPara) 00114 { 00115 PCCERT_CONTEXT issuer = pvPara; 00116 00117 ret = CertCompareCertificateName(issuer->dwCertEncodingType, 00118 &issuer->pCertInfo->Subject, &pCrlContext->pCrlInfo->Issuer); 00119 if (ret && (dwFlags & CRL_FIND_ISSUED_BY_SIGNATURE_FLAG)) 00120 ret = CryptVerifyCertificateSignatureEx(0, 00121 issuer->dwCertEncodingType, 00122 CRYPT_VERIFY_CERT_SIGN_SUBJECT_CRL, (void *)pCrlContext, 00123 CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, (void *)issuer, 0, NULL); 00124 if (ret && (dwFlags & CRL_FIND_ISSUED_BY_AKI_FLAG)) 00125 { 00126 PCERT_EXTENSION ext = CertFindExtension( 00127 szOID_AUTHORITY_KEY_IDENTIFIER2, pCrlContext->pCrlInfo->cExtension, 00128 pCrlContext->pCrlInfo->rgExtension); 00129 00130 if (ext) 00131 { 00132 CERT_AUTHORITY_KEY_ID2_INFO *info; 00133 DWORD size; 00134 00135 if ((ret = CryptDecodeObjectEx(X509_ASN_ENCODING, 00136 X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData, 00137 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size))) 00138 { 00139 if (info->AuthorityCertIssuer.cAltEntry && 00140 info->AuthorityCertSerialNumber.cbData) 00141 { 00142 PCERT_ALT_NAME_ENTRY directoryName = NULL; 00143 DWORD i; 00144 00145 for (i = 0; !directoryName && 00146 i < info->AuthorityCertIssuer.cAltEntry; i++) 00147 if (info->AuthorityCertIssuer.rgAltEntry[i]. 00148 dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME) 00149 directoryName = 00150 &info->AuthorityCertIssuer.rgAltEntry[i]; 00151 if (directoryName) 00152 { 00153 ret = CertCompareCertificateName( 00154 issuer->dwCertEncodingType, 00155 &issuer->pCertInfo->Subject, 00156 &directoryName->u.DirectoryName); 00157 if (ret) 00158 ret = CertCompareIntegerBlob( 00159 &issuer->pCertInfo->SerialNumber, 00160 &info->AuthorityCertSerialNumber); 00161 } 00162 else 00163 { 00164 FIXME("no supported name type in authority key id2\n"); 00165 ret = FALSE; 00166 } 00167 } 00168 else if (info->KeyId.cbData) 00169 { 00170 DWORD size; 00171 00172 ret = CertGetCertificateContextProperty(issuer, 00173 CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); 00174 if (ret && size == info->KeyId.cbData) 00175 { 00176 LPBYTE buf = CryptMemAlloc(size); 00177 00178 if (buf) 00179 { 00180 CertGetCertificateContextProperty(issuer, 00181 CERT_KEY_IDENTIFIER_PROP_ID, buf, &size); 00182 ret = !memcmp(buf, info->KeyId.pbData, size); 00183 CryptMemFree(buf); 00184 } 00185 else 00186 ret = FALSE; 00187 } 00188 else 00189 ret = FALSE; 00190 } 00191 else 00192 { 00193 FIXME("unsupported value for AKI extension\n"); 00194 ret = FALSE; 00195 } 00196 LocalFree(info); 00197 } 00198 } 00199 /* else: a CRL without an AKI matches any cert */ 00200 } 00201 } 00202 else 00203 ret = TRUE; 00204 return ret; 00205 } 00206 00207 static BOOL compare_crl_existing(PCCRL_CONTEXT pCrlContext, DWORD dwType, 00208 DWORD dwFlags, const void *pvPara) 00209 { 00210 BOOL ret; 00211 00212 if (pvPara) 00213 { 00214 PCCRL_CONTEXT crl = pvPara; 00215 00216 ret = CertCompareCertificateName(pCrlContext->dwCertEncodingType, 00217 &pCrlContext->pCrlInfo->Issuer, &crl->pCrlInfo->Issuer); 00218 } 00219 else 00220 ret = TRUE; 00221 return ret; 00222 } 00223 00224 static BOOL compare_crl_issued_for(PCCRL_CONTEXT pCrlContext, DWORD dwType, 00225 DWORD dwFlags, const void *pvPara) 00226 { 00227 const CRL_FIND_ISSUED_FOR_PARA *para = pvPara; 00228 BOOL ret; 00229 00230 ret = CertCompareCertificateName(para->pIssuerCert->dwCertEncodingType, 00231 ¶->pIssuerCert->pCertInfo->Issuer, &pCrlContext->pCrlInfo->Issuer); 00232 return ret; 00233 } 00234 00235 PCCRL_CONTEXT WINAPI CertFindCRLInStore(HCERTSTORE hCertStore, 00236 DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType, 00237 const void *pvFindPara, PCCRL_CONTEXT pPrevCrlContext) 00238 { 00239 PCCRL_CONTEXT ret; 00240 CrlCompareFunc compare; 00241 00242 TRACE("(%p, %d, %d, %d, %p, %p)\n", hCertStore, dwCertEncodingType, 00243 dwFindFlags, dwFindType, pvFindPara, pPrevCrlContext); 00244 00245 switch (dwFindType) 00246 { 00247 case CRL_FIND_ANY: 00248 compare = compare_crl_any; 00249 break; 00250 case CRL_FIND_ISSUED_BY: 00251 compare = compare_crl_issued_by; 00252 break; 00253 case CRL_FIND_EXISTING: 00254 compare = compare_crl_existing; 00255 break; 00256 case CRL_FIND_ISSUED_FOR: 00257 compare = compare_crl_issued_for; 00258 break; 00259 default: 00260 FIXME("find type %08x unimplemented\n", dwFindType); 00261 compare = NULL; 00262 } 00263 00264 if (compare) 00265 { 00266 BOOL matches = FALSE; 00267 00268 ret = pPrevCrlContext; 00269 do { 00270 ret = CertEnumCRLsInStore(hCertStore, ret); 00271 if (ret) 00272 matches = compare(ret, dwFindType, dwFindFlags, pvFindPara); 00273 } while (ret != NULL && !matches); 00274 if (!ret) 00275 SetLastError(CRYPT_E_NOT_FOUND); 00276 } 00277 else 00278 { 00279 SetLastError(CRYPT_E_NOT_FOUND); 00280 ret = NULL; 00281 } 00282 return ret; 00283 } 00284 00285 PCCRL_CONTEXT WINAPI CertGetCRLFromStore(HCERTSTORE hCertStore, 00286 PCCERT_CONTEXT pIssuerContext, PCCRL_CONTEXT pPrevCrlContext, DWORD *pdwFlags) 00287 { 00288 static const DWORD supportedFlags = CERT_STORE_SIGNATURE_FLAG | 00289 CERT_STORE_TIME_VALIDITY_FLAG | CERT_STORE_BASE_CRL_FLAG | 00290 CERT_STORE_DELTA_CRL_FLAG; 00291 PCCRL_CONTEXT ret; 00292 00293 TRACE("(%p, %p, %p, %08x)\n", hCertStore, pIssuerContext, pPrevCrlContext, 00294 *pdwFlags); 00295 00296 if (*pdwFlags & ~supportedFlags) 00297 { 00298 SetLastError(E_INVALIDARG); 00299 return NULL; 00300 } 00301 if (pIssuerContext) 00302 ret = CertFindCRLInStore(hCertStore, pIssuerContext->dwCertEncodingType, 00303 0, CRL_FIND_ISSUED_BY, pIssuerContext, pPrevCrlContext); 00304 else 00305 ret = CertFindCRLInStore(hCertStore, 0, 0, CRL_FIND_ANY, NULL, 00306 pPrevCrlContext); 00307 if (ret) 00308 { 00309 if (*pdwFlags & CERT_STORE_TIME_VALIDITY_FLAG) 00310 { 00311 if (0 == CertVerifyCRLTimeValidity(NULL, ret->pCrlInfo)) 00312 *pdwFlags &= ~CERT_STORE_TIME_VALIDITY_FLAG; 00313 } 00314 if (*pdwFlags & CERT_STORE_SIGNATURE_FLAG) 00315 { 00316 if (CryptVerifyCertificateSignatureEx(0, ret->dwCertEncodingType, 00317 CRYPT_VERIFY_CERT_SIGN_SUBJECT_CRL, (void *)ret, 00318 CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, (void *)pIssuerContext, 0, 00319 NULL)) 00320 *pdwFlags &= ~CERT_STORE_SIGNATURE_FLAG; 00321 } 00322 } 00323 return ret; 00324 } 00325 00326 PCCRL_CONTEXT WINAPI CertDuplicateCRLContext(PCCRL_CONTEXT pCrlContext) 00327 { 00328 TRACE("(%p)\n", pCrlContext); 00329 if (pCrlContext) 00330 Context_AddRef((void *)pCrlContext, sizeof(CRL_CONTEXT)); 00331 return pCrlContext; 00332 } 00333 00334 static void CrlDataContext_Free(void *context) 00335 { 00336 PCRL_CONTEXT crlContext = context; 00337 00338 CryptMemFree(crlContext->pbCrlEncoded); 00339 LocalFree(crlContext->pCrlInfo); 00340 } 00341 00342 BOOL WINAPI CertFreeCRLContext( PCCRL_CONTEXT pCrlContext) 00343 { 00344 BOOL ret = TRUE; 00345 00346 TRACE("(%p)\n", pCrlContext); 00347 00348 if (pCrlContext) 00349 ret = Context_Release((void *)pCrlContext, sizeof(CRL_CONTEXT), 00350 CrlDataContext_Free); 00351 return ret; 00352 } 00353 00354 DWORD WINAPI CertEnumCRLContextProperties(PCCRL_CONTEXT pCRLContext, 00355 DWORD dwPropId) 00356 { 00357 PCONTEXT_PROPERTY_LIST properties = Context_GetProperties( 00358 pCRLContext, sizeof(CRL_CONTEXT)); 00359 DWORD ret; 00360 00361 TRACE("(%p, %d)\n", pCRLContext, dwPropId); 00362 00363 if (properties) 00364 ret = ContextPropertyList_EnumPropIDs(properties, dwPropId); 00365 else 00366 ret = 0; 00367 return ret; 00368 } 00369 00370 static BOOL CRLContext_SetProperty(PCCRL_CONTEXT context, DWORD dwPropId, 00371 DWORD dwFlags, const void *pvData); 00372 00373 static BOOL CRLContext_GetHashProp(PCCRL_CONTEXT context, DWORD dwPropId, 00374 ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData, 00375 DWORD *pcbData) 00376 { 00377 BOOL ret = CryptHashCertificate(0, algID, 0, toHash, toHashLen, pvData, 00378 pcbData); 00379 if (ret && pvData) 00380 { 00381 CRYPT_DATA_BLOB blob = { *pcbData, pvData }; 00382 00383 ret = CRLContext_SetProperty(context, dwPropId, 0, &blob); 00384 } 00385 return ret; 00386 } 00387 00388 static BOOL CRLContext_GetProperty(PCCRL_CONTEXT context, DWORD dwPropId, 00389 void *pvData, DWORD *pcbData) 00390 { 00391 PCONTEXT_PROPERTY_LIST properties = 00392 Context_GetProperties(context, sizeof(CRL_CONTEXT)); 00393 BOOL ret; 00394 CRYPT_DATA_BLOB blob; 00395 00396 TRACE("(%p, %d, %p, %p)\n", context, dwPropId, pvData, pcbData); 00397 00398 if (properties) 00399 ret = ContextPropertyList_FindProperty(properties, dwPropId, &blob); 00400 else 00401 ret = FALSE; 00402 if (ret) 00403 { 00404 if (!pvData) 00405 *pcbData = blob.cbData; 00406 else if (*pcbData < blob.cbData) 00407 { 00408 SetLastError(ERROR_MORE_DATA); 00409 *pcbData = blob.cbData; 00410 ret = FALSE; 00411 } 00412 else 00413 { 00414 memcpy(pvData, blob.pbData, blob.cbData); 00415 *pcbData = blob.cbData; 00416 } 00417 } 00418 else 00419 { 00420 /* Implicit properties */ 00421 switch (dwPropId) 00422 { 00423 case CERT_SHA1_HASH_PROP_ID: 00424 ret = CRLContext_GetHashProp(context, dwPropId, CALG_SHA1, 00425 context->pbCrlEncoded, context->cbCrlEncoded, pvData, 00426 pcbData); 00427 break; 00428 case CERT_MD5_HASH_PROP_ID: 00429 ret = CRLContext_GetHashProp(context, dwPropId, CALG_MD5, 00430 context->pbCrlEncoded, context->cbCrlEncoded, pvData, 00431 pcbData); 00432 break; 00433 default: 00434 SetLastError(CRYPT_E_NOT_FOUND); 00435 } 00436 } 00437 TRACE("returning %d\n", ret); 00438 return ret; 00439 } 00440 00441 BOOL WINAPI CertGetCRLContextProperty(PCCRL_CONTEXT pCRLContext, 00442 DWORD dwPropId, void *pvData, DWORD *pcbData) 00443 { 00444 BOOL ret; 00445 00446 TRACE("(%p, %d, %p, %p)\n", pCRLContext, dwPropId, pvData, pcbData); 00447 00448 switch (dwPropId) 00449 { 00450 case 0: 00451 case CERT_CERT_PROP_ID: 00452 case CERT_CRL_PROP_ID: 00453 case CERT_CTL_PROP_ID: 00454 SetLastError(E_INVALIDARG); 00455 ret = FALSE; 00456 break; 00457 case CERT_ACCESS_STATE_PROP_ID: 00458 if (!pvData) 00459 { 00460 *pcbData = sizeof(DWORD); 00461 ret = TRUE; 00462 } 00463 else if (*pcbData < sizeof(DWORD)) 00464 { 00465 SetLastError(ERROR_MORE_DATA); 00466 *pcbData = sizeof(DWORD); 00467 ret = FALSE; 00468 } 00469 else 00470 { 00471 if (pCRLContext->hCertStore) 00472 ret = CertGetStoreProperty(pCRLContext->hCertStore, dwPropId, 00473 pvData, pcbData); 00474 else 00475 { 00476 *(DWORD *)pvData = 0; 00477 ret = TRUE; 00478 } 00479 } 00480 break; 00481 default: 00482 ret = CRLContext_GetProperty(pCRLContext, dwPropId, pvData, 00483 pcbData); 00484 } 00485 return ret; 00486 } 00487 00488 static BOOL CRLContext_SetProperty(PCCRL_CONTEXT context, DWORD dwPropId, 00489 DWORD dwFlags, const void *pvData) 00490 { 00491 PCONTEXT_PROPERTY_LIST properties = 00492 Context_GetProperties(context, sizeof(CRL_CONTEXT)); 00493 BOOL ret; 00494 00495 TRACE("(%p, %d, %08x, %p)\n", context, dwPropId, dwFlags, pvData); 00496 00497 if (!properties) 00498 ret = FALSE; 00499 else if (!pvData) 00500 { 00501 ContextPropertyList_RemoveProperty(properties, dwPropId); 00502 ret = TRUE; 00503 } 00504 else 00505 { 00506 switch (dwPropId) 00507 { 00508 case CERT_AUTO_ENROLL_PROP_ID: 00509 case CERT_CTL_USAGE_PROP_ID: /* same as CERT_ENHKEY_USAGE_PROP_ID */ 00510 case CERT_DESCRIPTION_PROP_ID: 00511 case CERT_FRIENDLY_NAME_PROP_ID: 00512 case CERT_HASH_PROP_ID: 00513 case CERT_KEY_IDENTIFIER_PROP_ID: 00514 case CERT_MD5_HASH_PROP_ID: 00515 case CERT_NEXT_UPDATE_LOCATION_PROP_ID: 00516 case CERT_PUBKEY_ALG_PARA_PROP_ID: 00517 case CERT_PVK_FILE_PROP_ID: 00518 case CERT_SIGNATURE_HASH_PROP_ID: 00519 case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID: 00520 case CERT_SUBJECT_NAME_MD5_HASH_PROP_ID: 00521 case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID: 00522 case CERT_ENROLLMENT_PROP_ID: 00523 case CERT_CROSS_CERT_DIST_POINTS_PROP_ID: 00524 case CERT_RENEWAL_PROP_ID: 00525 { 00526 PCRYPT_DATA_BLOB blob = (PCRYPT_DATA_BLOB)pvData; 00527 00528 ret = ContextPropertyList_SetProperty(properties, dwPropId, 00529 blob->pbData, blob->cbData); 00530 break; 00531 } 00532 case CERT_DATE_STAMP_PROP_ID: 00533 ret = ContextPropertyList_SetProperty(properties, dwPropId, 00534 pvData, sizeof(FILETIME)); 00535 break; 00536 default: 00537 FIXME("%d: stub\n", dwPropId); 00538 ret = FALSE; 00539 } 00540 } 00541 TRACE("returning %d\n", ret); 00542 return ret; 00543 } 00544 00545 BOOL WINAPI CertSetCRLContextProperty(PCCRL_CONTEXT pCRLContext, 00546 DWORD dwPropId, DWORD dwFlags, const void *pvData) 00547 { 00548 BOOL ret; 00549 00550 TRACE("(%p, %d, %08x, %p)\n", pCRLContext, dwPropId, dwFlags, pvData); 00551 00552 /* Handle special cases for "read-only"/invalid prop IDs. Windows just 00553 * crashes on most of these, I'll be safer. 00554 */ 00555 switch (dwPropId) 00556 { 00557 case 0: 00558 case CERT_ACCESS_STATE_PROP_ID: 00559 case CERT_CERT_PROP_ID: 00560 case CERT_CRL_PROP_ID: 00561 case CERT_CTL_PROP_ID: 00562 SetLastError(E_INVALIDARG); 00563 return FALSE; 00564 } 00565 ret = CRLContext_SetProperty(pCRLContext, dwPropId, dwFlags, pvData); 00566 TRACE("returning %d\n", ret); 00567 return ret; 00568 } 00569 00570 static BOOL compare_dist_point_name(const CRL_DIST_POINT_NAME *name1, 00571 const CRL_DIST_POINT_NAME *name2) 00572 { 00573 BOOL match; 00574 00575 if (name1->dwDistPointNameChoice == name2->dwDistPointNameChoice) 00576 { 00577 match = TRUE; 00578 if (name1->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME) 00579 { 00580 if (name1->u.FullName.cAltEntry == name2->u.FullName.cAltEntry) 00581 { 00582 DWORD i; 00583 00584 for (i = 0; match && i < name1->u.FullName.cAltEntry; i++) 00585 { 00586 const CERT_ALT_NAME_ENTRY *entry1 = 00587 &name1->u.FullName.rgAltEntry[i]; 00588 const CERT_ALT_NAME_ENTRY *entry2 = 00589 &name2->u.FullName.rgAltEntry[i]; 00590 00591 if (entry1->dwAltNameChoice == entry2->dwAltNameChoice) 00592 { 00593 switch (entry1->dwAltNameChoice) 00594 { 00595 case CERT_ALT_NAME_URL: 00596 match = !strcmpiW(entry1->u.pwszURL, 00597 entry2->u.pwszURL); 00598 break; 00599 case CERT_ALT_NAME_DIRECTORY_NAME: 00600 match = (entry1->u.DirectoryName.cbData == 00601 entry2->u.DirectoryName.cbData) && 00602 !memcmp(entry1->u.DirectoryName.pbData, 00603 entry2->u.DirectoryName.pbData, 00604 entry1->u.DirectoryName.cbData); 00605 break; 00606 default: 00607 FIXME("unimplemented for type %d\n", 00608 entry1->dwAltNameChoice); 00609 match = FALSE; 00610 } 00611 } 00612 else 00613 match = FALSE; 00614 } 00615 } 00616 else 00617 match = FALSE; 00618 } 00619 } 00620 else 00621 match = FALSE; 00622 return match; 00623 } 00624 00625 static BOOL match_dist_point_with_issuing_dist_point( 00626 const CRL_DIST_POINT *distPoint, const CRL_ISSUING_DIST_POINT *idp) 00627 { 00628 BOOL match; 00629 00630 /* While RFC 5280, section 4.2.1.13 recommends against segmenting 00631 * CRL distribution points by reasons, it doesn't preclude doing so. 00632 * "This profile RECOMMENDS against segmenting CRLs by reason code." 00633 * If the issuing distribution point for this CRL is only valid for 00634 * some reasons, only match if the reasons covered also match the 00635 * reasons in the CRL distribution point. 00636 */ 00637 if (idp->OnlySomeReasonFlags.cbData) 00638 { 00639 if (idp->OnlySomeReasonFlags.cbData == distPoint->ReasonFlags.cbData) 00640 { 00641 DWORD i; 00642 00643 match = TRUE; 00644 for (i = 0; match && i < distPoint->ReasonFlags.cbData; i++) 00645 if (idp->OnlySomeReasonFlags.pbData[i] != 00646 distPoint->ReasonFlags.pbData[i]) 00647 match = FALSE; 00648 } 00649 else 00650 match = FALSE; 00651 } 00652 else 00653 match = TRUE; 00654 if (match) 00655 match = compare_dist_point_name(&idp->DistPointName, 00656 &distPoint->DistPointName); 00657 return match; 00658 } 00659 00660 BOOL WINAPI CertIsValidCRLForCertificate(PCCERT_CONTEXT pCert, 00661 PCCRL_CONTEXT pCrl, DWORD dwFlags, void *pvReserved) 00662 { 00663 PCERT_EXTENSION ext; 00664 BOOL ret; 00665 00666 TRACE("(%p, %p, %08x, %p)\n", pCert, pCrl, dwFlags, pvReserved); 00667 00668 if (!pCert) 00669 return TRUE; 00670 00671 if ((ext = CertFindExtension(szOID_ISSUING_DIST_POINT, 00672 pCrl->pCrlInfo->cExtension, pCrl->pCrlInfo->rgExtension))) 00673 { 00674 CRL_ISSUING_DIST_POINT *idp; 00675 DWORD size; 00676 00677 if ((ret = CryptDecodeObjectEx(pCrl->dwCertEncodingType, 00678 X509_ISSUING_DIST_POINT, ext->Value.pbData, ext->Value.cbData, 00679 CRYPT_DECODE_ALLOC_FLAG, NULL, &idp, &size))) 00680 { 00681 if ((ext = CertFindExtension(szOID_CRL_DIST_POINTS, 00682 pCert->pCertInfo->cExtension, pCert->pCertInfo->rgExtension))) 00683 { 00684 CRL_DIST_POINTS_INFO *distPoints; 00685 00686 if ((ret = CryptDecodeObjectEx(pCert->dwCertEncodingType, 00687 X509_CRL_DIST_POINTS, ext->Value.pbData, ext->Value.cbData, 00688 CRYPT_DECODE_ALLOC_FLAG, NULL, &distPoints, &size))) 00689 { 00690 DWORD i; 00691 00692 ret = FALSE; 00693 for (i = 0; !ret && i < distPoints->cDistPoint; i++) 00694 ret = match_dist_point_with_issuing_dist_point( 00695 &distPoints->rgDistPoint[i], idp); 00696 if (!ret) 00697 SetLastError(CRYPT_E_NO_MATCH); 00698 LocalFree(distPoints); 00699 } 00700 } 00701 else 00702 { 00703 /* no CRL dist points extension in cert, can't match the CRL 00704 * (which has an issuing dist point extension) 00705 */ 00706 ret = FALSE; 00707 SetLastError(CRYPT_E_NO_MATCH); 00708 } 00709 LocalFree(idp); 00710 } 00711 } 00712 else 00713 ret = TRUE; 00714 return ret; 00715 } 00716 00717 static PCRL_ENTRY CRYPT_FindCertificateInCRL(PCERT_INFO cert, const CRL_INFO *crl) 00718 { 00719 DWORD i; 00720 PCRL_ENTRY entry = NULL; 00721 00722 for (i = 0; !entry && i < crl->cCRLEntry; i++) 00723 if (CertCompareIntegerBlob(&crl->rgCRLEntry[i].SerialNumber, 00724 &cert->SerialNumber)) 00725 entry = &crl->rgCRLEntry[i]; 00726 return entry; 00727 } 00728 00729 BOOL WINAPI CertFindCertificateInCRL(PCCERT_CONTEXT pCert, 00730 PCCRL_CONTEXT pCrlContext, DWORD dwFlags, void *pvReserved, 00731 PCRL_ENTRY *ppCrlEntry) 00732 { 00733 TRACE("(%p, %p, %08x, %p, %p)\n", pCert, pCrlContext, dwFlags, pvReserved, 00734 ppCrlEntry); 00735 00736 *ppCrlEntry = CRYPT_FindCertificateInCRL(pCert->pCertInfo, 00737 pCrlContext->pCrlInfo); 00738 return TRUE; 00739 } 00740 00741 BOOL WINAPI CertVerifyCRLRevocation(DWORD dwCertEncodingType, 00742 PCERT_INFO pCertId, DWORD cCrlInfo, PCRL_INFO rgpCrlInfo[]) 00743 { 00744 DWORD i; 00745 PCRL_ENTRY entry = NULL; 00746 00747 TRACE("(%08x, %p, %d, %p)\n", dwCertEncodingType, pCertId, cCrlInfo, 00748 rgpCrlInfo); 00749 00750 for (i = 0; !entry && i < cCrlInfo; i++) 00751 entry = CRYPT_FindCertificateInCRL(pCertId, rgpCrlInfo[i]); 00752 return entry == NULL; 00753 } 00754 00755 LONG WINAPI CertVerifyCRLTimeValidity(LPFILETIME pTimeToVerify, 00756 PCRL_INFO pCrlInfo) 00757 { 00758 FILETIME fileTime; 00759 LONG ret; 00760 00761 if (!pTimeToVerify) 00762 { 00763 GetSystemTimeAsFileTime(&fileTime); 00764 pTimeToVerify = &fileTime; 00765 } 00766 if ((ret = CompareFileTime(pTimeToVerify, &pCrlInfo->ThisUpdate)) >= 0) 00767 { 00768 ret = CompareFileTime(pTimeToVerify, &pCrlInfo->NextUpdate); 00769 if (ret < 0) 00770 ret = 0; 00771 } 00772 return ret; 00773 } Generated on Sun May 27 2012 04:23:12 for ReactOS by
1.7.6.1
|