jdk/src/java.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java
author chegar
Sun, 17 Aug 2014 15:54:13 +0100
changeset 25859 3317bb8137f4
parent 25522 jdk/src/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java@10d789df41bb
permissions -rw-r--r--
8054834: Modular Source Code Reviewed-by: alanb, chegar, ihse, mduigou Contributed-by: alan.bateman@oracle.com, alex.buckley@oracle.com, chris.hegarty@oracle.com, erik.joelsson@oracle.com, jonathan.gibbons@oracle.com, karen.kinnear@oracle.com, magnus.ihse.bursie@oracle.com, mandy.chung@oracle.com, mark.reinhold@oracle.com, paul.sandoz@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
23010
6dadb192ad81 8029235: Update copyright year to match last edit in jdk8 jdk repository for 2013
lana
parents: 17209
diff changeset
     2
 * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package com.sun.security.sasl.gsskerb;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.util.Map;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.util.logging.Level;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import javax.security.sasl.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
// JAAS
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import javax.security.auth.callback.CallbackHandler;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
// JGSS
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import org.ietf.jgss.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
  * Implements the GSSAPI SASL client mechanism for Kerberos V5.
5820
4f5e99470724 6967036: Need to fix links with // in Javadoc comments
ohair
parents: 5506
diff changeset
    41
  * (<A HREF="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</A>,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
  * <a HREF="http://www.ietf.org/internet-drafts/draft-ietf-cat-sasl-gssapi-04.txt">draft-ietf-cat-sasl-gssapi-04.txt</a>).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
  * It uses the Java Bindings for GSSAPI
