New Upstream Release - ruby-aes-key-wrap

Ready changes

Summary

Merged new upstream version: 1.1.0 (was: 1.0.1).

Resulting package

Built on 2022-03-09T20:08 (took 2m19s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases ruby-aes-key-wrap

Lintian Result

Diff

diff --git a/.rspec b/.rspec
deleted file mode 100644
index 8c18f1a..0000000
--- a/.rspec
+++ /dev/null
@@ -1,2 +0,0 @@
---format documentation
---color
diff --git a/.ruby-version b/.ruby-version
index ccbccc3..1effb00 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-2.2.0
+2.7
diff --git a/.travis.yml b/.travis.yml
index f819a51..13c385f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1 +1,22 @@
+script: bundle exec ruby test/aes_key_wrap.rb
 language: ruby
+
+# test on old rubies
+rvm:
+  - 2.3.8
+  - 2.4.10
+  - 2.5.8
+  - 2.6.6
+
+# run latest ruby differently (run codeclimate)
+matrix:
+  include:
+  - rvm: 2.7.1
+    # code climate config
+    env: CC_TEST_REPORTER_ID=112d90dacd3bbf36bbf39282309a52581175ae544be2cf8ef3b8c0c0221515f5
+    before_script:
+      - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
+      - chmod +x ./cc-test-reporter
+      - ./cc-test-reporter before-build
+    after_script:
+      - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..074097e
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,21 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [1.1.0] - 2020-07-12
+### Added
+- IV arguments can be either `String`s or `Integer`s. Previously, they could
+  only be `Integer`s. This is a backwards-compatible addition as long as you
+  aren't doing something freaky with IVs, like using negative numbers (they are
+  supposed to be unsigned).
+
+## [1.0.1] - 2015-04-24
+### Fixed
+- Didn't work unless you had `require 'openssl'` somewhere first. The gem now
+  `require`s its own dependencies, surprising no one.
+
+## [1.0.0] - 2015-04-24
+### Added
+- Everything (Initial release)
diff --git a/README.md b/README.md
index 3409a92..fe6554f 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,5 @@
 [![Build Status](https://travis-ci.org/tomdalling/aes_key_wrap.svg?branch=master)](https://travis-ci.org/tomdalling/aes_key_wrap)
+[![Test Coverage](https://codeclimate.com/github/tomdalling/aes_key_wrap/badges/coverage.svg)](https://codeclimate.com/github/tomdalling/aes_key_wrap)
 
 # AESKeyWrap 
 
@@ -14,20 +15,22 @@ To wrap a key, call `AESKeyWrap.wrap` with:
 
 ```ruby
 require 'aes_key_wrap'
+
 plaintext_key = ['00112233445566778899AABBCCDDEEFF'].pack('H*') #binary string
 kek =  ['000102030405060708090A0B0C0D0E0F'].pack('H*') # binary string
-iv = 0xDEADBEEFC0FFEEEE
-wrapped_key = AESKeyWrap.wrap(plaintext_key, kek, iv)
+iv = ['DEADBEEFC0FFEEEE'].pack("H*") # binary string (always 8 bytes)
+
+wrapped_key = AESKeyWrap.wrap(plaintext_key, kek, iv)  # iv is optional
 ```
 
 To unwrap a key, call `AESKeyWrap.unwrap`:
 
 ```ruby
-unwrapped = AESKeyWrap.unwrap(wrapped_key, kek, iv)
+unwrapped = AESKeyWrap.unwrap(wrapped_key, kek, iv)  # iv is optional
 ```
 
-There also `unwrap!`, which throws an exception if unwrapping
-fails, instead of returning nil.
+There also `unwrap!`, which throws an exception if unwrapping fails, instead of
+returning nil.
 
 ## Contributing
 
diff --git a/Rakefile b/Rakefile
deleted file mode 100644
index b0d7a0f..0000000
--- a/Rakefile
+++ /dev/null
@@ -1,9 +0,0 @@
-require "bundler/gem_tasks"
-
-begin
-  require 'rspec/core/rake_task'
-  RSpec::Core::RakeTask.new(:spec)
-rescue LoadError
-end
-
-task :default => :spec
diff --git a/aes_key_wrap.gemspec b/aes_key_wrap.gemspec
index f8adeef..41511e6 100644
--- a/aes_key_wrap.gemspec
+++ b/aes_key_wrap.gemspec
@@ -16,7 +16,11 @@ Gem::Specification.new do |spec|
   spec.files         = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
   spec.require_paths = ['lib']
 
-  spec.add_development_dependency 'rake', '~> 10.0'
-  spec.add_development_dependency 'rspec', '~> 3.2.0'
+  spec.add_development_dependency 'test_bench', '~> 1.0'
+  spec.add_development_dependency 'gem-release'
+
+  # code climate doesn't support v0.18+
+  # see: https://github.com/codeclimate/test-reporter/issues/413
+  spec.add_development_dependency 'simplecov', '< 0.18'
 end
 
diff --git a/debian/changelog b/debian/changelog
index d32ed06..17b6dd8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-ruby-aes-key-wrap (1.0.1-2) UNRELEASED; urgency=medium
+ruby-aes-key-wrap (1.1.0-1) UNRELEASED; urgency=medium
 
   [ Utkarsh Gupta ]
   * Add salsa-ci.yml
@@ -11,8 +11,9 @@ ruby-aes-key-wrap (1.0.1-2) UNRELEASED; urgency=medium
   * Update standards version to 4.2.1, no changes needed.
   * Apply multi-arch hints.
     + ruby-aes-key-wrap: Add :any qualifier for ruby dependency.
+  * New upstream release.
 
- -- Utkarsh Gupta <guptautkarsh2102@gmail.com>  Tue, 13 Aug 2019 03:24:27 +0530
+ -- Utkarsh Gupta <guptautkarsh2102@gmail.com>  Wed, 09 Mar 2022 20:06:38 -0000
 
 ruby-aes-key-wrap (1.0.1-1) unstable; urgency=medium
 
diff --git a/lib/aes_key_wrap.rb b/lib/aes_key_wrap.rb
index 903c618..2c16dd9 100644
--- a/lib/aes_key_wrap.rb
+++ b/lib/aes_key_wrap.rb
@@ -5,6 +5,8 @@ require 'openssl'
 #
 module AESKeyWrap
   DEFAULT_IV = 0xA6A6A6A6A6A6A6A6
+  IV_SIZE = 8 # bytes
+
   UnwrapFailedError = Class.new(StandardError)
 
   class << self
@@ -18,7 +20,9 @@ module AESKeyWrap
     #
     # @param unwrapped_key [String] The plaintext key to be wrapped, as a binary string
     # @param kek [String] The key-encrypting key, as a binary_string
-    # @param iv [Integer] The "initial value", as unsigned 64bit integer
+    # @param iv [Integer, String] The "initial value", as either an unsigned
+    #   64-bit integer (e.g. `0xDEADBEEFC0FFEEEE`) or an 8-byte string (e.g.
+    #   `"\xDE\xAD\xBE\xEF\xC0\xFF\xEE\xEE"`).
     # @return [String] The wrapped key, as a binary string
     #
     def wrap(unwrapped_key, kek, iv=DEFAULT_IV)
@@ -31,7 +35,7 @@ module AESKeyWrap
       #    n: block_count
       #    AES: aes(:encrypt, _, _)
       #    IV: iv
-      buffer = [iv] + unwrapped_key.unpack('Q>*')
+      buffer = [coerce_uint64(iv)] + unwrapped_key.unpack('Q>*')
       block_count = buffer.size - 1
 
       # 2) Calculate intermediate values.
@@ -61,10 +65,12 @@ module AESKeyWrap
     #
     # @param wrapped_key [String] The wrapped key (cyphertext), as a binary string
     # @param kek [String] The key-encrypting key, as a binary string
-    # @param expected_iv [Integer] The IV used to wrap the key, as an unsigned 64bit integer
+    # @param expected_iv [Integer, String] The IV used to wrap the key, as either
+    #   an unsigned 64-bit integer (e.g. `0xDEADBEEFC0FFEEEE`) or an 8-byte
+    #   string (e.g. `"\xDE\xAD\xBE\xEF\xC0\xFF\xEE\xEE"`).
     # @return [String] The unwrapped (plaintext) key as a binary string, or
-    #                  `nil` if unwrapping failed due to `expected_iv` not matching the
-    #                  decrypted IV
+    #   `nil` if unwrapping failed due to `expected_iv` not matching the
+    #   decrypted IV
     #
     # @see #unwrap!
     #
@@ -95,7 +101,7 @@ module AESKeyWrap
       end
 
       # 3) Output the results.
-      if buffer[0] == expected_iv
+      if buffer[0] == coerce_uint64(expected_iv)
         buffer.drop(1).pack('Q>*')
       else
         nil
@@ -113,6 +119,8 @@ module AESKeyWrap
 
     private
 
+      MAX_UINT64 = 0xFFFFFFFFFFFFFFFF
+
       def aes(encrypt_or_decrypt, key, data)
         decipher = OpenSSL::Cipher::AES.new(key.bytesize * 8, :ECB)
         decipher.send(encrypt_or_decrypt)
@@ -121,6 +129,27 @@ module AESKeyWrap
 
         decipher.update(data) + decipher.final
       end
+
+      def coerce_uint64(value)
+        case value
+        when Integer
+          if value > MAX_UINT64
+            raise ArgumentError, "IV is too large to fit in a 64-bit unsigned integer"
+          elsif value < 0
+            raise ArgumentError, "IV is not an unsigned integer (it's negative)"
+          else
+            value
+          end
+        when String
+          if value.bytesize == IV_SIZE
+            value.unpack("Q>").first
+          else
+            raise ArgumentError, "IV is not #{IV_SIZE} bytes long"
+          end
+        else
+          raise ArgumentError, "IV is not valid: #{value.inspect}"
+        end
+      end
   end
 end
 
diff --git a/lib/aes_key_wrap/version.rb b/lib/aes_key_wrap/version.rb
index e62e66a..11150de 100644
--- a/lib/aes_key_wrap/version.rb
+++ b/lib/aes_key_wrap/version.rb
@@ -1,3 +1,3 @@
 module AESKeyWrap
-  VERSION = '1.0.1'
+  VERSION = '1.1.0'
 end

More details

Full run details