SchannelCertificate::SchannelCertificate(const ByteArray& der) { if (!der.empty()) { // Convert the DER encoded certificate to a PCERT_CONTEXT CERT_BLOB certBlob = {0}; certBlob.cbData = der.size(); certBlob.pbData = (BYTE*)&der[0]; if (!CryptQueryObject( CERT_QUERY_OBJECT_BLOB, &certBlob, CERT_QUERY_CONTENT_FLAG_CERT, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, NULL, NULL, NULL, NULL, (const void**)m_cert.Reset())) { // TODO: Because Swiften isn't exception safe, we have no way to indicate failure } } }
/** * Obtains the public key for the passed in cert data * * @param provider The crypto provider * @param certData Data of the certificate to extract the public key from * @param sizeOfCertData The size of the certData buffer * @param certStore Pointer to the handle of the certificate store to use * @param CryptoX_Success on success */ CryptoX_Result CryptoAPI_LoadPublicKey(HCRYPTPROV provider, BYTE *certData, DWORD sizeOfCertData, HCRYPTKEY *publicKey) { CRYPT_DATA_BLOB blob; CERT_CONTEXT *context; if (!provider || !certData || !publicKey) { return CryptoX_Error; } blob.cbData = sizeOfCertData; blob.pbData = certData; if (!CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_CONTENT_FLAG_CERT, CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL, NULL, NULL, (const void **)&context)) { return CryptoX_Error; } if (!CryptImportPublicKeyInfo(provider, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, &context->pCertInfo->SubjectPublicKeyInfo, publicKey)) { CertFreeCertificateContext(context); return CryptoX_Error; } CertFreeCertificateContext(context); return CryptoX_Success; }
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); } } }
BinaryCertificate( const std::wstring &path ) : store( 0 ) , msg( 0 ) , signerInfo( 0 ) , certContext( 0 ) { if( !CryptQueryObject( CERT_QUERY_OBJECT_FILE, path.c_str(), CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY, 0, 0, 0, 0, &store, &msg, NULL ) ) return; DWORD signerInfoSize; if( !CryptMsgGetParam( msg, CMSG_SIGNER_INFO_PARAM, 0, 0, &signerInfoSize ) ) return; signerInfo = (PCMSG_SIGNER_INFO)LocalAlloc( LPTR, signerInfoSize ); if( !CryptMsgGetParam( msg, CMSG_SIGNER_INFO_PARAM, 0, signerInfo, &signerInfoSize ) ) return; CERT_INFO certInfo; certInfo.Issuer = signerInfo->Issuer; certInfo.SerialNumber = signerInfo->SerialNumber; certContext = CertFindCertificateInStore( store, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_CERT, &certInfo, 0 ); }
/** * Checks to see if a file stored at filePath matches the specified info. This * only supports the name and issuer attributes currently. * * @param filePath The PE file path to check * @param infoToMatch The acceptable information to match * @return ERROR_SUCCESS if successful, ERROR_NOT_FOUND if the info * does not match, or the last error otherwise. */ DWORD CheckCertificateForPEFile(LPCWSTR filePath, CertificateCheckInfo &infoToMatch) { HCERTSTORE certStore = NULL; HCRYPTMSG cryptMsg = NULL; PCCERT_CONTEXT certContext = NULL; PCMSG_SIGNER_INFO signerInfo = NULL; DWORD lastError = ERROR_SUCCESS; // Get the HCERTSTORE and HCRYPTMSG from the signed file. DWORD encoding, contentType, formatType; BOOL result = CryptQueryObject(CERT_QUERY_OBJECT_FILE, filePath, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_CONTENT_FLAG_ALL, 0, &encoding, &contentType, &formatType, &certStore, &cryptMsg, NULL); if (!result) { lastError = GetLastError(); goto cleanup; } // Pass in NULL to get the needed signer information size. DWORD signerInfoSize; result = CryptMsgGetParam(cryptMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &signerInfoSize); if (!result) { lastError = GetLastError(); goto cleanup; } // Allocate the needed size for the signer information. signerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, signerInfoSize); if (!signerInfo) { lastError = GetLastError(); goto cleanup; } // Get the signer information (PCMSG_SIGNER_INFO). // In particular we want the issuer and serial number. result = CryptMsgGetParam(cryptMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)signerInfo, &signerInfoSize); if (!result) { lastError = GetLastError(); goto cleanup; } // Search for the signer certificate in the certificate store. CERT_INFO certInfo; certInfo.Issuer = signerInfo->Issuer; certInfo.SerialNumber = signerInfo->SerialNumber; certContext = CertFindCertificateInStore(certStore, ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&certInfo, NULL); if (!certContext) { lastError = GetLastError(); goto cleanup; } if (!DoCertificateAttributesMatch(certContext, infoToMatch)) { lastError = ERROR_NOT_FOUND; goto cleanup; } cleanup: if (signerInfo) { LocalFree(signerInfo); } if (certContext) { CertFreeCertificateContext(certContext); } if (certStore) { CertCloseStore(certStore, 0); } if (cryptMsg) { CryptMsgClose(cryptMsg); } return lastError; }
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara) { HCERTSTORE store = 0; LPCWSTR fileName = pvPara; DWORD access, create; HANDLE file; TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName)); if (!fileName) { SetLastError(ERROR_PATH_NOT_FOUND); return NULL; } if ((dwFlags & CERT_STORE_READONLY_FLAG) && (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)) { SetLastError(E_INVALIDARG); return NULL; } access = GENERIC_READ; if (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG) access |= GENERIC_WRITE; if (dwFlags & CERT_STORE_CREATE_NEW_FLAG) create = CREATE_NEW; else if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG) create = OPEN_EXISTING; else create = OPEN_ALWAYS; file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create, FILE_ATTRIBUTE_NORMAL, NULL); if (file != INVALID_HANDLE_VALUE) { HCERTSTORE memStore = NULL; DWORD size = GetFileSize(file, NULL), type = 0; /* If the file isn't empty, try to get the type from the file itself */ if (size) { DWORD contentType; BOOL ret; /* Close the file so CryptQueryObject can succeed.. */ CloseHandle(file); ret = CryptQueryObject(CERT_QUERY_OBJECT_FILE, fileName, CERT_QUERY_CONTENT_FLAG_CERT | CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE | CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, &contentType, NULL, &memStore, NULL, NULL); if (ret) { if (contentType == CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED) type = CERT_STORE_SAVE_AS_PKCS7; else type = CERT_STORE_SAVE_AS_STORE; /* and reopen the file. */ file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create, FILE_ATTRIBUTE_NORMAL, NULL); } } else { static const WCHAR spc[] = { 's','p','c',0 }; static const WCHAR p7c[] = { 'p','7','c',0 }; LPCWSTR ext = strrchrW(fileName, '.'); if (ext) { ext++; if (!lstrcmpiW(ext, spc) || !lstrcmpiW(ext, p7c)) type = CERT_STORE_SAVE_AS_PKCS7; } if (!type) type = CERT_STORE_SAVE_AS_STORE; memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); } if (memStore) { store = CRYPT_CreateFileStore(dwFlags, memStore, file, type); /* File store doesn't need crypto provider, so close it */ if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG)) CryptReleaseContext(hCryptProv, 0); } } return store; }
static BOOL WINAPI CRYPT_FileControl(HCERTSTORE hCertStore, DWORD dwFlags, DWORD dwCtrlType, void const *pvCtrlPara) { PWINE_FILESTOREINFO store = hCertStore; BOOL ret; TRACE("(%p, %08x, %d, %p)\n", hCertStore, dwFlags, dwCtrlType, pvCtrlPara); switch (dwCtrlType) { case CERT_STORE_CTRL_RESYNC: store->dirty = FALSE; if (store->type == CERT_STORE_SAVE_AS_STORE) { HCERTSTORE memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); /* FIXME: if I could translate a handle to a path, I could use * CryptQueryObject instead, but there's no API to do so yet. */ ret = CRYPT_ReadSerializedStoreFromFile(store->file, memStore); if (ret) I_CertUpdateStore(store->memStore, memStore, 0, 0); CertCloseStore(memStore, 0); } else if (store->type == CERT_STORE_SAVE_AS_PKCS7) { CERT_BLOB blob = { 0, NULL }; ret = CRYPT_ReadBlobFromFile(store->file, &blob); if (ret) { HCERTSTORE messageStore; ret = CryptQueryObject(CERT_QUERY_OBJECT_BLOB, &blob, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED, CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, NULL, NULL, &messageStore, NULL, NULL); I_CertUpdateStore(store->memStore, messageStore, 0, 0); CertCloseStore(messageStore, 0); CryptMemFree(blob.pbData); } } else { WARN("unknown type %d\n", store->type); ret = FALSE; } break; case CERT_STORE_CTRL_COMMIT: if (!(store->dwOpenFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); ret = FALSE; } else if (store->dirty) ret = CertSaveStore(store->memStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, store->type, CERT_STORE_SAVE_TO_FILE, store->file, 0); else ret = TRUE; break; default: FIXME("%d: stub\n", dwCtrlType); ret = FALSE; } return ret; }
bool isCertificateValidated(const generic_string & fullFilePath, const generic_string & subjectName2check) { bool isOK = false; HCERTSTORE hStore = NULL; HCRYPTMSG hMsg = NULL; PCCERT_CONTEXT pCertContext = NULL; BOOL result; DWORD dwEncoding, dwContentType, dwFormatType; PCMSG_SIGNER_INFO pSignerInfo = NULL; DWORD dwSignerInfo; CERT_INFO CertInfo; LPTSTR szName = NULL; generic_string subjectName; try { // Get message handle and store handle from the signed file. result = CryptQueryObject(CERT_QUERY_OBJECT_FILE, fullFilePath.c_str(), CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY, 0, &dwEncoding, &dwContentType, &dwFormatType, &hStore, &hMsg, NULL); if (!result) { generic_string errorMessage = TEXT("Check certificate of ") + fullFilePath + TEXT(" : "); errorMessage += GetLastErrorAsString(GetLastError()); throw errorMessage; } // Get signer information size. result = CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo); if (!result) { generic_string errorMessage = TEXT("CryptMsgGetParam first call: "); errorMessage += GetLastErrorAsString(GetLastError()); throw errorMessage; } // Allocate memory for signer information. pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo); if (!pSignerInfo) { generic_string errorMessage = TEXT("CryptMsgGetParam memory allocation problem: "); errorMessage += GetLastErrorAsString(GetLastError()); throw errorMessage; } // Get Signer Information. result = CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)pSignerInfo, &dwSignerInfo); if (!result) { generic_string errorMessage = TEXT("CryptMsgGetParam: "); errorMessage += GetLastErrorAsString(GetLastError()); throw errorMessage; } // Search for the signer certificate in the temporary // certificate store. CertInfo.Issuer = pSignerInfo->Issuer; CertInfo.SerialNumber = pSignerInfo->SerialNumber; pCertContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&CertInfo, NULL); if (not pCertContext) { generic_string errorMessage = TEXT("Certificate context: "); errorMessage += GetLastErrorAsString(GetLastError()); throw errorMessage; } DWORD dwData; // Get Subject name size. dwData = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0); if (dwData <= 1) { throw generic_string(TEXT("Certificate checking error: getting data size problem.")); } // Allocate memory for subject name. szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR)); if (!szName) { throw generic_string(TEXT("Certificate checking error: memory allocation problem.")); } // Get subject name. if (CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, szName, dwData) <= 1) { throw generic_string(TEXT("Cannot get certificate info.")); } // check Subject name. subjectName = szName; if (subjectName != subjectName2check) { throw generic_string(TEXT("Certificate checking error: the certificate is not matched.")); } isOK = true; } catch (generic_string s) { // display error message MessageBox(NULL, s.c_str(), TEXT("Certificate checking"), MB_OK); } catch (...) { // Unknown error generic_string errorMessage = TEXT("Unknown exception occured. "); errorMessage += GetLastErrorAsString(GetLastError()); MessageBox(NULL, errorMessage.c_str(), TEXT("Certificate checking"), MB_OK); } // Clean up. if (pSignerInfo != NULL) LocalFree(pSignerInfo); if (pCertContext != NULL) CertFreeCertificateContext(pCertContext); if (hStore != NULL) CertCloseStore(hStore, 0); if (hMsg != NULL) CryptMsgClose(hMsg); if (szName != NULL) LocalFree(szName); return isOK; }
/***************************************************************************** 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; }
LPTSTR CPublisherHelp::GetSigningName(const WCHAR* szFileName){ HCERTSTORE hStore = NULL; HCRYPTMSG hMsg = NULL; PCCERT_CONTEXT pCertContext = NULL; BOOL fResult; DWORD dwEncoding, dwContentType, dwFormatType; PCMSG_SIGNER_INFO pSignerInfo = NULL; PCMSG_SIGNER_INFO pCounterSignerInfo = NULL; DWORD dwSignerInfo; CERT_INFO CertInfo; SPROG_PUBLISHERINFO ProgPubInfo; ZeroMemory(&ProgPubInfo, sizeof(ProgPubInfo)); __try{ fResult = CryptQueryObject(CERT_QUERY_OBJECT_FILE, szFileName, CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, CERT_QUERY_FORMAT_FLAG_BINARY, 0, &dwEncoding, &dwContentType, &dwFormatType, &hStore, &hMsg, NULL); if (!fResult) { return NULL; } // Get signer information size. fResult = CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, NULL, &dwSignerInfo); if (!fResult) { return NULL; } pSignerInfo = (PCMSG_SIGNER_INFO)LocalAlloc(LPTR, dwSignerInfo); if (!pSignerInfo) { return NULL; } // Get Signer Information. fResult = CryptMsgGetParam(hMsg, CMSG_SIGNER_INFO_PARAM, 0, (PVOID)pSignerInfo, &dwSignerInfo); if (!fResult) { return NULL; } // Get program name and publisher information from // signer info structure. if (GetProgAndPublisherInfo(pSignerInfo, &ProgPubInfo)) { } else{ return NULL; } // Search for the signer certificate in the temporary // certificate store. CertInfo.Issuer = pSignerInfo->Issuer; CertInfo.SerialNumber = pSignerInfo->SerialNumber; pCertContext = CertFindCertificateInStore(hStore, ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&CertInfo, NULL); if (!pCertContext) { return NULL; } // Print Signer certificate information. LPTSTR szName = NULL; DWORD dwData; // Get Subject name size. if (!(dwData = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0))) { return NULL; } // Allocate memory for subject name. szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR)); if (!szName) { return NULL; } // Get subject name. if (!(CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, szName, dwData))) { return NULL; } // Print Subject Name. return szName; } __finally { if (ProgPubInfo.lpszProgramName != NULL) LocalFree(ProgPubInfo.lpszProgramName); if (ProgPubInfo.lpszPublisherLink != NULL) LocalFree(ProgPubInfo.lpszPublisherLink); if (ProgPubInfo.lpszMoreInfoLink != NULL) LocalFree(ProgPubInfo.lpszMoreInfoLink); if (pSignerInfo != NULL) LocalFree(pSignerInfo); if (pCounterSignerInfo != NULL) LocalFree(pCounterSignerInfo); if (pCertContext != NULL) CertFreeCertificateContext(pCertContext); if (hStore != NULL) CertCloseStore(hStore, 0); if (hMsg != NULL) CryptMsgClose(hMsg); } return NULL; }
/***************************************************************************** wmain *****************************************************************************/ DWORD __cdecl wmain( int argc, LPWSTR argv[] ) { HRESULT hr = S_OK; int i = 0; BOOL fPeerTrust = FALSE; DWORD dwChainFlags = CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT; LPCWSTR wsCertFile = NULL; LPCWSTR wsStoreFile = NULL; PCCERT_CONTEXT pCert = NULL; HCERTSTORE hStore = NULL; HCERTCHAINENGINE hChainEngine = NULL; PCCERT_CHAIN_CONTEXT pChainContext = NULL; CERT_ENHKEY_USAGE EnhkeyUsage = {0}; CERT_USAGE_MATCH CertUsage = {0}; CERT_CHAIN_PARA ChainPara = {0}; CERT_CHAIN_POLICY_PARA ChainPolicy = {0}; CERT_CHAIN_POLICY_STATUS PolicyStatus = {0}; CERT_CHAIN_ENGINE_CONFIG EngineConfig = {0}; //--------------------------------------------------------- // Initialize data structures for chain building. EnhkeyUsage.cUsageIdentifier = 0; EnhkeyUsage.rgpszUsageIdentifier=NULL; CertUsage.dwType = USAGE_MATCH_TYPE_AND; CertUsage.Usage = EnhkeyUsage; ChainPara.cbSize = sizeof(ChainPara); ChainPara.RequestedUsage=CertUsage; ChainPolicy.cbSize = sizeof(ChainPolicy); PolicyStatus.cbSize = sizeof(PolicyStatus); EngineConfig.cbSize = sizeof(EngineConfig); EngineConfig.dwUrlRetrievalTimeout = 0; // // options // for( i=1; i<argc; i++ ) { if ( lstrcmpW (argv[i], L"/?") == 0 || lstrcmpW (argv[i], L"-?") == 0 ) { Usage(argv[0]); goto CleanUp; } if( *argv[i] != L'-' ) break; if ( lstrcmpW (argv[i], L"-fc") == 0 ) { if( i+1 >= argc ) { goto InvalidCommandLine; } dwChainFlags = (DWORD)wcstoul( argv[++i], NULL, 0 ); } else if ( lstrcmpW (argv[i], L"-fe") == 0 ) { if( i+1 >= argc ) { goto InvalidCommandLine; } EngineConfig.dwFlags = (DWORD)wcstoul( argv[++i], NULL, 0 ); } else if ( lstrcmpW (argv[i], L"-p") == 0 ) { fPeerTrust = TRUE; } else { goto InvalidCommandLine; } } if( i >= argc ) { goto InvalidCommandLine; } wsStoreFile = argv[i++]; if( i < argc ) { wsCertFile = argv[i]; } hStore = CertOpenStore( CERT_STORE_PROV_FILENAME_W, X509_ASN_ENCODING, NULL, CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, wsStoreFile ); if( NULL == hStore ) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto CleanUp; } if( NULL != wsCertFile && 0 != *wsCertFile ) { if( !CryptQueryObject( CERT_QUERY_OBJECT_FILE, wsCertFile, CERT_QUERY_CONTENT_FLAG_CERT | CERT_QUERY_CONTENT_SERIALIZED_CERT , CERT_QUERY_FORMAT_FLAG_ALL, 0, // dwFlags, 0, // pdwMsgAndCertEncodingType, 0, // pdwContentType, 0, // pdwFormatType, 0, // phCertStore, 0, // phMsg, (const void**)&pCert )) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto CleanUp; } } else { pCert = CertFindCertificateInStore( hStore, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL ); if( NULL == pCert ) { hr = CRYPT_E_NOT_FOUND; goto CleanUp; } } if( fPeerTrust ) { EngineConfig.hExclusiveTrustedPeople = hStore; // Exclusive peer trust dwChainFlags |= CERT_CHAIN_ENABLE_PEER_TRUST; } else { EngineConfig.hExclusiveRoot = hStore; // Exclusive root } //--------------------------------------------------------- // Create chain engine. if( !CertCreateCertificateChainEngine( &EngineConfig, &hChainEngine )) { hr = HRESULT_FROM_WIN32( GetLastError() ); goto CleanUp; } //------------------------------------------------------------------- // Build a chain using CertGetCertificateChain if( !CertGetCertificateChain( hChainEngine, pCert, // pointer to the end certificate NULL, // use the default time NULL, // search no additional stores &ChainPara, // use AND logic and enhanced key usage // as indicated in the ChainPara // data structure dwChainFlags, NULL, // currently reserved &pChainContext )) // return a pointer to the chain created { hr = HRESULT_FROM_WIN32( GetLastError() ); goto CleanUp; } //--------------------------------------------------------------- // Verify that the chain complies with policy if( !CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_BASE, // use the base policy pChainContext, // pointer to the chain &ChainPolicy, &PolicyStatus )) // return a pointer to the policy status { hr = HRESULT_FROM_WIN32( GetLastError() ); goto CleanUp; } if( PolicyStatus.dwError != S_OK ) { hr = PolicyStatus.dwError; // Instruction: If the PolicyStatus.dwError is CRYPT_E_NO_REVOCATION_CHECK or CRYPT_E_REVOCATION_OFFLINE, it indicates errors in obtaining // revocation information. These can be ignored since the retrieval of revocation information depends on network availability goto CleanUp; } wprintf( L"CertVerifyCertificateChainPolicy succeeded.\n" ); hr = S_OK; // // END // goto CleanUp; // // Invalid Command Line // InvalidCommandLine: if( i < argc ) { wprintf( L"Invalid command line '%s'\n", argv[i] ); } else Usage(argv[0]); hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); CleanUp: if( FAILED(hr) ) { ReportError( NULL, hr ); } if( NULL != pChainContext ) { CertFreeCertificateChain( pChainContext ); } if( NULL != hChainEngine ) { CertFreeCertificateChainEngine( hChainEngine ); } if( NULL != pCert ) { CertFreeCertificateContext( pCert ); } if( NULL != hStore ) { CertCloseStore( hStore, 0 ); } return (DWORD)hr; } // end main