cose 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/.travis.yml +12 -3
- data/Appraisals +3 -0
- data/CHANGELOG.md +14 -0
- data/README.md +46 -29
- data/cose.gemspec +1 -1
- data/gemfiles/openssl_default.gemfile +5 -0
- data/lib/cose/key.rb +5 -0
- data/lib/cose/key/base.rb +38 -4
- data/lib/cose/key/curve_key.rb +48 -0
- data/lib/cose/key/ec2.rb +33 -47
- data/lib/cose/key/okp.rb +22 -0
- data/lib/cose/key/rsa.rb +86 -61
- data/lib/cose/key/symmetric.rb +20 -9
- data/lib/cose/version.rb +1 -1
- metadata +9 -6
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 32030549359b2c5afe6862546965c13f4071b55c9ace03a6385ce5c62c3af7bc
         | 
| 4 | 
            +
              data.tar.gz: 46e4769b04dadb56b998ae807a2cfe80e73c95c131c93b8b6424d5752f1aae0a
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 907c461c040d4e80b19403922557a7098e30cb348a829f9252ed74ab4c9f8d3ca62ba24f75ddc6e4df6c19de95f900be53483dbc4c97ded66927433513a38ce0
         | 
| 7 | 
            +
              data.tar.gz: 8142ebaaf7c32486f60f29243e689ae5bf96a4a39eed87838c55eeed8a13cc102e7dbd14d489749da9cff5ac149aa4a97c172f113e69f70e0658d285f3571063
         | 
    
        data/.rubocop.yml
    CHANGED
    
    
    
        data/.travis.yml
    CHANGED
    
    | @@ -4,16 +4,25 @@ language: ruby | |
| 4 4 | 
             
            rvm:
         | 
| 5 5 | 
             
              - ruby-head
         | 
| 6 6 | 
             
              - 2.6.2
         | 
| 7 | 
            -
              - 2.5. | 
| 8 | 
            -
              - 2.4. | 
| 7 | 
            +
              - 2.5.5
         | 
| 8 | 
            +
              - 2.4.6
         | 
| 9 | 
            +
              - 2.3.8
         | 
| 10 | 
            +
              - 2.2.10
         | 
| 9 11 |  | 
| 10 12 | 
             
            gemfile:
         | 
| 11 13 | 
             
              - gemfiles/openssl_2_0.gemfile
         | 
| 12 14 | 
             
              - gemfiles/openssl_2_1.gemfile
         | 
| 15 | 
            +
              - gemfiles/openssl_default.gemfile
         | 
| 13 16 |  | 
| 14 | 
            -
            before_install: gem install bundler -v  | 
| 17 | 
            +
            before_install: gem install bundler -v '~> 1.17'
         | 
| 15 18 |  | 
| 16 19 | 
             
            matrix:
         | 
| 17 20 | 
             
              fast_finish: true
         | 
| 18 21 | 
             
              allow_failures:
         | 
| 19 22 | 
             
                - rvm: ruby-head
         | 
| 23 | 
            +
                - rvm: 2.2.10
         | 
| 24 | 
            +
              exclude:
         | 
| 25 | 
            +
                - rvm: 2.2.10
         | 
| 26 | 
            +
                  gemfile: gemfiles/openssl_2_0.gemfile
         | 
| 27 | 
            +
                - rvm: 2.2.10
         | 
| 28 | 
            +
                  gemfile: gemfiles/openssl_2_1.gemfile
         | 
    
        data/Appraisals
    CHANGED
    
    
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,18 @@ | |
| 1 1 | 
             
            # Changelog
         | 
| 2 2 |  | 
| 3 | 
            +
            ## [v0.6.0] - 2019-04-03
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            ### Added
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            - Support Key Common Parameters (`#base_iv`, `key_ops`, `#alg` and `#kid`)
         | 
| 8 | 
            +
            - Support OKP Key
         | 
| 9 | 
            +
            - Support RSA private key serialization
         | 
| 10 | 
            +
            - Works with ruby 2.3
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            ### Changed
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            - Key type-specific parameters names better match RFC
         | 
| 15 | 
            +
             | 
| 3 16 | 
             
            ## [v0.5.0] - 2019-03-25
         | 
| 4 17 |  | 
| 5 18 | 
             
            ### Added
         | 
| @@ -54,6 +67,7 @@ | |
| 54 67 | 
             
            - EC2 key object
         | 
| 55 68 | 
             
            - Works with ruby 2.5
         | 
| 56 69 |  | 
| 70 | 
            +
            [v0.6.0]: https://github.com/cedarcode/cose-ruby/compare/v0.5.0...v0.6.0/
         | 
| 57 71 | 
             
            [v0.5.0]: https://github.com/cedarcode/cose-ruby/compare/v0.4.1...v0.5.0/
         | 
| 58 72 | 
             
            [v0.4.1]: https://github.com/cedarcode/cose-ruby/compare/v0.4.0...v0.4.1/
         | 
| 59 73 | 
             
            [v0.4.0]: https://github.com/cedarcode/cose-ruby/compare/v0.3.0...v0.4.0/
         | 
    
        data/README.md
    CHANGED
    
    | @@ -30,48 +30,65 @@ Or install it yourself as: | |
| 30 30 | 
             
            ```ruby
         | 
| 31 31 | 
             
            cbor_data = "..."
         | 
| 32 32 |  | 
| 33 | 
            -
             | 
| 33 | 
            +
            key = COSE::Key.deserialize(cbor_data)
         | 
| 34 34 | 
             
            ```
         | 
