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