AwsEncryptionSdk.Keyring.RawRsa (AWS Encryption SDK v0.7.0)

View Source

Raw RSA Keyring implementation.

Uses locally-provided RSA key pairs to wrap and unwrap data keys using asymmetric encryption. Supports multiple padding schemes.

Example

iex> {:ok, public_key} = AwsEncryptionSdk.Keyring.RawRsa.load_public_key_pem(pem_string)
iex> {:ok, keyring} = AwsEncryptionSdk.Keyring.RawRsa.new("my-ns", "my-key", {:oaep, :sha256}, public_key: public_key)
iex> is_struct(keyring, AwsEncryptionSdk.Keyring.RawRsa)
true

Spec Reference

https://github.com/awslabs/aws-encryption-sdk-specification/blob/master/framework/raw-rsa-keyring.md

Summary

Types

RSA padding scheme

RSA private key in Erlang format

RSA public key in Erlang format

t()

Functions

Loads an RSA private key from PEM-encoded string.

Loads an RSA public key from PEM-encoded string.

Unwraps a data key using this keyring's private key.

Wraps a data key using this keyring's public key.

Types

padding_scheme()

@type padding_scheme() ::
  :pkcs1_v1_5
  | {:oaep, :sha1}
  | {:oaep, :sha256}
  | {:oaep, :sha384}
  | {:oaep, :sha512}

RSA padding scheme

rsa_private_key()

@type rsa_private_key() :: tuple()

RSA private key in Erlang format

rsa_public_key()

@type rsa_public_key() :: {:RSAPublicKey, integer(), integer()}

RSA public key in Erlang format

t()

@type t() :: %AwsEncryptionSdk.Keyring.RawRsa{
  key_name: String.t(),
  key_namespace: String.t(),
  padding_scheme: padding_scheme(),
  private_key: rsa_private_key() | nil,
  public_key: rsa_public_key() | nil
}

Functions

load_private_key_pem(pem_string)

@spec load_private_key_pem(String.t()) :: {:ok, rsa_private_key()} | {:error, term()}

Loads an RSA private key from PEM-encoded string.

Supports PKCS#8 PrivateKeyInfo and RSAPrivateKey formats.

Examples

iex> pem = "-----BEGIN PRIVATE KEY-----\n..."
iex> {:ok, key} = AwsEncryptionSdk.Keyring.RawRsa.load_private_key_pem(pem)

load_public_key_pem(pem_string)

@spec load_public_key_pem(String.t()) :: {:ok, rsa_public_key()} | {:error, term()}

Loads an RSA public key from PEM-encoded string.

Supports X.509 SubjectPublicKeyInfo and RSAPublicKey formats.

Examples

iex> pem = "-----BEGIN PUBLIC KEY-----\n..."
iex> {:ok, key} = AwsEncryptionSdk.Keyring.RawRsa.load_public_key_pem(pem)

new(key_namespace, key_name, padding_scheme, opts \\ [])

@spec new(String.t(), String.t(), padding_scheme(), keyword()) ::
  {:ok, t()} | {:error, term()}

Creates a new Raw RSA Keyring.

Parameters

  • key_namespace - Key provider ID (must not start with "aws-kms")
  • key_name - Unique identifier for the key pair
  • padding_scheme - One of :pkcs1_v1_5, {:oaep, :sha1}, {:oaep, :sha256}, {:oaep, :sha384}, {:oaep, :sha512}
  • opts - Keyword list with :public_key and/or :private_key (at least one required)

Returns

  • {:ok, keyring} on success
  • {:error, reason} on validation failure

Errors

  • {:error, :reserved_provider_id} - key_namespace starts with "aws-kms"
  • {:error, :invalid_padding_scheme} - unsupported padding scheme
  • {:error, :no_keys_provided} - neither public nor private key provided

Examples

iex> {:ok, pub} = AwsEncryptionSdk.Keyring.RawRsa.load_public_key_pem(pem)
iex> {:ok, keyring} = AwsEncryptionSdk.Keyring.RawRsa.new("ns", "key", {:oaep, :sha256}, public_key: pub)
iex> keyring.padding_scheme
{:oaep, :sha256}

unwrap_key(keyring, materials, edks)

Unwraps a data key using this keyring's private key.

Iterates through EDKs to find one that:

  1. Has matching key_provider_id (key_namespace)
  2. Has matching key_provider_info (key_name)
  3. Successfully decrypts with this keyring's private key

Returns

  • {:ok, materials} - Data key successfully unwrapped and set
  • {:error, :no_private_key} - No private key configured
  • {:error, :plaintext_data_key_already_set} - Materials already have a key
  • {:error, :unable_to_decrypt_data_key} - No matching EDK could be decrypted

Examples

iex> {:ok, priv} = RawRsa.load_private_key_pem(pem)
iex> {:ok, keyring} = RawRsa.new("ns", "key", {:oaep, :sha256}, private_key: priv)
iex> dec_materials = DecryptionMaterials.new_for_decrypt(suite, ec)
iex> {:ok, result} = RawRsa.unwrap_key(keyring, dec_materials, edks)
iex> is_binary(result.plaintext_data_key)
true

wrap_key(keyring, materials)

Wraps a data key using this keyring's public key.

If materials don't have a plaintext data key, one will be generated. The wrapped key is added to the materials as an EDK.

Examples

iex> {:ok, pub} = RawRsa.load_public_key_pem(pem)
iex> {:ok, keyring} = RawRsa.new("ns", "key", {:oaep, :sha256}, public_key: pub)
iex> suite = AwsEncryptionSdk.AlgorithmSuite.aes_256_gcm_hkdf_sha512_commit_key()
iex> materials = AwsEncryptionSdk.Materials.EncryptionMaterials.new_for_encrypt(suite, %{})
iex> {:ok, result} = RawRsa.wrap_key(keyring, materials)
iex> length(result.encrypted_data_keys) == 1
true