static BOOL DigiCrypt_GetContainerFromCert(PCCERT_CONTEXT pCertContext, char *psResult, int iMaxResLen) { BOOL fRes = FALSE; CRYPT_KEY_PROV_INFO *poKeyInfo; DWORD pcbData; DWORD dwLen; if (pCertContext == NULL || psResult == 0) return(fRes); fRes = CertGetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID,NULL,&pcbData); if (fRes == TRUE) { poKeyInfo = (CRYPT_KEY_PROV_INFO *)malloc(pcbData); if (poKeyInfo != NULL) { fRes = CertGetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID,poKeyInfo,&pcbData); if (fRes == TRUE) { if (poKeyInfo->pwszContainerName != NULL) { dwLen = WideCharToMultiByte(CP_ACP,0,poKeyInfo->pwszContainerName,-1,psResult,iMaxResLen,NULL,NULL); } else fRes = FALSE; } free(poKeyInfo); } } return(fRes); }
//************************************************** // Checks of older registered certificates are not // still bound to the CSP when the minidriver is used //************************************************** BOOL ProviderNameCorrect (PCCERT_CONTEXT pCertContext ) { unsigned long dwPropId= CERT_KEY_PROV_INFO_PROP_ID; DWORD cbData = 0; CRYPT_KEY_PROV_INFO * pCryptKeyProvInfo; if (!UseMinidriver()) return TRUE; if(!(CertGetCertificateContextProperty( pCertContext, // A pointer to the certificate where the property will be set. dwPropId, // An identifier of the property to get. NULL, // NULL on the first call to get the length. &cbData))) // The number of bytes that must be allocated for the structure. { if (GetLastError() != CRYPT_E_NOT_FOUND) // The certificate does not have the specified property. return FALSE; } if(!(pCryptKeyProvInfo = (CRYPT_KEY_PROV_INFO *)malloc(cbData))) { return TRUE; } if(CertGetCertificateContextProperty(pCertContext, dwPropId, pCryptKeyProvInfo, &cbData)) { if (!wcscmp(pCryptKeyProvInfo->pwszProvName, L"Belgium Identity Card CSP")) return FALSE; } return TRUE; }
/* Returns TRUE if pCert is not in the Disallowed system store, or FALSE if it * is. */ static BOOL CRYPTDLG_IsCertAllowed(PCCERT_CONTEXT pCert) { BOOL ret; BYTE hash[20]; DWORD size = sizeof(hash); if ((ret = CertGetCertificateContextProperty(pCert, CERT_SIGNATURE_HASH_PROP_ID, hash, &size))) { static const WCHAR disallowedW[] = { 'D','i','s','a','l','l','o','w','e','d',0 }; HCERTSTORE disallowed = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, X509_ASN_ENCODING, 0, CERT_SYSTEM_STORE_CURRENT_USER, disallowedW); if (disallowed) { PCCERT_CONTEXT found = CertFindCertificateInStore(disallowed, X509_ASN_ENCODING, 0, CERT_FIND_SIGNATURE_HASH, hash, NULL); if (found) { ret = FALSE; CertFreeCertificateContext(found); } CertCloseStore(disallowed, 0); } } return ret; }
unsigned int ma_tls_get_finger_print(MARIADB_TLS *ctls, unsigned char *fp, unsigned int len) { SC_CTX *sctx= (SC_CTX *)ctls->ssl; PCCERT_CONTEXT pRemoteCertContext = NULL; if (QueryContextAttributes(&sctx->ctxt, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&pRemoteCertContext) != SEC_E_OK) return 0; CertGetCertificateContextProperty(pRemoteCertContext, CERT_HASH_PROP_ID, fp, (DWORD *)&len); return len; }
bool mod_crypto::getKiwiKeyProvInfo(PCCERT_CONTEXT certCTX, KIWI_KEY_PROV_INFO * keyProvInfo) { bool reussite = false; DWORD taille = 0; if(CertGetCertificateContextProperty(certCTX, CERT_KEY_PROV_INFO_PROP_ID, NULL, &taille)) { BYTE * monBuffer = new BYTE[taille]; if(reussite = (CertGetCertificateContextProperty(certCTX, CERT_KEY_PROV_INFO_PROP_ID, monBuffer, &taille) != 0)) { CRYPT_KEY_PROV_INFO * mesInfos = reinterpret_cast<CRYPT_KEY_PROV_INFO *>(monBuffer); keyProvInfo->pwszProvName.assign(mesInfos->pwszProvName ? mesInfos->pwszProvName : L"(null)"); keyProvInfo->pwszContainerName.assign(mesInfos->pwszContainerName ? mesInfos->pwszContainerName : L"(null)"); keyProvInfo->cProvParam = mesInfos->cProvParam; keyProvInfo->dwFlags = mesInfos->dwFlags; keyProvInfo->dwKeySpec = mesInfos->dwKeySpec; keyProvInfo->dwProvType = mesInfos->dwProvType; } delete[] monBuffer; } return reussite; }
char * capi_cert_get_fname(CAPI_CTX *ctx, PCCERT_CONTEXT cert) { LPWSTR wfname; DWORD dlen; CAPI_trace(ctx, "capi_cert_get_fname\n"); if (!CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen)) return NULL; wfname = OPENSSL_malloc(dlen); if (CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen)) { char *fname = wide_to_asc(wfname); OPENSSL_free(wfname); return fname; } CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME); capi_addlasterror(); OPENSSL_free(wfname); return NULL; }
CRYPT_KEY_PROV_INFO *capi_get_prov_info(CAPI_CTX *ctx, PCCERT_CONTEXT cert) { DWORD len; CRYPT_KEY_PROV_INFO *pinfo; if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len)) return NULL; pinfo = OPENSSL_malloc(len); if (!pinfo) { CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, ERR_R_MALLOC_FAILURE); return NULL; } if(!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len)) { CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO); capi_addlasterror(); OPENSSL_free(pinfo); return NULL; } return pinfo; }
static BOOL DigiCrypt_CertIsSig(PCCERT_CONTEXT pCertContext) { BOOL fRes = FALSE; CRYPT_KEY_PROV_INFO *poKeyInfo; DWORD pcbData; if (pCertContext == NULL) return(fRes); fRes = CertGetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID,NULL,&pcbData); if (fRes == TRUE) { poKeyInfo = (CRYPT_KEY_PROV_INFO *)malloc(pcbData); if (poKeyInfo != NULL) { fRes = CertGetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID,poKeyInfo,&pcbData); if (fRes == TRUE) { if (poKeyInfo->dwProvType == PROV_RSA_SIG) fRes = TRUE; } free(poKeyInfo); } } return(fRes); }
static std::string getCertUri(PCCERT_CONTEXT cert, const char * cert_store_name) { DWORD cbHash = SHA1_HASH_LENGTH; BYTE aHash[SHA1_HASH_LENGTH]; std::string result("certstore:"); result += cert_store_name; result += ":sha1:"; if (CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID, aHash, &cbHash) == FALSE ) { return ""; } ByteArray byteArray = createByteArray((char *)(&aHash[0]), cbHash); result += Hexify::hexify(byteArray); return result; }
/*! * @brief Wrapper around WinHTTP-specific request response validation. * @param hReq HTTP request handle. * @param ctx The HTTP transport context. * @return An indication of the result of getting a response. */ static DWORD validate_response_winhttp(HANDLE hReq, HttpTransportContext* ctx) { DWORD statusCode; DWORD statusCodeSize = sizeof(statusCode); vdprintf("[PACKET RECEIVE WINHTTP] Getting the result code..."); if (WinHttpQueryHeaders(hReq, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeSize, WINHTTP_NO_HEADER_INDEX)) { vdprintf("[PACKET RECEIVE WINHTTP] Returned status code is %d", statusCode); // did the request succeed? if (statusCode != 200) { // There are a few reasons why this could fail, including proxy related stuff. // If we fail, we're going to fallback to WinINET and see if that works instead. // there could be a number of reasons for failure, but we're only going to try // to handle the case where proxy authentication fails. We'll indicate failure and // let the switchover happen for us. // However, we won't do this in the case where cert hash verification is turned on, // because we don't want to expose people to MITM if they've explicitly asked us not // to. if (ctx->cert_hash == NULL && statusCode == 407) { return ERROR_WINHTTP_CANNOT_CONNECT; } // indicate something is up. return ERROR_BAD_CONFIGURATION; } } if (ctx->cert_hash != NULL) { vdprintf("[PACKET RECEIVE WINHTTP] validating certificate hash"); PCERT_CONTEXT pCertContext = NULL; DWORD dwCertContextSize = sizeof(pCertContext); if (!WinHttpQueryOption(hReq, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &pCertContext, &dwCertContextSize)) { dprintf("[PACKET RECEIVE WINHTTP] Failed to get the certificate context: %u", GetLastError()); return ERROR_WINHTTP_SECURE_INVALID_CERT; } DWORD dwHashSize = 20; BYTE hash[20]; if (!CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, hash, &dwHashSize)) { dprintf("[PACKET RECEIVE WINHTTP] Failed to get the certificate hash: %u", GetLastError()); return ERROR_WINHTTP_SECURE_INVALID_CERT; } if (memcmp(hash, ctx->cert_hash, CERT_HASH_SIZE) != 0) { dprintf("[SERVER] Server hash set to: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", hash[0], hash[1], hash[2], hash[3], hash[4], hash[5], hash[6], hash[7], hash[8], hash[9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15], hash[16], hash[17], hash[18], hash[19]); dprintf("[PACKET RECEIVE WINHTTP] Certificate hash doesn't match, bailing out"); return ERROR_WINHTTP_SECURE_INVALID_CERT; } } return ERROR_SUCCESS; }
BOOL WINAPI CertAddCertificateContextToStore(HCERTSTORE hCertStore, PCCERT_CONTEXT pCertContext, DWORD dwAddDisposition, PCCERT_CONTEXT *ppStoreContext) { PWINECRYPT_CERTSTORE store = hCertStore; BOOL ret = TRUE; PCCERT_CONTEXT toAdd = NULL, existing = NULL; TRACE("(%p, %p, %08x, %p)\n", hCertStore, pCertContext, dwAddDisposition, ppStoreContext); switch (dwAddDisposition) { case CERT_STORE_ADD_ALWAYS: break; case CERT_STORE_ADD_NEW: case CERT_STORE_ADD_REPLACE_EXISTING: case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES: case CERT_STORE_ADD_USE_EXISTING: case CERT_STORE_ADD_NEWER: case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES: { BYTE hashToAdd[20]; DWORD size = sizeof(hashToAdd); ret = CertGetCertificateContextProperty(pCertContext, CERT_HASH_PROP_ID, hashToAdd, &size); if (ret) { CRYPT_HASH_BLOB blob = { sizeof(hashToAdd), hashToAdd }; existing = CertFindCertificateInStore(hCertStore, pCertContext->dwCertEncodingType, 0, CERT_FIND_SHA1_HASH, &blob, NULL); } break; } default: FIXME("Unimplemented add disposition %d\n", dwAddDisposition); SetLastError(E_INVALIDARG); ret = FALSE; } switch (dwAddDisposition) { case CERT_STORE_ADD_ALWAYS: toAdd = CertDuplicateCertificateContext(pCertContext); break; case CERT_STORE_ADD_NEW: if (existing) { TRACE("found matching certificate, not adding\n"); SetLastError(CRYPT_E_EXISTS); ret = FALSE; } else toAdd = CertDuplicateCertificateContext(pCertContext); break; case CERT_STORE_ADD_REPLACE_EXISTING: toAdd = CertDuplicateCertificateContext(pCertContext); break; case CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES: toAdd = CertDuplicateCertificateContext(pCertContext); if (existing) CertContext_CopyProperties(toAdd, existing); break; case CERT_STORE_ADD_USE_EXISTING: if (existing) { CertContext_CopyProperties(existing, pCertContext); if (ppStoreContext) *ppStoreContext = CertDuplicateCertificateContext(existing); } else toAdd = CertDuplicateCertificateContext(pCertContext); break; case CERT_STORE_ADD_NEWER: if (existing) { if (CompareFileTime(&existing->pCertInfo->NotBefore, &pCertContext->pCertInfo->NotBefore) >= 0) { TRACE("existing certificate is newer, not adding\n"); SetLastError(CRYPT_E_EXISTS); ret = FALSE; } else toAdd = CertDuplicateCertificateContext(pCertContext); } else toAdd = CertDuplicateCertificateContext(pCertContext); break; case CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES: if (existing) { if (CompareFileTime(&existing->pCertInfo->NotBefore, &pCertContext->pCertInfo->NotBefore) >= 0) { TRACE("existing certificate is newer, not adding\n"); SetLastError(CRYPT_E_EXISTS); ret = FALSE; } else { toAdd = CertDuplicateCertificateContext(pCertContext); CertContext_CopyProperties(toAdd, existing); } } else toAdd = CertDuplicateCertificateContext(pCertContext); break; } if (toAdd) { if (store) ret = store->certs.addContext(store, (void *)toAdd, (void *)existing, (const void **)ppStoreContext); else if (ppStoreContext) *ppStoreContext = CertDuplicateCertificateContext(toAdd); CertFreeCertificateContext(toAdd); } CertFreeCertificateContext(existing); TRACE("returning %d\n", ret); return ret; }
/*- * _gnutls_privkey_import_system: * @pkey: The private key * @url: The URL of the key * * This function will import the given private key to the abstract * #gnutls_privkey_t type. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.4.0 * -*/ int _gnutls_privkey_import_system_url(gnutls_privkey_t pkey, const char *url) { #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); #else uint8_t id[MAX_WID_SIZE]; HCERTSTORE store = NULL; size_t id_size; const CERT_CONTEXT *cert = NULL; CRYPT_HASH_BLOB blob; CRYPT_KEY_PROV_INFO *kpi = NULL; NCRYPT_KEY_HANDLE nc = NULL; HCRYPTPROV hCryptProv = NULL; NCRYPT_PROV_HANDLE sctx = NULL; DWORD kpi_size; SECURITY_STATUS r; int ret, enc_too = 0; WCHAR algo_str[64]; DWORD algo_str_size = 0; priv_st *priv; DWORD i, dwErrCode = 0; if (ncrypt_init == 0) return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); if (url == NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); priv = gnutls_calloc(1, sizeof(*priv)); if (priv == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); id_size = sizeof(id); ret = get_id(url, id, &id_size, 0); if (ret < 0) return gnutls_assert_val(ret); blob.cbData = id_size; blob.pbData = id; store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, L"MY"); if (store == NULL) { gnutls_assert(); ret = GNUTLS_E_FILE_ERROR; goto cleanup; } cert = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, CERT_FIND_KEY_IDENTIFIER, &blob, NULL); if (cert == NULL) { char buf[64]; _gnutls_debug_log("cannot find ID: %s from %s\n", _gnutls_bin2hex(id, id_size, buf, sizeof(buf), NULL), url); ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); goto cleanup; } kpi_size = 0; r = CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &kpi_size); if (r == 0) { _gnutls_debug_log("error in getting context: %d from %s\n", (int)GetLastError(), url); ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); goto cleanup; } kpi = gnutls_malloc(kpi_size); if (kpi == NULL) { gnutls_assert(); ret = GNUTLS_E_MEMORY_ERROR; goto cleanup; } r = CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, kpi, &kpi_size); if (r == 0) { _gnutls_debug_log("error in getting context: %d from %s\n", (int)GetLastError(), url); ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); goto cleanup; } r = pNCryptOpenStorageProvider(&sctx, kpi->pwszProvName, 0); if (!FAILED(r)) { /* if this works carry on with CNG */ r = pNCryptOpenKey(sctx, &nc, kpi->pwszContainerName, 0, 0); if (FAILED(r)) { ret = gnutls_assert_val (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); goto cleanup; } r = pNCryptGetProperty(nc, NCRYPT_ALGORITHM_PROPERTY, (BYTE *) algo_str, sizeof(algo_str), &algo_str_size, 0); if (FAILED(r)) { ret = gnutls_assert_val (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); goto cleanup; } if (StrCmpW(algo_str, BCRYPT_RSA_ALGORITHM) == 0) { priv->pk = GNUTLS_PK_RSA; priv->sign_algo = GNUTLS_SIGN_RSA_SHA256; enc_too = 1; } else if (StrCmpW(algo_str, BCRYPT_DSA_ALGORITHM) == 0) { priv->pk = GNUTLS_PK_DSA; priv->sign_algo = GNUTLS_SIGN_DSA_SHA1; } else if (StrCmpW(algo_str, BCRYPT_ECDSA_P256_ALGORITHM) == 0) { priv->pk = GNUTLS_PK_EC; priv->sign_algo = GNUTLS_SIGN_ECDSA_SHA256; } else if (StrCmpW(algo_str, BCRYPT_ECDSA_P384_ALGORITHM) == 0) { priv->pk = GNUTLS_PK_EC; priv->sign_algo = GNUTLS_SIGN_ECDSA_SHA384; } else if (StrCmpW(algo_str, BCRYPT_ECDSA_P521_ALGORITHM) == 0) { priv->pk = GNUTLS_PK_EC; priv->sign_algo = GNUTLS_SIGN_ECDSA_SHA512; } else { _gnutls_debug_log("unknown key algorithm: %ls\n", algo_str); ret = gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM); goto cleanup; } priv->nc = nc; ret = gnutls_privkey_import_ext3(pkey, priv, cng_sign, (enc_too != 0) ? cng_decrypt : NULL, cng_deinit, cng_info, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } } else { /* this should be CAPI */ _gnutls_debug_log ("error in opening CNG keystore: %x from %ls\n", (int)r, kpi->pwszProvName); if (CryptAcquireContextW(&hCryptProv, kpi->pwszContainerName, kpi->pwszProvName, kpi->dwProvType, kpi->dwFlags)) { for (i = 0; i < kpi->cProvParam; i++) if (!CryptSetProvParam(hCryptProv, kpi->rgProvParam[i]. dwParam, kpi->rgProvParam[i]. pbData, kpi->rgProvParam[i]. dwFlags)) { dwErrCode = GetLastError(); break; }; } else { dwErrCode = GetLastError(); } if (ERROR_SUCCESS != dwErrCode) { _gnutls_debug_log ("error in getting cryptprov: %d from %s\n", (int)GetLastError(), url); ret = gnutls_assert_val (GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); goto cleanup; } { BYTE buf[100 + sizeof(PROV_ENUMALGS_EX) * 2]; PROV_ENUMALGS_EX *pAlgo = (PROV_ENUMALGS_EX *) buf; DWORD len = sizeof(buf); if (CryptGetProvParam (hCryptProv, PP_ENUMALGS_EX, buf, &len, CRYPT_FIRST)) { DWORD hash = 0; do { switch (pAlgo->aiAlgid) { case CALG_RSA_SIGN: priv->pk = GNUTLS_PK_RSA; enc_too = 1; break; case CALG_DSS_SIGN: priv->pk = priv->pk == GNUTLS_PK_RSA ? GNUTLS_PK_RSA : GNUTLS_PK_DSA; break; case CALG_SHA1: hash = 1; break; case CALG_SHA_256: hash = 256; break; default: break; } len = sizeof(buf); // reset the buffer size } while (CryptGetProvParam (hCryptProv, PP_ENUMALGS_EX, buf, &len, CRYPT_NEXT)); if (priv->pk == GNUTLS_PK_DSA) priv->sign_algo = GNUTLS_SIGN_DSA_SHA1; else priv->sign_algo = (hash > 1) ? GNUTLS_SIGN_RSA_SHA256 : GNUTLS_SIGN_RSA_SHA1; } } priv->hCryptProv = hCryptProv; priv->dwKeySpec = kpi->dwKeySpec; ret = gnutls_privkey_import_ext3(pkey, priv, capi_sign, (enc_too != 0) ? capi_decrypt : NULL, capi_deinit, capi_info, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } } ret = 0; cleanup: if (ret < 0) { if (nc != 0) pNCryptFreeObject(nc); if (hCryptProv != 0) CryptReleaseContext(hCryptProv, 0); gnutls_free(priv); } if (sctx != 0) pNCryptFreeObject(sctx); gnutls_free(kpi); if (cert != 0) CertFreeCertificateContext(cert); CertCloseStore(store, 0); return ret; #endif }
void CAPICertificate::setUri (const std::string& capiUri) { valid_ = false; /* Syntax: "certstore:" <cert_store> ":" <hash> ":" <hash_of_cert> */ if (!boost::iequals(capiUri.substr(0, 10), "certstore:")) { return; } /* Substring of subject: uses "storename" */ std::string capiIdentity = capiUri.substr(10); std::string newCertStoreName; size_t pos = capiIdentity.find_first_of (':'); if (pos == std::string::npos) { /* Using the default certificate store */ newCertStoreName = "MY"; certName_ = capiIdentity; } else { newCertStoreName = capiIdentity.substr(0, pos); certName_ = capiIdentity.substr(pos + 1); } if (certStoreHandle_ != NULL) { if (newCertStoreName != certStore_) { CertCloseStore(certStoreHandle_, 0); certStoreHandle_ = NULL; } } if (certStoreHandle_ == NULL) { certStoreHandle_ = CertOpenSystemStore(0, newCertStoreName.c_str()); if (!certStoreHandle_) { return; } } certStore_ = newCertStoreName; PCCERT_CONTEXT certContext = findCertificateInStore (certStoreHandle_, certName_); if (!certContext) { return; } /* Now verify that we can have access to the corresponding private key */ DWORD len; CRYPT_KEY_PROV_INFO *pinfo; HCRYPTPROV hprov; HCRYPTKEY key; if (!CertGetCertificateContextProperty(certContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len)) { CertFreeCertificateContext(certContext); return; } pinfo = static_cast<CRYPT_KEY_PROV_INFO *>(malloc(len)); if (!pinfo) { CertFreeCertificateContext(certContext); return; } if (!CertGetCertificateContextProperty(certContext, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len)) { CertFreeCertificateContext(certContext); free(pinfo); return; } CertFreeCertificateContext(certContext); // Now verify if we have access to the private key if (!CryptAcquireContextW(&hprov, pinfo->pwszContainerName, pinfo->pwszProvName, pinfo->dwProvType, 0)) { free(pinfo); return; } char smartCardReader[1024]; DWORD bufferLength = sizeof(smartCardReader); if (!CryptGetProvParam(hprov, PP_SMARTCARD_READER, (BYTE *)&smartCardReader, &bufferLength, 0)) { DWORD error = GetLastError(); smartCardReaderName_ = ""; } else { smartCardReaderName_ = smartCardReader; LONG result = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &scardContext_); if (SCARD_S_SUCCESS == result) { // Initiate monitoring for smartcard ejection smartCardTimer_ = timerFactory_->createTimer(SMARTCARD_EJECTION_CHECK_FREQUENCY_MILLISECONDS); } else { ///Need to handle an error here } } if (!CryptGetUserKey(hprov, pinfo->dwKeySpec, &key)) { CryptReleaseContext(hprov, 0); free(pinfo); return; } CryptDestroyKey(key); CryptReleaseContext(hprov, 0); free(pinfo); if (smartCardTimer_) { smartCardTimer_->onTick.connect(boost::bind(&CAPICertificate::handleSmartCardTimerTick, this)); smartCardTimer_->start(); } valid_ = true; }
DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString) { DWORD ret; PCERT_NAME_BLOB name; LPCSTR altNameOID; TRACE("(%p, %ld, %08lx, %p, %p, %ld)\n", pCertContext, dwType, dwFlags, pvTypePara, pszNameString, cchNameString); if (dwFlags & CERT_NAME_ISSUER_FLAG) { name = &pCertContext->pCertInfo->Issuer; altNameOID = szOID_ISSUER_ALT_NAME; } else { name = &pCertContext->pCertInfo->Subject; altNameOID = szOID_SUBJECT_ALT_NAME; } switch (dwType) { case CERT_NAME_SIMPLE_DISPLAY_TYPE: { static const LPCSTR simpleAttributeOIDs[] = { szOID_COMMON_NAME, szOID_ORGANIZATIONAL_UNIT_NAME, szOID_ORGANIZATION_NAME, szOID_RSA_emailAddr }; CERT_NAME_INFO *info = NULL; PCERT_RDN_ATTR nameAttr = NULL; DWORD bytes = 0, i; if (CryptDecodeObjectEx(pCertContext->dwCertEncodingType, X509_NAME, name->pbData, name->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &bytes)) { for (i = 0; !nameAttr && i < sizeof(simpleAttributeOIDs) / sizeof(simpleAttributeOIDs[0]); i++) nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], info); } else ret = 0; if (!nameAttr) { PCERT_EXTENSION ext = CertFindExtension(altNameOID, pCertContext->pCertInfo->cExtension, pCertContext->pCertInfo->rgExtension); if (ext) { for (i = 0; !nameAttr && i < sizeof(simpleAttributeOIDs) / sizeof(simpleAttributeOIDs[0]); i++) nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], info); if (!nameAttr) { /* FIXME: gotta then look for a rfc822Name choice in ext. * Failing that, look for the first attribute. */ FIXME("CERT_NAME_SIMPLE_DISPLAY_TYPE: stub\n"); ret = 0; } } } ret = CertRDNValueToStrW(nameAttr->dwValueType, &nameAttr->Value, pszNameString, cchNameString); if (info) LocalFree(info); break; } case CERT_NAME_FRIENDLY_DISPLAY_TYPE: { DWORD cch = cchNameString; if (CertGetCertificateContextProperty(pCertContext, CERT_FRIENDLY_NAME_PROP_ID, pszNameString, &cch)) ret = cch; else ret = CertGetNameStringW(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, dwFlags, pvTypePara, pszNameString, cchNameString); break; } default: FIXME("unimplemented for type %ld\n", dwType); ret = 0; } return ret; }
static PCCERT_CONTEXT xmlSecMSCryptoKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name, xmlSecKeyInfoCtxPtr keyInfoCtx) { LPCTSTR storeName; HCERTSTORE hStoreHandle = NULL; PCCERT_CONTEXT pCertContext = NULL; LPTSTR wcName = NULL; xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecMSCryptoKeysStoreId), NULL); xmlSecAssert2(name != NULL, NULL); xmlSecAssert2(keyInfoCtx != NULL, NULL); storeName = xmlSecMSCryptoAppGetCertStoreName(); if(storeName == NULL) { storeName = XMLSEC_MSCRYPTO_APP_DEFAULT_CERT_STORE_NAME; } hStoreHandle = CertOpenSystemStore(0, storeName); if (NULL == hStoreHandle) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "CertOpenSystemStore", XMLSEC_ERRORS_R_CRYPTO_FAILED, "storeName=%s", xmlSecErrorsSafeString(storeName)); return(NULL); } /* convert name to unicode */ wcName = xmlSecMSCryptoConvertUtf8ToTstr(name); if(wcName == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)), "xmlSecMSCryptoConvertUtf8ToUnicode", XMLSEC_ERRORS_R_XMLSEC_FAILED, "wcName"); CertCloseStore(hStoreHandle, 0); return(NULL); } /* first attempt: try to find the cert with a full blown subject dn */ if(NULL == pCertContext) { pCertContext = xmlSecMSCryptoX509FindCertBySubject( hStoreHandle, wcName, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING); } /* * Try ro find certificate with name="Friendly Name" */ if (NULL == pCertContext) { DWORD dwPropSize; PBYTE pbFriendlyName; PCCERT_CONTEXT pCertCtxIter = NULL; while (pCertCtxIter = CertEnumCertificatesInStore(hStoreHandle, pCertCtxIter)) { if (TRUE != CertGetCertificateContextProperty(pCertCtxIter, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dwPropSize)) { continue; } pbFriendlyName = xmlMalloc(dwPropSize); if(pbFriendlyName == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)), NULL, XMLSEC_ERRORS_R_MALLOC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlFree(wcName); CertCloseStore(hStoreHandle, 0); return(NULL); } if (TRUE != CertGetCertificateContextProperty(pCertCtxIter, CERT_FRIENDLY_NAME_PROP_ID, pbFriendlyName, &dwPropSize)) { xmlFree(pbFriendlyName); continue; } /* Compare FriendlyName to name */ if (!lstrcmp(wcName, (LPCTSTR)pbFriendlyName)) { pCertContext = pCertCtxIter; xmlFree(pbFriendlyName); break; } xmlFree(pbFriendlyName); } } /* We don't give up easily, now try to find cert with part of the name */ if (NULL == pCertContext) { pCertContext = CertFindCertificateInStore( hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, wcName, NULL); } /* We could do the following here: * It would be nice if we could locate the cert with issuer name and * serial number, the given keyname can be something like this: * 'serial=1234567;issuer=CN=ikke, C=NL' * to be implemented by the first person who reads this, and thinks it's * a good idea :) WK */ /* OK, I give up, I'm gone :( */ /* aleksey todo: is it a right idea to close store if we have a handle to * a cert in this store? */ xmlFree(wcName); CertCloseStore(hStoreHandle, 0); return(pCertContext); }
static PCCERT_CONTEXT xmlSecMSCryptoKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name, xmlSecKeyInfoCtxPtr keyInfoCtx) { const char* storeName; HCERTSTORE hStoreHandle = NULL; PCCERT_CONTEXT pCertContext = NULL; xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecMSCryptoKeysStoreId), NULL); xmlSecAssert2(name != NULL, NULL); xmlSecAssert2(keyInfoCtx != NULL, NULL); storeName = xmlSecMSCryptoAppGetCertStoreName(); if(storeName == NULL) { storeName = XMLSEC_MSCRYPTO_APP_DEFAULT_CERT_STORE_NAME; } hStoreHandle = CertOpenSystemStore(0, storeName); if (NULL == hStoreHandle) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "CertOpenSystemStore", XMLSEC_ERRORS_R_CRYPTO_FAILED, "storeName=%s", xmlSecErrorsSafeString(storeName)); return(NULL); } /* first attempt: search by cert id == name */ if(pCertContext == NULL) { size_t len = xmlStrlen(name) + 1; wchar_t * lpCertID; /* aleksey todo: shouldn't we call MultiByteToWideChar first to get the buffer size? */ lpCertID = (wchar_t *)xmlMalloc(sizeof(wchar_t) * len); if(lpCertID == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)), NULL, XMLSEC_ERRORS_R_MALLOC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); CertCloseStore(hStoreHandle, 0); return(NULL); } MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, lpCertID, len); pCertContext = CertFindCertificateInStore( hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, lpCertID, NULL); xmlFree(lpCertID); } /* We don't give up easily, now try to fetch the cert with a full blown * subject dn */ if (NULL == pCertContext) { BYTE* bdata; DWORD len; bdata = xmlSecMSCryptoCertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, name, CERT_OID_NAME_STR, &len); if(bdata != NULL) { CERT_NAME_BLOB cnb; cnb.cbData = len; cnb.pbData = bdata; pCertContext = CertFindCertificateInStore(hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &cnb, NULL); xmlFree(bdata); } } /* We don't give up easily, now try to fetch the cert with a full blown * subject dn, and try with a reversed dn */ if (NULL == pCertContext) { BYTE* bdata; DWORD len; bdata = xmlSecMSCryptoCertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, name, CERT_OID_NAME_STR | CERT_NAME_STR_REVERSE_FLAG, &len); if(bdata != NULL) { CERT_NAME_BLOB cnb; cnb.cbData = len; cnb.pbData = bdata; pCertContext = CertFindCertificateInStore(hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &cnb, NULL); xmlFree(bdata); } } /* * Try ro find certificate with name="Friendly Name" */ if (NULL == pCertContext) { DWORD dwPropSize; PBYTE pbFriendlyName; PCCERT_CONTEXT pCertCtxIter = NULL; size_t len = xmlStrlen(name) + 1; wchar_t * lpFName; lpFName = (wchar_t *)xmlMalloc(sizeof(wchar_t) * len); if(lpFName == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)), NULL, XMLSEC_ERRORS_R_MALLOC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); CertCloseStore(hStoreHandle, 0); return(NULL); } MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, lpFName, len); while (pCertCtxIter = CertEnumCertificatesInStore(hStoreHandle, pCertCtxIter)) { if (TRUE != CertGetCertificateContextProperty(pCertCtxIter, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dwPropSize)) { continue; } pbFriendlyName = xmlMalloc(dwPropSize); if(pbFriendlyName == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)), NULL, XMLSEC_ERRORS_R_MALLOC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlFree(lpFName); CertCloseStore(hStoreHandle, 0); return(NULL); } if (TRUE != CertGetCertificateContextProperty(pCertCtxIter, CERT_FRIENDLY_NAME_PROP_ID, pbFriendlyName, &dwPropSize)) { xmlFree(pbFriendlyName); continue; } /* Compare FriendlyName to name */ if (!wcscmp(lpFName, (const wchar_t *)pbFriendlyName)) { pCertContext = pCertCtxIter; xmlFree(pbFriendlyName); break; } xmlFree(pbFriendlyName); } xmlFree(lpFName); } /* We could do the following here: * It would be nice if we could locate the cert with issuer name and * serial number, the given keyname can be something like this: * 'serial=1234567;issuer=CN=ikke, C=NL' * to be implemented by the first person who reads this, and thinks it's * a good idea :) WK */ /* OK, I give up, I'm gone :( */ /* aleksey todo: is it a right idea to close store if we have a handle to * a cert in this store? */ CertCloseStore(hStoreHandle, 0); return(pCertContext); }
DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString) { DWORD ret = 0; PCERT_NAME_BLOB name; LPCSTR altNameOID; TRACE("(%p, %d, %08x, %p, %p, %d)\n", pCertContext, dwType, dwFlags, pvTypePara, pszNameString, cchNameString); if (dwFlags & CERT_NAME_ISSUER_FLAG) { name = &pCertContext->pCertInfo->Issuer; altNameOID = szOID_ISSUER_ALT_NAME; } else { name = &pCertContext->pCertInfo->Subject; altNameOID = szOID_SUBJECT_ALT_NAME; } switch (dwType) { case CERT_NAME_EMAIL_TYPE: { CERT_ALT_NAME_INFO *info; PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, altNameOID, CERT_ALT_NAME_RFC822_NAME, &info); if (entry) { if (!pszNameString) ret = strlenW(entry->u.pwszRfc822Name) + 1; else if (cchNameString) { ret = min(strlenW(entry->u.pwszRfc822Name), cchNameString - 1); memcpy(pszNameString, entry->u.pwszRfc822Name, ret * sizeof(WCHAR)); pszNameString[ret++] = 0; } } if (info) LocalFree(info); if (!ret) ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType, name, szOID_RSA_emailAddr, pszNameString, cchNameString); break; } case CERT_NAME_RDN_TYPE: if (name->cbData) ret = CertNameToStrW(pCertContext->dwCertEncodingType, name, *(DWORD *)pvTypePara, pszNameString, cchNameString); else { CERT_ALT_NAME_INFO *info; PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, altNameOID, CERT_ALT_NAME_DIRECTORY_NAME, &info); if (entry) ret = CertNameToStrW(pCertContext->dwCertEncodingType, &entry->u.DirectoryName, *(DWORD *)pvTypePara, pszNameString, cchNameString); if (info) LocalFree(info); } break; case CERT_NAME_ATTR_TYPE: ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType, name, pvTypePara, pszNameString, cchNameString); if (!ret) { CERT_ALT_NAME_INFO *altInfo; PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, altNameOID, CERT_ALT_NAME_DIRECTORY_NAME, &altInfo); if (entry) ret = cert_name_to_str_with_indent(X509_ASN_ENCODING, 0, &entry->u.DirectoryName, 0, pszNameString, cchNameString); if (altInfo) LocalFree(altInfo); } break; case CERT_NAME_SIMPLE_DISPLAY_TYPE: { static const LPCSTR simpleAttributeOIDs[] = { szOID_COMMON_NAME, szOID_ORGANIZATIONAL_UNIT_NAME, szOID_ORGANIZATION_NAME, szOID_RSA_emailAddr }; CERT_NAME_INFO *nameInfo = NULL; DWORD bytes = 0, i; if (CryptDecodeObjectEx(pCertContext->dwCertEncodingType, X509_NAME, name->pbData, name->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &nameInfo, &bytes)) { PCERT_RDN_ATTR nameAttr = NULL; for (i = 0; !nameAttr && i < sizeof(simpleAttributeOIDs) / sizeof(simpleAttributeOIDs[0]); i++) nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], nameInfo); if (nameAttr) ret = CertRDNValueToStrW(nameAttr->dwValueType, &nameAttr->Value, pszNameString, cchNameString); LocalFree(nameInfo); } if (!ret) { CERT_ALT_NAME_INFO *altInfo; PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, altNameOID, CERT_ALT_NAME_RFC822_NAME, &altInfo); if (altInfo) { if (!entry && altInfo->cAltEntry) entry = &altInfo->rgAltEntry[0]; if (entry) { if (!pszNameString) ret = strlenW(entry->u.pwszRfc822Name) + 1; else if (cchNameString) { ret = min(strlenW(entry->u.pwszRfc822Name), cchNameString - 1); memcpy(pszNameString, entry->u.pwszRfc822Name, ret * sizeof(WCHAR)); pszNameString[ret++] = 0; } } LocalFree(altInfo); } } break; } case CERT_NAME_FRIENDLY_DISPLAY_TYPE: { DWORD cch = cchNameString; if (CertGetCertificateContextProperty(pCertContext, CERT_FRIENDLY_NAME_PROP_ID, pszNameString, &cch)) ret = cch; else ret = CertGetNameStringW(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, dwFlags, pvTypePara, pszNameString, cchNameString); break; } case CERT_NAME_DNS_TYPE: { CERT_ALT_NAME_INFO *info; PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, altNameOID, CERT_ALT_NAME_DNS_NAME, &info); if (entry) { if (!pszNameString) ret = strlenW(entry->u.pwszDNSName) + 1; else if (cchNameString) { ret = min(strlenW(entry->u.pwszDNSName), cchNameString - 1); memcpy(pszNameString, entry->u.pwszDNSName, ret * sizeof(WCHAR)); pszNameString[ret++] = 0; } } if (info) LocalFree(info); if (!ret) ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType, name, szOID_COMMON_NAME, pszNameString, cchNameString); break; } case CERT_NAME_URL_TYPE: { CERT_ALT_NAME_INFO *info; PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext, altNameOID, CERT_ALT_NAME_URL, &info); if (entry) { if (!pszNameString) ret = strlenW(entry->u.pwszURL) + 1; else if (cchNameString) { ret = min(strlenW(entry->u.pwszURL), cchNameString - 1); memcpy(pszNameString, entry->u.pwszURL, ret * sizeof(WCHAR)); pszNameString[ret++] = 0; } } if (info) LocalFree(info); break; } default: FIXME("unimplemented for type %d\n", dwType); ret = 0; } if (!ret) { if (!pszNameString) ret = 1; else if (cchNameString) { pszNameString[0] = 0; ret = 1; } } return ret; }
NTSTATUS kuhl_m_crypto_l_certificates(int argc, wchar_t * argv[]) { HCERTSTORE hCertificateStore; PCCERT_CONTEXT pCertContext; DWORD i, j, dwSizeNeeded, keySpec; wchar_t *certName; PCRYPT_KEY_PROV_INFO pBuffer; HCRYPTPROV_OR_NCRYPT_KEY_HANDLE monProv; HCRYPTKEY maCle; BOOL keyToFree; PCWCHAR szSystemStore, szStore; DWORD dwSystemStore = 0; BOOL export = kull_m_string_args_byName(argc, argv, L"export", NULL, NULL); kull_m_string_args_byName(argc, argv, L"systemstore", &szSystemStore, kuhl_m_crypto_system_stores[0].name); dwSystemStore = kuhl_m_crypto_system_store_to_dword(szSystemStore); kull_m_string_args_byName(argc, argv, L"store", &szStore, L"My"); kprintf(L" * System Store : \'%s\' (0x%08x)\n" L" * Store : \'%s\'\n\n", szSystemStore, dwSystemStore, szStore); if(hCertificateStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, dwSystemStore | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, szStore)) { for (i = 0, pCertContext = CertEnumCertificatesInStore(hCertificateStore, NULL); pCertContext != NULL; pCertContext = CertEnumCertificatesInStore(hCertificateStore, pCertContext), i++) { for(j = 0; j < ARRAYSIZE(nameSrc); j++) { dwSizeNeeded = CertGetNameString(pCertContext, nameSrc[j], 0, NULL, NULL, 0); if(dwSizeNeeded > 0) { if(certName = (wchar_t *) LocalAlloc(LPTR, dwSizeNeeded * sizeof(wchar_t))) { if(CertGetNameString(pCertContext, nameSrc[j], 0, NULL, certName, dwSizeNeeded) == dwSizeNeeded) { kprintf(L"%2u. %s\n", i, certName); dwSizeNeeded = 0; if(CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwSizeNeeded)) { if(pBuffer = (PCRYPT_KEY_PROV_INFO) LocalAlloc(LPTR, dwSizeNeeded)) { if(CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, pBuffer, &dwSizeNeeded)) { kprintf( L"\tKey Container : %s\n" L"\tProvider : %s\n", (pBuffer->pwszContainerName ? pBuffer->pwszContainerName : L"(null)"), (pBuffer->pwszProvName ? pBuffer->pwszProvName : L"(null)")); if(CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG /* CRYPT_ACQUIRE_SILENT_FLAG NULL */, NULL, &monProv, &keySpec, &keyToFree)) { kprintf(L"\tType : %s (0x%08x)\n", kuhl_m_crypto_keytype_to_str(keySpec), keySpec); if(keySpec != CERT_NCRYPT_KEY_SPEC) { if(CryptGetUserKey(monProv, keySpec, &maCle)) { kuhl_m_crypto_printKeyInfos(0, maCle); CryptDestroyKey(maCle); } else PRINT_ERROR_AUTO(L"CryptGetUserKey"); if(keyToFree) CryptReleaseContext(monProv, 0); } else if(kuhl_m_crypto_hNCrypt) { kuhl_m_crypto_printKeyInfos(monProv, 0); if(keyToFree) K_NCryptFreeObject(monProv); } else PRINT_ERROR(L"keySpec == CERT_NCRYPT_KEY_SPEC without CNG Handle ?\n"); } else PRINT_ERROR_AUTO(L"CryptAcquireCertificatePrivateKey"); } else PRINT_ERROR_AUTO(L"CertGetCertificateContextProperty"); } LocalFree(pBuffer); if(!export) kprintf(L"\n"); } if(export) kuhl_m_crypto_exportCert(pCertContext, (BOOL) dwSizeNeeded, szSystemStore, szStore, i, certName); } else PRINT_ERROR_AUTO(L"CertGetNameString"); LocalFree(certName); } break; } else PRINT_ERROR_AUTO(L"CertGetNameString (for len)"); }
/*- * _gnutls_privkey_import_system: * @pkey: The private key * @url: The URL of the key * * This function will import the given private key to the abstract * #gnutls_privkey_t type. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.4.0 * -*/ int _gnutls_privkey_import_system_url(gnutls_privkey_t pkey, const char *url) { uint8_t id[MAX_WID_SIZE]; HCERTSTORE store = NULL; size_t id_size; const CERT_CONTEXT *cert = NULL; CRYPT_HASH_BLOB blob; CRYPT_KEY_PROV_INFO *kpi = NULL; NCRYPT_KEY_HANDLE nc = NULL; NCRYPT_PROV_HANDLE sctx = NULL; DWORD kpi_size; SECURITY_STATUS r; int ret, enc_too = 0; WCHAR algo_str[64]; DWORD algo_str_size = 0; priv_st *priv; if (ncrypt_init == 0) return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); if (url == NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); priv = gnutls_calloc(1, sizeof(*priv)); if (priv == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); id_size = sizeof(id); ret = get_id(url, id, &id_size, 0); if (ret < 0) return gnutls_assert_val(ret); blob.cbData = id_size; blob.pbData = id; store = CertOpenSystemStore(0, "MY"); if (store == NULL) { gnutls_assert(); ret = GNUTLS_E_FILE_ERROR; goto cleanup; } cert = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, CERT_FIND_KEY_IDENTIFIER, &blob, NULL); if (cert == NULL) { char buf[64]; _gnutls_debug_log("cannot find ID: %s from %s\n", _gnutls_bin2hex(id, id_size, buf, sizeof(buf), NULL), url); ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); goto cleanup; } kpi_size = 0; r = CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &kpi_size); if (r == 0) { _gnutls_debug_log("error in getting context: %d from %s\n", (int)GetLastError(), url); ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); goto cleanup; } kpi = gnutls_malloc(kpi_size); if (kpi == NULL) { gnutls_assert(); ret = GNUTLS_E_MEMORY_ERROR; goto cleanup; } r = CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, kpi, &kpi_size); if (r == 0) { _gnutls_debug_log("error in getting context: %d from %s\n", (int)GetLastError(), url); ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); goto cleanup; } r = pNCryptOpenStorageProvider(&sctx, kpi->pwszProvName, 0); if (FAILED(r)) { ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); goto cleanup; } r = pNCryptOpenKey(sctx, &nc, kpi->pwszContainerName, 0, 0); if (FAILED(r)) { ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); goto cleanup; } r = pNCryptGetProperty(nc, NCRYPT_ALGORITHM_PROPERTY, (BYTE*)algo_str, sizeof(algo_str), &algo_str_size, 0); if (FAILED(r)) { ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); goto cleanup; } if (StrCmpW(algo_str, BCRYPT_RSA_ALGORITHM) == 0) { priv->pk = GNUTLS_PK_RSA; priv->sign_algo = GNUTLS_SIGN_RSA_SHA256; enc_too = 1; } else if (StrCmpW(algo_str, BCRYPT_DSA_ALGORITHM) == 0) { priv->pk = GNUTLS_PK_DSA; priv->sign_algo = GNUTLS_SIGN_DSA_SHA1; } else if (StrCmpW(algo_str, BCRYPT_ECDSA_P256_ALGORITHM) == 0) { priv->pk = GNUTLS_PK_EC; priv->sign_algo = GNUTLS_SIGN_ECDSA_SHA256; } else if (StrCmpW(algo_str, BCRYPT_ECDSA_P384_ALGORITHM) == 0) { priv->pk = GNUTLS_PK_EC; priv->sign_algo = GNUTLS_SIGN_ECDSA_SHA384; } else if (StrCmpW(algo_str, BCRYPT_ECDSA_P521_ALGORITHM) == 0) { priv->pk = GNUTLS_PK_EC; priv->sign_algo = GNUTLS_SIGN_ECDSA_SHA512; } else { _gnutls_debug_log("unknown key algorithm: %ls\n", algo_str); ret = gnutls_assert_val(GNUTLS_E_UNKNOWN_PK_ALGORITHM); goto cleanup; } priv->nc = nc; ret = gnutls_privkey_import_ext3(pkey, priv, cng_sign, (enc_too!=0)?cng_decrypt:NULL, cng_deinit, cng_info, 0); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = 0; cleanup: if (ret < 0) { if (nc != 0) pNCryptFreeObject(nc); gnutls_free(priv); } if (sctx != 0) pNCryptFreeObject(sctx); gnutls_free(kpi); CertCloseStore(store, 0); return ret; }
// // Retrieve the thumbprint of the certificate // DWORD GetCertificate(IN WCHAR* pwcTrustRootCA, IN PBYTE pbCertHash, IN DWORD* pcbCertHash) { HCERTSTORE hCertStore; WCHAR *pwcSubjectName; DWORD cwcSubjectName; PBYTE pbSHA1; DWORD cbSHA1; PCCERT_CONTEXT pCertContext = NULL; DWORD dwRet; dwRet = NO_ERROR; if( ( hCertStore = CertOpenStore( CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, ( HCRYPTPROV ) NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"ROOT" ) ) ) { BOOL bFoundCert = FALSE; while( ( pCertContext = CertEnumCertificatesInStore( hCertStore, pCertContext ) ) && bFoundCert == FALSE ) { if( ( cwcSubjectName = CertGetNameString( pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0 ) ) > 0 ) { if( ( pwcSubjectName = ( WCHAR* ) malloc( cwcSubjectName * sizeof( WCHAR ) ) ) ) { if( CertGetNameStringW( pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pwcSubjectName, cwcSubjectName ) > 0 ) { //printf("Found the certificate [%ws] in the system store\n", pwcSubjectName); if ( wcscmp(pwcTrustRootCA, pwcSubjectName) == 0) { bFoundCert = TRUE; // Retrieve information on the property by first getting the property size. if(CertGetCertificateContextProperty( pCertContext, CERT_SHA1_HASH_PROP_ID , // work fine on XP NULL, &cbSHA1)) { // Use the size to allocate the memory for the property if ( pbSHA1 = (BYTE *) malloc(cbSHA1 * sizeof(BYTE) ) ) { // Retrieve HASH of the certificate if(CertGetCertificateContextProperty( pCertContext, CERT_SHA1_HASH_PROP_ID , pbSHA1, &cbSHA1)) { memcpy(pbCertHash, pbSHA1, cbSHA1); *pcbCertHash = cbSHA1; } else { printf("->GetCertificate :: Error retrieving certificate HASH.\n"); dwRet = ERROR_CANTOPEN; } free(pbSHA1); } else { printf("->GetCertificate :: Error allocating memory.\n"); dwRet = ERROR_NOT_ENOUGH_MEMORY; } } else { printf("->GetCertificate :: Error getting certificate property.\n"); dwRet = ERROR_CANTOPEN; } } } else { printf("->GetCertificate :: Error getting certificate name string.\n"); dwRet = ERROR_CANTOPEN; } free( pwcSubjectName ); cwcSubjectName = 0; } else { printf("->GetCertificate :: Error allocating memory.\n"); dwRet = ERROR_NOT_ENOUGH_MEMORY; } } else dwRet = ERROR_CANTOPEN; } if( !bFoundCert ) { printf("->GetCertificate :: Error looking for the certificate in the system store.\n"); dwRet = ERROR_CANTOPEN; } if( dwRet != NO_ERROR ) { if( pCertContext ) CertFreeCertificateContext( pCertContext ); } CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ); } else { printf("->GetCertificate :: Error opening system store.\n"); dwRet = ERROR_CANTOPEN; } return dwRet; }
HRESULT WINAPI SoftpubAuthenticode(CRYPT_PROVIDER_DATA *data) { BOOL ret; CERT_CHAIN_POLICY_STATUS policyStatus = { sizeof(policyStatus), 0 }; TRACE("(%p)\n", data); if (data->pWintrustData->dwUIChoice != WTD_UI_NONE) FIXME("unimplemented for UI choice %d\n", data->pWintrustData->dwUIChoice); if (!data->csSigners) { ret = FALSE; policyStatus.dwError = TRUST_E_NOSIGNATURE; } else { DWORD i; ret = TRUE; for (i = 0; ret && i < data->csSigners; i++) { BYTE hash[20]; DWORD size = sizeof(hash); /* First make sure cert isn't disallowed */ if ((ret = CertGetCertificateContextProperty( data->pasSigners[i].pasCertChain[0].pCert, CERT_SIGNATURE_HASH_PROP_ID, hash, &size))) { static const WCHAR disallowedW[] = { 'D','i','s','a','l','l','o','w','e','d',0 }; HCERTSTORE disallowed = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, X509_ASN_ENCODING, 0, CERT_SYSTEM_STORE_CURRENT_USER, disallowedW); if (disallowed) { PCCERT_CONTEXT found = CertFindCertificateInStore( disallowed, X509_ASN_ENCODING, 0, CERT_FIND_SIGNATURE_HASH, hash, NULL); if (found) { /* Disallowed! Can't verify it. */ policyStatus.dwError = TRUST_E_SUBJECT_NOT_TRUSTED; ret = FALSE; CertFreeCertificateContext(found); } CertCloseStore(disallowed, 0); } } if (ret) { CERT_CHAIN_POLICY_PARA policyPara = { sizeof(policyPara), 0 }; if (data->dwRegPolicySettings & WTPF_TRUSTTEST) policyPara.dwFlags |= CERT_CHAIN_POLICY_TRUST_TESTROOT_FLAG; if (data->dwRegPolicySettings & WTPF_TESTCANBEVALID) policyPara.dwFlags |= CERT_CHAIN_POLICY_ALLOW_TESTROOT_FLAG; if (data->dwRegPolicySettings & WTPF_IGNOREEXPIRATION) policyPara.dwFlags |= CERT_CHAIN_POLICY_IGNORE_NOT_TIME_VALID_FLAG | CERT_CHAIN_POLICY_IGNORE_CTL_NOT_TIME_VALID_FLAG | CERT_CHAIN_POLICY_IGNORE_NOT_TIME_NESTED_FLAG; if (data->dwRegPolicySettings & WTPF_IGNOREREVOKATION) policyPara.dwFlags |= CERT_CHAIN_POLICY_IGNORE_END_REV_UNKNOWN_FLAG | CERT_CHAIN_POLICY_IGNORE_CTL_SIGNER_REV_UNKNOWN_FLAG | CERT_CHAIN_POLICY_IGNORE_CA_REV_UNKNOWN_FLAG | CERT_CHAIN_POLICY_IGNORE_ROOT_REV_UNKNOWN_FLAG; CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_AUTHENTICODE, data->pasSigners[i].pChainContext, &policyPara, &policyStatus); if (policyStatus.dwError != NO_ERROR) ret = FALSE; } } } if (!ret) data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV] = policyStatus.dwError; TRACE("returning %d (%08x)\n", ret ? S_OK : S_FALSE, data->padwTrustStepErrors[TRUSTERROR_STEP_FINAL_POLICYPROV]); return ret ? S_OK : S_FALSE; }
static int get_win_urls(const CERT_CONTEXT * cert, char **cert_url, char **key_url, char **label, gnutls_datum_t * der) { BOOL r; int ret; DWORD tl_size; gnutls_datum_t tmp_label = { NULL, 0 }; char name[MAX_CN * 2]; char hex[MAX_WID_SIZE * 2 + 1]; gnutls_buffer_st str; #ifdef WORDS_BIGENDIAN const unsigned bigendian = 1; #else const unsigned bigendian = 0; #endif if (cert == NULL) return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); if (der) { der->data = gnutls_malloc(cert->cbCertEncoded); if (der->data == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); memcpy(der->data, cert->pbCertEncoded, cert->cbCertEncoded); der->size = cert->cbCertEncoded; } _gnutls_buffer_init(&str); if (label) *label = NULL; if (key_url) *key_url = NULL; if (cert_url) *cert_url = NULL; tl_size = sizeof(name); r = CertGetCertificateContextProperty(cert, CERT_FRIENDLY_NAME_PROP_ID, name, &tl_size); if (r != 0) { /* optional */ ret = _gnutls_ucs2_to_utf8(name, tl_size, &tmp_label, bigendian); if (ret < 0) { gnutls_assert(); goto fail; } if (label) *label = (char *)tmp_label.data; } tl_size = sizeof(name); r = CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, name, &tl_size); if (r == 0) { gnutls_assert(); ret = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; goto fail; } if (_gnutls_bin2hex(name, tl_size, hex, sizeof(hex), 0) == NULL) { ret = gnutls_assert_val(GNUTLS_E_PARSING_ERROR); goto fail; } ret = _gnutls_buffer_append_printf(&str, WIN_URL "id=%s;type=cert", hex); if (ret < 0) { gnutls_assert(); goto fail; } if (tmp_label.data) { ret = _gnutls_buffer_append_str(&str, ";name="); if (ret < 0) { gnutls_assert(); goto fail; } ret = _gnutls_buffer_append_escape(&str, tmp_label.data, tmp_label.size, " "); if (ret < 0) { gnutls_assert(); goto fail; } } ret = _gnutls_buffer_append_data(&str, "\x00", 1); if (ret < 0) { gnutls_assert(); goto fail; } if (cert_url) *cert_url = (char *)str.data; _gnutls_buffer_init(&str); ret = _gnutls_buffer_append_printf(&str, WIN_URL "id=%s;type=privkey", hex); if (ret < 0) { gnutls_assert(); goto fail; } if (tmp_label.data) { ret = _gnutls_buffer_append_str(&str, ";name="); if (ret < 0) { gnutls_assert(); goto fail; } ret = _gnutls_buffer_append_escape(&str, tmp_label.data, tmp_label.size, " "); if (ret < 0) { gnutls_assert(); goto fail; } } ret = _gnutls_buffer_append_data(&str, "\x00", 1); if (ret < 0) { gnutls_assert(); goto fail; } if (key_url) *key_url = (char *)str.data; _gnutls_buffer_init(&str); ret = 0; goto cleanup; fail: if (der) gnutls_free(der->data); if (cert_url) gnutls_free(*cert_url); if (key_url) gnutls_free(*key_url); if (label) gnutls_free(*label); cleanup: _gnutls_buffer_clear(&str); return ret; }
/* If containernumber == NULL, list the containers. * If containernumber is a string containing the number of the container, * fill in the provider name, container name and keyspec. */ long listMyCerts(const char *containerNumber, char *providerName, char *containerName, DWORD *pKeySpec) { HCERTSTORE hCertStore; PCCERT_CONTEXT pCertContext = NULL; int i = 1; int iContainerNr; if (containerNumber != NULL) { iContainerNr = atoi(containerNumber); providerName[0] = '\0'; containerName[0] = '\0'; *pKeySpec = -1; } if (hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, L"MY")) { if (containerNumber == NULL) printf("Listing certs in MY cert store:\n"); } else { int err = GetLastError(); printf("CertOpenStore: %s (0x%0x)\n", e2str(err), err); return err; } // Retrieve each of the certificates in the store. while(pCertContext= CertEnumCertificatesInStore(hCertStore, pCertContext)) { char buf[400], provName[200], contName[200]; DWORD size = sizeof(buf); CRYPT_KEY_PROV_INFO *prov_info; if (CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, buf, &size)) { prov_info = (CRYPT_KEY_PROV_INFO *) buf; unicode_to_ascii(prov_info->pwszProvName, provName, sizeof(provName)); unicode_to_ascii(prov_info->pwszContainerName, contName, sizeof(contName)); if (containerNumber == NULL) { printf("%d. %S: \t%S (%s)\n", i, prov_info->pwszProvName, prov_info->pwszContainerName, prov_info->dwKeySpec == AT_KEYEXCHANGE ? "AT_KEYEXCHANGE" : "AT_SIGNATURE"); } else if (i == iContainerNr) { strcpy_s(providerName,PROVIDER_BUFFER_SIZE, provName); strcpy_s(containerName,CONTAINER_BUFFER_SIZE, contName); *pKeySpec = prov_info->dwKeySpec; break; } i++; } else { int err = GetLastError(); printf("- Error doing CertEnumCertificatesInStore: %s (0x%0x)\n", e2str(err), err); } } CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG); if (containerNumber == NULL) printf(" done\n"); return 0; }
/*********************************************************************** * TrustIsCertificateSelfSigned (WINTRUST.@) */ BOOL WINAPI TrustIsCertificateSelfSigned( PCCERT_CONTEXT cert ) { PCERT_EXTENSION ext; DWORD size; BOOL ret; TRACE("%p\n", cert); if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER2, cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension))) { CERT_AUTHORITY_KEY_ID2_INFO *info; ret = CryptDecodeObjectEx(cert->dwCertEncodingType, X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL, &info, &size); if (ret) { if (info->AuthorityCertIssuer.cAltEntry && info->AuthorityCertSerialNumber.cbData) { PCERT_ALT_NAME_ENTRY directoryName = NULL; DWORD i; for (i = 0; !directoryName && i < info->AuthorityCertIssuer.cAltEntry; i++) if (info->AuthorityCertIssuer.rgAltEntry[i].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME) directoryName = &info->AuthorityCertIssuer.rgAltEntry[i]; if (directoryName) { ret = CertCompareCertificateName(cert->dwCertEncodingType, &directoryName->u.DirectoryName, &cert->pCertInfo->Issuer) && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber, &cert->pCertInfo->SerialNumber); } else { FIXME("no supported name type in authority key id2\n"); ret = FALSE; } } else if (info->KeyId.cbData) { ret = CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); if (ret && size == info->KeyId.cbData) { LPBYTE buf = CryptMemAlloc(size); if (buf) { CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, buf, &size); ret = !memcmp(buf, info->KeyId.pbData, size); CryptMemFree(buf); } else ret = FALSE; } else ret = FALSE; } LocalFree(info); } } else if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER, cert->pCertInfo->cExtension, cert->pCertInfo->rgExtension))) { CERT_AUTHORITY_KEY_ID_INFO *info; ret = CryptDecodeObjectEx(cert->dwCertEncodingType, X509_AUTHORITY_KEY_ID, ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, NULL, &info, &size); if (ret) { if (info->CertIssuer.cbData && info->CertSerialNumber.cbData) { ret = CertCompareCertificateName(cert->dwCertEncodingType, &info->CertIssuer, &cert->pCertInfo->Issuer) && CertCompareIntegerBlob(&info->CertSerialNumber, &cert->pCertInfo->SerialNumber); } else if (info->KeyId.cbData) { ret = CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); if (ret && size == info->KeyId.cbData) { LPBYTE buf = CryptMemAlloc(size); if (buf) { CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, buf, &size); ret = !memcmp(buf, info->KeyId.pbData, size); CryptMemFree(buf); } else ret = FALSE; } else ret = FALSE; } else ret = FALSE; LocalFree(info); } } else ret = CertCompareCertificateName(cert->dwCertEncodingType, &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer); return ret; }
static sqInt sqSetupCert(sqSSL *ssl, char *certName, int server) { SCHANNEL_CRED sc_cred = { 0 }; SECURITY_STATUS ret; HCERTSTORE hStore; PCCERT_CONTEXT pContext = NULL; DWORD dwPropSize; WCHAR wFriendlyName[MAX_NAME_SIZE]; char bFriendlyName[MAX_NAME_SIZE]; if(certName) { hStore = CertOpenSystemStore(0, "MY"); if(!hStore) { if(ssl->loglevel) printf("sqSetupCert: CertOpenSystemStore failed\n"); return 0; } pContext = NULL; /* Enumerate the certificate store to find the cert with the given friendly name */ while(pContext = CertEnumCertificatesInStore(hStore, pContext)) { if(ssl->loglevel) printf("Checking certificate: "); dwPropSize = MAX_NAME_SIZE * sizeof(WCHAR); if(!CertGetCertificateContextProperty(pContext, CERT_FRIENDLY_NAME_PROP_ID, wFriendlyName, &dwPropSize)) { if(ssl->loglevel) printf("<no friendly name>"); continue; } if(!WideCharToMultiByte(CP_UTF8, 0, wFriendlyName, -1, bFriendlyName, MAX_NAME_SIZE, NULL, NULL)) { if(ssl->loglevel) printf("<utf-8 conversion failure>"); continue; } if(ssl->loglevel) printf("%s\n", bFriendlyName); if(strcmp(certName, bFriendlyName) == 0) break; } if(pContext == 0) { /* For compatibility with older versions of SqueakSSL, attempt to match against subject string */ pContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR_A, certName, NULL); } if(!pContext) { if(ssl->loglevel) printf("sqSetupCert: No suitable certificate found\n"); CertCloseStore(hStore, 0); return 0; } } sc_cred.dwVersion = SCHANNEL_CRED_VERSION; sc_cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_MANUAL_CRED_VALIDATION; sc_cred.grbitEnabledProtocols = server ? SP_PROT_TLS1_SERVER | SP_PROT_SSL3_SERVER : 0; sc_cred.dwMinimumCipherStrength = 0; sc_cred.dwMaximumCipherStrength = 0; if(pContext) { sc_cred.cCreds = 1; sc_cred.paCred = &pContext; } else { sc_cred.cCreds = 0; } ret = AcquireCredentialsHandle(NULL, UNISP_NAME, server ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND, NULL, &sc_cred, NULL, NULL, &ssl->sslCred, NULL); if(ssl->loglevel) printf("AquireCredentialsHandle returned: %x\n", ret); if(pContext) { CertCloseStore(hStore, 0); CertFreeCertificateContext(pContext); } if (ret != SEC_E_OK) { if(ssl->loglevel) printf("AquireCredentialsHandle error: %x\n", ret); return 0; } return 1; }
/** * gnutls_system_key_delete: * @cert_url: the URL of the certificate * @key_url: the URL of the key * * This function will delete the key and certificate pair. * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.4.0 **/ int gnutls_system_key_delete(const char *cert_url, const char *key_url) { uint8_t id[MAX_WID_SIZE]; HCERTSTORE store = NULL; size_t id_size; const CERT_CONTEXT *cert = NULL; CRYPT_HASH_BLOB blob; NCRYPT_KEY_HANDLE nc; DWORD nc_size; BOOL r; int ret; if (ncrypt_init == 0) return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); if (cert_url == NULL && key_url == NULL) return 0; if (cert_url != NULL) { id_size = sizeof(id); ret = get_id(cert_url, id, &id_size, 1); if (ret < 0) return gnutls_assert_val(ret); } else { id_size = sizeof(id); ret = get_id(key_url, id, &id_size, 0); if (ret < 0) return gnutls_assert_val(ret); } blob.cbData = id_size; blob.pbData = id; store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, L"MY"); if (store != NULL) { do { cert = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, CERT_FIND_KEY_IDENTIFIER, &blob, cert); if (cert && key_url) { nc_size = sizeof(nc); r = CertGetCertificateContextProperty(cert, CERT_NCRYPT_KEY_HANDLE_TRANSFER_PROP_ID, &nc, &nc_size); if (r != 0) { pNCryptDeleteKey(nc, 0); pNCryptFreeObject(nc); } else { gnutls_assert(); } } if (cert && cert_url) CertDeleteCertificateFromStore(cert); } while (cert != NULL); CertCloseStore(store, 0); } return 0; }
DWORD do_low_sign (const char *infile, const char *outfile) { char OID[64] = szOID_CP_GOST_R3411; int include = 1; HCRYPTPROV hCryptProv = 0; // CSP handle PCCERT_CONTEXT pUserCert = NULL; // User certificate to be used DWORD keytype = 0; CSP_BOOL should_release_ctx = FALSE; DWORD ret = 1; FILE *tbs = NULL; BYTE *mem_tbs = NULL; DWORD mem_len = 0; HCRYPTMSG hMsg = 0; DWORD HashAlgSize; DWORD dwSize; CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm; CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo; CERT_BLOB SignerCertBlob; CERT_BLOB SignerCertBlobArray[1]; DWORD cbEncodedBlob; BYTE *pbEncodedBlob = NULL; CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1]; CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo; CSP_BOOL bResult = FALSE; CRYPT_KEY_PROV_INFO *pProvInfo = NULL; HCERTSTORE hCertStore = 0; hCertStore = CertOpenSystemStore(0, "My"); if(!hCertStore){ ret = CSP_GetLastError(); fprintf (stderr, "CertOpenSystemStore failed."); goto err; } while( !bResult){ pUserCert= CertEnumCertificatesInStore(hCertStore, pUserCert); if(!pUserCert){ break; } bResult = CertGetCertificateContextProperty( pUserCert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwSize); if (bResult) { free(pProvInfo); pProvInfo = (CRYPT_KEY_PROV_INFO *)malloc(dwSize); if (pProvInfo) { bResult = CertGetCertificateContextProperty( pUserCert, CERT_KEY_PROV_INFO_PROP_ID, pProvInfo, &dwSize); } } } if(!bResult){ fprintf (stderr, "No certificates with private key link."); goto err; } if (! infile) { fprintf (stderr, "No input file was specified\n"); goto err; } if (CryptAcquireCertificatePrivateKey( pUserCert, 0, //DWORD dwFlags, NULL, &hCryptProv, &keytype, // returned key type AT_SIGNATURE ! AT_KEYEXCAHGE &should_release_ctx // if FALSE DO NOT Release CTX )) { printf("A CSP has been acquired. \n"); } else { ret = CSP_GetLastError(); fprintf (stderr, "Cryptographic context could not be acquired."); goto err; } tbs = fopen (infile, "rb"); if (!tbs) { fprintf (stderr, "Cannot open input file\n"); goto err; } mem_len = 0; while (!feof(tbs)) { int r = 0; BYTE tmp[1024]; r = fread (tmp, 1, 1024, tbs); mem_tbs = (BYTE *)realloc(mem_tbs, mem_len+r); memcpy (&mem_tbs[mem_len], tmp, r); mem_len += r; } fclose (tbs); tbs = NULL; //-------------------------------------------------------------------- // Initialize the algorithm identifier structure. HashAlgSize = sizeof(HashAlgorithm); memset(&HashAlgorithm, 0, HashAlgSize); // Init. to zero. HashAlgorithm.pszObjId = OID; // Initialize the necessary member. //-------------------------------------------------------------------- // Initialize the CMSG_SIGNER_ENCODE_INFO structure. memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO)); SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO); SignerEncodeInfo.pCertInfo = pUserCert->pCertInfo; SignerEncodeInfo.hCryptProv = hCryptProv; SignerEncodeInfo.dwKeySpec = keytype; SignerEncodeInfo.HashAlgorithm = HashAlgorithm; SignerEncodeInfo.pvHashAuxInfo = NULL; //-------------------------------------------------------------------- // Create an array of one. Note: Currently, there can be only one // signer. SignerEncodeInfoArray[0] = SignerEncodeInfo; //-------------------------------------------------------------------- // Initialize the CMSG_SIGNED_ENCODE_INFO structure. SignerCertBlob.cbData = pUserCert->cbCertEncoded; SignerCertBlob.pbData = pUserCert->pbCertEncoded; //-------------------------------------------------------------------- // Initialize the array of one CertBlob. SignerCertBlobArray[0] = SignerCertBlob; memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO)); SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO); SignedMsgEncodeInfo.cSigners = 1; SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray; SignedMsgEncodeInfo.cCertEncoded = include; if (include) SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray; else SignedMsgEncodeInfo.rgCertEncoded = NULL; SignedMsgEncodeInfo.rgCrlEncoded = NULL; //-------------------------------------------------------------------- // Get the size of the encoded message blob. if(cbEncodedBlob = CryptMsgCalculateEncodedLength( TYPE_DER, // Message encoding type 0, // Flags CMSG_SIGNED, // Message type &SignedMsgEncodeInfo, // Pointer to structure NULL, // Inner content object ID mem_len)) // Size of content */ { printf("The length of the data has been calculated. \n"); } else { ret = CSP_GetLastError(); fprintf (stderr, "Getting cbEncodedBlob length failed"); goto err; } //-------------------------------------------------------------------- // Allocate memory for the encoded blob. pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob); if (!pbEncodedBlob){ ret = CSP_GetLastError(); fprintf (stderr, "Memory allocation failed"); goto err; } //-------------------------------------------------------------------- // Open a message to encode. if(hMsg = CryptMsgOpenToEncode( TYPE_DER, // Encoding type 0, // Flags CMSG_SIGNED, // Message type &SignedMsgEncodeInfo, // Pointer to structure NULL, // Inner content object ID NULL)) // Stream information (not used) { printf("The message to be encoded has been opened. \n"); } else { ret = CSP_GetLastError(); fprintf (stderr, "OpenToEncode failed"); goto err; } //-------------------------------------------------------------------- // Update the message with the data. if(CryptMsgUpdate( hMsg, // Handle to the message mem_tbs, // Pointer to the content mem_len, // Size of the content TRUE)) // Last call { printf("Content has been added to the encoded message. \n"); } else { ret = CSP_GetLastError(); fprintf (stderr, "MsgUpdate failed"); goto err; } //-------------------------------------------------------------------- // Get the resulting message. if(CryptMsgGetParam( hMsg, // Handle to the message CMSG_CONTENT_PARAM, // Parameter type 0, // Index pbEncodedBlob, // Pointer to the blob &cbEncodedBlob)) // Size of the blob { printf("Message encoded successfully. \n"); } else { ret = CSP_GetLastError(); fprintf (stderr, "MsgGetParam failed"); goto err; } //-------------------------------------------------------------------- // pbEncodedBlob now points to the encoded, signed content. //-------------------------------------------------------------------- if (outfile) { FILE *out = NULL; out = fopen (outfile, "wb"); if (out) { fwrite (pbEncodedBlob, cbEncodedBlob, 1, out); fclose (out); printf ("Output file (%s) has been saved\n", outfile); } else perror ("Cannot open out file\n"); } ret = 0; //-------------------------------------------------------------------- // Clean up. err: if(pbEncodedBlob) free(pbEncodedBlob); if(hMsg) CryptMsgClose(hMsg); if(hCryptProv) CryptReleaseContext(hCryptProv,0); if(hCertStore) CertCloseStore(hCertStore, 0); return ret; }
static BOOL compare_crl_issued_by(PCCRL_CONTEXT pCrlContext, DWORD dwType, DWORD dwFlags, const void *pvPara) { BOOL ret; if (pvPara) { PCCERT_CONTEXT issuer = pvPara; ret = CertCompareCertificateName(issuer->dwCertEncodingType, &issuer->pCertInfo->Subject, &pCrlContext->pCrlInfo->Issuer); if (ret && (dwFlags & CRL_FIND_ISSUED_BY_SIGNATURE_FLAG)) ret = CryptVerifyCertificateSignatureEx(0, issuer->dwCertEncodingType, CRYPT_VERIFY_CERT_SIGN_SUBJECT_CRL, (void *)pCrlContext, CRYPT_VERIFY_CERT_SIGN_ISSUER_CERT, (void *)issuer, 0, NULL); if (ret && (dwFlags & CRL_FIND_ISSUED_BY_AKI_FLAG)) { PCERT_EXTENSION ext = CertFindExtension( szOID_AUTHORITY_KEY_IDENTIFIER2, pCrlContext->pCrlInfo->cExtension, pCrlContext->pCrlInfo->rgExtension); if (ext) { CERT_AUTHORITY_KEY_ID2_INFO *info; DWORD size; if ((ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_AUTHORITY_KEY_ID2, ext->Value.pbData, ext->Value.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size))) { if (info->AuthorityCertIssuer.cAltEntry && info->AuthorityCertSerialNumber.cbData) { PCERT_ALT_NAME_ENTRY directoryName = NULL; DWORD i; for (i = 0; !directoryName && i < info->AuthorityCertIssuer.cAltEntry; i++) if (info->AuthorityCertIssuer.rgAltEntry[i]. dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME) directoryName = &info->AuthorityCertIssuer.rgAltEntry[i]; if (directoryName) { ret = CertCompareCertificateName( issuer->dwCertEncodingType, &issuer->pCertInfo->Subject, &directoryName->u.DirectoryName); if (ret) ret = CertCompareIntegerBlob( &issuer->pCertInfo->SerialNumber, &info->AuthorityCertSerialNumber); } else { FIXME("no supported name type in authority key id2\n"); ret = FALSE; } } else if (info->KeyId.cbData) { DWORD size; ret = CertGetCertificateContextProperty(issuer, CERT_KEY_IDENTIFIER_PROP_ID, NULL, &size); if (ret && size == info->KeyId.cbData) { LPBYTE buf = CryptMemAlloc(size); if (buf) { CertGetCertificateContextProperty(issuer, CERT_KEY_IDENTIFIER_PROP_ID, buf, &size); ret = !memcmp(buf, info->KeyId.pbData, size); CryptMemFree(buf); } else ret = FALSE; } else ret = FALSE; } else { FIXME("unsupported value for AKI extension\n"); ret = FALSE; } LocalFree(info); } } /* else: a CRL without an AKI matches any cert */ } } else ret = TRUE; return ret; }
// Display a UI with the certificate info and also write it to the debug output HRESULT ShowCertInfo(PCCERT_CONTEXT pCertContext, CString Title) { TCHAR pszNameString[256]; void* pvData; DWORD cbData; DWORD dwPropId = 0; // Display the certificate. if (!CryptUIDlgViewContext( CERT_STORE_CERTIFICATE_CONTEXT, pCertContext, NULL, CStringW(Title), 0, NULL)) { DebugMsg("UI failed."); } if (CertGetNameString( pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, 128)) { DebugMsg("Certificate for %S", ATL::CT2W(pszNameString)); } else DebugMsg("CertGetName failed."); int Extensions = pCertContext->pCertInfo->cExtension; auto *p = pCertContext->pCertInfo->rgExtension; for (int i = 0; i < Extensions; i++) { DebugMsg("Extension %s", (p++)->pszObjId); } //------------------------------------------------------------------- // Loop to find all of the property identifiers for the specified // certificate. The loop continues until // CertEnumCertificateContextProperties returns zero. while (0 != (dwPropId = CertEnumCertificateContextProperties( pCertContext, // The context whose properties are to be listed. dwPropId))) // Number of the last property found. // This must be zero to find the first // property identifier. { //------------------------------------------------------------------- // When the loop is executed, a property identifier has been found. // Print the property number. DebugMsg("Property # %d found->", dwPropId); //------------------------------------------------------------------- // Indicate the kind of property found. switch (dwPropId) { case CERT_FRIENDLY_NAME_PROP_ID: { DebugMsg("Friendly name: "); break; } case CERT_SIGNATURE_HASH_PROP_ID: { DebugMsg("Signature hash identifier "); break; } case CERT_KEY_PROV_HANDLE_PROP_ID: { DebugMsg("KEY PROVE HANDLE"); break; } case CERT_KEY_PROV_INFO_PROP_ID: { DebugMsg("KEY PROV INFO PROP ID "); break; } case CERT_SHA1_HASH_PROP_ID: { DebugMsg("SHA1 HASH identifier"); break; } case CERT_MD5_HASH_PROP_ID: { DebugMsg("md5 hash identifier "); break; } case CERT_KEY_CONTEXT_PROP_ID: { DebugMsg("KEY CONTEXT PROP identifier"); break; } case CERT_KEY_SPEC_PROP_ID: { DebugMsg("KEY SPEC PROP identifier"); break; } case CERT_ENHKEY_USAGE_PROP_ID: { DebugMsg("ENHKEY USAGE PROP identifier"); break; } case CERT_NEXT_UPDATE_LOCATION_PROP_ID: { DebugMsg("NEXT UPDATE LOCATION PROP identifier"); break; } case CERT_PVK_FILE_PROP_ID: { DebugMsg("PVK FILE PROP identifier "); break; } case CERT_DESCRIPTION_PROP_ID: { DebugMsg("DESCRIPTION PROP identifier "); break; } case CERT_ACCESS_STATE_PROP_ID: { DebugMsg("ACCESS STATE PROP identifier "); break; } case CERT_SMART_CARD_DATA_PROP_ID: { DebugMsg("SMART_CARD DATA PROP identifier "); break; } case CERT_EFS_PROP_ID: { DebugMsg("EFS PROP identifier "); break; } case CERT_FORTEZZA_DATA_PROP_ID: { DebugMsg("FORTEZZA DATA PROP identifier "); break; } case CERT_ARCHIVED_PROP_ID: { DebugMsg("ARCHIVED PROP identifier "); break; } case CERT_KEY_IDENTIFIER_PROP_ID: { DebugMsg("KEY IDENTIFIER PROP identifier "); break; } case CERT_AUTO_ENROLL_PROP_ID: { DebugMsg("AUTO ENROLL identifier. "); break; } case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID: { DebugMsg("ISSUER PUBLIC KEY MD5 HASH identifier. "); break; } } // End switch. //------------------------------------------------------------------- // Retrieve information on the property by first getting the // property size. // For more information, see CertGetCertificateContextProperty. if (CertGetCertificateContextProperty( pCertContext, dwPropId, NULL, &cbData)) { // Continue. } else { // If the first call to the function failed, // exit to an error routine. DebugMsg("Call #1 to GetCertContextProperty failed."); return E_FAIL; } //------------------------------------------------------------------- // The call succeeded. Use the size to allocate memory // for the property. if (NULL != (pvData = (void*)malloc(cbData))) { // Memory is allocated. Continue. } else { // If memory allocation failed, exit to an error routine. DebugMsg("Memory allocation failed."); return E_FAIL; } //---------------------------------------------------------------- // Allocation succeeded. Retrieve the property data. if (CertGetCertificateContextProperty( pCertContext, dwPropId, pvData, &cbData)) { // The data has been retrieved. Continue. } else { // If an error occurred in the second call, // exit to an error routine. DebugMsg("Call #2 failed."); return E_FAIL; } //--------------------------------------------------------------- // Show the results. DebugMsg("The Property Content is"); PrintHexDump(cbData, pvData); //---------------------------------------------------------------- // Free the certificate context property memory. free(pvData); } return S_OK; }