@@ -8,6 +8,7 @@ extern crate threadpool;
88
99pub mod yubicoerror;
1010
11+ use std:: ascii:: AsciiExt ;
1112use yubicoerror:: YubicoError ;
1213use hyper:: net:: HttpsConnector ;
1314use hyper_native_tls:: NativeTlsClient ;
@@ -62,15 +63,15 @@ impl Yubico {
6263 pub fn new ( client_id : String , key : String ) -> Self {
6364 Yubico {
6465 client_id : client_id,
65- key : decode ( key. as_ref ( ) ) . unwrap ( ) ,
66+ key : decode ( & key[ .. ] ) . unwrap ( ) ,
6667 }
6768 }
6869
6970 // Verify a provided OTP
7071 pub fn verify ( & self , otp : String ) -> Result < String > {
7172 match self . printable_characters ( otp. clone ( ) ) {
7273 false => Err ( YubicoError :: BadOTP ) ,
73- _ => {
74+ _ => {
7475 let nonce: String = self . generate_nonce ( ) ;
7576 let mut query = format ! ( "id={}&nonce={}&otp={}&sl=secure" , self . client_id, nonce, otp) ;
7677
@@ -133,7 +134,12 @@ impl Yubico {
133134
134135 // Recommendation is that clients only check that the input consists of 32-48 printable characters
135136 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
137143 }
138144
139145 fn process ( & self , sender : Sender < Response > , api_host : & str , request : Request ) {
@@ -146,18 +152,21 @@ impl Yubico {
146152 let signature_response : & str = & * response_map. get ( "h" ) . unwrap ( ) ;
147153 if !self . is_same_signature ( signature_response, response_map. clone ( ) ) {
148154 sender. send ( Response :: Signal ( Err ( YubicoError :: SignatureMismatch ) ) ) . unwrap ( ) ;
155+ return ;
149156 }
150157
151158 // Check if "otp" in the response is the same as the "otp" supplied in the request.
152159 let otp_response : & str = & * response_map. get ( "otp" ) . unwrap ( ) ;
153160 if !request. otp . contains ( otp_response) {
154161 sender. send ( Response :: Signal ( Err ( YubicoError :: OTPMismatch ) ) ) . unwrap ( ) ;
162+ return ;
155163 }
156164
157165 // Check if "nonce" in the response is the same as the "nonce" supplied in the request.
158166 let nonce_response : & str = & * response_map. get ( "nonce" ) . unwrap ( ) ;
159167 if !request. nonce . contains ( nonce_response) {
160168 sender. send ( Response :: Signal ( Err ( YubicoError :: NonceMismatch ) ) ) . unwrap ( ) ;
169+ return ;
161170 }
162171
163172 // Check the status of the operation
@@ -195,7 +204,6 @@ impl Yubico {
195204 query. pop ( ) ; // remove last &
196205
197206 let signature = self . build_signature ( query. clone ( ) ) ;
198-
199207 let decoded_signature = & decode ( signature_response) . unwrap ( ) [ ..] ;
200208
201209 crypto:: util:: fixed_time_eq ( signature. code ( ) , decoded_signature)
0 commit comments