jdk/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/RSACipher.java
author sundar
Mon, 31 Aug 2015 17:51:02 +0530
changeset 32434 769b3d81ae69
parent 28091 cbd670e95e2f
permissions -rw-r--r--
8134731: Function.prototype.apply interacts incorrectly with arguments Reviewed-by: attila, hannesw
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
28091
cbd670e95e2f 8067091: Fix Windows-specific deprecation warnings in the jdk.crypto.mscapi module
darcy
parents: 25859
diff changeset
     2
 * Copyright (c) 2005, 2014, 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
28091
cbd670e95e2f 8067091: Fix Windows-specific deprecation warnings in the jdk.crypto.mscapi module
darcy
parents: 25859
diff changeset
   162
    @SuppressWarnings("deprecation")
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    protected void engineInit(int opmode, Key key,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            AlgorithmParameterSpec params, SecureRandom random)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            throws InvalidKeyException, InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        if (params != null) {
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   168
            if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   169
                throw new InvalidAlgorithmParameterException(
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   170
                        "Parameters not supported");
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   171
            }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   172
            spec = params;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   173
            this.random = random;   // for TLS RSA premaster secret
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        init(opmode, key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    protected void engineInit(int opmode, Key key,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            AlgorithmParameters params, SecureRandom random)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
            throws InvalidKeyException, InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        if (params != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            throw new InvalidAlgorithmParameterException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
                ("Parameters not supported");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        init(opmode, key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
    // initialize this cipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    private void init(int opmode, Key key) throws InvalidKeyException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
        boolean encrypt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        switch (opmode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
        case Cipher.ENCRYPT_MODE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        case Cipher.WRAP_MODE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            paddingLength = PAD_PKCS1_LENGTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
            encrypt = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        case Cipher.DECRYPT_MODE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        case Cipher.UNWRAP_MODE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            paddingLength = 0; // reset
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
            encrypt = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            throw new InvalidKeyException("Unknown mode: " + opmode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        }
9505
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   209
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        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
   211
            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
   212
                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
   213
                    (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
   214
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   215
                // 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
   216
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   217
                BigInteger modulus = rsaKey.getModulus();
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   218
                BigInteger exponent =  rsaKey.getPublicExponent();
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   219
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   220
                // 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
   221
                // 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
   222
                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
   223
                    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
   224
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   225
                byte[] modulusBytes = modulus.toByteArray();
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   226
                byte[] exponentBytes = exponent.toByteArray();
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   227
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   228
                // 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
   229
                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
   230
                    ? (modulusBytes.length - 1) * 8
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   231
                    : modulusBytes.length * 8;
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   232
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   233
                byte[] keyBlob = RSASignature.generatePublicKeyBlob(
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   234
                    keyBitLength, modulusBytes, exponentBytes);
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   235
9508
310b4f6c8e61 6732372: Some MSCAPI native methods not returning correct exceptions.
vinnie
parents: 9505
diff changeset
   236
                try {
310b4f6c8e61 6732372: Some MSCAPI native methods not returning correct exceptions.
vinnie
parents: 9505
diff changeset
   237
                    key = RSASignature.importPublicKey(keyBlob, keyBitLength);
310b4f6c8e61 6732372: Some MSCAPI native methods not returning correct exceptions.
vinnie
parents: 9505
diff changeset
   238
310b4f6c8e61 6732372: Some MSCAPI native methods not returning correct exceptions.
vinnie
parents: 9505
diff changeset
   239
                } catch (KeyStoreException e) {
310b4f6c8e61 6732372: Some MSCAPI native methods not returning correct exceptions.
vinnie
parents: 9505
diff changeset
   240
                    throw new InvalidKeyException(e);
310b4f6c8e61 6732372: Some MSCAPI native methods not returning correct exceptions.
vinnie
parents: 9505
diff changeset
   241
                }
9505
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   242
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   243
            } else {
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   244
                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
   245
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        if (key instanceof PublicKey) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
            mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            publicKey = (sun.security.mscapi.Key)key;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
            privateKey = null;
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9508
diff changeset
   252
            outputSize = publicKey.length() / 8;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        } else if (key instanceof PrivateKey) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            mode = encrypt ? MODE_SIGN : MODE_DECRYPT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            privateKey = (sun.security.mscapi.Key)key;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            publicKey = null;
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 9508
diff changeset
   257
            outputSize = privateKey.length() / 8;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
            throw new InvalidKeyException("Unknown key type: " + key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        bufOfs = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        buffer = new byte[outputSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    // internal update method
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
    private void update(byte[] in, int inOfs, int inLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        if ((inLen == 0) || (in == null)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        if (bufOfs + inLen > (buffer.length - paddingLength)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            bufOfs = buffer.length + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        System.arraycopy(in, inOfs, buffer, bufOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        bufOfs += inLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    // internal doFinal() method. Here we perform the actual RSA operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    private byte[] doFinal() throws BadPaddingException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            IllegalBlockSizeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        if (bufOfs > buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
            throw new IllegalBlockSizeException("Data must not be longer "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                + "than " + (buffer.length - paddingLength)  + " bytes");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            byte[] data = buffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
            switch (mode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            case MODE_SIGN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                return encryptDecrypt(data, bufOfs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                    privateKey.getHCryptKey(), true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            case MODE_VERIFY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                return encryptDecrypt(data, bufOfs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                    publicKey.getHCryptKey(), false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            case MODE_ENCRYPT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                return encryptDecrypt(data, bufOfs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                    publicKey.getHCryptKey(), true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
            case MODE_DECRYPT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                return encryptDecrypt(data, bufOfs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
                    privateKey.getHCryptKey(), false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
                throw new AssertionError("Internal error");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        } catch (KeyException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            throw new ProviderException(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            bufOfs = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
    protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        update(in, inOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        return B0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
    protected int engineUpdate(byte[] in, int inOfs, int inLen, byte[] out,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            int outOfs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        update(in, inOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
    protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
            throws BadPaddingException, IllegalBlockSizeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        update(in, inOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        return doFinal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            int outOfs) throws ShortBufferException, BadPaddingException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
            IllegalBlockSizeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        if (outputSize > out.length - outOfs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            throw new ShortBufferException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                ("Need " + outputSize + " bytes for output");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        update(in, inOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        byte[] result = doFinal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        int n = result.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
        System.arraycopy(result, 0, out, outOfs, n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        return n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
    protected byte[] engineWrap(Key key) throws InvalidKeyException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            IllegalBlockSizeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
        byte[] encoded = key.getEncoded(); // TODO - unextractable key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
        if ((encoded == null) || (encoded.length == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
            throw new InvalidKeyException("Could not obtain encoded key");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
        if (encoded.length > buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
            throw new InvalidKeyException("Key is too long for wrapping");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        update(encoded, 0, encoded.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
            return doFinal();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
        } catch (BadPaddingException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
            // should not occur
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
            throw new InvalidKeyException("Wrapping failed", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    // see JCE spec
28091
cbd670e95e2f 8067091: Fix Windows-specific deprecation warnings in the jdk.crypto.mscapi module
darcy
parents: 25859
diff changeset
   373
    @SuppressWarnings("deprecation")
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   374
    protected java.security.Key engineUnwrap(byte[] wrappedKey,
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   375
            String algorithm,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
            int type) throws InvalidKeyException, NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
        if (wrappedKey.length > buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            throw new InvalidKeyException("Key is too long for unwrapping");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   382
        boolean isTlsRsaPremasterSecret =
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   383
                algorithm.equals("TlsRsaPremasterSecret");
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   384
        Exception failover = null;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   385
        byte[] encoded = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   387
        update(wrappedKey, 0, wrappedKey.length);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   388
        try {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   389
            encoded = doFinal();
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   390
        } catch (BadPaddingException e) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   391
            if (isTlsRsaPremasterSecret) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   392
                failover = e;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   393
            } else {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   394
                throw new InvalidKeyException("Unwrapping failed", e);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        } catch (IllegalBlockSizeException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
            // should not occur, handled with length check above
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
            throw new InvalidKeyException("Unwrapping failed", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        }
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   400
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   401
        if (isTlsRsaPremasterSecret) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   402
            if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   403
                throw new IllegalStateException(
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   404
                        "No TlsRsaPremasterSecretParameterSpec specified");
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   405
            }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   406
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   407
            // polish the TLS premaster secret
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   408
            encoded = KeyUtil.checkTlsPreMasterSecretKey(
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   409
                ((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(),
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   410
                ((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(),
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   411
                random, encoded, (failover != null));
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   412
        }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   413
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   414
        return constructKey(encoded, algorithm, type);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
    protected int engineGetKeySize(Key key) throws InvalidKeyException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        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
   421
            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
   422
3bbc6ff8a905 6888925: SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
vinnie
parents: 5506
diff changeset
   423
        } 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
   424
            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
   425
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
            throw new InvalidKeyException("Unsupported key type: " + key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
    // Construct an X.509 encoded public key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
    private static PublicKey constructPublicKey(byte[] encodedKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        String encodedKeyAlgorithm)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            throws InvalidKeyException, NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
            KeyFactory keyFactory = KeyFactory.getInstance(encodedKeyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            return keyFactory.generatePublic(keySpec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        } catch (NoSuchAlgorithmException nsae) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            throw new NoSuchAlgorithmException("No installed provider " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                "supports the " + encodedKeyAlgorithm + " algorithm", nsae);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        } catch (InvalidKeySpecException ike) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
            throw new InvalidKeyException("Cannot construct public key", ike);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
    // Construct a PKCS #8 encoded private key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
    private static PrivateKey constructPrivateKey(byte[] encodedKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        String encodedKeyAlgorithm)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            throws InvalidKeyException, NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
            KeyFactory keyFactory = KeyFactory.getInstance(encodedKeyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            return keyFactory.generatePrivate(keySpec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        } catch (NoSuchAlgorithmException nsae) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
            throw new NoSuchAlgorithmException("No installed provider " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
                "supports the " + encodedKeyAlgorithm + " algorithm", nsae);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        } catch (InvalidKeySpecException ike) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
            throw new InvalidKeyException("Cannot construct private key", ike);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
    // Construct an encoded secret key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    private static SecretKey constructSecretKey(byte[] encodedKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        String encodedKeyAlgorithm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        return new SecretKeySpec(encodedKey, encodedKeyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   478
    private static Key constructKey(byte[] encodedKey,
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   479
            String encodedKeyAlgorithm,
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   480
            int keyType) throws InvalidKeyException, NoSuchAlgorithmException {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   481
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   482
        switch (keyType) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   483
            case Cipher.PUBLIC_KEY:
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   484
                return constructPublicKey(encodedKey, encodedKeyAlgorithm);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   485
            case Cipher.PRIVATE_KEY:
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   486
                return constructPrivateKey(encodedKey, encodedKeyAlgorithm);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   487
            case Cipher.SECRET_KEY:
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   488
                return constructSecretKey(encodedKey, encodedKeyAlgorithm);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   489
            default:
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   490
                throw new InvalidKeyException("Unknown key type " + keyType);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   491
        }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   492
    }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 11521
diff changeset
   493
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
     * Encrypt/decrypt a data buffer using Microsoft Crypto API with HCRYPTKEY.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
     * It expects and returns ciphertext data in big-endian form.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
    private native static byte[] encryptDecrypt(byte[] data, int dataSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        long hCryptKey, boolean doEncrypt) throws KeyException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
}