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

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


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

commit e9c20e63dc1694dbc5e116e4c9e82190aa81320a
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
---
 .../org/apache/wss4j/common/util/UsernameTokenUtil.java  | 10 ++++++----
 .../wss4j/dom/validate/UsernameTokenValidator.java       | 16 +++++++++++-----
 .../wss4j/stax/validate/UsernameTokenValidatorImpl.java  | 13 ++++++++++---
 3 files changed, 27 insertions(+), 12 deletions(-)

diff --git 
a/ws-security-common/src/main/java/org/apache/wss4j/common/util/UsernameTokenUtil.java
 
b/ws-security-common/src/main/java/org/apache/wss4j/common/util/UsernameTokenUtil.java
index c88e5d5..9988278 100644
--- 
a/ws-security-common/src/main/java/org/apache/wss4j/common/util/UsernameTokenUtil.java
+++ 
b/ws-security-common/src/main/java/org/apache/wss4j/common/util/UsernameTokenUtil.java
@@ -152,7 +152,11 @@ public final class UsernameTokenUtil {
     }
 
     public static String doPasswordDigest(byte[] nonce, String created, byte[] 
password) throws WSSecurityException {
-        String passwdDigest = null;
+        byte[] digestBytes = doRawPasswordDigest(nonce, created, password);
+        return 
org.apache.xml.security.utils.XMLUtils.encodeToString(digestBytes);
+    }
+
+    public static byte[] doRawPasswordDigest(byte[] nonce, String created, 
byte[] password) throws WSSecurityException {
         try {
             byte[] b1 = nonce != null ? nonce : new byte[0];
             byte[] b2 = created != null ? 
created.getBytes(StandardCharsets.UTF_8) : new byte[0];
@@ -167,13 +171,11 @@ public final class UsernameTokenUtil {
 
             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);
             throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e, 
"decoding.general");
         }
-        return passwdDigest;
     }
 
     /**
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 4c9717a..a3a0d3c 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;
@@ -166,19 +168,23 @@ public class UsernameTokenValidator implements Validator {
             throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
         }
         if (usernameToken.isHashed()) {
-            String passDigest;
             byte[] decodedNonce = XMLUtils.decode(nonce);
+            byte[] decodedPassword = XMLUtils.decode(password);
+            byte[] passDigest;
             if (passwordsAreEncoded) {
-                passDigest = UsernameTokenUtil.doPasswordDigest(decodedNonce, 
createdTime,
+                passDigest = 
UsernameTokenUtil.doRawPasswordDigest(decodedNonce, createdTime,
                                                             
XMLUtils.decode(origPassword));
             } else {
-                passDigest = UsernameTokenUtil.doPasswordDigest(decodedNonce, 
createdTime, origPassword);
+                passDigest = 
UsernameTokenUtil.doRawPasswordDigest(decodedNonce, 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/validate/UsernameTokenValidatorImpl.java
 
b/ws-security-stax/src/main/java/org/apache/wss4j/stax/validate/UsernameTokenValidatorImpl.java
index 42b75e5..916fca9 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;
@@ -180,8 +183,10 @@ public class UsernameTokenValidatorImpl implements 
UsernameTokenValidator {
             throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
         }
 
-        String passDigest = UsernameTokenUtil.doPasswordDigest(nonceVal, 
created, pwCb.getPassword());
-        if (!passwordType.getValue().equals(passDigest)) {
+        byte[] passDigest = UsernameTokenUtil.doRawPasswordDigest(nonceVal, 
created,
+                pwCb.getPassword().getBytes(StandardCharsets.UTF_8));
+        byte[] decodedPassword = XMLUtils.decode(passwordType.getValue());
+        if (!MessageDigest.isEqual(decodedPassword, passDigest)) {
             throw new 
WSSecurityException(WSSecurityException.ErrorCode.FAILED_AUTHENTICATION);
         }
         passwordType.setValue(pwCb.getPassword());
@@ -209,7 +214,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