@@ -12,7 +12,7 @@ use hyper::Client;
12
12
use hyper:: header:: { Headers } ;
13
13
use std:: io:: prelude:: * ;
14
14
use base64:: { encode, decode} ;
15
- use crypto:: mac:: { Mac } ;
15
+ use crypto:: mac:: { Mac , MacResult } ;
16
16
use crypto:: hmac:: Hmac ;
17
17
use crypto:: sha1:: Sha1 ;
18
18
use rand:: { thread_rng, Rng } ;
@@ -74,13 +74,15 @@ impl Yubico {
74
74
let mut query = format ! ( "id={}&nonce={}&otp={}&sl=secure" , self . client_id, nonce, otp) ;
75
75
76
76
let signature = self . build_signature ( query. clone ( ) ) ;
77
+ // Base 64 encode the resulting value according to RFC 4648
78
+ let encoded_signature = encode ( signature. code ( ) ) ;
77
79
78
80
// Append the value under key h to the message.
79
- let signature_param = format ! ( "&h={}" , signature ) ;
81
+ let signature_param = format ! ( "&h={}" , encoded_signature ) ;
80
82
let encoded = utf8_percent_encode ( signature_param. as_ref ( ) , QUERY_ENCODE_SET ) . collect :: < String > ( ) ;
81
83
query. push_str ( encoded. as_ref ( ) ) ;
82
84
83
- let request = Request { otp : otp, nonce : nonce, signature : signature , query : query} ;
85
+ let request = Request { otp : otp, nonce : nonce, signature : encoded_signature , query : query} ;
84
86
85
87
let pool = ThreadPool :: new ( 3 ) ;
86
88
let ( tx, rx) = channel ( ) ;
@@ -122,12 +124,10 @@ impl Yubico {
122
124
}
123
125
124
126
// 1. Apply the HMAC-SHA-1 algorithm on the line as an octet string using the API key as key
125
- // 2. Base 64 encode the resulting value according to RFC 4648
126
- fn build_signature ( & self , query : String ) -> String {
127
+ fn build_signature ( & self , query : String ) -> MacResult {
127
128
let mut hmac = Hmac :: new ( Sha1 :: new ( ) , & self . key [ ..] ) ;
128
129
hmac. input ( query. as_bytes ( ) ) ;
129
- let signature = encode ( hmac. result ( ) . code ( ) ) ;
130
- format ! ( "{}" , signature)
130
+ hmac. result ( )
131
131
}
132
132
133
133
// Recommendation is that clients only check that the input consists of 32-48 printable characters
@@ -195,7 +195,10 @@ impl Yubico {
195
195
196
196
let signature = self . build_signature ( query. clone ( ) ) ;
197
197
198
- if signature == signature_response { true } else { false }
198
+
199
+ let decoded_signature = & decode ( signature_response) . unwrap ( ) [ ..] ;
200
+
201
+ crypto:: util:: fixed_time_eq ( signature. code ( ) , decoded_signature)
199
202
}
200
203
201
204
fn build_response_map ( & self , result : String ) -> BTreeMap < String , String > {
0 commit comments