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