sandal 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/CHANGELOG.md +14 -0
- data/README.md +1 -1
- data/lib/sandal.rb +77 -76
- data/lib/sandal/claims.rb +13 -13
- data/lib/sandal/enc.rb +15 -49
- data/lib/sandal/enc/acbc_hs.rb +97 -52
- data/lib/sandal/enc/agcm.rb +64 -26
- data/lib/sandal/enc/alg.rb +2 -3
- data/lib/sandal/enc/alg/direct.rb +27 -25
- data/lib/sandal/enc/alg/rsa.rb +82 -0
- data/lib/sandal/sig.rb +12 -12
- data/lib/sandal/sig/es.rb +43 -25
- data/lib/sandal/sig/hs.rb +21 -8
- data/lib/sandal/sig/rs.rb +34 -23
- data/lib/sandal/util.rb +7 -7
- data/lib/sandal/version.rb +1 -1
- data/spec/helper.rb +1 -0
- data/spec/sample_keys.rb +28 -0
- data/spec/sandal/claims_spec.rb +4 -4
- data/spec/sandal/enc/a128cbc_hs256_spec.rb +15 -39
- data/spec/sandal/enc/a128gcm_spec.rb +13 -6
- data/spec/sandal/enc/a256cbc_hs512_spec.rb +13 -4
- data/spec/sandal/enc/a256gcm_spec.rb +15 -37
- data/spec/sandal/enc/alg/direct_spec.rb +27 -33
- data/spec/sandal/enc/alg/rsa_spec.rb +100 -0
- data/spec/sandal/enc/shared_examples.rb +93 -21
- data/spec/sandal/sig/es_spec.rb +145 -188
- data/spec/sandal/sig/hs_spec.rb +73 -18
- data/spec/sandal/sig/rs_spec.rb +81 -78
- metadata +7 -6
- data/lib/sandal/enc/alg/rsa1_5.rb +0 -47
- data/lib/sandal/enc/alg/rsa_oaep.rb +0 -48
- data/spec/sandal/enc/alg/rsa1_5_spec.rb +0 -40
data/spec/sandal/sig/es_spec.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "helper"
|
2
|
+
require "openssl"
|
3
3
|
|
4
4
|
include Sandal::Util
|
5
5
|
|
@@ -7,237 +7,194 @@ include Sandal::Util
|
|
7
7
|
if defined? Sandal::Sig::ES
|
8
8
|
|
9
9
|
def make_point(group, x, y)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
elsif c.length <= 96
|
14
|
-
padding_length = 96 - c.length
|
15
|
-
elsif c.length <= 132
|
16
|
-
padding_length = 132 - c.length
|
17
|
-
end
|
18
|
-
('0' * padding_length) + c
|
19
|
-
end
|
20
|
-
str = '04' + pad(x.to_s(16)) + pad(y.to_s(16))
|
10
|
+
group_size = group.curve_name.match(/(\d+)/)[0].to_i
|
11
|
+
bn_size = ((group_size + 7) / 8) * 2
|
12
|
+
str = "04" + x.to_s(16).rjust(bn_size, "0") + y.to_s(16).rjust(bn_size, "0")
|
21
13
|
bn = OpenSSL::BN.new(str, 16)
|
22
14
|
OpenSSL::PKey::EC::Point.new(group, bn)
|
23
15
|
end
|
24
16
|
|
25
|
-
|
26
|
-
|
27
|
-
it 'can encode the signature in JWS section A3.1' do
|
28
|
-
r = make_bn([14, 209, 33, 83, 121, 99, 108, 72, 60, 47, 127, 21, 88, 7, 212, 2, 163, 178, 40, 3, 58, 249, 124, 126, 23, 129, 154, 195, 22, 158, 166, 101] )
|
29
|
-
s = make_bn([197, 10, 7, 211, 140, 60, 112, 229, 216, 241, 45, 175, 8, 74, 84, 128, 166, 101, 144, 197, 242, 147, 80, 154, 143, 63, 127, 138, 131, 163, 84, 213])
|
30
|
-
signature = Sandal::Sig::ES.encode_jws_signature(r, s, 256)
|
31
|
-
base64_signature = jwt_base64_encode(signature)
|
32
|
-
base64_signature.should == 'DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q'
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'can encode the signature in JWS section A4.1' do
|
36
|
-
r = make_bn([1, 220, 12, 129, 231, 171, 194, 209, 232, 135, 233, 117, 247, 105, 122, 210, 26, 125, 192, 1, 217, 21, 82, 91, 45, 240, 255, 83, 19, 34, 239, 71, 48, 157, 147, 152, 105, 18, 53, 108, 163, 214, 68, 231, 62, 153, 150, 106, 194, 164, 246, 72, 143, 138, 24, 50, 129, 223, 133, 206, 209, 172, 63, 237, 119, 109] )
|
37
|
-
s = make_bn([0, 111, 6, 105, 44, 5, 41, 208, 128, 61, 152, 40, 92, 61, 152, 4, 150, 66, 60, 69, 247, 196, 170, 81, 193, 199, 78, 59, 194, 169, 16, 124, 9, 143, 42, 142, 131, 48, 206, 238, 34, 175, 83, 203, 220, 159, 3, 107, 155, 22, 27, 73, 111, 68, 68, 21, 238, 144, 229, 232, 148, 188, 222, 59, 242, 103] )
|
38
|
-
signature = Sandal::Sig::ES.encode_jws_signature(r, s, 521)
|
39
|
-
base64_signature = jwt_base64_encode(signature)
|
40
|
-
base64_signature.should == 'AdwMgeerwtHoh-l192l60hp9wAHZFVJbLfD_UxMi70cwnZOYaRI1bKPWROc-mZZqwqT2SI-KGDKB34XO0aw_7XdtAG8GaSwFKdCAPZgoXD2YBJZCPEX3xKpRwcdOO8KpEHwJjyqOgzDO7iKvU8vcnwNrmxYbSW9ERBXukOXolLzeO_Jn'
|
41
|
-
end
|
17
|
+
shared_examples "signing and validation" do |enc_class|
|
42
18
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
it 'can sign data and verify signatures' do
|
48
|
-
group = OpenSSL::PKey::EC::Group.new('prime256v1')
|
19
|
+
it "can sign data and validate signatures" do
|
20
|
+
data = "some data to sign"
|
21
|
+
group = OpenSSL::PKey::EC::Group.new(enc_class::CURVE_NAME)
|
49
22
|
private_key = OpenSSL::PKey::EC.new(group).generate_key
|
50
|
-
|
51
|
-
signer = Sandal::Sig::ES256.new(private_key)
|
23
|
+
signer = enc_class.new(private_key)
|
52
24
|
signature = signer.sign(data)
|
53
25
|
public_key = OpenSSL::PKey::EC.new(group)
|
54
26
|
public_key.public_key = private_key.public_key
|
55
|
-
validator =
|
27
|
+
validator = enc_class.new(public_key)
|
56
28
|
validator.valid?(signature, data).should == true
|
57
29
|
end
|
58
30
|
|
59
|
-
it
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
-----BEGIN EC PRIVATE KEY-----
|
65
|
-
MHcCAQEEII1Ar4w2EVK6wNL84EpVTVY7XXXVmVqyvjZ4EW9kBGhSoAoGCCqGSM49
|
66
|
-
AwEHoUQDQgAEVnYRY+AEiU+UNdYzl+KtuWvdAfKBoAmEekv4icfZQCbLew/eXIlv
|
67
|
-
32E8+j0bFYwYi3XjxCJXRE3S2iWPEEygcA==
|
68
|
-
-----END EC PRIVATE KEY-----
|
69
|
-
KEY_END
|
70
|
-
public_key = <<KEY_END
|
71
|
-
-----BEGIN PUBLIC KEY-----
|
72
|
-
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEVnYRY+AEiU+UNdYzl+KtuWvdAfKB
|
73
|
-
oAmEekv4icfZQCbLew/eXIlv32E8+j0bFYwYi3XjxCJXRE3S2iWPEEygcA==
|
74
|
-
-----END PUBLIC KEY-----
|
75
|
-
KEY_END
|
76
|
-
data = 'Hello ES256'
|
77
|
-
signer = Sandal::Sig::ES256.new(private_key)
|
31
|
+
it "can use DER-encoded keys to sign data and validate signatures" do
|
32
|
+
data = "some data to sign"
|
33
|
+
group = OpenSSL::PKey::EC::Group.new(enc_class::CURVE_NAME)
|
34
|
+
private_key = OpenSSL::PKey::EC.new(group).generate_key
|
35
|
+
signer = enc_class.new(private_key.to_der)
|
78
36
|
signature = signer.sign(data)
|
79
|
-
|
37
|
+
public_key = OpenSSL::PKey::EC.new(group)
|
38
|
+
public_key.public_key = private_key.public_key
|
39
|
+
validator = enc_class.new(public_key.to_der)
|
80
40
|
validator.valid?(signature, data).should == true
|
81
41
|
end
|
82
42
|
|
83
|
-
it
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
signature =
|
89
|
-
|
90
|
-
group = OpenSSL::PKey::EC::Group.new('prime256v1')
|
43
|
+
it "can use PEM-encoded keys to sign data and validate signatures" do
|
44
|
+
data = "some data to sign"
|
45
|
+
group = OpenSSL::PKey::EC::Group.new(enc_class::CURVE_NAME)
|
46
|
+
private_key = OpenSSL::PKey::EC.new(group).generate_key
|
47
|
+
signer = enc_class.new(private_key.to_pem)
|
48
|
+
signature = signer.sign(data)
|
91
49
|
public_key = OpenSSL::PKey::EC.new(group)
|
92
|
-
public_key.public_key =
|
93
|
-
validator =
|
50
|
+
public_key.public_key = private_key.public_key
|
51
|
+
validator = enc_class.new(public_key.to_pem)
|
94
52
|
validator.valid?(signature, data).should == true
|
95
53
|
end
|
96
54
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
55
|
+
context "#initialize" do
|
56
|
+
|
57
|
+
it "raises an argument error if the key has the wrong curve" do
|
58
|
+
group = OpenSSL::PKey::EC::Group.new("secp224k1")
|
59
|
+
private_key = OpenSSL::PKey::EC.new(group).generate_key
|
60
|
+
expect { enc_class.new(private_key) }.to raise_error ArgumentError
|
61
|
+
end
|
103
62
|
|
104
|
-
group = OpenSSL::PKey::EC::Group.new('prime256v1')
|
105
|
-
public_key = OpenSSL::PKey::EC.new(group)
|
106
|
-
public_key.public_key = make_point(group, x, y)
|
107
|
-
validator = Sandal::Sig::ES256.new(public_key)
|
108
|
-
validator.valid?(signature, data).should == false
|
109
63
|
end
|
110
64
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
65
|
+
context "#valid?" do
|
66
|
+
|
67
|
+
it "fails to validate the signature when the key is changed" do
|
68
|
+
data = "some data to sign"
|
69
|
+
group = OpenSSL::PKey::EC::Group.new(enc_class::CURVE_NAME)
|
70
|
+
private_key = OpenSSL::PKey::EC.new(group).generate_key
|
71
|
+
signer = enc_class.new(private_key)
|
72
|
+
signature = signer.sign(data)
|
73
|
+
public_key = OpenSSL::PKey::EC.new(group).generate_key
|
74
|
+
validator = enc_class.new(public_key)
|
75
|
+
validator.valid?(signature, data).should == false
|
76
|
+
end
|
77
|
+
|
78
|
+
it "fails to validate the signature when the signature is changed" do
|
79
|
+
data = "some data to sign"
|
80
|
+
group = OpenSSL::PKey::EC::Group.new(enc_class::CURVE_NAME)
|
81
|
+
private_key = OpenSSL::PKey::EC.new(group).generate_key
|
82
|
+
signer = enc_class.new(private_key)
|
83
|
+
signature = signer.sign(data)
|
84
|
+
public_key = OpenSSL::PKey::EC.new(group)
|
85
|
+
public_key.public_key = private_key.public_key
|
86
|
+
validator = enc_class.new(public_key)
|
87
|
+
validator.valid?(signature + "x", data).should == false
|
88
|
+
end
|
89
|
+
|
90
|
+
it "fails to validate the signature when the data is changed" do
|
91
|
+
data = "some data to sign"
|
92
|
+
group = OpenSSL::PKey::EC::Group.new(enc_class::CURVE_NAME)
|
93
|
+
private_key = OpenSSL::PKey::EC.new(group).generate_key
|
94
|
+
signer = enc_class.new(private_key)
|
95
|
+
signature = signer.sign(data)
|
96
|
+
public_key = OpenSSL::PKey::EC.new(group)
|
97
|
+
public_key.public_key = private_key.public_key
|
98
|
+
validator = enc_class.new(public_key)
|
99
|
+
validator.valid?(signature, data + "x").should == false
|
100
|
+
end
|
101
|
+
|
115
102
|
end
|
116
103
|
|
117
104
|
end
|
118
105
|
|
119
|
-
describe Sandal::Sig::
|
106
|
+
describe Sandal::Sig::ES do
|
120
107
|
|
121
|
-
|
122
|
-
group = OpenSSL::PKey::EC::Group.new('secp384r1')
|
123
|
-
private_key = OpenSSL::PKey::EC.new(group).generate_key
|
124
|
-
data = 'Hello ES384'
|
125
|
-
signer = Sandal::Sig::ES384.new(private_key)
|
126
|
-
signature = signer.sign(data)
|
127
|
-
public_key = OpenSSL::PKey::EC.new(group)
|
128
|
-
public_key.public_key = private_key.public_key
|
129
|
-
validator = Sandal::Sig::ES384.new(public_key)
|
130
|
-
validator.valid?(signature, data).should == true
|
131
|
-
end
|
108
|
+
context "#encode_jws_signature" do
|
132
109
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
DIrhT21BXFmpsaPIVFE8S6XcL66xByFVdrq12lXNCh3UqPd21RBzDry2I6VxV7vv
|
149
|
-
H+hbte6H3BAgzSGiPQPrsnVmNxP3CVAz
|
150
|
-
-----END PUBLIC KEY-----
|
151
|
-
KEY_END
|
152
|
-
data = 'Hello ES384'
|
153
|
-
signer = Sandal::Sig::ES384.new(private_key)
|
154
|
-
signature = signer.sign(data)
|
155
|
-
validator = Sandal::Sig::ES384.new(public_key)
|
156
|
-
validator.valid?(signature, data).should == true
|
157
|
-
end
|
110
|
+
it "can encode the signature in JWS draft-11 appendix 3" do
|
111
|
+
r = make_bn([14, 209, 33, 83, 121, 99, 108, 72, 60, 47, 127, 21, 88, 7, 212, 2, 163, 178, 40, 3, 58, 249, 124, 126, 23, 129, 154, 195, 22, 158, 166, 101])
|
112
|
+
s = make_bn([197, 10, 7, 211, 140, 60, 112, 229, 216, 241, 45, 175, 8, 74, 84, 128, 166, 101, 144, 197, 242, 147, 80, 154, 143, 63, 127, 138, 131, 163, 84, 213])
|
113
|
+
signature = Sandal::Sig::ES.encode_jws_signature(r, s, 256)
|
114
|
+
base64_signature = jwt_base64_encode(signature)
|
115
|
+
base64_signature.should == "DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q"
|
116
|
+
end
|
117
|
+
|
118
|
+
it "can encode the signature in JWS draft-11 appendix 4" do
|
119
|
+
r = make_bn([1, 220, 12, 129, 231, 171, 194, 209, 232, 135, 233, 117, 247, 105, 122, 210, 26, 125, 192, 1, 217, 21, 82, 91, 45, 240, 255, 83, 19, 34, 239, 71, 48, 157, 147, 152, 105, 18, 53, 108, 163, 214, 68, 231, 62, 153, 150, 106, 194, 164, 246, 72, 143, 138, 24, 50, 129, 223, 133, 206, 209, 172, 63, 237, 119, 109])
|
120
|
+
s = make_bn([0, 111, 6, 105, 44, 5, 41, 208, 128, 61, 152, 40, 92, 61, 152, 4, 150, 66, 60, 69, 247, 196, 170, 81, 193, 199, 78, 59, 194, 169, 16, 124, 9, 143, 42, 142, 131, 48, 206, 238, 34, 175, 83, 203, 220, 159, 3, 107, 155, 22, 27, 73, 111, 68, 68, 21, 238, 144, 229, 232, 148, 188, 222, 59, 242, 103])
|
121
|
+
signature = Sandal::Sig::ES.encode_jws_signature(r, s, 521)
|
122
|
+
base64_signature = jwt_base64_encode(signature)
|
123
|
+
base64_signature.should == "AdwMgeerwtHoh-l192l60hp9wAHZFVJbLfD_UxMi70cwnZOYaRI1bKPWROc-mZZqwqT2SI-KGDKB34XO0aw_7XdtAG8GaSwFKdCAPZgoXD2YBJZCPEX3xKpRwcdOO8KpEHwJjyqOgzDO7iKvU8vcnwNrmxYbSW9ERBXukOXolLzeO_Jn"
|
124
|
+
end
|
158
125
|
|
159
|
-
it 'raises an argument error if the key has the wrong curve' do
|
160
|
-
group = OpenSSL::PKey::EC::Group.new('secp521r1')
|
161
|
-
private_key = OpenSSL::PKey::EC.new(group).generate_key
|
162
|
-
expect { Sandal::Sig::ES384.new(private_key) }.to raise_error ArgumentError
|
163
126
|
end
|
164
127
|
|
165
128
|
end
|
166
129
|
|
167
|
-
describe Sandal::Sig::
|
130
|
+
describe Sandal::Sig::ES256 do
|
131
|
+
include_examples "signing and validation", Sandal::Sig::ES256, "prime256v1"
|
168
132
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
signature = signer.sign(data)
|
175
|
-
public_key = OpenSSL::PKey::EC.new(group)
|
176
|
-
public_key.public_key = private_key.public_key
|
177
|
-
validator = Sandal::Sig::ES512.new(public_key)
|
178
|
-
validator.valid?(signature, data).should == true
|
133
|
+
context "#name" do
|
134
|
+
it "is 'ES256'" do
|
135
|
+
enc = Sandal::Sig::ES256.new(OpenSSL::PKey::EC.new("prime256v1").generate_key)
|
136
|
+
enc.name.should == "ES256"
|
137
|
+
end
|
179
138
|
end
|
180
139
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
p+ozs9xNBD84wyUvNuu10TnUi8YfxXTOeB2meWpNg6tFU4UjqriXZIsuo8gBDpVy
|
198
|
-
3s5w61fWT/XXRRRQPDjDNmiJlPh3Rquq5VqwLO6jFLbupT/ZN/lhw+2dfmJAmn6M
|
199
|
-
fpaa2hODa55ZFajtkVY=
|
200
|
-
-----END PUBLIC KEY-----
|
201
|
-
KEY_END
|
202
|
-
data = 'Hello ES512'
|
203
|
-
signer = Sandal::Sig::ES512.new(private_key)
|
204
|
-
signature = signer.sign(data)
|
205
|
-
validator = Sandal::Sig::ES512.new(public_key)
|
206
|
-
validator.valid?(signature, data).should == true
|
140
|
+
context "#valid?" do
|
141
|
+
|
142
|
+
it "can validate the signature in JWS draft-11 appendix 3" do
|
143
|
+
x = make_bn([127, 205, 206, 39, 112, 246, 196, 93, 65, 131, 203, 238, 111, 219, 75, 123, 88, 7, 51, 53, 123, 233, 239, 19, 186, 207, 110, 60, 123, 209, 84, 69])
|
144
|
+
y = make_bn([199, 241, 68, 205, 27, 189, 155, 126, 135, 44, 223, 237, 185, 238, 185, 244, 179, 105, 93, 110, 169, 11, 36, 173, 138, 70, 35, 40, 133, 136, 229, 173])
|
145
|
+
d = make_bn([142, 155, 16, 158, 113, 144, 152, 191, 152, 4, 135, 223, 31, 93, 119, 233, 203, 41, 96, 110, 190, 210, 38, 59, 95, 87, 194, 19, 223, 132, 244, 178])
|
146
|
+
data = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ"
|
147
|
+
signature = jwt_base64_decode("DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q")
|
148
|
+
|
149
|
+
group = OpenSSL::PKey::EC::Group.new("prime256v1")
|
150
|
+
public_key = OpenSSL::PKey::EC.new(group)
|
151
|
+
public_key.public_key = make_point(group, x, y)
|
152
|
+
validator = Sandal::Sig::ES256.new(public_key)
|
153
|
+
validator.valid?(signature, data).should == true
|
154
|
+
end
|
155
|
+
|
207
156
|
end
|
208
157
|
|
209
|
-
|
210
|
-
x = make_bn([1, 233, 41, 5, 15, 18, 79, 198, 188, 85, 199, 213, 57, 51, 101, 223, 157, 239, 74, 176, 194, 44, 178, 87, 152, 249, 52, 235, 4, 227, 198, 186, 227, 112, 26, 87, 167, 145, 14, 157, 129, 191, 54, 49, 89, 232, 235, 203, 21, 93, 99, 73, 244, 189, 182, 204, 248, 169, 76, 92, 89, 199, 170, 193, 1, 164])
|
211
|
-
y = make_bn([0, 52, 166, 68, 14, 55, 103, 80, 210, 55, 31, 209, 189, 194, 200, 243, 183, 29, 47, 78, 229, 234, 52, 50, 200, 21, 204, 163, 21, 96, 254, 93, 147, 135, 236, 119, 75, 85, 131, 134, 48, 229, 203, 191, 90, 140, 190, 10, 145, 221, 0, 100, 198, 153, 154, 31, 110, 110, 103, 250, 221, 237, 228, 200, 200, 246])
|
212
|
-
d = make_bn([1, 142, 105, 111, 176, 52, 80, 88, 129, 221, 17, 11, 72, 62, 184, 125, 50, 206, 73, 95, 227, 107, 55, 69, 237, 242, 216, 202, 228, 240, 242, 83, 159, 70, 21, 160, 233, 142, 171, 82, 179, 192, 197, 234, 196, 206, 7, 81, 133, 168, 231, 187, 71, 222, 172, 29, 29, 231, 123, 204, 246, 97, 53, 230, 61, 130] )
|
213
|
-
data = 'eyJhbGciOiJFUzUxMiJ9.UGF5bG9hZA'
|
214
|
-
signature = jwt_base64_decode('AdwMgeerwtHoh-l192l60hp9wAHZFVJbLfD_UxMi70cwnZOYaRI1bKPWROc-mZZqwqT2SI-KGDKB34XO0aw_7XdtAG8GaSwFKdCAPZgoXD2YBJZCPEX3xKpRwcdOO8KpEHwJjyqOgzDO7iKvU8vcnwNrmxYbSW9ERBXukOXolLzeO_Jn')
|
158
|
+
end
|
215
159
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
160
|
+
describe Sandal::Sig::ES384 do
|
161
|
+
include_examples "signing and validation", Sandal::Sig::ES384, "secp384r1"
|
162
|
+
|
163
|
+
context "#name" do
|
164
|
+
it "is 'ES384'" do
|
165
|
+
enc = Sandal::Sig::ES384.new(OpenSSL::PKey::EC.new("secp384r1").generate_key)
|
166
|
+
enc.name.should == "ES384"
|
167
|
+
end
|
221
168
|
end
|
222
169
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
data = 'not the data that was signed'
|
228
|
-
signature = jwt_base64_decode('AdwMgeerwtHoh-l192l60hp9wAHZFVJbLfD_UxMi70cwnZOYaRI1bKPWROc-mZZqwqT2SI-KGDKB34XO0aw_7XdtAG8GaSwFKdCAPZgoXD2YBJZCPEX3xKpRwcdOO8KpEHwJjyqOgzDO7iKvU8vcnwNrmxYbSW9ERBXukOXolLzeO_Jn')
|
170
|
+
end
|
171
|
+
|
172
|
+
describe Sandal::Sig::ES512 do
|
173
|
+
include_examples "signing and validation", Sandal::Sig::ES512, "secp521r1"
|
229
174
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
175
|
+
context "#name" do
|
176
|
+
it "is 'ES512'" do
|
177
|
+
enc = Sandal::Sig::ES512.new(OpenSSL::PKey::EC.new("secp521r1").generate_key)
|
178
|
+
enc.name.should == "ES512"
|
179
|
+
end
|
235
180
|
end
|
236
181
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
182
|
+
context "#validate?" do
|
183
|
+
|
184
|
+
it "can validate the signature in JWS draft-11 appendix 4" do
|
185
|
+
x = make_bn([1, 233, 41, 5, 15, 18, 79, 198, 188, 85, 199, 213, 57, 51, 101, 223, 157, 239, 74, 176, 194, 44, 178, 87, 152, 249, 52, 235, 4, 227, 198, 186, 227, 112, 26, 87, 167, 145, 14, 157, 129, 191, 54, 49, 89, 232, 235, 203, 21, 93, 99, 73, 244, 189, 182, 204, 248, 169, 76, 92, 89, 199, 170, 193, 1, 164])
|
186
|
+
y = make_bn([0, 52, 166, 68, 14, 55, 103, 80, 210, 55, 31, 209, 189, 194, 200, 243, 183, 29, 47, 78, 229, 234, 52, 50, 200, 21, 204, 163, 21, 96, 254, 93, 147, 135, 236, 119, 75, 85, 131, 134, 48, 229, 203, 191, 90, 140, 190, 10, 145, 221, 0, 100, 198, 153, 154, 31, 110, 110, 103, 250, 221, 237, 228, 200, 200, 246])
|
187
|
+
d = make_bn([1, 142, 105, 111, 176, 52, 80, 88, 129, 221, 17, 11, 72, 62, 184, 125, 50, 206, 73, 95, 227, 107, 55, 69, 237, 242, 216, 202, 228, 240, 242, 83, 159, 70, 21, 160, 233, 142, 171, 82, 179, 192, 197, 234, 196, 206, 7, 81, 133, 168, 231, 187, 71, 222, 172, 29, 29, 231, 123, 204, 246, 97, 53, 230, 61, 130] )
|
188
|
+
data = "eyJhbGciOiJFUzUxMiJ9.UGF5bG9hZA"
|
189
|
+
signature = jwt_base64_decode("AdwMgeerwtHoh-l192l60hp9wAHZFVJbLfD_UxMi70cwnZOYaRI1bKPWROc-mZZqwqT2SI-KGDKB34XO0aw_7XdtAG8GaSwFKdCAPZgoXD2YBJZCPEX3xKpRwcdOO8KpEHwJjyqOgzDO7iKvU8vcnwNrmxYbSW9ERBXukOXolLzeO_Jn")
|
190
|
+
|
191
|
+
group = OpenSSL::PKey::EC::Group.new("secp521r1")
|
192
|
+
public_key = OpenSSL::PKey::EC.new(group)
|
193
|
+
public_key.public_key = make_point(group, x, y)
|
194
|
+
validator = Sandal::Sig::ES512.new(public_key)
|
195
|
+
validator.valid?(signature, data).should == true
|
196
|
+
end
|
197
|
+
|
241
198
|
end
|
242
199
|
|
243
200
|
end
|
data/spec/sandal/sig/hs_spec.rb
CHANGED
@@ -1,32 +1,87 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "helper"
|
2
|
+
require "openssl"
|
3
|
+
|
4
|
+
shared_examples "signing and validation" do |enc_class|
|
5
|
+
|
6
|
+
it "can sign data and validate signatures" do
|
7
|
+
data = "some data to sign"
|
8
|
+
key = "A secret key"
|
9
|
+
signer = enc_class.new(key)
|
10
|
+
signature = signer.sign(data)
|
11
|
+
signer.valid?(signature, data).should == true
|
12
|
+
end
|
13
|
+
|
14
|
+
context "#valid?" do
|
15
|
+
|
16
|
+
it "fails to validate the signature when the key is changed" do
|
17
|
+
data = "some other data to sign"
|
18
|
+
key = "Another secret key"
|
19
|
+
signer = enc_class.new(key)
|
20
|
+
signature = signer.sign(data)
|
21
|
+
verifier = enc_class.new(key + "x")
|
22
|
+
verifier.valid?(signature, data).should == false
|
23
|
+
end
|
24
|
+
|
25
|
+
it "fails to validate the signature when the signature is changed" do
|
26
|
+
data = "some other data to sign"
|
27
|
+
key = "Another secret key"
|
28
|
+
signer = enc_class.new(key)
|
29
|
+
signature = signer.sign(data)
|
30
|
+
signer.valid?(signature + "x", data).should == false
|
31
|
+
end
|
32
|
+
|
33
|
+
it "fails to validate the signature when the data is changed" do
|
34
|
+
data = "some other data to sign"
|
35
|
+
key = "Another secret key"
|
36
|
+
signer = enc_class.new(key)
|
37
|
+
signature = signer.sign(data)
|
38
|
+
signer.valid?(signature, data + "x").should == false
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
3
44
|
|
4
45
|
describe Sandal::Sig::HS256 do
|
5
|
-
|
6
|
-
|
7
|
-
|
46
|
+
include_examples "signing and validation", Sandal::Sig::HS256
|
47
|
+
|
48
|
+
context "#name" do
|
49
|
+
it "is 'HS256'" do
|
50
|
+
enc = Sandal::Sig::HS256.new("any old key")
|
51
|
+
enc.name.should == "HS256"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "can validate the signature from JWS dratf-11 appendix 1" do
|
56
|
+
data = "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ"
|
57
|
+
key = [3, 35, 53, 75, 43, 15, 165, 188, 131, 126, 6, 101, 119, 123, 166, 143, 90, 179, 40, 230, 240, 84, 201, 40, 169, 15, 132, 178, 210, 80, 46, 191, 211, 251, 90, 146, 210, 6, 71, 239, 150, 138, 180, 195, 119, 98, 61, 34, 61, 46, 33, 114, 5, 46, 79, 8, 192, 205, 154, 245, 103, 208, 128, 163].pack("C*")
|
8
58
|
signer = Sandal::Sig::HS256.new(key)
|
9
|
-
signature =
|
59
|
+
signature = [116, 24, 223, 180, 151, 153, 224, 37, 79, 250, 96, 125, 216, 173, 187, 186, 22, 212, 37, 77, 105, 214, 191, 240, 91, 88, 5, 88, 83, 132, 141, 121].pack("C*")
|
10
60
|
signer.valid?(signature, data).should == true
|
11
61
|
end
|
62
|
+
|
12
63
|
end
|
13
64
|
|
14
65
|
describe Sandal::Sig::HS384 do
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
66
|
+
include_examples "signing and validation", Sandal::Sig::HS384
|
67
|
+
|
68
|
+
context "#name" do
|
69
|
+
it "is 'HS384'" do
|
70
|
+
enc = Sandal::Sig::HS384.new("any old key")
|
71
|
+
enc.name.should == "HS384"
|
72
|
+
end
|
21
73
|
end
|
74
|
+
|
22
75
|
end
|
23
76
|
|
24
77
|
describe Sandal::Sig::HS512 do
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
78
|
+
include_examples "signing and validation", Sandal::Sig::HS512
|
79
|
+
|
80
|
+
context "#name" do
|
81
|
+
it "is 'HS512'" do
|
82
|
+
enc = Sandal::Sig::HS512.new("any old key")
|
83
|
+
enc.name.should == "HS512"
|
84
|
+
end
|
31
85
|
end
|
86
|
+
|
32
87
|
end
|