Skip to content

Commit 192f8a6

Browse files
committed
first pass at kms sign request and mocks
1 parent a1390b5 commit 192f8a6

File tree

6 files changed

+101
-14
lines changed

6 files changed

+101
-14
lines changed

lib/fog/aws/kms.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class KMS < Fog::Service
2222
request :describe_key
2323
request :get_public_key
2424
request :schedule_key_deletion
25+
request :sign
2526

2627
model_path 'fog/aws/models/kms'
2728
model :key

lib/fog/aws/parsers/kms/sign.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module Fog
2+
module Parsers
3+
module AWS
4+
module KMS
5+
class Sign < Fog::Parsers::Base
6+
def reset
7+
@response = {}
8+
end
9+
10+
def start_element(name, attrs = [])
11+
super
12+
end
13+
14+
def end_element(name)
15+
case name
16+
when 'KeyId', 'Signature', 'SigningAlgorithm'
17+
@response[name] = value
18+
end
19+
end
20+
end
21+
end
22+
end
23+
end
24+
end

lib/fog/aws/requests/kms/create_key.rb

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,18 @@ def create_key(*args)
5252

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

55-
size = key['KeySpec'].split('_').last
56-
type = key['KeySpec'].split('_').first
57-
case type
58-
when 'ECC'
59-
curve = {
60-
'ECC_NIST_P256' => 'secp256k1',
61-
'ECC_NIST_P384' => 'secp384r1',
62-
'ECC_NIST_P521' => 'secp521r1',
63-
'ECC_SECG_P256K1' => 'prime256v1'
64-
}[key['KeySpec']]
65-
self.data[:pkeys][key_id] = OpenSSL::PKey::EC.generate(curve)
66-
when 'RSA'
67-
self.data[:pkeys][key_id] = OpenSSL::PKey::RSA.generate(size.to_i)
68-
end
55+
klass, arg = {
56+
'ECC_NIST_P256' => [OpenSSL::PKey::EC, 'secp256k1'],
57+
'ECC_NIST_P384' => [OpenSSL::PKey::EC, 'secp384r1'],
58+
'ECC_NIST_P521' => [OpenSSL::PKey::EC, 'secp521r1'],
59+
'ECC_SECG_P256K1' => [OpenSSL::PKey::EC, 'prime256v1'],
60+
'RSA_2048' => [OpenSSL::PKey::RSA, 2048],
61+
'RSA_3072' => [OpenSSL::PKey::RSA, 3072],
62+
'RSA_4096' => [OpenSSL::PKey::RSA, 4096]
63+
}[key['KeySpec']]
64+
raise "Unknown or not-yet-implemented #{key['KeySpec']} KeySpec for kms create_key mocks" unless klass
65+
66+
self.data[:pkeys][key_id] = klass.generate(arg)
6967

7068
response.body = { 'KeyMetadata' => key }
7169
response

lib/fog/aws/requests/kms/sign.rb

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
module Fog
2+
module AWS
3+
class KMS
4+
class Real
5+
require 'fog/aws/parsers/kms/sign'
6+
7+
# Sign
8+
#
9+
# ==== Parameters
10+
#
11+
# === Returns
12+
#
13+
# ==== See Also
14+
# https://docs.aws.amazon.com/kms/latest/APIReference/API_Sign.html
15+
def sign(identifier, message, algorithm, options = {})
16+
request({
17+
'Action' => 'Sign',
18+
'KeyId' => identifier,
19+
'Message' => message,
20+
'SigningAlgorithm' => algorithm,
21+
:parser => Fog::Parsers::AWS::KMS::Sign.new
22+
}.merge!(options))
23+
end
24+
end
25+
26+
class Mock
27+
def sign(identifier, message, algorithm, _options = {})
28+
response = Excon::Response.new
29+
pkey = self.data[:pkeys][identifier]
30+
unless pkey
31+
response.status = 404
32+
raise(Excon::Errors.status_error({ expects: 200 }, response))
33+
end
34+
35+
# FIXME: SM2 support?
36+
sha = "SHA#{algorithm.split('_SHA_').last}"
37+
hash = OpenSSL::Digest.digest(sha, message)
38+
39+
signopts = {}
40+
signopts[:rsa_padding_mode] = 'pss' if algorithm.start_with?('RSASSA_PSS')
41+
42+
signature = pkey.sign_raw(sha, hash, signopts)
43+
44+
response.body = {
45+
'KeyId' => identifier,
46+
'Signature' => Base64.strict_encode64(signature),
47+
'SigningAlgorithm' => algorithm
48+
}
49+
response
50+
end
51+
end
52+
end
53+
end
54+
end

tests/requests/kms/helper.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ module Formats
4242
'KeyState' => String,
4343
'PendingWindowInDays' => Integer
4444
}.freeze
45+
46+
SIGN = {
47+
'KeyId' => String,
48+
'Signature' => String,
49+
'SigningAlgorithm' => String
50+
}.freeze
4551
end
4652
end
4753
end

tests/requests/kms/key_tests.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
Fog::AWS[:kms].list_keys.body
3030
end
3131

32+
tests('#sign').data_matches_schema(AWS::KMS::Formats::SIGN) do
33+
Fog::AWS[:kms].sign(key_id, 'sign me', 'RSASSA_PSS_SHA_256').body
34+
end
35+
3236
tests('#schedule_key_deletion').data_matches_schema(AWS::KMS::Formats::SCHEDULE_KEY_DELETION) do
3337
Fog::AWS[:kms].schedule_key_deletion(key_id, 7).body
3438
end

0 commit comments

Comments
 (0)