void CEstEIDCertificate::loadCertContexts(PCCERT_CONTEXT certContext) { USES_CONVERSION; CryptoErrorHandler(CertGetNameString(certContext, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, this->CN, 64)); std::string s = W2A(this->CN); EstEID_log("Certificate = %s", s.c_str()); CryptoErrorHandler(CertGetNameString(certContext, CERT_NAME_ATTR_TYPE, CERT_NAME_ISSUER_FLAG, szOID_COMMON_NAME, this->issuerCN, 64)); std::stringstream buf; for(size_t i = certContext->pCertInfo->SerialNumber.cbData ; i > 0 ;i--) buf << std::hex << std::setfill('0') << std::setw(2) << (int) certContext->pCertInfo->SerialNumber.pbData[i-1] << " "; std::string strBuf = buf.str(); EstEID_log("serial=%s", strBuf.c_str()); this->validFrom = dateToString(&certContext->pCertInfo->NotBefore); this->validTo = dateToString(&certContext->pCertInfo->NotAfter); this->certificate = (BYTE*)malloc(certContext->cbCertEncoded + 1); memcpy(this->certificate, certContext->pbCertEncoded, certContext->cbCertEncoded); this->certificate[certContext->cbCertEncoded] = '\0'; EstEID_log("certificate binary length = %i", certContext->cbCertEncoded); calculateMD5Hash(certContext->cbCertEncoded); binCert2Hex(certContext->cbCertEncoded); }
PCCERT_CONTEXT SslCredential::findCertificate(const std::string& name) { loadPrivCertStore(); if (loadError.pending()) return NULL; // search for the certificate by Friendly Name PCCERT_CONTEXT tmpctx = NULL; while (tmpctx = CertEnumCertificatesInStore(certStore, tmpctx)) { DWORD len = CertGetNameString(tmpctx, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0); if (len == 1) continue; std::vector<char> ctxname(len); CertGetNameString(tmpctx, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, &ctxname[0], len); bool found = !name.compare(&ctxname[0]); if (found) break; } // verify whether some certificate has been found if (tmpctx == NULL) { loadError.set(Msg() << "Client SSL/TLS certificate not found in the certificate store for name " << name, "client certificate not found"); } return tmpctx; }
int TestCryptoCertEnumCertificatesInStore(int argc, char* argv[]) { int index; DWORD status; LPTSTR pszNameString; HCERTSTORE hCertStore = NULL; PCCERT_CONTEXT pCertContext = NULL; /** * System Store Locations: * http://msdn.microsoft.com/en-us/library/windows/desktop/aa388136/ */ /** * Requires elevated rights: * hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE, _T("Remote Desktop")); */ hCertStore = CertOpenSystemStore((HCRYPTPROV_LEGACY) NULL, _T("MY")); // hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, CERT_SYSTEM_STORE_CURRENT_USER, _T("MY")); if (!hCertStore) { printf("Failed to open system store\n"); return -1; } index = 0; while ((pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext))) { status = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0); pszNameString = (LPTSTR) malloc(status * sizeof(TCHAR)); if (!pszNameString) { printf("Unable to allocate memory\n"); return -1; } status = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, status); _tprintf(_T("Certificate #%d: %s\n"), index++, pszNameString); #ifdef WITH_CRYPTUI CryptUIDlgViewContext(CERT_STORE_CERTIFICATE_CONTEXT, pCertContext, NULL, NULL, 0, NULL); #endif } if (!CertCloseStore(hCertStore, 0)) { printf("Failed to close system store\n"); return -1; } return 0; }
QString subjectName() const { if( !certContext ) return QString(); DWORD nameSize = CertGetNameString( certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, 0, 0, 0 ); LPTSTR name = (LPTSTR)LocalAlloc( LPTR, nameSize * sizeof(WCHAR) ); CertGetNameString( certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, 0, name, nameSize ); QString result = QString::fromUtf16( name ); LocalFree( name ); return result; }
LRESULT OnUnhandled(const Context& context) { if (context.message == WM_USER+1) { auto consumer = scenario->monitor.getconsumer(); auto readers = consumer.pop(); for (auto& reader : readers) { if (reader.card.valid()) { auto card = reader.card.get(); for (auto& key : card.certificates) { unique_winerror winerror; PCCERT_CONTEXT certcontext = CertCreateCertificateContext( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &key.cert[0], key.cert.size() ); winerror = make_winerror_if(!certcontext); if (!winerror) { continue; } DWORD sizesubject = 0; std::wstring subjectname; for (bool getsize = true; ; getsize = false) { sizesubject = CertGetNameString( certcontext, CERT_ALT_NAME_RFC822_NAME,//CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, getsize ? nullptr : &subjectname[0], sizesubject ); if (sizesubject == 1) { break; } if (getsize) { subjectname.resize(sizesubject - 1); } else { break; } } } } } return 0; } return DefWindowProc(context.window, context.message, context.wParam, context.lParam); }
char* KSI_PKICertificate_toString(KSI_PKICertificate *cert, char *buf, unsigned buf_len){ char *ret = NULL; char strSubjectname[256]; char strIssuerName[256]; if (cert == NULL || buf == NULL) goto cleanup; CertGetNameString(cert->x509, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, strSubjectname, sizeof(strSubjectname)); CertGetNameString(cert->x509, CERT_NAME_SIMPLE_DISPLAY_TYPE , CERT_NAME_ISSUER_FLAG, 0,strIssuerName, sizeof(strIssuerName)); KSI_snprintf(buf, buf_len, "Subject: '%s', Issuer '%s'.", strSubjectname, strIssuerName); ret = buf; cleanup: return ret; }
/*TODO: for debugging*/ static void printCertInfo(PCCERT_CONTEXT cert){ char strMail[256]; char strData[256]; char strIssuerName[256]; if (cert == NULL){ printf("Certificate is nullptr.\n"); return; } CertGetNameString(cert, CERT_NAME_EMAIL_TYPE, 0, NULL, strMail, sizeof(strMail)); CertGetNameString(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, strData, sizeof(strData)); CertGetNameString(cert, CERT_NAME_SIMPLE_DISPLAY_TYPE , CERT_NAME_ISSUER_FLAG, 0,strIssuerName, sizeof(strIssuerName)); printf("Cert: '%s' Mail '%s' Issuer '%s'.\n", strData,strMail, strIssuerName); return; }
static int KSI_PKITruststore_verifySignatureCertificate(const KSI_PKITruststore *pki, const KSI_PKISignature *signature) { int res = KSI_UNKNOWN_ERROR; KSI_CTX *ctx = NULL; PCCERT_CONTEXT subjectCert = NULL; char tmp[256]; char *magicEmail = NULL; if (pki == NULL || signature == NULL){ res = KSI_INVALID_ARGUMENT; goto cleanup; } ctx = pki->ctx; KSI_ERR_clearErrors(ctx); res = extractSigningCertificate(signature, &subjectCert); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } //printCertInfo(subjectCert); res=KSI_CTX_getPublicationCertEmail(ctx, &magicEmail); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } if (magicEmail != NULL){ if (CertGetNameString(subjectCert, CERT_NAME_EMAIL_TYPE, 0, NULL, tmp, sizeof(tmp))==1){ KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to get subjects name from PKI certificate."); goto cleanup; } KSI_LOG_debug(ctx, "CryptoAPI: Subjects E-mail: %s.", tmp); if (strcmp(tmp, magicEmail) != 0) { KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, "Wrong subject name."); goto cleanup; } } res = KSI_PKITruststore_verifyCertificate(pki, subjectCert); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } res = KSI_OK; cleanup: if (subjectCert) CertFreeCertificateContext(subjectCert); return res; }
bool mod_crypto::getCertNameFromCertCTX(PCCERT_CONTEXT certCTX, wstring * certName) { bool reussite = false; wchar_t * monBuffer = NULL; DWORD maRecherche[] = {CERT_NAME_FRIENDLY_DISPLAY_TYPE, CERT_NAME_DNS_TYPE, CERT_NAME_EMAIL_TYPE, CERT_NAME_UPN_TYPE, CERT_NAME_URL_TYPE}; for(DWORD i = 0; !reussite && (i < (sizeof(maRecherche) / sizeof(DWORD))); i++) { DWORD tailleRequise = CertGetNameString(certCTX, maRecherche[i], 0, NULL, NULL, 0); if(tailleRequise > 1) { monBuffer = new wchar_t[tailleRequise]; reussite = CertGetNameString(certCTX, maRecherche[i], 0, NULL, monBuffer, tailleRequise) > 1; certName->assign(monBuffer); delete[] monBuffer; } } return reussite; }
static BOOL RunDlg_FillItem(PCCERT_CONTEXT pCertContext, char *psRes) { char sTemp[dSTRING_ITEM_LEN+1]; SYSTEMTIME oT; PCERT_INFO pCertInfo; BOOL fRes = TRUE; *psRes = 0; if (pCertContext == NULL || pCertContext->pCertInfo == NULL || psRes == NULL) return(FALSE); pCertInfo = pCertContext->pCertInfo; CertGetNameString(pCertContext,CERT_NAME_SIMPLE_DISPLAY_TYPE,CERT_NAME_ISSUER_FLAG,NULL,sTemp,dSTRING_ITEM_LEN); if (lstrlen(sTemp) > 0) { lstrcat(psRes,sTemp); lstrcat(psRes," \t"); } CertGetNameString(pCertContext,CERT_NAME_SIMPLE_DISPLAY_TYPE,0,NULL,sTemp,dSTRING_ITEM_LEN); //CorrectCharacters(sTemp); if (lstrlen(sTemp) > 0) { lstrcat(psRes,sTemp); lstrcat(psRes," \t"); } if (FileTimeToSystemTime(&pCertInfo->NotBefore,&oT) == TRUE) { sprintf(sTemp,"%02d/%02d/%02d \t",oT.wYear,oT.wMonth,oT.wDay); lstrcat(psRes,sTemp); } else fRes = FALSE; if (FileTimeToSystemTime(&pCertInfo->NotAfter,&oT) == TRUE) { sprintf(sTemp,"%02d/%02d/%02d \t",oT.wYear,oT.wMonth,oT.wDay); lstrcat(psRes,sTemp); } else fRes = FALSE; if (DigiCrypt_GetCSPFromCert(pCertContext, sTemp, dSTRING_ITEM_LEN) == TRUE) lstrcat(psRes,sTemp); return(fRes); }
static int KSI_PKITruststore_verifySignatureCertificate(const KSI_PKITruststore *pki, const KSI_PKISignature *signature) { int res = KSI_UNKNOWN_ERROR; KSI_CTX *ctx = NULL; PCCERT_CONTEXT subjectCert = NULL; char tmp[256]; size_t i; if (pki == NULL || signature == NULL){ res = KSI_INVALID_ARGUMENT; goto cleanup; } ctx = pki->ctx; KSI_ERR_clearErrors(ctx); res = extractSigningCertificate(signature, &subjectCert); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } for (i = 0; pki->ctx->certConstraints[i].oid != NULL; i++) { KSI_CertConstraint *ptr = &pki->ctx->certConstraints[i]; KSI_LOG_info(pki->ctx, "Verifying PKI signature certificate with oid = '%s' expected value '%s'.", ptr->oid, ptr->val); if (CertGetNameString(subjectCert, CERT_NAME_ATTR_TYPE, 0, ptr->oid, tmp, sizeof(tmp)) == 1){ KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to get OID value."); goto cleanup; } if (strcmp(tmp, ptr->val) != 0) { KSI_LOG_debug(pki->ctx, "Unexpected value for OID='%s': '%s'", ptr->oid, tmp); KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, "Unexpected OID value."); goto cleanup; } } res = KSI_PKITruststore_verifyCertificate(pki, subjectCert); if (res != KSI_OK){ KSI_pushError(ctx, res, NULL); goto cleanup; } res = KSI_OK; cleanup: if (subjectCert) CertFreeCertificateContext(subjectCert); return res; }
void printCertificates(lib::rng::range<Certificate> certificates) { for (auto& key : certificates) { unique_winerror winerror; PCCERT_CONTEXT certcontext = CertCreateCertificateContext( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &key.cert[0], key.cert.size() ); winerror = make_winerror_if(!certcontext); if (!winerror) { std::wcout << L"could not get cert context" << std::endl; continue; } DWORD sizesubject = 0; std::wstring subjectname; for (bool getsize = true; ; getsize = false) { sizesubject = CertGetNameString( certcontext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, getsize ? nullptr : &subjectname[0], sizesubject ); if (sizesubject == 1) { std::wcout << L"could not get subject name" << std::endl; break; } if (getsize) { subjectname.resize(sizesubject - 1); } else { std::wcout << L"key name: " << key.key.c_str() << L" subject name: " << subjectname.c_str() << std::endl; break; } } } }
void SSL_SOCKET :: GetCertificateInfoString(TCHAR* s) { PCCERT_CONTEXT pRemoteCertContext = NULL; SECURITY_STATUS Status = QueryContextAttributes(&hCtx,SECPKG_ATTR_REMOTE_CERT_CONTEXT,(PVOID)&pRemoteCertContext); if (Status != SEC_E_OK) return; CertGetNameString( pRemoteCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, s, 1000); CertFreeCertificateContext(pRemoteCertContext); }
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; }
/** * Checks to see if a file stored at filePath matches the specified info. * * @param certContext The certificate context of the file * @param infoToMatch The acceptable information to match * @return FALSE if the info does not match or if any error occurs in the check */ BOOL DoCertificateAttributesMatch(PCCERT_CONTEXT certContext, CertificateCheckInfo &infoToMatch) { DWORD dwData; LPWSTR szName = nullptr; if (infoToMatch.issuer) { // Pass in nullptr to get the needed size of the issuer buffer. dwData = CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, nullptr, nullptr, 0); if (!dwData) { LOG_WARN(("CertGetNameString failed. (%d)", GetLastError())); return FALSE; } // Allocate memory for Issuer name buffer. szName = (LPWSTR)LocalAlloc(LPTR, dwData * sizeof(WCHAR)); if (!szName) { LOG_WARN(("Unable to allocate memory for issuer name. (%d)", GetLastError())); return FALSE; } // Get Issuer name. if (!CertGetNameStringW(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, nullptr, szName, dwData)) { LOG_WARN(("CertGetNameString failed. (%d)", GetLastError())); LocalFree(szName); return FALSE; } // If the issuer does not match, return a failure. if (!infoToMatch.issuer || wcscmp(szName, infoToMatch.issuer)) { LocalFree(szName); return FALSE; } LocalFree(szName); szName = nullptr; } if (infoToMatch.name) { // Pass in nullptr to get the needed size of the name buffer. dwData = CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, nullptr, nullptr, 0); if (!dwData) { LOG_WARN(("CertGetNameString failed. (%d)", GetLastError())); return FALSE; } // Allocate memory for the name buffer. szName = (LPWSTR)LocalAlloc(LPTR, dwData * sizeof(WCHAR)); if (!szName) { LOG_WARN(("Unable to allocate memory for subject name. (%d)", GetLastError())); return FALSE; } // Obtain the name. if (!(CertGetNameStringW(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, nullptr, szName, dwData))) { LOG_WARN(("CertGetNameString failed. (%d)", GetLastError())); LocalFree(szName); return FALSE; } // If the issuer does not match, return a failure. if (!infoToMatch.name || wcscmp(szName, infoToMatch.name)) { LocalFree(szName); return FALSE; } // We have a match! LocalFree(szName); } // If there were any errors we would have aborted by now. return TRUE; }
/// /// Disabled all enhanced key usages for the specified certificate. /// void RemoveAllEnhancedKeyUsages(LPTSTR pszStoreName, LPTSTR szSubjectName) { HANDLE hStoreHandle = NULL; PCCERT_CONTEXT pCertContext = NULL; // Open Store. if (hStoreHandle = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE, pszStoreName)) { _tprintf(TEXT("[i] Successfully opened certificate store '%s'\n"), pszStoreName); } else { ErrorHandler("Failed to open certificate store"); exit(1); } // // Iterate over certificates in this store. while (pCertContext = CertEnumCertificatesInStore(hStoreHandle, pCertContext)) { DWORD cbSize; LPTSTR pszName; // Get the Certificate Subject Name. cbSize = CertNameToStr(pCertContext->dwCertEncodingType, &(pCertContext->pCertInfo->Subject), CERT_OID_NAME_STR, NULL, 0); if (1 == cbSize) { ErrorHandler("Failed to return the subject name of the certificate."); } if (!(pszName = (LPTSTR)malloc(cbSize * sizeof(TCHAR)))) { ErrorHandler("Failed to allocate memory"); } if (CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszName, cbSize)) { // _tprintf(TEXT("%s\n"), pszName); } else { ErrorHandler("CertGetNameString failed"); } // // Is this the certificate we're looking for? if (_tcscmp(pszName, szSubjectName) == 0) { _tprintf(TEXT("[i] Located certificate %s\n"), pszName); PCERT_ENHKEY_USAGE pEKeyUsage = NULL; if (!(pEKeyUsage = (PCERT_ENHKEY_USAGE)CryptMemAlloc(sizeof(CERT_ENHKEY_USAGE)))) { ErrorHandler("Failed to allocate memory"); } if (CertSetEnhancedKeyUsage(pCertContext, pEKeyUsage)) { _tprintf(TEXT("[i] Removed EKU\n")); } else { ErrorHandler("CertSetEnhancedKeyUsage Failed"); } CryptMemFree(pEKeyUsage); } free(pszName); } // Clean Up if (pCertContext) CertFreeCertificateContext(pCertContext); if (hStoreHandle) { if (!CertCloseStore(hStoreHandle, 0)) ErrorHandler("Failed CertCloseStorn"); } }
void SchannelCertificate::parse() { // // Subject name // DWORD requiredSize = CertNameToStr(X509_ASN_ENCODING, &m_cert->pCertInfo->Subject, CERT_OID_NAME_STR, NULL, 0); if (requiredSize > 1) { vector<char> rawSubjectName(requiredSize); CertNameToStr(X509_ASN_ENCODING, &m_cert->pCertInfo->Subject, CERT_OID_NAME_STR, &rawSubjectName[0], rawSubjectName.size()); m_subjectName = std::string(&rawSubjectName[0]); } // // Common name // // Note: We only pull out one common name from the cert. requiredSize = CertGetNameString(m_cert, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, NULL, 0); if (requiredSize > 1) { vector<char> rawCommonName(requiredSize); requiredSize = CertGetNameString(m_cert, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, &rawCommonName[0], rawCommonName.size()); m_commonNames.push_back( std::string(&rawCommonName[0]) ); } // // Subject alternative names // PCERT_EXTENSION pExtensions = CertFindExtension(szOID_SUBJECT_ALT_NAME2, m_cert->pCertInfo->cExtension, m_cert->pCertInfo->rgExtension); if (pExtensions) { CRYPT_DECODE_PARA decodePara = {0}; decodePara.cbSize = sizeof(decodePara); CERT_ALT_NAME_INFO* pAltNameInfo = NULL; DWORD altNameInfoSize = 0; BOOL status = CryptDecodeObjectEx( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, szOID_SUBJECT_ALT_NAME2, pExtensions->Value.pbData, pExtensions->Value.cbData, CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG, &decodePara, &pAltNameInfo, &altNameInfoSize); if (status && pAltNameInfo) { for (int i = 0; i < pAltNameInfo->cAltEntry; i++) { if (pAltNameInfo->rgAltEntry[i].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME) addDNSName( wstrToStr( pAltNameInfo->rgAltEntry[i].pwszDNSName ) ); } } } // if (pExtensions) // { // vector<wchar_t> subjectAlt // CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, szOID_SUBJECT_ALT_NAME, pExtensions->Value->pbData, pExtensions->Value->cbData, ) // } // // // subjectAltNames // int subjectAltNameLoc = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1); // if(subjectAltNameLoc != -1) { // X509_EXTENSION* extension = X509_get_ext(cert.get(), subjectAltNameLoc); // std::shared_ptr<GENERAL_NAMES> generalNames(reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(extension)), GENERAL_NAMES_free); // std::shared_ptr<ASN1_OBJECT> xmppAddrObject(OBJ_txt2obj(ID_ON_XMPPADDR_OID, 1), ASN1_OBJECT_free); // std::shared_ptr<ASN1_OBJECT> dnsSRVObject(OBJ_txt2obj(ID_ON_DNSSRV_OID, 1), ASN1_OBJECT_free); // for (int i = 0; i < sk_GENERAL_NAME_num(generalNames.get()); ++i) { // GENERAL_NAME* generalName = sk_GENERAL_NAME_value(generalNames.get(), i); // if (generalName->type == GEN_OTHERNAME) { // OTHERNAME* otherName = generalName->d.otherName; // if (OBJ_cmp(otherName->type_id, xmppAddrObject.get()) == 0) { // // XmppAddr // if (otherName->value->type != V_ASN1_UTF8STRING) { // continue; // } // ASN1_UTF8STRING* xmppAddrValue = otherName->value->value.utf8string; // addXMPPAddress(ByteArray(ASN1_STRING_data(xmppAddrValue), ASN1_STRING_length(xmppAddrValue)).toString()); // } // else if (OBJ_cmp(otherName->type_id, dnsSRVObject.get()) == 0) { // // SRVName // if (otherName->value->type != V_ASN1_IA5STRING) { // continue; // } // ASN1_IA5STRING* srvNameValue = otherName->value->value.ia5string; // addSRVName(ByteArray(ASN1_STRING_data(srvNameValue), ASN1_STRING_length(srvNameValue)).toString()); // } // } // else if (generalName->type == GEN_DNS) { // // DNSName // addDNSName(ByteArray(ASN1_STRING_data(generalName->d.dNSName), ASN1_STRING_length(generalName->d.dNSName)).toString()); // } // } // } }
void DecodeMessage(PCRYPT_DATA_BLOB pEncodedBlob, LPWSTR pwszSignerName) { //--------------------------------------------------------------- // Buffer to hold the name of the subject of a certificate. wchar_t pszNameString[MAX_NAME]; //--------------------------------------------------------------- // The following variables are used only in the decoding phase. HCRYPTMSG hMsg; HCERTSTORE hStoreHandle; // certificate store handle DWORD cbData = sizeof(DWORD); DWORD cbDecoded; BYTE *pbDecoded; DWORD cbSignerCertInfo; PCERT_INFO pSignerCertInfo; PCCERT_CONTEXT pSignerCertContext; /*--------------------------------------------------------------- The following code decodes the message and verifies the message signature. This code would normally be in a stand-alone program that would read the signed and encoded message and its length from a file from an email message, or from some other source. ---------------------------------------------------------------*/ //--------------------------------------------------------------- // Open a message for decoding. if(hMsg = CryptMsgOpenToDecode( MY_ENCODING_TYPE, // encoding type 0, // flags 0, // use the default message type // the message type is // listed in the message header NULL, // cryptographic provider // use NULL for the default provider NULL, // recipient information NULL)) // stream information { printf("The message to decode is open. \n"); } else { MyHandleError("OpenToDecode failed"); } //--------------------------------------------------------------- // Update the message with an encoded BLOB. if(CryptMsgUpdate( hMsg, // handle to the message pEncodedBlob->pbData, // pointer to the encoded BLOB pEncodedBlob->cbData, // size of the encoded BLOB TRUE)) // last call { printf("The encoded BLOB has been added to the message. \n"); } else { MyHandleError("Decode MsgUpdate failed"); } //--------------------------------------------------------------- // Get the number of bytes needed for a buffer // to hold the decoded message. if(CryptMsgGetParam( hMsg, // handle to the message CMSG_CONTENT_PARAM, // parameter type 0, // index NULL, &cbDecoded)) // size of the returned information { printf("The message parameter has been acquired. \n"); } else { MyHandleError("Decode CMSG_CONTENT_PARAM failed."); } //--------------------------------------------------------------- // Allocate memory. if(!(pbDecoded = (BYTE *) malloc(cbDecoded))) { MyHandleError("Decode memory allocation failed."); } //--------------------------------------------------------------- // Copy the content to the buffer. if(CryptMsgGetParam( hMsg, // handle to the message CMSG_CONTENT_PARAM, // parameter type 0, // index pbDecoded, // address for returned information &cbDecoded)) // size of the returned information { printf("The decoded message is =>\n%s\n\n", (LPSTR)pbDecoded); } else { MyHandleError("Decode CMSG_CONTENT_PARAM #2 failed"); } //--------------------------------------------------------------- // Verify the signature. // First, get the signer CERT_INFO from the message. //--------------------------------------------------------------- // Get the size of memory required for the certificate. if(CryptMsgGetParam( hMsg, // handle to the message CMSG_SIGNER_CERT_INFO_PARAM, // parameter type 0, // index NULL, &cbSignerCertInfo)) // size of the returned // information { printf("%d bytes needed for the buffer.\n", cbSignerCertInfo); } else { MyHandleError("Verify SIGNER_CERT_INFO #1 failed."); } //--------------------------------------------------------------- // Allocate memory. if(!(pSignerCertInfo = (PCERT_INFO) malloc(cbSignerCertInfo))) { MyHandleError("Verify memory allocation failed."); } //--------------------------------------------------------------- // Get the message certificate information (CERT_INFO // structure). if(!(CryptMsgGetParam( hMsg, // handle to the message CMSG_SIGNER_CERT_INFO_PARAM, // parameter type 0, // index pSignerCertInfo, // address for returned // information &cbSignerCertInfo))) // size of the returned // information { MyHandleError("Verify SIGNER_CERT_INFO #2 failed"); } //--------------------------------------------------------------- // Open a certificate store in memory using CERT_STORE_PROV_MSG, // which initializes it with the certificates from the message. if(hStoreHandle = CertOpenStore( CERT_STORE_PROV_MSG, // store provider type MY_ENCODING_TYPE, // encoding type NULL, // cryptographic provider // use NULL for the default 0, // flags hMsg)) // handle to the message { printf("The certificate store to be used for message " \ "verification has been opened.\n"); } else { MyHandleError("Verify open store failed"); } //--------------------------------------------------------------- // Find the signer's certificate in the store. if(pSignerCertContext = CertGetSubjectCertificateFromStore( hStoreHandle, // handle to the store MY_ENCODING_TYPE, // encoding type pSignerCertInfo)) // pointer to retrieved CERT_CONTEXT { if(CertGetNameString( pSignerCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, MAX_NAME) > 1) { wprintf(L"The message signer is %s \n",pszNameString); } else { MyHandleError("Getting the signer's name failed.\n"); } } else { MyHandleError("Verify GetSubjectCert failed"); } //--------------------------------------------------------------- // Use the CERT_INFO from the signer certificate to verify // the signature. if(CryptMsgControl( hMsg, 0, CMSG_CTRL_VERIFY_SIGNATURE, pSignerCertContext->pCertInfo)) { printf("Verify signature succeeded. \n"); } else { printf("The signature was not verified. \n"); DWORD const errcode = GetLastError(); std::wcerr << format_sys_message<TCHAR>(errcode) << TEXT("\n"); ReportFailure(); } //--------------------------------------------------------------- // Clean up. if(pEncodedBlob->pbData) { free(pEncodedBlob->pbData); pEncodedBlob->pbData = NULL; } if(pbDecoded) { free(pbDecoded); } if(pSignerCertInfo) { free(pSignerCertInfo); } if(pSignerCertContext) { CertFreeCertificateContext(pSignerCertContext); } if(hStoreHandle) { CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG); } if(hMsg) { CryptMsgClose(hMsg); } }
static CURLcode verify_certificate(struct connectdata *conn, int sockindex) { SECURITY_STATUS status; struct SessionHandle *data = conn->data; struct ssl_connect_data *connssl = &conn->ssl[sockindex]; CURLcode result = CURLE_OK; CERT_CONTEXT *pCertContextServer = NULL; const CERT_CHAIN_CONTEXT *pChainContext = NULL; status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &pCertContextServer); if((status != SEC_E_OK) || (pCertContextServer == NULL)) { failf(data, "schannel: Failed to read remote certificate context: %s", Curl_sspi_strerror(conn, status)); result = CURLE_PEER_FAILED_VERIFICATION; } if(result == CURLE_OK) { CERT_CHAIN_PARA ChainPara; memset(&ChainPara, 0, sizeof(ChainPara)); ChainPara.cbSize = sizeof(ChainPara); if(!CertGetCertificateChain(NULL, pCertContextServer, NULL, pCertContextServer->hCertStore, &ChainPara, 0, NULL, &pChainContext)) { failf(data, "schannel: CertGetCertificateChain failed: %s", Curl_sspi_strerror(conn, GetLastError())); pChainContext = NULL; result = CURLE_PEER_FAILED_VERIFICATION; } if(result == CURLE_OK) { CERT_SIMPLE_CHAIN *pSimpleChain = pChainContext->rgpChain[0]; DWORD dwTrustErrorMask = ~(DWORD)(CERT_TRUST_IS_NOT_TIME_NESTED| CERT_TRUST_REVOCATION_STATUS_UNKNOWN); dwTrustErrorMask &= pSimpleChain->TrustStatus.dwErrorStatus; if(dwTrustErrorMask) { if(dwTrustErrorMask & CERT_TRUST_IS_PARTIAL_CHAIN) failf(data, "schannel: CertGetCertificateChain trust error" " CERT_TRUST_IS_PARTIAL_CHAIN"); if(dwTrustErrorMask & CERT_TRUST_IS_UNTRUSTED_ROOT) failf(data, "schannel: CertGetCertificateChain trust error" " CERT_TRUST_IS_UNTRUSTED_ROOT"); if(dwTrustErrorMask & CERT_TRUST_IS_NOT_TIME_VALID) failf(data, "schannel: CertGetCertificateChain trust error" " CERT_TRUST_IS_NOT_TIME_VALID"); failf(data, "schannel: CertGetCertificateChain error mask: 0x%08x", dwTrustErrorMask); result = CURLE_PEER_FAILED_VERIFICATION; } } } if(result == CURLE_OK) { if(data->set.ssl.verifyhost) { TCHAR cert_hostname_buff[128]; xcharp_u hostname; xcharp_u cert_hostname; DWORD len; cert_hostname.const_tchar_ptr = cert_hostname_buff; hostname.tchar_ptr = Curl_convert_UTF8_to_tchar(conn->host.name); len = CertGetNameString(pCertContextServer, CERT_NAME_DNS_TYPE, 0, NULL, cert_hostname.tchar_ptr, 128); if(len > 0 && *cert_hostname.tchar_ptr == '*') { /* this is a wildcard cert. try matching the last len - 1 chars */ int hostname_len = strlen(conn->host.name); cert_hostname.tchar_ptr++; if(_tcsicmp(cert_hostname.const_tchar_ptr, hostname.const_tchar_ptr + hostname_len - len + 2) != 0) result = CURLE_PEER_FAILED_VERIFICATION; } else if(len == 0 || _tcsicmp(hostname.const_tchar_ptr, cert_hostname.const_tchar_ptr) != 0) { result = CURLE_PEER_FAILED_VERIFICATION; } if(result == CURLE_PEER_FAILED_VERIFICATION) { char *_cert_hostname; _cert_hostname = Curl_convert_tchar_to_UTF8(cert_hostname.tchar_ptr); failf(data, "schannel: CertGetNameString() certificate hostname " "(%s) did not match connection (%s)", _cert_hostname, conn->host.name); Curl_unicodefree(_cert_hostname); } Curl_unicodefree(hostname.tchar_ptr); } } if(pChainContext) CertFreeCertificateChain(pChainContext); if(pCertContextServer) CertFreeCertificateContext(pCertContextServer); return result; }
BYTE* SignAndEncrypt( wchar_t const*const signer_name, const BYTE *pbToBeSignedAndEncrypted, DWORD cbToBeSignedAndEncrypted, DWORD *pcbSignedAndEncryptedBlob) { //--------------------------------------------------------------- // Declare and initialize local variables. FILE *hToSave; HCERTSTORE hCertStore; //--------------------------------------------------------------- // pSignerCertContext will be the certificate of // the message signer. PCCERT_CONTEXT pSignerCertContext ; //--------------------------------------------------------------- // pReceiverCertContext will be the certificate of the // message receiver. PCCERT_CONTEXT pReceiverCertContext; TCHAR pszNameString[256]; CRYPT_SIGN_MESSAGE_PARA SignPara; CRYPT_ENCRYPT_MESSAGE_PARA EncryptPara; DWORD cRecipientCert; PCCERT_CONTEXT rgpRecipientCert[5]; BYTE *pbSignedAndEncryptedBlob = NULL; //CERT_NAME_BLOB Subject_Blob; BYTE *pbDataIn; DWORD dwKeySpec; NCRYPT_KEY_HANDLE hCryptProv; //--------------------------------------------------------------- // Open the MY certificate store. // For more information, see the CertOpenStore function // PSDK reference page. // Note: Case is not significant in certificate store names. if ( !( hCertStore = CertOpenStore( CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"my"))) { MyHandleError(TEXT("The MY store could not be opened.")); } //--------------------------------------------------------------- // Get the certificate for the signer. if(!(pSignerCertContext = CertFindCertificateInStore( hCertStore, MY_ENCODING_TYPE, 0, CERT_FIND_SUBJECT_STR, signer_name, NULL))) { MyHandleError(TEXT("Cert not found.\n")); } //--------------------------------------------------------------- // Get and print the name of the message signer. // The following two calls to CertGetNameString with different // values for the second parameter get two different forms of // the certificate subject's name. if(CertGetNameString( pSignerCertContext , CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, MAX_NAME) > 1) { _tprintf( TEXT("The SIMPLE_DISPLAY_TYPE message signer's name is ") TEXT("%s \n"), pszNameString); } else { MyHandleError( TEXT("Getting the name of the signer failed.\n")); } if(CertGetNameString( pSignerCertContext, CERT_NAME_RDN_TYPE, 0, NULL, pszNameString, MAX_NAME) > 1) { _tprintf( TEXT("The RDM_TYPE message signer's name is %s \n"), pszNameString); } else { MyHandleError( TEXT("Getting the name of the signer failed.\n")); } if(!( CryptAcquireCertificatePrivateKey( pSignerCertContext, CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, NULL, &hCryptProv, &dwKeySpec, NULL))) { DWORD const errcode = GetLastError(); std::wcerr << format_sys_message<TCHAR>(errcode) << TEXT("\n"); MyHandleError(TEXT("CryptAcquireCertificatePrivateKey.\n")); } pReceiverCertContext = pSignerCertContext; // send to self //--------------------------------------------------------------- // Get and print the subject name from the receiver's // certificate. if(CertGetNameString( pReceiverCertContext , CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, MAX_NAME) > 1) { _tprintf(TEXT("The message receiver is %s \n"), pszNameString); } else { MyHandleError( TEXT("Getting the name of the receiver failed.\n")); } //--------------------------------------------------------------- // Initialize variables and data structures // for the call to CryptSignAndEncryptMessage. SignPara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA); SignPara.dwMsgEncodingType = MY_ENCODING_TYPE; SignPara.pSigningCert = pSignerCertContext ; SignPara.HashAlgorithm.pszObjId = OID_HASH_G34311; SignPara.HashAlgorithm.Parameters.cbData = 0; SignPara.pvHashAuxInfo = NULL; SignPara.cMsgCert = 1; SignPara.rgpMsgCert = &pSignerCertContext ; SignPara.cMsgCrl = 0; SignPara.rgpMsgCrl = NULL; SignPara.cAuthAttr = 0; SignPara.rgAuthAttr = NULL; SignPara.cUnauthAttr = 0; SignPara.rgUnauthAttr = NULL; SignPara.dwFlags = 0; SignPara.dwInnerContentType = 0; EncryptPara.cbSize = sizeof(CRYPT_ENCRYPT_MESSAGE_PARA); EncryptPara.dwMsgEncodingType = MY_ENCODING_TYPE; EncryptPara.hCryptProv = 0; EncryptPara.ContentEncryptionAlgorithm.pszObjId = OID_G28147_89_GAMMA_CBC; //szOID_RSA_RC4; EncryptPara.ContentEncryptionAlgorithm.Parameters.cbData = 0; EncryptPara.pvEncryptionAuxInfo = NULL; EncryptPara.dwFlags = 0; EncryptPara.dwInnerContentType = 0; cRecipientCert = 1; rgpRecipientCert[0] = pReceiverCertContext; *pcbSignedAndEncryptedBlob = 0; pbSignedAndEncryptedBlob = NULL; if( CryptSignAndEncryptMessage( &SignPara, &EncryptPara, cRecipientCert, rgpRecipientCert, pbToBeSignedAndEncrypted, cbToBeSignedAndEncrypted, NULL, // the pbSignedAndEncryptedBlob pcbSignedAndEncryptedBlob)) { _tprintf(TEXT("%d bytes for the buffer .\n"), *pcbSignedAndEncryptedBlob); } else { DWORD const errcode = GetLastError(); std::wcerr << format_sys_message<TCHAR>(errcode) << TEXT("\n"); MyHandleError(TEXT("Getting the buffer length failed.")); } //--------------------------------------------------------------- // Allocate memory for the buffer. if(!(pbSignedAndEncryptedBlob = (unsigned char *)malloc(*pcbSignedAndEncryptedBlob))) { MyHandleError(TEXT("Memory allocation failed.")); } //--------------------------------------------------------------- // Call the function a second time to copy the signed and // encrypted message into the buffer. if( CryptSignAndEncryptMessage( &SignPara, &EncryptPara, cRecipientCert, rgpRecipientCert, pbToBeSignedAndEncrypted, cbToBeSignedAndEncrypted, pbSignedAndEncryptedBlob, pcbSignedAndEncryptedBlob)) { _tprintf(TEXT("The message is signed and encrypted.\n")); } else { MyHandleError( TEXT("The message failed to sign and encrypt.")); } //--------------------------------------------------------------- // Clean up. if(pSignerCertContext ) { CertFreeCertificateContext(pSignerCertContext); } // send to self so the same cert is used // if(pReceiverCertContext ) // { // CertFreeCertificateContext(pReceiverCertContext); // } CertCloseStore(hCertStore, 0); //--------------------------------------------------------------- // Return the signed and encrypted message. return pbSignedAndEncryptedBlob; } // End SignAndEncrypt.
BOOL CPublisherHelp::PrintCertificateInfo(PCCERT_CONTEXT pCertContext) { BOOL fReturn = FALSE; LPTSTR szName = NULL; DWORD dwData; __try { // Print Serial Number. _tprintf(_T("Serial Number: ")); dwData = pCertContext->pCertInfo->SerialNumber.cbData; for (DWORD n = 0; n < dwData; n++) { _tprintf(_T("%02x "), pCertContext->pCertInfo->SerialNumber.pbData[dwData - (n + 1)]); } _tprintf(_T("\n")); // Get Issuer name size. if (!(dwData = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, 0))) { _tprintf(_T("CertGetNameString failed.\n")); __leave; } // Allocate memory for Issuer name. szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR)); if (!szName) { _tprintf(_T("Unable to allocate memory for issuer name.\n")); __leave; } // Get Issuer name. if (!(CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, szName, dwData))) { _tprintf(_T("CertGetNameString failed.\n")); __leave; } // print Issuer name. _tprintf(_T("Issuer Name: %s\n"), szName); LocalFree(szName); szName = NULL; // Get Subject name size. if (!(dwData = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0))) { _tprintf(_T("CertGetNameString failed.\n")); __leave; } // Allocate memory for subject name. szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(TCHAR)); if (!szName) { _tprintf(_T("Unable to allocate memory for subject name.\n")); __leave; } // Get subject name. if (!(CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, szName, dwData))) { _tprintf(_T("CertGetNameString failed.\n")); __leave; } // Print Subject Name. _tprintf(_T("Subject Name: %s\n"), szName); fReturn = TRUE; } __finally { if (szName != NULL) LocalFree(szName); } return fReturn; }
// 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; }
// Select, and return a handle to a server certificate located by name // Usually used for a best guess at a certificate to be used as the SSL certificate for a server SECURITY_STATUS CertFindServerByName(PCCERT_CONTEXT & pCertContext, LPCTSTR pszSubjectName, boolean fUserStore) { HCERTSTORE hMyCertStore = NULL; TCHAR pszFriendlyNameString[128]; TCHAR pszNameString[128]; if (pszSubjectName == NULL || _tcslen(pszSubjectName) == 0) { DebugMsg("**** No subject name specified!"); return E_POINTER; } if (fUserStore) hMyCertStore = CertOpenSystemStore(NULL, _T("MY")); else { // Open the local machine certificate store. hMyCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING, NULL, CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE, L"MY"); } if (!hMyCertStore) { int err = GetLastError(); if (err == ERROR_ACCESS_DENIED) DebugMsg("**** CertOpenStore failed with 'access denied'"); else DebugMsg("**** Error %d returned by CertOpenStore", err); return HRESULT_FROM_WIN32(err); } if (pCertContext) // The caller passed in a certificate context we no longer need, so free it CertFreeCertificateContext(pCertContext); pCertContext = NULL; char * serverauth = szOID_PKIX_KP_SERVER_AUTH; CERT_ENHKEY_USAGE eku; PCCERT_CONTEXT pCertContextSaved = NULL; eku.cUsageIdentifier = 1; eku.rgpszUsageIdentifier = &serverauth; // Find a server certificate. Note that this code just searches for a // certificate that has the required enhanced key usage for server authentication // it then selects the best one (ideally one that contains the server name // in the subject name). while (NULL != (pCertContext = CertFindCertificateInStore(hMyCertStore, X509_ASN_ENCODING, CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG, CERT_FIND_ENHKEY_USAGE, &eku, pCertContext))) { //ShowCertInfo(pCertContext); if (!CertGetNameString(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszFriendlyNameString, sizeof(pszFriendlyNameString))) { DebugMsg("CertGetNameString failed getting friendly name."); continue; } DebugMsg("Certificate '%S' is allowed to be used for server authentication.", ATL::CT2W(pszFriendlyNameString)); if (!CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, sizeof(pszNameString))) DebugMsg("CertGetNameString failed getting subject name."); else if (_tcscmp(pszNameString, pszSubjectName)) DebugMsg("Certificate has wrong subject name."); else if (CertCompareCertificateName(X509_ASN_ENCODING, &pCertContext->pCertInfo->Subject, &pCertContext->pCertInfo->Issuer)) { if (!pCertContextSaved) { DebugMsg("A self-signed certificate was found and saved in case it is needed."); pCertContextSaved = CertDuplicateCertificateContext(pCertContext); } } else { DebugMsg("Certificate is acceptable."); if (pCertContextSaved) // We have a saved self signed certificate context we no longer need, so free it CertFreeCertificateContext(pCertContextSaved); pCertContextSaved = NULL; break; } } if (pCertContextSaved && !pCertContext) { // We have a saved self-signed certificate and nothing better DebugMsg("A self-signed certificate was the best we had."); pCertContext = pCertContextSaved; pCertContextSaved = NULL; } if (!pCertContext) { DWORD LastError = GetLastError(); if (LastError == CRYPT_E_NOT_FOUND) { DebugMsg("**** CertFindCertificateInStore did not find a certificate, creating one"); pCertContext = CreateCertificate(true, pszSubjectName); if (!pCertContext) { LastError = GetLastError(); DebugMsg("**** Error 0x%x returned by CreateCertificate", LastError); std::cout << "Could not create certificate, are you running as administrator?" << std::endl; return HRESULT_FROM_WIN32(LastError); } } else { DebugMsg("**** Error 0x%x returned by CertFindCertificateInStore", LastError); return HRESULT_FROM_WIN32(LastError); } } return SEC_E_OK; }
/** * Checks to see if a file stored at filePath matches the specified info. This * only supports the name and issuer attributes currently. * * @param certContext The certificate context of the file * @param infoToMatch The acceptable information to match * @return FALSE if the info does not match or if any error occurs in the check */ BOOL DoCertificateAttributesMatch(PCCERT_CONTEXT certContext, CertificateCheckInfo &infoToMatch) { DWORD dwData; LPTSTR szName = NULL; // Pass in NULL to get the needed size of the issuer buffer. dwData = CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, 0); if (!dwData) { return FALSE; } // Allocate memory for Issuer name buffer. szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(WCHAR)); if (!szName) { return FALSE; } // Get Issuer name. if (!CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, szName, dwData)) { LocalFree(szName); return FALSE; } // If the issuer does not match, return a failure. if (!infoToMatch.issuer || wcscmp(szName, infoToMatch.issuer)) { LocalFree(szName); return FALSE; } LocalFree(szName); szName = NULL; // Pass in NULL to get the needed size of the name buffer. dwData = CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0); if (!dwData) { return FALSE; } // Allocate memory for the name buffer. szName = (LPTSTR)LocalAlloc(LPTR, dwData * sizeof(WCHAR)); if (!szName) { return FALSE; } // Obtain the name. if (!(CertGetNameString(certContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, szName, dwData))) { LocalFree(szName); return FALSE; } // If the issuer does not match, return a failure. if (!infoToMatch.name || wcscmp(szName, infoToMatch.name)) { LocalFree(szName); return FALSE; } // We have a match! LocalFree(szName); // If there were any errors we would have aborted by now. return TRUE; }
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)"); }
int sserver_connect(const struct protocol_interface *protocol, int verify_only) { char crypt_password[64]; char server_version[128]; char tmp_keyname[256]; const char *begin_request = "BEGIN SSL AUTH REQUEST"; const char *end_request = "END SSL AUTH REQUEST"; const char *username = NULL; const char *cert = current_server()->current_root->optional_3; int l; int sserver_version = 0; int strict = 0; CScramble scramble; bool send_client_version = false; if(current_server()->current_root->optional_1) { sserver_version = atoi(current_server()->current_root->optional_1); if(sserver_version != 0 && sserver_version != 1) { server_error(0,"version must be one of:"); server_error(0,"0 - All CVSNT-type servers"); server_error(0,"1 - Unix server using Corey Minards' sserver patches"); server_error(1,"Please specify a valid value"); } } if(!CGlobalSettings::GetUserValue("cvsnt","sserver","StrictChecking",server_version,sizeof(server_version))) { strict = atoi(server_version); } if(!cert && !CGlobalSettings::GetUserValue("cvsnt","sserver","ClientCert",tmp_keyname,sizeof(tmp_keyname))) { cert = tmp_keyname; } if(current_server()->current_root->optional_2) strict = atoi(current_server()->current_root->optional_2); if(sserver_version == 1) /* Old sserver */ { begin_request = verify_only?"BEGIN SSL VERIFICATION REQUEST":"BEGIN SSL REQUEST"; end_request = verify_only?"END SSL VERIFICATION REQUEST":"END SSL REQUEST"; } else if(verify_only) { begin_request = "BEGIN SSL VERIFICATION REQUEST"; end_request = "END SSL VERIFICATION REQUEST"; } username = get_username(current_server()->current_root); if(!username || !current_server()->current_root->hostname || !current_server()->current_root->directory) return CVSPROTO_BADPARMS; if(tcp_connect(current_server()->current_root)) return CVSPROTO_FAIL; if(current_server()->current_root->password) strncpy(crypt_password,scramble.Scramble(current_server()->current_root->password),sizeof(crypt_password)); else { if(sserver_get_user_password(username,current_server()->current_root->hostname,current_server()->current_root->port,current_server()->current_root->directory,crypt_password,sizeof(crypt_password))) { /* Using null password - trace something out here */ server_error(0,"Using an empty password; you may need to do 'cvs login' with a real password\n"); strncpy(crypt_password,scramble.Scramble(""),sizeof(crypt_password)); } } if(sserver_version == 0) /* Pre-CVSNT had no version check */ { if(tcp_printf("%s\n",begin_request)<0) return CVSPROTO_FAIL; for(;;) { *server_version='\0'; if((l=tcp_readline(server_version,sizeof(server_version))<0)) return CVSPROTO_FAIL; if(*server_version) break; #ifdef _WIN32 Sleep(10); #else usleep(10); #endif } if(strncmp(server_version,"SSERVER ",8)) { server_error(0,"%s\n",server_version); return CVSPROTO_FAIL; } if(strncmp(server_version+8,"1.0 ",4)) send_client_version = true; } if(!ClientAuthenticate(cert,current_server()->current_root->hostname)) return CVSPROTO_AUTHFAIL; QueryContextAttributes(&contextHandle,SECPKG_ATTR_STREAM_SIZES,&secSizes); PCERT_CONTEXT sc; PCCERT_CHAIN_CONTEXT pcc; CERT_SIMPLE_CHAIN *psc; CERT_CHAIN_PARA para = { sizeof(CERT_CHAIN_PARA) }; DWORD trust,rc; rc = QueryContextAttributes(&contextHandle,SECPKG_ATTR_REMOTE_CERT_CONTEXT,&sc); if(rc) server_error(1,"Couldn't get server certificate"); if(!CertGetCertificateChain(NULL, sc, NULL, NULL, ¶, 0, NULL, &pcc)) server_error(1,"Couldn't get server certificate chain"); psc = pcc->rgpChain[0]; trust = psc->TrustStatus.dwErrorStatus; if (trust) { if (trust & (CERT_TRUST_IS_PARTIAL_CHAIN | CERT_TRUST_IS_UNTRUSTED_ROOT)) ; // Seld signed else if (trust & (CERT_TRUST_IS_NOT_TIME_VALID)) server_error(1,"Server certificate expired"); else server_error(1,"Server certificate verification failed - %08x",trust); } if(strict) { char certname[256]; CertGetNameString(sc, CERT_NAME_DNS_TYPE, 0, NULL, certname, sizeof(certname)); if(strcasecmp(certname,current_server()->current_root->hostname)) server_error(1, "Certificate CommonName '%s' does not match server name '%s'\n",certname,current_server()->current_root->hostname); } CertFreeCertificateChain(pcc); FreeContextBuffer(sc); g_sslBufferInPos=g_sslBufferOutPos=0; g_sslBufferInLen=g_sslBufferOutLen=0; if(sserver_version == 1) { if(sserver_printf("%s\n",begin_request)<0) return CVSPROTO_FAIL; } // For server versions 1.1+ send CLIENT_VERSION_STRING if(send_client_version && sserver_printf(SSERVER_CLIENT_VERSION_STRING)<0) return CVSPROTO_FAIL; if(sserver_printf("%s\n%s\n",current_server()->current_root->directory,username)<0) return CVSPROTO_FAIL; if(sserver_printf("%s\n",crypt_password)<0) return CVSPROTO_FAIL; if(sserver_printf("%s\n",end_request)<0) return CVSPROTO_FAIL; return CVSPROTO_SUCCESS; }
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; }
// // 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; }
BOOL EncodeMessage(PCRYPT_DATA_BLOB pEncodedBlob, LPWSTR pwszSignerName) { /*--------------------------------------------------------------- Declare and initialize variables. This includes getting a pointer to the message content. This sample creates the message content and gets a pointer to it. In most situations, the content will exist somewhere, and a pointer to it will get passed to the application. ---------------------------------------------------------------*/ HCERTSTORE hSystemStoreHandle; CRYPT_SIGN_MESSAGE_PARA SignMessagePara; //--------------------------------------------------------------- // The message to be signed and encoded. BYTE* pbContent = (BYTE*) "The quick brown fox jumped over " \ "the lazy dog."; /*--------------------------------------------------------------- The length of the message. This must be one more than the value returned by strlen() to include the terminal NULL character. ---------------------------------------------------------------*/ DWORD cbContent = lstrlenA((char *) pbContent) + 1; //--------------------------------------------------------------- // Arrays to hold the message to be signed and its length. const BYTE *rgpbToBeSigned[1] ; DWORD rgcbToBeSigned[1]; //--------------------------------------------------------------- // The signer's certificate. PCCERT_CONTEXT pSignerCert; //--------------------------------------------------------------- // Buffer to hold the name of the subject of a certificate. wchar_t pszNameString[MAX_NAME]; //--------------------------------------------------------------- // The following variables are used only in the decoding phase. DWORD cbData = sizeof(DWORD); //--------------------------------------------------------------- // Begin processing. Display the original message. rgpbToBeSigned[0] = pbContent; rgcbToBeSigned[0] = cbContent; printf("The original message = \n%s\n\n", rgpbToBeSigned[0]); //--------------------------------------------------------------- // Open a certificate store. if(hSystemStoreHandle = CertOpenStore( CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER, CERTIFICATE_STORE_NAME)) { printf("The certificate store is open. \n"); } else { MyHandleError( "Error Getting Store Handle"); } /*--------------------------------------------------------------- Find a certificate in the store. This certificate will be used to sign the message. To sign the message, the certificate must have a private key accessible. ---------------------------------------------------------------*/ if(pSignerCert = CertFindCertificateInStore( hSystemStoreHandle, MY_ENCODING_TYPE, 0, CERT_FIND_SUBJECT_STR, pwszSignerName, NULL)) { //----------------------------------------------------------- // Get and print the name of the subject of the certificate. if(CertGetNameString( pSignerCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, MAX_NAME) > 1) { wprintf(L"The message signer is %s \n",pszNameString); } else { MyHandleError("Getting the name of the signer " \ "failed.\n"); } } else { MyHandleError("Signer certificate not found."); } /*--------------------------------------------------------------- Initialize the CRYPT_SIGN_MESSAGE_PARA structure. First, use memset to set all members to zero or NULL. Then set the values of all members that must be nonzero. ---------------------------------------------------------------*/ memset(&SignMessagePara, 0, sizeof(CRYPT_SIGN_MESSAGE_PARA)); SignMessagePara.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA); SignMessagePara.HashAlgorithm.pszObjId = szOID_RSA_MD2; SignMessagePara.pSigningCert = pSignerCert; SignMessagePara.dwMsgEncodingType = MY_ENCODING_TYPE; SignMessagePara.cMsgCert = 1; SignMessagePara.rgpMsgCert = &pSignerCert; /*--------------------------------------------------------------- In two steps, sign and encode the message. First, get the number of bytes required for the buffer to hold the signed and encoded message. ---------------------------------------------------------------*/ if( CryptSignMessage( &SignMessagePara, FALSE, 1, rgpbToBeSigned, rgcbToBeSigned, NULL, &pEncodedBlob->cbData)) { printf("The needed length is %d \n", pEncodedBlob->cbData); } else { MyHandleError("Getting the length failed.\n"); } //--------------------------------------------------------------- // Allocate memory for the required buffer. pEncodedBlob->pbData = (BYTE *)malloc(pEncodedBlob->cbData); if(!pEncodedBlob->pbData) { MyHandleError("Memory allocation failed."); } //--------------------------------------------------------------- // Call CryptSignMessage a second time to // copy the signed and encoded message to the buffer. if( CryptSignMessage( &SignMessagePara, FALSE, 1, rgpbToBeSigned, rgcbToBeSigned, pEncodedBlob->pbData, &pEncodedBlob->cbData)) { printf("Signing worked \n"); } else { MyHandleError("Signing failed.\n"); } //--------------------------------------------------------------- // Clean up after signing and encoding. if(pSignerCert) { CertFreeCertificateContext(pSignerCert); } if(hSystemStoreHandle) { CertCloseStore(hSystemStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG); } return TRUE; }