jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Signature.java
author chegar
Sun, 17 Aug 2014 15:54:13 +0100
changeset 25859 3317bb8137f4
parent 25213 jdk/src/share/classes/sun/security/pkcs11/P11Signature.java@04804347bc19
child 27936 ca9ee8e3d527
permissions -rw-r--r--
8054834: Modular Source Code Reviewed-by: alanb, chegar, ihse, mduigou Contributed-by: alan.bateman@oracle.com, alex.buckley@oracle.com, chris.hegarty@oracle.com, erik.joelsson@oracle.com, jonathan.gibbons@oracle.com, karen.kinnear@oracle.com, magnus.ihse.bursie@oracle.com, mandy.chung@oracle.com, mark.reinhold@oracle.com, paul.sandoz@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
25213
04804347bc19 8046046: Test sun/security/pkcs11/Signature/TestDSAKeyLength.java fails intermittently on Solaris 11 in 8u40 nightly
valeriep
parents: 21848
diff changeset
     2
 * Copyright (c) 2003, 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: 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.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.math.BigInteger;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.nio.ByteBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.security.*;
5155
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
    33
import java.security.interfaces.*;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import sun.nio.ch.DirectBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import sun.security.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import sun.security.x509.AlgorithmId;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
import sun.security.rsa.RSASignature;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import sun.security.rsa.RSAPadding;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import sun.security.pkcs11.wrapper.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
17916
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 12685
diff changeset
    44
