src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11RSACipher.java
author mbalao
Thu, 29 Nov 2018 13:36:23 -0300
changeset 53257 5170dc2bcf64
parent 47216 71c04702a3d5
child 54062 62ab0859e7e5
permissions -rw-r--r--
6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space Summary: Extract cryptographic keys within NSS PKCS11 software tokens for memory management purposes. Reviewed-by: valeriep
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
     2
 * Copyright (c) 2003, 2018, 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: 5291
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: 5291
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: 5291
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5291
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 5291
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.pkcs11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.security.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.security.spec.AlgorithmParameterSpec;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.security.spec.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
6122
16fa7ed7ff1b 6867345: Turkish regional options cause NPE in sun.security.x509.AlgorithmId.algOID
xuelei
parents: 5506
diff changeset
    32
import java.util.Locale;
16fa7ed7ff1b 6867345: Turkish regional options cause NPE in sun.security.x509.AlgorithmId.algOID
xuelei
parents: 5506
diff changeset
    33
2
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
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import static sun.security.pkcs11.TemplateManager.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import sun.security.pkcs11.wrapper.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
    40
import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
    41
import sun.security.util.KeyUtil;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * RSA Cipher implementation class. We currently only support
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * PKCS#1 v1.5 padding on top of CKM_RSA_PKCS.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * @author  Andreas Sterbenz
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * @since   1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
final class P11RSACipher extends CipherSpi {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
    // minimum length of PKCS#1 v1.5 padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
    private final static int PKCS1_MIN_PADDING_LENGTH = 11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
    // constant byte[] of length 0
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    private final static byte[] B0 = new byte[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
    // mode constant for public key encryption
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    private final static int MODE_ENCRYPT = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    // mode constant for private key decryption
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    private final static int MODE_DECRYPT = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    // mode constant for private key encryption (signing)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
    private final static int MODE_SIGN    = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    // mode constant for public key decryption (verifying)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
    private final static int MODE_VERIFY  = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
8578
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
    67
    // padding type constant for NoPadding
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
    68
    private final static int PAD_NONE = 1;
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
    69
    // padding type constant for PKCS1Padding
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
    70
    private final static int PAD_PKCS1 = 2;
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
    71
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    // token instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    private final Token token;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    // algorithm name (always "RSA")
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    private final String algorithm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    // mechanism id
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    private final long mechanism;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    // associated session, if any
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    private Session session;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    // mode, one of MODE_* above
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    private int mode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
8578
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
    87
    // padding, one of PAD_* above
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
    88
    private int padType;
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
    89
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    private byte[] buffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    private int bufOfs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    // key, if init() was called
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    private P11Key p11Key;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    // flag indicating whether an operation is initialized
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    private boolean initialized;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    // maximum input data size allowed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    // for decryption, this is the length of the key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    // for encryption, length of the key minus minimum padding length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    private int maxInputSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    // maximum output size. this is the length of the key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    private int outputSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   107
    // cipher parameter for TLS RSA premaster secret
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   108
    private AlgorithmParameterSpec spec = null;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   109
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   110
    // the source of randomness
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   111
    private SecureRandom random;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   112
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    P11RSACipher(Token token, String algorithm, long mechanism)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
            throws PKCS11Exception {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        super();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        this.token = token;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
        this.algorithm = "RSA";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        this.mechanism = mechanism;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    // modes do not make sense for RSA, but allow ECB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
        if (mode.equalsIgnoreCase("ECB") == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
            throw new NoSuchAlgorithmException("Unsupported mode " + mode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    protected void engineSetPadding(String padding)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
            throws NoSuchPaddingException {
6122
16fa7ed7ff1b 6867345: Turkish regional options cause NPE in sun.security.x509.AlgorithmId.algOID
xuelei
parents: 5506
diff changeset
   131
        String lowerPadding = padding.toLowerCase(Locale.ENGLISH);
8578
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
   132
        if (lowerPadding.equals("pkcs1padding")) {
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
   133
            padType = PAD_PKCS1;
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
   134
        } else if (lowerPadding.equals("nopadding")) {
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
   135
            padType = PAD_NONE;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
            throw new NoSuchPaddingException("Unsupported padding " + padding);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    // return 0 as block size, we are not a block cipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    protected int engineGetBlockSize() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    // return the output size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    protected int engineGetOutputSize(int inputLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        return outputSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
    // no IV, return null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
    protected byte[] engineGetIV() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
    // no parameters, return null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
    protected AlgorithmParameters engineGetParameters() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    protected void engineInit(int opmode, Key key, SecureRandom random)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
            throws InvalidKeyException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        implInit(opmode, key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    // see JCE spec
27936
ca9ee8e3d527 8066638: Suppress deprecation warnings in jdk.crypto module
darcy
parents: 25859
diff changeset
   172
    @SuppressWarnings("deprecation")
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    protected void engineInit(int opmode, Key key,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
            AlgorithmParameterSpec params, SecureRandom random)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
            throws InvalidKeyException, InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        if (params != null) {
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   177
            if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   178
                throw new InvalidAlgorithmParameterException(
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   179
                        "Parameters not supported");
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   180
            }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   181
            spec = params;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   182
            this.random = random;   // for TLS RSA premaster secret
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        implInit(opmode, key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    protected void engineInit(int opmode, Key key, AlgorithmParameters params,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            SecureRandom random)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            throws InvalidKeyException, InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        if (params != null) {
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   192
            throw new InvalidAlgorithmParameterException(
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   193
                        "Parameters not supported");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        implInit(opmode, key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    private void implInit(int opmode, Key key) throws InvalidKeyException {
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   199
        reset(true);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        p11Key = P11KeyFactory.convertKey(token, key, algorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        boolean encrypt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        if (opmode == Cipher.ENCRYPT_MODE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            encrypt = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        } else if (opmode == Cipher.DECRYPT_MODE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            encrypt = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        } else if (opmode == Cipher.WRAP_MODE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            if (p11Key.isPublic() == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                throw new InvalidKeyException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                                ("Wrap has to be used with public keys");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            }
290
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   211
            // No further setup needed for C_Wrap(). We'll initialize later if
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   212
            // we can't use C_Wrap().
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        } else if (opmode == Cipher.UNWRAP_MODE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            if (p11Key.isPrivate() == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                throw new InvalidKeyException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                                ("Unwrap has to be used with private keys");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            }
2180
9994f4f08a59 6812738: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes with PCKS11 provider
valeriep
parents: 290
diff changeset
   219
            // No further setup needed for C_Unwrap(). We'll initialize later
9994f4f08a59 6812738: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes with PCKS11 provider
valeriep
parents: 290
diff changeset
   220
            // if we can't use C_Unwrap().
9994f4f08a59 6812738: SSL stress test with GF leads to 32 bit max process size in less than 5 minutes with PCKS11 provider
valeriep
parents: 290
diff changeset
   221
            return;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
            throw new InvalidKeyException("Unsupported mode: " + opmode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        if (p11Key.isPublic()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
            mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        } else if (p11Key.isPrivate()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            mode = encrypt ? MODE_SIGN : MODE_DECRYPT;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            throw new InvalidKeyException("Unknown key type: " + p11Key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
        }
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 8578
diff changeset
   232
        int n = (p11Key.length() + 7) >> 3;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        outputSize = n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        buffer = new byte[n];
8578
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
   235
        maxInputSize = ((padType == PAD_PKCS1 && encrypt) ?
f5d3509ad92b 6994008: PKCS11 should support "RSA" and "RSA/ECB/NoPadding" ciphers
valeriep
parents: 6122
diff changeset
   236
                            (n - PKCS1_MIN_PADDING_LENGTH) : n);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
            initialize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        } catch (PKCS11Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
            throw new InvalidKeyException("init() failed", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   244
    // reset the states to the pre-initialized values
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   245
    private void reset(boolean doCancel) {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   246
        if (!initialized) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        initialized = false;
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   250
        try {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   251
            if (session == null) {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   252
                return;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   253
            }
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   254
            if (doCancel && token.explicitCancel) {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   255
                cancelOperation();
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   256
            }
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   257
        } finally {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   258
            p11Key.releaseKeyID();
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   259
            session = token.releaseSession(session);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        }
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   261
    }
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   262
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   263
    // should only called by reset as this method does not update other
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   264
    // state variables such as "initialized"
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   265
    private void cancelOperation() {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   266
        token.ensureValid();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
        if (session.hasObjects() == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            session = token.killSession(session);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            return;
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   270
        } else {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   271
            try {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   272
                PKCS11 p11 = token.p11;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   273
                int inLen = maxInputSize;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   274
                int outLen = buffer.length;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   275
                long sessId = session.id();
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   276
                switch (mode) {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   277
                case MODE_ENCRYPT:
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   278
                    p11.C_Encrypt(sessId, buffer, 0, inLen, buffer, 0, outLen);
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   279
                    break;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   280
                case MODE_DECRYPT:
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   281
                    p11.C_Decrypt(sessId, buffer, 0, inLen, buffer, 0, outLen);
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   282
                    break;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   283
                case MODE_SIGN:
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   284
                    byte[] tmpBuffer = new byte[maxInputSize];
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   285
                    p11.C_Sign(sessId, tmpBuffer);
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   286
                    break;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   287
                case MODE_VERIFY:
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   288
                    p11.C_VerifyRecover(sessId, buffer, 0, inLen, buffer,
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   289
                            0, outLen);
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   290
                    break;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   291
                default:
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   292
                    throw new ProviderException("internal error");
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   293
                }
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   294
            } catch (PKCS11Exception e) {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   295
                // XXX ensure this always works, ignore error
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    private void ensureInitialized() throws PKCS11Exception {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        token.ensureValid();
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   302
        if (!initialized) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
            initialize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    private void initialize() throws PKCS11Exception {
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   308
        if (p11Key == null) {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   309
            throw new ProviderException(
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   310
                    "Operation cannot be performed without " +
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   311
                    "calling engineInit first");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        }
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   313
        long keyID = p11Key.getKeyID();
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   314
        try {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   315
            if (session == null) {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   316
                session = token.getOpSession();
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   317
            }
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   318
            PKCS11 p11 = token.p11;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   319
            CK_MECHANISM ckMechanism = new CK_MECHANISM(mechanism);
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   320
            switch (mode) {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   321
            case MODE_ENCRYPT:
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   322
                p11.C_EncryptInit(session.id(), ckMechanism, keyID);
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   323
                break;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   324
            case MODE_DECRYPT:
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   325
                p11.C_DecryptInit(session.id(), ckMechanism, keyID);
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   326
                break;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   327
            case MODE_SIGN:
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   328
                p11.C_SignInit(session.id(), ckMechanism, keyID);
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   329
                break;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   330
            case MODE_VERIFY:
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   331
                p11.C_VerifyRecoverInit(session.id(), ckMechanism, keyID);
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   332
                break;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   333
            default:
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   334
                throw new AssertionError("internal error");
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   335
            }
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   336
            bufOfs = 0;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   337
            initialized = true;
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   338
        } catch (PKCS11Exception e) {
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   339
            p11Key.releaseKeyID();
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   340
            session = token.releaseSession(session);
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   341
            throw e;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
    private void implUpdate(byte[] in, int inOfs, int inLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
            ensureInitialized();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        } catch (PKCS11Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
            throw new ProviderException("update() failed", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        if ((inLen == 0) || (in == null)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
        if (bufOfs + inLen > maxInputSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
            bufOfs = maxInputSize + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        System.arraycopy(in, inOfs, buffer, bufOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        bufOfs += inLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    private int implDoFinal(byte[] out, int outOfs, int outLen)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
            throws BadPaddingException, IllegalBlockSizeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
        if (bufOfs > maxInputSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
            throw new IllegalBlockSizeException("Data must not be longer "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                + "than " + maxInputSize + " bytes");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
            ensureInitialized();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
            PKCS11 p11 = token.p11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
            int n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
            switch (mode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
            case MODE_ENCRYPT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                n = p11.C_Encrypt
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                        (session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            case MODE_DECRYPT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
                n = p11.C_Decrypt
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
                        (session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            case MODE_SIGN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                byte[] tmpBuffer = new byte[bufOfs];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
                System.arraycopy(buffer, 0, tmpBuffer, 0, bufOfs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
                tmpBuffer = p11.C_Sign(session.id(), tmpBuffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
                if (tmpBuffer.length > outLen) {
40544
807dd9a425db 8150530: Improve javax.crypto.BadPaddingException messages
coffeys
parents: 35287
diff changeset
   386
                    throw new BadPaddingException(
807dd9a425db 8150530: Improve javax.crypto.BadPaddingException messages
coffeys
parents: 35287
diff changeset
   387
                        "Output buffer (" + outLen + ") is too small to " +
807dd9a425db 8150530: Improve javax.crypto.BadPaddingException messages
coffeys
parents: 35287
diff changeset
   388
                        "hold the produced data (" + tmpBuffer.length + ")");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
                System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
                n = tmpBuffer.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
            case MODE_VERIFY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
                n = p11.C_VerifyRecover
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
                        (session.id(), buffer, 0, bufOfs, out, outOfs, outLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
            default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
                throw new ProviderException("internal error");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
            return n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        } catch (PKCS11Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            throw (BadPaddingException)new BadPaddingException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
                ("doFinal() failed").initCause(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        } finally {
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   405
            reset(false);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
    protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        implUpdate(in, inOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        return B0;
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 engineUpdate(byte[] in, int inOfs, int inLen,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
            byte[] out, int outOfs) throws ShortBufferException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        implUpdate(in, inOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            throws IllegalBlockSizeException, BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        implUpdate(in, inOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        int n = implDoFinal(buffer, 0, buffer.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        byte[] out = new byte[n];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        System.arraycopy(buffer, 0, out, 0, n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        return out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
    protected int engineDoFinal(byte[] in, int inOfs, int inLen,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            byte[] out, int outOfs) throws ShortBufferException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            IllegalBlockSizeException, BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        implUpdate(in, inOfs, inLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        return implDoFinal(out, outOfs, out.length - outOfs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
290
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   440
    private byte[] doFinal() throws BadPaddingException,
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   441
            IllegalBlockSizeException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        byte[] t = new byte[2048];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        int n = implDoFinal(t, 0, t.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        byte[] out = new byte[n];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        System.arraycopy(t, 0, out, 0, n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        return out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
    protected byte[] engineWrap(Key key) throws InvalidKeyException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            IllegalBlockSizeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        String keyAlg = key.getAlgorithm();
290
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   453
        P11Key sKey = null;
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   454
        try {
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   455
            // The conversion may fail, e.g. trying to wrap an AES key on
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   456
            // a token that does not support AES, or when the key size is
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   457
            // not within the range supported by the token.
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   458
            sKey = P11SecretKeyFactory.convertKey(token, key, keyAlg);
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   459
        } catch (InvalidKeyException ike) {
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   460
            byte[] toBeWrappedKey = key.getEncoded();
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   461
            if (toBeWrappedKey == null) {
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   462
                throw new InvalidKeyException
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   463
                        ("wrap() failed, no encoding available", ike);
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   464
            }
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   465
            // Directly encrypt the key encoding when key conversion failed
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   466
            implInit(Cipher.ENCRYPT_MODE, p11Key);
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   467
            implUpdate(toBeWrappedKey, 0, toBeWrappedKey.length);
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   468
            try {
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   469
                return doFinal();
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   470
            } catch (BadPaddingException bpe) {
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   471
                // should not occur
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   472
                throw new InvalidKeyException("wrap() failed", bpe);
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   473
            } finally {
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   474
                // Restore original mode
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   475
                implInit(Cipher.WRAP_MODE, p11Key);
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   476
            }
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   477
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        Session s = null;
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   479
        long p11KeyID = p11Key.getKeyID();
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   480
        long sKeyID = sKey.getKeyID();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
            s = token.getOpSession();
290
519d4185fbe2 6572331: regression: cipher.wrap operation fails with CKR_ATTRIBUTE_VALUE_INVALID
valeriep
parents: 2
diff changeset
   483
            return token.p11.C_WrapKey(s.id(), new CK_MECHANISM(mechanism),
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   484
                    p11KeyID, sKeyID);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        } catch (PKCS11Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
            throw new InvalidKeyException("wrap() failed", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
        } finally {
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   488
            p11Key.releaseKeyID();
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   489
            sKey.releaseKeyID();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
            token.releaseSession(s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
    // see JCE spec
27936
ca9ee8e3d527 8066638: Suppress deprecation warnings in jdk.crypto module
darcy
parents: 25859
diff changeset
   495
    @SuppressWarnings("deprecation")
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
    protected Key engineUnwrap(byte[] wrappedKey, String algorithm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
            int type) throws InvalidKeyException, NoSuchAlgorithmException {
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 11521
diff changeset
   498
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   499
        boolean isTlsRsaPremasterSecret =
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   500
                algorithm.equals("TlsRsaPremasterSecret");
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   501
        Exception failover = null;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   502
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   503
        // Should C_Unwrap be preferred for non-TLS RSA premaster secret?
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   504
        if (token.supportsRawSecretKeyImport()) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   505
            // XXX implement unwrap using C_Unwrap() for all keys
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   506
            implInit(Cipher.DECRYPT_MODE, p11Key);
35287
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   507
            try {
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   508
                if (wrappedKey.length > maxInputSize) {
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   509
                    throw new InvalidKeyException("Key is too long for unwrapping");
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   510
                }
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   511
35287
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   512
                byte[] encoded = null;
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   513
                implUpdate(wrappedKey, 0, wrappedKey.length);
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   514
                try {
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   515
                    encoded = doFinal();
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   516
                } catch (BadPaddingException e) {
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   517
                    if (isTlsRsaPremasterSecret) {
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   518
                        failover = e;
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   519
                    } else {
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   520
                        throw new InvalidKeyException("Unwrapping failed", e);
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   521
                    }
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   522
                } catch (IllegalBlockSizeException e) {
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   523
                    // should not occur, handled with length check above
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   524
                    throw new InvalidKeyException("Unwrapping failed", e);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   525
                }
35287
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   526
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   527
                if (isTlsRsaPremasterSecret) {
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   528
                    if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   529
                        throw new IllegalStateException(
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   530
                                "No TlsRsaPremasterSecretParameterSpec specified");
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   531
                    }
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   532
35287
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   533
                    // polish the TLS premaster secret
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   534
                    TlsRsaPremasterSecretParameterSpec psps =
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   535
                            (TlsRsaPremasterSecretParameterSpec)spec;
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   536
                    encoded = KeyUtil.checkTlsPreMasterSecretKey(
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   537
                            psps.getClientVersion(), psps.getServerVersion(),
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   538
                            random, encoded, (failover != null));
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   539
                }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   540
35287
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   541
                return ConstructKeys.constructKey(encoded, algorithm, type);
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   542
            } finally {
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   543
                // Restore original mode
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   544
                implInit(Cipher.UNWRAP_MODE, p11Key);
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   545
            }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   546
        } else {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   547
            Session s = null;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   548
            SecretKey secretKey = null;
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   549
            long p11KeyID = p11Key.getKeyID();
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   550
            try {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   551
                try {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   552
                    s = token.getObjSession();
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   553
                    long keyType = CKK_GENERIC_SECRET;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   554
                    CK_ATTRIBUTE[] attributes = new CK_ATTRIBUTE[] {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   555
                            new CK_ATTRIBUTE(CKA_CLASS, CKO_SECRET_KEY),
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   556
                            new CK_ATTRIBUTE(CKA_KEY_TYPE, keyType),
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   557
                        };
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   558
                    attributes = token.getAttributes(
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   559
                            O_IMPORT, CKO_SECRET_KEY, keyType, attributes);
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   560
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   561
                    long keyID = token.p11.C_UnwrapKey(s.id(),
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   562
                                    new CK_MECHANISM(mechanism), p11KeyID,
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   563
                                    wrappedKey, attributes);
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   564
                    secretKey = P11Key.secretKey(s, keyID,
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   565
                            algorithm, 48 << 3, attributes);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   566
                } catch (PKCS11Exception e) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   567
                    if (isTlsRsaPremasterSecret) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   568
                        failover = e;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   569
                    } else {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   570
                        throw new InvalidKeyException("unwrap() failed", e);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   571
                    }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   572
                }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   573
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   574
                if (isTlsRsaPremasterSecret) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   575
                    TlsRsaPremasterSecretParameterSpec psps =
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   576
                            (TlsRsaPremasterSecretParameterSpec)spec;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   577
35287
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   578
                    // Please use the tricky failover as the parameter so that
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   579
                    // smart compiler won't dispose the unused variable.
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   580
                    secretKey = polishPreMasterSecretKey(token, s,
35287
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   581
                            failover, secretKey,
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   582
                            psps.getClientVersion(), psps.getServerVersion());
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   583
                }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   584
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   585
                return secretKey;
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   586
            } finally {
53257
5170dc2bcf64 6913047: Long term memory leak when using PKCS11 and JCE exceeds 32 bit process address space
mbalao
parents: 47216
diff changeset
   587
                p11Key.releaseKeyID();
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   588
                token.releaseSession(s);
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   589
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
    // see JCE spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
    protected int engineGetKeySize(Key key) throws InvalidKeyException {
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 8578
diff changeset
   595
        int n = P11KeyFactory.convertKey(token, key, algorithm).length();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
        return n;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    }
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   598
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   599
    private static SecretKey polishPreMasterSecretKey(
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   600
            Token token, Session session,
35287
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   601
            Exception failover, SecretKey unwrappedKey,
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   602
            int clientVersion, int serverVersion) {
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   603
35287
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   604
        SecretKey newKey;
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   605
        CK_VERSION version = new CK_VERSION(
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   606
                (clientVersion >>> 8) & 0xFF, clientVersion & 0xFF);
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   607
        try {
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   608
            CK_ATTRIBUTE[] attributes = token.getAttributes(
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   609
                    O_GENERATE, CKO_SECRET_KEY,
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   610
                    CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   611
            long keyID = token.p11.C_GenerateKey(session.id(),
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   612
                    new CK_MECHANISM(CKM_SSL3_PRE_MASTER_KEY_GEN, version),
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   613
                    attributes);
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   614
            newKey = P11Key.secretKey(session,
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   615
                    keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   616
        } catch (PKCS11Exception e) {
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   617
            throw new ProviderException(
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   618
                    "Could not generate premaster secret", e);
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   619
        }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   620
35287
e59d934ce2ba 8134605: Partial rework of the fix for 8081297
igerasim
parents: 27936
diff changeset
   621
        return (failover == null) ? unwrappedKey : newKey;
23733
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   622
    }
b9b80421cfa7 8028192: Use of PKCS11-NSS provider in FIPS mode broken
xuelei
parents: 22309
diff changeset
   623
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
final class ConstructKeys {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
     * Construct a public key from its encoding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
     * @param encodedKey the encoding of a public key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
     * @param encodedKeyAlgorithm the algorithm the encodedKey is for.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
     * @return a public key constructed from the encodedKey.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
    private static final PublicKey constructPublicKey(byte[] encodedKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
            String encodedKeyAlgorithm)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
            throws InvalidKeyException, NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
            KeyFactory keyFactory =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
                KeyFactory.getInstance(encodedKeyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
            return keyFactory.generatePublic(keySpec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        } catch (NoSuchAlgorithmException nsae) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
            throw new NoSuchAlgorithmException("No installed providers " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
                                               "can create keys for the " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
                                               encodedKeyAlgorithm +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
                                               "algorithm", nsae);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
        } catch (InvalidKeySpecException ike) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
            throw new InvalidKeyException("Cannot construct public key", ike);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
     * Construct a private key from its encoding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
     * @param encodedKey the encoding of a private key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
     * @param encodedKeyAlgorithm the algorithm the wrapped key is for.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
     * @return a private key constructed from the encodedKey.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
    private static final PrivateKey constructPrivateKey(byte[] encodedKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
            String encodedKeyAlgorithm) throws InvalidKeyException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
            NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
            KeyFactory keyFactory =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
                KeyFactory.getInstance(encodedKeyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
            return keyFactory.generatePrivate(keySpec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        } catch (NoSuchAlgorithmException nsae) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
            throw new NoSuchAlgorithmException("No installed providers " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
                                               "can create keys for the " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
                                               encodedKeyAlgorithm +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
                                               "algorithm", nsae);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        } catch (InvalidKeySpecException ike) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
            throw new InvalidKeyException("Cannot construct private key", ike);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
     * Construct a secret key from its encoding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
     * @param encodedKey the encoding of a secret key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
     * @param encodedKeyAlgorithm the algorithm the secret key is for.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
     * @return a secret key constructed from the encodedKey.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
    private static final SecretKey constructSecretKey(byte[] encodedKey,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
            String encodedKeyAlgorithm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
        return new SecretKeySpec(encodedKey, encodedKeyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
    static final Key constructKey(byte[] encoding, String keyAlgorithm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
            int keyType) throws InvalidKeyException, NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
        switch (keyType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
        case Cipher.SECRET_KEY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
            return constructSecretKey(encoding, keyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
        case Cipher.PRIVATE_KEY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
            return constructPrivateKey(encoding, keyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
        case Cipher.PUBLIC_KEY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
            return constructPublicKey(encoding, keyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
            throw new InvalidKeyException("Unknown keytype " + keyType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
}