Sha256: 3cb1ff1abe87009c3996d47c4dac1a5e461543511f7a0af47bbc2771a5a53b10

Contents?: true

Size: 1.98 KB

Versions: 1

Compression:

Stored size: 1.98 KB

Contents

module JSON
  class JWK < Hash
    class UnknownAlgorithm < JWT::Exception; end

    def initialize(public_key, options = {})
      replace encode(public_key, options)
    end

    private

    def ecdsa_curve_name(ecdsa_key)
      case ecdsa_key.group.curve_name
      when 'secp256k1'
        :'P-256'
      when 'secp384r1'
        :'P-384'
      when 'secp521r1'
        :'P-521'
      else
        raise UnknownAlgorithm.new('Unknown ECDSA Curve')
      end
    end

    def ecdsa_coodinates(ecdsa_key)
      unless @ecdsa_coodinates
        hex = ecdsa_key.public_key.to_bn.to_s(16)
        data_len = hex.length - 2
        type = hex[0,2]
        hex_x =  hex[2, data_len/2]
        hex_y = hex[2+data_len/2, data_len/2]
        @ecdsa_coodinates = {
          x: hex_x,
          y: hex_y
        }
      end
      @ecdsa_coodinates
    end

    def encode(public_key, options = {})
      hash = case public_key
      when OpenSSL::PKey::RSA
        {
          alg: :RSA,
          xpo: UrlSafeBase64.encode64(public_key.e.to_s(2)),
          mod: UrlSafeBase64.encode64(public_key.n.to_s(2))
        }
      when OpenSSL::PKey::EC
        {
          alg: :EC,
          crv: ecdsa_curve_name(public_key),
          x: UrlSafeBase64.encode64(ecdsa_coodinates(public_key)[:x].to_s),
          y: UrlSafeBase64.encode64(ecdsa_coodinates(public_key)[:y].to_s)
        }
      else
        raise UnknownAlgorithm.new('Unknown Algorithm')
      end
      hash.merge(options)
    end

    class << self
      def decode(jwk)
        case jwk[:alg].to_s
        when 'RSA'
          exp = OpenSSL::BN.new UrlSafeBase64.decode64(jwk[:xpo]), 2
          mod = OpenSSL::BN.new UrlSafeBase64.decode64(jwk[:mod]), 2
          key = OpenSSL::PKey::RSA.new
          key.e = exp
          key.n = mod
          key
        when 'EC'
          raise NotImplementedError.new('Not Implemented Yet')
        else
          raise UnknownAlgorithm.new('Unknown Algorithm')
        end
      end
    end
  end
end

require 'json/jwk/set'

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
json-jwt-0.3.1 lib/json/jwk.rb