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 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             try {
 377                 if (keyAlgo.equals("RSA")) {
 378                     keySize = ((RSAKey) key).getModulus().bitLength();
 379                 } else if (keyAlgo.equals("DSA")) {
 380                     keySize = ((DSAKey) key).getParams().getP().bitLength();
 381                 } else if (keyAlgo.equals("EC")) {
 382                     keySize = ((ECKey) key).getParams().getCurve().getField().getFieldSize();
 383                 } else {
 384                     throw new ProviderException("Error: unsupported algo " + keyAlgo);
 385                 }
 386             } catch (ClassCastException cce) {
 387                 throw new InvalidKeyException(keyAlgo +
 388                     " key must be the right type", cce);
 389             }
 390         }
 391         if ((minKeySize != -1) && (keySize < minKeySize)) {
 392             throw new InvalidKeyException(keyAlgo +
 393                 " key must be at least " + minKeySize + " bits");
 394         }
 395         if ((maxKeySize != -1) && (keySize > maxKeySize)) {
 396             throw new InvalidKeyException(keyAlgo +
 397                 " key must be at most " + maxKeySize + " bits");
 398         }
 399         if (keyAlgo.equals("RSA")) {
 400             checkRSAKeyLength(keySize);
 401         }
 402     }
 403 
 404     private void checkRSAKeyLength(int len) throws InvalidKeyException {
 405         RSAPadding padding;
 406         try {
 407             padding = RSAPadding.getInstance
 408                 (RSAPadding.PAD_BLOCKTYPE_1, (len + 7) >> 3);
 409         } catch (InvalidAlgorithmParameterException iape) {
 410             throw new InvalidKeyException(iape.getMessage());
 411         }
 412         int maxDataSize = padding.getMaxDataSize();
 413         int encodedLength;
 414         if (algorithm.equals("MD5withRSA") ||
 415             algorithm.equals("MD2withRSA")) {
 416             encodedLength = 34;
 417         } else if (algorithm.equals("SHA1withRSA")) {
 418             encodedLength = 35;
 419         } else if (algorithm.equals("SHA224withRSA")) {
 420             encodedLength = 47;
 421         } else if (algorithm.equals("SHA256withRSA")) {
 422             encodedLength = 51;
 423         } else if (algorithm.equals("SHA384withRSA")) {
 424             encodedLength = 67;
 425         } else if (algorithm.equals("SHA512withRSA")) {
 426             encodedLength = 83;
 427         } else {
 428             throw new ProviderException("Unknown signature algo: " + algorithm);
 429         }
 430         if (encodedLength > maxDataSize) {
 431             throw new InvalidKeyException
 432                 ("Key is too short for this signature algorithm");
 433         }
 434     }
 435 
 436     // see JCA spec
 437     protected void engineInitVerify(PublicKey publicKey)
 438             throws InvalidKeyException {
 439         if (publicKey == null) {
 440             throw new InvalidKeyException("Key must not be null");
 441         }
 442         // Need to check key length whenever a new key is set
 443         if (publicKey != p11Key) {
 444             checkKeySize(keyAlgorithm, publicKey);
 445         }
 446         cancelOperation();
 447         mode = M_VERIFY;
 448         p11Key = P11KeyFactory.convertKey(token, publicKey, keyAlgorithm);
 449         initialize();
 450     }
 451 
 452     // see JCA spec
 453     protected void engineInitSign(PrivateKey privateKey)
 454             throws InvalidKeyException {
 455         if (privateKey == null) {
 456             throw new InvalidKeyException("Key must not be null");
 457         }
 458         // Need to check RSA key length whenever a new key is set
 459         if (privateKey != p11Key) {
 460             checkKeySize(keyAlgorithm, privateKey);
 461         }
 462         cancelOperation();
 463         mode = M_SIGN;
 464         p11Key = P11KeyFactory.convertKey(token, privateKey, keyAlgorithm);
 465         initialize();
 466     }
 467 
 468     // see JCA spec
 469     protected void engineUpdate(byte b) throws SignatureException {
 470         ensureInitialized();
 471         switch (type) {
 472         case T_UPDATE:
 473             buffer[0] = b;
 474             engineUpdate(buffer, 0, 1);
 475             break;
 476         case T_DIGEST:
 477             md.update(b);
 478             bytesProcessed++;
 479             break;
 480         case T_RAW:
 481             if (bytesProcessed >= buffer.length) {
 482                 bytesProcessed = buffer.length + 1;
 483                 return;
 484             }
 485             buffer[bytesProcessed++] = b;
 486             break;
 487         default:
 488             throw new ProviderException("Internal error");
 489         }
 490     }
 491 
 492     // see JCA spec
 493     protected void engineUpdate(byte[] b, int ofs, int len)
 494             throws SignatureException {
 495         ensureInitialized();
 496         if (len == 0) {
 497             return;
 498         }
 499         switch (type) {
 500         case T_UPDATE:
 501             try {
 502                 if (mode == M_SIGN) {
 503                     token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
 504                 } else {
 505                     token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);
 506                 }
 507                 bytesProcessed += len;
 508             } catch (PKCS11Exception e) {
 509                 throw new ProviderException(e);
 510             }
 511             break;
 512         case T_DIGEST:
 513             md.update(b, ofs, len);
 514             bytesProcessed += len;
 515             break;
 516         case T_RAW:
 517             if (bytesProcessed + len > buffer.length) {
 518                 bytesProcessed = buffer.length + 1;
 519                 return;
 520             }
 521             System.arraycopy(b, ofs, buffer, bytesProcessed, len);
 522             bytesProcessed += len;
 523             break;
 524         default:
 525             throw new ProviderException("Internal error");
 526         }
 527     }
 528 
 529     // see JCA spec
 530     protected void engineUpdate(ByteBuffer byteBuffer) {
 531         ensureInitialized();
 532         int len = byteBuffer.remaining();
 533         if (len <= 0) {
 534             return;
 535         }
 536         switch (type) {
 537         case T_UPDATE:
 538             if (byteBuffer instanceof DirectBuffer == false) {
 539                 // cannot do better than default impl
 540                 super.engineUpdate(byteBuffer);
 541                 return;
 542             }
 543             long addr = ((DirectBuffer)byteBuffer).address();
 544             int ofs = byteBuffer.position();
 545             try {
 546                 if (mode == M_SIGN) {
 547                     token.p11.C_SignUpdate
 548                         (session.id(), addr + ofs, null, 0, len);
 549                 } else {
 550                     token.p11.C_VerifyUpdate
 551                         (session.id(), addr + ofs, null, 0, len);
 552                 }
 553                 bytesProcessed += len;
 554                 byteBuffer.position(ofs + len);
 555             } catch (PKCS11Exception e) {
 556                 throw new ProviderException("Update failed", e);
 557             }
 558             break;
 559         case T_DIGEST:
 560             md.update(byteBuffer);
 561             bytesProcessed += len;
 562             break;
 563         case T_RAW:
 564             if (bytesProcessed + len > buffer.length) {
 565                 bytesProcessed = buffer.length + 1;
 566                 return;
 567             }
 568             byteBuffer.get(buffer, bytesProcessed, len);
 569             bytesProcessed += len;
 570             break;
 571         default:
 572             throw new ProviderException("Internal error");
 573         }
 574     }
 575 
 576     // see JCA spec
 577     protected byte[] engineSign() throws SignatureException {
 578         ensureInitialized();
 579         try {
 580             byte[] signature;
 581             if (type == T_UPDATE) {
 582                 int len = keyAlgorithm.equals("DSA") ? 40 : 0;
 583                 signature = token.p11.C_SignFinal(session.id(), len);
 584             } else {
 585                 byte[] digest;
 586                 if (type == T_DIGEST) {
 587                     digest = md.digest();
 588                 } else { // T_RAW
 589                     if (mechanism == CKM_DSA) {
 590                         if (bytesProcessed != buffer.length) {
 591                             throw new SignatureException
 592                             ("Data for RawDSA must be exactly 20 bytes long");
 593                         }
 594                         digest = buffer;
 595                     } else { // CKM_ECDSA
 596                         if (bytesProcessed > buffer.length) {
 597                             throw new SignatureException("Data for NONEwithECDSA"
 598                             + " must be at most " + RAW_ECDSA_MAX + " bytes long");
 599                         }
 600                         digest = new byte[bytesProcessed];
 601                         System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
 602                     }
 603                 }
 604                 if (keyAlgorithm.equals("RSA") == false) {
 605                     // DSA and ECDSA
 606                     signature = token.p11.C_Sign(session.id(), digest);
 607                 } else { // RSA
 608                     byte[] data = encodeSignature(digest);
 609                     if (mechanism == CKM_RSA_X_509) {
 610                         data = pkcs1Pad(data);
 611                     }
 612                     signature = token.p11.C_Sign(session.id(), data);
 613                 }
 614             }
 615             if (keyAlgorithm.equals("RSA")) {
 616                 return signature;
 617             } else {
 618                 if (p1363Format) {
 619                     return signature;
 620                 } else {
 621                     return dsaToASN1(signature);
 622                 }
 623             }
 624         } catch (PKCS11Exception pe) {
 625             throw new ProviderException(pe);
 626         } catch (SignatureException | ProviderException e) {
 627             cancelOperation();
 628             throw e;
 629         } finally {
 630             initialized = false;
 631             session = token.releaseSession(session);
 632         }
 633     }
 634 
 635     // see JCA spec
 636     protected boolean engineVerify(byte[] signature) throws SignatureException {
 637         ensureInitialized();
 638         try {
 639             if (!p1363Format) {
 640                 if (keyAlgorithm.equals("DSA")) {
 641                     signature = asn1ToDSA(signature);
 642                 } else if (keyAlgorithm.equals("EC")) {
 643                     signature = asn1ToECDSA(signature);
 644                 }
 645             }
 646             if (type == T_UPDATE) {
 647                 token.p11.C_VerifyFinal(session.id(), signature);
 648             } else {
 649                 byte[] digest;
 650                 if (type == T_DIGEST) {
 651                     digest = md.digest();
 652                 } else { // T_RAW
 653                     if (mechanism == CKM_DSA) {
 654                         if (bytesProcessed != buffer.length) {
 655                             throw new SignatureException
 656                             ("Data for RawDSA must be exactly 20 bytes long");
 657                         }
 658                         digest = buffer;
 659                     } else {
 660                         if (bytesProcessed > buffer.length) {
 661                             throw new SignatureException("Data for NONEwithECDSA"
 662                             + " must be at most " + RAW_ECDSA_MAX + " bytes long");
 663                         }
 664                         digest = new byte[bytesProcessed];
 665                         System.arraycopy(buffer, 0, digest, 0, bytesProcessed);
 666                     }
 667                 }
 668                 if (keyAlgorithm.equals("RSA") == false) {
 669                     // DSA and ECDSA
 670                     token.p11.C_Verify(session.id(), digest, signature);
 671                 } else { // RSA
 672                     byte[] data = encodeSignature(digest);
 673                     if (mechanism == CKM_RSA_X_509) {
 674                         data = pkcs1Pad(data);
 675                     }
 676                     token.p11.C_Verify(session.id(), data, signature);
 677                 }
 678             }
 679             return true;
 680         } catch (PKCS11Exception pe) {
 681             long errorCode = pe.getErrorCode();
 682             if (errorCode == CKR_SIGNATURE_INVALID) {
 683                 return false;
 684             }
 685             if (errorCode == CKR_SIGNATURE_LEN_RANGE) {
 686                 // return false rather than throwing an exception
 687                 return false;
 688             }
 689             // ECF bug?
 690             if (errorCode == CKR_DATA_LEN_RANGE) {
 691                 return false;
 692             }
 693             throw new ProviderException(pe);
 694         }  catch (SignatureException | ProviderException e) {
 695             cancelOperation();
 696             throw e;
 697         } finally {
 698             initialized = false;
 699             session = token.releaseSession(session);
 700         }
 701     }
 702 
 703     private byte[] pkcs1Pad(byte[] data) {
 704         try {
 705             int len = (p11Key.length() + 7) >> 3;
 706             RSAPadding padding = RSAPadding.getInstance
 707                                         (RSAPadding.PAD_BLOCKTYPE_1, len);
 708             byte[] padded = padding.pad(data);
 709             return padded;
 710         } catch (GeneralSecurityException e) {
 711             throw new ProviderException(e);
 712         }
 713     }
 714 
 715     private byte[] encodeSignature(byte[] digest) throws SignatureException {
 716         try {
 717             return RSASignature.encodeSignature(digestOID, digest);
 718         } catch (IOException e) {
 719             throw new SignatureException("Invalid encoding", e);
 720         }
 721     }
 722 
 723 //    private static byte[] decodeSignature(byte[] signature) throws IOException {
 724 //      return RSASignature.decodeSignature(digestOID, signature);
 725 //    }
 726 
 727     // For DSA and ECDSA signatures, PKCS#11 represents them as a simple
 728     // byte array that contains the concatenation of r and s.
 729     // For DSA, r and s are always exactly 20 bytes long.
 730     // For ECDSA, r and s are of variable length, but we know that each
 731     // occupies half of the array.
 732     private static byte[] dsaToASN1(byte[] signature) {
 733         int n = signature.length >> 1;
 734         BigInteger r = new BigInteger(1, P11Util.subarray(signature, 0, n));
 735         BigInteger s = new BigInteger(1, P11Util.subarray(signature, n, n));
 736         try {
 737             DerOutputStream outseq = new DerOutputStream(100);
 738             outseq.putInteger(r);
 739             outseq.putInteger(s);
 740             DerValue result = new DerValue(DerValue.tag_Sequence,
 741                                            outseq.toByteArray());
 742             return result.toByteArray();
 743         } catch (java.io.IOException e) {
 744             throw new RuntimeException("Internal error", e);
 745         }
 746     }
 747 
 748     private static byte[] asn1ToDSA(byte[] sig) throws SignatureException {
 749         try {
 750             // Enforce strict DER checking for signatures
 751             DerInputStream in = new DerInputStream(sig, 0, sig.length, false);
 752             DerValue[] values = in.getSequence(2);
 753 
 754             // check number of components in the read sequence
 755             // and trailing data
 756             if ((values.length != 2) || (in.available() != 0)) {
 757                 throw new IOException("Invalid encoding for signature");
 758             }
 759 
 760             BigInteger r = values[0].getPositiveBigInteger();
 761             BigInteger s = values[1].getPositiveBigInteger();
 762 
 763             byte[] br = toByteArray(r, 20);
 764             byte[] bs = toByteArray(s, 20);
 765             if ((br == null) || (bs == null)) {
 766                 throw new SignatureException("Out of range value for R or S");
 767             }
 768             return P11Util.concat(br, bs);
 769         } catch (SignatureException e) {
 770             throw e;
 771         } catch (Exception e) {
 772             throw new SignatureException("Invalid encoding for signature", e);
 773         }
 774     }
 775 
 776     private byte[] asn1ToECDSA(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             // trim leading zeroes
 792             byte[] br = KeyUtil.trimZeroes(r.toByteArray());
 793             byte[] bs = KeyUtil.trimZeroes(s.toByteArray());
 794             int k = Math.max(br.length, bs.length);
 795             // r and s each occupy half the array
 796             byte[] res = new byte[k << 1];
 797             System.arraycopy(br, 0, res, k - br.length, br.length);
 798             System.arraycopy(bs, 0, res, res.length - bs.length, bs.length);
 799             return res;
 800         } catch (Exception e) {
 801             throw new SignatureException("Invalid encoding for signature", e);
 802         }
 803     }
 804 
 805     private static byte[] toByteArray(BigInteger bi, int len) {
 806         byte[] b = bi.toByteArray();
 807         int n = b.length;
 808         if (n == len) {
 809             return b;
 810         }
 811         if ((n == len + 1) && (b[0] == 0)) {
 812             byte[] t = new byte[len];
 813             System.arraycopy(b, 1, t, 0, len);
 814             return t;
 815         }
 816         if (n > len) {
 817             return null;
 818         }
 819         // must be smaller
 820         byte[] t = new byte[len];
 821         System.arraycopy(b, 0, t, (len - n), n);
 822         return t;
 823     }
 824 
 825     // see JCA spec
 826     @SuppressWarnings("deprecation")
 827     protected void engineSetParameter(String param, Object value)
 828             throws InvalidParameterException {
 829         throw new UnsupportedOperationException("setParameter() not supported");
 830     }
 831 
 832     // see JCA spec
 833     @SuppressWarnings("deprecation")
 834     protected Object engineGetParameter(String param)
 835             throws InvalidParameterException {
 836         throw new UnsupportedOperationException("getParameter() not supported");
 837     }
 838 }