# HG changeset patch # User weijun # Date 1277360795 -28800 # Node ID 076cd013e5e4a46024284f87b54df9c64478cf98 # Parent f0531b7dfebe79b91f6b57c3e970900b00dea434 6946669: SSL/Krb5 should not call EncryptedData.reset(data, false) Reviewed-by: xuelei diff -r f0531b7dfebe -r 076cd013e5e4 jdk/src/share/classes/sun/security/krb5/EncryptedData.java --- a/jdk/src/share/classes/sun/security/krb5/EncryptedData.java Thu Jun 24 14:26:28 2010 +0800 +++ b/jdk/src/share/classes/sun/security/krb5/EncryptedData.java Thu Jun 24 14:26:35 2010 +0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -336,38 +336,29 @@ } /** - * Reset data stream after decryption, remove redundant bytes. + * Reset asn.1 data stream after decryption, remove redundant bytes. * @param data the decrypted data from decrypt(). - * @param encoded true if the encrypted data is ASN1 encoded data, - * false if the encrypted data is not ASN1 encoded data. * @return the reset byte array which holds exactly one asn1 datum * including its tag and length. * */ - public byte[] reset(byte[] data, boolean encoded) { + public byte[] reset(byte[] data) { byte[] bytes = null; - // if it is encoded data, we use length field to + // for asn.1 encoded data, we use length field to // determine the data length and remove redundant paddings. - if (encoded) { - if ((data[1] & 0xFF) < 128) { - bytes = new byte[data[1] + 2]; - System.arraycopy(data, 0, bytes, 0, data[1] + 2); - } else - if ((data[1] & 0xFF) > 128) { - int len = data[1] & (byte)0x7F; - int result = 0; - for (int i = 0; i < len; i++) { - result |= (data[i + 2] & 0xFF) << (8 * (len - i - 1)); - } - bytes = new byte[result + len + 2]; - System.arraycopy(data, 0, bytes, 0, result + len + 2); + if ((data[1] & 0xFF) < 128) { + bytes = new byte[data[1] + 2]; + System.arraycopy(data, 0, bytes, 0, data[1] + 2); + } else { + if ((data[1] & 0xFF) > 128) { + int len = data[1] & (byte)0x7F; + int result = 0; + for (int i = 0; i < len; i++) { + result |= (data[i + 2] & 0xFF) << (8 * (len - i - 1)); } - } else { - // if it is not encoded, which happens in GSS tokens, - // we remove padding data according to padding pattern. - bytes = new byte[data.length - data[data.length - 1]]; - System.arraycopy(data, 0, bytes, 0, - data.length - data[data.length - 1]); + bytes = new byte[result + len + 2]; + System.arraycopy(data, 0, bytes, 0, result + len + 2); + } } return bytes; } diff -r f0531b7dfebe -r 076cd013e5e4 jdk/src/share/classes/sun/security/krb5/KrbApRep.java --- a/jdk/src/share/classes/sun/security/krb5/KrbApRep.java Thu Jun 24 14:26:28 2010 +0800 +++ b/jdk/src/share/classes/sun/security/krb5/KrbApRep.java Thu Jun 24 14:26:35 2010 +0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -130,7 +130,7 @@ byte[] temp = rep.encPart.decrypt(tgs_creds.key, KeyUsage.KU_ENC_AP_REP_PART); - byte[] enc_ap_rep_part = rep.encPart.reset(temp, true); + byte[] enc_ap_rep_part = rep.encPart.reset(temp); encoding = new DerValue(enc_ap_rep_part); encPart = new EncAPRepPart(encoding); diff -r f0531b7dfebe -r 076cd013e5e4 jdk/src/share/classes/sun/security/krb5/KrbApReq.java --- a/jdk/src/share/classes/sun/security/krb5/KrbApReq.java Thu Jun 24 14:26:28 2010 +0800 +++ b/jdk/src/share/classes/sun/security/krb5/KrbApReq.java Thu Jun 24 14:26:35 2010 +0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -279,14 +279,14 @@ byte[] bytes = apReqMessg.ticket.encPart.decrypt(dkey, KeyUsage.KU_TICKET); - byte[] temp = apReqMessg.ticket.encPart.reset(bytes, true); + byte[] temp = apReqMessg.ticket.encPart.reset(bytes); EncTicketPart enc_ticketPart = new EncTicketPart(temp); checkPermittedEType(enc_ticketPart.key.getEType()); byte[] bytes2 = apReqMessg.authenticator.decrypt(enc_ticketPart.key, KeyUsage.KU_AP_REQ_AUTHENTICATOR); - byte[] temp2 = apReqMessg.authenticator.reset(bytes2, true); + byte[] temp2 = apReqMessg.authenticator.reset(bytes2); authenticator = new Authenticator(temp2); ctime = authenticator.ctime; cusec = authenticator.cusec; diff -r f0531b7dfebe -r 076cd013e5e4 jdk/src/share/classes/sun/security/krb5/KrbAsRep.java --- a/jdk/src/share/classes/sun/security/krb5/KrbAsRep.java Thu Jun 24 14:26:28 2010 +0800 +++ b/jdk/src/share/classes/sun/security/krb5/KrbAsRep.java Thu Jun 24 14:26:35 2010 +0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -95,7 +95,7 @@ byte[] enc_as_rep_bytes = rep.encPart.decrypt(dkey, KeyUsage.KU_ENC_AS_REP_PART); - byte[] enc_as_rep_part = rep.encPart.reset(enc_as_rep_bytes, true); + byte[] enc_as_rep_part = rep.encPart.reset(enc_as_rep_bytes); encoding = new DerValue(enc_as_rep_part); EncASRepPart enc_part = new EncASRepPart(encoding); diff -r f0531b7dfebe -r 076cd013e5e4 jdk/src/share/classes/sun/security/krb5/KrbCred.java --- a/jdk/src/share/classes/sun/security/krb5/KrbCred.java Thu Jun 24 14:26:28 2010 +0800 +++ b/jdk/src/share/classes/sun/security/krb5/KrbCred.java Thu Jun 24 14:26:35 2010 +0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -130,7 +130,7 @@ byte[] temp = credMessg.encPart.decrypt(key, KeyUsage.KU_ENC_KRB_CRED_PART); - byte[] plainText = credMessg.encPart.reset(temp, true); + byte[] plainText = credMessg.encPart.reset(temp); DerValue encoding = new DerValue(plainText); EncKrbCredPart encPart = new EncKrbCredPart(encoding); diff -r f0531b7dfebe -r 076cd013e5e4 jdk/src/share/classes/sun/security/krb5/KrbPriv.java --- a/jdk/src/share/classes/sun/security/krb5/KrbPriv.java Thu Jun 24 14:26:28 2010 +0800 +++ b/jdk/src/share/classes/sun/security/krb5/KrbPriv.java Thu Jun 24 14:26:35 2010 +0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,6 @@ package sun.security.krb5; -import sun.security.krb5.EncryptionKey; import sun.security.krb5.internal.*; import sun.security.krb5.internal.crypto.*; import sun.security.util.*; @@ -159,7 +158,7 @@ byte[] bytes = krb_priv.encPart.decrypt(key, KeyUsage.KU_ENC_KRB_PRIV_PART); - byte[] temp = krb_priv.encPart.reset(bytes, true); + byte[] temp = krb_priv.encPart.reset(bytes); DerValue ref = new DerValue(temp); EncKrbPrivPart enc_part = new EncKrbPrivPart(ref); diff -r f0531b7dfebe -r 076cd013e5e4 jdk/src/share/classes/sun/security/krb5/KrbTgsRep.java --- a/jdk/src/share/classes/sun/security/krb5/KrbTgsRep.java Thu Jun 24 14:26:28 2010 +0800 +++ b/jdk/src/share/classes/sun/security/krb5/KrbTgsRep.java Thu Jun 24 14:26:35 2010 +0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,7 +79,7 @@ tgsReq.usedSubkey() ? KeyUsage.KU_ENC_TGS_REP_PART_SUBKEY : KeyUsage.KU_ENC_TGS_REP_PART_SESSKEY); - byte[] enc_tgs_rep_part = rep.encPart.reset(enc_tgs_rep_bytes, true); + byte[] enc_tgs_rep_part = rep.encPart.reset(enc_tgs_rep_bytes); ref = new DerValue(enc_tgs_rep_part); EncTGSRepPart enc_part = new EncTGSRepPart(ref); rep.ticket.sname.setRealm(rep.ticket.realm); diff -r f0531b7dfebe -r 076cd013e5e4 jdk/src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java --- a/jdk/src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java Thu Jun 24 14:26:28 2010 +0800 +++ b/jdk/src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java Thu Jun 24 14:26:35 2010 +0800 @@ -212,7 +212,7 @@ byte[] bytes = encPart.decrypt(secretKey, KeyUsage.KU_TICKET); // Reset data stream after decryption, remove redundant bytes - byte[] temp = encPart.reset(bytes, true); + byte[] temp = encPart.reset(bytes); EncTicketPart encTicketPart = new EncTicketPart(temp); // Record the Kerberos Principals diff -r f0531b7dfebe -r 076cd013e5e4 jdk/src/share/classes/sun/security/ssl/krb5/KerberosPreMasterSecret.java --- a/jdk/src/share/classes/sun/security/ssl/krb5/KerberosPreMasterSecret.java Thu Jun 24 14:26:28 2010 +0800 +++ b/jdk/src/share/classes/sun/security/ssl/krb5/KerberosPreMasterSecret.java Thu Jun 24 14:26:35 2010 +0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ import java.io.*; import java.security.*; -import java.security.interfaces.*; +import java.util.Arrays; import javax.net.ssl.*; @@ -128,8 +128,8 @@ "are not supported for TLS Kerberos cipher suites"); } - // Decrypt premaster secret - try { + // Decrypt premaster secret + try { EncryptedData data = new EncryptedData(sessionKey.getEType(), null /* optional kvno */, encrypted); @@ -141,8 +141,25 @@ } } - // Reset data stream after decryption, remove redundant bytes - preMaster = data.reset(temp, false); + // Remove padding bytes after decryption. Only DES and DES3 have + // paddings and we don't support DES3 in TLS (see above) + + if (temp.length == 52 && + data.getEType() == EncryptedData.ETYPE_DES_CBC_CRC) { + // For des-cbc-crc, 4 paddings. Value can be 0x04 or 0x00. + if (paddingByteIs(temp, 52, (byte)4) || + paddingByteIs(temp, 52, (byte)0)) { + temp = Arrays.copyOf(temp, 48); + } + } else if (temp.length == 56 && + data.getEType() == EncryptedData.ETYPE_DES_CBC_MD5) { + // For des-cbc-md5, 8 paddings with 0x08, or no padding + if (paddingByteIs(temp, 56, (byte)8)) { + temp = Arrays.copyOf(temp, 48); + } + } + + preMaster = temp; protocolVersion = ProtocolVersion.valueOf(preMaster[0], preMaster[1]); @@ -191,6 +208,19 @@ } } + /** + * Checks if all paddings of data are b + * @param data the block with padding + * @param len length of data, >= 48 + * @param b expected padding byte + */ + private static boolean paddingByteIs(byte[] data, int len, byte b) { + for (int i=48; i