absl::StatusOr Session::GenerateKeyPair()

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;
}