@@ -8,6 +8,7 @@ extern crate threadpool;
8
8
9
9
pub mod yubicoerror;
10
10
11
+ use std:: ascii:: AsciiExt ;
11
12
use yubicoerror:: YubicoError ;
12
13
use hyper:: net:: HttpsConnector ;
13
14
use hyper_native_tls:: NativeTlsClient ;
@@ -62,15 +63,15 @@ impl Yubico {
62
63
pub fn new ( client_id : String , key : String ) -> Self {
63
64
Yubico {
64
65
client_id : client_id,
65
- key : decode ( key. as_ref ( ) ) . unwrap ( ) ,
66
+ key : decode ( & key[ .. ] ) . unwrap ( ) ,
66
67
}
67
68
}
68
69
69
70
// Verify a provided OTP
70
71
pub fn verify ( & self , otp : String ) -> Result < String > {
71
72
match self . printable_characters ( otp. clone ( ) ) {
72
73
false => Err ( YubicoError :: BadOTP ) ,
73
- _ => {
74
+ _ => {
74
75
let nonce: String = self . generate_nonce ( ) ;
75
76
let mut query = format ! ( "id={}&nonce={}&otp={}&sl=secure" , self . client_id, nonce, otp) ;
76
77
@@ -133,7 +134,12 @@ impl Yubico {
133
134
134
135
// Recommendation is that clients only check that the input consists of 32-48 printable characters
135
136
fn printable_characters ( & self , otp : String ) -> bool {
136
- if otp. len ( ) < 32 || otp. len ( ) > 48 { false } else { true }
137
+ for c in otp. chars ( ) {
138
+ if !c. is_ascii ( ) {
139
+ return false ;
140
+ }
141
+ }
142
+ otp. len ( ) > 32 && otp. len ( ) < 48
137
143
}
138
144
139
145
fn process ( & self , sender : Sender < Response > , api_host : & str , request : Request ) {
@@ -146,18 +152,21 @@ impl Yubico {
146
152
let signature_response : & str = & * response_map. get ( "h" ) . unwrap ( ) ;
147
153
if !self . is_same_signature ( signature_response, response_map. clone ( ) ) {
148
154
sender. send ( Response :: Signal ( Err ( YubicoError :: SignatureMismatch ) ) ) . unwrap ( ) ;
155
+ return ;
149
156
}
150
157
151
158
// Check if "otp" in the response is the same as the "otp" supplied in the request.
152
159
let otp_response : & str = & * response_map. get ( "otp" ) . unwrap ( ) ;
153
160
if !request. otp . contains ( otp_response) {
154
161
sender. send ( Response :: Signal ( Err ( YubicoError :: OTPMismatch ) ) ) . unwrap ( ) ;
162
+ return ;
155
163
}
156
164
157
165
// Check if "nonce" in the response is the same as the "nonce" supplied in the request.
158
166
let nonce_response : & str = & * response_map. get ( "nonce" ) . unwrap ( ) ;
159
167
if !request. nonce . contains ( nonce_response) {
160
168
sender. send ( Response :: Signal ( Err ( YubicoError :: NonceMismatch ) ) ) . unwrap ( ) ;
169
+ return ;
161
170
}
162
171
163
172
// Check the status of the operation
@@ -195,7 +204,6 @@ impl Yubico {
195
204
query. pop ( ) ; // remove last &
196
205
197
206
let signature = self . build_signature ( query. clone ( ) ) ;
198
-
199
207
let decoded_signature = & decode ( signature_response) . unwrap ( ) [ ..] ;
200
208
201
209
crypto:: util:: fixed_time_eq ( signature. code ( ) , decoded_signature)
0 commit comments