This is an automated email from the ASF dual-hosted git repository.

coheigea pushed a commit to branch 2_2_x-fixes
in repository https://gitbox.apache.org/repos/asf/ws-wss4j.git


The following commit(s) were added to refs/heads/2_2_x-fixes by this push:
     new cc11b9b  WSS-677 - Switch to using MessageDigest.isEqual() to compare 
passwords
cc11b9b is described below

commit cc11b9bd912b6d2640309e39247eb06930c84676
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Tue Aug 18 11:34:02 2020 +0100

    WSS-677 - Switch to using MessageDigest.isEqual() to compare passwords
---
 .../apache/wss4j/dom/message/token/UsernameToken.java    | 11 +++++++----
 .../wss4j/dom/validate/UsernameTokenValidator.java       | 16 +++++++++++-----
 .../main/java/org/apache/wss4j/stax/utils/WSSUtils.java  |  7 ++++++-
 .../wss4j/stax/validate/UsernameTokenValidatorImpl.java  | 13 ++++++++++---
 4 files changed, 34 insertions(+), 13 deletions(-)

diff --git 
a/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/UsernameToken.java
 
b/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/UsernameToken.java
index 7c0bb0d..9d33f2f 100644
--- 
a/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/UsernameToken.java
+++ 
b/ws-security-dom/src/main/java/org/apache/wss4j/dom/message/token/UsernameToken.java
@@ -565,7 +565,11 @@ public class UsernameToken {
     }
 
     public static String doPasswordDigest(String nonce, String created, byte[] 
password) {
-        String passwdDigest = null;
+        byte[] digestBytes = doRawPasswordDigest(nonce, created, password);
+        return digestBytes != null ? 
org.apache.xml.security.utils.XMLUtils.encodeToString(digestBytes) : null;
+    }
+
+    public static byte[] doRawPasswordDigest(String nonce, String created, 
byte[] password) {
         try {
             byte[] b1 = nonce != null ? 
org.apache.xml.security.utils.XMLUtils.decode(nonce) : new byte[0];
             byte[] b2 = created != null ? 
created.getBytes(StandardCharsets.UTF_8) : new byte[0];
@@ -580,12 +584,11 @@ public class UsernameToken {
 
             System.arraycopy(b3, 0, b4, offset, b3.length);
 
-            byte[] digestBytes = KeyUtils.generateDigest(b4);
-            passwdDigest = 
org.apache.xml.security.utils.XMLUtils.encodeToString(digestBytes);
+            return KeyUtils.generateDigest(b4);
         } catch (Exception e) {
             LOG.debug(e.getMessage(), e);
         }
-        return passwdDigest;
+        return null;
     }
 
     public static String doPasswordDigest(String nonce, String created, String 
password) {
diff --git 
a/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/UsernameTokenValidator.java
 
b/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/UsernameTokenValidator.java
index fd1320d..6ea8467 100644
--- 
a/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/UsernameTokenValidator.java
+++ 
b/ws-security-dom/src/main/java/org/apache/wss4j/dom/validate/UsernameTokenValidator.java
@@ -20,6 +20,8 @@
 package org.apache.wss4j.dom.validate;
 
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
 
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.UnsupportedCallbackException;
@@ -165,18 +167,22 @@ public class UsernameTokenValidator implements Validator {
             throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
         }
         if (usernameToken.isHashed()) {
-            String passDigest;
+            byte[] decodedPassword = XMLUtils.decode(password);
+            byte[] passDigest;
             if (passwordsAreEncoded) {
-                passDigest = UsernameToken.doPasswordDigest(nonce, createdTime,
+                passDigest = UsernameToken.doRawPasswordDigest(nonce, 
createdTime,
                                                             
XMLUtils.decode(origPassword));
             } else {
-                passDigest = UsernameToken.doPasswordDigest(nonce, 
createdTime, origPassword);
+                passDigest = UsernameToken.doRawPasswordDigest(nonce, 
createdTime,
+                        origPassword.getBytes(StandardCharsets.UTF_8));
             }
-            if (!passDigest.equals(password)) {
+            if (!MessageDigest.isEqual(decodedPassword, passDigest)) {
                 throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
             }
         } else {
-            if (!origPassword.equals(password)) {
+            byte[] origPasswordBytes = 
origPassword.getBytes(StandardCharsets.UTF_8);
+            byte[] passwordBytes = password.getBytes(StandardCharsets.UTF_8);
+            if (!MessageDigest.isEqual(origPasswordBytes, passwordBytes)) {
                 throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
             }
         }
diff --git 
a/ws-security-stax/src/main/java/org/apache/wss4j/stax/utils/WSSUtils.java 
b/ws-security-stax/src/main/java/org/apache/wss4j/stax/utils/WSSUtils.java
index 67e26d6..0213b5a 100644
--- a/ws-security-stax/src/main/java/org/apache/wss4j/stax/utils/WSSUtils.java
+++ b/ws-security-stax/src/main/java/org/apache/wss4j/stax/utils/WSSUtils.java
@@ -114,6 +114,11 @@ public class WSSUtils extends XMLSecurityUtils {
     }
 
     public static String doPasswordDigest(byte[] nonce, String created, String 
password) throws WSSecurityException {
+        byte[] digest = doRawPasswordDigest(nonce, created, password);
+        return XMLUtils.encodeToString(digest);
+    }
+
+    public static byte[] doRawPasswordDigest(byte[] nonce, String created, 
String password) throws WSSecurityException {
         try {
             byte[] b1 = nonce != null ? nonce : new byte[0];
             byte[] b2 = created != null ? 
created.getBytes(StandardCharsets.UTF_8) : new byte[0];
@@ -131,7 +136,7 @@ public class WSSUtils extends XMLSecurityUtils {
             MessageDigest sha = MessageDigest.getInstance("SHA-1");
             sha.reset();
             sha.update(b4);
-            return XMLUtils.encodeToString(sha.digest());
+            return sha.digest();
         } catch (NoSuchAlgorithmException e) {
             throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e, 
"decoding.general");
         }
diff --git 
a/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/UsernameTokenValidatorImpl.java
 
b/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/UsernameTokenValidatorImpl.java
index f72609f..acf9e1b 100644
--- 
a/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/UsernameTokenValidatorImpl.java
+++ 
b/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/UsernameTokenValidatorImpl.java
@@ -18,6 +18,9 @@
  */
 package org.apache.wss4j.stax.validate;
 
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+
 import org.apache.wss4j.binding.wss10.AttributedString;
 import org.apache.wss4j.binding.wss10.EncodedString;
 import org.apache.wss4j.binding.wss10.PasswordString;
@@ -179,8 +182,10 @@ public class UsernameTokenValidatorImpl implements 
UsernameTokenValidator {
             throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
         }
 
-        String passDigest = WSSUtils.doPasswordDigest(nonceVal, created, 
pwCb.getPassword());
-        if (!passwordType.getValue().equals(passDigest)) {
+
+        byte[] passDigest = WSSUtils.doRawPasswordDigest(nonceVal, created, 
pwCb.getPassword());
+        byte[] decodedPassword = XMLUtils.decode(passwordType.getValue());
+        if (!MessageDigest.isEqual(decodedPassword, passDigest)) {
             throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
         }
         passwordType.setValue(pwCb.getPassword());
@@ -208,7 +213,9 @@ public class UsernameTokenValidatorImpl implements 
UsernameTokenValidator {
             throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
         }
 
-        if (!passwordType.getValue().equals(pwCb.getPassword())) {
+        byte[] origPasswordBytes = 
pwCb.getPassword().getBytes(StandardCharsets.UTF_8);
+        byte[] passwordBytes = 
passwordType.getValue().getBytes(StandardCharsets.UTF_8);
+        if (!MessageDigest.isEqual(origPasswordBytes, passwordBytes)) {
             throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
         }
         passwordType.setValue(pwCb.getPassword());

Reply via email to