void __cdecl main(void) { //------------------------------------------------------------------- // Pointer to a certificate. PCCERT_CONTEXT pCertContext = NULL; //------------------------------------------------------------------- // Declare and Initialize variables DWORD cbData = 0; BYTE* pbData = NULL; LPWSTR pwszMimeType = NULL; //------------------------------------------------------------------- // Use the helper function to get the certificate which has a logotype // extension pCertContext = MyGetCertificate(); if(pCertContext == NULL) { MyHandleError( L"The certificate with logotype extension not found.\n"); goto done; } //------------------------------------------------------------------- // This API allocates memory for pbData and pwszMimeType which has to be freed // by calling CryptMemFree() if(!CertRetrieveLogoOrBiometricInfo( pCertContext, CERT_RETRIEVE_ISSUER_LOGO, 0, // Retrieval Flags RETRIEVAL_TIMEOUT, // TimeOut in milliseconds 0, // dwFlags : reserved NULL, // Reserved for future use &pbData, &cbData, &pwszMimeType )) { MyHandleError( L"CertRetrieveLogoOrBiometricInfo failed.\n"); } else { wprintf( L"Successfully retrieved logo information \n"); } //------------------------------------------------------------------- // Clean up. done: if(pwszMimeType) CryptMemFree(pwszMimeType); if(pbData) CryptMemFree(pbData); if(pCertContext) CertFreeCertificateContext(pCertContext); } //end Main
static void CTLDataContext_Free(void *context) { PCTL_CONTEXT ctlContext = context; CryptMsgClose(ctlContext->hCryptMsg); CryptMemFree(ctlContext->pbCtlEncoded); CryptMemFree(ctlContext->pbCtlContext); LocalFree(ctlContext->pCtlInfo); }
static void test_cryptAllocate(void) { LPVOID buf; buf = CryptMemAlloc(0); ok(buf != NULL, "CryptMemAlloc failed: %08x\n", GetLastError()); CryptMemFree(buf); /* CryptMemRealloc(NULL, 0) fails pre-Vista */ buf = CryptMemAlloc(0); buf = CryptMemRealloc(buf, 1); ok(buf != NULL, "CryptMemRealloc failed: %08x\n", GetLastError()); CryptMemFree(buf); }
/* Reads any base64-encoded certificates present in fp and adds them to store. * Returns TRUE if any certificates were successfully imported. */ static BOOL import_base64_certs_from_fp(FILE *fp, HCERTSTORE store) { char line[1024]; BOOL in_cert = FALSE; struct DynamicBuffer saved_cert = { 0, 0, NULL }; int num_certs = 0; TRACE("\n"); while (fgets(line, sizeof(line), fp)) { static const char header[] = "-----BEGIN CERTIFICATE-----"; static const char trailer[] = "-----END CERTIFICATE-----"; if (!strncmp(line, header, strlen(header))) { TRACE("begin new certificate\n"); in_cert = TRUE; reset_buffer(&saved_cert); } else if (!strncmp(line, trailer, strlen(trailer))) { DWORD size; TRACE("end of certificate, adding cert\n"); in_cert = FALSE; if (CryptStringToBinaryA((char *)saved_cert.data, saved_cert.used, CRYPT_STRING_BASE64, NULL, &size, NULL, NULL)) { LPBYTE buf = CryptMemAlloc(size); if (buf) { CryptStringToBinaryA((char *)saved_cert.data, saved_cert.used, CRYPT_STRING_BASE64, buf, &size, NULL, NULL); if (CertAddEncodedCertificateToStore(store, X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_NEW, NULL)) num_certs++; CryptMemFree(buf); } } } else if (in_cert) add_line_to_buffer(&saved_cert, line); } CryptMemFree(saved_cert.data); TRACE("Read %d certs\n", num_certs); return num_certs > 0; }
static void CrlDataContext_Free(void *context) { PCRL_CONTEXT crlContext = context; CryptMemFree(crlContext->pbCrlEncoded); LocalFree(crlContext->pCrlInfo); }
context_t *Context_CreateDataContext(size_t contextSize, const context_vtbl_t *vtbl, WINECRYPT_CERTSTORE *store) { context_t *context; context = CryptMemAlloc(sizeof(context_t) + contextSize); if (!context) return NULL; context->properties = ContextPropertyList_Create(); if (!context->properties) { CryptMemFree(context); return NULL; } context->vtbl = vtbl; context->ref = 1; context->linked = NULL; store->vtbl->addref(store); context->store = store; TRACE("returning %p\n", context); return context; }
/* Opens path, which must be a directory, and imports certificates from every * file in the directory into store. * Returns TRUE if any certificates were successfully imported. */ static BOOL import_certs_from_dir(LPCSTR path, HCERTSTORE store) { BOOL ret = FALSE; DIR *dir; TRACE("(%s, %p)\n", debugstr_a(path), store); dir = opendir(path); if (dir) { size_t bufsize = strlen(path) + 1 + PATH_MAX + 1; char *filebuf = CryptMemAlloc(bufsize); if (filebuf) { struct dirent *entry; while ((entry = readdir(dir))) { if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) { snprintf(filebuf, bufsize, "%s/%s", path, entry->d_name); if (import_certs_from_path(filebuf, store, FALSE) && !ret) ret = TRUE; } } closedir(dir); CryptMemFree(filebuf); } } return ret; }
BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500, DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded, LPCSTR *ppszError) { LPWSTR x500, errorStr; BOOL ret; int len; TRACE("(%08lx, %s, %08lx, %p, %p, %p, %p)\n", dwCertEncodingType, debugstr_a(pszX500), dwStrType, pvReserved, pbEncoded, pcbEncoded, ppszError); len = MultiByteToWideChar(CP_ACP, 0, pszX500, -1, NULL, 0); x500 = CryptMemAlloc(len * sizeof(WCHAR)); if (x500) { MultiByteToWideChar(CP_ACP, 0, pszX500, -1, x500, len); ret = CertStrToNameW(dwCertEncodingType, x500, dwStrType, pvReserved, pbEncoded, pcbEncoded, ppszError ? (LPCWSTR *)&errorStr : NULL); if (ppszError) { DWORD i; *ppszError = pszX500; for (i = 0; i < errorStr - x500; i++) CharNextA(*ppszError); } CryptMemFree(x500); } else ret = FALSE; return ret; }
static BOOL CRYPT_SerializeContextsToStream(SerializedOutputFunc output, void *handle, const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE store) { const void *context = NULL; BOOL ret; do { context = contextInterface->enumContextsInStore(store, context); if (context) { DWORD size = 0; LPBYTE buf = NULL; ret = contextInterface->serialize(context, 0, NULL, &size); if (size) buf = CryptMemAlloc(size); if (buf) { ret = contextInterface->serialize(context, 0, buf, &size); if (ret) ret = output(handle, buf, size); } CryptMemFree(buf); } else ret = TRUE; } while (ret && context != NULL); if (context) contextInterface->free(context); return ret; }
static void CRL_free(context_t *context) { crl_t *crl = (crl_t*)context; CryptMemFree(crl->ctx.pbCrlEncoded); LocalFree(crl->ctx.pCrlInfo); }
static PWINECRYPT_CERTSTORE CRYPT_SysOpenStoreA(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara) { int len; PWINECRYPT_CERTSTORE ret = NULL; TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_a(pvPara)); if (!pvPara) { SetLastError(ERROR_FILE_NOT_FOUND); return NULL; } len = MultiByteToWideChar(CP_ACP, 0, pvPara, -1, NULL, 0); if (len) { LPWSTR storeName = CryptMemAlloc(len * sizeof(WCHAR)); if (storeName) { MultiByteToWideChar(CP_ACP, 0, pvPara, -1, storeName, len); ret = CRYPT_SysOpenStoreW(hCryptProv, dwFlags, storeName); CryptMemFree(storeName); } } return ret; }
static void WINAPI CRYPT_FileCloseStore(HCERTSTORE hCertStore, DWORD dwFlags) { PWINE_FILESTOREINFO store = hCertStore; TRACE("(%p, %08x)\n", store, dwFlags); if (store->dirty) CertSaveStore(store->memStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0); CloseHandle(store->file); CryptMemFree(store); }
BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500, DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded, LPCSTR *ppszError) { BOOL ret; int len; TRACE("(%08x, %s, %08x, %p, %p, %p, %p)\n", dwCertEncodingType, debugstr_a(pszX500), dwStrType, pvReserved, pbEncoded, pcbEncoded, ppszError); len = MultiByteToWideChar(CP_ACP, 0, pszX500, -1, NULL, 0); if (len) { LPWSTR x500, errorStr; if ((x500 = CryptMemAlloc(len * sizeof(WCHAR)))) { MultiByteToWideChar(CP_ACP, 0, pszX500, -1, x500, len); ret = CertStrToNameW(dwCertEncodingType, x500, dwStrType, pvReserved, pbEncoded, pcbEncoded, ppszError ? (LPCWSTR *)&errorStr : NULL); if (ppszError) { if (!ret) { DWORD i; *ppszError = pszX500; for (i = 0; i < errorStr - x500; i++) *ppszError = CharNextA(*ppszError); } else *ppszError = NULL; } CryptMemFree(x500); } else { SetLastError(ERROR_OUTOFMEMORY); ret = FALSE; } } else { SetLastError(CRYPT_E_INVALID_X500_STRING); if (ppszError) *ppszError = pszX500; ret = FALSE; } return ret; }
/* Encodes the string represented by value as the string type type into the * CERT_NAME_BLOB output. If there is an error and ppszError is not NULL, * *ppszError is set to the first failing character. If there is no error, * output's pbData must be freed with LocalFree. */ static BOOL CRYPT_EncodeValueWithType(DWORD dwCertEncodingType, const struct X500TokenW *value, PCERT_NAME_BLOB output, DWORD type, LPCWSTR *ppszError) { CERT_NAME_VALUE nameValue = { type, { 0, NULL } }; BOOL ret = TRUE; if (value->end > value->start) { nameValue.Value.pbData = CryptMemAlloc((value->end - value->start) * sizeof(WCHAR)); if (!nameValue.Value.pbData) { SetLastError(ERROR_OUTOFMEMORY); ret = FALSE; } } if (ret) { if (value->end > value->start) { DWORD i; LPWSTR ptr = (LPWSTR)nameValue.Value.pbData; for (i = 0; i < value->end - value->start; i++) { *ptr++ = value->start[i]; if (value->start[i] == '"') i++; } nameValue.Value.cbData = (LPBYTE)ptr - nameValue.Value.pbData; } ret = CryptEncodeObjectEx(dwCertEncodingType, X509_UNICODE_NAME_VALUE, &nameValue, CRYPT_ENCODE_ALLOC_FLAG, NULL, &output->pbData, &output->cbData); if (!ret && ppszError) { if (type == CERT_RDN_NUMERIC_STRING && GetLastError() == CRYPT_E_INVALID_NUMERIC_STRING) *ppszError = value->start + output->cbData; else if (type == CERT_RDN_PRINTABLE_STRING && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING) *ppszError = value->start + output->cbData; else if (type == CERT_RDN_IA5_STRING && GetLastError() == CRYPT_E_INVALID_IA5_STRING) *ppszError = value->start + output->cbData; } CryptMemFree(nameValue.Value.pbData); } return ret; }
static BOOL CRYPT_RegWriteToReg(PWINE_REGSTOREINFO store) { static const WCHAR * const subKeys[] = { CertsW, CRLsW, CTLsW }; const WINE_CONTEXT_INTERFACE * const interfaces[] = { pCertInterface, pCRLInterface, pCTLInterface }; struct list *listToDelete[] = { &store->certsToDelete, &store->crlsToDelete, &store->ctlsToDelete }; BOOL ret = TRUE; DWORD i; for (i = 0; ret && i < sizeof(subKeys) / sizeof(subKeys[0]); i++) { HKEY key; LONG rc = RegCreateKeyExW(store->key, subKeys[i], 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL); if (!rc) { if (listToDelete[i]) { PWINE_HASH_TO_DELETE toDelete, next; WCHAR asciiHash[20 * 2 + 1]; EnterCriticalSection(&store->cs); LIST_FOR_EACH_ENTRY_SAFE(toDelete, next, listToDelete[i], WINE_HASH_TO_DELETE, entry) { LONG rc; CRYPT_HashToStr(toDelete->hash, asciiHash); TRACE("Removing %s\n", debugstr_w(asciiHash)); rc = RegDeleteKeyW(key, asciiHash); if (rc != ERROR_SUCCESS && rc != ERROR_FILE_NOT_FOUND) { SetLastError(rc); ret = FALSE; } list_remove(&toDelete->entry); CryptMemFree(toDelete); } LeaveCriticalSection(&store->cs); } ret = CRYPT_SerializeContextsToReg(key, interfaces[i], store->memStore); RegCloseKey(key); } else {
void Context_Free(context_t *context) { TRACE("(%p)\n", context); assert(!context->ref); if (!context->linked) { ContextPropertyList_Free(context->properties); context->vtbl->free(context); }else { Context_Release(context->linked); } CryptMemFree(context); }
static BOOL CRYPT_ReadBlobFromFile(HANDLE file, PCERT_BLOB blob) { BOOL ret = TRUE; blob->cbData = GetFileSize(file, NULL); if (blob->cbData) { blob->pbData = CryptMemAlloc(blob->cbData); if (blob->pbData) { DWORD read; ret = ReadFile(file, blob->pbData, blob->cbData, &read, NULL) && read == blob->cbData; if (!ret) CryptMemFree(blob->pbData); } } return ret; }
PCCRL_CONTEXT WINAPI CertCreateCRLContext(DWORD dwCertEncodingType, const BYTE* pbCrlEncoded, DWORD cbCrlEncoded) { PCRL_CONTEXT crl = NULL; BOOL ret; PCRL_INFO crlInfo = NULL; DWORD size = 0; TRACE("(%08x, %p, %d)\n", dwCertEncodingType, pbCrlEncoded, cbCrlEncoded); if ((dwCertEncodingType & CERT_ENCODING_TYPE_MASK) != X509_ASN_ENCODING) { SetLastError(E_INVALIDARG); return NULL; } ret = CryptDecodeObjectEx(dwCertEncodingType, X509_CERT_CRL_TO_BE_SIGNED, pbCrlEncoded, cbCrlEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &crlInfo, &size); if (ret) { BYTE *data = NULL; crl = Context_CreateDataContext(sizeof(CRL_CONTEXT)); if (!crl) goto end; data = CryptMemAlloc(cbCrlEncoded); if (!data) { CryptMemFree(crl); crl = NULL; goto end; } memcpy(data, pbCrlEncoded, cbCrlEncoded); crl->dwCertEncodingType = dwCertEncodingType; crl->pbCrlEncoded = data; crl->cbCrlEncoded = cbCrlEncoded; crl->pCrlInfo = crlInfo; crl->hCertStore = 0; } end: return crl; }
DWORD WINAPI CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, void *pvTypePara, LPSTR pszNameString, DWORD cchNameString) { DWORD ret; TRACE("(%p, %ld, %08lx, %p, %p, %ld)\n", pCertContext, dwType, dwFlags, pvTypePara, pszNameString, cchNameString); if (pszNameString) { LPWSTR wideName; DWORD nameLen; nameLen = CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0); wideName = CryptMemAlloc(nameLen * sizeof(WCHAR)); if (wideName) { CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, wideName, nameLen); nameLen = WideCharToMultiByte(CP_ACP, 0, wideName, nameLen, pszNameString, cchNameString, NULL, NULL); if (nameLen <= cchNameString) ret = nameLen; else { pszNameString[cchNameString - 1] = '\0'; ret = cchNameString; } CryptMemFree(wideName); } else { *pszNameString = '\0'; ret = 1; } } else ret = CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara, NULL, 0); return ret; }
/* Opens path, which must be a directory, and imports certificates from every * file in the directory into store. * Returns TRUE if any certificates were successfully imported. */ static BOOL import_certs_from_dir(LPCSTR path, HCERTSTORE store) { #ifdef HAVE_READDIR BOOL ret = FALSE; DIR *dir; TRACE("(%s, %p)\n", debugstr_a(path), store); dir = opendir(path); if (dir) { size_t path_len = strlen(path), bufsize = 0; char *filebuf = NULL; struct dirent *entry; while ((entry = readdir(dir))) { if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) { size_t name_len = strlen(entry->d_name); if (!check_buffer_resize(&filebuf, &bufsize, path_len + 1 + name_len + 1)) { ERR("Path buffer (re)allocation failed with out of memory condition\n"); break; } snprintf(filebuf, bufsize, "%s/%s", path, entry->d_name); if (import_certs_from_path(filebuf, store, FALSE) && !ret) ret = TRUE; } } CryptMemFree(filebuf); closedir(dir); } return ret; #else FIXME("not implemented without readdir available\n"); return FALSE; #endif }
BOOL CRYPT_SerializeContextsToReg(HKEY key, DWORD flags, const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE memStore) { const void *context = NULL; BOOL ret; do { context = contextInterface->enumContextsInStore(memStore, context); if (context) { BYTE hash[20]; DWORD hashSize = sizeof(hash); ret = contextInterface->getProp(context, CERT_HASH_PROP_ID, hash, &hashSize); if (ret) { DWORD size = 0; LPBYTE buf = NULL; ret = contextInterface->serialize(context, 0, NULL, &size); if (size) buf = CryptMemAlloc(size); if (buf) { ret = contextInterface->serialize(context, 0, buf, &size); if (ret) ret = CRYPT_WriteSerializedToReg(key, flags, hash, buf, size); } CryptMemFree(buf); } } else ret = TRUE; } while (ret && context != NULL); if (context) Context_Release(context_from_ptr(context)); return ret; }
static CERT_INFO *CRYPT_GetSignerCertInfoFromMsg(HCRYPTMSG msg, DWORD dwSignerIndex) { CERT_INFO *certInfo = NULL; DWORD size; if (CryptMsgGetParam(msg, CMSG_SIGNER_CERT_INFO_PARAM, dwSignerIndex, NULL, &size)) { certInfo = CryptMemAlloc(size); if (certInfo) { if (!CryptMsgGetParam(msg, CMSG_SIGNER_CERT_INFO_PARAM, dwSignerIndex, certInfo, &size)) { CryptMemFree(certInfo); certInfo = NULL; } } } else SetLastError(CRYPT_E_UNEXPECTED_MSG_TYPE); return certInfo; }
BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500, DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded, LPCWSTR *ppszError) { CERT_NAME_INFO info = { 0, NULL }; LPCWSTR str; struct KeynameKeeper keeper; DWORD i, error = ERROR_SUCCESS; BOOL ret = TRUE; TRACE("(%08lx, %s, %08lx, %p, %p, %p, %p)\n", dwCertEncodingType, debugstr_w(pszX500), dwStrType, pvReserved, pbEncoded, pcbEncoded, ppszError); CRYPT_InitializeKeynameKeeper(&keeper); str = pszX500; while (str && *str && !error && ret) { struct X500TokenW token; error = CRYPT_GetNextKeyW(str, &token, ppszError); if (!error && token.start) { PCCRYPT_OID_INFO keyOID; CRYPT_KeynameKeeperFromTokenW(&keeper, &token); keyOID = CryptFindOIDInfo(CRYPT_OID_INFO_NAME_KEY, keeper.keyName, CRYPT_RDN_ATTR_OID_GROUP_ID); if (!keyOID) { if (ppszError) *ppszError = token.start; error = CRYPT_E_INVALID_X500_STRING; } else { str = token.end; while (isspace(*str)) str++; if (*str != '=') { if (ppszError) *ppszError = str; error = CRYPT_E_INVALID_X500_STRING; } else { static const WCHAR commaSep[] = { ',',0 }; static const WCHAR semiSep[] = { ';',0 }; static const WCHAR crlfSep[] = { '\r','\n',0 }; static const WCHAR allSeps[] = { ',',';','\r','\n',0 }; LPCWSTR sep; str++; if (dwStrType & CERT_NAME_STR_COMMA_FLAG) sep = commaSep; else if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG) sep = semiSep; else if (dwStrType & CERT_NAME_STR_CRLF_FLAG) sep = crlfSep; else sep = allSeps; error = CRYPT_GetNextValueW(str, dwStrType, sep, &token, ppszError); if (!error) { str = token.end; ret = CRYPT_ValueToRDN(dwCertEncodingType, &info, keyOID, &token, ppszError); } } } } } CRYPT_FreeKeynameKeeper(&keeper); if (!error) { ret = CryptEncodeObjectEx(dwCertEncodingType, X509_NAME, &info, 0, NULL, pbEncoded, pcbEncoded); for (i = 0; i < info.cRDN; i++) { DWORD j; for (j = 0; j < info.rgRDN[i].cRDNAttr; j++) LocalFree(info.rgRDN[i].rgRDNAttr[j].Value.pbData); CryptMemFree(info.rgRDN[i].rgRDNAttr); } CryptMemFree(info.rgRDN); } else { SetLastError(error); ret = FALSE; } return ret; }
static void CRYPT_FreeKeynameKeeper(struct KeynameKeeper *keeper) { if (keeper->keyName != keeper->buf) CryptMemFree(keeper->keyName); }
static BOOL CRYPT_SavePKCSToMem(HCERTSTORE store, DWORD dwMsgAndCertEncodingType, void *handle) { CERT_BLOB *blob = handle; CRYPT_SIGNED_INFO signedInfo = { 0 }; PCCERT_CONTEXT cert = NULL; PCCRL_CONTEXT crl = NULL; DWORD size; BOOL ret = TRUE; TRACE("(%d, %p)\n", blob->pbData ? blob->cbData : 0, blob->pbData); do { cert = CertEnumCertificatesInStore(store, cert); if (cert) signedInfo.cCertEncoded++; } while (cert); if (signedInfo.cCertEncoded) { signedInfo.rgCertEncoded = CryptMemAlloc( signedInfo.cCertEncoded * sizeof(CERT_BLOB)); if (!signedInfo.rgCertEncoded) { SetLastError(ERROR_OUTOFMEMORY); ret = FALSE; } else { DWORD i = 0; do { cert = CertEnumCertificatesInStore(store, cert); if (cert) { signedInfo.rgCertEncoded[i].cbData = cert->cbCertEncoded; signedInfo.rgCertEncoded[i].pbData = cert->pbCertEncoded; i++; } } while (cert); } } do { crl = CertEnumCRLsInStore(store, crl); if (crl) signedInfo.cCrlEncoded++; } while (crl); if (signedInfo.cCrlEncoded) { signedInfo.rgCrlEncoded = CryptMemAlloc( signedInfo.cCrlEncoded * sizeof(CERT_BLOB)); if (!signedInfo.rgCrlEncoded) { SetLastError(ERROR_OUTOFMEMORY); ret = FALSE; } else { DWORD i = 0; do { crl = CertEnumCRLsInStore(store, crl); if (crl) { signedInfo.rgCrlEncoded[i].cbData = crl->cbCrlEncoded; signedInfo.rgCrlEncoded[i].pbData = crl->pbCrlEncoded; i++; } } while (crl); } } if (ret) { ret = CRYPT_AsnEncodeCMSSignedInfo(&signedInfo, NULL, &size); if (ret) { if (!blob->pbData) blob->cbData = size; else if (blob->cbData < size) { blob->cbData = size; SetLastError(ERROR_MORE_DATA); ret = FALSE; } else { blob->cbData = size; ret = CRYPT_AsnEncodeCMSSignedInfo(&signedInfo, blob->pbData, &blob->cbData); } } } CryptMemFree(signedInfo.rgCertEncoded); CryptMemFree(signedInfo.rgCrlEncoded); TRACE("returning %d\n", ret); return ret; }
static BOOL CRYPT_ReadSerializedStore(void *handle, read_serialized_func read_func, HCERTSTORE store) { BYTE fileHeaderBuf[sizeof(fileHeader)]; DWORD read; BOOL ret; /* Failure reading is non-critical, we'll leave the store empty */ ret = read_func(handle, fileHeaderBuf, sizeof(fileHeaderBuf), &read); if (ret) { if (!read) ; /* an empty file is okay */ else if (read != sizeof(fileHeaderBuf)) ret = FALSE; else if (!memcmp(fileHeaderBuf, fileHeader, read)) { WINE_CERT_PROP_HEADER propHdr; const void *context = NULL; const WINE_CONTEXT_INTERFACE *contextInterface = NULL; LPBYTE buf = NULL; DWORD bufSize = 0; do { ret = read_func(handle, &propHdr, sizeof(propHdr), &read); if (ret && read == sizeof(propHdr)) { if (contextInterface && context && (propHdr.propID == CERT_CERT_PROP_ID || propHdr.propID == CERT_CRL_PROP_ID || propHdr.propID == CERT_CTL_PROP_ID)) { /* We have a new context, so free the existing one */ contextInterface->free(context); } if (propHdr.cb > bufSize) { /* Not reusing realloc, because the old data aren't * needed any longer. */ CryptMemFree(buf); buf = CryptMemAlloc(propHdr.cb); bufSize = propHdr.cb; } if (!propHdr.cb) ; /* Property is empty, nothing to do */ else if (buf) { ret = read_func(handle, buf, propHdr.cb, &read); if (ret && read == propHdr.cb) { if (propHdr.propID == CERT_CERT_PROP_ID) { contextInterface = pCertInterface; ret = contextInterface->addEncodedToStore(store, X509_ASN_ENCODING, buf, read, CERT_STORE_ADD_NEW, &context); } else if (propHdr.propID == CERT_CRL_PROP_ID) { contextInterface = pCRLInterface; ret = contextInterface->addEncodedToStore(store, X509_ASN_ENCODING, buf, read, CERT_STORE_ADD_NEW, &context); } else if (propHdr.propID == CERT_CTL_PROP_ID) { contextInterface = pCTLInterface; ret = contextInterface->addEncodedToStore(store, X509_ASN_ENCODING, buf, read, CERT_STORE_ADD_NEW, &context); } else { if (!contextInterface) { WARN("prop id %d before a context id\n", propHdr.propID); ret = FALSE; } else ret = CRYPT_ReadContextProp( contextInterface, context, &propHdr, buf, read); } } } else ret = FALSE; } } while (ret && read > 0 && propHdr.cb); if (contextInterface && context) { /* Free the last context added */ contextInterface->free(context); } CryptMemFree(buf); ret = TRUE; } else ret = FALSE; } else ret = TRUE; return ret; }
static BOOL CRYPT_SerializeStoreElement(const void *context, const BYTE *encodedContext, DWORD cbEncodedContext, DWORD contextPropID, PCWINE_CONTEXT_INTERFACE contextInterface, DWORD dwFlags, BOOL omitHashes, BYTE *pbElement, DWORD *pcbElement) { BOOL ret; TRACE("(%p, %p, %08x, %d, %p, %p)\n", context, contextInterface, dwFlags, omitHashes, pbElement, pcbElement); if (context) { DWORD bytesNeeded = sizeof(WINE_CERT_PROP_HEADER) + cbEncodedContext; DWORD prop = 0; ret = TRUE; do { prop = contextInterface->enumProps(context, prop); if (prop && (!omitHashes || !IS_CERT_HASH_PROP_ID(prop))) { DWORD propSize = 0; ret = contextInterface->getProp(context, prop, NULL, &propSize); if (ret) bytesNeeded += sizeof(WINE_CERT_PROP_HEADER) + propSize; } } while (ret && prop != 0); if (!pbElement) { *pcbElement = bytesNeeded; ret = TRUE; } else if (*pcbElement < bytesNeeded) { *pcbElement = bytesNeeded; SetLastError(ERROR_MORE_DATA); ret = FALSE; } else { PWINE_CERT_PROP_HEADER hdr; DWORD bufSize = 0; LPBYTE buf = NULL; prop = 0; do { prop = contextInterface->enumProps(context, prop); if (prop && (!omitHashes || !IS_CERT_HASH_PROP_ID(prop))) { DWORD propSize = 0; ret = contextInterface->getProp(context, prop, NULL, &propSize); if (ret) { if (bufSize < propSize) { if (buf) buf = CryptMemRealloc(buf, propSize); else buf = CryptMemAlloc(propSize); bufSize = propSize; } if (buf) { ret = contextInterface->getProp(context, prop, buf, &propSize); if (ret) { hdr = (PWINE_CERT_PROP_HEADER)pbElement; hdr->propID = prop; hdr->unknown = 1; hdr->cb = propSize; pbElement += sizeof(WINE_CERT_PROP_HEADER); if (propSize) { memcpy(pbElement, buf, propSize); pbElement += propSize; } } } else ret = FALSE; } } } while (ret && prop != 0); CryptMemFree(buf); hdr = (PWINE_CERT_PROP_HEADER)pbElement; hdr->propID = contextPropID; hdr->unknown = 1; hdr->cb = cbEncodedContext; memcpy(pbElement + sizeof(WINE_CERT_PROP_HEADER), encodedContext, cbEncodedContext); } } else ret = FALSE; return ret; }
void CRYPT_FreeStore(PWINECRYPT_CERTSTORE store) { if (store->properties) ContextPropertyList_Free(store->properties); CryptMemFree(store); }
static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara) { PWINECRYPT_CERTSTORE store = NULL; HCRYPTMSG msg = (HCRYPTMSG)pvPara; PWINECRYPT_CERTSTORE memStore; TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); if (memStore) { BOOL ret; DWORD size, count, i; size = sizeof(count); ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size); for (i = 0; ret && i < count; i++) { size = 0; ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size); if (ret) { LPBYTE buf = CryptMemAlloc(size); if (buf) { ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size); if (ret) ret = CertAddEncodedCertificateToStore(memStore, X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS, NULL); CryptMemFree(buf); } } } size = sizeof(count); ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size); for (i = 0; ret && i < count; i++) { size = 0; ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size); if (ret) { LPBYTE buf = CryptMemAlloc(size); if (buf) { ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size); if (ret) ret = CertAddEncodedCRLToStore(memStore, X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS, NULL); CryptMemFree(buf); } } } if (ret) { CERT_STORE_PROV_INFO provInfo = { 0 }; provInfo.cbSize = sizeof(provInfo); provInfo.cStoreProvFunc = sizeof(msgProvFuncs) / sizeof(msgProvFuncs[0]); provInfo.rgpvStoreProvFunc = msgProvFuncs; provInfo.hStoreProv = CryptMsgDuplicate(msg); store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo); /* Msg store doesn't need crypto provider, so close it */ if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG)) CryptReleaseContext(hCryptProv, 0); } else CertCloseStore(memStore, 0); } TRACE("returning %p\n", store); return store; }
static PWINECRYPT_CERTSTORE CRYPT_SysRegOpenStoreW(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara) { static const WCHAR fmt[] = { '%','s','\\','%','s',0 }; LPCWSTR storeName = pvPara; LPWSTR storePath; PWINECRYPT_CERTSTORE store = NULL; HKEY root; LPCWSTR base; TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(pvPara)); if (!pvPara) { SetLastError(E_INVALIDARG); return NULL; } /* FIXME: In Windows, the root store (even the current user location) is * protected: adding to it or removing from it present a user interface, * and the keys are owned by the system process, not the current user. * Wine's registry doesn't implement access controls, so a similar * mechanism isn't possible yet. */ if ((dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) == CERT_SYSTEM_STORE_LOCAL_MACHINE && !lstrcmpiW(storeName, rootW)) return CRYPT_RootOpenStore(hCryptProv, dwFlags); switch (dwFlags & CERT_SYSTEM_STORE_LOCATION_MASK) { case CERT_SYSTEM_STORE_LOCAL_MACHINE: root = HKEY_LOCAL_MACHINE; base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH; break; case CERT_SYSTEM_STORE_CURRENT_USER: root = HKEY_CURRENT_USER; base = CERT_LOCAL_MACHINE_SYSTEM_STORE_REGPATH; break; case CERT_SYSTEM_STORE_CURRENT_SERVICE: /* hklm\Software\Microsoft\Cryptography\Services\servicename\ * SystemCertificates */ FIXME("CERT_SYSTEM_STORE_CURRENT_SERVICE, %s: stub\n", debugstr_w(storeName)); return NULL; case CERT_SYSTEM_STORE_SERVICES: /* hklm\Software\Microsoft\Cryptography\Services\servicename\ * SystemCertificates */ FIXME("CERT_SYSTEM_STORE_SERVICES, %s: stub\n", debugstr_w(storeName)); return NULL; case CERT_SYSTEM_STORE_USERS: /* hku\user sid\Software\Microsoft\SystemCertificates */ FIXME("CERT_SYSTEM_STORE_USERS, %s: stub\n", debugstr_w(storeName)); return NULL; case CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY: root = HKEY_CURRENT_USER; base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH; break; case CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY: root = HKEY_LOCAL_MACHINE; base = CERT_GROUP_POLICY_SYSTEM_STORE_REGPATH; break; case CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE: /* hklm\Software\Microsoft\EnterpriseCertificates */ FIXME("CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, %s: stub\n", debugstr_w(storeName)); return NULL; default: SetLastError(E_INVALIDARG); return NULL; } storePath = CryptMemAlloc((lstrlenW(base) + lstrlenW(storeName) + 2) * sizeof(WCHAR)); if (storePath) { LONG rc; HKEY key; REGSAM sam = dwFlags & CERT_STORE_READONLY_FLAG ? KEY_READ : KEY_ALL_ACCESS; wsprintfW(storePath, fmt, base, storeName); if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG) rc = RegOpenKeyExW(root, storePath, 0, sam, &key); else { DWORD disp; rc = RegCreateKeyExW(root, storePath, 0, NULL, 0, sam, NULL, &key, &disp); if (!rc && dwFlags & CERT_STORE_CREATE_NEW_FLAG && disp == REG_OPENED_EXISTING_KEY) { RegCloseKey(key); rc = ERROR_FILE_EXISTS; } } if (!rc) { store = CRYPT_RegOpenStore(hCryptProv, dwFlags, key); RegCloseKey(key); } else SetLastError(rc); CryptMemFree(storePath); } return store; }