1 /*
   2  * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.pkcs11;
  27 
  28 import java.io.IOException;
  29 import java.math.BigInteger;
  30 import java.nio.ByteBuffer;
  31 
  32 import java.security.*;
  33 import java.security.interfaces.*;
  34 import java.security.spec.AlgorithmParameterSpec;
  35 import sun.nio.ch.DirectBuffer;
  36 
  37 import sun.security.util.*;
  38 import sun.security.x509.AlgorithmId;
  39 
  40 import sun.security.rsa.RSASignature;
  41 import sun.security.rsa.RSAPadding;
  42 
  43 import sun.security.pkcs11.wrapper.*;
  44 import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
  45 import sun.security.util.KeyUtil;
  46 
  47 /**
  48  * Signature implementation class. This class currently supports the
  49  * following algorithms:
  50  *
  51  * . DSA
  52  *   . NONEwithDSA (RawDSA)
  53  *   . SHA1withDSA
  54  *   . NONEwithDSAinP1363Format (RawDSAinP1363Format)
  55  *   . SHA1withDSAinP1363Format
  56  * . RSA:
  57  *   . MD2withRSA
  58  *   . MD5withRSA
  59  *   . SHA1withRSA
  60  *   . SHA224withRSA
  61  *   . SHA256withRSA
  62  *   . SHA384withRSA
  63  *   . SHA512withRSA
  64  * . ECDSA
  65  *   . NONEwithECDSA
  66  *   . SHA1withECDSA
  67  *   . SHA224withECDSA
  68  *   . SHA256withECDSA
  69  *   . SHA384withECDSA
  70  *   . SHA512withECDSA
  71  *   . NONEwithECDSAinP1363Format
  72  *   . SHA1withECDSAinP1363Format
  73  *   . SHA224withECDSAinP1363Format
  74  *   . SHA256withECDSAinP1363Format
  75  *   . SHA384withECDSAinP1363Format
  76  *   . SHA512withECDSAinP1363Format
  77  *
  78  * Note that the underlying PKCS#11 token may support complete signature
  79  * algorithm (e.g. CKM_DSA_SHA1, CKM_MD5_RSA_PKCS), or it may just
  80  * implement the signature algorithm without hashing (e.g. CKM_DSA, CKM_PKCS),
  81  * or it may only implement the raw public key operation (CKM_RSA_X_509).
  82  * This class uses what is available and adds whatever extra processing
  83  * is needed.
  84  *
  85  * @author  Andreas Sterbenz
  86  * @since   1.5
  87  */
  88 final class P11Signature extends SignatureSpi {
  89 
  90     // token instance
  91     private final Token token;
  92 
  93     // algorithm name
  94     private final String algorithm;
  95 
  96     // name of the key algorithm, currently either RSA or DSA
  97     private final String keyAlgorithm;
  98 
  99     // mechanism id
 100     private final long mechanism;
 101 
 102     // digest algorithm OID, if we encode RSA signature ourselves
 103     private final ObjectIdentifier digestOID;
 104 
 105     // type, one of T_* below
 106     private final int type;
 107 
 108     // key instance used, if init*() was called
 109     private P11Key p11Key;
 110 
 111     // message digest, if we do the digesting ourselves
 112     private final MessageDigest md;
 113 
 114     // associated session, if any
 115     private Session session;
 116 
 117     // mode, one of M_* below
 118     private int mode;
 119 
 120     // flag indicating whether an operation is initialized
 121     private boolean initialized;
 122 
 123     // buffer, for update(byte) or DSA
 124     private final byte[] buffer;
 125 
 126     // total number of bytes processed in current operation
 127     private int bytesProcessed;
 128 
 129     // The format, to be used for DSA and ECDSA signatures.
 130     // If true, the IEEE P1363 format will be used, the concatenation of
 131     // r and s. If false (default), the signature will be formatted as a
 132     // DER-encoded ASN.1 sequence of r and s.
 133     private boolean p1363Format = false;
 134 
 135     // constant for signing mode
 136     private final static int M_SIGN   = 1;
 137     // constant for verification mode
 138     private final static int M_VERIFY = 2;
 139 
 140     // constant for type digesting, we do the hashing ourselves
 141     private final static int T_DIGEST = 1;
 142     // constant for type update, token does everything
 143     private final static int T_UPDATE = 2;
 144     // constant for type raw, used with RawDSA and NONEwithECDSA only
 145     private final static int T_RAW    = 3;
 146 
 147     // XXX PKCS#11 v2.20 says "should not be longer than 1024 bits",
 148     // but this is a little arbitrary
 149     private final static int RAW_ECDSA_MAX = 128;
 150 
 151     P11Signature(Token token, String algorithm, long mechanism)
 152             throws NoSuchAlgorithmException, PKCS11Exception {
 153         super();
 154         this.token = token;
 155         this.algorithm = algorithm;
 156         this.mechanism = mechanism;
 157         byte[] buffer = null;
 158         ObjectIdentifier digestOID = null;
 159         MessageDigest md = null;
 160         switch ((int)mechanism) {
 161         case (int)CKM_MD2_RSA_PKCS:
 162         case (int)CKM_MD5_RSA_PKCS:
 163         case (int)CKM_SHA1_RSA_PKCS:
 164         case (int)CKM_SHA224_RSA_PKCS:
 165         case (int)CKM_SHA256_RSA_PKCS:
 166         case (int)CKM_SHA384_RSA_PKCS:
 167         case (int)CKM_SHA512_RSA_PKCS:
 168             keyAlgorithm = "RSA";
 169             type = T_UPDATE;
 170             buffer = new byte[1];
 171             break;
 172         case (int)CKM_DSA_SHA1:
 173             keyAlgorithm = "DSA";
 174             type = T_UPDATE;
 175             buffer = new byte[1];
 176             break;
 177         case (int)CKM_ECDSA_SHA1:
 178             keyAlgorithm = "EC";
 179             type = T_UPDATE;
 180             buffer = new byte[1];
 181             break;
 182         case (int)CKM_DSA:
 183             keyAlgorithm = "DSA";
 184             if (algorithm.equals("DSA") ||
 185                 algorithm.equals("DSAinP1363Format")) {
 186                 type = T_DIGEST;
 187                 md = MessageDigest.getInstance("SHA-1");
 188             } else if (algorithm.equals("RawDSA") ||
 189                        algorithm.equals("RawDSAinP1363Format")) {
 190                 type = T_RAW;
 191                 buffer = new byte[20];
 192             } else {
 193                 throw new ProviderException(algorithm);
 194             }
 195             break;
 196         case (int)CKM_ECDSA:
 197             keyAlgorithm = "EC";
 198             if (algorithm.equals("NONEwithECDSA") ||
 199                 algorithm.equals("NONEwithECDSAinP1363Format")) {
 200                 type = T_RAW;
 201                 buffer = new byte[RAW_ECDSA_MAX];
 202             } else {
 203                 String digestAlg;
 204                 if (algorithm.equals("SHA1withECDSA") ||
 205                     algorithm.equals("SHA1withECDSAinP1363Format")) {
 206                     digestAlg = "SHA-1";
 207                 } else if (algorithm.equals("SHA224withECDSA") ||
 208                            algorithm.equals("SHA224withECDSAinP1363Format")) {
 209                     digestAlg = "SHA-224";
 210                 } else if (algorithm.equals("SHA256withECDSA") ||
 211                            algorithm.equals("SHA256withECDSAinP1363Format")) {
 212                     digestAlg = "SHA-256";
 213                 } else if (algorithm.equals("SHA384withECDSA") ||
 214                            algorithm.equals("SHA384withECDSAinP1363Format")) {
 215                     digestAlg = "SHA-384";
 216                 } else if (algorithm.equals("SHA512withECDSA") ||
 217                            algorithm.equals("SHA512withECDSAinP1363Format")) {
 218                     digestAlg = "SHA-512";
 219                 } else {
 220                     throw new ProviderException(algorithm);
 221                 }
 222                 type = T_DIGEST;
 223                 md = MessageDigest.getInstance(digestAlg);
 224             }
 225             break;
 226         case (int)CKM_RSA_PKCS:
 227         case (int)CKM_RSA_X_509:
 228             keyAlgorithm = "RSA";
 229             type = T_DIGEST;
 230             if (algorithm.equals("MD5withRSA")) {
 231                 md = MessageDigest.getInstance("MD5");
 232                 digestOID = AlgorithmId.MD5_oid;
 233             } else if (algorithm.equals("SHA1withRSA")) {
 234                 md = MessageDigest.getInstance("SHA-1");
 235                 digestOID = AlgorithmId.SHA_oid;
 236             } else if (algorithm.equals("MD2withRSA")) {
 237                 md = MessageDigest.getInstance("MD2");
 238                 digestOID = AlgorithmId.MD2_oid;
 239             } else if (algorithm.equals("SHA224withRSA")) {
 240                 md = MessageDigest.getInstance("SHA-224");
 241                 digestOID = AlgorithmId.SHA224_oid;
 242             } else if (algorithm.equals("SHA256withRSA")) {
 243                 md = MessageDigest.getInstance("SHA-256");
 244                 digestOID = AlgorithmId.SHA256_oid;
 245             } else if (algorithm.equals("SHA384withRSA")) {
 246                 md = MessageDigest.getInstance("SHA-384");
 247                 digestOID = AlgorithmId.SHA384_oid;
 248             } else if (algorithm.equals("SHA512withRSA")) {
 249                 md = MessageDigest.getInstance("SHA-512");
 250                 digestOID = AlgorithmId.SHA512_oid;
 251             } else {
 252                 throw new ProviderException("Unknown signature: " + algorithm);
 253             }
 254             break;
 255         default:
 256             throw new ProviderException("Unknown mechanism: " + mechanism);
 257         }
 258         this.buffer = buffer;
 259         this.digestOID = digestOID;
 260         this.md = md;
 261         if (algorithm.endsWith("inP1363Format")) {
 262             this.p1363Format = true;
 263         }
 264     }
 265 
 266     // reset the states to the pre-initialized values
 267     private void reset(boolean doCancel) {
 268         if (!initialized) {
 269             return;
 270         }
 271         initialized = false;
 272         try {
 273             if (session == null) {
 274                 return;
 275             }
 276             if (doCancel && token.explicitCancel) {
 277                 cancelOperation();
 278             }
 279         } finally {
 280             p11Key.decNativeKeyRef();
 281             session = token.releaseSession(session);
 282         }
 283     }
 284 
 285     private void cancelOperation() {
 286         token.ensureValid();
 287         if (session.hasObjects() == false) {
 288             session = token.killSession(session);
 289             return;
 290         } else {
 291             // "cancel" operation by finishing it
 292             // XXX make sure all this always works correctly
 293             try {
 294                 if (mode == M_SIGN) {
 295                     if (type == T_UPDATE) {
 296                         token.p11.C_SignFinal(session.id(), 0);
 297                     } else {
 298                         byte[] digest;
 299                         if (type == T_DIGEST) {
 300                             digest = md.digest();
 301                         } else { // T_RAW
 302                             digest = buffer;
 303                         }
 304                         token.p11.C_Sign(session.id(), digest);
 305                     }
 306                 } else { // M_VERIFY
 307                     byte[] signature;
 308                     if (keyAlgorithm.equals("DSA")) {
 309                         signature = new byte[40];
 310                     } else {
 311                         signature = new byte[(p11Key.length() + 7) >> 3];
 312                     }
 313                     if (type == T_UPDATE) {
 314                         token.p11.C_VerifyFinal(session.id(), signature);
 315                     } else {
 316                         byte[] digest;
 317                         if (type == T_DIGEST) {
 318                             digest = md.digest();
 319                         } else { // T_RAW
 320                             digest = buffer;
 321                         }
 322                         token.p11.C_Verify(session.id(), digest, signature);
 323                     }
 324                 }
 325             } catch (PKCS11Exception e) {
 326                 throw new ProviderException("cancel failed", e);
 327             }
 328         }
 329     }
 330 
 331     // assumes current state is initialized == false
 332     private void ensureInitialized() {
 333         if (initialized) {
 334             return;
 335         }
 336         if (p11Key == null) {
 337             throw new ProviderException(
 338                     "Operation cannot be performed without " +
 339                     "calling engineInit first");
 340         }
 341         try {
 342             token.ensureValid();
 343             p11Key.incNativeKeyRef();
 344             try {
 345                 if (session == null) {
 346                     session = token.getOpSession();
 347                 }
 348                 if (mode == M_SIGN) {
 349                     token.p11.C_SignInit(session.id(),
 350                             new CK_MECHANISM(mechanism), p11Key.keyID);
 351                 } else {
 352                     token.p11.C_VerifyInit(session.id(),
 353                             new CK_MECHANISM(mechanism), p11Key.keyID);
 354                 }
 355             } catch (Throwable t) {
 356                 p11Key.decNativeKeyRef();
 357                 session = token.releaseSession(session);
 358                 throw t;
 359             }
 360             initialized = true;
 361             if (bytesProcessed != 0 && md != null) {
 362                 md.reset();
 363             }
 364             bytesProcessed = 0;
 365         } catch (PKCS11Exception e) {
 366             throw new ProviderException("Initialization failed", e);
 367         }
 368     }
 369 
 370     private void checkKeySize(String keyAlgo, Key key)
 371         throws InvalidKeyException {
 372         CK_MECHANISM_INFO mechInfo = null;
 373         try {
 374             mechInfo = token.getMechanismInfo(mechanism);
 375         } catch (PKCS11Exception e) {
 376             // should not happen, ignore for now.
 377         }
 378         if (mechInfo == null) {
 379             // skip the check if no native info available
 380             return;
 381         }
 382         int minKeySize = (int) mechInfo.ulMinKeySize;
 383         int maxKeySize = (int) mechInfo.ulMaxKeySize;
 384         // need to override the MAX keysize for SHA1withDSA
 385         if (md != null && mechanism == CKM_DSA && maxKeySize > 1024) {
 386                maxKeySize = 1024;
 387         }
 388         int keySize = 0;
 389         if (key instanceof P11Key) {
 390             keySize = ((P11Key) key).length();
 391         } else {
 392             try {
 393                 if (keyAlgo.equals("RSA")) {
 394                     keySize = ((RSAKey) key).getModulus().bitLength();
 395                 } else if (keyAlgo.equals("DSA")) {
 396                     keySize = ((DSAKey) key).getParams().getP().bitLength();
 397                 } else if (keyAlgo.equals("EC")) {
 398                     keySize = ((ECKey) key).getParams().getCurve().getField().getFieldSize();
 399                 } else {
 400                     throw new ProviderException("Error: unsupported algo " + keyAlgo);
 401                 }
 402             } catch (ClassCastException cce) {
 403                 throw new InvalidKeyException(keyAlgo +
 404                     " key must be the right type", cce);
 405             }
 406         }
 407         if ((minKeySize != -1) && (keySize < minKeySize)) {
 408             throw new InvalidKeyException(keyAlgo +
 409                 " key must be at least " + minKeySize + " bits");
 410         }
 411         if ((maxKeySize != -1) && (keySize > maxKeySize)) {
 412             throw new InvalidKeyException(keyAlgo +
 413                 " key must be at most " + maxKeySize + " bits");
 414         }
 415         if (keyAlgo.equals("RSA")) {
 416             checkRSAKeyLength(keySize);
 417         }
 418     }
 419 
 420     private void checkRSAKeyLength(int len) throws InvalidKeyException {
 421         RSAPadding padding;
 422         try {
 423             padding = RSAPadding.getInstance
 424                 (RSAPadding.PAD_BLOCKTYPE_1, (len + 7) >> 3);
 425         } catch (InvalidAlgorithmParameterException iape) {
 426             throw new InvalidKeyException(iape.getMessage());
 427         }
 428         int maxDataSize = padding.getMaxDataSize();
 429         int encodedLength;
 430         if (algorithm.equals("MD5withRSA") ||
 431             algorithm.equals("MD2withRSA")) {
 432             encodedLength = 34;
 433         } else if (algorithm.equals("SHA1withRSA")) {
 434             encodedLength = 35;
 435         } else if (algorithm.equals("SHA224withRSA")) {
 436             encodedLength = 47;
 437         } else if (algorithm.equals("SHA256withRSA")) {
 438             encodedLength = 51;
 439         } else if (algorithm.equals("SHA384withRSA")) {
 440             encodedLength = 67;
 441         } else if (algorithm.equals("SHA512withRSA")) {
 442             encodedLength = 83;
 443         } else {
 444             throw new ProviderException("Unknown signature algo: " + algorithm);
 445         }
 446         if (encodedLength > maxDataSize) {
 447             throw new InvalidKeyException
 448                 ("Key is too short for this signature algorithm");
 449         }
 450     }
 451 
 452     // see JCA spec
 453     @Override
 454     protected void engineInitVerify(PublicKey publicKey)
 455             throws InvalidKeyException {
 456         if (publicKey == null) {
 457             throw new InvalidKeyException("Key must not be null");
 458         }
 459         // Need to check key length whenever a new key is set
 460         if (publicKey != p11Key) {
 461             checkKeySize(keyAlgorithm, publicKey);
 462         }
 463         reset(true);
 464         mode = M_VERIFY;
 465         p11Key = P11KeyFactory.convertKey(token, publicKey, keyAlgorithm);
 466         ensureInitialized();
 467     }
 468 
 469     // see JCA spec
 470     @Override
 471     protected void engineInitSign(PrivateKey privateKey)
 472             throws InvalidKeyException {
 473         if (privateKey == null) {
 474             throw new InvalidKeyException("Key must not be null");
 475         }
 476         // Need to check RSA key length whenever a new key is set
 477         if (privateKey != p11Key) {
 478             checkKeySize(keyAlgorithm, privateKey);
 479         }
 480         reset(true);
 481         mode = M_SIGN;
 482         p11Key = P11KeyFactory.convertKey(token, privateKey, keyAlgorithm);
 483         ensureInitialized();
 484     }
 485 
 486     // see JCA spec
 487     @Override
 488     protected void engineUpdate(byte b) throws SignatureException {
 489         ensureInitialized();
 490         switch (type) {
 491         case T_UPDATE:
 492             buffer[0] = b;
 493             engineUpdate(buffer, 0, 1);
 494             break;
 495         case T_DIGEST:
 496             md.update(b);
 497             bytesProcessed++;
 498             break;
 499         case T_RAW:
 500             if (bytesProcessed >= buffer.length) {
 501                 bytesProcessed = buffer.length + 1;
 502                 return;
 503             }
 504             buffer[bytesProcessed++] = b;
 505             break;
 506         default:
 507             throw new ProviderException("Internal error");
 508         }
 509     }
 510 
 511     // see JCA spec
 512     @Override
 513     protected void engineUpdate(byte[] b, int ofs, int len)
 514             throws SignatureException {
 515         ensureInitialized();
 516         if (len == 0) {
 517             return;
 518         }
 519         // check for overflow
 520         if (len + bytesProcessed < 0) {
 521             throw new ProviderException("Processed bytes limits exceeded.");
 522         }
 523         switch (type) {
 524         case T_UPDATE:
 525             try {
 526                 if (mode == M_SIGN) {
 527                     token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
 528                 } else {
 529                     token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);
 530                 }
 531                 bytesProcessed += len;
 532             } catch (PKCS11Exception e) {
 533                 reset(true);
 534                 throw new ProviderException(e);
 535             }
 536             break;
 537         case T_DIGEST:
 538             md.update(b, ofs, len);
 539             bytesProcessed += len;
 540             break;
 541         case T_RAW:
 542             if (bytesProcessed + len > buffer.length) {
 543                 bytesProcessed = buffer.length + 1;
 544                 return;
 545             }
 546             System.arraycopy(b, ofs, buffer, bytesProcessed, len);
 547             bytesProcessed += len;
 548             break;
 549         default:
 550             throw new ProviderException("Internal error");
 551         }
 552     }
 553 
 554     // see JCA spec
 555     @Override
 556     protected void engineUpdate(ByteBuffer byteBuffer) {
 557         ensureInitialized();
 558         int len = byteBuffer.remaining();
 559         if (len <= 0) {
 560             return;
 561         }
 562         switch (type) {
 563         case T_UPDATE:
 564             if (byteBuffer instanceof DirectBuffer == false) {
 565                 // cannot do better than default impl
 566                 super.engineUpdate(byteBuffer);
 567                 return;
 568             }
 569             long addr = ((DirectBuffer)byteBuffer).address();
 570             int ofs = byteBuffer.position();
 571             try {
 572                 if (mode == M_SIGN) {
 573                     token.p11.C_SignUpdate
 574                         (session.id(), addr + ofs, null, 0, len);
 575                 } else {
 576                     token.p11.C_VerifyUpdate
 577                         (session.id(), addr + ofs, null, 0, len);
 578                 }
 579                 bytesProcessed += len;
 580                 byteBuffer.position(ofs + len);
 581             } catch (PKCS11Exception e) {
 582                 initialized = false;
 583                 session = token.releaseSession(session);
 584                 throw new ProviderException("Update failed", e);
 585             }
 586             break;
 587         case T_DIGEST:
 588             md.update(byteBuffer);
 589             bytesProcessed += len;
 590             break;
 591         case T_RAW:
 592             if (bytesProcessed + len > buffer.length) {
 593                 bytesProcessed = buffer.length + 1;
 594                 return;
 595             }
 596             byteBuffer.get(buffer, bytesProcessed, len);
 597             bytesProcessed += len;
 598             break;
 599         default:
 600             throw new ProviderException("Internal error");
 601         }
 602     }
 603 
 604     // see JCA spec
 605     @Override
 606     protected byte[] engineSign() throws SignatureException {
 607         ensureInitialized();
 608         try {
 609             byte[] signature;
 610             if (type == T_UPDATE) {
 611                 int len = keyAlgorithm.equals("DSA") ? 40 : 0;
 612                 signature = token.p11.C_SignFinal(session.id(), len);
 613             } else {
 614                 byte[] digest;
 615                 if (type == T_DIGEST) {
 616                     digest = md.digest();
 617                 } else { // T_RAW
 618                     if (mechanism == CKM_DSA) {
 619                         if (bytesProcessed != buffer.length) {
 620                             throw new SignatureException
 621                             ("Data for RawDSA must be exactly 20 bytes long");
 622                         }
 623                         digest = buffer;
 624                     } else { // CKM_ECDSA
 625                         if (bytesProcessed > buffer.length) {
 626                             throw new SignatureException("Data for NONEwithECDSA"
 627                             + " must be at most " + RAW_ECDSA_MAX + " bytes long");
 628                         }
 629                         digest = new byte[bytesProcessed];
 630                         System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
 631                     }
 632                 }
 633                 if (keyAlgorithm.equals("RSA") == false) {
 634                     // DSA and ECDSA
 635                     signature = token.p11.C_Sign(session.id(), digest);
 636                 } else { // RSA
 637                     byte[] data = encodeSignature(digest);
 638                     if (mechanism == CKM_RSA_X_509) {
 639                         data = pkcs1Pad(data);
 640                     }
 641                     signature = token.p11.C_Sign(session.id(), data);
 642                 }
 643             }
 644             if (keyAlgorithm.equals("RSA")) {
 645                 return signature;
 646             } else {
 647                 if (p1363Format) {
 648                     return signature;
 649                 } else {
 650                     return dsaToASN1(signature);
 651                 }
 652             }
 653         } catch (PKCS11Exception pe) {
 654             throw new ProviderException(pe);
 655         } catch (SignatureException | ProviderException e) {
 656             reset(true);
 657             throw e;
 658         } finally {
 659             reset(false);
 660         }
 661     }
 662 
 663     // see JCA spec
 664     @Override
 665     protected boolean engineVerify(byte[] signature) throws SignatureException {
 666         ensureInitialized();
 667         try {
 668             if (!p1363Format) {
 669                 if (keyAlgorithm.equals("DSA")) {
 670                     signature = asn1ToDSA(signature);
 671                 } else if (keyAlgorithm.equals("EC")) {
 672                     signature = asn1ToECDSA(signature);
 673                 }
 674             }
 675             if (type == T_UPDATE) {
 676                 token.p11.C_VerifyFinal(session.id(), signature);
 677             } else {
 678                 byte[] digest;
 679                 if (type == T_DIGEST) {
 680                     digest = md.digest();
 681                 } else { // T_RAW
 682                     if (mechanism == CKM_DSA) {
 683                         if (bytesProcessed != buffer.length) {
 684                             throw new SignatureException
 685                             ("Data for RawDSA must be exactly 20 bytes long");
 686                         }
 687                         digest = buffer;
 688                     } else {
 689                         if (bytesProcessed > buffer.length) {
 690                             throw new SignatureException("Data for NONEwithECDSA"
 691                             + " must be at most " + RAW_ECDSA_MAX + " bytes long");
 692                         }
 693                         digest = new byte[bytesProcessed];
 694                         System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
 695                     }
 696                 }
 697                 if (keyAlgorithm.equals("RSA") == false) {
 698                     // DSA and ECDSA
 699                     token.p11.C_Verify(session.id(), digest, signature);
 700                 } else { // RSA
 701                     byte[] data = encodeSignature(digest);
 702                     if (mechanism == CKM_RSA_X_509) {
 703                         data = pkcs1Pad(data);
 704                     }
 705                     token.p11.C_Verify(session.id(), data, signature);
 706                 }
 707             }
 708             return true;
 709         } catch (PKCS11Exception pe) {
 710             long errorCode = pe.getErrorCode();
 711             if (errorCode == CKR_SIGNATURE_INVALID) {
 712                 return false;
 713             }
 714             if (errorCode == CKR_SIGNATURE_LEN_RANGE) {
 715                 // return false rather than throwing an exception
 716                 return false;
 717             }
 718             // ECF bug?
 719             if (errorCode == CKR_DATA_LEN_RANGE) {
 720                 return false;
 721             }
 722             throw new ProviderException(pe);
 723         }  catch (SignatureException | ProviderException e) {
 724             reset(true);
 725             throw e;
 726         } finally {
 727             reset(false);
 728         }
 729     }
 730 
 731     private byte[] pkcs1Pad(byte[] data) {
 732         try {
 733             int len = (p11Key.length() + 7) >> 3;
 734             RSAPadding padding = RSAPadding.getInstance
 735                                         (RSAPadding.PAD_BLOCKTYPE_1, len);
 736             byte[] padded = padding.pad(data);
 737             return padded;
 738         } catch (GeneralSecurityException e) {
 739             throw new ProviderException(e);
 740         }
 741     }
 742 
 743     private byte[] encodeSignature(byte[] digest) throws SignatureException {
 744         try {
 745             return RSASignature.encodeSignature(digestOID, digest);
 746         } catch (IOException e) {
 747             throw new SignatureException("Invalid encoding", e);
 748         }
 749     }
 750 
 751 //    private static byte[] decodeSignature(byte[] signature) throws IOException {
 752 //      return RSASignature.decodeSignature(digestOID, signature);
 753 //    }
 754 
 755     // For DSA and ECDSA signatures, PKCS#11 represents them as a simple
 756     // byte array that contains the concatenation of r and s.
 757     // For DSA, r and s are always exactly 20 bytes long.
 758     // For ECDSA, r and s are of variable length, but we know that each
 759     // occupies half of the array.
 760     private static byte[] dsaToASN1(byte[] signature) {
 761         int n = signature.length >> 1;
 762         BigInteger r = new BigInteger(1, P11Util.subarray(signature, 0, n));
 763         BigInteger s = new BigInteger(1, P11Util.subarray(signature, n, n));
 764         try {
 765             DerOutputStream outseq = new DerOutputStream(100);
 766             outseq.putInteger(r);
 767             outseq.putInteger(s);
 768             DerValue result = new DerValue(DerValue.tag_Sequence,
 769                                            outseq.toByteArray());
 770             return result.toByteArray();
 771         } catch (java.io.IOException e) {
 772             throw new RuntimeException("Internal error", e);
 773         }
 774     }
 775 
 776     private static byte[] asn1ToDSA(byte[] sig) throws SignatureException {
 777         try {
 778             // Enforce strict DER checking for signatures
 779             DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
 780             DerValue[] values = in.getSequence(2);
 781 
 782             // check number of components in the read sequence
 783             // and trailing data
 784             if ((values.length != 2) || (in.available() != 0)) {
 785                 throw new IOException("Invalid encoding for signature");
 786             }
 787 
 788             BigInteger r = values[0].getPositiveBigInteger();
 789             BigInteger s = values[1].getPositiveBigInteger();
 790 
 791             byte[] br = toByteArray(r, 20);
 792             byte[] bs = toByteArray(s, 20);
 793             if ((br == null) || (bs == null)) {
 794                 throw new SignatureException("Out of range value for R or S");
 795             }
 796             return P11Util.concat(br, bs);
 797         } catch (SignatureException e) {
 798             throw e;
 799         } catch (Exception e) {
 800             throw new SignatureException("Invalid encoding for signature", e);
 801         }
 802     }
 803 
 804     private byte[] asn1ToECDSA(byte[] sig) throws SignatureException {
 805         try {
 806             // Enforce strict DER checking for signatures
 807             DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
 808             DerValue[] values = in.getSequence(2);
 809 
 810             // check number of components in the read sequence
 811             // and trailing data
 812             if ((values.length != 2) || (in.available() != 0)) {
 813                 throw new IOException("Invalid encoding for signature");
 814             }
 815 
 816             BigInteger r = values[0].getPositiveBigInteger();
 817             BigInteger s = values[1].getPositiveBigInteger();
 818 
 819             // trim leading zeroes
 820             byte[] br = KeyUtil.trimZeroes(r.toByteArray());
 821             byte[] bs = KeyUtil.trimZeroes(s.toByteArray());
 822             int k = Math.max(br.length, bs.length);
 823             // r and s each occupy half the array
 824             byte[] res = new byte[k << 1];
 825             System.arraycopy(br, 0, res, k - br.length, br.length);
 826             System.arraycopy(bs, 0, res, res.length - bs.length, bs.length);
 827             return res;
 828         } catch (Exception e) {
 829             throw new SignatureException("Invalid encoding for signature", e);
 830         }
 831     }
 832 
 833     private static byte[] toByteArray(BigInteger bi, int len) {
 834         byte[] b = bi.toByteArray();
 835         int n = b.length;
 836         if (n == len) {
 837             return b;
 838         }
 839         if ((n == len + 1) && (b[0] == 0)) {
 840             byte[] t = new byte[len];
 841             System.arraycopy(b, 1, t, 0, len);
 842             return t;
 843         }
 844         if (n > len) {
 845             return null;
 846         }
 847         // must be smaller
 848         byte[] t = new byte[len];
 849         System.arraycopy(b, 0, t, (len - n), n);
 850         return t;
 851     }
 852 
 853     // see JCA spec
 854     @SuppressWarnings("deprecation")
 855     @Override
 856     protected void engineSetParameter(String param, Object value)
 857             throws InvalidParameterException {
 858         throw new UnsupportedOperationException("setParameter() not supported");
 859     }
 860 
 861     // see JCA spec
 862     @Override
 863     protected void engineSetParameter(AlgorithmParameterSpec params)
 864             throws InvalidAlgorithmParameterException {
 865         if (params != null) {
 866             throw new InvalidAlgorithmParameterException("No parameter accepted");
 867         }
 868     }
 869 
 870     // see JCA spec
 871     @SuppressWarnings("deprecation")
 872     @Override
 873     protected Object engineGetParameter(String param)
 874             throws InvalidParameterException {
 875         throw new UnsupportedOperationException("getParameter() not supported");
 876     }
 877 
 878     // see JCA spec
 879     @Override
 880     protected AlgorithmParameters engineGetParameters() {
 881         return null;
 882     }
 883 }