# HG changeset patch # User weijun # Date 1562125381 -28800 # Node ID 1e95931e7d8fa7e3899340a9c7cb28dbea50c10c # Parent 8e3a0ebf34972365e15109627d6ad6874787a4b6 8226719: Kerberos login to Windows 2000 failed with "Inappropriate type of checksum in message" Reviewed-by: xuelei diff -r 8e3a0ebf3497 -r 1e95931e7d8f src/java.security.jgss/share/classes/sun/security/krb5/Checksum.java --- a/src/java.security.jgss/share/classes/sun/security/krb5/Checksum.java Tue Jul 02 18:24:47 2019 -0400 +++ b/src/java.security.jgss/share/classes/sun/security/krb5/Checksum.java Wed Jul 03 11:43:01 2019 +0800 @@ -197,6 +197,26 @@ 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 -r 8e3a0ebf3497 -r 1e95931e7d8f src/java.security.jgss/share/classes/sun/security/krb5/KrbKdcRep.java --- a/src/java.security.jgss/share/classes/sun/security/krb5/KrbKdcRep.java Tue Jul 02 18:24:47 2019 -0400 +++ b/src/java.security.jgss/share/classes/sun/security/krb5/KrbKdcRep.java Wed Jul 03 11:43:01 2019 +0800 @@ -158,8 +158,10 @@ 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 -r 8e3a0ebf3497 -r 1e95931e7d8f src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/CksumType.java --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/CksumType.java Tue Jul 02 18:24:47 2019 -0400 +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/CksumType.java Wed Jul 03 11:43:01 2019 +0800 @@ -156,6 +156,11 @@ 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 -r 8e3a0ebf3497 -r 1e95931e7d8f src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java Tue Jul 02 18:24:47 2019 -0400 +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java Wed Jul 03 11:43:01 2019 +0800 @@ -101,4 +101,14 @@ 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; + } + } }