BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore, const BYTE *pbElement, DWORD cbElement, DWORD dwAddDisposition, DWORD dwFlags, DWORD dwContextTypeFlags, DWORD *pdwContentType, const void **ppvContext) { const void *context; DWORD type; BOOL ret; TRACE("(%p, %p, %d, %08x, %08x, %08x, %p, %p)\n", hCertStore, pbElement, cbElement, dwAddDisposition, dwFlags, dwContextTypeFlags, pdwContentType, ppvContext); /* Call the internal function, then delete the hashes. Tests show this * function uses real hash values, not whatever's stored in the hash * property. */ context = CRYPT_ReadSerializedElement(pbElement, cbElement, dwContextTypeFlags, &type); if (context) { const WINE_CONTEXT_INTERFACE *contextInterface = NULL; switch (type) { case CERT_STORE_CERTIFICATE_CONTEXT: contextInterface = pCertInterface; break; case CERT_STORE_CRL_CONTEXT: contextInterface = pCRLInterface; break; case CERT_STORE_CTL_CONTEXT: contextInterface = pCTLInterface; break; default: SetLastError(E_INVALIDARG); } if (contextInterface) { contextInterface->setProp(context, CERT_HASH_PROP_ID, 0, NULL); contextInterface->setProp(context, CERT_MD5_HASH_PROP_ID, 0, NULL); contextInterface->setProp(context, CERT_SIGNATURE_HASH_PROP_ID, 0, NULL); if (pdwContentType) *pdwContentType = type; ret = contextInterface->addContextToStore(hCertStore, context, dwAddDisposition, ppvContext); contextInterface->free(context); } else ret = FALSE; } else ret = FALSE; return ret; }
static void CRYPT_RegReadSerializedFromReg(HKEY key, DWORD contextType, HCERTSTORE store) { LONG rc; DWORD index = 0; WCHAR subKeyName[MAX_PATH]; do { DWORD size = sizeof(subKeyName) / sizeof(WCHAR); rc = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL, NULL, NULL); if (!rc) { HKEY subKey; rc = RegOpenKeyExW(key, subKeyName, 0, KEY_READ, &subKey); if (!rc) { LPBYTE buf = NULL; size = 0; rc = RegQueryValueExW(subKey, BlobW, NULL, NULL, NULL, &size); if (!rc) buf = CryptMemAlloc(size); if (buf) { rc = RegQueryValueExW(subKey, BlobW, NULL, NULL, buf, &size); if (!rc) { const void *context; DWORD addedType; TRACE("Adding cert with hash %s\n", debugstr_w(subKeyName)); context = CRYPT_ReadSerializedElement(buf, size, contextType, &addedType); if (context) { const WINE_CONTEXT_INTERFACE *contextInterface; BYTE hash[20]; switch (addedType) { case CERT_STORE_CERTIFICATE_CONTEXT: contextInterface = pCertInterface; break; case CERT_STORE_CRL_CONTEXT: contextInterface = pCRLInterface; break; case CERT_STORE_CTL_CONTEXT: contextInterface = pCTLInterface; break; default: contextInterface = NULL; } if (contextInterface) { size = sizeof(hash); if (contextInterface->getProp(context, CERT_HASH_PROP_ID, hash, &size)) { WCHAR asciiHash[20 * 2 + 1]; CRYPT_HashToStr(hash, asciiHash); TRACE("comparing %s\n", debugstr_w(asciiHash)); TRACE("with %s\n", debugstr_w(subKeyName)); if (!lstrcmpW(asciiHash, subKeyName)) { TRACE("hash matches, adding\n"); contextInterface->addContextToStore( store, context, CERT_STORE_ADD_REPLACE_EXISTING, NULL); } else TRACE("hash doesn't match, ignoring\n"); } Context_Release(context_from_ptr(context)); } } } CryptMemFree(buf); } RegCloseKey(subKey); } /* Ignore intermediate errors, continue enumerating */ rc = ERROR_SUCCESS; } } while (!rc); }
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; }