| 35 35 |  | 
| 36 36 | 
             
            Once you have a `COSE::Key` instance you can either access key parameters directly and/or convert it to an
         | 
| 37 | 
            -
            `OpenSSL::PKey::PKey` instance for operating with it | 
| 37 | 
            +
            `OpenSSL::PKey::PKey` instance (if supported for the key type) for operating with it
         | 
| 38 | 
            +
            (encrypting/decrypting, signing/verifying, etc).
         | 
| 38 39 |  | 
| 39 40 | 
             
            ```ruby
         | 
| 40 41 | 
             
            # Convert to an OpenSSL::PKey::PKey
         | 
| 41 | 
            -
             | 
| 42 | 
            +
            if key.respond_to?(:to_pkey)
         | 
| 43 | 
            +
              openssl_pkey = key.to_pkey
         | 
| 44 | 
            +
            end
         | 
| 42 45 |  | 
| 43 46 | 
             
            # Access COSE key parameters
         | 
| 44 47 | 
             
            case key
         | 
| 48 | 
            +
            when COSE::Key::OKP
         | 
| 49 | 
            +
              key.crv
         | 
| 50 | 
            +
              key.x
         | 
| 51 | 
            +
              key.d
         | 
| 45 52 | 
             
            when COSE::Key::EC2
         | 
| 46 | 
            -
              key. | 
| 47 | 
            -
              key. | 
| 48 | 
            -
              key. | 
| 49 | 
            -
              key. | 
| 53 | 
            +
              key.crv
         | 
| 54 | 
            +
              key.x
         | 
| 55 | 
            +
              key.y
         | 
| 56 | 
            +
              key.d
         | 
| 50 57 | 
             
            when COSE::Key::RSA
         | 
| 51 | 
            -
              key. | 
| 52 | 
            -
              key. | 
| 53 | 
            -
              key. | 
| 54 | 
            -
              key. | 
| 55 | 
            -
              key. | 
| 56 | 
            -
              key. | 
| 57 | 
            -
              key. | 
| 58 | 
            -
              key. | 
| 58 | 
            +
              key.n
         | 
| 59 | 
            +
              key.e
         | 
| 60 | 
            +
              key.d
         | 
| 61 | 
            +
              key.p
         | 
| 62 | 
            +
              key.q
         | 
| 63 | 
            +
              key.dp
         | 
| 64 | 
            +
              key.dq
         | 
| 65 | 
            +
              key.qinv
         | 
| 59 66 | 
             
            when COSE::Key::Symmetric
         | 
| 60 | 
            -
              key. | 
| 67 | 
            +
              key.k
         | 
| 61 68 | 
             
            end
         | 
| 62 69 | 
             
            ```
         | 
| 63 70 |  | 
| 64 71 | 
             
            If you already know which COSE key type is encoded in the CBOR data, then:
         | 
| 65 72 |  | 
| 73 | 
            +
            ```ruby
         | 
| 74 | 
            +
            okp_key_cbor = "..."
         | 
| 75 | 
            +
             | 
| 76 | 
            +
            cose_okp_key = COSE::Key::OKP.deserialize(okp_key_cbor)
         | 
| 77 | 
            +
             | 
| 78 | 
            +
            cose_okp_key.crv
         | 
| 79 | 
            +
            cose_okp_key.x
         | 
| 80 | 
            +
            cose_okp_key.d
         | 
| 81 | 
            +
            ```
         | 
| 82 | 
            +
             | 
| 66 83 | 
             
            ```ruby
         | 
| 67 84 | 
             
            ec2_key_cbor = "..."
         | 
| 68 85 |  | 
| 69 86 | 
             
            cose_ec2_key = COSE::Key::EC2.deserialize(ec2_key_cbor)
         | 
| 70 87 |  | 
| 71 | 
            -
            cose_ec2_key. | 
| 72 | 
            -
            cose_ec2_key. | 
| 73 | 
            -
            cose_ec2_key. | 
| 74 | 
            -
            cose_ec2_key. | 
| 88 | 
            +
            cose_ec2_key.crv
         | 
| 89 | 
            +
            cose_ec2_key.x
         | 
| 90 | 
            +
            cose_ec2_key.y
         | 
| 91 | 
            +
            cose_ec2_key.d
         | 
| 75 92 |  | 
| 76 93 | 
             
            # or
         | 
| 77 94 |  | 
| @@ -83,7 +100,7 @@ symmetric_key_cbor = "..." | |
| 83 100 |  | 
| 84 101 | 
             
            cose_symmetric_key = COSE::Key::Symmetric.deserialize(symmetric_key_cbor)
         | 
| 85 102 |  | 
| 86 | 
            -
            cose_symmetric_key. | 
| 103 | 
            +
            cose_symmetric_key.k
         | 
| 87 104 | 
             
            ```
         | 
