7077640: gss wrap for cfx doesn't handle rrc != 0
authorweijun
Wed, 28 Sep 2011 14:21:10 +0800
changeset 10696 3811a12690ce
parent 10695 08c28770f82b
child 10697 ecee258b7d87
7077640: gss wrap for cfx doesn't handle rrc != 0 Reviewed-by: valeriep
jdk/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java
jdk/test/sun/security/krb5/auto/Context.java
jdk/test/sun/security/krb5/auto/RRC.java
--- a/jdk/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java	Wed Sep 28 14:21:10 2011 +0800
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/MessageToken_v2.java	Wed Sep 28 14:21:10 2011 +0800
@@ -233,7 +233,6 @@
             }
 
             if (tokenId == Krb5Token.WRAP_ID_v2) {
-                // Does non-confidential data needs a rotate?
                 rotate();
             }
 
@@ -421,10 +420,12 @@
         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);
--- a/jdk/test/sun/security/krb5/auto/Context.java	Wed Sep 28 14:21:10 2011 +0800
+++ b/jdk/test/sun/security/krb5/auto/Context.java	Wed Sep 28 14:21:10 2011 +0800
@@ -375,6 +375,89 @@
         }
     }
 
+    public byte[] wrap(byte[] t, final boolean privacy)
+            throws Exception {
+        return doAs(new Action() {
+            @Override
+            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(input), os, p1);
+                    out = os.toByteArray();
+                } else {
+                    out = me.x.wrap(input, 0, input.length, p1);
+                }
+                System.out.println(printProp(p1));
+                return out;
+            }
+        }, t);
+    }
+
+    public byte[] unwrap(byte[] t, final boolean privacy)
+            throws Exception {
+        return doAs(new Action() {
+            @Override
+            public byte[] run(Context me, byte[] input) throws Exception {
+                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();
+                    me.x.unwrap(new ByteArrayInputStream(input), os, p1);
+                    bytes = os.toByteArray();
+                } else {
+                    bytes = me.x.unwrap(input, 0, input.length, p1);
+                }
+                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.printf("getMic from %s: ", me.name);
+                if (usingStream) {
+                    ByteArrayOutputStream os = new ByteArrayOutputStream();
+                    me.x.getMIC(new ByteArrayInputStream(input), os, p1);
+                    bytes = os.toByteArray();
+                } else {
+                    bytes = me.x.getMIC(input, 0, input.length, p1);
+                }
+                System.out.println(printProp(p1));
+                return bytes;
+            }
+        }, t);
+    }
+
+    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.printf("verifyMic from %s: ", me.name);
+                if (usingStream) {
+                    me.x.verifyMIC(new ByteArrayInputStream(input),
+                            new ByteArrayInputStream(msg), p1);
+                } else {
+                    me.x.verifyMIC(input, 0, input.length,
+                            msg, 0, msg.length,
+                            p1);
+                }
+                System.out.println(printProp(p1));
+                return null;
+            }
+        }, 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
@@ -390,73 +473,13 @@
         final byte[] messageBytes = message.getBytes();
         System.out.printf("-------------------- TRANSMIT from %s to %s------------------------\n",
                 s1.name, s2.name);
-
-        byte[] t = s1.doAs(new Action() {
-            @Override
-            public byte[] run(Context me, byte[] dummy) throws Exception {
-                System.out.println("wrap");
-                MessageProp p1 = new MessageProp(0, true);
-                byte[] out;
-                if (usingStream) {
-                    ByteArrayOutputStream os = new ByteArrayOutputStream();
-                    me.x.wrap(new ByteArrayInputStream(messageBytes), os, p1);
-                    out = os.toByteArray();
-                } else {
-                    out = me.x.wrap(messageBytes, 0, messageBytes.length, p1);
-                }
-                System.out.println(printProp(p1));
-                return out;
-            }
-        }, null);
-
-        t = s2.doAs(new Action() {
-            @Override
-            public byte[] run(Context me, byte[] input) throws Exception {
-                MessageProp p1 = new MessageProp(0, true);
-                byte[] bytes;
-                if (usingStream) {
-                    ByteArrayOutputStream os = new ByteArrayOutputStream();
-                    me.x.unwrap(new ByteArrayInputStream(input), os, p1);
-                    bytes = os.toByteArray();
-                } 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));
-                p1 = new MessageProp(0, true);
-                System.out.println("getMIC");
-                if (usingStream) {
-                    ByteArrayOutputStream os = new ByteArrayOutputStream();
-                    me.x.getMIC(new ByteArrayInputStream(messageBytes), os, p1);
-                    bytes = os.toByteArray();
-                } else {
-                    bytes = me.x.getMIC(messageBytes, 0, messageBytes.length, p1);
-                }
-                System.out.println(printProp(p1));
-                return bytes;
-            }
-        }, t);
-
-        // Re-unwrap should make p2.isDuplicateToken() returns true
-        s1.doAs(new Action() {
-            @Override
-            public byte[] run(Context me, byte[] input) throws Exception {
-                MessageProp p1 = new MessageProp(0, true);
-                System.out.println("verifyMIC");
-                if (usingStream) {
-                    me.x.verifyMIC(new ByteArrayInputStream(input),
-                            new ByteArrayInputStream(messageBytes), p1);
-                } else {
-                    me.x.verifyMIC(input, 0, input.length,
-                            messageBytes, 0, messageBytes.length,
-                            p1);
-                }
-                System.out.println(printProp(p1));
-                return null;
-            }
-        }, t);
+        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);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/RRC.java	Wed Sep 28 14:21:10 2011 +0800
@@ -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();
+    }
+}