aes_key_wrap 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9c0f645c56b2c0ae94cabd1077535d2a46674367
4
- data.tar.gz: f9db99d515349bd73276c3dab991965df415ea4d
2
+ SHA256:
3
+ metadata.gz: 975893714de4407b4e7810177589efcc6602e32a3586b94b525ba6efc5d61c8e
4
+ data.tar.gz: 8f10761ae857d59739e0b88c875348374018ec9537da21be113dea8eab97a97f
5
5
  SHA512:
6
- metadata.gz: e1bc33d21b3971adca4cfe8ebb810ff278e810507dd22462df83a99cd614a95b8bac81ee6bfbe86cb5be386aa97404e8d04ca8f735431091a228fa88ec75159a
7
- data.tar.gz: d26e72d021f09467fc09c8cd31bd068fb41001ae0d5619e91d6944746c9adff0f35bd78384bab260148f03b3b4e76d843a24d007c7b753aacc72a2c35bc23665
6
+ metadata.gz: eac3ed6586dd4aff0b76bab567359969809c6e326aa68210c058f5509d94cecb7c7d35f059f8c8932524dd302e29a2221f0943a1a445111875becf0af2c8c394
7
+ data.tar.gz: db11cf15a329f48fe0ba8d451c98a63c8bc47bf1dcbd3dd0f4de7227e039a4f4b1c673b8060a945de2d5a3b642dfa19032aa7b9fa3ca5786d83005a55d76abd8
@@ -1 +1 @@
1
- 2.2.0
1
+ 2.7
@@ -1 +1,22 @@
1
+ script: bundle exec ruby test/aes_key_wrap.rb
1
2
  language: ruby
