PWINECRYPT_CERTSTORE CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags) { TRACE("(%ld, %08x)\n", hCryptProv, dwFlags); if (dwFlags & CERT_STORE_DELETE_FLAG) { WARN("root store can't be deleted\n"); SetLastError(ERROR_ACCESS_DENIED); return NULL; } switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) { case CERT_SYSTEM_STORE_LOCAL_MACHINE: case CERT_SYSTEM_STORE_CURRENT_USER: break; default: TRACE("location %08x unsupported\n", dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK); SetLastError(E_INVALIDARG); return NULL; } if (!CRYPT_rootStore) { HCERTSTORE root = CRYPT_RootOpenStoreFromKnownLocations(); InterlockedCompareExchangePointer((PVOID *)&CRYPT_rootStore, root, NULL); if (CRYPT_rootStore != root) CertCloseStore(root, 0); } CertDuplicateStore(CRYPT_rootStore); return CRYPT_rootStore; }
static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to) { DWORD root_count = 0; CERT_CHAIN_ENGINE_CONFIG chainEngineConfig = { sizeof(chainEngineConfig), 0 }; HCERTCHAINENGINE engine; TRACE("\n"); CertDuplicateStore(to); engine = CRYPT_CreateChainEngine(to, &chainEngineConfig); if (engine) { PCCERT_CONTEXT cert = NULL; do { cert = CertEnumCertificatesInStore(from, cert); if (cert) { CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } }; PCCERT_CHAIN_CONTEXT chain; BOOL ret = CertGetCertificateChain(engine, cert, NULL, from, &chainPara, 0, NULL, &chain); if (!ret) TRACE("rejecting %s: %s\n", get_cert_common_name(cert), "chain creation failed"); else { /* The only allowed error is CERT_TRUST_IS_UNTRUSTED_ROOT */ if (chain->TrustStatus.dwErrorStatus & ~CERT_TRUST_IS_UNTRUSTED_ROOT) TRACE("rejecting %s: %s\n", get_cert_common_name(cert), trust_status_to_str(chain->TrustStatus.dwErrorStatus & ~CERT_TRUST_IS_UNTRUSTED_ROOT)); else { DWORD i, j; for (i = 0; i < chain->cChain; i++) for (j = 0; j < chain->rgpChain[i]->cElement; j++) if (CertAddCertificateContextToStore(to, chain->rgpChain[i]->rgpElement[j]->pCertContext, CERT_STORE_ADD_NEW, NULL)) root_count++; } CertFreeCertificateChain(chain); } } } while (cert); CertFreeCertificateChainEngine(engine); } TRACE("Added %d root certificates\n", root_count); }
PWINECRYPT_CERTSTORE CRYPT_RootOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags) { TRACE("(%ld, %08x)\n", hCryptProv, dwFlags); if (dwFlags & CERT_STORE_DELETE_FLAG) { WARN("root store can't be deleted\n"); SetLastError(ERROR_ACCESS_DENIED); return NULL; } if (!CRYPT_rootStore) { HCERTSTORE root = create_root_store(); InterlockedCompareExchangePointer((PVOID *)&CRYPT_rootStore, root, NULL); if (CRYPT_rootStore != root) CertCloseStore(root, 0); } CertDuplicateStore(CRYPT_rootStore); return CRYPT_rootStore; }
static BOOL CRYPT_QuerySerializedStoreObject(DWORD dwObjectType, const void *pvObject, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, HCERTSTORE *phCertStore, HCRYPTMSG *phMsg) { LPCWSTR fileName = (LPCWSTR)pvObject; HANDLE file; BOOL ret = FALSE; if (dwObjectType != CERT_QUERY_OBJECT_FILE) { FIXME("unimplemented for non-file type %d\n", dwObjectType); SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */ return FALSE; } TRACE("%s\n", debugstr_w(fileName)); file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (file != INVALID_HANDLE_VALUE) { HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); ret = CRYPT_ReadSerializedStoreFromFile(file, store); if (ret) { if (pdwMsgAndCertEncodingType) *pdwMsgAndCertEncodingType = X509_ASN_ENCODING; if (pdwContentType) *pdwContentType = CERT_QUERY_CONTENT_SERIALIZED_STORE; if (phCertStore) *phCertStore = CertDuplicateStore(store); } CertCloseStore(store, 0); CloseHandle(file); } TRACE("returning %d\n", ret); return ret; }
BOOL WINAPI WINTRUST_AddStore(CRYPT_PROVIDER_DATA *data, HCERTSTORE store) { BOOL ret = FALSE; TRACE("(%p, %p)\n", data, store); if (data->chStores) data->pahStores = WINTRUST_ReAlloc(data->pahStores, (data->chStores + 1) * sizeof(HCERTSTORE)); else { data->pahStores = WINTRUST_Alloc(sizeof(HCERTSTORE)); data->chStores = 0; } if (data->pahStores) { data->pahStores[data->chStores++] = CertDuplicateStore(store); ret = TRUE; } else SetLastError(ERROR_OUTOFMEMORY); return ret; }
static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to) { DWORD root_count = 0; CERT_CHAIN_ENGINE_CONFIG chainEngineConfig = { sizeof(chainEngineConfig), 0 }; HCERTCHAINENGINE engine; TRACE("\n"); CertDuplicateStore(to); engine = CRYPT_CreateChainEngine(to, CERT_SYSTEM_STORE_CURRENT_USER, &chainEngineConfig); if (engine) { PCCERT_CONTEXT cert = NULL; do { cert = CertEnumCertificatesInStore(from, cert); if (cert) { CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } }; PCCERT_CHAIN_CONTEXT chain; BOOL ret; ret = CertGetCertificateChain(engine, cert, NULL, from, &chainPara, CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL, NULL, &chain); if (!ret) TRACE("rejecting %s: %s\n", get_cert_common_name(cert), "chain creation failed"); else { DWORD allowedErrors = CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_VALID_FOR_USAGE | CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_NOT_TIME_VALID; /* The certificate chain verification only allows certain * invalid CA certs if they're installed locally: CA * certs missing the key usage extension, and CA certs * missing the basic constraints extension. Of course * there's a chicken and egg problem: we have to accept * them here in order for them to be accepted later. * Expired, locally installed certs are also allowed here, * because we don't know (yet) what date will be checked * for an item signed by one of these certs. * Thus, accept certs with any of the allowed errors. */ if (chain->TrustStatus.dwErrorStatus & ~allowedErrors) TRACE("rejecting %s: %s\n", get_cert_common_name(cert), trust_status_to_str(chain->TrustStatus.dwErrorStatus & ~CERT_TRUST_IS_UNTRUSTED_ROOT)); else { DWORD i, j; for (i = 0; i < chain->cChain; i++) for (j = 0; j < chain->rgpChain[i]->cElement; j++) if (CertAddCertificateContextToStore(to, chain->rgpChain[i]->rgpElement[j]->pCertContext, CERT_STORE_ADD_NEW, NULL)) root_count++; } CertFreeCertificateChain(chain); } } } while (cert); CertFreeCertificateChainEngine(engine); } TRACE("Added %d root certificates\n", root_count); }
static BOOL CRYPT_QueryContextObject(DWORD dwObjectType, const void *pvObject, DWORD dwExpectedContentTypeFlags, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, HCERTSTORE *phCertStore, const void **ppvContext) { CERT_BLOB fileBlob; const CERT_BLOB *blob; HCERTSTORE store; DWORD contentType; BOOL ret; switch (dwObjectType) { case CERT_QUERY_OBJECT_FILE: /* Cert, CRL, and CTL contexts can't be "embedded" in a file, so * just read the file directly */ ret = CRYPT_ReadBlobFromFile((LPCWSTR)pvObject, &fileBlob); blob = &fileBlob; break; case CERT_QUERY_OBJECT_BLOB: blob = (const CERT_BLOB *)pvObject; ret = TRUE; break; default: SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */ ret = FALSE; } if (!ret) return FALSE; store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); ret = FALSE; if (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CERT) { ret = pCertInterface->addEncodedToStore(store, X509_ASN_ENCODING, blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext); if (ret) contentType = CERT_QUERY_CONTENT_CERT; } if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CRL)) { ret = pCRLInterface->addEncodedToStore(store, X509_ASN_ENCODING, blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext); if (ret) contentType = CERT_QUERY_CONTENT_CRL; } if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_CTL)) { ret = pCTLInterface->addEncodedToStore(store, X509_ASN_ENCODING, blob->pbData, blob->cbData, CERT_STORE_ADD_ALWAYS, ppvContext); if (ret) contentType = CERT_QUERY_CONTENT_CTL; } if (ret) { if (pdwMsgAndCertEncodingType) *pdwMsgAndCertEncodingType = X509_ASN_ENCODING; if (pdwContentType) *pdwContentType = contentType; if (phCertStore) *phCertStore = CertDuplicateStore(store); } CertCloseStore(store, 0); if (blob == &fileBlob) CryptMemFree(blob->pbData); TRACE("returning %d\n", ret); return ret; }
static BOOL CRYPT_QuerySerializedContextObject(DWORD dwObjectType, const void *pvObject, DWORD dwExpectedContentTypeFlags, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, HCERTSTORE *phCertStore, const void **ppvContext) { CERT_BLOB fileBlob; const CERT_BLOB *blob; const WINE_CONTEXT_INTERFACE *contextInterface = NULL; const void *context; DWORD contextType; BOOL ret; switch (dwObjectType) { case CERT_QUERY_OBJECT_FILE: /* Cert, CRL, and CTL contexts can't be "embedded" in a file, so * just read the file directly */ ret = CRYPT_ReadBlobFromFile((LPCWSTR)pvObject, &fileBlob); blob = &fileBlob; break; case CERT_QUERY_OBJECT_BLOB: blob = (const CERT_BLOB *)pvObject; ret = TRUE; break; default: SetLastError(E_INVALIDARG); /* FIXME: is this the correct error? */ ret = FALSE; } if (!ret) return FALSE; context = CRYPT_ReadSerializedElement(blob->pbData, blob->cbData, CERT_STORE_ALL_CONTEXT_FLAG, &contextType); if (context) { DWORD contentType, certStoreOffset; ret = TRUE; switch (contextType) { case CERT_STORE_CERTIFICATE_CONTEXT: contextInterface = pCertInterface; contentType = CERT_QUERY_CONTENT_SERIALIZED_CERT; certStoreOffset = offsetof(CERT_CONTEXT, hCertStore); if (!(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_CERT)) { SetLastError(ERROR_INVALID_DATA); ret = FALSE; goto end; } break; case CERT_STORE_CRL_CONTEXT: contextInterface = pCRLInterface; contentType = CERT_QUERY_CONTENT_SERIALIZED_CRL; certStoreOffset = offsetof(CRL_CONTEXT, hCertStore); if (!(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_CRL)) { SetLastError(ERROR_INVALID_DATA); ret = FALSE; goto end; } break; case CERT_STORE_CTL_CONTEXT: contextInterface = pCTLInterface; contentType = CERT_QUERY_CONTENT_SERIALIZED_CTL; certStoreOffset = offsetof(CTL_CONTEXT, hCertStore); if (!(dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_SERIALIZED_CTL)) { SetLastError(ERROR_INVALID_DATA); ret = FALSE; goto end; } break; default: SetLastError(ERROR_INVALID_DATA); ret = FALSE; goto end; } if (pdwMsgAndCertEncodingType) *pdwMsgAndCertEncodingType = X509_ASN_ENCODING; if (pdwContentType) *pdwContentType = contentType; if (phCertStore) *phCertStore = CertDuplicateStore( *(HCERTSTORE *)((const BYTE *)context + certStoreOffset)); if (ppvContext) *ppvContext = contextInterface->duplicate(context); } end: if (contextInterface && context) contextInterface->free(context); if (blob == &fileBlob) CryptMemFree(blob->pbData); TRACE("returning %d\n", ret); return ret; }