absl::StatusOr Object::NewKeyPair()

in kmsp11/object.cc [256:295]


absl::StatusOr<KeyPair> Object::NewKeyPair(const kms_v1::CryptoKeyVersion& ckv,
                                           BSSL_CONST EVP_PKEY* public_key) {
  ASSIGN_OR_RETURN(std::string pub_der, MarshalX509PublicKeyDer(public_key));

  AttributeMap pub_attrs;
  pub_attrs.PutULong(CKA_CLASS, CKO_PUBLIC_KEY);
  RETURN_IF_ERROR(AddStorageAttributes(&pub_attrs, ckv));
  RETURN_IF_ERROR(AddKeyAttributes(&pub_attrs, ckv));
  RETURN_IF_ERROR(AddPublicKeyAttributes(&pub_attrs, ckv, pub_der));

  AttributeMap prv_attrs;
  prv_attrs.PutULong(CKA_CLASS, CKO_PRIVATE_KEY);
  RETURN_IF_ERROR(AddStorageAttributes(&prv_attrs, ckv));
  RETURN_IF_ERROR(AddKeyAttributes(&prv_attrs, ckv));
  RETURN_IF_ERROR(AddPrivateKeyAttributes(&prv_attrs, ckv, pub_der));

  int pkey_id = EVP_PKEY_id(public_key);
  switch (pkey_id) {
    case EVP_PKEY_EC: {
      BSSL_CONST EC_KEY* ec_public_key = EVP_PKEY_get0_EC_KEY(public_key);
      RETURN_IF_ERROR(AddEcPublicKeyAttributes(&pub_attrs, ec_public_key));
      RETURN_IF_ERROR(AddEcPrivateKeyAttributes(&prv_attrs, ec_public_key));
      break;
    }
    case EVP_PKEY_RSA: {
      BSSL_CONST RSA* rsa_public_key = EVP_PKEY_get0_RSA(public_key);
      RETURN_IF_ERROR(AddRsaPublicKeyAttributes(&pub_attrs, rsa_public_key));
      RETURN_IF_ERROR(AddRsaPrivateKeyAttributes(&prv_attrs, rsa_public_key));
      break;
    }
    default:
      return NewError(absl::StatusCode::kUnimplemented,
                      absl::StrFormat("unsupported EVP_PKEY type: %d", pkey_id),
                      CKR_GENERAL_ERROR, SOURCE_LOCATION);
  }

  ASSIGN_OR_RETURN(AlgorithmDetails algorithm, GetDetails(ckv.algorithm()));
  return KeyPair{Object(ckv.name(), CKO_PUBLIC_KEY, algorithm, pub_attrs),
                 Object(ckv.name(), CKO_PRIVATE_KEY, algorithm, prv_attrs)};
}