in kmsp11/object_loader.cc [204:284]
absl::StatusOr<ObjectStoreState> ObjectLoader::BuildState(
const KmsClient& client) {
// In the initial implementation of Provider::LoopRefresh, there is no danger
// of overlapping calls to BuildState. That said, holding the mutex for the
// duration of BuildState seems like a pretty cheap way to guard against an
// unintentional change that causes BuildState calls to overlap.
absl::MutexLock lock(&cache_mutex_);
ObjectStoreState result;
kms_v1::ListCryptoKeysRequest req;
req.set_parent(key_ring_name_);
CryptoKeysRange keys = client.ListCryptoKeys(req);
for (CryptoKeysRange::iterator it = keys.begin(); it != keys.end(); it++) {
ASSIGN_OR_RETURN(kms_v1::CryptoKey key, *it);
if (!IsLoadable(key)) {
continue;
}
kms_v1::ListCryptoKeyVersionsRequest req;
req.set_parent(key.name());
CryptoKeyVersionsRange v = client.ListCryptoKeyVersions(req);
for (CryptoKeyVersionsRange::iterator it = v.begin(); it != v.end(); it++) {
ASSIGN_OR_RETURN(kms_v1::CryptoKeyVersion ckv, *it);
if (!IsLoadable(ckv)) {
continue;
}
Key* cached_key = cache_.Get(ckv.name());
if (cached_key) {
*result.add_keys() = *cached_key;
continue;
}
if (key.purpose() == kms_v1::CryptoKey::MAC ||
key.purpose() == kms_v1::CryptoKey::RAW_ENCRYPT_DECRYPT) {
*result.add_keys() = *cache_.StoreSecretKey(ckv);
} else {
kms_v1::GetPublicKeyRequest pub_req;
pub_req.set_name(ckv.name());
ASSIGN_OR_RETURN(kms_v1::PublicKey pub_resp,
client.GetPublicKey(pub_req));
ASSIGN_OR_RETURN(bssl::UniquePtr<EVP_PKEY> pub,
ParseX509PublicKeyPem(pub_resp.pem()));
ASSIGN_OR_RETURN(std::string public_key_der,
MarshalX509PublicKeyDer(pub.get()));
std::string cert_der;
if (auto it = user_certs_.find(public_key_der);
it != user_certs_.end()) {
cert_der = it->second;
} else if (cert_authority_) {
ASSIGN_OR_RETURN(bssl::UniquePtr<X509> cert,
cert_authority_->GenerateCert(ckv, pub.get()));
ASSIGN_OR_RETURN(cert_der, MarshalX509CertificateDer(cert.get()));
}
*result.add_keys() = *cache_.Store(ckv, public_key_der, cert_der);
}
}
}
// Compute the unused user certificates by copying all of them, then removing
// the ones that were actually used.
absl::flat_hash_set<std::string> unused_user_certs;
for (const auto& [spki, cert] : user_certs_) {
unused_user_certs.emplace(cert);
}
for (const Key& key : result.keys()) {
unused_user_certs.erase(key.certificate().x509_der());
}
if (unused_user_certs.size() > 0) {
LOG(INFO) << "INFO: one or more provided certificates could not be matched "
"to a KMS key.";
}
cache_.EvictUnused(result);
return result;
}