This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/8.5.x by this push:
new d93a0c2 Correct Javadoc and refactor code for clarity
d93a0c2 is described below
commit d93a0c201d924035a7ca6e8efebc84ae0007bada
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Aug 19 15:56:09 2020 +0100
Correct Javadoc and refactor code for clarity
Based on a PR by Milo van der Zee
---
.../realm/MessageDigestCredentialHandler.java | 57 ++++++++++------------
webapps/docs/changelog.xml | 6 +++
2 files changed, 31 insertions(+), 32 deletions(-)
diff --git a/java/org/apache/catalina/realm/MessageDigestCredentialHandler.java
b/java/org/apache/catalina/realm/MessageDigestCredentialHandler.java
index 720fc0e..616e0e5 100644
--- a/java/org/apache/catalina/realm/MessageDigestCredentialHandler.java
+++ b/java/org/apache/catalina/realm/MessageDigestCredentialHandler.java
@@ -38,8 +38,9 @@ import
org.apache.tomcat.util.security.ConcurrentMessageDigest;
* password</li>
* <li><b>{SHA}encodedCredential</b> - a Base64 encoded SHA1 digest of the
* password</li>
- * <li><b>{SSHA}encodedCredential</b> - 20 character salt followed by the
salted
- * SHA1 digest Base64 encoded</li>
+ * <li><b>{SSHA}encodedCredential</b> - 20 byte Base64 encoded SHA1 digest
+ * followed by variable length salt.
+ * <pre>{SSHA}<sha-1 digest:20><salt:n></pre></li>
* <li><b>salt$iterationCount$encodedCredential</b> - a hex encoded salt,
* iteration code and a hex encoded credential, each separated by $</li>
* </ul>
@@ -72,8 +73,7 @@ public class MessageDigestCredentialHandler extends
DigestCredentialHandlerBase
try {
this.encoding = B2CConverter.getCharset(encodingName);
} catch (UnsupportedEncodingException e) {
- log.warn(sm.getString("mdCredentialHandler.unknownEncoding",
- encodingName, encoding.name()));
+ log.error(sm.getString("mdCredentialHandler.unknownEncoding",
encodingName, encoding.name()));
}
}
}
@@ -94,7 +94,6 @@ public class MessageDigestCredentialHandler extends
DigestCredentialHandlerBase
@Override
public boolean matches(String inputCredentials, String storedCredentials) {
-
if (inputCredentials == null || storedCredentials == null) {
return false;
}
@@ -106,33 +105,30 @@ public class MessageDigestCredentialHandler extends
DigestCredentialHandlerBase
// Some directories and databases prefix the password with the hash
// type. The string is in a format compatible with Base64.encode
not
// the normal hex encoding of the digest
- if (storedCredentials.startsWith("{MD5}") ||
- storedCredentials.startsWith("{SHA}")) {
+ if (storedCredentials.startsWith("{MD5}") ||
storedCredentials.startsWith("{SHA}")) {
// Server is storing digested passwords with a prefix
indicating
// the digest type
- String serverDigest = storedCredentials.substring(5);
- String userDigest =
Base64.encodeBase64String(ConcurrentMessageDigest.digest(
- getAlgorithm(),
inputCredentials.getBytes(StandardCharsets.ISO_8859_1)));
- return userDigest.equals(serverDigest);
-
+ String base64ServerDigest = storedCredentials.substring(5);
+ byte[] userDigest = ConcurrentMessageDigest.digest(
+ getAlgorithm(),
inputCredentials.getBytes(StandardCharsets.ISO_8859_1));
+ String base64UserDigest =
Base64.encodeBase64String(userDigest);
+ return base64UserDigest.equals(base64ServerDigest);
} else if (storedCredentials.startsWith("{SSHA}")) {
- // Server is storing digested passwords with a prefix
indicating
- // the digest type and the salt used when creating that digest
-
- String serverDigestPlusSalt = storedCredentials.substring(6);
-
+ // "{SSHA}<sha-1 digest:20><salt:n>"
// Need to convert the salt to bytes to apply it to the user's
// digested password.
- byte[] serverDigestPlusSaltBytes =
- Base64.decodeBase64(serverDigestPlusSalt);
- final int saltPos = 20;
- byte[] serverDigestBytes = new byte[saltPos];
- System.arraycopy(serverDigestPlusSaltBytes, 0,
- serverDigestBytes, 0, saltPos);
- final int saltLength = serverDigestPlusSaltBytes.length -
saltPos;
+ String serverDigestPlusSalt = storedCredentials.substring(6);
+ byte[] serverDigestPlusSaltBytes =
Base64.decodeBase64(serverDigestPlusSalt);
+
+ // Extract the first 20 bytes containing the SHA-1 digest
+ final int digestLength = 20;
+ byte[] serverDigestBytes = new byte[digestLength];
+ System.arraycopy(serverDigestPlusSaltBytes, 0,
serverDigestBytes, 0, digestLength);
+
+ // the remaining bytes are the salt
+ final int saltLength = serverDigestPlusSaltBytes.length -
digestLength;
byte[] serverSaltBytes = new byte[saltLength];
- System.arraycopy(serverDigestPlusSaltBytes, saltPos,
- serverSaltBytes, 0, saltLength);
+ System.arraycopy(serverDigestPlusSaltBytes, digestLength,
serverSaltBytes, 0, saltLength);
// Generate the digested form of the user provided password
// using the salt
@@ -141,10 +137,8 @@ public class MessageDigestCredentialHandler extends
DigestCredentialHandlerBase
serverSaltBytes);
return Arrays.equals(userDigestBytes, serverDigestBytes);
-
} else if (storedCredentials.indexOf('$') > -1) {
return matchesSaltIterationsEncoded(inputCredentials,
storedCredentials);
-
} else {
// Hex hashes should be compared case-insensitively
String userDigest = mutate(inputCredentials, null, 1);
@@ -164,13 +158,12 @@ public class MessageDigestCredentialHandler extends
DigestCredentialHandlerBase
if (algorithm == null) {
return inputCredentials;
} else {
+ byte[] inputCredentialbytes = inputCredentials.getBytes(encoding);
byte[] userDigest;
if (salt == null) {
- userDigest = ConcurrentMessageDigest.digest(algorithm,
iterations,
- inputCredentials.getBytes(encoding));
+ userDigest = ConcurrentMessageDigest.digest(algorithm,
iterations, inputCredentialbytes);
} else {
- userDigest = ConcurrentMessageDigest.digest(algorithm,
iterations,
- salt, inputCredentials.getBytes(encoding));
+ userDigest = ConcurrentMessageDigest.digest(algorithm,
iterations, salt, inputCredentialbytes);
}
return HexUtils.toHexString(userDigest);
}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index fb57417..da9ecf0 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -76,6 +76,12 @@
the requested resource. Based on a pull request by Sergey Ponomarev.
(markt)
</fix>
+ <fix>
+ Correct the description of the storage format for salted hashes in the
+ Javadoc for <code>MessageDigestCredentialHandler</code> and refactor
the
+ associated code for clarity.
+ Based on a patch provided by Milo van der Zee. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]