3
+
4
+ # test on old rubies
5
+ rvm:
6
+ - 2.3.8
7
+ - 2.4.10
8
+ - 2.5.8
9
+ - 2.6.6
10
+
11
+ # run latest ruby differently (run codeclimate)
12
+ matrix:
13
+ include:
14
+ - rvm: 2.7.1
15
+ # code climate config
16
+ env: CC_TEST_REPORTER_ID=112d90dacd3bbf36bbf39282309a52581175ae544be2cf8ef3b8c0c0221515f5
17
+ before_script:
18
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
19
+ - chmod +x ./cc-test-reporter
20
+ - ./cc-test-reporter before-build
21
+ after_script:
22
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
@@ -0,0 +1,21 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [1.1.0] - 2020-07-12
8
+ ### Added
9
+ - IV arguments can be either `String`s or `Integer`s. Previously, they could
10
+ only be `Integer`s. This is a backwards-compatible addition as long as you
11
+ aren't doing something freaky with IVs, like using negative numbers (they are
12
+ supposed to be unsigned).
13
+
14
+ ## [1.0.1] - 2015-04-24
15
+ ### Fixed
16
+ - Didn't work unless you had `require 'openssl'` somewhere first. The gem now
17
+ `require`s its own dependencies, surprising no one.
18
+
19
+ ## [1.0.0] - 2015-04-24
20
+ ### Added
21
+ - Everything (Initial release)
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  [![Build Status](https://travis-ci.org/tomdalling/aes_key_wrap.svg?branch=master)](https://travis-ci.org/tomdalling/aes_key_wrap)
2
+ [![Test Coverage](https://codeclimate.com/github/tomdalling/aes_key_wrap/badges/coverage.svg)](https://codeclimate.com/github/tomdalling/aes_key_wrap)
2
3
 
3
4
  # AESKeyWrap
4
5
 
@@ -14,20 +15,22 @@ To wrap a key, call `AESKeyWrap.wrap` with:
14
15
 
15
16
  ```ruby
16
17
  require 'aes_key_wrap'
18
+
17
19
  plaintext_key = ['00112233445566778899AABBCCDDEEFF'].pack('H*') #binary string
18
20
  kek = ['000102030405060708090A0B0C0D0E0F'].pack('H*') # binary string
19
- iv = 0xDEADBEEFC0FFEEEE
20
- wrapped_key = AESKeyWrap.wrap(plaintext_key, kek, iv)
21
+ iv = ['DEADBEEFC0FFEEEE'].pack("H*") # binary string (always 8 bytes)
22
+
23
+ wrapped_key = AESKeyWrap.wrap(plaintext_key, kek, iv) # iv is optional
21
24
  ```
22
25
 
23
26
  To unwrap a key, call `AESKeyWrap.unwrap`:
24
27
 
25
28
  ```ruby
26
- unwrapped = AESKeyWrap.unwrap(wrapped_key, kek, iv)
29
+ unwrapped = AESKeyWrap.unwrap(wrapped_key, kek, iv) # iv is optional
27
30
  ```
28
31
 
29
- There also `unwrap!`, which throws an exception if unwrapping
30
- fails, instead of returning nil.
32
+ There also `unwrap!`, which throws an exception if unwrapping fails, instead of
33
+ returning nil.
31
34
 
32
35
  ## Contributing
33
36
 
@@ -16,7 +16,11 @@ Gem::Specification.new do |spec|
16
16
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
17
  spec.require_paths = ['lib']
18
18
 
19
- spec.add_development_dependency 'rake', '~> 10.0'
20
- spec.add_development_dependency 'rspec', '~> 3.2.0'
19
+ spec.add_development_dependency 'test_bench', '~> 1.0'
20
+ spec.add_development_dependency 'gem-release'
21
+
22
+ # code climate doesn't support v0.18+
23
+ # see: https://github.com/codeclimate/test-reporter/issues/413
24
+ spec.add_development_dependency 'simplecov', '< 0.18'
21
25
  end
22
26
 
@@ -5,6 +5,8 @@ require 'openssl'
5
5
  #
6
6
  module AESKeyWrap
7
7
  DEFAULT_IV = 0xA6A6A6A6A6A6A6A6
8
+ IV_SIZE = 8 # bytes
9
+
8
10
  UnwrapFailedError = Class.new(StandardError)
9
11
 
10
12
  class << self
@@ -18,7 +20,9 @@ module AESKeyWrap
18
20
  #
19
21
  # @param unwrapped_key [String] The plaintext key to be wrapped, as a binary string
20
22
  # @param kek [String] The key-encrypting key, as a binary_string
21
- # @param iv [Integer] The "initial value", as unsigned 64bit integer
23
+ # @param iv [Integer, String] The "initial value", as either an unsigned
24
+ # 64-bit integer (e.g. `0xDEADBEEFC0FFEEEE`) or an 8-byte string (e.g.
25
+ # `"\xDE\xAD\xBE\xEF\xC0\xFF\xEE\xEE"`).
22
26
  # @return [String] The wrapped key, as a binary string
23
27
  #
24
28
  def wrap(unwrapped_key, kek, iv=DEFAULT_IV)
@@ -31,7 +35,7 @@ module AESKeyWrap
31
35
  # n: block_count
32
36
  # AES: aes(:encrypt, _, _)
33
37
  # IV: iv
34
- buffer = [iv] + unwrapped_key.unpack('Q>*')
38
+ buffer = [coerce_uint64(iv)] + unwrapped_key.unpack('Q>*')
35
39
  block_count = buffer.size - 1
36
40
 
37
41
  # 2) Calculate intermediate values.
@@ -61,10 +65,12 @@ module AESKeyWrap
61
65
  #
62
66
  # @param wrapped_key [String] The wrapped key (cyphertext), as a binary string
63
67
  # @param kek [String] The key-encrypting key, as a binary string
64
- # @param expected_iv [Integer] The IV used to wrap the key, as an unsigned 64bit integer
68
+ # @param expected_iv [Integer, String] The IV used to wrap the key, as either
69
+ # an unsigned 64-bit integer (e.g. `0xDEADBEEFC0FFEEEE`) or an 8-byte
70
+ # string (e.g. `"\xDE\xAD\xBE\xEF\xC0\xFF\xEE\xEE"`).
65
71
  # @return [String] The unwrapped (plaintext) key as a binary string, or
66
- # `nil` if unwrapping failed due to `expected_iv` not matching the
67
- # decrypted IV
72
+ # `nil` if unwrapping failed due to `expected_iv` not matching the
73
+ # decrypted IV
68
74
  #
69
75
  # @see #unwrap!
70
76
  #
@@ -95,7 +101,7 @@ module AESKeyWrap
95
101
  end
96
102
 
97
103
  # 3) Output the results.
98
- if buffer[0] == expected_iv
104
+ if buffer[0] == coerce_uint64(expected_iv)
99
105
  buffer.drop(1).pack('Q>*')
100
106
  else
101
107
  nil
@@ -113,6 +119,8 @@ module AESKeyWrap
113
119
 
114
120
  private
115
121
 
122
+ MAX_UINT64 = 0xFFFFFFFFFFFFFFFF
123
+
116
124
  def aes(encrypt_or_decrypt, key, data)
117
125
  decipher = OpenSSL::Cipher::AES.new(key.bytesize * 8, :ECB)
118
126
  decipher.send(encrypt_or_decrypt)
@@ -121,6 +129,27 @@ module AESKeyWrap
121
129
 
122
130
  decipher.update(data) + decipher.final
123
131
  end
132
+
133
+ def coerce_uint64(value)
134
+ case value
135
+ when Integer
136
+ if value > MAX_UINT64
137
+ raise ArgumentError, "IV is too large to fit in a 64-bit unsigned integer"
138
+ elsif value < 0
139
+ raise ArgumentError, "IV is not an unsigned integer (it's negative)"
140
+ else
141
+ value
142
+ end
143
+ when String
144
+ if value.bytesize == IV_SIZE
145
+ value.unpack("Q>").first
146
+ else
147
+ raise ArgumentError, "IV is not #{IV_SIZE} bytes long"
148
+ end
149
+ else
150
+ raise ArgumentError, "IV is not valid: #{value.inspect}"
151
+ end
152
+ end
124
153
  end
125
154
  end
126
155
 
@@ -1,3 +1,3 @@
1
1
  module AESKeyWrap
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'
3
3
  end
metadata CHANGED
@@ -1,43 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aes_key_wrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Dalling
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-24 00:00:00.000000000 Z
11
+ date: 2020-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rake
14
+ name: test_bench
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '10.0'
19
+ version: '1.0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '10.0'
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rspec
28
+ name: gem-release
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 3.2.0
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: simplecov
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "<"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.18'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "<"
39
53
  - !ruby/object:Gem::Version
40
- version: 3.2.0
54
+ version: '0.18'
41
55
  description:
42
56
  email:
43
57
  - tom@tomdalling.com
@@ -46,13 +60,12 @@ extensions: []
46
60
  extra_rdoc_files: []
47
61
  files:
48
62
  - ".gitignore"
49
- - ".rspec"
50
63
  - ".ruby-version"
51
64
  - ".travis.yml"
65
+ - CHANGELOG.md
52
66
  - Gemfile
53
67
  - LICENSE.txt
54
68
  - README.md
55
- - Rakefile
56
69
  - aes_key_wrap.gemspec
57
70
  - bin/console
58
71
  - bin/setup
@@ -77,10 +90,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
77
90
  - !ruby/object:Gem::Version
78
91
  version: '0'
79
92
  requirements: []
80
- rubyforge_project:
81
- rubygems_version: 2.4.5
93
+ rubygems_version: 3.1.2
82
94
  signing_key:
83
95
  specification_version: 4
84
96
  summary: A Ruby implementation of AES Key Wrap, a.k.a RFC 3394, a.k.a NIST Key Wrap.
85
97
  test_files: []
86
- has_rdoc:
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --format documentation
2
- --color
data/Rakefile DELETED
@@ -1,9 +0,0 @@
1
- require "bundler/gem_tasks"
2
-
3
- begin
4
- require 'rspec/core/rake_task'
5
- RSpec::Core::RakeTask.new(:spec)
6
- rescue LoadError
7
- end
8
-
9
- task :default => :spec