1
1
//! SASL-based authentication support.
2
2
3
3
use base64;
4
- use generic_array:: GenericArray ;
5
4
use generic_array:: typenum:: U32 ;
5
+ use generic_array:: GenericArray ;
6
6
use hmac:: { Hmac , Mac } ;
7
- use sha2:: { Sha256 , Digest } ;
7
+ use rand:: { OsRng , Rng } ;
8
+ use sha2:: { Digest , Sha256 } ;
8
9
use std:: fmt:: Write ;
9
10
use std:: io;
10
11
use std:: iter;
11
12
use std:: mem;
12
13
use std:: str;
13
- use rand:: { OsRng , Rng } ;
14
14
use stringprep;
15
15
16
16
const NONCE_LENGTH : usize = 24 ;
@@ -34,16 +34,15 @@ fn normalize(pass: &[u8]) -> Vec<u8> {
34
34
}
35
35
36
36
fn hi ( str : & [ u8 ] , salt : & [ u8 ] , i : u32 ) -> GenericArray < u8 , U32 > {
37
- let mut hmac = Hmac :: < Sha256 > :: new ( str)
38
- . expect ( "HMAC is able to accept all key sizes" ) ;
37
+ let mut hmac = Hmac :: < Sha256 > :: new_varkey ( str) . expect ( "HMAC is able to accept all key sizes" ) ;
39
38
hmac. input ( salt) ;
40
39
hmac. input ( & [ 0 , 0 , 0 , 1 ] ) ;
41
40
let mut prev = hmac. result ( ) . code ( ) ;
42
41
43
42
let mut hi = GenericArray :: < u8 , U32 > :: clone_from_slice ( & prev) ;
44
43
45
44
for _ in 1 ..i {
46
- let mut hmac = Hmac :: < Sha256 > :: new ( str) . expect ( "already checked above" ) ;
45
+ let mut hmac = Hmac :: < Sha256 > :: new_varkey ( str) . expect ( "already checked above" ) ;
47
46
hmac. input ( prev. as_slice ( ) ) ;
48
47
prev = hmac. result ( ) . code ( ) ;
49
48
@@ -56,7 +55,10 @@ fn hi(str: &[u8], salt: &[u8], i: u32) -> GenericArray<u8, U32> {
56
55
}
57
56
58
57
enum State {
59
- Update { nonce : String , password : Vec < u8 > } ,
58
+ Update {
59
+ nonce : String ,
60
+ password : Vec < u8 > ,
61
+ } ,
60
62
Finish {
61
63
salted_password : GenericArray < u8 , U32 > ,
62
64
auth_message : String ,
@@ -134,9 +136,8 @@ impl ScramSha256 {
134
136
_ => return Err ( io:: Error :: new ( io:: ErrorKind :: Other , "invalid SCRAM state" ) ) ,
135
137
} ;
136
138
137
- let message = str:: from_utf8 ( message) . map_err ( |e| {
138
- io:: Error :: new ( io:: ErrorKind :: InvalidInput , e)
139
- } ) ?;
139
+ let message =
140
+ str:: from_utf8 ( message) . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: InvalidInput , e) ) ?;
140
141
141
142
let parsed = Parser :: new ( message) . server_first_message ( ) ?;
142
143
@@ -151,7 +152,7 @@ impl ScramSha256 {
151
152
152
153
let salted_password = hi ( & password, & salt, parsed. iteration_count ) ;
153
154
154
- let mut hmac = Hmac :: < Sha256 > :: new ( & salted_password)
155
+ let mut hmac = Hmac :: < Sha256 > :: new_varkey ( & salted_password)
155
156
. expect ( "HMAC is able to accept all key sizes" ) ;
156
157
hmac. input ( b"Client Key" ) ;
157
158
let client_key = hmac. result ( ) . code ( ) ;
@@ -165,8 +166,8 @@ impl ScramSha256 {
165
166
166
167
let auth_message = format ! ( "n=,r={},{},{}" , client_nonce, message, self . message) ;
167
168
168
- let mut hmac = Hmac :: < Sha256 > :: new ( & stored_key )
169
- . expect ( "HMAC is able to accept all key sizes" ) ;
169
+ let mut hmac =
170
+ Hmac :: < Sha256 > :: new_varkey ( & stored_key ) . expect ( "HMAC is able to accept all key sizes" ) ;
170
171
hmac. input ( auth_message. as_bytes ( ) ) ;
171
172
let client_signature = hmac. result ( ) ;
172
173
@@ -197,9 +198,8 @@ impl ScramSha256 {
197
198
_ => return Err ( io:: Error :: new ( io:: ErrorKind :: Other , "invalid SCRAM state" ) ) ,
198
199
} ;
199
200
200
- let message = str:: from_utf8 ( message) . map_err ( |e| {
201
- io:: Error :: new ( io:: ErrorKind :: InvalidInput , e)
202
- } ) ?;
201
+ let message =
202
+ str:: from_utf8 ( message) . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: InvalidInput , e) ) ?;
203
203
204
204
let parsed = Parser :: new ( message) . server_final_message ( ) ?;
205
205
@@ -218,18 +218,16 @@ impl ScramSha256 {
218
218
Err ( e) => return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidInput , e) ) ,
219
219
} ;
220
220
221
- let mut hmac = Hmac :: < Sha256 > :: new ( & salted_password)
221
+ let mut hmac = Hmac :: < Sha256 > :: new_varkey ( & salted_password)
222
222
. expect ( "HMAC is able to accept all key sizes" ) ;
223
223
hmac. input ( b"Server Key" ) ;
224
224
let server_key = hmac. result ( ) ;
225
225
226
- let mut hmac = Hmac :: < Sha256 > :: new ( & server_key. code ( ) )
226
+ let mut hmac = Hmac :: < Sha256 > :: new_varkey ( & server_key. code ( ) )
227
227
. expect ( "HMAC is able to accept all key sizes" ) ;
228
228
hmac. input ( auth_message. as_bytes ( ) ) ;
229
- hmac. verify ( & verifier) . map_err ( |_| io:: Error :: new (
230
- io:: ErrorKind :: InvalidInput ,
231
- "SCRAM verification error" ,
232
- ) )
229
+ hmac. verify ( & verifier)
230
+ . map_err ( |_| io:: Error :: new ( io:: ErrorKind :: InvalidInput , "SCRAM verification error" ) )
233
231
}
234
232
}
235
233
@@ -252,9 +250,7 @@ impl<'a> Parser<'a> {
252
250
Some ( ( i, c) ) => {
253
251
let m = format ! (
254
252
"unexpected character at byte {}: expected `{}` but got `{}" ,
255
- i,
256
- target,
257
- c
253
+ i, target, c
258
254
) ;
259
255
Err ( io:: Error :: new ( io:: ErrorKind :: InvalidInput , m) )
260
256
}
@@ -316,9 +312,8 @@ impl<'a> Parser<'a> {
316
312
'0' ...'9' => true ,
317
313
_ => false ,
318
314
} ) ?;
319
- n. parse ( ) . map_err (
320
- |e| io:: Error :: new ( io:: ErrorKind :: InvalidInput , e) ,
321
- )
315
+ n. parse ( )
316
+ . map_err ( |e| io:: Error :: new ( io:: ErrorKind :: InvalidInput , e) )
322
317
}
323
318
324
319
fn iteration_count ( & mut self ) -> io:: Result < u32 > {
@@ -329,12 +324,10 @@ impl<'a> Parser<'a> {
329
324
330
325
fn eof ( & mut self ) -> io:: Result < ( ) > {
331
326
match self . it . peek ( ) {
332
- Some ( & ( i, _) ) => {
333
- Err ( io:: Error :: new (
334
- io:: ErrorKind :: InvalidInput ,
335
- format ! ( "unexpected trailing data at byte {}" , i) ,
336
- ) )
337
- }
327
+ Some ( & ( i, _) ) => Err ( io:: Error :: new (
328
+ io:: ErrorKind :: InvalidInput ,
329
+ format ! ( "unexpected trailing data at byte {}" , i) ,
330
+ ) ) ,
338
331
None => Ok ( ( ) ) ,
339
332
}
340
333
}
@@ -419,10 +412,12 @@ mod test {
419
412
let nonce = "9IZ2O01zb9IgiIZ1WJ/zgpJB" ;
420
413
421
414
let client_first = "n,,n=,r=9IZ2O01zb9IgiIZ1WJ/zgpJB" ;
422
- let server_first = "r=9IZ2O01zb9IgiIZ1WJ/zgpJBjx/oIRLs02gGSHcw1KEty3eY,s=fs3IXBy7U7+IvVjZ,i\
423
- =4096";
424
- let client_final = "c=biws,r=9IZ2O01zb9IgiIZ1WJ/zgpJBjx/oIRLs02gGSHcw1KEty3eY,p=AmNKosjJzS3\
425
- 1NTlQYNs5BTeQjdHdk7lOflDo5re2an8=";
415
+ let server_first =
416
+ "r=9IZ2O01zb9IgiIZ1WJ/zgpJBjx/oIRLs02gGSHcw1KEty3eY,s=fs3IXBy7U7+IvVjZ,i\
417
+ =4096";
418
+ let client_final =
419
+ "c=biws,r=9IZ2O01zb9IgiIZ1WJ/zgpJBjx/oIRLs02gGSHcw1KEty3eY,p=AmNKosjJzS3\
420
+ 1NTlQYNs5BTeQjdHdk7lOflDo5re2an8=";
426
421
let server_final = "v=U+ppxD5XUKtradnv8e2MkeupiA8FU87Sg8CXzXHDAzw=" ;
427
422
428
423
let mut scram = ScramSha256 :: new_inner ( password. as_bytes ( ) , nonce. to_string ( ) ) . unwrap ( ) ;
0 commit comments