< prev index next >

src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/P11Cipher.java

Print this page




 327         byte[] ivValue;
 328         if (params != null) {
 329             try {
 330                 IvParameterSpec ivSpec =
 331                         params.getParameterSpec(IvParameterSpec.class);
 332                 ivValue = ivSpec.getIV();
 333             } catch (InvalidParameterSpecException e) {
 334                 throw new InvalidAlgorithmParameterException
 335                         ("Could not decode IV", e);
 336             }
 337         } else {
 338             ivValue = null;
 339         }
 340         implInit(opmode, key, ivValue, random);
 341     }
 342 
 343     // actual init() implementation
 344     private void implInit(int opmode, Key key, byte[] iv,
 345             SecureRandom random)
 346             throws InvalidKeyException, InvalidAlgorithmParameterException {
 347         cancelOperation();
 348         if (fixedKeySize != -1 && key.getEncoded().length != fixedKeySize) {
 349             throw new InvalidKeyException("Key size is invalid");
 350         }
 351         switch (opmode) {
 352             case Cipher.ENCRYPT_MODE:
 353                 encrypt = true;
 354                 break;
 355             case Cipher.DECRYPT_MODE:
 356                 encrypt = false;
 357                 break;
 358             default:
 359                 throw new InvalidAlgorithmParameterException
 360                         ("Unsupported mode: " + opmode);
 361         }
 362         if (blockMode == MODE_ECB) { // ECB or stream cipher
 363             if (iv != null) {
 364                 if (blockSize == 0) {
 365                     throw new InvalidAlgorithmParameterException
 366                             ("IV not used with stream ciphers");
 367                 } else {


 387             } else {
 388                 if (iv.length != blockSize) {
 389                     throw new InvalidAlgorithmParameterException
 390                             ("IV length must match block size");
 391                 }
 392             }
 393         }
 394         this.iv = iv;
 395         p11Key = P11SecretKeyFactory.convertKey(token, key, keyAlgorithm);
 396         try {
 397             initialize();
 398         } catch (PKCS11Exception e) {
 399             throw new InvalidKeyException("Could not initialize cipher", e);
 400         }
 401     }
 402 
 403     private void cancelOperation() {
 404         if (initialized == false) {
 405             return;
 406         }
 407         initialized = false;
 408         if ((session == null) || (token.explicitCancel == false)) {
 409             return;
 410         }





 411         // cancel operation by finishing it
 412         int bufLen = doFinalLength(0);
 413         byte[] buffer = new byte[bufLen];
 414         try {
 415             if (encrypt) {
 416                 token.p11.C_EncryptFinal(session.id(), 0, buffer, 0, bufLen);
 417             } else {
 418                 token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen);
 419             }

 420         } catch (PKCS11Exception e) {
 421             throw new ProviderException("Cancel failed", e);
 422         } finally {
 423             reset();
 424         }
 425     }
 426 
 427     private void ensureInitialized() throws PKCS11Exception {
 428         if (initialized == false) {
 429             initialize();
 430         }
 431     }
 432 
 433     private void initialize() throws PKCS11Exception {
 434         if (session == null) {
 435             session = token.getOpSession();
 436         }
 437         CK_MECHANISM mechParams = (blockMode == MODE_CTR?
 438             new CK_MECHANISM(mechanism, new CK_AES_CTR_PARAMS(iv)) :
 439             new CK_MECHANISM(mechanism, iv));
 440 
 441         try {
 442             if (encrypt) {
 443                 token.p11.C_EncryptInit(session.id(), mechParams, p11Key.keyID);


 466             result -= (result & (blockSize - 1));
 467         }
 468         return result;
 469     }
 470 
 471     // if doFinal(inLen) is called, how big does the output buffer have to be?
 472     private int doFinalLength(int inLen) {
 473         if (inLen < 0) {
 474             return 0;
 475         }
 476 
 477         int result = inLen + bytesBuffered;
 478         if (blockSize != 0 && encrypt && paddingType != PAD_NONE) {
 479             // add the number of bytes to make the last block complete.
 480             result += (blockSize - (result & (blockSize - 1)));
 481         }
 482         return result;
 483     }
 484 
 485     // reset the states to the pre-initialized values
 486     private void reset() {


 487         initialized = false;
 488         bytesBuffered = 0;
 489         padBufferLen = 0;
 490         if (session != null) {
 491             session = token.releaseSession(session);
 492         }
 493     }
 494 
 495     // see JCE spec
 496     protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
 497         try {
 498             byte[] out = new byte[updateLength(inLen)];
 499             int n = engineUpdate(in, inOfs, inLen, out, 0);
 500             return P11Util.convert(out, 0, n);
 501         } catch (ShortBufferException e) {
 502             // convert since the output length is calculated by updateLength()
 503             throw new ProviderException(e);
 504         }
 505     }
 506 


 593                         newPadBufferLen = padBuffer.length;
 594                     }
 595                     inLen -= newPadBufferLen;
 596                 }
 597                 if (inLen > 0) {
 598                     k += token.p11.C_DecryptUpdate(session.id(), 0, in, inOfs,
 599                             inLen, 0, out, (outOfs + k), (outLen - k));
 600                 }
 601                 // update 'padBuffer' if using our own padding impl.
 602                 if (paddingObj != null) {
 603                     bufferInputBytes(in, inOfs + inLen, newPadBufferLen);
 604                 }
 605             }
 606             bytesBuffered += (inLen - k);
 607             return k;
 608         } catch (PKCS11Exception e) {
 609             if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
 610                 throw (ShortBufferException)
 611                         (new ShortBufferException().initCause(e));
 612             }
 613             reset();
 614             throw new ProviderException("update() failed", e);
 615         }
 616     }
 617 
 618     private int implUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
 619             throws ShortBufferException {
 620         int inLen = inBuffer.remaining();
 621         if (inLen <= 0) {
 622             return 0;
 623         }
 624 
 625         int outLen = outBuffer.remaining();
 626         if (outLen < updateLength(inLen)) {
 627             throw new ShortBufferException();
 628         }
 629         int origPos = inBuffer.position();
 630         try {
 631             ensureInitialized();
 632 
 633             long inAddr = 0;


 711                 // update 'padBuffer' if using our own padding impl.
 712                 if (paddingObj != null && newPadBufferLen != 0) {
 713                     bufferInputBytes(inBuffer, newPadBufferLen);
 714                 }
 715             }
 716             bytesBuffered += (inLen - k);
 717             if (!(outBuffer instanceof DirectBuffer) &&
 718                     !outBuffer.hasArray()) {
 719                 outBuffer.put(outArray, outOfs, k);
 720             } else {
 721                 outBuffer.position(outBuffer.position() + k);
 722             }
 723             return k;
 724         } catch (PKCS11Exception e) {
 725             // Reset input buffer to its original position for
 726             inBuffer.position(origPos);
 727             if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
 728                 throw (ShortBufferException)
 729                         (new ShortBufferException().initCause(e));
 730             }
 731             reset();
 732             throw new ProviderException("update() failed", e);
 733         }
 734     }
 735 
 736     private int implDoFinal(byte[] out, int outOfs, int outLen)
 737             throws ShortBufferException, IllegalBlockSizeException,
 738             BadPaddingException {
 739         int requiredOutLen = doFinalLength(0);
 740         if (outLen < requiredOutLen) {
 741             throw new ShortBufferException();
 742         }

 743         try {
 744             ensureInitialized();
 745             int k = 0;
 746             if (encrypt) {
 747                 if (paddingObj != null) {
 748                     int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
 749                             requiredOutLen - bytesBuffered);
 750                     k = token.p11.C_EncryptUpdate(session.id(),
 751                             0, padBuffer, 0, actualPadLen,
 752                             0, out, outOfs, outLen);
 753                 }
 754                 k += token.p11.C_EncryptFinal(session.id(),
 755                         0, out, (outOfs + k), (outLen - k));

 756             } else {




 757                 if (paddingObj != null) {
 758                     if (padBufferLen != 0) {
 759                         k = token.p11.C_DecryptUpdate(session.id(), 0,
 760                                 padBuffer, 0, padBufferLen, 0, padBuffer, 0,
 761                                 padBuffer.length);
 762                     }
 763                     k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k,
 764                             padBuffer.length - k);


 765                     int actualPadLen = paddingObj.unpad(padBuffer, k);
 766                     k -= actualPadLen;
 767                     System.arraycopy(padBuffer, 0, out, outOfs, k);
 768                 } else {
 769                     k = token.p11.C_DecryptFinal(session.id(), 0, out, outOfs,
 770                             outLen);

 771                 }
 772             }
 773             return k;
 774         } catch (PKCS11Exception e) {

 775             handleException(e);
 776             throw new ProviderException("doFinal() failed", e);
 777         } finally {
 778             reset();
 779         }
 780     }
 781 
 782     private int implDoFinal(ByteBuffer outBuffer)
 783             throws ShortBufferException, IllegalBlockSizeException,
 784             BadPaddingException {
 785         int outLen = outBuffer.remaining();
 786         int requiredOutLen = doFinalLength(0);
 787         if (outLen < requiredOutLen) {
 788             throw new ShortBufferException();
 789         }
 790 

 791         try {
 792             ensureInitialized();
 793 
 794             long outAddr = 0;
 795             byte[] outArray = null;
 796             int outOfs = 0;
 797             if (outBuffer instanceof DirectBuffer) {
 798                 outAddr = ((DirectBuffer) outBuffer).address();
 799                 outOfs = outBuffer.position();
 800             } else {
 801                 if (outBuffer.hasArray()) {
 802                     outArray = outBuffer.array();
 803                     outOfs = outBuffer.position() + outBuffer.arrayOffset();
 804                 } else {
 805                     outArray = new byte[outLen];
 806                 }
 807             }
 808 
 809             int k = 0;
 810 
 811             if (encrypt) {
 812                 if (paddingObj != null) {
 813                     int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
 814                             requiredOutLen - bytesBuffered);
 815                     k = token.p11.C_EncryptUpdate(session.id(),
 816                             0, padBuffer, 0, actualPadLen,
 817                             outAddr, outArray, outOfs, outLen);
 818                 }
 819                 k += token.p11.C_EncryptFinal(session.id(),
 820                         outAddr, outArray, (outOfs + k), (outLen - k));

 821             } else {





 822                 if (paddingObj != null) {
 823                     if (padBufferLen != 0) {
 824                         k = token.p11.C_DecryptUpdate(session.id(),
 825                                 0, padBuffer, 0, padBufferLen,
 826                                 0, padBuffer, 0, padBuffer.length);
 827                         padBufferLen = 0;
 828                     }
 829                     k += token.p11.C_DecryptFinal(session.id(),
 830                             0, padBuffer, k, padBuffer.length - k);


 831                     int actualPadLen = paddingObj.unpad(padBuffer, k);
 832                     k -= actualPadLen;
 833                     outArray = padBuffer;
 834                     outOfs = 0;
 835                 } else {
 836                     k = token.p11.C_DecryptFinal(session.id(),
 837                             outAddr, outArray, outOfs, outLen);

 838                 }
 839             }
 840             if ((!encrypt && paddingObj != null) ||
 841                     (!(outBuffer instanceof DirectBuffer) &&
 842                     !outBuffer.hasArray())) {
 843                 outBuffer.put(outArray, outOfs, k);
 844             } else {
 845                 outBuffer.position(outBuffer.position() + k);
 846             }
 847             return k;
 848         } catch (PKCS11Exception e) {

 849             handleException(e);
 850             throw new ProviderException("doFinal() failed", e);
 851         } finally {
 852             reset();
 853         }
 854     }
 855 
 856     private void handleException(PKCS11Exception e)
 857             throws ShortBufferException, IllegalBlockSizeException {
 858         long errorCode = e.getErrorCode();
 859         if (errorCode == CKR_BUFFER_TOO_SMALL) {
 860             throw (ShortBufferException)
 861                     (new ShortBufferException().initCause(e));
 862         } else if (errorCode == CKR_DATA_LEN_RANGE ||
 863                    errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) {
 864             throw (IllegalBlockSizeException)
 865                     (new IllegalBlockSizeException(e.toString()).initCause(e));
 866         }
 867     }
 868 
 869     // see JCE spec
 870     protected byte[] engineWrap(Key key) throws IllegalBlockSizeException,
 871             InvalidKeyException {
 872         // XXX key wrapping




 327         byte[] ivValue;
 328         if (params != null) {
 329             try {
 330                 IvParameterSpec ivSpec =
 331                         params.getParameterSpec(IvParameterSpec.class);
 332                 ivValue = ivSpec.getIV();
 333             } catch (InvalidParameterSpecException e) {
 334                 throw new InvalidAlgorithmParameterException
 335                         ("Could not decode IV", e);
 336             }
 337         } else {
 338             ivValue = null;
 339         }
 340         implInit(opmode, key, ivValue, random);
 341     }
 342 
 343     // actual init() implementation
 344     private void implInit(int opmode, Key key, byte[] iv,
 345             SecureRandom random)
 346             throws InvalidKeyException, InvalidAlgorithmParameterException {
 347         reset(true);
 348         if (fixedKeySize != -1 && key.getEncoded().length != fixedKeySize) {
 349             throw new InvalidKeyException("Key size is invalid");
 350         }
 351         switch (opmode) {
 352             case Cipher.ENCRYPT_MODE:
 353                 encrypt = true;
 354                 break;
 355             case Cipher.DECRYPT_MODE:
 356                 encrypt = false;
 357                 break;
 358             default:
 359                 throw new InvalidAlgorithmParameterException
 360                         ("Unsupported mode: " + opmode);
 361         }
 362         if (blockMode == MODE_ECB) { // ECB or stream cipher
 363             if (iv != null) {
 364                 if (blockSize == 0) {
 365                     throw new InvalidAlgorithmParameterException
 366                             ("IV not used with stream ciphers");
 367                 } else {


 387             } else {
 388                 if (iv.length != blockSize) {
 389                     throw new InvalidAlgorithmParameterException
 390                             ("IV length must match block size");
 391                 }
 392             }
 393         }
 394         this.iv = iv;
 395         p11Key = P11SecretKeyFactory.convertKey(token, key, keyAlgorithm);
 396         try {
 397             initialize();
 398         } catch (PKCS11Exception e) {
 399             throw new InvalidKeyException("Could not initialize cipher", e);
 400         }
 401     }
 402 
 403     private void cancelOperation() {
 404         if (initialized == false) {
 405             return;
 406         }
 407 
 408         if ((session == null) || (token.explicitCancel == false)) {
 409             return;
 410         }
 411         try {
 412             if (session.hasObjects() == false) {
 413                 session = token.killSession(session);
 414                 return;
 415             } else {
 416                 // cancel operation by finishing it
 417                 int bufLen = doFinalLength(0);
 418                 byte[] buffer = new byte[bufLen];

 419                 if (encrypt) {
 420                     token.p11.C_EncryptFinal(session.id(), 0, buffer, 0, bufLen);
 421                 } else {
 422                     token.p11.C_DecryptFinal(session.id(), 0, buffer, 0, bufLen);
 423                 }
 424             }
 425         } catch (PKCS11Exception e) {
 426             throw new ProviderException("Cancel failed", e);


 427         }
 428     }
 429 
 430     private void ensureInitialized() throws PKCS11Exception {
 431         if (initialized == false) {
 432             initialize();
 433         }
 434     }
 435 
 436     private void initialize() throws PKCS11Exception {
 437         if (session == null) {
 438             session = token.getOpSession();
 439         }
 440         CK_MECHANISM mechParams = (blockMode == MODE_CTR?
 441             new CK_MECHANISM(mechanism, new CK_AES_CTR_PARAMS(iv)) :
 442             new CK_MECHANISM(mechanism, iv));
 443 
 444         try {
 445             if (encrypt) {
 446                 token.p11.C_EncryptInit(session.id(), mechParams, p11Key.keyID);


 469             result -= (result & (blockSize - 1));
 470         }
 471         return result;
 472     }
 473 
 474     // if doFinal(inLen) is called, how big does the output buffer have to be?
 475     private int doFinalLength(int inLen) {
 476         if (inLen < 0) {
 477             return 0;
 478         }
 479 
 480         int result = inLen + bytesBuffered;
 481         if (blockSize != 0 && encrypt && paddingType != PAD_NONE) {
 482             // add the number of bytes to make the last block complete.
 483             result += (blockSize - (result & (blockSize - 1)));
 484         }
 485         return result;
 486     }
 487 
 488     // reset the states to the pre-initialized values
 489     private void reset(boolean doCancel) {
 490         if (doCancel) cancelOperation();
 491 
 492         initialized = false;
 493         bytesBuffered = 0;
 494         padBufferLen = 0;
 495         if (session != null) {
 496             session = token.releaseSession(session);
 497         }
 498     }
 499 
 500     // see JCE spec
 501     protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
 502         try {
 503             byte[] out = new byte[updateLength(inLen)];
 504             int n = engineUpdate(in, inOfs, inLen, out, 0);
 505             return P11Util.convert(out, 0, n);
 506         } catch (ShortBufferException e) {
 507             // convert since the output length is calculated by updateLength()
 508             throw new ProviderException(e);
 509         }
 510     }
 511 


 598                         newPadBufferLen = padBuffer.length;
 599                     }
 600                     inLen -= newPadBufferLen;
 601                 }
 602                 if (inLen > 0) {
 603                     k += token.p11.C_DecryptUpdate(session.id(), 0, in, inOfs,
 604                             inLen, 0, out, (outOfs + k), (outLen - k));
 605                 }
 606                 // update 'padBuffer' if using our own padding impl.
 607                 if (paddingObj != null) {
 608                     bufferInputBytes(in, inOfs + inLen, newPadBufferLen);
 609                 }
 610             }
 611             bytesBuffered += (inLen - k);
 612             return k;
 613         } catch (PKCS11Exception e) {
 614             if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
 615                 throw (ShortBufferException)
 616                         (new ShortBufferException().initCause(e));
 617             }
 618             reset(false);
 619             throw new ProviderException("update() failed", e);
 620         }
 621     }
 622 
 623     private int implUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
 624             throws ShortBufferException {
 625         int inLen = inBuffer.remaining();
 626         if (inLen <= 0) {
 627             return 0;
 628         }
 629 
 630         int outLen = outBuffer.remaining();
 631         if (outLen < updateLength(inLen)) {
 632             throw new ShortBufferException();
 633         }
 634         int origPos = inBuffer.position();
 635         try {
 636             ensureInitialized();
 637 
 638             long inAddr = 0;


 716                 // update 'padBuffer' if using our own padding impl.
 717                 if (paddingObj != null && newPadBufferLen != 0) {
 718                     bufferInputBytes(inBuffer, newPadBufferLen);
 719                 }
 720             }
 721             bytesBuffered += (inLen - k);
 722             if (!(outBuffer instanceof DirectBuffer) &&
 723                     !outBuffer.hasArray()) {
 724                 outBuffer.put(outArray, outOfs, k);
 725             } else {
 726                 outBuffer.position(outBuffer.position() + k);
 727             }
 728             return k;
 729         } catch (PKCS11Exception e) {
 730             // Reset input buffer to its original position for
 731             inBuffer.position(origPos);
 732             if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) {
 733                 throw (ShortBufferException)
 734                         (new ShortBufferException().initCause(e));
 735             }
 736             reset(false);
 737             throw new ProviderException("update() failed", e);
 738         }
 739     }
 740 
 741     private int implDoFinal(byte[] out, int outOfs, int outLen)
 742             throws ShortBufferException, IllegalBlockSizeException,
 743             BadPaddingException {
 744         int requiredOutLen = doFinalLength(0);
 745         if (outLen < requiredOutLen) {
 746             throw new ShortBufferException();
 747         }
 748         boolean doCancel = true;
 749         try {
 750             ensureInitialized();
 751             int k = 0;
 752             if (encrypt) {
 753                 if (paddingObj != null) {
 754                     int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
 755                             requiredOutLen - bytesBuffered);
 756                     k = token.p11.C_EncryptUpdate(session.id(),
 757                             0, padBuffer, 0, actualPadLen,
 758                             0, out, outOfs, outLen);
 759                 }
 760                 k += token.p11.C_EncryptFinal(session.id(),
 761                         0, out, (outOfs + k), (outLen - k));
 762                 doCancel = false;
 763             } else {
 764                 // Special handling to match SunJCE provider behavior
 765                 if (bytesBuffered == 0 && padBufferLen == 0) {
 766                     return 0;
 767                 }
 768                 if (paddingObj != null) {
 769                     if (padBufferLen != 0) {
 770                         k = token.p11.C_DecryptUpdate(session.id(), 0,
 771                                 padBuffer, 0, padBufferLen, 0, padBuffer, 0,
 772                                 padBuffer.length);
 773                     }
 774                     k += token.p11.C_DecryptFinal(session.id(), 0, padBuffer, k,
 775                             padBuffer.length - k);
 776                     doCancel = false;
 777 
 778                     int actualPadLen = paddingObj.unpad(padBuffer, k);
 779                     k -= actualPadLen;
 780                     System.arraycopy(padBuffer, 0, out, outOfs, k);
 781                 } else {
 782                     k = token.p11.C_DecryptFinal(session.id(), 0, out, outOfs,
 783                             outLen);
 784                     doCancel = false;
 785                 }
 786             }
 787             return k;
 788         } catch (PKCS11Exception e) {
 789             doCancel = false;
 790             handleException(e);
 791             throw new ProviderException("doFinal() failed", e);
 792         } finally {
 793             reset(doCancel);
 794         }
 795     }
 796 
 797     private int implDoFinal(ByteBuffer outBuffer)
 798             throws ShortBufferException, IllegalBlockSizeException,
 799             BadPaddingException {
 800         int outLen = outBuffer.remaining();
 801         int requiredOutLen = doFinalLength(0);
 802         if (outLen < requiredOutLen) {
 803             throw new ShortBufferException();
 804         }
 805 
 806         boolean doCancel = true; 
 807         try {
 808             ensureInitialized();
 809 
 810             long outAddr = 0;
 811             byte[] outArray = null;
 812             int outOfs = 0;
 813             if (outBuffer instanceof DirectBuffer) {
 814                 outAddr = ((DirectBuffer) outBuffer).address();
 815                 outOfs = outBuffer.position();
 816             } else {
 817                 if (outBuffer.hasArray()) {
 818                     outArray = outBuffer.array();
 819                     outOfs = outBuffer.position() + outBuffer.arrayOffset();
 820                 } else {
 821                     outArray = new byte[outLen];
 822                 }
 823             }
 824 
 825             int k = 0;
 826 
 827             if (encrypt) {
 828                 if (paddingObj != null) {
 829                     int actualPadLen = paddingObj.setPaddingBytes(padBuffer,
 830                             requiredOutLen - bytesBuffered);
 831                     k = token.p11.C_EncryptUpdate(session.id(),
 832                             0, padBuffer, 0, actualPadLen,
 833                             outAddr, outArray, outOfs, outLen);
 834                 }
 835                 k += token.p11.C_EncryptFinal(session.id(),
 836                         outAddr, outArray, (outOfs + k), (outLen - k));
 837                 doCancel = false;
 838             } else {
 839                 // Special handling to match SunJCE provider behavior
 840                 if (bytesBuffered == 0 && padBufferLen == 0) {
 841                     return 0;
 842                 }
 843 
 844                 if (paddingObj != null) {
 845                     if (padBufferLen != 0) {
 846                         k = token.p11.C_DecryptUpdate(session.id(),
 847                                 0, padBuffer, 0, padBufferLen,
 848                                 0, padBuffer, 0, padBuffer.length);
 849                         padBufferLen = 0;
 850                     }
 851                     k += token.p11.C_DecryptFinal(session.id(),
 852                             0, padBuffer, k, padBuffer.length - k);
 853                     doCancel = false;
 854 
 855                     int actualPadLen = paddingObj.unpad(padBuffer, k);
 856                     k -= actualPadLen;
 857                     outArray = padBuffer;
 858                     outOfs = 0;
 859                 } else {
 860                     k = token.p11.C_DecryptFinal(session.id(),
 861                             outAddr, outArray, outOfs, outLen);
 862                     doCancel = false;
 863                 }
 864             }
 865             if ((!encrypt && paddingObj != null) ||
 866                     (!(outBuffer instanceof DirectBuffer) &&
 867                     !outBuffer.hasArray())) {
 868                 outBuffer.put(outArray, outOfs, k);
 869             } else {
 870                 outBuffer.position(outBuffer.position() + k);
 871             }
 872             return k;
 873         } catch (PKCS11Exception e) {
 874             doCancel = false;
 875             handleException(e);
 876             throw new ProviderException("doFinal() failed", e);
 877         } finally {
 878             reset(doCancel);
 879         }
 880     }
 881 
 882     private void handleException(PKCS11Exception e)
 883             throws ShortBufferException, IllegalBlockSizeException {
 884         long errorCode = e.getErrorCode();
 885         if (errorCode == CKR_BUFFER_TOO_SMALL) {
 886             throw (ShortBufferException)
 887                     (new ShortBufferException().initCause(e));
 888         } else if (errorCode == CKR_DATA_LEN_RANGE ||
 889                    errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) {
 890             throw (IllegalBlockSizeException)
 891                     (new IllegalBlockSizeException(e.toString()).initCause(e));
 892         }
 893     }
 894 
 895     // see JCE spec
 896     protected byte[] engineWrap(Key key) throws IllegalBlockSizeException,
 897             InvalidKeyException {
 898         // XXX key wrapping


< prev index next >