import sun.security.util.KeyUtil;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * Signature implementation class. This class currently supports the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * following algorithms:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * . DSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 *   . NONEwithDSA (RawDSA)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 *   . SHA1withDSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * . RSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 *   . MD2withRSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 *   . MD5withRSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 *   . SHA1withRSA
12685
8a448b5b9006 4963723: Implement SHA-224
valeriep
parents: 11521
diff changeset
    57
 *   . SHA224withRSA
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 *   . SHA256withRSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 *   . SHA384withRSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 *   . SHA512withRSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * . ECDSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 *   . NONEwithECDSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 *   . SHA1withECDSA
12685
8a448b5b9006 4963723: Implement SHA-224
valeriep
parents: 11521
diff changeset
    64
 *   . SHA224withECDSA
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 *   . SHA256withECDSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *   . SHA384withECDSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 *   . SHA512withECDSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * Note that the underlying PKCS#11 token may support complete signature
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * algorithm (e.g. CKM_DSA_SHA1, CKM_MD5_RSA_PKCS), or it may just
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
 * implement the signature algorithm without hashing (e.g. CKM_DSA, CKM_PKCS),
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
 * or it may only implement the raw public key operation (CKM_RSA_X_509).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
 * This class uses what is available and adds whatever extra processing
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * is needed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * @author  Andreas Sterbenz
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * @since   1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
final class P11Signature extends SignatureSpi {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    // token instance
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    private final Token token;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    // algorithm name
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    private final String algorithm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    // name of the key algorithm, currently either RSA or DSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    private final String keyAlgorithm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    // mechanism id
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    private final long mechanism;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
5155
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
    93
    // digest algorithm OID, if we encode RSA signature ourselves
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    private final ObjectIdentifier digestOID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    // type, one of T_* below
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    private final int type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    // key instance used, if init*() was called
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    private P11Key p11Key;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    // message digest, if we do the digesting ourselves
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    private final MessageDigest md;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    // associated session, if any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    private Session session;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
5155
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   108
    // mode, one of M_* below
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    private int mode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    // flag indicating whether an operation is initialized
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    private boolean initialized;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    // buffer, for update(byte) or DSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    private final byte[] buffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    // total number of bytes processed in current operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    private int bytesProcessed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    // constant for signing mode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    private final static int M_SIGN   = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    // constant for verification mode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    private final static int M_VERIFY = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    // constant for type digesting, we do the hashing ourselves
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    private final static int T_DIGEST = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    // constant for type update, token does everything
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    private final static int T_UPDATE = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    // constant for type raw, used with RawDSA and NONEwithECDSA only
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    private final static int T_RAW    = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    // XXX PKCS#11 v2.20 says "should not be longer than 1024 bits",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    // but this is a little arbitrary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    private final static int RAW_ECDSA_MAX = 128;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    P11Signature(Token token, String algorithm, long mechanism)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
            throws NoSuchAlgorithmException, PKCS11Exception {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        super();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        this.token = token;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        this.algorithm = algorithm;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        this.mechanism = mechanism;
5155
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   142
        byte[] buffer = null;
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   143
        ObjectIdentifier digestOID = null;
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   144
        MessageDigest md = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        switch ((int)mechanism) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        case (int)CKM_MD2_RSA_PKCS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        case (int)CKM_MD5_RSA_PKCS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        case (int)CKM_SHA1_RSA_PKCS:
12685
8a448b5b9006 4963723: Implement SHA-224
valeriep
parents: 11521
diff changeset
   149
        case (int)CKM_SHA224_RSA_PKCS:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        case (int)CKM_SHA256_RSA_PKCS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        case (int)CKM_SHA384_RSA_PKCS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        case (int)CKM_SHA512_RSA_PKCS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
            keyAlgorithm = "RSA";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
            type = T_UPDATE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            buffer = new byte[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        case (int)CKM_DSA_SHA1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            keyAlgorithm = "DSA";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
            type = T_UPDATE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            buffer = new byte[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        case (int)CKM_ECDSA_SHA1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            keyAlgorithm = "EC";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            type = T_UPDATE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            buffer = new byte[1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        case (int)CKM_DSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            keyAlgorithm = "DSA";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
            if (algorithm.equals("DSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
                type = T_DIGEST;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                md = MessageDigest.getInstance("SHA-1");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
            } else if (algorithm.equals("RawDSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
                type = T_RAW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
                buffer = new byte[20];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
                throw new ProviderException(algorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        case (int)CKM_ECDSA:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
            keyAlgorithm = "EC";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
            if (algorithm.equals("NONEwithECDSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
                type = T_RAW;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
                buffer = new byte[RAW_ECDSA_MAX];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
                String digestAlg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
                if (algorithm.equals("SHA1withECDSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
                    digestAlg = "SHA-1";
12685
8a448b5b9006 4963723: Implement SHA-224
valeriep
parents: 11521
diff changeset
   188
                } else if (algorithm.equals("SHA224withECDSA")) {
8a448b5b9006 4963723: Implement SHA-224
valeriep
parents: 11521
diff changeset
   189
                    digestAlg = "SHA-224";
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
                } else if (algorithm.equals("SHA256withECDSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
                    digestAlg = "SHA-256";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
                } else if (algorithm.equals("SHA384withECDSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
                    digestAlg = "SHA-384";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                } else if (algorithm.equals("SHA512withECDSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                    digestAlg = "SHA-512";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
                    throw new ProviderException(algorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                type = T_DIGEST;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
                md = MessageDigest.getInstance(digestAlg);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        case (int)CKM_RSA_PKCS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        case (int)CKM_RSA_X_509:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            keyAlgorithm = "RSA";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            type = T_DIGEST;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
            if (algorithm.equals("MD5withRSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                md = MessageDigest.getInstance("MD5");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                digestOID = AlgorithmId.MD5_oid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            } else if (algorithm.equals("SHA1withRSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                md = MessageDigest.getInstance("SHA-1");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                digestOID = AlgorithmId.SHA_oid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            } else if (algorithm.equals("MD2withRSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                md = MessageDigest.getInstance("MD2");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                digestOID = AlgorithmId.MD2_oid;
12685
8a448b5b9006 4963723: Implement SHA-224
valeriep
parents: 11521
diff changeset
   216
            } else if (algorithm.equals("SHA224withRSA")) {
8a448b5b9006 4963723: Implement SHA-224
valeriep
parents: 11521
diff changeset
   217
                md = MessageDigest.getInstance("SHA-224");
8a448b5b9006 4963723: Implement SHA-224
valeriep
parents: 11521
diff changeset
   218
                digestOID = AlgorithmId.SHA224_oid;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            } else if (algorithm.equals("SHA256withRSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
                md = MessageDigest.getInstance("SHA-256");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                digestOID = AlgorithmId.SHA256_oid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
            } else if (algorithm.equals("SHA384withRSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
                md = MessageDigest.getInstance("SHA-384");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
                digestOID = AlgorithmId.SHA384_oid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
            } else if (algorithm.equals("SHA512withRSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                md = MessageDigest.getInstance("SHA-512");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
                digestOID = AlgorithmId.SHA512_oid;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
                throw new ProviderException("Unknown signature: " + algorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            throw new ProviderException("Unknown mechanism: " + mechanism);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        }
5155
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   235
        this.buffer = buffer;
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   236
        this.digestOID = digestOID;
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   237
        this.md = md;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
    private void ensureInitialized() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        token.ensureValid();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        if (initialized == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
            initialize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
    private void cancelOperation() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        token.ensureValid();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
        if (initialized == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        initialized = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
        if ((session == null) || (token.explicitCancel == false)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        if (session.hasObjects() == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
            session = token.killSession(session);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        // "cancel" operation by finishing it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        // XXX make sure all this always works correctly
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        if (mode == M_SIGN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                if (type == T_UPDATE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                    token.p11.C_SignFinal(session.id(), 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
                    byte[] digest;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
                    if (type == T_DIGEST) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
                        digest = md.digest();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                    } else { // T_RAW
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                        digest = buffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                    token.p11.C_Sign(session.id(), digest);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
            } catch (PKCS11Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
                throw new ProviderException("cancel failed", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
        } else { // M_VERIFY
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                byte[] signature;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                if (keyAlgorithm.equals("DSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
                    signature = new byte[40];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                } else {
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 10336
diff changeset
   284
                    signature = new byte[(p11Key.length() + 7) >> 3];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                if (type == T_UPDATE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                    token.p11.C_VerifyFinal(session.id(), signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
                    byte[] digest;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                    if (type == T_DIGEST) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                        digest = md.digest();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                    } else { // T_RAW
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                        digest = buffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                    token.p11.C_Verify(session.id(), digest, signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
            } catch (PKCS11Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                // will fail since the signature is incorrect
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                // XXX check error code
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    // assumes current state is initialized == false
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    private void initialize() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
            if (session == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
                session = token.getOpSession();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            if (mode == M_SIGN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                token.p11.C_SignInit(session.id(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                        new CK_MECHANISM(mechanism), p11Key.keyID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
                token.p11.C_VerifyInit(session.id(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
                        new CK_MECHANISM(mechanism), p11Key.keyID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            initialized = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
        } catch (PKCS11Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            throw new ProviderException("Initialization failed", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        if (bytesProcessed != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            bytesProcessed = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
            if (md != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
                md.reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
21848
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   329
    private void checkKeySize(String keyAlgo, Key key)
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   330
        throws InvalidKeyException {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   331
        CK_MECHANISM_INFO mechInfo = null;
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   332
        try {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   333
            mechInfo = token.getMechanismInfo(mechanism);
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   334
        } catch (PKCS11Exception e) {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   335
            // should not happen, ignore for now.
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   336
        }
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   337
        if (mechInfo == null) {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   338
            // skip the check if no native info available
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   339
            return;
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   340
        }
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   341
        int minKeySize = (int) mechInfo.ulMinKeySize;
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   342
        int maxKeySize = (int) mechInfo.ulMaxKeySize;
25213
04804347bc19 8046046: Test sun/security/pkcs11/Signature/TestDSAKeyLength.java fails intermittently on Solaris 11 in 8u40 nightly
valeriep
parents: 21848
diff changeset
   343
        // need to override the MAX keysize for SHA1withDSA
04804347bc19 8046046: Test sun/security/pkcs11/Signature/TestDSAKeyLength.java fails intermittently on Solaris 11 in 8u40 nightly
valeriep
parents: 21848
diff changeset
   344
        if (md != null && mechanism == CKM_DSA && maxKeySize > 1024) {
04804347bc19 8046046: Test sun/security/pkcs11/Signature/TestDSAKeyLength.java fails intermittently on Solaris 11 in 8u40 nightly
valeriep
parents: 21848
diff changeset
   345
               maxKeySize = 1024;
04804347bc19 8046046: Test sun/security/pkcs11/Signature/TestDSAKeyLength.java fails intermittently on Solaris 11 in 8u40 nightly
valeriep
parents: 21848
diff changeset
   346
        }
21848
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   347
        int keySize = 0;
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   348
        if (key instanceof P11Key) {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   349
            keySize = ((P11Key) key).length();
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   350
        } else {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   351
            if (keyAlgo.equals("RSA")) {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   352
                keySize = ((RSAKey) key).getModulus().bitLength();
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   353
            } else if (keyAlgo.equals("DSA")) {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   354
                keySize = ((DSAKey) key).getParams().getP().bitLength();
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   355
            } else if (keyAlgo.equals("EC")) {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   356
                keySize = ((ECKey) key).getParams().getCurve().getField().getFieldSize();
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   357
            } else {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   358
                throw new ProviderException("Error: unsupported algo " + keyAlgo);
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   359
            }
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   360
        }
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   361
        if ((minKeySize != -1) && (keySize < minKeySize)) {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   362
            throw new InvalidKeyException(keyAlgo +
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   363
                " key must be at least " + minKeySize + " bits");
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   364
        }
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   365
        if ((maxKeySize != -1) && (keySize > maxKeySize)) {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   366
            throw new InvalidKeyException(keyAlgo +
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   367
                " key must be at most " + maxKeySize + " bits");
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   368
        }
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   369
        if (keyAlgo.equals("RSA")) {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   370
            checkRSAKeyLength(keySize);
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   371
        }
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   372
    }
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   373
5155
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   374
    private void checkRSAKeyLength(int len) throws InvalidKeyException {
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   375
        RSAPadding padding;
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   376
        try {
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   377
            padding = RSAPadding.getInstance
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   378
                (RSAPadding.PAD_BLOCKTYPE_1, (len + 7) >> 3);
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   379
        } catch (InvalidAlgorithmParameterException iape) {
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   380
            throw new InvalidKeyException(iape.getMessage());
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   381
        }
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   382
        int maxDataSize = padding.getMaxDataSize();
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   383
        int encodedLength;
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   384
        if (algorithm.equals("MD5withRSA") ||
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   385
            algorithm.equals("MD2withRSA")) {
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   386
            encodedLength = 34;
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   387
        } else if (algorithm.equals("SHA1withRSA")) {
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   388
            encodedLength = 35;
12685
8a448b5b9006 4963723: Implement SHA-224
valeriep
parents: 11521
diff changeset
   389
        } else if (algorithm.equals("SHA224withRSA")) {
8a448b5b9006 4963723: Implement SHA-224
valeriep
parents: 11521
diff changeset
   390
            encodedLength = 47;
5155
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   391
        } else if (algorithm.equals("SHA256withRSA")) {
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   392
            encodedLength = 51;
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   393
        } else if (algorithm.equals("SHA384withRSA")) {
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   394
            encodedLength = 67;
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   395
        } else if (algorithm.equals("SHA512withRSA")) {
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   396
            encodedLength = 83;
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   397
        } else {
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   398
            throw new ProviderException("Unknown signature algo: " + algorithm);
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   399
        }
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   400
        if (encodedLength > maxDataSize) {
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   401
            throw new InvalidKeyException
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   402
                ("Key is too short for this signature algorithm");
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   403
        }
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   404
    }
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   405
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
    // see JCA spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    protected void engineInitVerify(PublicKey publicKey)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
            throws InvalidKeyException {
5155
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   409
        if (publicKey == null) {
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   410
            throw new InvalidKeyException("Key must not be null");
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   411
        }
21848
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   412
        // Need to check key length whenever a new key is set
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   413
        if (publicKey != p11Key) {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   414
            checkKeySize(keyAlgorithm, publicKey);
5155
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   415
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        cancelOperation();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        mode = M_VERIFY;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        p11Key = P11KeyFactory.convertKey(token, publicKey, keyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        initialize();
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 JCA spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
    protected void engineInitSign(PrivateKey privateKey)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
            throws InvalidKeyException {
5155
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   425
        if (privateKey == null) {
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   426
            throw new InvalidKeyException("Key must not be null");
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   427
        }
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   428
        // Need to check RSA key length whenever a new key is set
21848
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   429
        if (privateKey != p11Key) {
3902d25a64b1 7200306: SunPKCS11 provider delays the check of DSA key size for SHA1withDSA to sign() instead of init()
valeriep
parents: 17916
diff changeset
   430
            checkKeySize(keyAlgorithm, privateKey);
5155
d70c73fdc68e 6695485: SignedObject constructor throws ProviderException if it's called using provider "SunPKCS11-Solaris"
valeriep
parents: 2
diff changeset
   431
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        cancelOperation();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
        mode = M_SIGN;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        p11Key = P11KeyFactory.convertKey(token, privateKey, keyAlgorithm);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        initialize();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    // see JCA spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    protected void engineUpdate(byte b) throws SignatureException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
        ensureInitialized();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        switch (type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        case T_UPDATE:
10336
0bb1999251f8 7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 5506
diff changeset
   443
            buffer[0] = b;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            engineUpdate(buffer, 0, 1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        case T_DIGEST:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
            md.update(b);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            bytesProcessed++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        case T_RAW:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            if (bytesProcessed >= buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                bytesProcessed = buffer.length + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
            buffer[bytesProcessed++] = b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
            throw new ProviderException("Internal error");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
    // see JCA spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
    protected void engineUpdate(byte[] b, int ofs, int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
            throws SignatureException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        ensureInitialized();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        if (len == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        switch (type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
        case T_UPDATE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
                if (mode == M_SIGN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
                    token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
                    token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                bytesProcessed += len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
            } catch (PKCS11Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                throw new ProviderException(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        case T_DIGEST:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
            md.update(b, ofs, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
            bytesProcessed += len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        case T_RAW:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
            if (bytesProcessed + len > buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                bytesProcessed = buffer.length + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
            System.arraycopy(b, ofs, buffer, bytesProcessed, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
            bytesProcessed += len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
            throw new ProviderException("Internal error");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
    // see JCA spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
    protected void engineUpdate(ByteBuffer byteBuffer) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        ensureInitialized();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
        int len = byteBuffer.remaining();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        if (len <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
        switch (type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
        case T_UPDATE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
            if (byteBuffer instanceof DirectBuffer == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                // cannot do better than default impl
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
                super.engineUpdate(byteBuffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
            long addr = ((DirectBuffer)byteBuffer).address();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
            int ofs = byteBuffer.position();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                if (mode == M_SIGN) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                    token.p11.C_SignUpdate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
                        (session.id(), addr + ofs, null, 0, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
                    token.p11.C_VerifyUpdate
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                        (session.id(), addr + ofs, null, 0, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
                bytesProcessed += len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
                byteBuffer.position(ofs + len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            } catch (PKCS11Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
                throw new ProviderException("Update failed", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        case T_DIGEST:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            md.update(byteBuffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            bytesProcessed += len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
        case T_RAW:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
            if (bytesProcessed + len > buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                bytesProcessed = buffer.length + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            byteBuffer.get(buffer, bytesProcessed, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
            bytesProcessed += len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
            throw new ProviderException("Internal error");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
    // see JCA spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
    protected byte[] engineSign() throws SignatureException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
        ensureInitialized();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
            byte[] signature;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
            if (type == T_UPDATE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
                int len = keyAlgorithm.equals("DSA") ? 40 : 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
                signature = token.p11.C_SignFinal(session.id(), len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                byte[] digest;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
                if (type == T_DIGEST) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
                    digest = md.digest();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
                } else { // T_RAW
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
                    if (mechanism == CKM_DSA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
                        if (bytesProcessed != buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
                            throw new SignatureException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
                            ("Data for RawDSA must be exactly 20 bytes long");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
                        digest = buffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
                    } else { // CKM_ECDSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
                        if (bytesProcessed > buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                            throw new SignatureException("Data for NONEwithECDSA"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
                            + " must be at most " + RAW_ECDSA_MAX + " bytes long");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
                        digest = new byte[bytesProcessed];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
                        System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
                if (keyAlgorithm.equals("RSA") == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                    // DSA and ECDSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
                    signature = token.p11.C_Sign(session.id(), digest);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
                } else { // RSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
                    byte[] data = encodeSignature(digest);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
                    if (mechanism == CKM_RSA_X_509) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
                        data = pkcs1Pad(data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                    signature = token.p11.C_Sign(session.id(), data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
            if (keyAlgorithm.equals("RSA") == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
                return dsaToASN1(signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
                return signature;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
        } catch (PKCS11Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            throw new ProviderException(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
            initialized = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
            session = token.releaseSession(session);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
    // see JCA spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
    protected boolean engineVerify(byte[] signature) throws SignatureException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
        ensureInitialized();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
            if (keyAlgorithm.equals("DSA")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
                signature = asn1ToDSA(signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
            } else if (keyAlgorithm.equals("EC")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
                signature = asn1ToECDSA(signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
            if (type == T_UPDATE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                token.p11.C_VerifyFinal(session.id(), signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
                byte[] digest;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
                if (type == T_DIGEST) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
                    digest = md.digest();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
                } else { // T_RAW
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
                    if (mechanism == CKM_DSA) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
                        if (bytesProcessed != buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
                            throw new SignatureException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
                            ("Data for RawDSA must be exactly 20 bytes long");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
                        digest = buffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
                        if (bytesProcessed > buffer.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
                            throw new SignatureException("Data for NONEwithECDSA"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
                            + " must be at most " + RAW_ECDSA_MAX + " bytes long");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
                        digest = new byte[bytesProcessed];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                        System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
                if (keyAlgorithm.equals("RSA") == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
                    // DSA and ECDSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
                    token.p11.C_Verify(session.id(), digest, signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
                } else { // RSA
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
                    byte[] data = encodeSignature(digest);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
                    if (mechanism == CKM_RSA_X_509) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
                        data = pkcs1Pad(data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
                    token.p11.C_Verify(session.id(), data, signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
            return true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
        } catch (PKCS11Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
            long errorCode = e.getErrorCode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
            if (errorCode == CKR_SIGNATURE_INVALID) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
            if (errorCode == CKR_SIGNATURE_LEN_RANGE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
                // return false rather than throwing an exception
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
            // ECF bug?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
            if (errorCode == CKR_DATA_LEN_RANGE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
                return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
            throw new ProviderException(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
        } finally {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
            // XXX we should not release the session if we abort above
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
            // before calling C_Verify
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
            initialized = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
            session = token.releaseSession(session);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
    private byte[] pkcs1Pad(byte[] data) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
        try {
11521
d7698e6c5f51 7106773: 512 bits RSA key cannot work with SHA384 and SHA512
xuelei
parents: 10336
diff changeset
   665
            int len = (p11Key.length() + 7) >> 3;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
            RSAPadding padding = RSAPadding.getInstance
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
                                        (RSAPadding.PAD_BLOCKTYPE_1, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
            byte[] padded = padding.pad(data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
            return padded;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
        } catch (GeneralSecurityException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
            throw new ProviderException(e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
    private byte[] encodeSignature(byte[] digest) throws SignatureException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
            return RSASignature.encodeSignature(digestOID, digest);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
        } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
            throw new SignatureException("Invalid encoding", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
//    private static byte[] decodeSignature(byte[] signature) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
//      return RSASignature.decodeSignature(digestOID, signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
//    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
    // For DSA and ECDSA signatures, PKCS#11 represents them as a simple
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
    // byte array that contains the concatenation of r and s.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
    // For DSA, r and s are always exactly 20 bytes long.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
    // For ECDSA, r and s are of variable length, but we know that each
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
    // occupies half of the array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
    private static byte[] dsaToASN1(byte[] signature) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
        int n = signature.length >> 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
        BigInteger r = new BigInteger(1, P11Util.subarray(signature, 0, n));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
        BigInteger s = new BigInteger(1, P11Util.subarray(signature, n, n));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
            DerOutputStream outseq = new DerOutputStream(100);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
            outseq.putInteger(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
            outseq.putInteger(s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
            DerValue result = new DerValue(DerValue.tag_Sequence,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
                                           outseq.toByteArray());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
            return result.toByteArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
        } catch (java.io.IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
            throw new RuntimeException("Internal error", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
    private static byte[] asn1ToDSA(byte[] signature) throws SignatureException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
            DerInputStream in = new DerInputStream(signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
            DerValue[] values = in.getSequence(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
            BigInteger r = values[0].getPositiveBigInteger();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
            BigInteger s = values[1].getPositiveBigInteger();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
            byte[] br = toByteArray(r, 20);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
            byte[] bs = toByteArray(s, 20);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
            if ((br == null) || (bs == null)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
                throw new SignatureException("Out of range value for R or S");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
            return P11Util.concat(br, bs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
        } catch (SignatureException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
            throw e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
            throw new SignatureException("invalid encoding for signature", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
    private byte[] asn1ToECDSA(byte[] signature) throws SignatureException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            DerInputStream in = new DerInputStream(signature);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
            DerValue[] values = in.getSequence(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
            BigInteger r = values[0].getPositiveBigInteger();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
            BigInteger s = values[1].getPositiveBigInteger();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
            // trim leading zeroes
17916
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 12685
diff changeset
   734
            byte[] br = KeyUtil.trimZeroes(r.toByteArray());
e02ddef88f77 8014618: Need to strip leading zeros in TlsPremasterSecret of DHKeyAgreement
xuelei
parents: 12685
diff changeset
   735
            byte[] bs = KeyUtil.trimZeroes(s.toByteArray());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
            int k = Math.max(br.length, bs.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
            // r and s each occupy half the array
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
            byte[] res = new byte[k << 1];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
            System.arraycopy(br, 0, res, k - br.length, br.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
            System.arraycopy(bs, 0, res, res.length - bs.length, bs.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
            return res;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
        } catch (Exception e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
            throw new SignatureException("invalid encoding for signature", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
    private static byte[] toByteArray(BigInteger bi, int len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
        byte[] b = bi.toByteArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
        int n = b.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
        if (n == len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
            return b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
        if ((n == len + 1) && (b[0] == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
            byte[] t = new byte[len];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
            System.arraycopy(b, 1, t, 0, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
            return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
        if (n > len) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        // must be smaller
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        byte[] t = new byte[len];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
        System.arraycopy(b, 0, t, (len - n), n);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
    // see JCA spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
    protected void engineSetParameter(String param, Object value)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
            throws InvalidParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
        throw new UnsupportedOperationException("setParameter() not supported");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
    // see JCA spec
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
    protected Object engineGetParameter(String param)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
            throws InvalidParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
        throw new UnsupportedOperationException("getParameter() not supported");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
}