jdk/src/share/classes/sun/security/util/KeyUtil.java
author xuelei
Wed, 09 Apr 2014 12:49:51 +0000
changeset 23733 b9b80421cfa7
parent 17916 e02ddef88f77
child 25540 021f6cd857f5
permissions -rw-r--r--
8028192: Use of PKCS11-NSS provider in FIPS mode broken Reviewed-by: ahgross, ascarpino, asmotrak
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
     1
/*
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
     2
 * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
     4
 *
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    10
 *
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    15
 * accompanied this code).
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    16
 *
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    20
 *
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    23
 * questions.
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    24
 */
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    25
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    26
package sun.security.util;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    27
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    28
import java.security.Key;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    29
import java.security.PrivilegedAction;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    30
import java.security.AccessController;
16080
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
    31
import java.security.InvalidKeyException;
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    32
import java.security.interfaces.ECKey;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    33
import java.security.interfaces.RSAKey;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    34
import java.security.interfaces.DSAKey;
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
    35
import java.security.SecureRandom;
16080
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
    36
import java.security.spec.KeySpec;
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    37
import javax.crypto.SecretKey;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    38
import javax.crypto.interfaces.DHKey;
16080
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
    39
import javax.crypto.interfaces.DHPublicKey;
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
    40
import javax.crypto.spec.DHParameterSpec;
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
    41
import javax.crypto.spec.DHPublicKeySpec;
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
    42
import java.math.BigInteger;
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    43
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    44
/**
16080
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
    45
 * A utility class to get key length, valiate keys, etc.
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    46
 */
16080
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
    47
