in kmsp11/session.cc [510:568]
absl::StatusOr<AsymmetricHandleSet> Session::GenerateKeyPair(
const CK_MECHANISM& mechanism,
absl::Span<const CK_ATTRIBUTE> public_key_attrs,
absl::Span<const CK_ATTRIBUTE> private_key_attrs,
bool experimental_create_multiple_versions, bool allow_software_keys) {
if (session_type_ == SessionType::kReadOnly) {
return SessionReadOnlyError(SOURCE_LOCATION);
}
switch (mechanism.mechanism) {
case CKM_RSA_PKCS_KEY_PAIR_GEN:
case CKM_EC_KEY_PAIR_GEN:
break;
default:
return InvalidMechanismError(mechanism.mechanism, "GenerateKeyPair",
SOURCE_LOCATION);
}
if (mechanism.pParameter || mechanism.ulParameterLen > 0) {
return InvalidMechanismParamError(
"key generation mechanisms do not take parameters", SOURCE_LOCATION);
}
if (!public_key_attrs.empty()) {
return NewInvalidArgumentError(
"this token does not accept public key attributes",
CKR_TEMPLATE_INCONSISTENT, SOURCE_LOCATION);
}
ASSIGN_OR_RETURN(
KeyGenerationParams prv_gen_params,
ExtractKeyGenerationParams(private_key_attrs, allow_software_keys));
if (prv_gen_params.algorithm.key_gen_mechanism != mechanism.mechanism) {
return NewInvalidArgumentError("algorithm mismatches keygen mechanism",
CKR_TEMPLATE_INCONSISTENT, SOURCE_LOCATION);
}
ASSIGN_OR_RETURN(
CryptoKeyAndVersion key_and_version,
CreateKeyAndVersion(*kms_client_, token_->key_ring_name(), prv_gen_params,
experimental_create_multiple_versions,
allow_software_keys));
RETURN_IF_ERROR(token_->RefreshState(*kms_client_));
AsymmetricHandleSet result;
ASSIGN_OR_RETURN(result.public_key_handle,
token_->FindSingleObject([&](const Object& o) -> bool {
return o.kms_key_name() ==
key_and_version.crypto_key_version.name() &&
o.object_class() == CKO_PUBLIC_KEY;
}));
ASSIGN_OR_RETURN(result.private_key_handle,
token_->FindSingleObject([&](const Object& o) -> bool {
return o.kms_key_name() ==
key_and_version.crypto_key_version.name() &&
o.object_class() == CKO_PRIVATE_KEY;
}));
return result;
}