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 }