| 88 105 |  | 
| 89 106 | 
             
            ```ruby
         | 
| @@ -91,14 +108,14 @@ rsa_key_cbor = "..." | |
| 91 108 |  | 
| 92 109 | 
             
            cose_rsa_key = COSE::Key::RSA.deserialize(rsa_key_cbor)
         | 
| 93 110 |  | 
| 94 | 
            -
            cose_rsa_key. | 
| 95 | 
            -
            cose_rsa_key. | 
| 96 | 
            -
            cose_rsa_key. | 
| 97 | 
            -
            cose_rsa_key. | 
| 98 | 
            -
            cose_rsa_key. | 
| 99 | 
            -
            cose_rsa_key. | 
| 100 | 
            -
            cose_rsa_key. | 
| 101 | 
            -
            cose_rsa_key. | 
| 111 | 
            +
            cose_rsa_key.n
         | 
| 112 | 
            +
            cose_rsa_key.e
         | 
| 113 | 
            +
            cose_rsa_key.d
         | 
| 114 | 
            +
            cose_rsa_key.p
         | 
| 115 | 
            +
            cose_rsa_key.q
         | 
| 116 | 
            +
            cose_rsa_key.dp
         | 
| 117 | 
            +
            cose_rsa_key.dq
         | 
| 118 | 
            +
            cose_rsa_key.qinv
         | 
| 102 119 |  | 
| 103 120 | 
             
            # or
         | 
| 104 121 |  | 
    
        data/cose.gemspec
    CHANGED
    
    | @@ -35,7 +35,7 @@ Gem::Specification.new do |spec| | |
| 35 35 |  | 
| 36 36 | 
             
              spec.add_development_dependency "appraisal", "~> 2.2.0"
         | 
| 37 37 | 
             
              spec.add_development_dependency "bundler", ">= 1.17", "< 3"
         | 
| 38 | 
            -
              spec.add_development_dependency "byebug", " | 
| 38 | 
            +
              spec.add_development_dependency "byebug", ">= 10.0"
         | 
| 39 39 | 
             
              spec.add_development_dependency "rake", "~> 12.3"
         | 
| 40 40 | 
             
              spec.add_development_dependency "rspec", "~> 3.8"
         | 
| 41 41 | 
             
              spec.add_development_dependency "rubocop", "0.65.0"
         | 
    
        data/lib/cose/key.rb
    CHANGED
    
    | @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            require "cbor"
         | 
| 2 2 | 
             
            require "cose/key/ec2"
         | 
| 3 | 
            +
            require "cose/key/okp"
         | 
| 3 4 | 
             
            require "cose/key/rsa"
         | 
| 4 5 | 
             
            require "cose/key/symmetric"
         | 
| 5 6 | 
             
            require "openssl"
         | 
| @@ -23,12 +24,16 @@ module COSE | |
| 23 24 | 
             
                  map = CBOR.decode(data)
         | 
| 24 25 |  | 
| 25 26 | 
             
                  case map[Base::LABEL_KTY]
         | 
| 27 | 
            +
                  when COSE::Key::OKP::KTY_OKP
         | 
| 28 | 
            +
                    COSE::Key::OKP.from_map(map)
         | 
| 26 29 | 
             
                  when COSE::Key::EC2::KTY_EC2
         | 
| 27 30 | 
             
                    COSE::Key::EC2.from_map(map)
         | 
| 28 31 | 
             
                  when COSE::Key::RSA::KTY_RSA
         | 
| 29 32 | 
             
                    COSE::Key::RSA.from_map(map)
         | 
| 30 33 | 
             
                  when COSE::Key::Symmetric::KTY_SYMMETRIC
         | 
| 31 34 | 
             
                    COSE::Key::Symmetric.from_map(map)
         | 
| 35 | 
            +
                  when nil
         | 
| 36 | 
            +
                    raise UnknownKeyType, "Missing required key type kty label"
         | 
| 32 37 | 
             
                  else
         | 
| 33 38 | 
             
                    raise UnknownKeyType, "Unsupported or unknown key type #{map[Base::LABEL_KTY]}"
         | 
| 34 39 | 
             
                  end
         | 
    
        data/lib/cose/key/base.rb
    CHANGED
    
    | @@ -5,16 +5,50 @@ require "cbor" | |
| 5 5 | 
             
            module COSE
         | 
| 6 6 | 
             
              module Key
         | 
| 7 7 | 
             
                class Base
         | 
| 8 | 
            +
                  LABEL_BASE_IV = 5
         | 
| 9 | 
            +
                  LABEL_KEY_OPS = 4
         | 
| 10 | 
            +
                  LABEL_ALG = 3
         | 
| 11 | 
            +
                  LABEL_KID = 2
         | 
| 8 12 | 
             
                  LABEL_KTY = 1
         | 
| 9 13 |  | 
| 10 14 | 
             
                  def self.deserialize(cbor)
         | 
| 11 15 | 
             
                    from_map(CBOR.decode(cbor))
         | 
| 12 16 | 
             
                  end
         | 
| 13 17 |  | 
| 14 | 
            -
                  def self. | 
| 15 | 
            -
                     | 
| 16 | 
            -
             | 
| 17 | 
            -
                     | 
| 18 | 
            +
                  def self.from_map(map)
         | 
| 19 | 
            +
                    enforce_type(map)
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                    new(
         | 
| 22 | 
            +
                      base_iv: map[LABEL_BASE_IV],
         | 
| 23 | 
            +
                      key_ops: map[LABEL_KEY_OPS],
         | 
| 24 | 
            +
                      alg: map[LABEL_ALG],
         | 
| 25 | 
            +
                      kid: map[LABEL_KID],
         | 
| 26 | 
            +
                      **keyword_arguments_for_initialize(map)
         | 
| 27 | 
            +
                    )
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  attr_reader :kid, :alg, :key_ops, :base_iv
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def initialize(kid: nil, alg: nil, key_ops: nil, base_iv: nil)
         | 
| 33 | 
            +
                    @kid = kid
         | 
| 34 | 
            +
                    @alg = alg
         | 
| 35 | 
            +
                    @key_ops = key_ops
         | 
| 36 | 
            +
                    @base_iv = base_iv
         | 
| 37 | 
            +
                  end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  def serialize
         | 
| 40 | 
            +
                    CBOR.encode(map)
         | 
| 41 | 
            +
                  end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                  def map
         | 
| 44 | 
            +
                    map = {
         | 
| 45 | 
            +
                      LABEL_BASE_IV => base_iv,
         | 
| 46 | 
            +
                      LABEL_KEY_OPS => key_ops,
         | 
| 47 | 
            +
                      LABEL_ALG => alg,
         | 
| 48 | 
            +
                      LABEL_KID => kid,
         | 
| 49 | 
            +
                    }
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    map.reject { |_k, v| v.nil? }
         | 
| 18 52 | 
             
                  end
         | 
| 19 53 | 
             
                end
         | 
| 20 54 | 
             
              end
         | 
| @@ -0,0 +1,48 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "cose/key/base"
         | 
| 4 | 
            +
            require "openssl"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module COSE
         | 
| 7 | 
            +
              module Key
         | 
| 8 | 
            +
                class CurveKey < Base
         | 
| 9 | 
            +
                  LABEL_CRV = -1
         | 
| 10 | 
            +
                  LABEL_X = -2
         | 
| 11 | 
            +
                  LABEL_D = -4
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  attr_reader :crv, :d, :x
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  def self.keyword_arguments_for_initialize(map)
         | 
| 16 | 
            +
                    {
         | 
| 17 | 
            +
                      crv: map[LABEL_CRV],
         | 
| 18 | 
            +
                      x: map[LABEL_X],
         | 
| 19 | 
            +
                      d: map[LABEL_D]
         | 
| 20 | 
            +
                    }
         | 
| 21 | 
            +
                  end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  def initialize(crv:, x: nil, d: nil, **keyword_arguments) # rubocop:disable Naming/UncommunicativeMethodParamName
         | 
| 24 | 
            +
                    super(**keyword_arguments)
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                    if !crv
         | 
| 27 | 
            +
                      raise ArgumentError, "Required crv is missing"
         | 
| 28 | 
            +
                    elsif !x && !d
         | 
| 29 | 
            +
                      raise ArgumentError, "x and d cannot be missing simultaneously"
         | 
| 30 | 
            +
                    else
         | 
| 31 | 
            +
                      @crv = crv
         | 
| 32 | 
            +
                      @x = x
         | 
| 33 | 
            +
                      @d = d
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  def map
         | 
| 38 | 
            +
                    map = super.merge(
         | 
| 39 | 
            +
                      LABEL_CRV => crv,
         | 
| 40 | 
            +
                      LABEL_X => x,
         | 
| 41 | 
            +
                      LABEL_D => d
         | 
| 42 | 
            +
                    )
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                    map.reject { |_k, v| v.nil? }
         | 
| 45 | 
            +
                  end
         | 
| 46 | 
            +
                end
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
            end
         | 
    
        data/lib/cose/key/ec2.rb
    CHANGED
    
    | @@ -1,17 +1,12 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require "cose/key/ | 
| 3 | 
            +
            require "cose/key/curve_key"
         | 
| 4 4 | 
             
            require "openssl"
         | 
| 5 5 |  | 
| 6 6 | 
             
            module COSE
         | 
| 7 7 | 
             
              module Key
         | 
| 8 | 
            -
                class EC2 <  | 
| 9 | 
            -
                   | 
| 10 | 
            -
             | 
| 11 | 
            -
                  CRV_LABEL = -1
         | 
| 12 | 
            -
                  D_LABEL = -4
         | 
| 13 | 
            -
                  X_LABEL = -2
         | 
| 14 | 
            -
                  Y_LABEL = -3
         | 
| 8 | 
            +
                class EC2 < CurveKey
         | 
| 9 | 
            +
                  LABEL_Y = -3
         | 
| 15 10 |  | 
| 16 11 | 
             
                  KTY_EC2 = 2
         | 
| 17 12 | 
             
                  CRV_P256 = 1
         | 
| @@ -24,6 +19,12 @@ module COSE | |
| 24 19 | 
             
                    CRV_P521 => "secp521r1"
         | 
| 25 20 | 
             
                  }.freeze
         | 
| 26 21 |  | 
| 22 | 
            +
                  def self.enforce_type(map)
         | 
| 23 | 
            +
                    if map[LABEL_KTY] != KTY_EC2
         | 
| 24 | 
            +
                      raise "Not an EC2 key"
         | 
| 25 | 
            +
                    end
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
             | 
| 27 28 | 
             
                  def self.from_pkey(pkey)
         | 
| 28 29 | 
             
                    curve = PKEY_CURVES.key(pkey.group.curve_name) || raise("Unsupported EC curve #{pkey.group.curve_name}")
         | 
| 29 30 |  | 
| @@ -42,73 +43,58 @@ module COSE | |
| 42 43 |  | 
| 43 44 | 
             
                      coordinate_length = bytes.size / 2
         | 
| 44 45 |  | 
| 45 | 
            -
                       | 
| 46 | 
            -
                       | 
| 46 | 
            +
                      x = bytes[0..(coordinate_length - 1)]
         | 
| 47 | 
            +
                      y = bytes[coordinate_length..-1]
         | 
| 47 48 | 
             
                    end
         | 
| 48 49 |  | 
| 49 50 | 
             
                    if private_key
         | 
| 50 | 
            -
                       | 
| 51 | 
            +
                      d = private_key.to_s(2)
         | 
| 51 52 | 
             
                    end
         | 
| 52 53 |  | 
| 53 | 
            -
                    new( | 
| 54 | 
            +
                    new(crv: curve, x: x, y: y, d: d)
         | 
| 54 55 | 
             
                  end
         | 
| 55 56 |  | 
| 56 | 
            -
                  attr_reader : | 
| 57 | 
            +
                  attr_reader :y
         | 
| 57 58 |  | 
| 58 | 
            -
                  def initialize( | 
| 59 | 
            -
                    if ! | 
| 60 | 
            -
                      raise ArgumentError, " | 
| 61 | 
            -
                    elsif !x_coordinate
         | 
| 62 | 
            -
                      raise ArgumentError, "Required x-coordinate is missing"
         | 
| 63 | 
            -
                    elsif !y_coordinate
         | 
| 64 | 
            -
                      raise ArgumentError, "Required y-coordinate is missing"
         | 
| 59 | 
            +
                  def initialize(y: nil, **keyword_arguments) # rubocop:disable Naming/UncommunicativeMethodParamName
         | 
| 60 | 
            +
                    if (!y || !keyword_arguments[:x]) && !keyword_arguments[:d]
         | 
| 61 | 
            +
                      raise ArgumentError, "Both x and y are required if d is missing"
         | 
| 65 62 | 
             
                    else
         | 
| 66 | 
            -
                       | 
| 67 | 
            -
             | 
| 68 | 
            -
                      @ | 
| 69 | 
            -
                      @x_coordinate = x_coordinate
         | 
| 70 | 
            -
                      @y_coordinate = y_coordinate
         | 
| 63 | 
            +
                      super(**keyword_arguments)
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                      @y = y
         | 
| 71 66 | 
             
                    end
         | 
| 72 67 | 
             
                  end
         | 
| 73 68 |  | 
| 74 | 
            -
                  def  | 
| 75 | 
            -
                     | 
| 69 | 
            +
                  def map
         | 
| 70 | 
            +
                    map = super.merge(
         | 
| 76 71 | 
             
                      Base::LABEL_KTY => KTY_EC2,
         | 
| 77 | 
            -
                       | 
| 78 | 
            -
                      X_LABEL => x_coordinate,
         | 
| 79 | 
            -
                      Y_LABEL => y_coordinate,
         | 
| 80 | 
            -
                      D_LABEL => d_coordinate
         | 
| 72 | 
            +
                      LABEL_Y => y,
         | 
| 81 73 | 
             
                    )
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                    map.reject { |_k, v| v.nil? }
         | 
| 82 76 | 
             
                  end
         | 
| 83 77 |  | 
| 84 78 | 
             
                  def to_pkey
         | 
| 85 | 
            -
                    if PKEY_CURVES[ | 
| 86 | 
            -
                      group = OpenSSL::PKey::EC::Group.new(PKEY_CURVES[ | 
| 79 | 
            +
                    if PKEY_CURVES[crv]
         | 
| 80 | 
            +
                      group = OpenSSL::PKey::EC::Group.new(PKEY_CURVES[crv])
         | 
| 87 81 | 
             
                      pkey = OpenSSL::PKey::EC.new(group)
         | 
| 88 | 
            -
                      public_key_bn = OpenSSL::BN.new("\x04" +  | 
| 82 | 
            +
                      public_key_bn = OpenSSL::BN.new("\x04" + x + y, 2)
         | 
| 89 83 | 
             
                      public_key_point = OpenSSL::PKey::EC::Point.new(group, public_key_bn)
         | 
| 90 84 | 
             
                      pkey.public_key = public_key_point
         | 
| 91 85 |  | 
| 92 | 
            -
                      if  | 
| 93 | 
            -
                        pkey.private_key = OpenSSL::BN.new( | 
| 86 | 
            +
                      if d
         | 
| 87 | 
            +
                        pkey.private_key = OpenSSL::BN.new(d, 2)
         | 
| 94 88 | 
             
                      end
         | 
| 95 89 |  | 
| 96 90 | 
             
                      pkey
         | 
| 97 91 | 
             
                    else
         | 
| 98 | 
            -
                      raise "Unsupported curve #{ | 
| 92 | 
            +
                      raise "Unsupported curve #{crv}"
         | 
| 99 93 | 
             
                    end
         | 
| 100 94 | 
             
                  end
         | 
| 101 95 |  | 
| 102 | 
            -
                  def self. | 
| 103 | 
            -
                     | 
| 104 | 
            -
             | 
| 105 | 
            -
                    new(
         | 
| 106 | 
            -
                      algorithm: map[ALG_LABEL],
         | 
| 107 | 
            -
                      curve: map[CRV_LABEL],
         | 
| 108 | 
            -
                      d_coordinate: map[D_LABEL],
         | 
| 109 | 
            -
                      x_coordinate: map[X_LABEL],
         | 
| 110 | 
            -
                      y_coordinate: map[Y_LABEL]
         | 
| 111 | 
            -
                    )
         | 
| 96 | 
            +
                  def self.keyword_arguments_for_initialize(map)
         | 
| 97 | 
            +
                    super.merge(y: map[LABEL_Y])
         | 
| 112 98 | 
             
                  end
         | 
| 113 99 | 
             
                end
         | 
| 114 100 | 
             
              end
         | 
    
        data/lib/cose/key/okp.rb
    ADDED
    
    | @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "cose/key/curve_key"
         | 
| 4 | 
            +
            require "openssl"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module COSE
         | 
| 7 | 
            +
              module Key
         | 
| 8 | 
            +
                class OKP < CurveKey
         | 
| 9 | 
            +
                  KTY_OKP = 1
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                  def self.enforce_type(map)
         | 
| 12 | 
            +
                    if map[LABEL_KTY] != KTY_OKP
         | 
| 13 | 
            +
                      raise "Not an OKP key"
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def map
         | 
| 18 | 
            +
                    super.merge(LABEL_KTY => KTY_OKP)
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
    
        data/lib/cose/key/rsa.rb
    CHANGED
    
    | @@ -11,99 +11,124 @@ module COSE | |
| 11 11 | 
             
                  LABEL_D = -3
         | 
| 12 12 | 
             
                  LABEL_P = -4
         | 
| 13 13 | 
             
                  LABEL_Q = -5
         | 
| 14 | 
            -
                   | 
| 15 | 
            -
                   | 
| 16 | 
            -
                   | 
| 14 | 
            +
                  LABEL_DP = -6
         | 
| 15 | 
            +
                  LABEL_DQ = -7
         | 
| 16 | 
            +
                  LABEL_QINV = -8
         | 
| 17 17 |  | 
| 18 18 | 
             
                  KTY_RSA = 3
         | 
| 19 19 |  | 
| 20 | 
            +
                  def self.enforce_type(map)
         | 
| 21 | 
            +
                    if map[LABEL_KTY] != KTY_RSA
         | 
| 22 | 
            +
                      raise "Not an RSA key"
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
                  end
         | 
| 25 | 
            +
             | 
| 20 26 | 
             
                  def self.from_pkey(pkey)
         | 
| 21 27 | 
             
                    params = pkey.params
         | 
| 22 28 |  | 
| 23 29 | 
             
                    attributes = {
         | 
| 24 | 
            -
                       | 
| 25 | 
            -
                       | 
| 30 | 
            +
                      n: params["n"].to_s(2),
         | 
| 31 | 
            +
                      e: params["e"].to_s(2)
         | 
| 26 32 | 
             
                    }
         | 
| 27 33 |  | 
| 28 34 | 
             
                    if pkey.private?
         | 
| 29 35 | 
             
                      attributes.merge!(
         | 
| 30 | 
            -
                         | 
| 31 | 
            -
                         | 
| 32 | 
            -
                         | 
| 33 | 
            -
                         | 
| 34 | 
            -
                         | 
| 35 | 
            -
                         | 
| 36 | 
            +
                        d: params["d"].to_s(2),
         | 
| 37 | 
            +
                        p: params["p"].to_s(2),
         | 
| 38 | 
            +
                        q: params["q"].to_s(2),
         | 
| 39 | 
            +
                        dp: params["dmp1"].to_s(2),
         | 
| 40 | 
            +
                        dq: params["dmq1"].to_s(2),
         | 
| 41 | 
            +
                        qinv: params["iqmp"].to_s(2)
         | 
| 36 42 | 
             
                      )
         | 
| 37 43 | 
             
                    end
         | 
| 38 44 |  | 
| 39 45 | 
             
                    new(attributes)
         | 
| 40 46 | 
             
                  end
         | 
| 41 47 |  | 
| 42 | 
            -
                  attr_reader | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
                     | 
| 46 | 
            -
             | 
| 47 | 
            -
                     | 
| 48 | 
            -
             | 
| 49 | 
            -
                     | 
| 50 | 
            -
             | 
| 51 | 
            -
                  )
         | 
| 52 | 
            -
             | 
| 53 | 
            -
                  def initialize(
         | 
| 54 | 
            -
                    modulus_n:,
         | 
| 55 | 
            -
                    public_exponent_e:,
         | 
| 56 | 
            -
                    private_exponent_d: nil,
         | 
| 57 | 
            -
                    prime_factor_p: nil,
         | 
| 58 | 
            -
                    prime_factor_q: nil,
         | 
| 59 | 
            -
                    d_p: nil,
         | 
| 60 | 
            -
                    d_q: nil,
         | 
| 61 | 
            -
                    q_inv: nil
         | 
| 62 | 
            -
                  )
         | 
| 63 | 
            -
                    if !modulus_n
         | 
| 64 | 
            -
                      raise ArgumentError, "Required modulus_n is missing"
         | 
| 65 | 
            -
                    elsif !public_exponent_e
         | 
| 66 | 
            -
                      raise ArgumentError, "Required public_exponent_e is missing"
         | 
| 48 | 
            +
                  attr_reader :n, :e, :d, :p, :q, :dp, :dq, :qinv
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  def initialize(n:, e:, d: nil, p: nil, q: nil, dp: nil, dq: nil, qinv: nil, **keyword_arguments) # rubocop:disable Naming/UncommunicativeMethodParamName
         | 
| 51 | 
            +
                    super(**keyword_arguments)
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    if !n
         | 
| 54 | 
            +
                      raise ArgumentError, "Required public field n is missing"
         | 
| 55 | 
            +
                    elsif !e
         | 
| 56 | 
            +
                      raise ArgumentError, "Required public field e is missing"
         | 
| 67 57 | 
             
                    else
         | 
| 68 | 
            -
                       | 
| 69 | 
            -
             | 
| 70 | 
            -
                       | 
| 71 | 
            -
             | 
| 72 | 
            -
             | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 58 | 
            +
                      private_fields = { d: d, p: p, q: q, dp: dp, dq: dq, qinv: qinv }
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                      if private_fields.values.all?(&:nil?) || private_fields.values.none?(&:nil?)
         | 
| 61 | 
            +
                        @n = n
         | 
| 62 | 
            +
                        @e = e
         | 
| 63 | 
            +
                        @d = d
         | 
| 64 | 
            +
                        @p = p
         | 
| 65 | 
            +
                        @q = q
         | 
| 66 | 
            +
                        @dp = dp
         | 
| 67 | 
            +
                        @dq = dq
         | 
| 68 | 
            +
                        @qinv = qinv
         | 
| 69 | 
            +
                      else
         | 
| 70 | 
            +
                        missing = private_fields.detect { |_k, v| v.nil? }[0]
         | 
| 71 | 
            +
                        raise ArgumentError, "Incomplete private fields, #{missing} is missing"
         | 
| 72 | 
            +
                      end
         | 
| 76 73 | 
             
                    end
         | 
| 77 74 | 
             
                  end
         | 
| 78 75 |  | 
| 79 | 
            -
                  def  | 
| 80 | 
            -
                     | 
| 76 | 
            +
                  def map
         | 
| 77 | 
            +
                    map = super.merge(
         | 
| 81 78 | 
             
                      Base::LABEL_KTY => KTY_RSA,
         | 
| 82 | 
            -
                      LABEL_N =>  | 
| 83 | 
            -
                      LABEL_E =>  | 
| 84 | 
            -
                      LABEL_D =>  | 
| 85 | 
            -
                      LABEL_P =>  | 
| 86 | 
            -
                      LABEL_Q =>  | 
| 87 | 
            -
                       | 
| 88 | 
            -
                       | 
| 89 | 
            -
                       | 
| 79 | 
            +
                      LABEL_N => n,
         | 
| 80 | 
            +
                      LABEL_E => e,
         | 
| 81 | 
            +
                      LABEL_D => d,
         | 
| 82 | 
            +
                      LABEL_P => p,
         | 
| 83 | 
            +
                      LABEL_Q => q,
         | 
| 84 | 
            +
                      LABEL_DP => dp,
         | 
| 85 | 
            +
                      LABEL_DQ => dq,
         | 
| 86 | 
            +
                      LABEL_QINV => qinv
         | 
| 90 87 | 
             
                    )
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                    map.reject { |_k, v| v.nil? }
         | 
| 91 90 | 
             
                  end
         | 
| 92 91 |  | 
| 93 92 | 
             
                  def to_pkey
         | 
| 94 93 | 
             
                    pkey = OpenSSL::PKey::RSA.new
         | 
| 95 94 |  | 
| 96 | 
            -
                    pkey.set_key | 
| 97 | 
            -
             | 
| 98 | 
            -
                     | 
| 95 | 
            +
                    if pkey.respond_to?(:set_key)
         | 
| 96 | 
            +
                      pkey.set_key(bn(n), bn(e), bn(d))
         | 
| 97 | 
            +
                    else
         | 
| 98 | 
            +
                      pkey.n = bn(n)
         | 
| 99 | 
            +
                      pkey.e = bn(e)
         | 
| 100 | 
            +
                      pkey.d = bn(d)
         | 
| 101 | 
            +
                    end
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                    if pkey.respond_to?(:set_factors)
         | 
| 104 | 
            +
                      pkey.set_factors(bn(p), bn(q))
         | 
| 105 | 
            +
                    else
         | 
| 106 | 
            +
                      pkey.p = bn(p)
         | 
| 107 | 
            +
                      pkey.q = bn(q)
         | 
| 108 | 
            +
                    end
         | 
| 109 | 
            +
             | 
| 110 | 
            +
                    if pkey.respond_to?(:set_crt_params)
         | 
| 111 | 
            +
                      pkey.set_crt_params(bn(dp), bn(dq), bn(qinv))
         | 
| 112 | 
            +
                    else
         | 
| 113 | 
            +
                      pkey.dmp1 = bn(dp)
         | 
| 114 | 
            +
                      pkey.dmq1 = bn(dq)
         | 
| 115 | 
            +
                      pkey.iqmp = bn(qinv)
         | 
| 116 | 
            +
                    end
         | 
| 99 117 |  | 
| 100 118 | 
             
                    pkey
         | 
| 101 119 | 
             
                  end
         | 
| 102 120 |  | 
| 103 | 
            -
                  def self. | 
| 104 | 
            -
                     | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 121 | 
            +
                  def self.keyword_arguments_for_initialize(map)
         | 
| 122 | 
            +
                    {
         | 
| 123 | 
            +
                      n: map[LABEL_N],
         | 
| 124 | 
            +
                      e: map[LABEL_E],
         | 
| 125 | 
            +
                      d: map[LABEL_D],
         | 
| 126 | 
            +
                      p: map[LABEL_P],
         | 
| 127 | 
            +
                      q: map[LABEL_Q],
         | 
| 128 | 
            +
                      dp: map[LABEL_DP],
         | 
| 129 | 
            +
                      dq: map[LABEL_DQ],
         | 
| 130 | 
            +
                      qinv: map[LABEL_QINV]
         | 
| 131 | 
            +
                    }
         | 
| 107 132 | 
             
                  end
         | 
| 108 133 |  | 
| 109 134 | 
             
                  private
         | 
    
        data/lib/cose/key/symmetric.rb
    CHANGED
    
    | @@ -5,23 +5,34 @@ require "cose/key/base" | |
| 5 5 | 
             
            module COSE
         | 
| 6 6 | 
             
              module Key
         | 
| 7 7 | 
             
                class Symmetric < Base
         | 
| 8 | 
            -
                   | 
| 8 | 
            +
                  LABEL_K = -1
         | 
| 9 | 
            +
             | 
| 9 10 | 
             
                  KTY_SYMMETRIC = 4
         | 
| 10 11 |  | 
| 11 | 
            -
                  attr_reader : | 
| 12 | 
            +
                  attr_reader :k
         | 
| 12 13 |  | 
| 13 | 
            -
                  def  | 
| 14 | 
            -
                    if  | 
| 15 | 
            -
                      raise  | 
| 14 | 
            +
                  def self.enforce_type(map)
         | 
| 15 | 
            +
                    if map[LABEL_KTY] != KTY_SYMMETRIC
         | 
| 16 | 
            +
                      raise "Not a Symmetric key"
         | 
| 16 17 | 
             
                    end
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  def initialize(k:, **keyword_arguments) # rubocop:disable Naming/UncommunicativeMethodParamName
         | 
| 21 | 
            +
                    super(**keyword_arguments)
         | 
| 17 22 |  | 
| 18 | 
            -
                     | 
| 23 | 
            +
                    if !k
         | 
| 24 | 
            +
                      raise ArgumentError, "Required key value k is missing"
         | 
| 25 | 
            +
                    else
         | 
| 26 | 
            +
                      @k = k
         | 
| 27 | 
            +
                    end
         | 
| 19 28 | 
             
                  end
         | 
| 20 29 |  | 
| 21 | 
            -
                  def  | 
| 22 | 
            -
                     | 
| 30 | 
            +
                  def map
         | 
| 31 | 
            +
                    super.merge(LABEL_KTY => KTY_SYMMETRIC, LABEL_K => k)
         | 
| 32 | 
            +
                  end
         | 
| 23 33 |  | 
| 24 | 
            -
             | 
| 34 | 
            +
                  def self.keyword_arguments_for_initialize(map)
         | 
| 35 | 
            +
                    { k: map[LABEL_K] }
         | 
| 25 36 | 
             
                  end
         | 
| 26 37 | 
             
                end
         | 
| 27 38 | 
             
              end
         | 
    
        data/lib/cose/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: cose
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.6.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Gonzalo Rodriguez
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: exe
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2019-03 | 
| 12 | 
            +
            date: 2019-04-03 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: cbor
         | 
| @@ -63,16 +63,16 @@ dependencies: | |
| 63 63 | 
             
              name: byebug
         | 
| 64 64 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 65 65 | 
             
                requirements:
         | 
| 66 | 
            -
                - - " | 
| 66 | 
            +
                - - ">="
         | 
| 67 67 | 
             
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            -
                    version: ' | 
| 68 | 
            +
                    version: '10.0'
         | 
| 69 69 | 
             
              type: :development
         | 
| 70 70 | 
             
              prerelease: false
         | 
| 71 71 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 72 72 | 
             
                requirements:
         | 
| 73 | 
            -
                - - " | 
| 73 | 
            +
                - - ">="
         | 
| 74 74 | 
             
                  - !ruby/object:Gem::Version
         | 
| 75 | 
            -
                    version: ' | 
| 75 | 
            +
                    version: '10.0'
         | 
| 76 76 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 77 77 | 
             
              name: rake
         | 
| 78 78 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -138,12 +138,15 @@ files: | |
| 138 138 | 
             
            - cose.gemspec
         | 
| 139 139 | 
             
            - gemfiles/openssl_2_0.gemfile
         | 
| 140 140 | 
             
            - gemfiles/openssl_2_1.gemfile
         | 
| 141 | 
            +
            - gemfiles/openssl_default.gemfile
         | 
| 141 142 | 
             
            - lib/cose.rb
         | 
| 142 143 | 
             
            - lib/cose/encrypt.rb
         | 
| 143 144 | 
             
            - lib/cose/encrypt0.rb
         | 
| 144 145 | 
             
            - lib/cose/key.rb
         | 
| 145 146 | 
             
            - lib/cose/key/base.rb
         | 
| 147 | 
            +
            - lib/cose/key/curve_key.rb
         | 
| 146 148 | 
             
            - lib/cose/key/ec2.rb
         | 
| 149 | 
            +
            - lib/cose/key/okp.rb
         | 
| 147 150 | 
             
            - lib/cose/key/rsa.rb
         | 
| 148 151 | 
             
            - lib/cose/key/symmetric.rb
         | 
| 149 152 | 
             
            - lib/cose/mac.rb
         |