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