diff --git a/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java b/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java index d76a58bc06e1bdeb601c1885ce9764627c7869c0..5dbce5b5dd367d4774323db2843c78af862a41d3 100644 --- a/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java +++ b/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java @@ -233,7 +233,6 @@ abstract class MessageToken_v2 extends Krb5Token { } if (tokenId == Krb5Token.WRAP_ID_v2) { - // Does non-confidential data needs a rotate? rotate(); } @@ -421,10 +420,12 @@ abstract class MessageToken_v2 extends Krb5Token { int conf_flag = tokenHeaderBytes[TOKEN_FLAG_POS] & FLAG_WRAP_CONFIDENTIAL; - // clear EC in token header for checksum calculation + // clear EC and RRC in token header for checksum calculation if ((conf_flag == 0) && (tokenId == WRAP_ID_v2)) { tokenHeaderBytes[4] = 0; tokenHeaderBytes[5] = 0; + tokenHeaderBytes[6] = 0; + tokenHeaderBytes[7] = 0; } return cipherHelper.calculateChecksum(tokenHeaderBytes, data, offset, len, key_usage); diff --git a/test/sun/security/krb5/auto/Context.java b/test/sun/security/krb5/auto/Context.java index 1739f876f08714b4c626ab550a63856b027110e6..eb2a94a1e7d99d38e7b959317b2107b07bd634f7 100644 --- a/test/sun/security/krb5/auto/Context.java +++ b/test/sun/security/krb5/auto/Context.java @@ -375,44 +375,34 @@ public class Context { } } - /** - * Transmits a message from one Context to another. The sender wraps the - * message and sends it to the receiver. The receiver unwraps it, creates - * a MIC of the clear text and sends it back to the sender. The sender - * verifies the MIC against the message sent earlier. - * @param message the message - * @param s1 the sender - * @param s2 the receiver - * @throws java.lang.Exception If anything goes wrong - */ - static public void transmit(final String message, final Context s1, - final Context s2) throws Exception { - final byte[] messageBytes = message.getBytes(); - System.out.printf("-------------------- TRANSMIT from %s to %s------------------------\n", - s1.name, s2.name); - - byte[] t = s1.doAs(new Action() { + public byte[] wrap(byte[] t, final boolean privacy) + throws Exception { + return doAs(new Action() { @Override - public byte[] run(Context me, byte[] dummy) throws Exception { - System.out.println("wrap"); - MessageProp p1 = new MessageProp(0, true); + public byte[] run(Context me, byte[] input) throws Exception { + System.out.printf("wrap %s privacy from %s: ", privacy?"with":"without", me.name); + MessageProp p1 = new MessageProp(0, privacy); byte[] out; if (usingStream) { ByteArrayOutputStream os = new ByteArrayOutputStream(); - me.x.wrap(new ByteArrayInputStream(messageBytes), os, p1); + me.x.wrap(new ByteArrayInputStream(input), os, p1); out = os.toByteArray(); } else { - out = me.x.wrap(messageBytes, 0, messageBytes.length, p1); + out = me.x.wrap(input, 0, input.length, p1); } System.out.println(printProp(p1)); return out; } - }, null); + }, t); + } - t = s2.doAs(new Action() { + public byte[] unwrap(byte[] t, final boolean privacy) + throws Exception { + return doAs(new Action() { @Override public byte[] run(Context me, byte[] input) throws Exception { - MessageProp p1 = new MessageProp(0, true); + System.out.printf("unwrap %s privacy from %s: ", privacy?"with":"without", me.name); + MessageProp p1 = new MessageProp(0, privacy); byte[] bytes; if (usingStream) { ByteArrayOutputStream os = new ByteArrayOutputStream(); @@ -421,36 +411,45 @@ public class Context { } else { bytes = me.x.unwrap(input, 0, input.length, p1); } - if (!Arrays.equals(messageBytes, bytes)) - throw new Exception("wrap/unwrap mismatch"); - System.out.println("unwrap"); System.out.println(printProp(p1)); + return bytes; + } + }, t); + } + + public byte[] getMic(byte[] t) throws Exception { + return doAs(new Action() { + @Override + public byte[] run(Context me, byte[] input) throws Exception { + MessageProp p1 = new MessageProp(0, true); + byte[] bytes; p1 = new MessageProp(0, true); - System.out.println("getMIC"); + System.out.printf("getMic from %s: ", me.name); if (usingStream) { ByteArrayOutputStream os = new ByteArrayOutputStream(); - me.x.getMIC(new ByteArrayInputStream(messageBytes), os, p1); + me.x.getMIC(new ByteArrayInputStream(input), os, p1); bytes = os.toByteArray(); } else { - bytes = me.x.getMIC(messageBytes, 0, messageBytes.length, p1); + bytes = me.x.getMIC(input, 0, input.length, p1); } System.out.println(printProp(p1)); return bytes; } }, t); + } - // Re-unwrap should make p2.isDuplicateToken() returns true - s1.doAs(new Action() { + public void verifyMic(byte[] t, final byte[] msg) throws Exception { + doAs(new Action() { @Override public byte[] run(Context me, byte[] input) throws Exception { MessageProp p1 = new MessageProp(0, true); - System.out.println("verifyMIC"); + System.out.printf("verifyMic from %s: ", me.name); if (usingStream) { me.x.verifyMIC(new ByteArrayInputStream(input), - new ByteArrayInputStream(messageBytes), p1); + new ByteArrayInputStream(msg), p1); } else { me.x.verifyMIC(input, 0, input.length, - messageBytes, 0, messageBytes.length, + msg, 0, msg.length, p1); } System.out.println(printProp(p1)); @@ -459,6 +458,30 @@ public class Context { }, t); } + /** + * Transmits a message from one Context to another. The sender wraps the + * message and sends it to the receiver. The receiver unwraps it, creates + * a MIC of the clear text and sends it back to the sender. The sender + * verifies the MIC against the message sent earlier. + * @param message the message + * @param s1 the sender + * @param s2 the receiver + * @throws java.lang.Exception If anything goes wrong + */ + static public void transmit(final String message, final Context s1, + final Context s2) throws Exception { + final byte[] messageBytes = message.getBytes(); + System.out.printf("-------------------- TRANSMIT from %s to %s------------------------\n", + s1.name, s2.name); + byte[] wrapped = s1.wrap(messageBytes, true); + byte[] unwrapped = s2.unwrap(wrapped, true); + if (!Arrays.equals(messageBytes, unwrapped)) { + throw new Exception("wrap/unwrap mismatch"); + } + byte[] mic = s2.getMic(unwrapped); + s1.verifyMic(mic, messageBytes); + } + /** * Returns a string description of a MessageProp object * @param prop the object diff --git a/test/sun/security/krb5/auto/RRC.java b/test/sun/security/krb5/auto/RRC.java new file mode 100644 index 0000000000000000000000000000000000000000..ade12a40abe5da7bb1c9205041492f5ef31fa344 --- /dev/null +++ b/test/sun/security/krb5/auto/RRC.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2011, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7077640 + * @summary gss wrap for cfx doesn't handle rrc != 0 + * @compile -XDignore.symbol.file RRC.java + * @run main/othervm RRC + */ + +import java.util.Arrays; +import sun.security.jgss.GSSUtil; + +// The basic krb5 test skeleton you can copy from +public class RRC { + + public static void main(String[] args) throws Exception { + + new OneKDC(null).writeJAASConf(); + + Context c, s; + c = Context.fromJAAS("client"); + s = Context.fromJAAS("server"); + + c.startAsClient(OneKDC.SERVER, GSSUtil.GSS_SPNEGO_MECH_OID); + s.startAsServer(GSSUtil.GSS_SPNEGO_MECH_OID); + + Context.handshake(c, s); + + byte[] msg = "i say high --".getBytes(); + byte[] wrapped = c.wrap(msg, false); + + // Simulate RRC equals to EC + int rrc = wrapped[5]; + byte[] rotated = new byte[wrapped.length]; + System.arraycopy(wrapped, 0, rotated, 0, 16); + System.arraycopy(wrapped, wrapped.length-rrc, rotated, 16, rrc); + System.arraycopy(wrapped, 16, rotated, 16+rrc, wrapped.length-16-rrc); + rotated[7] = (byte)rrc; + + byte[] unwrapped = s.unwrap(rotated, false); + if (!Arrays.equals(msg, unwrapped)) { + throw new Exception("Failure"); + } + + s.dispose(); + c.dispose(); + } +}