aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorweijun <unknown>2019-07-03 11:43:01 +0800
committerbell-sw <liberica@bell-sw.com>2020-01-19 09:13:15 +0300
commitd0914d0650d253ef64088b9cabf830100407e725 (patch)
tree7528499b3de21012d29239a4f9ce760db3d4d437
parent60a534034e3f10ff6f6b0da2e6a83e90f3a8316b (diff)
downloadjdk8u_jdk-d0914d0650d253ef64088b9cabf830100407e725.tar.gz
8226719: Kerberos login to Windows 2000 failed with "Inappropriate type of checksum in message"
Reviewed-by: xuelei
-rw-r--r--src/share/classes/sun/security/krb5/Checksum.java20
-rw-r--r--src/share/classes/sun/security/krb5/KrbKdcRep.java4
-rw-r--r--src/share/classes/sun/security/krb5/internal/crypto/CksumType.java5
-rw-r--r--src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java10
4 files changed, 38 insertions, 1 deletions
diff --git a/src/share/classes/sun/security/krb5/Checksum.java b/src/share/classes/sun/security/krb5/Checksum.java
index 377a07b973..f0fa577fc1 100644
--- a/src/share/classes/sun/security/krb5/Checksum.java
+++ b/src/share/classes/sun/security/krb5/Checksum.java
@@ -193,6 +193,26 @@ public class Checksum {
usage);
}
+ // =============== ATTENTION! Use with care ==================
+ // According to https://tools.ietf.org/html/rfc3961#section-6.1,
+ // An unkeyed checksum should only be used "in limited circumstances
+ // where the lack of a key does not provide a window for an attack,
+ // preferably as part of an encrypted message".
+ public boolean verifyAnyChecksum(byte[] data, EncryptionKey key,
+ int usage)
+ throws KdcErrException, KrbCryptoException {
+ CksumType cksumEngine = CksumType.getInstance(cksumType);
+ if (!cksumEngine.isSafe()) {
+ return cksumEngine.verifyChecksum(data, checksum);
+ } else {
+ return cksumEngine.verifyKeyedChecksum(data,
+ data.length,
+ key.getBytes(),
+ checksum,
+ usage);
+ }
+ }
+
/*
public Checksum(byte[] data) throws KdcErrException, KrbCryptoException {
this(Checksum.CKSUMTYPE_DEFAULT, data);
diff --git a/src/share/classes/sun/security/krb5/KrbKdcRep.java b/src/share/classes/sun/security/krb5/KrbKdcRep.java
index 6ecf00b492..7dc21cd21c 100644
--- a/src/share/classes/sun/security/krb5/KrbKdcRep.java
+++ b/src/share/classes/sun/security/krb5/KrbKdcRep.java
@@ -143,8 +143,10 @@ abstract class KrbKdcRep {
Checksum repCksum = new Checksum(
new DerInputStream(
pa.getValue()).getDerValue());
+ // The checksum is inside encKDCRepPart so we don't
+ // care if it's keyed or not.
repPaReqEncPaRepValid =
- repCksum.verifyKeyedChecksum(
+ repCksum.verifyAnyChecksum(
req.asn1Encode(), replyKey,
KeyUsage.KU_AS_REQ);
} catch (Exception e) {
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java b/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java
index 83256927e7..4e912ce80a 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/CksumType.java
@@ -156,6 +156,11 @@ public abstract class CksumType {
public abstract byte[] calculateKeyedChecksum(byte[] data, int size,
byte[] key, int usage) throws KrbCryptoException;
+ public boolean verifyChecksum(byte[] data, byte[] checksum)
+ throws KrbCryptoException {
+ throw new UnsupportedOperationException("Not supported");
+ }
+
public abstract boolean verifyKeyedChecksum(byte[] data, int size,
byte[] key, byte[] checksum, int usage) throws KrbCryptoException;
diff --git a/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java b/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java
index c475749bfa..8a4d324524 100644
--- a/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java
+++ b/src/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java
@@ -101,4 +101,14 @@ public final class RsaMd5CksumType extends CksumType {
return false;
}
+ @Override
+ public boolean verifyChecksum(byte[] data, byte[] checksum)
+ throws KrbCryptoException {
+ try {
+ byte[] calculated = MessageDigest.getInstance("MD5").digest(data);
+ return CksumType.isChecksumEqual(calculated, checksum);
+ } catch (Exception e) {
+ return false;
+ }
+ }
}