sandal 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|