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     private void ensureInitialized() {
 267         token.ensureValid();
 268         if (initialized == false) {
 269             initialize();
 270         }
 271     }
 272 
 273     private void cancelOperation() {
 274         token.ensureValid();
 275         if (initialized == false) {
 276             return;
 277         }
 278         initialized = false;
 279         if ((session == null) || (token.explicitCancel == false)) {
 280             return;
 281         }
 282         if (session.hasObjects() == false) {
 283             session = token.killSession(session);
 284             return;
 285         }
 286         // "cancel" operation by finishing it
 287         // XXX make sure all this always works correctly
 288         if (mode == M_SIGN) {
 289             try {
 290                 if (type == T_UPDATE) {
 291                     token.p11.C_SignFinal(session.id(), 0);
 292                 } else {
 293                     byte[] digest;
 294                     if (type == T_DIGEST) {
 295                         digest = md.digest();
 296                     } else { // T_RAW
 297                         digest = buffer;
 298                     }
 299                     token.p11.C_Sign(session.id(), digest);
 300                 }
 301             } catch (PKCS11Exception e) {
 302                 throw new ProviderException("cancel failed", e);
 303             }
 304         } else { // M_VERIFY
 305             try {
 306                 byte[] signature;
 307                 if (keyAlgorithm.equals("DSA")) {
 308                     signature = new byte[40];
 309                 } else {
 310                     signature = new byte[(p11Key.length() + 7) >> 3];
 311                 }
 312                 if (type == T_UPDATE) {
 313                     token.p11.C_VerifyFinal(session.id(), signature);
 314                 } else {
 315                     byte[] digest;
 316                     if (type == T_DIGEST) {
 317                         digest = md.digest();
 318                     } else { // T_RAW
 319                         digest = buffer;
 320                     }
 321                     token.p11.C_Verify(session.id(), digest, signature);
 322                 }
 323             } catch (PKCS11Exception e) {
 324                 // will fail since the signature is incorrect
 325                 // XXX check error code
 326             }
 327         }
 328     }
 329 
 330     // assumes current state is initialized == false
 331     private void initialize() {
 332         try {
 333             if (session == null) {
 334                 session = token.getOpSession();
 335             }
 336             if (mode == M_SIGN) {
 337                 token.p11.C_SignInit(session.id(),
 338                         new CK_MECHANISM(mechanism), p11Key.keyID);
 339             } else {
 340                 token.p11.C_VerifyInit(session.id(),
 341                         new CK_MECHANISM(mechanism), p11Key.keyID);
 342             }
 343             initialized = true;
 344         } catch (PKCS11Exception e) {
 345             throw new ProviderException("Initialization failed", e);
 346         }
 347         if (bytesProcessed != 0) {
 348             bytesProcessed = 0;
 349             if (md != null) {
 350                 md.reset();
 351             }
 352         }
 353     }
 354 
 355     private void checkKeySize(String keyAlgo, Key key)
 356         throws InvalidKeyException {
 357         CK_MECHANISM_INFO mechInfo = null;
 358         try {
 359             mechInfo = token.getMechanismInfo(mechanism);
 360         } catch (PKCS11Exception e) {
 361             // should not happen, ignore for now.
 362         }
 363         if (mechInfo == null) {
 364             // skip the check if no native info available
 365             return;
 366         }
 367         int minKeySize = (int) mechInfo.ulMinKeySize;
 368         int maxKeySize = (int) mechInfo.ulMaxKeySize;
 369         // need to override the MAX keysize for SHA1withDSA
 370         if (md != null && mechanism == CKM_DSA && maxKeySize > 1024) {
 371                maxKeySize = 1024;
 372         }
 373         int keySize = 0;
 374         if (key instanceof P11Key) {
 375             keySize = ((P11Key) key).length();
 376         } else {
 377             try {
 378                 if (keyAlgo.equals("RSA")) {
 379                     keySize = ((RSAKey) key).getModulus().bitLength();
 380                 } else if (keyAlgo.equals("DSA")) {
 381                     keySize = ((DSAKey) key).getParams().getP().bitLength();
 382                 } else if (keyAlgo.equals("EC")) {
 383                     keySize = ((ECKey) key).getParams().getCurve().getField().getFieldSize();
 384                 } else {
 385                     throw new ProviderException("Error: unsupported algo " + keyAlgo);
 386                 }
 387             } catch (ClassCastException cce) {
 388                 throw new InvalidKeyException(keyAlgo +
 389                     " key must be the right type", cce);
 390             }
 391         }
 392         if ((minKeySize != -1) && (keySize < minKeySize)) {
 393             throw new InvalidKeyException(keyAlgo +
 394                 " key must be at least " + minKeySize + " bits");
 395         }
 396         if ((maxKeySize != -1) && (keySize > maxKeySize)) {
 397             throw new InvalidKeyException(keyAlgo +
 398                 " key must be at most " + maxKeySize + " bits");
 399         }
 400         if (keyAlgo.equals("RSA")) {
 401             checkRSAKeyLength(keySize);
 402         }
 403     }
 404 
 405     private void checkRSAKeyLength(int len) throws InvalidKeyException {
 406         RSAPadding padding;
 407         try {
 408             padding = RSAPadding.getInstance
 409                 (RSAPadding.PAD_BLOCKTYPE_1, (len + 7) >> 3);
 410         } catch (InvalidAlgorithmParameterException iape) {
 411             throw new InvalidKeyException(iape.getMessage());
 412         }
 413         int maxDataSize = padding.getMaxDataSize();
 414         int encodedLength;
 415         if (algorithm.equals("MD5withRSA") ||
 416             algorithm.equals("MD2withRSA")) {
 417             encodedLength = 34;
 418         } else if (algorithm.equals("SHA1withRSA")) {
 419             encodedLength = 35;
 420         } else if (algorithm.equals("SHA224withRSA")) {
 421             encodedLength = 47;
 422         } else if (algorithm.equals("SHA256withRSA")) {
 423             encodedLength = 51;
 424         } else if (algorithm.equals("SHA384withRSA")) {
 425             encodedLength = 67;
 426         } else if (algorithm.equals("SHA512withRSA")) {
 427             encodedLength = 83;
 428         } else {
 429             throw new ProviderException("Unknown signature algo: " + algorithm);
 430         }
 431         if (encodedLength > maxDataSize) {
 432             throw new InvalidKeyException
 433                 ("Key is too short for this signature algorithm");
 434         }
 435     }
 436 
 437     // see JCA spec
 438     @Override
 439     protected void engineInitVerify(PublicKey publicKey)
 440             throws InvalidKeyException {
 441         if (publicKey == null) {
 442             throw new InvalidKeyException("Key must not be null");
 443         }
 444         // Need to check key length whenever a new key is set
 445         if (publicKey != p11Key) {
 446             checkKeySize(keyAlgorithm, publicKey);
 447         }
 448         cancelOperation();
 449         mode = M_VERIFY;
 450         p11Key = P11KeyFactory.convertKey(token, publicKey, keyAlgorithm);
 451         initialize();
 452     }
 453 
 454     // see JCA spec
 455     @Override
 456     protected void engineInitSign(PrivateKey privateKey)
 457             throws InvalidKeyException {
 458         if (privateKey == null) {
 459             throw new InvalidKeyException("Key must not be null");
 460         }
 461         // Need to check RSA key length whenever a new key is set
 462         if (privateKey != p11Key) {
 463             checkKeySize(keyAlgorithm, privateKey);
 464         }
 465         cancelOperation();
 466         mode = M_SIGN;
 467         p11Key = P11KeyFactory.convertKey(token, privateKey, keyAlgorithm);
 468         initialize();
 469     }
 470 
 471     // see JCA spec
 472     @Override
 473     protected void engineUpdate(byte b) throws SignatureException {
 474         ensureInitialized();
 475         switch (type) {
 476         case T_UPDATE:
 477             buffer[0] = b;
 478             engineUpdate(buffer, 0, 1);
 479             break;
 480         case T_DIGEST:
 481             md.update(b);
 482             bytesProcessed++;
 483             break;
 484         case T_RAW:
 485             if (bytesProcessed >= buffer.length) {
 486                 bytesProcessed = buffer.length + 1;
 487                 return;
 488             }
 489             buffer[bytesProcessed++] = b;
 490             break;
 491         default:
 492             throw new ProviderException("Internal error");
 493         }
 494     }
 495 
 496     // see JCA spec
 497     @Override
 498     protected void engineUpdate(byte[] b, int ofs, int len)
 499             throws SignatureException {
 500         ensureInitialized();
 501         if (len == 0) {
 502             return;
 503         }
 504         switch (type) {
 505         case T_UPDATE:
 506             try {
 507                 if (mode == M_SIGN) {
 508                     token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
 509                 } else {
 510                     token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);
 511                 }
 512                 bytesProcessed += len;
 513             } catch (PKCS11Exception e) {
 514                 throw new ProviderException(e);
 515             }
 516             break;
 517         case T_DIGEST:
 518             md.update(b, ofs, len);
 519             bytesProcessed += len;
 520             break;
 521         case T_RAW:
 522             if (bytesProcessed + len > buffer.length) {
 523                 bytesProcessed = buffer.length + 1;
 524                 return;
 525             }
 526             System.arraycopy(b, ofs, buffer, bytesProcessed, len);
 527             bytesProcessed += len;
 528             break;
 529         default:
 530             throw new ProviderException("Internal error");
 531         }
 532     }
 533 
 534     // see JCA spec
 535     @Override
 536     protected void engineUpdate(ByteBuffer byteBuffer) {
 537         ensureInitialized();
 538         int len = byteBuffer.remaining();
 539         if (len <= 0) {
 540             return;
 541         }
 542         switch (type) {
 543         case T_UPDATE:
 544             if (byteBuffer instanceof DirectBuffer == false) {
 545                 // cannot do better than default impl
 546                 super.engineUpdate(byteBuffer);
 547                 return;
 548             }
 549             long addr = ((DirectBuffer)byteBuffer).address();
 550             int ofs = byteBuffer.position();
 551             try {
 552                 if (mode == M_SIGN) {
 553                     token.p11.C_SignUpdate
 554                         (session.id(), addr + ofs, null, 0, len);
 555                 } else {
 556                     token.p11.C_VerifyUpdate
 557                         (session.id(), addr + ofs, null, 0, len);
 558                 }
 559                 bytesProcessed += len;
 560                 byteBuffer.position(ofs + len);
 561             } catch (PKCS11Exception e) {
 562                 throw new ProviderException("Update failed", e);
 563             }
 564             break;
 565         case T_DIGEST:
 566             md.update(byteBuffer);
 567             bytesProcessed += len;
 568             break;
 569         case T_RAW:
 570             if (bytesProcessed + len > buffer.length) {
 571                 bytesProcessed = buffer.length + 1;
 572                 return;
 573             }
 574             byteBuffer.get(buffer, bytesProcessed, len);
 575             bytesProcessed += len;
 576             break;
 577         default:
 578             throw new ProviderException("Internal error");
 579         }
 580     }
 581 
 582     // see JCA spec
 583     @Override
 584     protected byte[] engineSign() throws SignatureException {
 585         ensureInitialized();
 586         try {
 587             byte[] signature;
 588             if (type == T_UPDATE) {
 589                 int len = keyAlgorithm.equals("DSA") ? 40 : 0;
 590                 signature = token.p11.C_SignFinal(session.id(), len);
 591             } else {
 592                 byte[] digest;
 593                 if (type == T_DIGEST) {
 594                     digest = md.digest();
 595                 } else { // T_RAW
 596                     if (mechanism == CKM_DSA) {
 597                         if (bytesProcessed != buffer.length) {
 598                             throw new SignatureException
 599                             ("Data for RawDSA must be exactly 20 bytes long");
 600                         }
 601                         digest = buffer;
 602                     } else { // CKM_ECDSA
 603                         if (bytesProcessed > buffer.length) {
 604                             throw new SignatureException("Data for NONEwithECDSA"
 605                             + " must be at most " + RAW_ECDSA_MAX + " bytes long");
 606                         }
 607                         digest = new byte[bytesProcessed];
 608                         System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
 609                     }
 610                 }
 611                 if (keyAlgorithm.equals("RSA") == false) {
 612                     // DSA and ECDSA
 613                     signature = token.p11.C_Sign(session.id(), digest);
 614                 } else { // RSA
 615                     byte[] data = encodeSignature(digest);
 616                     if (mechanism == CKM_RSA_X_509) {
 617                         data = pkcs1Pad(data);
 618                     }
 619                     signature = token.p11.C_Sign(session.id(), data);
 620                 }
 621             }
 622             if (keyAlgorithm.equals("RSA")) {
 623                 return signature;
 624             } else {
 625                 if (p1363Format) {
 626                     return signature;
 627                 } else {
 628                     return dsaToASN1(signature);
 629                 }
 630             }
 631         } catch (PKCS11Exception pe) {
 632             throw new ProviderException(pe);
 633         } catch (SignatureException | ProviderException e) {
 634             cancelOperation();
 635             throw e;
 636         } finally {
 637             initialized = false;
 638             session = token.releaseSession(session);
 639         }
 640     }
 641 
 642     // see JCA spec
 643     @Override
 644     protected boolean engineVerify(byte[] signature) throws SignatureException {
 645         ensureInitialized();
 646         try {
 647             if (!p1363Format) {
 648                 if (keyAlgorithm.equals("DSA")) {
 649                     signature = asn1ToDSA(signature);
 650                 } else if (keyAlgorithm.equals("EC")) {
 651                     signature = asn1ToECDSA(signature);
 652                 }
 653             }
 654             if (type == T_UPDATE) {
 655                 token.p11.C_VerifyFinal(session.id(), signature);
 656             } else {
 657                 byte[] digest;
 658                 if (type == T_DIGEST) {
 659                     digest = md.digest();
 660                 } else { // T_RAW
 661                     if (mechanism == CKM_DSA) {
 662                         if (bytesProcessed != buffer.length) {
 663                             throw new SignatureException
 664                             ("Data for RawDSA must be exactly 20 bytes long");
 665                         }
 666                         digest = buffer;
 667                     } else {
 668                         if (bytesProcessed > buffer.length) {
 669                             throw new SignatureException("Data for NONEwithECDSA"
 670                             + " must be at most " + RAW_ECDSA_MAX + " bytes long");
 671                         }
 672                         digest = new byte[bytesProcessed];
 673                         System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
 674                     }
 675                 }
 676                 if (keyAlgorithm.equals("RSA") == false) {
 677                     // DSA and ECDSA
 678                     token.p11.C_Verify(session.id(), digest, signature);
 679                 } else { // RSA
 680                     byte[] data = encodeSignature(digest);
 681                     if (mechanism == CKM_RSA_X_509) {
 682                         data = pkcs1Pad(data);
 683                     }
 684                     token.p11.C_Verify(session.id(), data, signature);
 685                 }
 686             }
 687             return true;
 688         } catch (PKCS11Exception pe) {
 689             long errorCode = pe.getErrorCode();
 690             if (errorCode == CKR_SIGNATURE_INVALID) {
 691                 return false;
 692             }
 693             if (errorCode == CKR_SIGNATURE_LEN_RANGE) {
 694                 // return false rather than throwing an exception
 695                 return false;
 696             }
 697             // ECF bug?
 698             if (errorCode == CKR_DATA_LEN_RANGE) {
 699                 return false;
 700             }
 701             throw new ProviderException(pe);
 702         }  catch (SignatureException | ProviderException e) {
 703             cancelOperation();
 704             throw e;
 705         } finally {
 706             initialized = false;
 707             session = token.releaseSession(session);
 708         }
 709     }
 710 
 711     private byte[] pkcs1Pad(byte[] data) {
 712         try {
 713             int len = (p11Key.length() + 7) >> 3;
 714             RSAPadding padding = RSAPadding.getInstance
 715                                         (RSAPadding.PAD_BLOCKTYPE_1, len);
 716             byte[] padded = padding.pad(data);
 717             return padded;
 718         } catch (GeneralSecurityException e) {
 719             throw new ProviderException(e);
 720         }
 721     }
 722 
 723     private byte[] encodeSignature(byte[] digest) throws SignatureException {
 724         try {
 725             return RSASignature.encodeSignature(digestOID, digest);
 726         } catch (IOException e) {
 727             throw new SignatureException("Invalid encoding", e);
 728         }
 729     }
 730 
 731 //    private static byte[] decodeSignature(byte[] signature) throws IOException {
 732 //      return RSASignature.decodeSignature(digestOID, signature);
 733 //    }
 734 
 735     // For DSA and ECDSA signatures, PKCS#11 represents them as a simple
 736     // byte array that contains the concatenation of r and s.
 737     // For DSA, r and s are always exactly 20 bytes long.
 738     // For ECDSA, r and s are of variable length, but we know that each
 739     // occupies half of the array.
 740     private static byte[] dsaToASN1(byte[] signature) {
 741         int n = signature.length >> 1;
 742         BigInteger r = new BigInteger(1, P11Util.subarray(signature, 0, n));
 743         BigInteger s = new BigInteger(1, P11Util.subarray(signature, n, n));
 744         try {
 745             DerOutputStream outseq = new DerOutputStream(100);
 746             outseq.putInteger(r);
 747             outseq.putInteger(s);
 748             DerValue result = new DerValue(DerValue.tag_Sequence,
 749                                            outseq.toByteArray());
 750             return result.toByteArray();
 751         } catch (java.io.IOException e) {
 752             throw new RuntimeException("Internal error", e);
 753         }
 754     }
 755 
 756     private static byte[] asn1ToDSA(byte[] sig) throws SignatureException {
 757         try {
 758             // Enforce strict DER checking for signatures
 759             DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
 760             DerValue[] values = in.getSequence(2);
 761 
 762             // check number of components in the read sequence
 763             // and trailing data
 764             if ((values.length != 2) || (in.available() != 0)) {
 765                 throw new IOException("Invalid encoding for signature");
 766             }
 767 
 768             BigInteger r = values[0].getPositiveBigInteger();
 769             BigInteger s = values[1].getPositiveBigInteger();
 770 
 771             byte[] br = toByteArray(r, 20);
 772             byte[] bs = toByteArray(s, 20);
 773             if ((br == null) || (bs == null)) {
 774                 throw new SignatureException("Out of range value for R or S");
 775             }
 776             return P11Util.concat(br, bs);
 777         } catch (SignatureException e) {
 778             throw e;
 779         } catch (Exception e) {
 780             throw new SignatureException("Invalid encoding for signature", e);
 781         }
 782     }
 783 
 784     private byte[] asn1ToECDSA(byte[] sig) throws SignatureException {
 785         try {
 786             // Enforce strict DER checking for signatures
 787             DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
 788             DerValue[] values = in.getSequence(2);
 789 
 790             // check number of components in the read sequence
 791             // and trailing data
 792             if ((values.length != 2) || (in.available() != 0)) {
 793                 throw new IOException("Invalid encoding for signature");
 794             }
 795 
 796             BigInteger r = values[0].getPositiveBigInteger();
 797             BigInteger s = values[1].getPositiveBigInteger();
 798 
 799             // trim leading zeroes
 800             byte[] br = KeyUtil.trimZeroes(r.toByteArray());
 801             byte[] bs = KeyUtil.trimZeroes(s.toByteArray());
 802             int k = Math.max(br.length, bs.length);
 803             // r and s each occupy half the array
 804             byte[] res = new byte[k << 1];
 805             System.arraycopy(br, 0, res, k - br.length, br.length);
 806             System.arraycopy(bs, 0, res, res.length - bs.length, bs.length);
 807             return res;
 808         } catch (Exception e) {
 809             throw new SignatureException("Invalid encoding for signature", e);
 810         }
 811     }
 812 
 813     private static byte[] toByteArray(BigInteger bi, int len) {
 814         byte[] b = bi.toByteArray();
 815         int n = b.length;
 816         if (n == len) {
 817             return b;
 818         }
 819         if ((n == len + 1) && (b[0] == 0)) {
 820             byte[] t = new byte[len];
 821             System.arraycopy(b, 1, t, 0, len);
 822             return t;
 823         }
 824         if (n > len) {
 825             return null;
 826         }
 827         // must be smaller
 828         byte[] t = new byte[len];
 829         System.arraycopy(b, 0, t, (len - n), n);
 830         return t;
 831     }
 832 
 833     // see JCA spec
 834     @SuppressWarnings("deprecation")
 835     @Override
 836     protected void engineSetParameter(String param, Object value)
 837             throws InvalidParameterException {
 838         throw new UnsupportedOperationException("setParameter() not supported");
 839     }
 840 
 841     // see JCA spec
 842     @Override
 843     protected void engineSetParameter(AlgorithmParameterSpec params)
 844             throws InvalidAlgorithmParameterException {
 845         if (params != null) {
 846             throw new InvalidAlgorithmParameterException("No parameter accepted");
 847         }
 848     }
 849 
 850     // see JCA spec
 851     @SuppressWarnings("deprecation")
 852     @Override
 853     protected Object engineGetParameter(String param)
 854             throws InvalidParameterException {
 855         throw new UnsupportedOperationException("getParameter() not supported");
 856     }
 857 
 858     // see JCA spec
 859     @Override
 860     protected AlgorithmParameters engineGetParameters() {
 861         return null;
 862     }
 863 }