| /* |
| * Copyright (c) 2003, 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 1.2 07/03/29 |
| * @bug 4634892 |
| * @summary Ensure that client requesting integrity causes resulting channel to |
| * be integrity-protected. |
| */ |
| |
| /* |
| * Can set logging to FINEST to view exchange. |
| */ |
| import javax.security.sasl.*; |
| import javax.security.auth.callback.*; |
| import java.security.Security; |
| import java.util.*; |
| |
| public class Integrity { |
| private static final String MECH = "DIGEST-MD5"; |
| private static final String SERVER_FQDN = "machineX.imc.org"; |
| private static final String PROTOCOL = "jmx"; |
| |
| private static final byte[] EMPTY = new byte[0]; |
| |
| private static String pwfile, namesfile, proxyfile; |
| private static boolean auto; |
| private static boolean verbose = false; |
| |
| private static byte[][] clntdata, srvdata; |
| |
| private static void init(String[] args) throws Exception { |
| if (args.length == 0) { |
| pwfile = "pw.properties"; |
| namesfile = "names.properties"; |
| auto = true; |
| } else { |
| int i = 0; |
| if (args[i].equals("-m")) { |
| i++; |
| auto = false; |
| } |
| if (args.length > i) { |
| pwfile = args[i++]; |
| |
| if (args.length > i) { |
| namesfile = args[i++]; |
| |
| if (args.length > i) { |
| proxyfile = args[i]; |
| } |
| } |
| } else { |
| pwfile = "pw.properties"; |
| namesfile = "names.properties"; |
| } |
| } |
| |
| initData(); |
| } |
| |
| |
| public static void main(String[] args) throws Exception { |
| |
| init(args); |
| |
| CallbackHandler clntCbh = new ClientCallbackHandler(auto); |
| |
| CallbackHandler srvCbh = |
| new PropertiesFileCallbackHandler(pwfile, namesfile, proxyfile); |
| |
| Map srvProps = new HashMap(); |
| srvProps.put(Sasl.QOP, "auth-int"); |
| |
| Map clntProps = new HashMap(); |
| clntProps.put(Sasl.QOP, "auth-int"); |
| |
| SaslClient clnt = Sasl.createSaslClient( |
| new String[]{MECH}, null, PROTOCOL, SERVER_FQDN, clntProps, clntCbh); |
| |
| SaslServer srv = Sasl.createSaslServer(MECH, PROTOCOL, SERVER_FQDN, |
| srvProps, srvCbh); |
| |
| if (clnt == null) { |
| throw new IllegalStateException( |
| "Unable to find client impl for " + MECH); |
| } |
| if (srv == null) { |
| throw new IllegalStateException( |
| "Unable to find server impl for " + MECH); |
| } |
| |
| byte[] response = (clnt.hasInitialResponse()? |
| clnt.evaluateChallenge(EMPTY) : EMPTY); |
| byte[] challenge; |
| |
| while (!clnt.isComplete() || !srv.isComplete()) { |
| challenge = srv.evaluateResponse(response); |
| |
| if (challenge != null) { |
| response = clnt.evaluateChallenge(challenge); |
| } |
| } |
| |
| if (clnt.isComplete() && srv.isComplete()) { |
| if (verbose) { |
| System.out.println("SUCCESS"); |
| System.out.println("authzid is " + srv.getAuthorizationID()); |
| } |
| } else { |
| throw new IllegalStateException("FAILURE: mismatched state:" + |
| " client complete? " + clnt.isComplete() + |
| " server complete? " + srv.isComplete()); |
| } |
| |
| /* Use security layer */ |
| int count = 0; |
| for (int i = 0; i < clntStrs.length; i++) { |
| byte[] orig = clntdata[i]; |
| byte[] wrapped = clnt.wrap(clntdata[i], 0, clntdata[i].length); |
| byte[] unwrapped = srv.unwrap(wrapped, 0, wrapped.length); |
| |
| if (!Arrays.equals(orig, unwrapped)) { |
| throw new SaslException("Server cannot unwrap client data"); |
| } |
| |
| byte[] sorig = srvdata[i]; |
| byte[] swrapped = srv.wrap(srvdata[i], 0, srvdata[i].length); |
| byte[] sunwrapped = clnt.unwrap(swrapped, 0, swrapped.length); |
| |
| if (!Arrays.equals(sorig, sunwrapped)) { |
| throw new SaslException("Client cannot unwrap server data"); |
| } |
| ++count; |
| } |
| |
| if (verbose) |
| System.out.println(count + " sets of wrap/unwrap between client/server"); |
| |
| clnt.dispose(); |
| srv.dispose(); |
| } |
| |
| private static final String[] srvStrs = new String[] { |
| "A is the 1st letter", |
| "B is the 2nd letter", |
| "C is the 3rd letter", |
| "D is the 4th letter", |
| "E is the 5th letter", |
| "F is the 6th letter", |
| "G is the 7th letter", |
| "H is the 8th letter", |
| "I is the 9th letter", |
| "J is the 10th letter", |
| "K is the 11th letter", |
| "L is the 12th letter", |
| "M is the 13th letter", |
| }; |
| |
| private static final String[] clntStrs = new String[] { |
| "0", |
| "1", |
| "2", |
| "3", |
| "4", |
| "5", |
| "6", |
| "7", |
| "8", |
| "9", |
| "10", |
| "11", |
| "12", |
| }; |
| |
| private static void initData() { |
| clntdata = new byte[clntStrs.length][]; |
| for (int i = 0; i < clntStrs.length; i++) { |
| clntdata[i] = clntStrs[i].getBytes(); |
| } |
| |
| srvdata = new byte[srvStrs.length][]; |
| for (int i = 0; i < srvStrs.length; i++) { |
| srvdata[i] = srvStrs[i].getBytes(); |
| } |
| } |
| } |