Class: Fog::AWS::KMS::Mock

Inherits:
Object
  • Object
show all
Defined in:
lib/fog/aws/kms.rb,
lib/fog/aws/requests/kms/sign.rb,
lib/fog/aws/requests/kms/list_keys.rb,
lib/fog/aws/requests/kms/create_key.rb,
lib/fog/aws/requests/kms/describe_key.rb,
lib/fog/aws/requests/kms/get_public_key.rb,
lib/fog/aws/requests/kms/schedule_key_deletion.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Mock

Returns a new instance of Mock.



49
50
51
52
53
54
55
56
57
# File 'lib/fog/aws/kms.rb', line 49

def initialize(options={})
  @use_iam_profile = options[:use_iam_profile]
  @account_id = Fog::AWS::Mock.owner_id

  @region = options[:region] || 'us-east-1'
  setup_credentials(options)

  Fog::AWS.validate_region!(@region)
end

Instance Attribute Details

#account_idObject (readonly)

Returns the value of attribute account_id.



47
48
49
# File 'lib/fog/aws/kms.rb', line 47

def 
  @account_id
end

Class Method Details

.dataObject



32
33
34
35
36
37
38
39
40
41
# File 'lib/fog/aws/kms.rb', line 32

def self.data
  @data ||= Hash.new do |hash, region|
    hash[region] = Hash.new do |region_hash, access_key|
      region_hash[access_key] = {
        keys: {},
        pkeys: {}
      }
    end
  end
end

.resetObject



43
44
45
# File 'lib/fog/aws/kms.rb', line 43

def self.reset
  data.clear
end

Instance Method Details

#create_key(*args) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/fog/aws/requests/kms/create_key.rb', line 30

def create_key(*args)
  options = Fog::AWS::KMS.parse_create_key_args(args)

  response = Excon::Response.new
  key_id   = UUID.uuid
  key_arn  = Fog::AWS::Mock.arn("kms", self., "key/#{key_id}", @region)

  key = {
    'Arn' => key_arn,
    'AWSAccountId' => self.,
    'CreationDate' => Time.now.utc,
    'DeletionDate' => nil,
    'Description' => nil,
    'Enabled' => true,
    'KeyId' => key_id,
    'KeySpec' => 'SYMMETRIC_DEFAULT',
    'KeyState' => 'Enabled',
    'KeyUsage' => 'ENCRYPT_DECRYPT',
    'Policy' => nil
  }.merge!(options)

  # @todo use default policy

  self.data[:keys][key_id] = key

  klass, arg = {
    'ECC_NIST_P256' => [OpenSSL::PKey::EC, 'prime256v1'],
    'ECC_NIST_P384' => [OpenSSL::PKey::EC, 'secp384r1'],
    'ECC_NIST_P521' => [OpenSSL::PKey::EC, 'secp521r1'],
    'ECC_SECG_P256K1' => [OpenSSL::PKey::EC, 'secp256k1'],
    'RSA_2048' => [OpenSSL::PKey::RSA, 2048],
    'RSA_3072' => [OpenSSL::PKey::RSA, 3072],
    'RSA_4096' => [OpenSSL::PKey::RSA, 4096]
  }[key['KeySpec']]
  raise "Unknown or not-yet-implemented #{key['KeySpec']} KeySpec for kms create_key mocks" unless klass

  self.data[:pkeys][key_id] = klass.generate(arg)

  response.body = { 'KeyMetadata' => key }
  response
end

#dataObject



66
67
68
# File 'lib/fog/aws/kms.rb', line 66

def data
  self.class.data[@region][@aws_access_key_id]
end

#describe_key(identifier) ⇒ Object



17
18
19
20
21
22
23
# File 'lib/fog/aws/requests/kms/describe_key.rb', line 17

def describe_key(identifier)
  response = Excon::Response.new
  key = self.data[:keys][identifier]

  response.body = { "KeyMetadata" => key }
  response
end

#get_public_key(identifier, _grant_tokens = []) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/fog/aws/requests/kms/get_public_key.rb', line 18

