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