public final class KeyUtil {
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    48
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    49
    /**
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    50
     * Returns the key size of the given key object in bits.
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    51
     *
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    52
     * @param key the key object, cannot be null
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    53
     * @return the key size of the given key object in bits, or -1 if the
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    54
     *       key size is not accessible
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    55
     */
16080
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
    56
    public static final int getKeySize(Key key) {
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    57
        int size = -1;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    58
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    59
        if (key instanceof Length) {
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    60
            try {
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    61
                Length ruler = (Length)key;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    62
                size = ruler.length();
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    63
            } catch (UnsupportedOperationException usoe) {
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    64
                // ignore the exception
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    65
            }
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    66
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    67
            if (size >= 0) {
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    68
                return size;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    69
            }
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    70
        }
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    71
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    72
        // try to parse the length from key specification
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    73
        if (key instanceof SecretKey) {
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    74
            SecretKey sk = (SecretKey)key;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    75
            String format = sk.getFormat();
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    76
            if ("RAW".equals(format) && sk.getEncoded() != null) {
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    77
                size = (sk.getEncoded().length * 8);
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    78
            }   // Otherwise, it may be a unextractable key of PKCS#11, or
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    79
                // a key we are not able to handle.
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    80
        } else if (key instanceof RSAKey) {
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    81
            RSAKey pubk = (RSAKey)key;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    82
            size = pubk.getModulus().bitLength();
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    83
        } else if (key instanceof ECKey) {
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    84
            ECKey pubk = (ECKey)key;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    85
            size = pubk.getParams().getOrder().bitLength();
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    86
        } else if (key instanceof DSAKey) {
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    87
            DSAKey pubk = (DSAKey)key;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    88
            size = pubk.getParams().getP().bitLength();
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    89
        } else if (key instanceof DHKey) {
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    90
            DHKey pubk = (DHKey)key;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    91
            size = pubk.getParams().getP().bitLength();
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    92
        }   // Otherwise, it may be a unextractable key of PKCS#11, or
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    93
            // a key we are not able to handle.
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    94
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    95
        return size;
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
    96
    }
16080
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
    97
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
    98
    /**
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
    99
     * Returns whether the key is valid or not.
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   100
     * <P>
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   101
     * Note that this method is only apply to DHPublicKey at present.
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   102
     *
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   103
     * @param  publicKey
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   104
     *         the key object, cannot be null
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   105
     *
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   106
     * @throws NullPointerException if {@code publicKey} is null
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   107
     * @throws InvalidKeyException if {@code publicKey} is invalid
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   108
     */
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   109
    public static final void validate(Key key)
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   110
            throws InvalidKeyException {
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   111
        if (key == null) {
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   112
            throw new NullPointerException(
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   113
                "The key to be validated cannot be null");
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   114
        }
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   115
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   116
        if (key instanceof DHPublicKey) {
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   117
            validateDHPublicKey((DHPublicKey)key);
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   118
        }
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   119
    }
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   120
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   121
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   122
    /**
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   123
     * Returns whether the key spec is valid or not.
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   124
     * <P>
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   125
     * Note that this method is only apply to DHPublicKeySpec at present.
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   126
     *
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   127
     * @param  keySpec
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   128
     *         the key spec object, cannot be null
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   129
     *
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   130
     * @throws NullPointerException if {@code keySpec} is null
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   131
     * @throws InvalidKeyException if {@code keySpec} is invalid
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   132
     */
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   133
    public static final void validate(KeySpec keySpec)
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   134
            throws InvalidKeyException {
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   135
        if (keySpec == null) {
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   136
            throw new NullPointerException(
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   137
                "The key spec to be validated cannot be null");
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   138
        }
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   139
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   140
        if (keySpec instanceof DHPublicKeySpec) {
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   141
            validateDHPublicKey((DHPublicKeySpec)keySpec);
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   142
        }
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   143
    }
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   144
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   145
    /**
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   146
     * Returns whether the specified provider is Oracle provider or not.
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   147
     * <P>
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   148
     * Note that this method is only apply to SunJCE and SunPKCS11 at present.
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   149
     *
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   150
     * @param  providerName
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   151
     *         the provider name
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   152
     * @return true if, and only if, the provider of the specified
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   153
     *         {@code providerName} is Oracle provider
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   154
     */
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   155
    public static final boolean isOracleJCEProvider(String providerName) {
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   156
        return providerName != null && (providerName.equals("SunJCE") ||
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   157
                                        providerName.startsWith("SunPKCS11"));
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   158
    }
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   159
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   160
    /**
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   161
     * Check the format of TLS PreMasterSecret.
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   162
     * <P>
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   163
     * To avoid vulnerabilities described by section 7.4.7.1, RFC 5246,
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   164
     * treating incorrectly formatted message blocks and/or mismatched
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   165
     * version numbers in a manner indistinguishable from correctly
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   166
     * formatted RSA blocks.
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   167
     *
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   168
     * RFC 5246 describes the approach as :
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   169
     *
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   170
     *  1. Generate a string R of 48 random bytes
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   171
     *
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   172
     *  2. Decrypt the message to recover the plaintext M
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   173
     *
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   174
     *  3. If the PKCS#1 padding is not correct, or the length of message
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   175
     *     M is not exactly 48 bytes:
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   176
     *        pre_master_secret = R
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   177
     *     else If ClientHello.client_version <= TLS 1.0, and version
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   178
     *     number check is explicitly disabled:
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   179
     *        premaster secret = M
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   180
     *     else If M[0..1] != ClientHello.client_version:
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   181
     *        premaster secret = R
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   182
     *     else:
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   183
     *        premaster secret = M
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   184
     *
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   185
     * Note that #2 should have completed before the call to this method.
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   186
     *
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   187
     * @param  clientVersion the version of the TLS protocol by which the
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   188
     *         client wishes to communicate during this session
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   189
     * @param  serverVersion the negotiated version of the TLS protocol which
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   190
     *         contains the lower of that suggested by the client in the client
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   191
     *         hello and the highest supported by the server.
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   192
     * @param  encoded the encoded key in its "RAW" encoding format
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   193
     * @param  isFailover whether or not the previous decryption of the
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   194
     *         encrypted PreMasterSecret message run into problem
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   195
     * @return the polished PreMasterSecret key in its "RAW" encoding format
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   196
     */
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   197
    public static byte[] checkTlsPreMasterSecretKey(
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   198
            int clientVersion, int serverVersion, SecureRandom random,
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   199
            byte[] encoded, boolean isFailOver) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   200
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   201
        if (random == null) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   202
            random = new SecureRandom();
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   203
        }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   204
        byte[] replacer = new byte[48];
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   205
        random.nextBytes(replacer);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   206
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   207
        if (!isFailOver && (encoded != null)) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   208
            // check the length
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   209
            if (encoded.length != 48) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   210
                // private, don't need to clone the byte array.
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   211
                return replacer;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   212
            }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   213
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   214
            int encodedVersion =
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   215
                    ((encoded[0] & 0xFF) << 8) | (encoded[1] & 0xFF);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   216
            if (clientVersion != encodedVersion) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   217
                if (clientVersion > 0x0301 ||               // 0x0301: TLSv1
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   218
                       serverVersion != encodedVersion) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   219
                    encoded = replacer;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   220
                }   // Otherwise, For compatibility, we maintain the behavior
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   221
                    // that the version in pre_master_secret can be the
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   222
                    // negotiated version for TLS v1.0 and SSL v3.0.
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   223
            }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   224
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   225
            // private, don't need to clone the byte array.
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   226
            return encoded;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   227
        }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   228
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   229
        // private, don't need to clone the byte array.
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   230
        return replacer;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   231
    }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   232
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 17916
diff changeset
   233
    /**
16080
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   234
     * Returns whether the Diffie-Hellman public key is valid or not.
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   235
     *
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   236
     * Per RFC 2631 and NIST SP800-56A, the following algorithm is used to
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   237
     * validate Diffie-Hellman public keys:
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   238
     * 1. Verify that y lies within the interval [2,p-1]. If it does not,
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   239
     *    the key is invalid.
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   240
     * 2. Compute y^q mod p. If the result == 1, the key is valid.
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   241
     *    Otherwise the key is invalid.
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   242
     */
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   243
    private static void validateDHPublicKey(DHPublicKey publicKey)
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   244
            throws InvalidKeyException {
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   245
        DHParameterSpec paramSpec = publicKey.getParams();
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   246
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   247
        BigInteger p = paramSpec.getP();
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   248
        BigInteger g = paramSpec.getG();
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   249
        BigInteger y = publicKey.getY();
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   250
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   251
        validateDHPublicKey(p, g, y);
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   252
    }
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   253
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   254
    private static void validateDHPublicKey(DHPublicKeySpec publicKeySpec)
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   255
            throws InvalidKeyException {
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   256
        validateDHPublicKey(publicKeySpec.getP(),
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   257
            publicKeySpec.getG(), publicKeySpec.getY());
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   258
    }
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   259
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   260
    private static void validateDHPublicKey(BigInteger p,
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   261
            BigInteger g, BigInteger y) throws InvalidKeyException {
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   262
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   263
        // For better interoperability, the interval is limited to [2, p-2].
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   264
        BigInteger leftOpen = BigInteger.ONE;
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   265
        BigInteger rightOpen = p.subtract(BigInteger.ONE);
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   266
        if (y.compareTo(leftOpen) <= 0) {
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   267
            throw new InvalidKeyException(
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   268
                    "Diffie-Hellman public key is too small");
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   269
        }
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   270
        if (y.compareTo(rightOpen) >= 0) {
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   271
            throw new InvalidKeyException(
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   272
                    "Diffie-Hellman public key is too large");
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   273
        }
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   274
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   275
        // Don't bother to check against the y^q mod p if safe primes are used.
0e6266b88242 7192392: Better validation of client keys
xuelei
parents: 11521
diff changeset
   276
    }
17916
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   277
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   278
    /**
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   279
     * Trim leading (most significant) zeroes from the result.
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   280
     *
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   281
     * @throws NullPointerException if {@code b} is null
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   282
     */
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   283
    public static byte[] trimZeroes(byte[] b) {
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   284
        int i = 0;
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   285
        while ((i < b.length - 1) && (b[i] == 0)) {
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   286
            i++;
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   287
        }
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   288
        if (i == 0) {
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   289
            return b;
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   290
        }
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   291
        byte[] t = new byte[b.length - i];
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   292
        System.arraycopy(b, i, t, 0, t.length);
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   293
        return t;
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   294
    }
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 16080
diff changeset
   295
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
   296
}
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents:
diff changeset
   297