@@ -10,8 +10,7 @@ class VapidKey
1010 # @return [Webpush::VapidKey] a VapidKey instance for the given public and private keys
1111 def self . from_keys ( public_key , private_key )
1212 key = new
13- key . public_key = public_key
14- key . private_key = private_key
13+ key . set_keys! ( public_key , private_key )
1514
1615 key
1716 end
@@ -20,19 +19,14 @@ def self.from_keys(public_key, private_key)
2019 #
2120 # @return [Webpush::VapidKey] a VapidKey instance for the given public and private keys
2221 def self . from_pem ( pem )
23- key = new
24- src = OpenSSL ::PKey . read pem
25- key . curve . public_key = src . public_key
26- key . curve . private_key = src . private_key
27-
28- key
22+ new ( OpenSSL ::PKey . read pem )
2923 end
3024
3125 attr_reader :curve
3226
33- def initialize
34- @curve = OpenSSL :: PKey :: EC . new ( 'prime256v1' )
35- @curve . generate_key
27+ def initialize ( pkey = nil )
28+ @curve = pkey
29+ @curve = OpenSSL :: PKey :: EC . generate ( 'prime256v1' ) if @curve . nil?
3630 end
3731
3832 # Retrieve the encoded elliptic curve public key for VAPID protocol
@@ -57,11 +51,11 @@ def private_key
5751 end
5852
5953 def public_key = ( key )
60- curve . public_key = OpenSSL :: PKey :: EC :: Point . new ( group , to_big_num ( key ) )
54+ set_keys! ( key , nil )
6155 end
6256
6357 def private_key = ( key )
64- curve . private_key = to_big_num ( key )
58+ set_keys! ( nil , key )
6559 end
6660
6761 def curve_name
@@ -78,16 +72,39 @@ def to_h
7872 alias to_hash to_h
7973
8074 def to_pem
81- public_key = OpenSSL ::PKey ::EC . new curve
82- public_key . private_key = nil
83-
84- curve . to_pem + public_key . to_pem
75+ curve . to_pem + curve . public_to_pem
8576 end
8677
8778 def inspect
8879 "#<#{ self . class } :#{ object_id . to_s ( 16 ) } #{ to_h . map { |k , v | ":#{ k } =#{ v } " } . join ( ' ' ) } >"
8980 end
9081
82+ def set_keys! ( public_key = nil , private_key = nil )
83+ if public_key . nil?
84+ public_key = curve . public_key
85+ else
86+ public_key = OpenSSL ::PKey ::EC ::Point . new ( group , to_big_num ( public_key ) )
87+ end
88+
89+ if private_key . nil?
90+ private_key = curve . private_key
91+ else
92+ private_key = to_big_num ( private_key )
93+ end
94+
95+ asn1 = OpenSSL ::ASN1 ::Sequence ( [
96+ OpenSSL ::ASN1 ::Integer . new ( 1 ) ,
97+ # Not properly padded but OpenSSL doesn't mind
98+ OpenSSL ::ASN1 ::OctetString ( private_key . to_s ( 2 ) ) ,
99+ OpenSSL ::ASN1 ::ObjectId ( 'prime256v1' , 0 , :EXPLICIT ) ,
100+ OpenSSL ::ASN1 ::BitString ( public_key . to_octet_string ( :uncompressed ) , 1 , :EXPLICIT ) ,
101+ ] )
102+
103+ der = asn1 . to_der
104+
105+ @curve = OpenSSL ::PKey ::EC . new ( der )
106+ end
107+
91108 private
92109
93110 def to_big_num ( key )
0 commit comments