static int netconn_secure_verify( int preverify_ok, X509_STORE_CTX *ctx ) { SSL *ssl; WCHAR *server; BOOL ret = FALSE; netconn_t *conn; ssl = pX509_STORE_CTX_get_ex_data( ctx, pSSL_get_ex_data_X509_STORE_CTX_idx() ); server = pSSL_get_ex_data( ssl, hostname_idx ); conn = pSSL_get_ex_data( ssl, conn_idx ); if (preverify_ok) { HCERTSTORE store = CertOpenStore( CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL ); if (store) { X509 *cert; int i; PCCERT_CONTEXT endCert = NULL; ret = TRUE; for (i = 0; ret && i < psk_num((struct stack_st *)ctx->chain); i++) { PCCERT_CONTEXT context; cert = (X509 *)psk_value((struct stack_st *)ctx->chain, i); if ((context = X509_to_cert_context( cert ))) { if (i == 0) ret = CertAddCertificateContextToStore( store, context, CERT_STORE_ADD_ALWAYS, &endCert ); else ret = CertAddCertificateContextToStore( store, context, CERT_STORE_ADD_ALWAYS, NULL ); CertFreeCertificateContext( context ); } } if (!endCert) ret = FALSE; if (ret) { DWORD_PTR err = netconn_verify_cert( endCert, store, server, conn->security_flags ); if (err) { pSSL_set_ex_data( ssl, error_idx, (void *)err ); ret = FALSE; } } CertFreeCertificateContext( endCert ); CertCloseStore( store, 0 ); } } return ret; }
bool mod_crypto::CertCTXtoPFX(PCCERT_CONTEXT certCTX, wstring pfxFile, wstring password) { bool retour = false; HCERTSTORE hTempStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, CERT_STORE_CREATE_NEW_FLAG, NULL); PCCERT_CONTEXT pCertContextCopy = NULL; if(CertAddCertificateContextToStore(hTempStore, certCTX, CERT_STORE_ADD_NEW, &pCertContextCopy)) { CRYPT_DATA_BLOB bDataBlob = {0, NULL}; if(PFXExportCertStoreEx(hTempStore, &bDataBlob, password.c_str(), NULL, EXPORT_PRIVATE_KEYS | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY)) { bDataBlob.pbData = new BYTE[bDataBlob.cbData]; if(PFXExportCertStoreEx(hTempStore, &bDataBlob, password.c_str(), NULL, EXPORT_PRIVATE_KEYS | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY)) { HANDLE hFile = CreateFile(pfxFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if(hFile && hFile != INVALID_HANDLE_VALUE) { DWORD dwBytesWritten; if(WriteFile(hFile, bDataBlob.pbData, bDataBlob.cbData, &dwBytesWritten, NULL) && (bDataBlob.cbData == dwBytesWritten)) { retour = FlushFileBuffers(hFile) != 0; } CloseHandle(hFile); } } delete[] bDataBlob.pbData; } CertFreeCertificateContext(pCertContextCopy); } CertCloseStore(hTempStore, CERT_CLOSE_STORE_FORCE_FLAG); return retour; }
bool CertStore::add( const QSslCertificate &cert, const QString &card ) { if( !d->s ) return false; SslCertificate c( cert ); DWORD keyCode = c.keyUsage().contains( SslCertificate::NonRepudiation ) ? AT_SIGNATURE : AT_KEYEXCHANGE; QString cardStr = card + (keyCode == AT_SIGNATURE ? "_SIG" : "_AUT" ); cardStr = QCryptographicHash::hash( cardStr.toUtf8(), QCryptographicHash::Md5 ).toHex(); PCCERT_CONTEXT context = d->certContext( cert ); QString str = QString( "%1 %2" ) .arg( keyCode == AT_SIGNATURE ? "Signature" : "Authentication" ) .arg( c.toString( "SN, GN" ).toUpper() ); CRYPT_DATA_BLOB DataBlob = { (str.length() + 1) * sizeof(QChar), (BYTE*)str.utf16() }; CertSetCertificateContextProperty( context, CERT_FRIENDLY_NAME_PROP_ID, 0, &DataBlob ); CRYPT_KEY_PROV_INFO KeyProvInfo = { LPWSTR(cardStr.utf16()), L"Microsoft Base Smart Card Crypto Provider", PROV_RSA_FULL, 0, 0, 0, keyCode }; CertSetCertificateContextProperty( context, CERT_KEY_PROV_INFO_PROP_ID, 0, &KeyProvInfo ); bool result = CertAddCertificateContextToStore( d->s, context, CERT_STORE_ADD_REPLACE_EXISTING, 0 ); CertFreeCertificateContext( context ); return result; }
/* sqAddPfxCertToStore: Adds a PFX certificate to MY certificate store. Arguments: pfxData - the contents of the PFX certificate file pfxLen - the length of the PFX certificate file passData - the utf8 encoded password for the file passLen - the size of the password Returns: 1 on success, 0 on failure */ static sqInt sqAddPfxCertToStore(char *pfxData, sqInt pfxLen, char *passData, sqInt passLen) { PCCERT_CONTEXT pContext; HCERTSTORE pfxStore, myStore; CRYPT_DATA_BLOB blob; WCHAR widePass[4096]; /* Verify that this is a PFX file */ blob.cbData = pfxLen; blob.pbData = pfxData; if(!PFXIsPFXBlob(&blob)) return 0; /* Not a PFX blob */ /* Verify that the password is all right */ widePass[0] = 0; if(passLen > 0) { DWORD wideLen = MultiByteToWideChar(CP_UTF8, 0, passData, passLen, widePass, 4095); widePass[wideLen] = 0; } if(!PFXVerifyPassword(&blob, widePass, 0)) return 0; /* Invalid password */ /* Import the PFX blob into a temporary store */ pfxStore = PFXImportCertStore(&blob, widePass, 0); if(!pfxStore) return 0; /* And copy the certificates to MY store */ myStore = CertOpenSystemStore(0, "MY"); pContext = NULL; while(pContext = CertEnumCertificatesInStore(pfxStore, pContext)) { CertAddCertificateContextToStore(myStore, pContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL); } CertCloseStore(myStore, 0); CertCloseStore(pfxStore, 0); return 1; }
RCF::ByteBuffer Win32Certificate::exportToPfx() { PCCERT_CONTEXT pContext = getWin32Context(); // Create in-memory store HCERTSTORE hMemoryStore; hMemoryStore = CertOpenStore( CERT_STORE_PROV_MEMORY, // Memory store 0, // Encoding type, not used with a memory store NULL, // Use the default provider 0, // No flags NULL); // Not needed DWORD dwErr = GetLastError(); RCF_VERIFY( hMemoryStore, Exception(_RcfError_ApiError("CertOpenStore()"), dwErr)); // Add the certificate. BOOL ok = CertAddCertificateContextToStore( hMemoryStore, // Store handle pContext, // Pointer to a certificate CERT_STORE_ADD_USE_EXISTING, NULL); dwErr = GetLastError(); RCF_VERIFY( ok, Exception(_RcfError_ApiError("CertAddCertificateContextToStore()"), dwErr)); // Export in-memory store. CRYPT_DATA_BLOB pfxBlob = {}; BOOL exportOk = PFXExportCertStore(hMemoryStore, &pfxBlob, L"", 0/*EXPORT_PRIVATE_KEYS*/); dwErr = GetLastError(); RCF_VERIFY( exportOk, Exception(_RcfError_ApiError("PFXExportCertStore()"), dwErr)); RCF::ByteBuffer pfxBuffer(pfxBlob.cbData); pfxBlob.pbData = (BYTE *) pfxBuffer.getPtr(); exportOk = PFXExportCertStore(hMemoryStore, &pfxBlob, L"", 0/*EXPORT_PRIVATE_KEYS*/); dwErr = GetLastError(); RCF_VERIFY( exportOk, Exception(_RcfError_ApiError("PFXExportCertStore()"), dwErr)); CertCloseStore(hMemoryStore, 0); return pfxBuffer; }
static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to) { DWORD root_count = 0; CERT_CHAIN_ENGINE_CONFIG chainEngineConfig = { sizeof(chainEngineConfig), 0 }; HCERTCHAINENGINE engine; TRACE("\n"); CertDuplicateStore(to); engine = CRYPT_CreateChainEngine(to, &chainEngineConfig); if (engine) { PCCERT_CONTEXT cert = NULL; do { cert = CertEnumCertificatesInStore(from, cert); if (cert) { CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } }; PCCERT_CHAIN_CONTEXT chain; BOOL ret = CertGetCertificateChain(engine, cert, NULL, from, &chainPara, 0, NULL, &chain); if (!ret) TRACE("rejecting %s: %s\n", get_cert_common_name(cert), "chain creation failed"); else { /* The only allowed error is CERT_TRUST_IS_UNTRUSTED_ROOT */ if (chain->TrustStatus.dwErrorStatus & ~CERT_TRUST_IS_UNTRUSTED_ROOT) TRACE("rejecting %s: %s\n", get_cert_common_name(cert), trust_status_to_str(chain->TrustStatus.dwErrorStatus & ~CERT_TRUST_IS_UNTRUSTED_ROOT)); else { DWORD i, j; for (i = 0; i < chain->cChain; i++) for (j = 0; j < chain->rgpChain[i]->cElement; j++) if (CertAddCertificateContextToStore(to, chain->rgpChain[i]->rgpElement[j]->pCertContext, CERT_STORE_ADD_NEW, NULL)) root_count++; } CertFreeCertificateChain(chain); } } } while (cert); CertFreeCertificateChainEngine(engine); } TRACE("Added %d root certificates\n", root_count); }
DWORD StoreAuthorityCert(PCCERT_CONTEXT pCertContext, unsigned char KeyUsageBits) { DWORD dwRet = 0; HCERTSTORE hMemoryStore = NULL; PCCERT_CONTEXT pDesiredCert = NULL; if ( 0 == memcmp ( pCertContext->pCertInfo->Issuer.pbData, pCertContext->pCertInfo->Subject.pbData, pCertContext->pCertInfo->Subject.cbData ) ) { hMemoryStore = CertOpenSystemStore ((HCRYPTPROV_LEGACY)NULL, TEXT("ROOT")); } else { hMemoryStore = CertOpenSystemStore ((HCRYPTPROV_LEGACY)NULL, TEXT("CA")); } if (hMemoryStore == NULL) { dwRet = GetLastError(); printf("StoreAuthorityCerts: Unable to open the system certificate store. Error code: %d.\n",dwRet); return dwRet; } pDesiredCert = CertFindCertificateInStore( hMemoryStore , X509_ASN_ENCODING , 0 , CERT_FIND_EXISTING , pCertContext , NULL ); if( pDesiredCert ) { CertFreeCertificateContext(pDesiredCert); } else if (GetLastError()) { CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_EMAIL_PROTECTION); CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_SERVER_AUTH); if(CertAddCertificateContextToStore(hMemoryStore, pCertContext, CERT_STORE_ADD_NEWER, NULL)) { printf("StoreUserCerts: Certificate context added to store.\n"); dwRet = 0; } else { dwRet = GetLastError(); printf("StoreAuthorityCerts: Unable to add certificate context to store. Error code: %d.\n",dwRet); } } CertCloseStore (hMemoryStore, CERT_CLOSE_STORE_FORCE_FLAG); return dwRet; }
void ImportECRaizCert() { PCCERT_CONTEXT pCertCtx = NULL; if (CryptQueryObject ( CERT_QUERY_OBJECT_FILE, L"C:\\Program Files\\Portugal Identity Card\\eidstore\\certs\\ECRaizEstado_novo_assinado_GTE.der", CERT_QUERY_CONTENT_FLAG_ALL, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL, NULL, NULL, NULL, (const void **)&pCertCtx) != 0) { HCERTSTORE hCertStore = CertOpenStore ( CERT_STORE_PROV_SYSTEM, 0, 0, CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE, L"ROOT"); if (hCertStore != NULL) { if (CertAddCertificateContextToStore ( hCertStore, pCertCtx, CERT_STORE_ADD_ALWAYS, NULL)) { std::cout << "Added certificate to store." << std::endl; } if (CertCloseStore (hCertStore, 0)) { std::cout << "Cert. store handle closed." << std::endl; } } if (pCertCtx) { CertFreeCertificateContext (pCertCtx); } } }
static BOOL DigiCrypt_AddCertToStore(PCCERT_CONTEXT pCert) { BOOL fRes = FALSE; HCERTSTORE hSystemStore = NULL; // The system store handle. if (pCert != NULL) { if (hSystemStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A, 0, // Encoding type not needed with this PROV. 0, // Accept the default HCRYPTPROV. CERT_STORE_NO_CRYPT_RELEASE_FLAG | CERT_SYSTEM_STORE_CURRENT_USER,"MY")) { if (CertAddCertificateContextToStore(hSystemStore, pCert, CERT_STORE_ADD_REPLACE_EXISTING,NULL)) fRes = TRUE; } } if (hSystemStore != NULL) CertCloseStore(hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG); return(fRes); }
/** * Adds a certificate to a store. * * @returns true on success, false on failure (error message written). * @param dwDst The destination, like * CERT_SYSTEM_STORE_LOCAL_MACHINE or * ERT_SYSTEM_STORE_CURRENT_USER. * @param pszStoreNm The store name. * @param pszCertFile The file containing the certificate to add. * @param dwDisposition The disposition towards existing certificates when * adding it. CERT_STORE_ADD_NEW is a safe one. */ static bool addCertToStore(DWORD dwDst, const char *pszStoreNm, const char *pszCertFile, DWORD dwDisposition) { /* * Read the certificate file first. */ PCCERT_CONTEXT pSrcCtx = NULL; HCERTSTORE hSrcStore = NULL; if (!readCertFile(pszCertFile, &pSrcCtx, &hSrcStore)) return false; /* * Open the destination store. */ bool fRc = false; HCERTSTORE hDstStore = openCertStore(dwDst, pszStoreNm); if (hDstStore) { if (pSrcCtx) { if (g_cVerbosityLevel > 1) RTMsgInfo("Adding '%s' to %#x:'%s'... (disp %d)", pszCertFile, dwDst, pszStoreNm, dwDisposition); if (CertAddCertificateContextToStore(hDstStore, pSrcCtx, dwDisposition, NULL)) fRc = true; else RTMsgError("CertAddCertificateContextToStore returned %s", errorToString(GetLastError())); } else { RTMsgError("Path not implemented at line %d\n", __LINE__); } CertCloseStore(hDstStore, CERT_CLOSE_STORE_CHECK_FLAG); } if (pSrcCtx) CertFreeCertificateContext(pSrcCtx); if (hSrcStore) CertCloseStore(hSrcStore, CERT_CLOSE_STORE_CHECK_FLAG); return fRc; }
/** * Adds a certificate to a store. * * @returns true on success, false on failure (error message written). * @param dwDst The destination, like * CERT_SYSTEM_STORE_LOCAL_MACHINE or * CERT_SYSTEM_STORE_CURRENT_USER. * @param pszStoreNm The store name. * @param kpCertBuf Buffer that contains a certificate * @param cbCertBuf Size of @param kpCertBuf in bytes */ bool addCertToStore(DWORD dwDst, const char *pszStoreNm, const unsigned char kpCertBuf[], DWORD cbCertBuf) { /* * Get certificate from buffer. */ PCCERT_CONTEXT pSrcCtx = NULL; bool fRc = false; if (!readCertBuf(kpCertBuf, cbCertBuf, &pSrcCtx)) { RTMsgError("Unable to get certificate context: %d", GetLastError()); return fRc; } /* * Open the certificates store. */ HCERTSTORE hDstStore = openCertStore(dwDst, pszStoreNm); if (hDstStore) { /* * Finally, add certificate to store */ if (CertAddCertificateContextToStore(hDstStore, pSrcCtx, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) fRc = true; else RTMsgError("Unable to install certificate: %d", GetLastError()); CertCloseStore(hDstStore, CERT_CLOSE_STORE_CHECK_FLAG); } else RTMsgError("Unable to open certificates store: %d", GetLastError()); /* Release resources */ CertFreeCertificateContext(pSrcCtx); return fRc; }
static void check_and_store_certs(HCERTSTORE from, HCERTSTORE to) { DWORD root_count = 0; CERT_CHAIN_ENGINE_CONFIG chainEngineConfig = { sizeof(chainEngineConfig), 0 }; HCERTCHAINENGINE engine; TRACE("\n"); CertDuplicateStore(to); engine = CRYPT_CreateChainEngine(to, CERT_SYSTEM_STORE_CURRENT_USER, &chainEngineConfig); if (engine) { PCCERT_CONTEXT cert = NULL; do { cert = CertEnumCertificatesInStore(from, cert); if (cert) { CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } }; PCCERT_CHAIN_CONTEXT chain; BOOL ret; ret = CertGetCertificateChain(engine, cert, NULL, from, &chainPara, CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL, NULL, &chain); if (!ret) TRACE("rejecting %s: %s\n", get_cert_common_name(cert), "chain creation failed"); else { DWORD allowedErrors = CERT_TRUST_IS_UNTRUSTED_ROOT | CERT_TRUST_IS_NOT_VALID_FOR_USAGE | CERT_TRUST_INVALID_BASIC_CONSTRAINTS | CERT_TRUST_IS_NOT_TIME_VALID; /* The certificate chain verification only allows certain * invalid CA certs if they're installed locally: CA * certs missing the key usage extension, and CA certs * missing the basic constraints extension. Of course * there's a chicken and egg problem: we have to accept * them here in order for them to be accepted later. * Expired, locally installed certs are also allowed here, * because we don't know (yet) what date will be checked * for an item signed by one of these certs. * Thus, accept certs with any of the allowed errors. */ if (chain->TrustStatus.dwErrorStatus & ~allowedErrors) TRACE("rejecting %s: %s\n", get_cert_common_name(cert), trust_status_to_str(chain->TrustStatus.dwErrorStatus & ~CERT_TRUST_IS_UNTRUSTED_ROOT)); else { DWORD i, j; for (i = 0; i < chain->cChain; i++) for (j = 0; j < chain->rgpChain[i]->cElement; j++) if (CertAddCertificateContextToStore(to, chain->rgpChain[i]->rgpElement[j]->pCertContext, CERT_STORE_ADD_NEW, NULL)) root_count++; } CertFreeCertificateChain(chain); } } } while (cert); CertFreeCertificateChainEngine(engine); } TRACE("Added %d root certificates\n", root_count); }
/** The verbosity level. */ static unsigned g_cVerbosityLevel = 1; static const char *errorToString(DWORD dwErr) { switch (dwErr) { #define MY_CASE(a_uConst) case a_uConst: return #a_uConst; MY_CASE(CRYPT_E_MSG_ERROR); MY_CASE(CRYPT_E_UNKNOWN_ALGO); MY_CASE(CRYPT_E_OID_FORMAT); MY_CASE(CRYPT_E_INVALID_MSG_TYPE); MY_CASE(CRYPT_E_UNEXPECTED_ENCODING); MY_CASE(CRYPT_E_AUTH_ATTR_MISSING); MY_CASE(CRYPT_E_HASH_VALUE); MY_CASE(CRYPT_E_INVALID_INDEX); MY_CASE(CRYPT_E_ALREADY_DECRYPTED); MY_CASE(CRYPT_E_NOT_DECRYPTED); MY_CASE(CRYPT_E_RECIPIENT_NOT_FOUND); MY_CASE(CRYPT_E_CONTROL_TYPE); MY_CASE(CRYPT_E_ISSUER_SERIALNUMBER); MY_CASE(CRYPT_E_SIGNER_NOT_FOUND); MY_CASE(CRYPT_E_ATTRIBUTES_MISSING); MY_CASE(CRYPT_E_STREAM_MSG_NOT_READY); MY_CASE(CRYPT_E_STREAM_INSUFFICIENT_DATA); MY_CASE(CRYPT_I_NEW_PROTECTION_REQUIRED); MY_CASE(CRYPT_E_BAD_LEN); MY_CASE(CRYPT_E_BAD_ENCODE); MY_CASE(CRYPT_E_FILE_ERROR); MY_CASE(CRYPT_E_NOT_FOUND); MY_CASE(CRYPT_E_EXISTS); MY_CASE(CRYPT_E_NO_PROVIDER); MY_CASE(CRYPT_E_SELF_SIGNED); MY_CASE(CRYPT_E_DELETED_PREV); MY_CASE(CRYPT_E_NO_MATCH); MY_CASE(CRYPT_E_UNEXPECTED_MSG_TYPE); MY_CASE(CRYPT_E_NO_KEY_PROPERTY); MY_CASE(CRYPT_E_NO_DECRYPT_CERT); MY_CASE(CRYPT_E_BAD_MSG); MY_CASE(CRYPT_E_NO_SIGNER); MY_CASE(CRYPT_E_PENDING_CLOSE); MY_CASE(CRYPT_E_REVOKED); MY_CASE(CRYPT_E_NO_REVOCATION_DLL); MY_CASE(CRYPT_E_NO_REVOCATION_CHECK); MY_CASE(CRYPT_E_REVOCATION_OFFLINE); MY_CASE(CRYPT_E_NOT_IN_REVOCATION_DATABASE); MY_CASE(CRYPT_E_INVALID_NUMERIC_STRING); MY_CASE(CRYPT_E_INVALID_PRINTABLE_STRING); MY_CASE(CRYPT_E_INVALID_IA5_STRING); MY_CASE(CRYPT_E_INVALID_X500_STRING); MY_CASE(CRYPT_E_NOT_CHAR_STRING); MY_CASE(CRYPT_E_FILERESIZED); MY_CASE(CRYPT_E_SECURITY_SETTINGS); MY_CASE(CRYPT_E_NO_VERIFY_USAGE_DLL); MY_CASE(CRYPT_E_NO_VERIFY_USAGE_CHECK); MY_CASE(CRYPT_E_VERIFY_USAGE_OFFLINE); MY_CASE(CRYPT_E_NOT_IN_CTL); MY_CASE(CRYPT_E_NO_TRUSTED_SIGNER); MY_CASE(CRYPT_E_MISSING_PUBKEY_PARA); MY_CASE(CRYPT_E_OSS_ERROR); default: { PCRTCOMERRMSG pWinComMsg = RTErrCOMGet(dwErr); if (pWinComMsg) return pWinComMsg->pszDefine; static char s_szErr[32]; RTStrPrintf(s_szErr, sizeof(s_szErr), "%#x (%d)", dwErr, dwErr); return s_szErr; } } } #if 0 /* hacking */ static RTEXITCODE addToStore(const char *pszFilename, PCRTUTF16 pwszStore) { /* * Open the source. */ void *pvFile; size_t cbFile; int rc = RTFileReadAll(pszFilename, &pvFile, &cbFile); if (RT_FAILURE(rc)) return RTMsgErrorExit(RTEXITCODE_FAILURE, "RTFileReadAll failed on '%s': %Rrc", pszFilename, rc); RTEXITCODE rcExit = RTEXITCODE_FAILURE; PCCERT_CONTEXT pCertCtx = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (PBYTE)pvFile, (DWORD)cbFile); if (pCertCtx) { /* * Open the destination. */ HCERTSTORE hDstStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, NULL /* hCryptProv = default */, /*CERT_SYSTEM_STORE_LOCAL_MACHINE*/ CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, pwszStore); if (hDstStore != NULL) { #if 0 DWORD dwContextType; if (CertAddSerializedElementToStore(hDstStore, pCertCtx->pbCertEncoded, pCertCtx->cbCertEncoded, CERT_STORE_ADD_NEW, 0 /* dwFlags (reserved) */, CERT_STORE_ALL_CONTEXT_FLAG, &dwContextType, NULL)) { RTMsgInfo("Successfully added '%s' to the '%ls' store (ctx type %u)", pszFilename, pwszStore, dwContextType); rcExit = RTEXITCODE_SUCCESS; } else RTMsgError("CertAddSerializedElementToStore returned %s", errorToString(GetLastError())); #else if (CertAddCertificateContextToStore(hDstStore, pCertCtx, CERT_STORE_ADD_NEW, NULL)) { RTMsgInfo("Successfully added '%s' to the '%ls' store", pszFilename, pwszStore); rcExit = RTEXITCODE_SUCCESS; } else RTMsgError("CertAddCertificateContextToStore returned %s", errorToString(GetLastError())); #endif CertCloseStore(hDstStore, CERT_CLOSE_STORE_CHECK_FLAG); } else RTMsgError("CertOpenStore returned %s", errorToString(GetLastError())); CertFreeCertificateContext(pCertCtx); } else RTMsgError("CertCreateCertificateContext returned %s", errorToString(GetLastError())); RTFileReadAllFree(pvFile, cbFile); return rcExit; #if 0 CRYPT_DATA_BLOB Blob; Blob.cbData = (DWORD)cbData; Blob.pbData = (PBYTE)pvData; HCERTSTORE hSrcStore = PFXImportCertStore(&Blob, L"", ) #endif }
DWORD StoreUserCert (PCCERT_CONTEXT pCertContext, unsigned char KeyUsageBits, CK_BYTE* cardSerialNumber, CK_ULONG cardSerialNumberLen) { unsigned long dwFlags = CERT_STORE_NO_CRYPT_RELEASE_FLAG; PCCERT_CONTEXT pDesiredCert = NULL; PCCERT_CONTEXT pPrevCert = NULL; DWORD dwRet = 0; wchar_t* pContainerName = NULL; size_t pContainerNameCharLen = cardSerialNumberLen+20; CK_CHAR_PTR pcardSerialNrString = NULL; wchar_t* pProviderName = NULL; CK_ULONG counter=0; HCERTSTORE hMyStore = CertOpenSystemStore((HCRYPTPROV_LEGACY)NULL, TEXT("MY")); CRYPT_KEY_PROV_INFO cryptKeyProvInfo; unsigned long dwPropId = CERT_KEY_PROV_INFO_PROP_ID; if (hMyStore == NULL) { dwRet = GetLastError(); printf("StoreUserCerts: Unable to open the system certificate store. Error code: %d.\n",dwRet); return dwRet; } // ---------------------------------------------------- // look if we already have a certificate with the same // subject (contains name and NNR) in the store // If the certificate is not found --> NULL // ---------------------------------------------------- do { if( NULL != (pDesiredCert = CertFindCertificateInStore(hMyStore, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &(pCertContext->pCertInfo->Subject) , pPrevCert))) { // ---------------------------------------------------- // If the certificates are identical and function // succeeds, the return value is nonzero, or TRUE. // ---------------------------------------------------- if(FALSE == CertCompareCertificate(X509_ASN_ENCODING,pCertContext->pCertInfo,pDesiredCert->pCertInfo) || !ProviderNameCorrect(pDesiredCert) ) { // ---------------------------------------------------- // certificates are not identical, but have the same // subject (contains name and NNR), // so we remove the one that was already in the store // ---------------------------------------------------- if(FALSE == CertDeleteCertificateFromStore(pDesiredCert)) { if (E_ACCESSDENIED == GetLastError()) { continue; } } pPrevCert = NULL; continue; } } pPrevCert = pDesiredCert; }while (NULL != pDesiredCert); // ---------------------------------------------------- // look if we already have the certificate in the store // If the certificate is not found --> NULL // ---------------------------------------------------- if( NULL != (pDesiredCert = CertFindCertificateInStore(hMyStore, X509_ASN_ENCODING, 0, CERT_FIND_EXISTING, pCertContext , NULL))) { // ---------------------------------------------------- // certificate is already in the store, then just return // ---------------------------------------------------- CertFreeCertificateContext(pDesiredCert); CertCloseStore (hMyStore, CERT_CLOSE_STORE_FORCE_FLAG); return 0; } pContainerName = (wchar_t*)malloc(sizeof(wchar_t) * (pContainerNameCharLen)); if(pContainerName == NULL) return E_OUTOFMEMORY; pcardSerialNrString = (CK_CHAR_PTR)malloc(cardSerialNumberLen*2 + 1); if(pcardSerialNrString == NULL) return E_OUTOFMEMORY; if(-1 == ByteArrayToString( &pcardSerialNrString, cardSerialNumberLen*2 + 1,cardSerialNumber ,cardSerialNumberLen)) return -1; if(pContainerName == NULL) { CertFreeCertificateContext(pDesiredCert); CertCloseStore (hMyStore, CERT_CLOSE_STORE_FORCE_FLAG); return -1; } if (UseMinidriver()) { if (KeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE) { swprintf_s(pContainerName,pContainerNameCharLen,L"NR_%hS",pcardSerialNrString); } else { swprintf_s(pContainerName,pContainerNameCharLen,L"DS_%hS",pcardSerialNrString); } cryptKeyProvInfo.pwszProvName = L"Microsoft Base Smart Card Crypto Provider"; cryptKeyProvInfo.dwKeySpec = AT_SIGNATURE; } else { if (KeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE) { swprintf_s(pContainerName,pContainerNameCharLen,L"Signature(%hS)",pcardSerialNrString); } else { swprintf_s(pContainerName,pContainerNameCharLen,L"Authentication(%hS)",pcardSerialNrString); } cryptKeyProvInfo.pwszProvName = L"Belgium Identity Card CSP"; cryptKeyProvInfo.dwKeySpec = AT_KEYEXCHANGE; } cryptKeyProvInfo.pwszContainerName = pContainerName; cryptKeyProvInfo.dwProvType = PROV_RSA_FULL; cryptKeyProvInfo.dwFlags = 0; cryptKeyProvInfo.cProvParam = 0; cryptKeyProvInfo.rgProvParam = NULL; /* // Set friendly names for the certificates DWORD dwsize = 0; dwsize = CertGetNameStringW(pCertContext, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, NULL, dwsize); auto_vec<WCHAR> pname(new WCHAR[dwsize]); dwsize = CertGetNameStringW(pCertContext, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, pname.get(), dwsize); CRYPT_DATA_BLOB tpFriendlyName = {0, 0}; tpFriendlyName.pbData = (BYTE *)pname.get(); tpFriendlyName.cbData = dwsize * sizeof(WCHAR); if (CertSetCertificateContextProperty( pCertContext, // A pointer to the certificate // where the propertiy will be set. CERT_FRIENDLY_NAME_PROP_ID, // An identifier of the property to be set. // In this case, CERT_KEY_PROV_INFO_PROP_ID // is to be set to provide a pointer with the // certificate to its associated private key // container. dwFlags, // The flag used in this case is // CERT_STORE_NO_CRYPT_RELEASE_FLAG // indicating that the cryptographic // context aquired should not // be released when the function finishes. &tpFriendlyName // A pointer to a data structure that holds // infomation on the private key container to // be associated with this certificate. )) */ // Set the property. if (CertSetCertificateContextProperty( pCertContext, // A pointer to the certificate where the property will be set. dwPropId, // An identifier of the property to be set. // In this case, CERT_KEY_PROV_INFO_PROP_ID is to be set to provide a pointer with the certificate to its associated private key container. dwFlags, // The flag used in this case is // CERT_STORE_NO_CRYPT_RELEASE_FLAG indicating that the cryptographic context acquired should not be released when the function finishes. &cryptKeyProvInfo // A pointer to a data structure that holds infomation on the private key container to be associated with this certificate. )) { if (KeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE) { CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_EMAIL_PROTECTION); } else { CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_EMAIL_PROTECTION); CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_CLIENT_AUTH); } if (CertAddCertificateContextToStore(hMyStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) { printf("StoreUserCerts: Certificate context added to store."); dwRet = 0; } else { dwRet = GetLastError(); printf("StoreUserCerts: Unable to add certificate context to store. Error code: %d.",dwRet); } CertCloseStore (hMyStore, CERT_CLOSE_STORE_FORCE_FLAG); hMyStore = NULL; } if(pContainerName != NULL) free (pContainerName); return dwRet; }
DWORD do_low_verify (const char *infile, const char *outfile) { HCRYPTPROV hCryptProv = 0; // CSP handle PCCERT_CONTEXT pUserCert = NULL; // User certificate to be used DWORD ret = 1; FILE *tbs = NULL; BYTE *mem_tbs = NULL; DWORD mem_len = 0; FILE *signature = NULL; BYTE *mem_signature = NULL; DWORD signature_len = 0; HCRYPTMSG hMsg = 0; DWORD cbDecoded; BYTE *pbDecoded; DWORD cbSignerCertInfo; PCERT_INFO pSignerCertInfo; PCCERT_CONTEXT pSignerCertContext; PCERT_INFO pSignerCertificateInfo; HCERTSTORE hStoreHandle = NULL; if (! infile) { fprintf (stderr, "No input file was specified\n"); 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; if (signature) { signature_len = 0; while (!feof(signature)) { int r = 0; BYTE tmp[1024]; r = fread (tmp, 1, 1024, signature); mem_signature = (BYTE *)realloc (mem_signature , signature_len+r); memcpy (&mem_signature [signature_len], tmp, r); signature_len += r; } fclose (signature); signature = NULL; } //-------------------------------------------------------------------- // Open a message for decoding. hMsg = CryptMsgOpenToDecode( TYPE_DER, // Encoding type. 0, // Flags. 0, // Use the default message type. hCryptProv, // Cryptographic provider. NULL, // Recipient information. NULL); // Stream information. if (hMsg) printf("The message to decode is open. \n"); else{ fprintf (stderr, "OpenToDecode failed"); ret = CSP_GetLastError(); goto err; } //-------------------------------------------------------------------- // Update the message with an encoded blob. // Both pbEncodedBlob, the encoded data, // and cbEnclodeBlob, the length of the encoded data, // must be available. if (CryptMsgUpdate( hMsg, // Handle to the message mem_tbs, // Pointer to the encoded blob mem_len, // Size of the encoded blob TRUE)){ // Last call) printf("The encoded blob has been added to the message. \n"); } else { fprintf (stderr, "Decode MsgUpdate failed"); ret = CSP_GetLastError(); goto err; } //-------------------------------------------------------------------- // Get the size of the content. ret = CryptMsgGetParam( hMsg, // Handle to the message CMSG_CONTENT_PARAM, // Parameter type 0, // Index NULL, // Address for returned info &cbDecoded); // Size of the returned info if (ret) printf("The message parameter (CMSG_CONTENT_PARAM) has been acquired. Message size: %d\n", cbDecoded); else{ fprintf (stderr, "Decode CMSG_CONTENT_PARAM failed"); ret = CSP_GetLastError(); goto err; } //-------------------------------------------------------------------- // Allocate memory. pbDecoded = (BYTE *) malloc(cbDecoded); if (!pbDecoded){ fprintf (stderr, "Decode memory allocation failed"); ret = CSP_GetLastError(); goto err; } //-------------------------------------------------------------------- // Get a pointer to the content. ret = CryptMsgGetParam( hMsg, // Handle to the message CMSG_CONTENT_PARAM, // Parameter type 0, // Index pbDecoded, // Address for returned &cbDecoded); // Size of the returned if (ret) printf("The message param (CMSG_CONTENT_PARAM) updated. Length is %lu.\n",(unsigned long)cbDecoded); else{ fprintf (stderr, "Decode CMSG_CONTENT_PARAM #2 failed"); ret = CSP_GetLastError(); goto err; } //-------------------------------------------------------------------- // Verify the signature. // First, get the signer CERT_INFO from the message. //-------------------------------------------------------------------- // Get the size of memory required. if (! pUserCert) { ret = CryptMsgGetParam( hMsg, // Handle to the message CMSG_SIGNER_CERT_INFO_PARAM, // Parameter type 0, // Index NULL, // Address for returned &cbSignerCertInfo); // Size of the returned if (ret) printf("Try to get user cert. OK. Length %d.\n",cbSignerCertInfo); else { printf("No user certificate found in message.\n"); } } if (pUserCert) { hStoreHandle = CertOpenStore(CERT_STORE_PROV_MEMORY, TYPE_DER, 0, CERT_STORE_CREATE_NEW_FLAG,NULL); if (!hStoreHandle){ printf("Cannot create temporary store in memory."); return CSP_GetLastError(); } if (pUserCert) { ret = CertAddCertificateContextToStore(hStoreHandle, pUserCert, CERT_STORE_ADD_ALWAYS, NULL); pSignerCertInfo = pUserCert->pCertInfo; } else ret = 0; if (!ret){ printf("Cannot add user certificate to store."); return CSP_GetLastError(); } } //-------------------------------------------------------------------- // Allocate memory. if (!pUserCert) { pSignerCertInfo = (PCERT_INFO) malloc(cbSignerCertInfo); if (!pSignerCertInfo){ printf("Verify memory allocation failed"); return CSP_GetLastError(); } } //-------------------------------------------------------------------- // Get the message certificate information (CERT_INFO // structure). if (! pUserCert) { ret = CryptMsgGetParam( hMsg, // Handle to the message CMSG_SIGNER_CERT_INFO_PARAM, // Parameter type 0, // Index pSignerCertInfo, // Address for returned &cbSignerCertInfo); // Size of the returned if (ret) printf("The signer info has been returned. \n"); else{ printf("Verify SIGNER_CERT_INFO #2 failed"); return CSP_GetLastError(); } } //-------------------------------------------------------------------- // Open a certificate store in memory using CERT_STORE_PROV_MSG, // which initializes it with the certificates from the message. if (! hStoreHandle) { hStoreHandle = CertOpenStore( CERT_STORE_PROV_MSG, // Store provider type TYPE_DER, // Encoding type hCryptProv, // Cryptographic provider 0, // Flags hMsg); // Handle to the message if (hStoreHandle) printf("The message certificate store be used for verifying\n"); } if (! hStoreHandle) { printf("Cannot open certificate store form message\n"); return CSP_GetLastError(); } //-------------------------------------------------------------------- // Find the signer's certificate in the store. if(pSignerCertContext = CertGetSubjectCertificateFromStore( hStoreHandle, // Handle to store TYPE_DER, // Encoding type pSignerCertInfo)) // Pointer to retrieved CERT_CONTEXT { DWORD errCode=0; DWORD err; printf("A signer certificate has been retrieved. \n"); err=VerifyCertificate(pSignerCertContext,&errCode); if (err) { printf("Subject cert verification failed: err=%x\n",err); return err; } if (errCode) { printf("Subject cert BAD: errCode=%x\n",errCode); return errCode; } } else { printf("Verify GetSubjectCert failed"); return CSP_GetLastError(); } //-------------------------------------------------------------------- // Use the CERT_INFO from the signer certificate to verify // the signature. pSignerCertificateInfo = pSignerCertContext->pCertInfo; if(CryptMsgControl( hMsg, // Handle to the message 0, // Flags CMSG_CTRL_VERIFY_SIGNATURE, // Control type pSignerCertificateInfo)) // Pointer to the CERT_INFO { printf("\nSignature was VERIFIED.\n"); } else { printf("\nThe signature was NOT VEIFIED.\n"); } if(hStoreHandle) CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG); ret = 0; err: return ret; }
/* * '_sspiGetCredentials()' - Retrieve an SSL/TLS certificate from the system store * If one cannot be found, one is created. */ BOOL /* O - 1 on success, 0 on failure */ _sspiGetCredentials(_sspi_struct_t *conn, /* I - Client connection */ const LPWSTR container, /* I - Cert container name */ const TCHAR *cn, /* I - Common name of certificate */ BOOL isServer) /* I - Is caller a server? */ { HCERTSTORE store = NULL; /* Certificate store */ PCCERT_CONTEXT storedContext = NULL; /* Context created from the store */ PCCERT_CONTEXT createdContext = NULL; /* Context created by us */ DWORD dwSize = 0; /* 32 bit size */ PBYTE p = NULL; /* Temporary storage */ HCRYPTPROV hProv = (HCRYPTPROV) NULL; /* Handle to a CSP */ CERT_NAME_BLOB sib; /* Arbitrary array of bytes */ SCHANNEL_CRED SchannelCred; /* Schannel credential data */ TimeStamp tsExpiry; /* Time stamp */ SECURITY_STATUS Status; /* Status */ HCRYPTKEY hKey = (HCRYPTKEY) NULL; /* Handle to crypto key */ CRYPT_KEY_PROV_INFO kpi; /* Key container info */ SYSTEMTIME et; /* System time */ CERT_EXTENSIONS exts; /* Array of cert extensions */ CRYPT_KEY_PROV_INFO ckp; /* Handle to crypto key */ BOOL ok = TRUE; /* Return value */ DEBUG_printf(("_sspiGetCredentials(conn=%p, container=%p, cn=\"%s\", isServer=%d)", conn, container, cn, isServer)); if (!conn) return (FALSE); if (!cn) return (FALSE); if (!CryptAcquireContextW(&hProv, (LPWSTR) container, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET)) { if (GetLastError() == NTE_EXISTS) { if (!CryptAcquireContextW(&hProv, (LPWSTR) container, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET)) { DEBUG_printf(("_sspiGetCredentials: CryptAcquireContext failed: %x\n", GetLastError())); ok = FALSE; goto cleanup; } } } store = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, hProv, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_NO_CRYPT_RELEASE_FLAG | CERT_STORE_OPEN_EXISTING_FLAG, L"MY"); if (!store) { DEBUG_printf(("_sspiGetCredentials: CertOpenSystemStore failed: %x\n", GetLastError())); ok = FALSE; goto cleanup; } dwSize = 0; if (!CertStrToName(X509_ASN_ENCODING, cn, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) { DEBUG_printf(("_sspiGetCredentials: CertStrToName failed: %x\n", GetLastError())); ok = FALSE; goto cleanup; } p = (PBYTE) malloc(dwSize); if (!p) { DEBUG_printf(("_sspiGetCredentials: malloc failed for %d bytes", dwSize)); ok = FALSE; goto cleanup; } if (!CertStrToName(X509_ASN_ENCODING, cn, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) { DEBUG_printf(("_sspiGetCredentials: CertStrToName failed: %x", GetLastError())); ok = FALSE; goto cleanup; } sib.cbData = dwSize; sib.pbData = p; storedContext = CertFindCertificateInStore(store, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &sib, NULL); if (!storedContext) { /* * If we couldn't find the context, then we'll * create a new one */ if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey)) { DEBUG_printf(("_sspiGetCredentials: CryptGenKey failed: %x", GetLastError())); ok = FALSE; goto cleanup; } ZeroMemory(&kpi, sizeof(kpi)); kpi.pwszContainerName = (LPWSTR) container; kpi.pwszProvName = MS_DEF_PROV_W; kpi.dwProvType = PROV_RSA_FULL; kpi.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID; kpi.dwKeySpec = AT_KEYEXCHANGE; GetSystemTime(&et); et.wYear += 10; ZeroMemory(&exts, sizeof(exts)); createdContext = CertCreateSelfSignCertificate(hProv, &sib, 0, &kpi, NULL, NULL, &et, &exts); if (!createdContext) { DEBUG_printf(("_sspiGetCredentials: CertCreateSelfSignCertificate failed: %x", GetLastError())); ok = FALSE; goto cleanup; } if (!CertAddCertificateContextToStore(store, createdContext, CERT_STORE_ADD_REPLACE_EXISTING, &storedContext)) { DEBUG_printf(("_sspiGetCredentials: CertAddCertificateContextToStore failed: %x", GetLastError())); ok = FALSE; goto cleanup; } ZeroMemory(&ckp, sizeof(ckp)); ckp.pwszContainerName = (LPWSTR) container; ckp.pwszProvName = MS_DEF_PROV_W; ckp.dwProvType = PROV_RSA_FULL; ckp.dwFlags = CRYPT_MACHINE_KEYSET; ckp.dwKeySpec = AT_KEYEXCHANGE; if (!CertSetCertificateContextProperty(storedContext, CERT_KEY_PROV_INFO_PROP_ID, 0, &ckp)) { DEBUG_printf(("_sspiGetCredentials: CertSetCertificateContextProperty failed: %x", GetLastError())); ok = FALSE; goto cleanup; } } ZeroMemory(&SchannelCred, sizeof(SchannelCred)); SchannelCred.dwVersion = SCHANNEL_CRED_VERSION; SchannelCred.cCreds = 1; SchannelCred.paCred = &storedContext; /* * SSPI doesn't seem to like it if grbitEnabledProtocols * is set for a client */ if (isServer) SchannelCred.grbitEnabledProtocols = SP_PROT_SSL3TLS1; /* * Create an SSPI credential. */ Status = AcquireCredentialsHandle(NULL, UNISP_NAME, isServer ? SECPKG_CRED_INBOUND:SECPKG_CRED_OUTBOUND, NULL, &SchannelCred, NULL, NULL, &conn->creds, &tsExpiry); if (Status != SEC_E_OK) { DEBUG_printf(("_sspiGetCredentials: AcquireCredentialsHandle failed: %x", Status)); ok = FALSE; goto cleanup; } cleanup: /* * Cleanup */ if (hKey) CryptDestroyKey(hKey); if (createdContext) CertFreeCertificateContext(createdContext); if (storedContext) CertFreeCertificateContext(storedContext); if (p) free(p); if (store) CertCloseStore(store, 0); if (hProv) CryptReleaseContext(hProv, 0); return (ok); }
void PfxCertificate::addToStore( Win32CertificateLocation certStoreLocation, Win32CertificateStore certStore) { std::wstring wStoreName; switch (certStore) { case Cs_AddressBook: wStoreName = L"AddressBook"; break; case Cs_AuthRoot: wStoreName = L"AuthRoot"; break; case Cs_CertificateAuthority: wStoreName = L"CA"; break; case Cs_Disallowed: wStoreName = L"Disallowed"; break; case Cs_My: wStoreName = L"MY"; break; case Cs_Root: wStoreName = L"Root"; break; case Cs_TrustedPeople: wStoreName = L"TrustedPeople"; break; case Cs_TrustedPublisher: wStoreName = L"TrustedPublisher"; break; default: RCF_ASSERT(0 && "Invalid certificate store value."); } DWORD dwFlags = 0; switch (certStoreLocation) { case Cl_CurrentUser: dwFlags = CERT_SYSTEM_STORE_CURRENT_USER; break; case Cl_LocalMachine: dwFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE; break; default: RCF_ASSERT(0 && "Invalid certificate store location value."); } HCERTSTORE hCertStore = CertOpenStore( (LPCSTR) CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING, 0, dwFlags, wStoreName.c_str()); DWORD dwErr = GetLastError(); RCF_VERIFY( hCertStore, RCF::Exception( _RcfError_CryptoApiError("CertOpenStore()"), dwErr, RCF::RcfSubsystem_Os)); BOOL ret = CertAddCertificateContextToStore( hCertStore, mpCert, CERT_STORE_ADD_USE_EXISTING, NULL); dwErr = GetLastError(); RCF_VERIFY( ret, RCF::Exception( _RcfError_CryptoApiError("CertAddCertificateContextToStore()"), dwErr, RCF::RcfSubsystem_Os)); CertCloseStore(hCertStore, 0); }
/* {{{ static int ma_tls_set_client_certs(MARIADB_TLS *ctls) */ static int ma_tls_set_client_certs(MARIADB_TLS *ctls) { MYSQL *mysql= ctls->pvio->mysql; char *certfile= mysql->options.ssl_cert, *keyfile= mysql->options.ssl_key, *cafile= mysql->options.ssl_ca; PCERT_CONTEXT ca_ctx= NULL; PCRL_CONTEXT crl_ctx = NULL; SC_CTX *sctx= (SC_CTX *)ctls->ssl; MARIADB_PVIO *pvio= ctls->pvio; if (cafile) { if (!(ca_ctx = ma_schannel_create_cert_context(pvio, cafile))) goto end; /* Add ca to in-memory certificate store */ if (CertAddCertificateContextToStore(ca_CertStore, ca_ctx, CERT_STORE_ADD_NEWER, NULL) != TRUE && GetLastError() != CRYPT_E_EXISTS) { ma_schannel_set_win_error(sctx->mysql); goto end; } ca_Check= 0; CertFreeCertificateContext(ca_ctx); } if (!certfile && keyfile) certfile= keyfile; if (!keyfile && certfile) keyfile= certfile; if (certfile && certfile[0]) if (!(sctx->client_cert_ctx = ma_schannel_create_cert_context(ctls->pvio, certfile))) goto end; if (sctx->client_cert_ctx && keyfile[0]) if (!ma_schannel_load_private_key(pvio, sctx->client_cert_ctx, keyfile)) goto end; if (mysql->options.extension && mysql->options.extension->ssl_crl) { if (!(crl_ctx= (CRL_CONTEXT *)ma_schannel_create_crl_context(pvio, mysql->options.extension->ssl_crl))) goto end; /* Add ca to in-memory certificate store */ if (CertAddCRLContextToStore(crl_CertStore, crl_ctx, CERT_STORE_ADD_NEWER, NULL) != TRUE && GetLastError() != CRYPT_E_EXISTS) { ma_schannel_set_win_error(sctx->mysql); goto end; } crl_Check = 1; CertFreeCertificateContext(ca_ctx); } return 0; end: if (ca_ctx) CertFreeCertificateContext(ca_ctx); if (sctx->client_cert_ctx) CertFreeCertificateContext(sctx->client_cert_ctx); if (crl_ctx) CertFreeCRLContext(crl_ctx); sctx->client_cert_ctx= NULL; return 1; }
/***************************************************************************** wmain *****************************************************************************/ DWORD __cdecl wmain( int argc, LPWSTR argv[] ) { HRESULT hr = S_OK; HCERTSTORE hStore = NULL; PCCERT_CONTEXT pCert = NULL; PCCERT_CONTEXT pStoreCert = NULL; char szStoreProvider[ 256 ] = { "TestExt" }; // Store provider name LPWSTR pwszStoreProvider = NULL; // Store name LPWSTR pwszStoreName = L"TestStoreName"; LPWSTR pwszCertPath = NULL; int i; // // options // for( i=1; i<argc; i++ ) { if ( lstrcmpW (argv[i], L"/?") == 0 || lstrcmpW (argv[i], L"-?") == 0 ) { Usage( L"SampleStoreProvider.exe" ); goto CleanUp; } if( *argv[i] != L'-' ) break; if ( lstrcmpW (argv[i], L"-s") == 0 ) { if( i+1 >= argc ) { hr = E_INVALIDARG; goto CleanUp; } pwszStoreName = argv[++i]; } else if ( lstrcmpW (argv[i], L"-p") == 0 ) { if( i+1 >= argc ) { hr = E_INVALIDARG; goto CleanUp; } pwszStoreProvider = argv[++i]; } } if( i >= argc ) { hr = E_INVALIDARG; goto CleanUp; } pwszCertPath = argv[i++]; // Load the certificate from the file passed in as cmd line parameter; if (!CryptQueryObject( CERT_QUERY_OBJECT_FILE, //dwObjectType pwszCertPath, //pvObject CERT_QUERY_CONTENT_FLAG_CERT, //dwExpectedContentTypeFlags CERT_QUERY_FORMAT_FLAG_ALL, //dwExpectedFormatTypeFlags 0, //dwFlags 0, //pdwMsgAndCertEncodingType 0, //pdwContentType 0, //pdwFormatType 0, //phCertStore 0, //phMsg (const void**)&pCert //ppvContext )) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto CleanUp; } // Open the store using the sample provider name if( NULL != pwszStoreProvider ) { if( 1 < WideCharToMultiByte( CP_ACP, WC_ERR_INVALID_CHARS, pwszStoreProvider, -1, szStoreProvider, sizeof(szStoreProvider), NULL, NULL )) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto CleanUp; } } hStore = CertOpenStore( szStoreProvider, // lpszStoreProvider X509_ASN_ENCODING, // dwMsgAndCertEncodingType NULL, // hCryptProv 0, // dwFlags (will create it if does not exists) (void*)pwszStoreName); // pvPara if (hStore == NULL) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto CleanUp; } // Add a certificate to store if(!CertAddCertificateContextToStore( hStore, // hCertStore pCert, // pCertContext CERT_STORE_ADD_REPLACE_EXISTING, // dwAddDisposition NULL // ppStoreContext )) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto CleanUp; } pStoreCert = CertFindCertificateInStore( hStore, // hCertStore X509_ASN_ENCODING, // dwCertEncodingType 0, // dwFindFlags CERT_FIND_EXISTING, // dwFindType pCert, // pvFindPara NULL // pPrevCertContext ); if (pStoreCert == NULL) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto CleanUp; } hr = S_OK; CleanUp: if( NULL != pCert ) CertFreeCertificateContext(pCert); if( NULL != pStoreCert ) CertFreeCertificateContext(pStoreCert); if( NULL != hStore ) CertCloseStore(hStore, 0); if( FAILED( hr )) { ReportError( NULL, hr ); } return (DWORD)hr; }
// Read URL server LPSTR SoffidEssoManager::readURL (HINTERNET hSession, const wchar_t* host, int port, LPCWSTR path, BOOL allowUnknownCA, size_t *pSize) { BOOL bResults = FALSE; HINTERNET hConnect = NULL, hRequest = NULL; DWORD dwDownloaded = -1; BYTE *buffer = NULL; if (debug) { log("Connecting to %s:%d...\n", host, port); } hConnect = WinHttpConnect(hSession, host, port, 0); if (hConnect) { if (debug) { log("Performing request %s...\n", path); } hRequest = WinHttpOpenRequest(hConnect, L"GET", path, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); } // Send a request. if (hRequest) { if (debug) log("Sending request ...\n"); WinHttpSetOption(hRequest, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, NULL, 0); if (allowUnknownCA) { DWORD flags = SECURITY_FLAG_IGNORE_UNKNOWN_CA; WinHttpSetOption(hRequest, WINHTTP_OPTION_SECURITY_FLAGS, (LPVOID) &flags, sizeof flags); } bResults = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); } if (bResults && allowUnknownCA) { // Agreagar la CA ROOT PCERT_CONTEXT context; DWORD dwSize = sizeof context; BOOL result = WinHttpQueryOption(hRequest, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &context, &dwSize); if (!result) { log("Cannot get context\n"); // notifyError(); } PCCERT_CONTEXT issuerContext = CertFindCertificateInStore(context->hCertStore, X509_ASN_ENCODING, 0, CERT_FIND_ISSUER_OF, context, NULL); HCERTSTORE systemStore = CertOpenStore((LPCSTR) 13, // CERT_STORE_PROV_SYSTEM_REGISTRY_W 0, (HCRYPTPROV) NULL, (2 << 16) | // CERT_SYSTEM_STORE_LOCAL_MACHINE 0x1000, // CERT_STORE_MAXIMUM_ALLOWED L"ROOT"); CertAddCertificateContextToStore(systemStore, issuerContext, 1 /*CERT_STORE_ADD_NEW*/, NULL); CertFreeCertificateContext(issuerContext); CertFreeCertificateContext(context); } // End the request. if (bResults) { if (debug) log("Waiting for response....\n"); bResults = WinHttpReceiveResponse(hRequest, NULL); } // Keep checking for data until there is nothing left. DWORD used = 0; if (bResults) { const DWORD chunk = 4096; DWORD allocated = 0; do { if (used + chunk > allocated) { allocated += chunk; buffer = (LPBYTE) realloc(buffer, allocated); } dwDownloaded = 0; if (!WinHttpReadData(hRequest, &buffer[used], chunk, &dwDownloaded)) dwDownloaded = -1; else used += dwDownloaded; } while (dwDownloaded > 0); buffer[used] = '\0'; } DWORD dw = GetLastError(); if (!bResults && debug) { if (dw == ERROR_WINHTTP_CANNOT_CONNECT) log("Error: Cannot connect\n"); else if (dw == ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED) log("Error: Client CERT required\n"); else if (dw == ERROR_WINHTTP_CONNECTION_ERROR) log("Error: Connection error\n"); else if (dw == ERROR_WINHTTP_INCORRECT_HANDLE_STATE) log("Error: ERROR_WINHTTP_INCORRECT_HANDLE_STATE\n"); else if (dw == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE) log("Error: ERROR_WINHTTP_INCORRECT_HANDLE_TYPE\n"); else if (dw == ERROR_WINHTTP_INTERNAL_ERROR) log("Error: ERROR_WINHTTP_INTERNAL_ERROR\n"); else if (dw == ERROR_WINHTTP_INVALID_URL) log("Error: ERROR_WINHTTP_INVALID_URL\n"); else if (dw == ERROR_WINHTTP_LOGIN_FAILURE) log("Error: ERROR_WINHTTP_LOGIN_FAILURE\n"); else if (dw == ERROR_WINHTTP_NAME_NOT_RESOLVED) log("Error: ERROR_WINHTTP_NAME_NOT_RESOLVED\n"); else if (dw == ERROR_WINHTTP_OPERATION_CANCELLED) log("Error: ERROR_WINHTTP_OPERATION_CANCELLED\n"); else if (dw == ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW) log("Error: ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW\n"); else if (dw == ERROR_WINHTTP_SECURE_FAILURE) log("Error: ERROR_WINHTTP_SECURE_FAILURE\n"); else if (dw == ERROR_WINHTTP_SHUTDOWN) log("Error: ERROR_WINHTTP_SHUTDOWN\n"); else if (dw == ERROR_WINHTTP_TIMEOUT) log("Error: ERROR_WINHTTP_TIMEOUT\n"); else if (dw == ERROR_WINHTTP_UNRECOGNIZED_SCHEME) log("Error: ERROR_WINHTTP_UNRECOGNIZED_SCHEME\n"); else if (dw == ERROR_NOT_ENOUGH_MEMORY) log("Error: ERROR_NOT_ENOUGH_MEMORY\n"); else if (dw == ERROR_INVALID_PARAMETER) log("Error: ERROR_INVALID_PARAMETER\n"); else if (dw == ERROR_WINHTTP_RESEND_REQUEST) log("Error: ERROR_WINHTTP_RESEND_REQUEST\n"); else if (dw != ERROR_SUCCESS) { log("Unkonwn error %d\n", dw); } // notifyError(); } // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); SetLastError(dw); if (pSize != NULL) *pSize = used; return (LPSTR) buffer; }
DWORD ShowCertsDlg(LPCTSTR szProviderName, LPCTSTR szReaderName /* Can be NULL */ ) { HCRYPTPROV HMainCryptProv = NULL; BOOL bStatus = FALSE; LPTSTR szMainContainerName = NULL; CHAR szContainerName[1024]; DWORD dwContainerNameLen = sizeof(szContainerName); DWORD dwErr = 0; DWORD dwFlags = CRYPT_FIRST; PCCERT_CONTEXT pContextArray[128]; DWORD dwContextArrayLen = 0; HCRYPTPROV hProv = NULL; HCRYPTKEY hKey = NULL; LPBYTE pbCert = NULL; DWORD dwCertLen = 0; PCCERT_CONTEXT pCertContext = NULL; DWORD pKeySpecs[2] = { AT_KEYEXCHANGE, AT_SIGNATURE}; if (szReaderName) { size_t ulNameLen = _tcslen(szReaderName); szMainContainerName = (LPTSTR) LocalAlloc(0, (ulNameLen + 6) * sizeof(TCHAR)); if (!szMainContainerName) { return GetLastError(); } _stprintf(szMainContainerName, _T("\\\\.\\%s\\"), szReaderName); } bStatus = CryptAcquireContext(&HMainCryptProv,szMainContainerName,szProviderName,PROV_RSA_FULL,0); if (!bStatus) { dwErr = GetLastError(); goto end; } /* Enumerate all the containers */ while (CryptGetProvParam(HMainCryptProv,PP_ENUMCONTAINERS,(LPBYTE) szContainerName,&dwContainerNameLen,dwFlags) &&(dwContextArrayLen < 128)) { #ifndef _UNICODE if (CryptAcquireContext(&hProv, szContainerName, szProviderName, PROV_RSA_FULL, 0)) #else // convert the container name to unicode int wLen = MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, NULL, 0); LPWSTR szWideContainerName = (LPWSTR) LocalAlloc(0, wLen * sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, szWideContainerName, wLen); // Acquire a context on the current container if (CryptAcquireContext(&hProv,szWideContainerName,szProviderName,PROV_RSA_FULL,0)) #endif { // Loop over all the key specs for (int i = 0; i < 2; i++) { if (CryptGetUserKey(hProv,pKeySpecs[i],&hKey) ) { if (CryptGetKeyParam(hKey,KP_CERTIFICATE,NULL,&dwCertLen,0)) { pbCert = (LPBYTE) LocalAlloc(0, dwCertLen); if (!pbCert) { dwErr = GetLastError(); goto end; } if (CryptGetKeyParam(hKey,KP_CERTIFICATE,pbCert,&dwCertLen,0)) { pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, pbCert,dwCertLen); if (pCertContext) { pContextArray[dwContextArrayLen++] = pCertContext; CRYPT_KEY_PROV_INFO ProvInfo; ProvInfo.pwszContainerName = szWideContainerName; ProvInfo.pwszProvName = L"Microsoft Base Smart Card Crypto Provider"; ProvInfo.dwProvType = PROV_RSA_FULL; ProvInfo.dwFlags = 0; ProvInfo.dwKeySpec = AT_SIGNATURE; ProvInfo.cProvParam = 0; ProvInfo.rgProvParam = NULL; CertSetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID, 0, &ProvInfo); HCERTSTORE dest = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_CURRENT_USER,L"My"); if(CertAddCertificateContextToStore(dest, pCertContext,CERT_STORE_ADD_REPLACE_EXISTING, NULL)) { //char certName[1024]; //LPWSTR certName = (LPWSTR)new wchar_t[1024]; LPTSTR certName; int cbSize = CertNameToStrW(pCertContext->dwCertEncodingType, &(pCertContext->pCertInfo->Subject),CERT_X500_NAME_STR,NULL,0); certName = (LPTSTR)malloc(cbSize * sizeof(TCHAR)); if (CertNameToStrW(pCertContext->dwCertEncodingType, &(pCertContext->pCertInfo->Subject),CERT_X500_NAME_STR,certName,sizeof(certName))) { } printf("Installed certificate."); } else printf("Error while adding certificate to store"); } } LocalFree(pbCert); } CryptDestroyKey(hKey); hKey = NULL; } } CryptReleaseContext(hProv, 0); hProv = NULL; } #ifdef _UNICODE LocalFree(szWideContainerName); #endif // prepare parameters for the next loop dwContainerNameLen = sizeof(szContainerName); dwFlags = 0; } if (dwContextArrayLen == 0) printf("No certificate contexts found on card\n"); end: while (dwContextArrayLen--) { CertFreeCertificateContext(pContextArray[dwContextArrayLen]); } if (hKey) CryptDestroyKey(hKey); if (hProv) CryptReleaseContext(hProv, 0); if (szMainContainerName) LocalFree(szMainContainerName); if (HMainCryptProv) CryptReleaseContext(HMainCryptProv, 0); return dwErr; }