ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

crl.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      &para->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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.