52
52
import java .util .HashMap ;
53
53
import java .util .Collections ;
54
54
import java .util .ResourceBundle ;
55
+ import java .security .MessageDigest ;
55
56
import javax .security .auth .Subject ;
56
57
import javax .security .auth .callback .Callback ;
57
58
import javax .security .auth .callback .PasswordCallback ;
@@ -516,7 +517,7 @@ private boolean checkOTP(String otp) throws AuthLoginException {
516
517
passLen ,
517
518
checksum ,
518
519
truncationOffset );
519
- if (otpGen . equals ( otp )) {
520
+ if (isEqual ( otpGen , otp )) {
520
521
//OTP is correct set the counter value to counter+i
521
522
setCounterAttr (id , counter + i );
522
523
return true ;
@@ -584,6 +585,11 @@ private boolean checkOTP(String otp) throws AuthLoginException {
584
585
long localTime = time ;
585
586
localTime /= totpTimeStep ;
586
587
588
+ if (lastLoginTime == localTime ){
589
+ debug .error ("OATH.checkOTP(): Login failed attempting to use the same OTP in same Time Step: " + localTime );
590
+ throw new InvalidPasswordException (amAuthOATH , "authFailed" , null , userName , null );
591
+ }
592
+
587
593
boolean sameWindow = false ;
588
594
589
595
//check if we are in the time window to prevent 2
@@ -603,7 +609,7 @@ private boolean checkOTP(String otp) throws AuthLoginException {
603
609
otpGen = TOTPAlgorithm .generateTOTP (secretKey ,
604
610
Long .toHexString (localTime ),
605
611
passLenStr );
606
- if (otpGen . equals ( otp )) {
612
+ if (isEqual ( otpGen , otp )) {
607
613
setLoginTime (id , localTime );
608
614
return true ;
609
615
}
@@ -616,7 +622,7 @@ private boolean checkOTP(String otp) throws AuthLoginException {
616
622
otpGen = TOTPAlgorithm .generateTOTP (secretKey ,
617
623
Long .toHexString (time1 ),
618
624
passLenStr );
619
- if (otpGen . equals ( otp )) {
625
+ if (isEqual ( otpGen , otp )) {
620
626
setLoginTime (id , time1 );
621
627
return true ;
622
628
}
@@ -626,12 +632,12 @@ private boolean checkOTP(String otp) throws AuthLoginException {
626
632
otpGen = TOTPAlgorithm .generateTOTP (secretKey ,
627
633
Long .toHexString (time2 ),
628
634
passLenStr );
629
- if (otpGen . equals ( otp ) && sameWindow ){
635
+ if (isEqual ( otpGen , otp ) && sameWindow ) {
630
636
debug .error ("OATH" +
631
637
".checkOTP() : " +
632
- "Loging in in the same window with a OTP that is older than the current times OTP" );
638
+ "Login the same window with a OTP that is older than the current OTP" );
633
639
return false ;
634
- } else if ( otpGen . equals ( otp ) && !sameWindow ) {
640
+ } else if ( isEqual ( otpGen , otp ) && !sameWindow ) {
635
641
setLoginTime (id , time2 );
636
642
return true ;
637
643
}
@@ -769,4 +775,16 @@ private void setLoginTime(AMIdentity id, long time)
769
775
}
770
776
return ;
771
777
}
778
+
779
+ /**
780
+ * Perform time constant equality check.
781
+ * Both values should not be null.
782
+ *
783
+ * @param str1 first value
784
+ * @param str2 second vale
785
+ * @return true if values are equal
786
+ */
787
+ private boolean isEqual (String str1 , String str2 ) {
788
+ return MessageDigest .isEqual (str1 .getBytes (StandardCharsets .UTF_8 ), str2 .getBytes (StandardCharsets .UTF_8 ));
789
+ }
772
790
}
0 commit comments