in fizz/extensions/delegatedcred/DelegatedCredentialUtils.cpp [75:158]
DelegatedCredential DelegatedCredentialUtils::generateCredential(
std::shared_ptr<SelfCert> cert,
const folly::ssl::EvpPkeyUniquePtr& certKey,
const folly::ssl::EvpPkeyUniquePtr& credKey,
SignatureScheme signScheme,
SignatureScheme verifyScheme,
std::chrono::seconds validSeconds) {
DelegatedCredential cred;
if (validSeconds > std::chrono::hours(24 * 7)) {
// Can't be valid longer than a week!
throw std::runtime_error(
"Requested credential with exceedingly large validity");
}
checkExtensions(cert->getX509());
if (X509_check_private_key(cert->getX509().get(), certKey.get()) != 1) {
throw std::runtime_error("Cert does not match private key");
}
std::vector<SignatureScheme> credKeySchemes;
switch (CertUtils::getKeyType(credKey)) {
case KeyType::RSA:
credKeySchemes = CertUtils::getSigSchemes<KeyType::RSA>();
break;
case KeyType::P256:
credKeySchemes = CertUtils::getSigSchemes<KeyType::P256>();
break;
case KeyType::P384:
credKeySchemes = CertUtils::getSigSchemes<KeyType::P384>();
break;
case KeyType::P521:
credKeySchemes = CertUtils::getSigSchemes<KeyType::P521>();
break;
case KeyType::ED25519:
credKeySchemes = CertUtils::getSigSchemes<KeyType::ED25519>();
break;
}
if (std::find(credKeySchemes.begin(), credKeySchemes.end(), verifyScheme) ==
credKeySchemes.end()) {
throw std::runtime_error(
"selected verification scheme not supported by credential key");
}
auto certSchemes = cert->getSigSchemes();
if (std::find(certSchemes.begin(), certSchemes.end(), signScheme) ==
certSchemes.end()) {
throw std::runtime_error(
"credential signature scheme not valid for parent cert");
}
cred.credential_scheme = signScheme;
cred.expected_verify_scheme = verifyScheme;
auto notBefore = X509_get0_notBefore(cert->getX509().get());
auto notBeforeTime =
folly::ssl::OpenSSLCertUtils::asnTimeToTimepoint(notBefore);
auto credentialExpiresTime = std::chrono::system_clock::now() + validSeconds;
cred.valid_time = std::chrono::duration_cast<std::chrono::seconds>(
credentialExpiresTime - notBeforeTime)
.count();
int sz = i2d_PUBKEY(credKey.get(), nullptr);
if (sz < 0) {
throw std::runtime_error("failed to get delegated pkey size");
}
unsigned int uSz = static_cast<unsigned int>(sz);
cred.public_key = folly::IOBuf::create(uSz);
auto ptr = reinterpret_cast<unsigned char*>(cred.public_key->writableData());
if (i2d_PUBKEY(credKey.get(), &ptr) < 0) {
throw std::runtime_error("failed to convert delegated key to der");
}
cred.public_key->append(uSz);
auto toSign = prepareSignatureBuffer(
cred, folly::ssl::OpenSSLCertUtils::derEncode(*cert->getX509()));
cred.signature = cert->sign(
cred.credential_scheme,
CertificateVerifyContext::DelegatedCredential,
toSign->coalesce());
return cred;
}