当我感觉到需要一些递归时,我来到这里,因为我正在实现一个可以验证证书链中信任链的函数。这不是 X.509,而是证书的颁发者密钥必须与签名者的公钥匹配的基础知识。
bool verify_chain(std::vector<Cert>& chain,
Cert* certificate,
unsigned char* pOrigin = nullptr, int depth = 0)
{
bool flag = false;
if (certificate == nullptr) {
// use first element in case parameter is null
certificate = &chain[0];
}
if (pOrigin == nullptr) {
pOrigin = certificate->pubkey;
} else {
if (std::memcmp(pOrigin, certificate->pubkey, 32) == 0) {
return false; // detected circular chain
}
}
if (certificate->hasValidSignature()) {
if (!certificate->isRootCA()) {
Cert* issuerCert = certificate->getIssuer(chain);
if (issuerCert) {
flag = verify_chain(chain, issuerCert, pOrigin, depth+1);
}
} else {
flag = true;
}
}
if (pOrigin && depth == 1) {
pOrigin = nullptr;
}
return flag;
}
我需要知道递归深度,以便正确清理pOrigin。在调用堆栈展开期间位于右侧堆栈帧。
我使用pOrigin 来检测一个循环链,没有它递归调用可以永远持续下去。例如,
- cert0 签署 cert1
- cert1 签署 cert2
- cert2 签署 cert0
我后来意识到一个简单的for-loop 可以在只有一个公共链的简单情况下做到这一点。
bool verify_chain2(std::vector<Cert> &chain, Cert& cert)
{
Cert *pCert = &cert;
unsigned char *startkey = cert.pubkey;
while (pCert != nullptr) {
if (pCert->hasValidSignature()) {
if (!pCert->isRootCA()) {
pCert = pCert->getIssuer(chain);
if (pCert == nullptr
|| std::memcmp(pCert->pubkey, startkey, 32) == 0) {
return false;
}
continue;
} else {
return true;
}
} else {
return false;
}
}
return false;
}
但是当没有一个公共链而是该链在每个证书内时,递归是必须的。我欢迎任何cmets。谢谢。