static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags, DWORD dwCtrlType, void const *pvCtrlPara) { PWINE_FILESTOREINFO store = hCertStore; BOOL ret; TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType, pvCtrlPara); switch (dwCtrlType) { case CERT_STORE_CTRL_RESYNC: store->dirty = FALSE; if (store->type == CERT_STORE_SAVE_AS_STORE) { HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); /* FIXME: if I could translate a handle to a path, I could use * CryptQueryObject instead, but there's no API to do so yet. */ ret = CRYPT_ReadSerializedStoreFromFile(store->file, memStore); if (ret) I_CertUpdateStore(store->memStore, memStore, 0, 0); CertCloseStore(memStore, 0); } else if (store->type == CERT_STORE_SAVE_AS_PKCS7) { CERT_BLOB blob = { 0, NULL }; ret = CRYPT_ReadBlobFromFile(store->file, &blob); if (ret) { HCERTSTORE messageStore; ret = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED, CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL, &messageStore, NULL, NULL); I_CertUpdateStore(store->memStore, messageStore, 0, 0); CertCloseStore(messageStore, 0); CryptMemFree(blob.pbData); } } else { WARN("unknown type %d\n", store->type); ret = FALSE; } break; case CERT_STORE_CTRL_COMMIT: if (!(store->dwOpenFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); ret = FALSE; } else if (store->dirty) ret = CertSaveStore(store->memStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0); else ret = TRUE; break; default: FIXME("%d: stub\n", dwCtrlType); ret = FALSE; } return ret; }
/* Used to decode non-embedded messages */ static BOOL CRYPT_QueryMessageObject(DWORD dwObjectType, const void *pvObject, DWORD dwExpectedContentTypeFlags, DWORD *pdwMsgAndCertEncodingType, DWORD *pdwContentType, HCERTSTORE *phCertStore, HCRYPTMSG *phMsg) { CERT_BLOB fileBlob; const CERT_BLOB *blob; BOOL ret; HCRYPTMSG msg = NULL; DWORD encodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; switch (dwObjectType) { case CERT_QUERY_OBJECT_FILE: /* This isn't an embedded PKCS7 message, 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; ret = FALSE; /* Try it first as a PKCS content info */ if ((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED) || (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED)) { msg = CryptMsgOpenToDecode(encodingType, 0, 0, 0, NULL, NULL); if (msg) { ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE); if (ret) { DWORD type, len = sizeof(type); ret = CryptMsgGetParam(msg, CMSG_TYPE_PARAM, 0, &type, &len); if (ret) { if ((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)) { if (type != CMSG_SIGNED) { SetLastError(ERROR_INVALID_DATA); ret = FALSE; } else if (pdwContentType) *pdwContentType = CERT_QUERY_CONTENT_PKCS7_SIGNED; } else if ((dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED)) { if (type != CMSG_DATA) { SetLastError(ERROR_INVALID_DATA); ret = FALSE; } else if (pdwContentType) *pdwContentType = CERT_QUERY_CONTENT_PKCS7_UNSIGNED; } } } if (!ret) { CryptMsgClose(msg); msg = NULL; } } } /* Failing that, try explicitly typed messages */ if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)) { msg = CryptMsgOpenToDecode(encodingType, 0, CMSG_SIGNED, 0, NULL, NULL); if (msg) { ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE); if (!ret) { CryptMsgClose(msg); msg = NULL; } } if (msg && pdwContentType) *pdwContentType = CERT_QUERY_CONTENT_PKCS7_SIGNED; } if (!ret && (dwExpectedContentTypeFlags & CERT_QUERY_CONTENT_FLAG_PKCS7_UNSIGNED)) { msg = CryptMsgOpenToDecode(encodingType, 0, CMSG_DATA, 0, NULL, NULL); if (msg) { ret = CryptMsgUpdate(msg, blob->pbData, blob->cbData, TRUE); if (!ret) { CryptMsgClose(msg); msg = NULL; } } if (msg && pdwContentType) *pdwContentType = CERT_QUERY_CONTENT_PKCS7_UNSIGNED; } if (pdwMsgAndCertEncodingType) *pdwMsgAndCertEncodingType = encodingType; if (msg) { if (phMsg) *phMsg = msg; if (phCertStore) *phCertStore = CertOpenStore(CERT_STORE_PROV_MSG, encodingType, 0, 0, msg); } if (blob == &fileBlob) CryptMemFree(blob->pbData); TRACE("returning %d\n", ret); return ret; }
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; }