5820
4f5e99470724 6967036: Need to fix links with // in Javadoc comments
ohair
parents: 5506
diff changeset
    44
  * (<A HREF="http://www.ietf.org/rfc/rfc2853.txt">RFC 2853</A>)
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
  * for getting GSSAPI/Kerberos V5 support.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
  * The client/server interactions are:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
  * C0: bind (GSSAPI, initial response)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
  * S0: sasl-bind-in-progress, challenge 1 (output of accept_sec_context or [])
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
  * C1: bind (GSSAPI, response 1 (output of init_sec_context or []))
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
  * S1: sasl-bind-in-progress challenge 2 (security layer, server max recv size)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
  * C2: bind (GSSAPI, response 2 (security layer, client max recv size, authzid))
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
  * S2: bind success response
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
  * Expects the client's credentials to be supplied from the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
  * javax.security.sasl.credentials property or from the thread's Subject.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
  * Otherwise the underlying KRB5 mech will attempt to acquire Kerberos creds
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
  * by logging into Kerberos (via default TextCallbackHandler).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
  * These creds will be used for exchange with server.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
  * Required callbacks: none.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
  * Environment properties that affect behavior of implementation:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
  * javax.security.sasl.qop
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
  * - quality of protection; list of auth, auth-int, auth-conf; default is "auth"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
  * javax.security.sasl.maxbuf
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
  * - max receive buffer size; default is 65536
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
  * javax.security.sasl.sendmaxbuffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
  * - max send buffer size; default is 65536; (min with server max recv size)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
  * javax.security.sasl.server.authentication
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
  * - "true" means require mutual authentication; default is "false"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
  * javax.security.sasl.credentials
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
  * - an {@link org.ietf.jgss.GSSCredential} used for delegated authentication.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
  * @author Rosanna Lee
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
final class GssKrb5Client extends GssKrb5Base implements SaslClient {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    // ---------------- Constants -----------------
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    private static final String MY_CLASS_NAME = GssKrb5Client.class.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    private boolean finalHandshake = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    private boolean mutual = false;       // default false
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    private byte[] authzID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
     * Creates a SASL mechanism with client credentials that it needs
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     * to participate in GSS-API/Kerberos v5 authentication exchange
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
     * with the server.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    GssKrb5Client(String authzID, String protocol, String serverName,
10336
0bb1999251f8 7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 7668
diff changeset
    95
        Map<String, ?> props, CallbackHandler cbh) throws SaslException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
        super(props, MY_CLASS_NAME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
        String service = protocol + "@" + serverName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        logger.log(Level.FINE, "KRB5CLNT01:Requesting service name: {0}",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
            service);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
            GSSManager mgr = GSSManager.getInstance();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
            // Create the name for the requested service entity for Krb5 mech
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
            GSSName acceptorName = mgr.createName(service,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
                GSSName.NT_HOSTBASED_SERVICE, KRB5_OID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
            // Parse properties to check for supplied credentials
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
            GSSCredential credentials = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
            if (props != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
                Object prop = props.get(Sasl.CREDENTIALS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
                if (prop != null && prop instanceof GSSCredential) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
                    credentials = (GSSCredential) prop;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
                    logger.log(Level.FINE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
                        "KRB5CLNT01:Using the credentials supplied in " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
                        "javax.security.sasl.credentials");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
            // Create a context using credentials for Krb5 mech
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
            secCtx = mgr.createContext(acceptorName,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
                KRB5_OID,   /* mechanism */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
                credentials, /* credentials */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
                GSSContext.INDEFINITE_LIFETIME);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
            // Request credential delegation when credentials have been supplied
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            if (credentials != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
                secCtx.requestCredDeleg(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
            // Parse properties  to set desired context options
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
            if (props != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
                // Mutual authentication
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
                String prop = (String)props.get(Sasl.SERVER_AUTH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
                if (prop != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
                    mutual = "true".equalsIgnoreCase(prop);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
            secCtx.requestMutualAuth(mutual);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
            // Always specify potential need for integrity and confidentiality
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
            // Decision will be made during final handshake
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            secCtx.requestConf(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            secCtx.requestInteg(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        } catch (GSSException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            throw new SaslException("Failure to initialize security context", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        if (authzID != null && authzID.length() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                this.authzID = authzID.getBytes("UTF8");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                throw new SaslException("Cannot encode authorization ID", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    public boolean hasInitialResponse() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * Processes the challenge data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * The server sends a challenge data using which the client must
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     * process using GSS_Init_sec_context.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
     * As per RFC 2222, when GSS_S_COMPLETE is returned, we do
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
     * an extra handshake to determine the negotiated security protection
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
     * and buffer sizes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     * @param challengeData A non-null byte array containing the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     * challenge data from the server.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     * @return A non-null byte array containing the response to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
     * sent to the server.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    public byte[] evaluateChallenge(byte[] challengeData) throws SaslException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        if (completed) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
            throw new IllegalStateException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
                "GSSAPI authentication already complete");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        if (finalHandshake) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
            return doFinalHandshake(challengeData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            // Security context not established yet; continue with init
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
                byte[] gssOutToken = secCtx.initSecContext(challengeData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
                    0, challengeData.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                if (logger.isLoggable(Level.FINER)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                    traceOutput(MY_CLASS_NAME, "evaluteChallenge",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                        "KRB5CLNT02:Challenge: [raw]", challengeData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
                    traceOutput(MY_CLASS_NAME, "evaluateChallenge",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                        "KRB5CLNT03:Response: [after initSecCtx]", gssOutToken);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
                if (secCtx.isEstablished()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
                    finalHandshake = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                    if (gssOutToken == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                        // RFC 2222 7.2.1:  Client responds with no data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
                        return EMPTY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                return gssOutToken;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            } catch (GSSException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                throw new SaslException("GSS initiate failed", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    private byte[] doFinalHandshake(byte[] challengeData) throws SaslException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            // Security context already established. challengeData
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            // should contain security layers and server's maximum buffer size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
            if (logger.isLoggable(Level.FINER)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
                    "KRB5CLNT04:Challenge [raw]:", challengeData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
            if (challengeData.length == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                // Received S0, should return []
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
                return EMPTY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            // Received S1 (security layer, server max recv size)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            byte[] gssOutToken = secCtx.unwrap(challengeData, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                challengeData.length, new MessageProp(0, false));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
            // First octet is a bit-mask specifying the protections
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
            // supported by the server
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            if (logger.isLoggable(Level.FINE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                if (logger.isLoggable(Level.FINER)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                    traceOutput(MY_CLASS_NAME, "doFinalHandshake",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                        "KRB5CLNT05:Challenge [unwrapped]:", gssOutToken);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
                logger.log(Level.FINE, "KRB5CLNT06:Server protections: {0}",
25187
08aff438def8 8048874: Replace uses of 'new Byte', 'new Short' and 'new Character' with appropriate alternative across core classes
prappo
parents: 23010
diff changeset
   244
                    gssOutToken[0]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
            // Client selects preferred protection
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
            // qop is ordered list of qop values
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
            byte selectedQop = findPreferredMask(gssOutToken[0], qop);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            if (selectedQop == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                throw new SaslException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
                    "No common protection layer between client and server");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            if ((selectedQop&PRIVACY_PROTECTION) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                privacy = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                integrity = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            } else if ((selectedQop&INTEGRITY_ONLY_PROTECTION) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                integrity = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
            // 2nd-4th octets specifies maximum buffer size expected by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            // server (in network byte order)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
            int srvMaxBufSize = networkByteOrderToInt(gssOutToken, 1, 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
            // Determine the max send buffer size based on what the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            // server is able to receive and our specified max
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            sendMaxBufSize = (sendMaxBufSize == 0) ? srvMaxBufSize :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                Math.min(sendMaxBufSize, srvMaxBufSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            // Update context to limit size of returned buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            rawSendSize = secCtx.getWrapSizeLimit(JGSS_QOP, privacy,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                sendMaxBufSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
            if (logger.isLoggable(Level.FINE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
                logger.log(Level.FINE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
"KRB5CLNT07:Client max recv size: {0}; server max recv size: {1}; rawSendSize: {2}",
25522
10d789df41bb 8049892: Replace uses of 'new Integer()' with appropriate alternative across core classes
prr
parents: 25187
diff changeset
   278
                    new Object[] {recvMaxBufSize,
10d789df41bb 8049892: Replace uses of 'new Integer()' with appropriate alternative across core classes
prr
parents: 25187
diff changeset
   279
                                  srvMaxBufSize,
10d789df41bb 8049892: Replace uses of 'new Integer()' with appropriate alternative across core classes
prr
parents: 25187
diff changeset
   280
                                  rawSendSize});
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            // Construct negotiated security layers and client's max
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
            // receive buffer size and authzID
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
            int len = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
            if (authzID != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                len += authzID.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            byte[] gssInToken = new byte[len];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
            gssInToken[0] = selectedQop;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            if (logger.isLoggable(Level.FINE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                logger.log(Level.FINE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            "KRB5CLNT08:Selected protection: {0}; privacy: {1}; integrity: {2}",
25187
08aff438def8 8048874: Replace uses of 'new Byte', 'new Short' and 'new Character' with appropriate alternative across core classes
prappo
parents: 23010
diff changeset
   296
                    new Object[]{selectedQop,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                                 Boolean.valueOf(privacy),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                                 Boolean.valueOf(integrity)});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            intToNetworkByteOrder(recvMaxBufSize, gssInToken, 1, 3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            if (authzID != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                // copy authorization id
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                System.arraycopy(authzID, 0, gssInToken, 4, authzID.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
                logger.log(Level.FINE, "KRB5CLNT09:Authzid: {0}", authzID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            if (logger.isLoggable(Level.FINER)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
                    "KRB5CLNT10:Response [raw]", gssInToken);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            gssOutToken = secCtx.wrap(gssInToken,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                0, gssInToken.length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                new MessageProp(0 /* qop */, false /* privacy */));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            if (logger.isLoggable(Level.FINER)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                traceOutput(MY_CLASS_NAME, "doFinalHandshake",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                    "KRB5CLNT11:Response [after wrap]", gssOutToken);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            completed = true;  // server authenticated
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            return gssOutToken;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
        } catch (GSSException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            throw new SaslException("Final handshake failed", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
}