File tree 3 files changed +52
-1
lines changed
lib/openssl/signature_algorithm
spec/openssl/signature_algorithm
3 files changed +52
-1
lines changed Original file line number Diff line number Diff line change @@ -22,7 +22,14 @@ def hash_function
22
22
end
23
23
24
24
def verify ( signature , verification_data )
25
- verify_key . verify ( hash_function , signature , verification_data ) ||
25
+ formatted_signature =
26
+ if respond_to? ( :formatted_signature , true )
27
+ formatted_signature ( signature )
28
+ else
29
+ signature
30
+ end
31
+
32
+ verify_key . verify ( hash_function , formatted_signature , verification_data ) ||
26
33
raise ( OpenSSL ::SignatureAlgorithm ::Error , "Signature verification failed" )
27
34
end
28
35
end
Original file line number Diff line number Diff line change 6
6
module OpenSSL
7
7
module SignatureAlgorithm
8
8
class ECDSA < Base
9
+ BYTE_LENGTH = 8
10
+
9
11
class SigningKey < OpenSSL ::PKey ::EC
10
12
def initialize ( *args )
11
13
super ( *args ) . generate_key
@@ -39,6 +41,29 @@ def curve_name
39
41
CURVE_BY_DIGEST_LENGTH [ digest_length ] ||
40
42
raise ( OpenSSL ::SignatureAlgorithm ::Error , "Unsupported digest length #{ digest_length } " )
41
43
end
44
+
45
+ private
46
+
47
+ # Borrowed from jwt rubygem.
48
+ # https://github.com/jwt/ruby-jwt/blob/7a6a3f1dbaff806993156d1dff9c217bb2523ff8/lib/jwt/security_utils.rb#L34-L39
49
+ #
50
+ # Hopefully this will be provided by openssl rubygem in the future.
51
+ def formatted_signature ( signature )
52
+ n = ( verify_key_length . to_f / BYTE_LENGTH ) . ceil
53
+
54
+ if signature . size == n * 2
55
+ r = signature [ 0 ..( n - 1 ) ]
56
+ s = signature [ n ..-1 ]
57
+
58
+ OpenSSL ::ASN1 ::Sequence . new ( [ r , s ] . map { |int | OpenSSL ::ASN1 ::Integer . new ( OpenSSL ::BN . new ( int , 2 ) ) } ) . to_der
59
+ else
60
+ signature
61
+ end
62
+ end
63
+
64
+ def verify_key_length
65
+ verify_key . group . degree
66
+ end
42
67
end
43
68
end
44
69
end
Original file line number Diff line number Diff line change 53
53
algorithm . verify_key = verify_key
54
54
algorithm . verify ( signature , to_be_signed )
55
55
end
56
+
57
+ it "works for raw (non DER) signature" do
58
+ to_be_signed = "to-be-signed"
59
+
60
+ # Signer
61
+ algorithm = OpenSSL ::SignatureAlgorithm ::ECDSA . new ( "256" )
62
+ signing_key = algorithm . generate_signing_key
63
+ signature = algorithm . sign ( to_be_signed )
64
+
65
+ raw_signature = OpenSSL ::ASN1 . decode ( signature ) . value . map { |v | v . value . to_s ( 2 ) } . join
66
+
67
+ # Signer sends verify key to Verifier
68
+ verify_key = signing_key . verify_key
69
+
70
+ # Verifier
71
+ algorithm = OpenSSL ::SignatureAlgorithm ::ECDSA . new ( "256" )
72
+ algorithm . verify_key = verify_key
73
+ algorithm . verify ( raw_signature , to_be_signed )
74
+ end
56
75
end
You can’t perform that action at this time.
0 commit comments