Thanks @RbMm for your suggestion with CertGetCertificateChain
, that does solve my question.
To get the whole chain, you need to start at the leaf certificate (store seams to start top-down).
Adapted from https://docs.microsoft.com/de-de/windows/desktop/SecCrypto/example-c-program-creating-a-certificate-chain:
CERT_INFO CertInfo;
CertInfo.Issuer = pSignerInfo->Issuer;
CertInfo.SerialNumber = pSignerInfo->SerialNumber;
pCertContext = CertFindCertificateInStore(hStore, ENCODING, 0, CERT_FIND_SUBJECT_CERT, (PVOID)&CertInfo, NULL);
if (!pCertContext) {
_tprintf(_T("CertFindCertificateInStore failed with %x\n"), GetLastError());
__leave;
}
CERT_ENHKEY_USAGE EnhkeyUsage;
CERT_USAGE_MATCH CertUsage;
CERT_CHAIN_PARA ChainPara;
EnhkeyUsage.cUsageIdentifier = 0;
EnhkeyUsage.rgpszUsageIdentifier = NULL;
CertUsage.dwType = USAGE_MATCH_TYPE_AND;
CertUsage.Usage = EnhkeyUsage;
ChainPara.cbSize = sizeof(CERT_CHAIN_PARA);
ChainPara.RequestedUsage = CertUsage;
if (!CertGetCertificateChain(
NULL, // use the default chain engine
pCertContext, // 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
dwFlags,
NULL, // currently reserved
&pChainContext)) {
cerr << "Error on CertGetCertificateChain" << endl;
__leave;
}
PCERT_SIMPLE_CHAIN rgpChain = NULL;
PCERT_CHAIN_ELEMENT rgpElement = NULL;
rgpChain = pChainContext->rgpChain[0];
for (int j = 0; j < rgpChain->cElement; j++) {
rgpElement = rgpChain->rgpElement[j];
PrintCertificateInfo(rgpElement->pCertContext);
cout << endl;
}
CertGetCertificateChain
– RbMmCertGetCertificateChain
. You can find thepCertContext
inpChainContext->rgpChain[0]->rgpElement[i]->pCertContext
– user2369952