< prev index next >

src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Signature.java

Print this page




 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;


 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             }


 504     protected void engineUpdate(byte[] b, int ofs, int len)
 505             throws SignatureException {
 506         ensureInitialized();
 507         if (len == 0) {
 508             return;
 509         }
 510         // check for overflow
 511         if (len + bytesProcessed < 0) {
 512             throw new ProviderException("Processed bytes limits exceeded.");
 513         }
 514         switch (type) {
 515         case T_UPDATE:
 516             try {
 517                 if (mode == M_SIGN) {
 518                     token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
 519                 } else {
 520                     token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);
 521                 }
 522                 bytesProcessed += len;
 523             } catch (PKCS11Exception e) {
 524                 initialized = false;
 525                 session = token.releaseSession(session);
 526                 throw new ProviderException(e);
 527             }
 528             break;
 529         case T_DIGEST:
 530             md.update(b, ofs, len);
 531             bytesProcessed += len;
 532             break;
 533         case T_RAW:
 534             if (bytesProcessed + len > buffer.length) {
 535                 bytesProcessed = buffer.length + 1;
 536                 return;
 537             }
 538             System.arraycopy(b, ofs, buffer, bytesProcessed, len);
 539             bytesProcessed += len;
 540             break;
 541         default:
 542             throw new ProviderException("Internal error");
 543         }
 544     }
 545 


 628                 } else { // RSA
 629                     byte[] data = encodeSignature(digest);
 630                     if (mechanism == CKM_RSA_X_509) {
 631                         data = pkcs1Pad(data);
 632                     }
 633                     signature = token.p11.C_Sign(session.id(), data);
 634                 }
 635             }
 636             if (keyAlgorithm.equals("RSA")) {
 637                 return signature;
 638             } else {
 639                 if (p1363Format) {
 640                     return signature;
 641                 } else {
 642                     return dsaToASN1(signature);
 643                 }
 644             }
 645         } catch (PKCS11Exception pe) {
 646             throw new ProviderException(pe);
 647         } catch (SignatureException | ProviderException e) {
 648             cancelOperation();
 649             throw e;
 650         } finally {
 651             initialized = false;
 652             session = token.releaseSession(session);
 653         }
 654     }
 655 
 656     // see JCA spec
 657     @Override
 658     protected boolean engineVerify(byte[] signature) throws SignatureException {
 659         ensureInitialized();
 660         try {
 661             if (!p1363Format) {
 662                 if (keyAlgorithm.equals("DSA")) {
 663                     signature = asn1ToDSA(signature);
 664                 } else if (keyAlgorithm.equals("EC")) {
 665                     signature = asn1ToECDSA(signature);
 666                 }
 667             }
 668             if (type == T_UPDATE) {
 669                 token.p11.C_VerifyFinal(session.id(), signature);
 670             } else {
 671                 byte[] digest;
 672                 if (type == T_DIGEST) {


 697                     }
 698                     token.p11.C_Verify(session.id(), data, signature);
 699                 }
 700             }
 701             return true;
 702         } catch (PKCS11Exception pe) {
 703             long errorCode = pe.getErrorCode();
 704             if (errorCode == CKR_SIGNATURE_INVALID) {
 705                 return false;
 706             }
 707             if (errorCode == CKR_SIGNATURE_LEN_RANGE) {
 708                 // return false rather than throwing an exception
 709                 return false;
 710             }
 711             // ECF bug?
 712             if (errorCode == CKR_DATA_LEN_RANGE) {
 713                 return false;
 714             }
 715             throw new ProviderException(pe);
 716         }  catch (SignatureException | ProviderException e) {
 717             cancelOperation();
 718             throw e;
 719         } finally {
 720             initialized = false;
 721             session = token.releaseSession(session);
 722         }
 723     }
 724 
 725     private byte[] pkcs1Pad(byte[] data) {
 726         try {
 727             int len = (p11Key.length() + 7) >> 3;
 728             RSAPadding padding = RSAPadding.getInstance
 729                                         (RSAPadding.PAD_BLOCKTYPE_1, len);
 730             byte[] padded = padding.pad(data);
 731             return padded;
 732         } catch (GeneralSecurityException e) {
 733             throw new ProviderException(e);
 734         }
 735     }
 736 
 737     private byte[] encodeSignature(byte[] digest) throws SignatureException {
 738         try {
 739             return RSASignature.encodeSignature(digestOID, digest);
 740         } catch (IOException e) {
 741             throw new SignatureException("Invalid encoding", e);




 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     // reset the states to the pre-initialized values
 267     private void reset(boolean doCancel) {
 268         if (!initialized) {







 269             return;
 270         }
 271         initialized = false;
 272         try {
 273             if (session == null) {
 274                 return;
 275             }
 276             if (doCancel && token.explicitCancel) {
 277                 cancelOperation();
 278             }
 279         } finally {
 280             p11Key.decNativeKeyRef();
 281             session = token.releaseSession(session);
 282         }
 283     }
 284 
 285     private void cancelOperation() {
 286         token.ensureValid();
 287         if (session.hasObjects() == false) {
 288             session = token.killSession(session);
 289             return;
 290         } else {

 291             // "cancel" operation by finishing it
 292             // XXX make sure all this always works correctly

 293             try {
 294                 if (mode == M_SIGN) {
 295                     if (type == T_UPDATE) {
 296                         token.p11.C_SignFinal(session.id(), 0);
 297                     } else {
 298                         byte[] digest;
 299                         if (type == T_DIGEST) {
 300                             digest = md.digest();
 301                         } else { // T_RAW
 302                             digest = buffer;
 303                         }
 304                         token.p11.C_Sign(session.id(), digest);
 305                     }



 306                 } else { // M_VERIFY

 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                 }
 325             } catch (PKCS11Exception e) {
 326                 throw new ProviderException("cancel failed", e);
 327             }


 328         }
 329     }
 330 
 331     // assumes current state is initialized == false
 332     private void ensureInitialized() {
 333         if (initialized) {
 334             return;
 335         }
 336         if (p11Key == null) {
 337             throw new ProviderException(
 338                     "Operation cannot be performed without " +
 339                     "calling engineInit first");
 340         }
 341         try {
 342             token.ensureValid();
 343             p11Key.incNativeKeyRef();
 344             try {
 345                 if (session == null) {
 346                     session = token.getOpSession();
 347                 }
 348                 if (mode == M_SIGN) {
 349                     token.p11.C_SignInit(session.id(),
 350                             new CK_MECHANISM(mechanism), p11Key.keyID);
 351                 } else {
 352                     token.p11.C_VerifyInit(session.id(),
 353                             new CK_MECHANISM(mechanism), p11Key.keyID);
 354                 }
 355             } catch (Throwable t) {
 356                 p11Key.decNativeKeyRef();

 357                 session = token.releaseSession(session);
 358                 throw t;
 359             }
 360             initialized = true;
 361             if (bytesProcessed != 0 && md != null) {

 362                 md.reset();
 363             }
 364             bytesProcessed = 0;
 365         } catch (PKCS11Exception e) {
 366             throw new ProviderException("Initialization failed", e);
 367         }
 368     }
 369 
 370     private void checkKeySize(String keyAlgo, Key key)
 371         throws InvalidKeyException {
 372         CK_MECHANISM_INFO mechInfo = null;
 373         try {
 374             mechInfo = token.getMechanismInfo(mechanism);
 375         } catch (PKCS11Exception e) {
 376             // should not happen, ignore for now.
 377         }
 378         if (mechInfo == null) {
 379             // skip the check if no native info available
 380             return;
 381         }
 382         int minKeySize = (int) mechInfo.ulMinKeySize;
 383         int maxKeySize = (int) mechInfo.ulMaxKeySize;
 384         // need to override the MAX keysize for SHA1withDSA
 385         if (md != null && mechanism == CKM_DSA && maxKeySize > 1024) {
 386                maxKeySize = 1024;


 443         } else {
 444             throw new ProviderException("Unknown signature algo: " + algorithm);
 445         }
 446         if (encodedLength > maxDataSize) {
 447             throw new InvalidKeyException
 448                 ("Key is too short for this signature algorithm");
 449         }
 450     }
 451 
 452     // see JCA spec
 453     @Override
 454     protected void engineInitVerify(PublicKey publicKey)
 455             throws InvalidKeyException {
 456         if (publicKey == null) {
 457             throw new InvalidKeyException("Key must not be null");
 458         }
 459         // Need to check key length whenever a new key is set
 460         if (publicKey != p11Key) {
 461             checkKeySize(keyAlgorithm, publicKey);
 462         }
 463         reset(true);
 464         mode = M_VERIFY;
 465         p11Key = P11KeyFactory.convertKey(token, publicKey, keyAlgorithm);
 466         ensureInitialized();
 467     }
 468 
 469     // see JCA spec
 470     @Override
 471     protected void engineInitSign(PrivateKey privateKey)
 472             throws InvalidKeyException {
 473         if (privateKey == null) {
 474             throw new InvalidKeyException("Key must not be null");
 475         }
 476         // Need to check RSA key length whenever a new key is set
 477         if (privateKey != p11Key) {
 478             checkKeySize(keyAlgorithm, privateKey);
 479         }
 480         reset(true);
 481         mode = M_SIGN;
 482         p11Key = P11KeyFactory.convertKey(token, privateKey, keyAlgorithm);
 483         ensureInitialized();
 484     }
 485 
 486     // see JCA spec
 487     @Override
 488     protected void engineUpdate(byte b) throws SignatureException {
 489         ensureInitialized();
 490         switch (type) {
 491         case T_UPDATE:
 492             buffer[0] = b;
 493             engineUpdate(buffer, 0, 1);
 494             break;
 495         case T_DIGEST:
 496             md.update(b);
 497             bytesProcessed++;
 498             break;
 499         case T_RAW:
 500             if (bytesProcessed >= buffer.length) {
 501                 bytesProcessed = buffer.length + 1;
 502                 return;
 503             }


 513     protected void engineUpdate(byte[] b, int ofs, int len)
 514             throws SignatureException {
 515         ensureInitialized();
 516         if (len == 0) {
 517             return;
 518         }
 519         // check for overflow
 520         if (len + bytesProcessed < 0) {
 521             throw new ProviderException("Processed bytes limits exceeded.");
 522         }
 523         switch (type) {
 524         case T_UPDATE:
 525             try {
 526                 if (mode == M_SIGN) {
 527                     token.p11.C_SignUpdate(session.id(), 0, b, ofs, len);
 528                 } else {
 529                     token.p11.C_VerifyUpdate(session.id(), 0, b, ofs, len);
 530                 }
 531                 bytesProcessed += len;
 532             } catch (PKCS11Exception e) {
 533                 reset(true);

 534                 throw new ProviderException(e);
 535             }
 536             break;
 537         case T_DIGEST:
 538             md.update(b, ofs, len);
 539             bytesProcessed += len;
 540             break;
 541         case T_RAW:
 542             if (bytesProcessed + len > buffer.length) {
 543                 bytesProcessed = buffer.length + 1;
 544                 return;
 545             }
 546             System.arraycopy(b, ofs, buffer, bytesProcessed, len);
 547             bytesProcessed += len;
 548             break;
 549         default:
 550             throw new ProviderException("Internal error");
 551         }
 552     }
 553 


 636                 } else { // RSA
 637                     byte[] data = encodeSignature(digest);
 638                     if (mechanism == CKM_RSA_X_509) {
 639                         data = pkcs1Pad(data);
 640                     }
 641                     signature = token.p11.C_Sign(session.id(), data);
 642                 }
 643             }
 644             if (keyAlgorithm.equals("RSA")) {
 645                 return signature;
 646             } else {
 647                 if (p1363Format) {
 648                     return signature;
 649                 } else {
 650                     return dsaToASN1(signature);
 651                 }
 652             }
 653         } catch (PKCS11Exception pe) {
 654             throw new ProviderException(pe);
 655         } catch (SignatureException | ProviderException e) {
 656             reset(true);
 657             throw e;
 658         } finally {
 659             reset(false);

 660         }
 661     }
 662 
 663     // see JCA spec
 664     @Override
 665     protected boolean engineVerify(byte[] signature) throws SignatureException {
 666         ensureInitialized();
 667         try {
 668             if (!p1363Format) {
 669                 if (keyAlgorithm.equals("DSA")) {
 670                     signature = asn1ToDSA(signature);
 671                 } else if (keyAlgorithm.equals("EC")) {
 672                     signature = asn1ToECDSA(signature);
 673                 }
 674             }
 675             if (type == T_UPDATE) {
 676                 token.p11.C_VerifyFinal(session.id(), signature);
 677             } else {
 678                 byte[] digest;
 679                 if (type == T_DIGEST) {


 704                     }
 705                     token.p11.C_Verify(session.id(), data, signature);
 706                 }
 707             }
 708             return true;
 709         } catch (PKCS11Exception pe) {
 710             long errorCode = pe.getErrorCode();
 711             if (errorCode == CKR_SIGNATURE_INVALID) {
 712                 return false;
 713             }
 714             if (errorCode == CKR_SIGNATURE_LEN_RANGE) {
 715                 // return false rather than throwing an exception
 716                 return false;
 717             }
 718             // ECF bug?
 719             if (errorCode == CKR_DATA_LEN_RANGE) {
 720                 return false;
 721             }
 722             throw new ProviderException(pe);
 723         }  catch (SignatureException | ProviderException e) {
 724             reset(true);
 725             throw e;
 726         } finally {
 727             reset(false);

 728         }
 729     }
 730 
 731     private byte[] pkcs1Pad(byte[] data) {
 732         try {
 733             int len = (p11Key.length() + 7) >> 3;
 734             RSAPadding padding = RSAPadding.getInstance
 735                                         (RSAPadding.PAD_BLOCKTYPE_1, len);
 736             byte[] padded = padding.pad(data);
 737             return padded;
 738         } catch (GeneralSecurityException e) {
 739             throw new ProviderException(e);
 740         }
 741     }
 742 
 743     private byte[] encodeSignature(byte[] digest) throws SignatureException {
 744         try {
 745             return RSASignature.encodeSignature(digestOID, digest);
 746         } catch (IOException e) {
 747             throw new SignatureException("Invalid encoding", e);


< prev index next >