lib/cose/key/rsa.rb in cose-0.4.1 vs lib/cose/key/rsa.rb in cose-0.5.0
- old
+ new
@@ -1,33 +1,116 @@
# frozen_string_literal: true
require "cose/key/base"
+require "openssl"
module COSE
module Key
class RSA < Base
LABEL_N = -1
LABEL_E = -2
+ LABEL_D = -3
+ LABEL_P = -4
+ LABEL_Q = -5
+ LABEL_D_P = -6
+ LABEL_D_Q = -7
+ LABEL_Q_INV = -8
KTY_RSA = 3
- attr_reader :modulus_n, :public_exponent_e
+ def self.from_pkey(pkey)
+ params = pkey.params
- def initialize(modulus_n:, public_exponent_e:)
+ attributes = {
+ modulus_n: params["n"].to_s(2),
+ public_exponent_e: params["e"].to_s(2)
+ }
+
+ if pkey.private?
+ attributes.merge!(
+ private_exponent_d: params["d"].to_s(2),
+ prime_factor_p: params["p"].to_s(2),
+ prime_factor_q: params["q"].to_s(2),
+ d_p: params["dmp1"].to_s(2),
+ d_q: params["dmq1"].to_s(2),
+ q_inv: params["iqmp"].to_s(2)
+ )
+ end
+
+ new(attributes)
+ end
+
+ attr_reader(
+ :modulus_n,
+ :public_exponent_e,
+ :private_exponent_d,
+ :prime_factor_p,
+ :prime_factor_q,
+ :d_p,
+ :d_q,
+ :q_inv
+ )
+
+ def initialize(
+ modulus_n:,
+ public_exponent_e:,
+ private_exponent_d: nil,
+ prime_factor_p: nil,
+ prime_factor_q: nil,
+ d_p: nil,
+ d_q: nil,
+ q_inv: nil
+ )
if !modulus_n
raise ArgumentError, "Required modulus_n is missing"
elsif !public_exponent_e
raise ArgumentError, "Required public_exponent_e is missing"
else
@modulus_n = modulus_n
@public_exponent_e = public_exponent_e
+ @private_exponent_d = private_exponent_d
+ @prime_factor_p = prime_factor_p
+ @prime_factor_q = prime_factor_q
+ @d_p = d_p
+ @d_q = d_q
+ @q_inv = q_inv
end
end
+ def serialize
+ CBOR.encode(
+ Base::LABEL_KTY => KTY_RSA,
+ LABEL_N => modulus_n,
+ LABEL_E => public_exponent_e,
+ LABEL_D => private_exponent_d,
+ LABEL_P => prime_factor_p,
+ LABEL_Q => prime_factor_q,
+ LABEL_D_P => d_p,
+ LABEL_D_Q => d_q,
+ LABEL_Q_INV => q_inv
+ )
+ end
+
+ def to_pkey
+ pkey = OpenSSL::PKey::RSA.new
+
+ pkey.set_key(bn(modulus_n), bn(public_exponent_e), bn(private_exponent_d))
+ pkey.set_factors(bn(prime_factor_p), bn(prime_factor_q))
+ pkey.set_crt_params(bn(d_p), bn(d_q), bn(q_inv))
+
+ pkey
+ end
+
def self.from_map(map)
enforce_type(map, KTY_RSA, "Not an RSA key")
new(modulus_n: map[LABEL_N], public_exponent_e: map[LABEL_E])
+ end
+
+ private
+
+ def bn(data)
+ OpenSSL::BN.new(data, 2)
end
end
end
end