jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSACipher.java
author jwilhelm
Thu, 30 Oct 2014 01:01:37 +0100
changeset 27445 a8354c76ae20
parent 25859 3317bb8137f4
child 28091 cbd670e95e2f
permissions -rw-r--r--
Merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9508
diff changeset
     2
 * Copyright (c) 2005, 2012, 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: 3353
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: 3353
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: 3353
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3353
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 3353
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 sun.security.mscapi;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
9505
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
    28
import java.math.BigInteger;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.security.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.security.Key;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.security.interfaces.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.security.spec.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import javax.crypto.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import javax.crypto.spec.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
9505
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
    37
import sun.security.rsa.RSAKeyFactory;
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
    38
import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
    39
import sun.security.util.KeyUtil;
9505
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
    40
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * RSA cipher implementation using the Microsoft Crypto API.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * Supports RSA en/decryption and signing/verifying using PKCS#1 v1.5 padding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * Objects should be instantiated by calling Cipher.getInstance() using the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * following algorithm name:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 *  . "RSA/ECB/PKCS1Padding" (or "RSA") for PKCS#1 padding. The mode (blocktype)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 *    is selected based on the en/decryption mode and public/private key used.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * We only do one RSA operation per doFinal() call. If the application passes
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * more data via calls to update() or doFinal(), we throw an
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * IllegalBlockSizeException when doFinal() is called (see JCE API spec).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * Bulk encryption using RSA does not make sense and is not standardized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * Note: RSA keys should be at least 512 bits long
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * @since   1.6
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * @author  Andreas Sterbenz
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * @author  Vincent Ryan
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
public final class RSACipher extends CipherSpi {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    // constant for an empty byte array
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    private final static byte[] B0 = new byte[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    // mode constant for public key encryption
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
    private final static int MODE_ENCRYPT = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    // mode constant for private key decryption
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
    private final static int MODE_DECRYPT = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    // mode constant for private key encryption (signing)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    private final static int MODE_SIGN    = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    // mode constant for public key decryption (verifying)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    private final static int MODE_VERIFY  = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    // constant for PKCS#1 v1.5 RSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    private final static String PAD_PKCS1 = "PKCS1Padding";
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    private final static int PAD_PKCS1_LENGTH = 11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    // current mode, one of MODE_* above. Set when init() is called
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    private int mode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    // active padding type, one of PAD_* above. Set by setPadding()
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    private String paddingType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    private int paddingLength = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    // buffer for the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    private byte[] buffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    // offset into the buffer (number of bytes buffered)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    private int bufOfs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    // size of the output (the length of the key).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    private int outputSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    // the public key, if we were initialized using a public key
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    private sun.security.mscapi.Key publicKey;
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
    97
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    // the private key, if we were initialized using a private key
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    private sun.security.mscapi.Key privateKey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   101
    // cipher parameter for TLS RSA premaster secret
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   102
    private AlgorithmParameterSpec spec = null;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   103
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   104
    // the source of randomness
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   105
    private SecureRandom random;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   106
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    public RSACipher() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        paddingType = PAD_PKCS1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    // modes do not make sense for RSA, but allow ECB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        if (mode.equalsIgnoreCase("ECB") == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
            throw new NoSuchAlgorithmException("Unsupported mode " + mode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    // set the padding type
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    protected void engineSetPadding(String paddingName)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
            throws NoSuchPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        if (paddingName.equalsIgnoreCase(PAD_PKCS1)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
            paddingType = PAD_PKCS1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
            throw new NoSuchPaddingException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
                ("Padding " + paddingName + " not supported");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    // return 0 as block size, we are not a block cipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    protected int engineGetBlockSize() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    // return the output size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    protected int engineGetOutputSize(int inputLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        return outputSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    // no iv, return null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    protected byte[] engineGetIV() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    // no parameters, return null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    protected AlgorithmParameters engineGetParameters() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
    protected void engineInit(int opmode, Key key, SecureRandom random)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            throws InvalidKeyException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        init(opmode, key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    protected void engineInit(int opmode, Key key,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            AlgorithmParameterSpec params, SecureRandom random)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            throws InvalidKeyException, InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        if (params != null) {
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   167
            if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   168
                throw new InvalidAlgorithmParameterException(
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   169
                        "Parameters not supported");
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   170
            }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   171
            spec = params;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   172
            this.random = random;   // for TLS RSA premaster secret
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        init(opmode, key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    protected void engineInit(int opmode, Key key,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
            AlgorithmParameters params, SecureRandom random)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            throws InvalidKeyException, InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
        if (params != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
            throw new InvalidAlgorithmParameterException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
                ("Parameters not supported");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        init(opmode, key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
    // initialize this cipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    private void init(int opmode, Key key) throws InvalidKeyException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        boolean encrypt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        switch (opmode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        case Cipher.ENCRYPT_MODE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        case Cipher.WRAP_MODE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            paddingLength = PAD_PKCS1_LENGTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            encrypt = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        case Cipher.DECRYPT_MODE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        case Cipher.UNWRAP_MODE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            paddingLength = 0; // reset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            encrypt = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            throw new InvalidKeyException("Unknown mode: " + opmode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        }
9505
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   208
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        if (!(key instanceof sun.security.mscapi.Key)) {
9505
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   210
            if (key instanceof java.security.interfaces.RSAPublicKey) {
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   211
                java.security.interfaces.RSAPublicKey rsaKey =
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   212
                    (java.security.interfaces.RSAPublicKey) key;
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   213
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   214
                // Convert key to MSCAPI format
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   215
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   216
                BigInteger modulus = rsaKey.getModulus();
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   217
                BigInteger exponent =  rsaKey.getPublicExponent();
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   218
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   219
                // Check against the local and global values to make sure
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   220
                // the sizes are ok.  Round up to the nearest byte.
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   221
                RSAKeyFactory.checkKeyLengths(((modulus.bitLength() + 7) & ~7),
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   222
                    exponent, -1, RSAKeyPairGenerator.KEY_SIZE_MAX);
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   223
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   224
                byte[] modulusBytes = modulus.toByteArray();
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   225
                byte[] exponentBytes = exponent.toByteArray();
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   226
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   227
                // Adjust key length due to sign bit
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   228
                int keyBitLength = (modulusBytes[0] == 0)
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   229
                    ? (modulusBytes.length - 1) * 8
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   230
                    : modulusBytes.length * 8;
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   231
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   232
                byte[] keyBlob = RSASignature.generatePublicKeyBlob(
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   233
                    keyBitLength, modulusBytes, exponentBytes);
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   234
9508
310b4f6c8e61 6732372: Some MSCAPI native methods not returning correct exceptions.
vinnie
parents: 9505
diff changeset
   235
                try {
310b4f6c8e61 6732372: Some MSCAPI native methods not returning correct exceptions.
vinnie
parents: 9505
diff changeset
   236
                    key = RSASignature.importPublicKey(keyBlob, keyBitLength);
310b4f6c8e61 6732372: Some MSCAPI native methods not returning correct exceptions.
vinnie
parents: 9505
diff changeset
   237
310b4f6c8e61 6732372: Some MSCAPI native methods not returning correct exceptions.
vinnie
parents: 9505
diff changeset
   238
                } catch (KeyStoreException e) {
310b4f6c8e61 6732372: Some MSCAPI native methods not returning correct exceptions.
vinnie
parents: 9505
diff changeset
   239
                    throw new InvalidKeyException(e);
310b4f6c8e61 6732372: Some MSCAPI native methods not returning correct exceptions.
vinnie
parents: 9505
diff changeset
   240
                }
9505
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   241
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   242
            } else {
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   243
                throw new InvalidKeyException("Unsupported key type: " + key);
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   244
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        if (key instanceof PublicKey) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
            mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
            publicKey = (sun.security.mscapi.Key)key;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            privateKey = null;
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9508
diff changeset
   251
            outputSize = publicKey.length() / 8;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        } else if (key instanceof PrivateKey) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
            mode = encrypt ? MODE_SIGN : MODE_DECRYPT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            privateKey = (sun.security.mscapi.Key)key;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            publicKey = null;
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9508
diff changeset
   256
            outputSize = privateKey.length() / 8;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            throw new InvalidKeyException("Unknown key type: " + key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        bufOfs = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        buffer = new byte[outputSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
    // internal update method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    private void update(byte[] in, int inOfs, int inLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        if ((inLen == 0) || (in == null)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        if (bufOfs + inLen > (buffer.length - paddingLength)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            bufOfs = buffer.length + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        System.arraycopy(in, inOfs, buffer, bufOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        bufOfs += inLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
    // internal doFinal() method. Here we perform the actual RSA operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    private byte[] doFinal() throws BadPaddingException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            IllegalBlockSizeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        if (bufOfs > buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            throw new IllegalBlockSizeException("Data must not be longer "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                + "than " + (buffer.length - paddingLength)  + " bytes");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
            byte[] data = buffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            switch (mode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            case MODE_SIGN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                return encryptDecrypt(data, bufOfs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                    privateKey.getHCryptKey(), true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            case MODE_VERIFY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                return encryptDecrypt(data, bufOfs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                    publicKey.getHCryptKey(), false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
            case MODE_ENCRYPT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                return encryptDecrypt(data, bufOfs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                    publicKey.getHCryptKey(), true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
            case MODE_DECRYPT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                return encryptDecrypt(data, bufOfs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                    privateKey.getHCryptKey(), false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
                throw new AssertionError("Internal error");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        } catch (KeyException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            throw new ProviderException(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            bufOfs = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
        update(in, inOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        return B0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    protected int engineUpdate(byte[] in, int inOfs, int inLen, byte[] out,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            int outOfs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        update(in, inOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            throws BadPaddingException, IllegalBlockSizeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        update(in, inOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        return doFinal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
    protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            int outOfs) throws ShortBufferException, BadPaddingException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            IllegalBlockSizeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
        if (outputSize > out.length - outOfs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            throw new ShortBufferException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
                ("Need " + outputSize + " bytes for output");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        update(in, inOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        byte[] result = doFinal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        int n = result.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        System.arraycopy(result, 0, out, outOfs, n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
        return n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    protected byte[] engineWrap(Key key) throws InvalidKeyException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            IllegalBlockSizeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
        byte[] encoded = key.getEncoded(); // TODO - unextractable key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
        if ((encoded == null) || (encoded.length == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
            throw new InvalidKeyException("Could not obtain encoded key");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        if (encoded.length > buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
            throw new InvalidKeyException("Key is too long for wrapping");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        update(encoded, 0, encoded.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
            return doFinal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        } catch (BadPaddingException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
            // should not occur
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
            throw new InvalidKeyException("Wrapping failed", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
    // see JCE spec
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   372
    protected java.security.Key engineUnwrap(byte[] wrappedKey,
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   373
            String algorithm,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
            int type) throws InvalidKeyException, NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        if (wrappedKey.length > buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            throw new InvalidKeyException("Key is too long for unwrapping");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   380
        boolean isTlsRsaPremasterSecret =
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   381
                algorithm.equals("TlsRsaPremasterSecret");
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   382
        Exception failover = null;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   383
        byte[] encoded = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   385
        update(wrappedKey, 0, wrappedKey.length);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   386
        try {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   387
            encoded = doFinal();
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   388
        } catch (BadPaddingException e) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   389
            if (isTlsRsaPremasterSecret) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   390
                failover = e;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   391
            } else {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   392
                throw new InvalidKeyException("Unwrapping failed", e);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        } catch (IllegalBlockSizeException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            // should not occur, handled with length check above
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
            throw new InvalidKeyException("Unwrapping failed", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        }
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   398
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   399
        if (isTlsRsaPremasterSecret) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   400
            if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   401
                throw new IllegalStateException(
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   402
                        "No TlsRsaPremasterSecretParameterSpec specified");
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   403
            }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   404
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   405
            // polish the TLS premaster secret
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   406
            encoded = KeyUtil.checkTlsPreMasterSecretKey(
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   407
                ((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(),
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   408
                ((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(),
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   409
                random, encoded, (failover != null));
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   410
        }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   411
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   412
        return constructKey(encoded, algorithm, type);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    protected int engineGetKeySize(Key key) throws InvalidKeyException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        if (key instanceof sun.security.mscapi.Key) {
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9508
diff changeset
   419
            return ((sun.security.mscapi.Key) key).length();
9505
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   420
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   421
        } else if (key instanceof RSAKey) {
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   422
            return ((RSAKey) key).getModulus().bitLength();
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   423
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
            throw new InvalidKeyException("Unsupported key type: " + key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    // Construct an X.509 encoded public key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
    private static PublicKey constructPublicKey(byte[] encodedKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        String encodedKeyAlgorithm)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
            throws InvalidKeyException, NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            KeyFactory keyFactory = KeyFactory.getInstance(encodedKeyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            return keyFactory.generatePublic(keySpec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        } catch (NoSuchAlgorithmException nsae) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
            throw new NoSuchAlgorithmException("No installed provider " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
                "supports the " + encodedKeyAlgorithm + " algorithm", nsae);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        } catch (InvalidKeySpecException ike) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
            throw new InvalidKeyException("Cannot construct public key", ike);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
    // Construct a PKCS #8 encoded private key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
    private static PrivateKey constructPrivateKey(byte[] encodedKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        String encodedKeyAlgorithm)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
            throws InvalidKeyException, NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
            KeyFactory keyFactory = KeyFactory.getInstance(encodedKeyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
            return keyFactory.generatePrivate(keySpec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        } catch (NoSuchAlgorithmException nsae) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            throw new NoSuchAlgorithmException("No installed provider " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                "supports the " + encodedKeyAlgorithm + " algorithm", nsae);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
        } catch (InvalidKeySpecException ike) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
            throw new InvalidKeyException("Cannot construct private key", ike);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
    // Construct an encoded secret key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
    private static SecretKey constructSecretKey(byte[] encodedKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        String encodedKeyAlgorithm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        return new SecretKeySpec(encodedKey, encodedKeyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   476
    private static Key constructKey(byte[] encodedKey,
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   477
            String encodedKeyAlgorithm,
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   478
            int keyType) throws InvalidKeyException, NoSuchAlgorithmException {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   479
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   480
        switch (keyType) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   481
            case Cipher.PUBLIC_KEY:
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   482
                return constructPublicKey(encodedKey, encodedKeyAlgorithm);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   483
            case Cipher.PRIVATE_KEY:
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   484
                return constructPrivateKey(encodedKey, encodedKeyAlgorithm);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   485
            case Cipher.SECRET_KEY:
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   486
                return constructSecretKey(encodedKey, encodedKeyAlgorithm);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   487
            default:
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   488
                throw new InvalidKeyException("Unknown key type " + keyType);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   489
        }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   490
    }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   491
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
     * Encrypt/decrypt a data buffer using Microsoft Crypto API with HCRYPTKEY.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
     * It expects and returns ciphertext data in big-endian form.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
    private native static byte[] encryptDecrypt(byte[] data, int dataSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        long hCryptKey, boolean doEncrypt) throws KeyException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
}