def get_public_key(identifier, _grant_tokens = [])
  response = Excon::Response.new
  key = self.data[:keys][identifier]
  pkey = self.data[:pkeys][identifier]

  response.body = {
    'KeyId' => key['Arn'],
    'KeyUsage' => key['KeyUsage'],
    'KeySpec' => key['KeySpec'],
    'PublicKey' => Base64.strict_encode64(pkey.public_to_der),
    'SigningAlgorithms' => key['SigningAlgorithms']
  }
  response
end

#list_keys(options = {}) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/fog/aws/requests/kms/list_keys.rb', line 26

def list_keys(options={})
  limit  = options[:limit]
  marker = options[:marker]

  if limit
    if limit > 1_000
      raise Fog::AWS::KMS::Error.new(
        "ValidationError => 1 validation error detected: Value '#{limit}' at 'limit' failed to satisfy constraint: Member must have value less than or equal to 1000"
      )
    elsif limit <  1
      raise Fog::AWS::KMS::Error.new(
        "ValidationError => 1 validation error detected: Value '#{limit}' at 'limit' failed to satisfy constraint: Member must have value greater than or equal to 1"
      )
    end
  end

  key_set = if marker
              self.data[:markers][marker] || []
            else
              self.data[:keys].inject([]) do |r, (k, v)|
                r << { 'KeyArn' => v['Arn'], 'KeyId' => k }
              end
            end

  keys = if limit
           key_set.slice!(0, limit)
         else
           key_set
         end

  truncated = keys.size < key_set.size

  marker = truncated && "metadata/l/#{}/#{UUID.uuid}"

  response = Excon::Response.new

  body = {
    'Keys'      => keys,
    'Truncated' => truncated,
    'RequestId' => Fog::AWS::Mock.request_id
  }

  if marker
    self.data[:markers][marker] = key_set
    body.merge!('Marker' => marker)
  end

  response.body = body
  response.status = 200

  response
end

#reset_dataObject



70
71
72
# File 'lib/fog/aws/kms.rb', line 70

def reset_data
  self.class.data[@region].delete(@aws_access_key_id)
end

#schedule_key_deletion(identifier, pending_window_in_days) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/fog/aws/requests/kms/schedule_key_deletion.rb', line 18

def schedule_key_deletion(identifier, pending_window_in_days)
  response = Excon::Response.new
  key = self.data[:keys][identifier]

  key['DeletionDate'] = Time.now + (60 * 60 * 24 * pending_window_in_days)
  key['Enabled'] = false
  key['KeyState'] = 'PendingDeletion'

  response.body = {
    'DeletionDate' => key['DeletionDate'],
    'KeyId' => key['KeyId'],
    'KeyState' => key['KeyState'],
    'PendingWindowInDays' => pending_window_in_days
  }
  response
end

#setup_credentials(options) ⇒ Object



59
60
61
62
63
64
# File 'lib/fog/aws/kms.rb', line 59

def setup_credentials(options)
  @aws_access_key_id     = options[:aws_access_key_id]
  @aws_secret_access_key = options[:aws_secret_access_key]

  @signer = Fog::AWS::SignatureV4.new(@aws_access_key_id, @aws_secret_access_key, @region, 'kms')
end

#sign(identifier, message, algorithm, options = {}) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/fog/aws/requests/kms/sign.rb', line 31

def sign(identifier, message, algorithm, options = {})
  response = Excon::Response.new
  pkey = self.data[:pkeys][identifier]
  unless pkey
    response.status = 404
    raise(Excon::Errors.status_error({ expects: 200 }, response))
  end

  data = Base64.decode64(message)

  # FIXME: SM2 support?
  sha = "SHA#{algorithm.split('_SHA_').last}"
  signopts = {}
  signopts[:rsa_padding_mode] = 'pss' if algorithm.start_with?('RSASSA_PSS')

  signature = if options['MessageType'] == 'DIGEST'
                pkey.sign_raw(sha, data, signopts)
              else
                pkey.sign(sha, data, signopts)
              end

  response.body = {
    'KeyId' => identifier,
    'Signature' => Base64.strict_encode64(signature),
    'SigningAlgorithm' => algorithm
  }
  response
end