src/java.security.sasl/share/classes/com/sun/security/sasl/digest/DigestMD5Client.java
author hb
Tue, 02 Jan 2018 15:03:52 +0530
branchjmx-rest-api
changeset 56005 90cff2ac77b8
parent 47216 71c04702a3d5
child 59024 b046ba510bbc
permissions -rw-r--r--
REST base url gets complete complete domain name
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: 17424
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.digest;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.security.NoSuchAlgorithmException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.io.ByteArrayOutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.io.UnsupportedEncodingException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.util.StringTokenizer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.util.ArrayList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import java.util.List;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import java.util.Map;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import java.util.Arrays;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import java.util.logging.Level;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import javax.security.sasl.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import javax.security.auth.callback.CallbackHandler;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import javax.security.auth.callback.PasswordCallback;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import javax.security.auth.callback.NameCallback;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import javax.security.auth.callback.Callback;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import javax.security.auth.callback.UnsupportedCallbackException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
  * An implementation of the DIGEST-MD5
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
  * (<a href="http://www.ietf.org/rfc/rfc2831.txt">RFC 2831</a>) SASL
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
  * (<a href="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</a>) mechanism.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
  * The DIGEST-MD5 SASL mechanism specifies two modes of authentication.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
  * - Initial Authentication
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
  * - Subsequent Authentication - optional, (currently unsupported)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
  * Required callbacks:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
  * - RealmChoiceCallback
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
  *    shows user list of realms server has offered; handler must choose one
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
  *    from list
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
  * - RealmCallback
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
  *    shows user the only realm server has offered or none; handler must
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
  *    enter realm to use
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
  * - NameCallback
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
  *    handler must enter username to use for authentication
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
  * - PasswordCallback
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
  *    handler must enter password for username to use for authentication
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
  * Environment properties that affect behavior of implementation:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
  * javax.security.sasl.qop
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
  *    quality of protection; list of auth, auth-int, auth-conf; default is "auth"
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
  * javax.security.sasl.strength
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
  *    auth-conf strength; list of high, medium, low; default is highest
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
  *    available on platform ["high,medium,low"].
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
  *    high means des3 or rc4 (128); medium des or rc4-56; low is rc4-40;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
  *    choice of cipher depends on its availablility on platform
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
  * javax.security.sasl.maxbuf
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
  *    max receive buffer size; default is 65536
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
  * javax.security.sasl.sendmaxbuffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
  *    max send buffer size; default is 65536; (min with server max recv size)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
  * com.sun.security.sasl.digest.cipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
  *    name a specific cipher to use; setting must be compatible with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
  *    setting of the javax.security.sasl.strength property.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
  * @see <a href="http://www.ietf.org/rfc/rfc2222.txt">RFC 2222</a>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
  * - Simple Authentication and Security Layer (SASL)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
  * @see <a href="http://www.ietf.org/rfc/rfc2831.txt">RFC 2831</a>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
  * - Using Digest Authentication as a SASL Mechanism
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
  * @see <a href="http://java.sun.com/products/jce">Java(TM)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
  * Cryptography Extension 1.2.1 (JCE)</a>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
  * @see <a href="http://java.sun.com/products/jaas">Java(TM)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
  * Authentication and Authorization Service (JAAS)</a>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
  *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
  * @author Jonathan Bruce
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
  * @author Rosanna Lee
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
  */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
final class DigestMD5Client extends DigestMD5Base implements SaslClient {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    private static final String MY_CLASS_NAME = DigestMD5Client.class.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    // Property for specifying cipher explicitly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    private static final String CIPHER_PROPERTY =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        "com.sun.security.sasl.digest.cipher";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    /* Directives encountered in challenges sent by the server. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    private static final String[] DIRECTIVE_KEY = {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
        "realm",      // >= 0 times
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        "qop",        // atmost once; default is "auth"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
        "algorithm",  // exactly once
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        "nonce",      // exactly once
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        "maxbuf",     // atmost once; default is 65536
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        "charset",    // atmost once; default is ISO 8859-1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        "cipher",     // exactly once if qop is "auth-conf"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        "rspauth",    // exactly once in 2nd challenge
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        "stale",      // atmost once for in subsequent auth (not supported)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    /* Indices into DIRECTIVE_KEY */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    private static final int REALM = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    private static final int QOP = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    private static final int ALGORITHM = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    private static final int NONCE = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    private static final int MAXBUF = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    private static final int CHARSET = 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    private static final int CIPHER = 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    private static final int RESPONSE_AUTH = 7;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    private static final int STALE = 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    private int nonceCount; // number of times nonce has been used/seen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    /* User-supplied/generated information */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    private String specifiedCipher;  // cipher explicitly requested by user
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    private byte[] cnonce;        // client generated nonce
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    private String username;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    private char[] passwd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    private byte[] authzidBytes;  // byte repr of authzid
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
      * Constructor for DIGEST-MD5 mechanism.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
      *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
      * @param authzid A non-null String representing the principal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
      * for which authorization is being granted..
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
      * @param digestURI A non-null String representing detailing the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
      * combined protocol and host being used for authentication.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
      * @param props The possibly null properties to be used by the SASL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
      * mechanism to configure the authentication exchange.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
      * @param cbh The non-null CallbackHanlder object for callbacks
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
      * @throws SaslException if no authentication ID or password is supplied
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
      */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    DigestMD5Client(String authzid, String protocol, String serverName,
10336
0bb1999251f8 7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 5506
diff changeset
   151
        Map<String, ?> props, CallbackHandler cbh) throws SaslException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        super(props, MY_CLASS_NAME, 2, protocol + "/" + serverName, cbh);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        // authzID can only be encoded in UTF8 - RFC 2222
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        if (authzid != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            this.authzid = authzid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
                authzidBytes = authzid.getBytes("UTF8");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            } catch (UnsupportedEncodingException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                throw new SaslException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                    "DIGEST-MD5: Error encoding authzid value into UTF-8", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        if (props != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            specifiedCipher = (String)props.get(CIPHER_PROPERTY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
            logger.log(Level.FINE, "DIGEST60:Explicitly specified cipher: {0}",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                specifiedCipher);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
   }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     * DIGEST-MD5 has no initial response
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
     * @return false
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    public boolean hasInitialResponse() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     * Process the challenge data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     * The server sends a digest-challenge which the client must reply to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     * in a digest-response. When the authentication is complete, the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * completed field is set to true.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
     * @param challengeData A non-null byte array containing the challenge
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
     * data from the server.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
     * @return A possibly null byte array containing the response to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
     * be sent to the server.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * @throws SaslException If the platform does not have MD5 digest support
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     * or if the server sends an invalid challenge.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    public byte[] evaluateChallenge(byte[] challengeData) throws SaslException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        if (challengeData.length > MAX_CHALLENGE_LENGTH) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            throw new SaslException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                "DIGEST-MD5: Invalid digest-challenge length. Got:  " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                challengeData.length + " Expected < " + MAX_CHALLENGE_LENGTH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        /* Extract and process digest-challenge */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        byte[][] challengeVal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        switch (step) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        case 2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
            /* Process server's first challenge (from Step 1) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            /* Get realm, qop, maxbuf, charset, algorithm, cipher, nonce
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
               directives */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            List<byte[]> realmChoices = new ArrayList<byte[]>(3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
            challengeVal = parseDirectives(challengeData, DIRECTIVE_KEY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                realmChoices, REALM);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                processChallenge(challengeVal, realmChoices);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                checkQopSupport(challengeVal[QOP], challengeVal[CIPHER]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                ++step;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
                return generateClientResponse(challengeVal[CHARSET]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
            } catch (SaslException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                step = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                clearPassword();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                throw e; // rethrow
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
                step = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
                clearPassword();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
                throw new SaslException("DIGEST-MD5: Error generating " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
                    "digest response-value", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        case 3:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
                /* Process server's step 3 (server response to digest response) */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
                /* Get rspauth directive */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
                challengeVal = parseDirectives(challengeData, DIRECTIVE_KEY,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
                    null, REALM);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
                validateResponseValue(challengeVal[RESPONSE_AUTH]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                /* Initialize SecurityCtx implementation */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                if (integrity && privacy) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
                    secCtx = new DigestPrivacy(true /* client */);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
                } else if (integrity) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                    secCtx = new DigestIntegrity(true /* client */);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
                return null; // Mechanism has completed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
            } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
                clearPassword();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
                step = 0;  // Set to invalid state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
                completed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            // No other possible state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            throw new SaslException("DIGEST-MD5: Client at illegal state");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
   /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    * Record information from the challengeVal array into variables/fields.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    * Check directive values that are multi-valued and ensure that mandatory
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    * directives not missing from the digest-challenge.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    * @throws SaslException if a sasl is a the mechanism cannot
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    * correcly handle a callbacks or if a violation in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
    * digest challenge format is detected.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    private void processChallenge(byte[][] challengeVal, List<byte[]> realmChoices)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        throws SaslException, UnsupportedEncodingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
        /* CHARSET: optional atmost once */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        if (challengeVal[CHARSET] != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            if (!"utf-8".equals(new String(challengeVal[CHARSET], encoding))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                throw new SaslException("DIGEST-MD5: digest-challenge format " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                    "violation. Unrecognised charset value: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                    new String(challengeVal[CHARSET]));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                encoding = "UTF8";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                useUTF8 = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        /* ALGORITHM: required exactly once */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        if (challengeVal[ALGORITHM] == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
            throw new SaslException("DIGEST-MD5: Digest-challenge format " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                "violation: algorithm directive missing");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        } else if (!"md5-sess".equals(new String(challengeVal[ALGORITHM], encoding))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            throw new SaslException("DIGEST-MD5: Digest-challenge format " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                "violation. Invalid value for 'algorithm' directive: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                challengeVal[ALGORITHM]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        /* NONCE: required exactly once */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
        if (challengeVal[NONCE] == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            throw new SaslException("DIGEST-MD5: Digest-challenge format " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                "violation: nonce directive missing");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            nonce = challengeVal[NONCE];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            /* REALM: optional, if multiple, stored in realmChoices */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            String[] realmTokens = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            if (challengeVal[REALM] != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                if (realmChoices == null || realmChoices.size() <= 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
                    // Only one realm specified
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                    negotiatedRealm = new String(challengeVal[REALM], encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
                    realmTokens = new String[realmChoices.size()];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                    for (int i = 0; i < realmTokens.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                        realmTokens[i] =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
                            new String(realmChoices.get(i), encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            NameCallback ncb = authzid == null ?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                new NameCallback("DIGEST-MD5 authentication ID: ") :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
                new NameCallback("DIGEST-MD5 authentication ID: ", authzid);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            PasswordCallback pcb =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                new PasswordCallback("DIGEST-MD5 password: ", false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
            if (realmTokens == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                // Server specified <= 1 realm
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                // If 0, RFC 2831: the client SHOULD solicit a realm from the user.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                RealmCallback tcb =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                    (negotiatedRealm == null? new RealmCallback("DIGEST-MD5 realm: ") :
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                        new RealmCallback("DIGEST-MD5 realm: ", negotiatedRealm));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                cbh.handle(new Callback[] {tcb, ncb, pcb});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                /* Acquire realm from RealmCallback */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                negotiatedRealm = tcb.getText();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                if (negotiatedRealm == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
                    negotiatedRealm = "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
                RealmChoiceCallback ccb = new RealmChoiceCallback(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                    "DIGEST-MD5 realm: ",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                    realmTokens,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                    0, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                cbh.handle(new Callback[] {ccb, ncb, pcb});
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
17424
cb03ce64ed07 8013855: DigestMD5Client has not checked RealmChoiceCallback value
weijun
parents: 10336
diff changeset
   351
                // Acquire realm from RealmChoiceCallback
cb03ce64ed07 8013855: DigestMD5Client has not checked RealmChoiceCallback value
weijun
parents: 10336
diff changeset
   352
                int[] selected = ccb.getSelectedIndexes();
cb03ce64ed07 8013855: DigestMD5Client has not checked RealmChoiceCallback value
weijun
parents: 10336
diff changeset
   353
                if (selected == null
cb03ce64ed07 8013855: DigestMD5Client has not checked RealmChoiceCallback value
weijun
parents: 10336
diff changeset
   354
                        || selected[0] < 0
cb03ce64ed07 8013855: DigestMD5Client has not checked RealmChoiceCallback value
weijun
parents: 10336
diff changeset
   355
                        || selected[0] >= realmTokens.length) {
cb03ce64ed07 8013855: DigestMD5Client has not checked RealmChoiceCallback value
weijun
parents: 10336
diff changeset
   356
                    throw new SaslException("DIGEST-MD5: Invalid realm chosen");
cb03ce64ed07 8013855: DigestMD5Client has not checked RealmChoiceCallback value
weijun
parents: 10336
diff changeset
   357
                }
cb03ce64ed07 8013855: DigestMD5Client has not checked RealmChoiceCallback value
weijun
parents: 10336
diff changeset
   358
                negotiatedRealm = realmTokens[selected[0]];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
            passwd = pcb.getPassword();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
            pcb.clearPassword();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
            username = ncb.getName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
17424
cb03ce64ed07 8013855: DigestMD5Client has not checked RealmChoiceCallback value
weijun
parents: 10336
diff changeset
   365
        } catch (SaslException se) {
cb03ce64ed07 8013855: DigestMD5Client has not checked RealmChoiceCallback value
weijun
parents: 10336
diff changeset
   366
            throw se;
cb03ce64ed07 8013855: DigestMD5Client has not checked RealmChoiceCallback value
weijun
parents: 10336
diff changeset
   367
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        } catch (UnsupportedCallbackException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
            throw new SaslException("DIGEST-MD5: Cannot perform callback to " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                "acquire realm, authentication ID or password", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
            throw new SaslException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                "DIGEST-MD5: Error acquiring realm, authentication ID or password", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        if (username == null || passwd == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            throw new SaslException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                "DIGEST-MD5: authentication ID and password must be specified");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        /* MAXBUF: optional atmost once */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        int srvMaxBufSize =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            (challengeVal[MAXBUF] == null) ? DEFAULT_MAXBUF
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            : Integer.parseInt(new String(challengeVal[MAXBUF], encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
        sendMaxBufSize =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
            (sendMaxBufSize == 0) ? srvMaxBufSize
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
            : Math.min(sendMaxBufSize, srvMaxBufSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     * Parses the 'qop' directive. If 'auth-conf' is specified by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     * the client and offered as a QOP option by the server, then a check
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
     * is client-side supported ciphers is performed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
     * @throws IOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
    private void checkQopSupport(byte[] qopInChallenge, byte[] ciphersInChallenge)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        /* QOP: optional; if multiple, merged earlier */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        String qopOptions;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        if (qopInChallenge == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
            qopOptions = "auth";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
            qopOptions = new String(qopInChallenge, encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
        // process
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        String[] serverQopTokens = new String[3];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        byte[] serverQop = parseQop(qopOptions, serverQopTokens,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
            true /* ignore unrecognized tokens */);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        byte serverAllQop = combineMasks(serverQop);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        switch (findPreferredMask(serverAllQop, qop)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        case 0:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            throw new SaslException("DIGEST-MD5: No common protection " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
                "layer between client and server");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        case NO_PROTECTION:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            negotiatedQop = "auth";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
            // buffer sizes not applicable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        case INTEGRITY_ONLY_PROTECTION:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
            negotiatedQop = "auth-int";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
            integrity = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
            rawSendSize = sendMaxBufSize - 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        case PRIVACY_PROTECTION:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            negotiatedQop = "auth-conf";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            privacy = integrity = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            rawSendSize = sendMaxBufSize - 26;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            checkStrengthSupport(ciphersInChallenge);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        if (logger.isLoggable(Level.FINE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
            logger.log(Level.FINE, "DIGEST61:Raw send size: {0}",
25522
10d789df41bb 8049892: Replace uses of 'new Integer()' with appropriate alternative across core classes
prr
parents: 23010
diff changeset
   442
                rawSendSize);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
     * Processes the 'cipher' digest-challenge directive. This allows the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
     * mechanism to check for client-side support against the list of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
     * supported ciphers send by the server. If no match is found,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     * the mechanism aborts.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
     * @throws SaslException If an error is encountered in processing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
     * the cipher digest-challenge directive or if no client-side
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
     * support is found.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
    private void checkStrengthSupport(byte[] ciphersInChallenge)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
        /* CIPHER: required exactly once if qop=auth-conf */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        if (ciphersInChallenge == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            throw new SaslException("DIGEST-MD5: server did not specify " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                "cipher to use for 'auth-conf'");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        // First determine ciphers that server supports
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        String cipherOptions = new String(ciphersInChallenge, encoding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        StringTokenizer parser = new StringTokenizer(cipherOptions, ", \t\n");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        int tokenCount = parser.countTokens();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        String token = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        byte[] serverCiphers = { UNSET,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
                                 UNSET,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                                 UNSET,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                                 UNSET,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                                 UNSET };
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        String[] serverCipherStrs = new String[serverCiphers.length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        // Parse ciphers in challenge; mark each that server supports
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        for (int i = 0; i < tokenCount; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
            token = parser.nextToken();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
            for (int j = 0; j < CIPHER_TOKENS.length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                if (token.equals(CIPHER_TOKENS[j])) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                    serverCiphers[j] |= CIPHER_MASKS[j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
                    serverCipherStrs[j] = token; // keep for replay to server
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
                    logger.log(Level.FINE, "DIGEST62:Server supports {0}", token);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
        // Determine which ciphers are available on client
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
        byte[] clntCiphers = getPlatformCiphers();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        // Take intersection of server and client supported ciphers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        byte inter = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        for (int i = 0; i < serverCiphers.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
            serverCiphers[i] &= clntCiphers[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
            inter |= serverCiphers[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        if (inter == UNSET) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            throw new SaslException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                "DIGEST-MD5: Client supports none of these cipher suites: " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
                cipherOptions);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        // now have a clear picture of user / client; client / server
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        // cipher options. Leverage strength array against what is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        // supported to choose a cipher.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
        negotiatedCipher = findCipherAndStrength(serverCiphers, serverCipherStrs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        if (negotiatedCipher == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
            throw new SaslException("DIGEST-MD5: Unable to negotiate " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
                "a strength level for 'auth-conf'");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
        logger.log(Level.FINE, "DIGEST63:Cipher suite: {0}", negotiatedCipher);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
     * Steps through the ordered 'strength' array, and compares it with
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
     * the 'supportedCiphers' array. The cipher returned represents
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
     * the best possible cipher based on the strength preference and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
     * available ciphers on both the server and client environments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
     * @param tokens The array of cipher tokens sent by server
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
     * @return The agreed cipher.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
    private String findCipherAndStrength(byte[] supportedCiphers,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        String[] tokens) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        byte s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        for (int i = 0; i < strength.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            if ((s=strength[i]) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
                for (int j = 0; j < supportedCiphers.length; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
                    // If user explicitly requested cipher, then it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                    // must be the one we choose
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                    if (s == supportedCiphers[j] &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
                        (specifiedCipher == null ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
                            specifiedCipher.equals(tokens[j]))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                        switch (s) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                        case HIGH_STRENGTH:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                            negotiatedStrength = "high";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                        case MEDIUM_STRENGTH:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                            negotiatedStrength = "medium";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                        case LOW_STRENGTH:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                            negotiatedStrength = "low";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                        return tokens[j];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
        return null;  // none found
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
     * Returns digest-response suitable for an initial authentication.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
     * The following are qdstr-val (quoted string values) as per RFC 2831,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
     * which means that any embedded quotes must be escaped.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
     *    realm-value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
     *    nonce-value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
     *    username-value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
     *    cnonce-value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
     *    authzid-value
32275
17eeb583a331 8133802: replace some <tt> tags (obsolete in html5) in security-libs docs
avstepan
parents: 25859
diff changeset
   570
     * @return {@code digest-response} in a byte array
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
     * @throws SaslException if there is an error generating the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
     * response value or the cnonce value.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
    private byte[] generateClientResponse(byte[] charset) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
        ByteArrayOutputStream digestResp = new ByteArrayOutputStream();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
        if (useUTF8) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
            digestResp.write("charset=".getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
            digestResp.write(charset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
            digestResp.write(',');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
        digestResp.write(("username=\"" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            quotedStringValue(username) + "\",").getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
        if (negotiatedRealm.length() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
            digestResp.write(("realm=\"" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
                quotedStringValue(negotiatedRealm) + "\",").getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
        digestResp.write("nonce=\"".getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
        writeQuotedStringValue(digestResp, nonce);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
        digestResp.write('"');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        digestResp.write(',');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
        nonceCount = getNonceCount(nonce);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
        digestResp.write(("nc=" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
            nonceCountToHex(nonceCount) + ",").getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        cnonce = generateNonce();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
        digestResp.write("cnonce=\"".getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
        writeQuotedStringValue(digestResp, cnonce);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
        digestResp.write("\",".getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
        digestResp.write(("digest-uri=\"" + digestUri + "\",").getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        digestResp.write("maxbuf=".getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
        digestResp.write(String.valueOf(recvMaxBufSize).getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
        digestResp.write(',');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
            digestResp.write("response=".getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
            digestResp.write(generateResponseValue("AUTHENTICATE",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
                digestUri, negotiatedQop, username,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
                negotiatedRealm, passwd, nonce, cnonce,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
                nonceCount, authzidBytes));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
            digestResp.write(',');
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
            throw new SaslException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                "DIGEST-MD5: Error generating response value", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        digestResp.write(("qop=" + negotiatedQop).getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        if (negotiatedCipher != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
            digestResp.write((",cipher=\"" + negotiatedCipher + "\"").getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        if (authzidBytes != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
            digestResp.write(",authzid=\"".getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
            writeQuotedStringValue(digestResp, authzidBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            digestResp.write("\"".getBytes(encoding));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        if (digestResp.size() > MAX_RESPONSE_LENGTH) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
            throw new SaslException ("DIGEST-MD5: digest-response size too " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
                "large. Length: "  + digestResp.size());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
        return digestResp.toByteArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
     }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
     * From RFC 2831, Section 2.1.3: Step Three
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
     * [Server] sends a message formatted as follows:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
     *     response-auth = "rspauth" "=" response-value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
     * where response-value is calculated as above, using the values sent in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
     * step two, except that if qop is "auth", then A2 is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
     *  A2 = { ":", digest-uri-value }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
     * And if qop is "auth-int" or "auth-conf" then A2 is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
     *  A2 = { ":", digest-uri-value, ":00000000000000000000000000000000" }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    private void validateResponseValue(byte[] fromServer) throws SaslException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
        if (fromServer == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
            throw new SaslException("DIGEST-MD5: Authenication failed. " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
                "Expecting 'rspauth' authentication success message");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
            byte[] expected = generateResponseValue("",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
                digestUri, negotiatedQop, username, negotiatedRealm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
                passwd, nonce, cnonce,  nonceCount, authzidBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
            if (!Arrays.equals(expected, fromServer)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                /* Server's rspauth value does not match */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
                throw new SaslException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
                    "Server's rspauth value does not match what client expects");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        } catch (NoSuchAlgorithmException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
            throw new SaslException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
                "Problem generating response value for verification", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
            throw new SaslException(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
                "Problem generating response value for verification", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
     * Returns the number of requests (including current request)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
     * that the client has sent in response to nonceValue.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
     * This is 1 the first time nonceValue is seen.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
     * We don't cache nonce values seen, and we don't support subsequent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
     * authentication, so the value is always 1.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    private static int getNonceCount(byte[] nonceValue) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
        return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
    private void clearPassword() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        if (passwd != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
            for (int i = 0; i < passwd.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
                passwd[i] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
            passwd = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
}