private int implUpdate(byte[] in, int inOfs, int inLen, byte[] out, int outOfs, int outLen) throws ShortBufferException { if (outLen < updateLength(inLen)) { throw new ShortBufferException(); } try { ensureInitialized(); int k = 0; if (encrypt) { k = token.p11.C_EncryptUpdate(session.id(), 0, in, inOfs, inLen, 0, out, outOfs, outLen); } else { int newPadBufferLen = 0; if (paddingObj != null) { if (padBufferLen != 0) { // NSS throws up when called with data not in multiple // of blocks. Try to work around this by holding the // extra data in padBuffer. if (padBufferLen != padBuffer.length) { int bufCapacity = padBuffer.length - padBufferLen; if (inLen > bufCapacity) { bufferInputBytes(in, inOfs, bufCapacity); inOfs += bufCapacity; inLen -= bufCapacity; } else { bufferInputBytes(in, inOfs, inLen); return 0; } } k = token.p11.C_DecryptUpdate( session.id(), 0, padBuffer, 0, padBufferLen, 0, out, outOfs, outLen); padBufferLen = 0; } newPadBufferLen = inLen & (blockSize - 1); if (newPadBufferLen == 0) { newPadBufferLen = padBuffer.length; } inLen -= newPadBufferLen; } if (inLen > 0) { k += token.p11.C_DecryptUpdate( session.id(), 0, in, inOfs, inLen, 0, out, (outOfs + k), (outLen - k)); } // update 'padBuffer' if using our own padding impl. if (paddingObj != null) { bufferInputBytes(in, inOfs + inLen, newPadBufferLen); } } bytesBuffered += (inLen - k); return k; } catch (PKCS11Exception e) { if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) { throw (ShortBufferException) (new ShortBufferException().initCause(e)); } reset(); throw new ProviderException("update() failed", e); } }
private void handleException(PKCS11Exception e) throws ShortBufferException, IllegalBlockSizeException { long errorCode = e.getErrorCode(); if (errorCode == CKR_BUFFER_TOO_SMALL) { throw (ShortBufferException) (new ShortBufferException().initCause(e)); } else if (errorCode == CKR_DATA_LEN_RANGE || errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) { throw (IllegalBlockSizeException) (new IllegalBlockSizeException(e.toString()).initCause(e)); } }
/** * Enumerate all available slots of a given PKCS11 provider. * * @param provider The PKCS11 provider to retrieve the slots for. * @return A list of all available slots. * @throws PKCS11Exception Upon errors when retrieving the slot information. */ public static PKCS11Slot waitForSlot(PKCS11Provider provider) throws PKCS11Exception { long id = -1; try { id = waitForSlotNative(provider.getPkcs11ModuleHandle()); } catch (PKCS11Exception e) { if (e.getErrorCode() == PKCS11Exception.CKR_FUNCTION_NOT_SUPPORTED) try { PKCS11Slot ret = null; do { Thread.sleep(1000); List<PKCS11Slot> slots = enumerateSlots(provider); for (PKCS11Slot slot : slots) { if (ret == null && slot.isTokenPresent()) ret = slot; else try { slot.destroy(); } catch (DestroyFailedException e1) { log.warn("destroy error while waiting for slot:", e1); } } } while (ret == null); return ret; } catch (InterruptedException e1) { throw new PKCS11Exception( PKCS11Exception.CKR_FUNCTION_CANCELED, "The operation has been interrupted."); } else { throw e; } } return new PKCS11Slot(provider, id); }
private int implUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer) throws ShortBufferException { int inLen = inBuffer.remaining(); if (inLen <= 0) { return 0; } int outLen = outBuffer.remaining(); if (outLen < updateLength(inLen)) { throw new ShortBufferException(); } int origPos = inBuffer.position(); try { ensureInitialized(); long inAddr = 0; int inOfs = 0; byte[] inArray = null; if (inBuffer instanceof DirectBuffer) { inAddr = ((DirectBuffer) inBuffer).address(); inOfs = origPos; } else if (inBuffer.hasArray()) { inArray = inBuffer.array(); inOfs = (origPos + inBuffer.arrayOffset()); } long outAddr = 0; int outOfs = 0; byte[] outArray = null; if (outBuffer instanceof DirectBuffer) { outAddr = ((DirectBuffer) outBuffer).address(); outOfs = outBuffer.position(); } else { if (outBuffer.hasArray()) { outArray = outBuffer.array(); outOfs = (outBuffer.position() + outBuffer.arrayOffset()); } else { outArray = new byte[outLen]; } } int k = 0; if (encrypt) { if (inAddr == 0 && inArray == null) { inArray = new byte[inLen]; inBuffer.get(inArray); } else { inBuffer.position(origPos + inLen); } k = token.p11.C_EncryptUpdate( session.id(), inAddr, inArray, inOfs, inLen, outAddr, outArray, outOfs, outLen); } else { int newPadBufferLen = 0; if (paddingObj != null) { if (padBufferLen != 0) { // NSS throws up when called with data not in multiple // of blocks. Try to work around this by holding the // extra data in padBuffer. if (padBufferLen != padBuffer.length) { int bufCapacity = padBuffer.length - padBufferLen; if (inLen > bufCapacity) { bufferInputBytes(inBuffer, bufCapacity); inOfs += bufCapacity; inLen -= bufCapacity; } else { bufferInputBytes(inBuffer, inLen); return 0; } } k = token.p11.C_DecryptUpdate( session.id(), 0, padBuffer, 0, padBufferLen, outAddr, outArray, outOfs, outLen); padBufferLen = 0; } newPadBufferLen = inLen & (blockSize - 1); if (newPadBufferLen == 0) { newPadBufferLen = padBuffer.length; } inLen -= newPadBufferLen; } if (inLen > 0) { if (inAddr == 0 && inArray == null) { inArray = new byte[inLen]; inBuffer.get(inArray); } else { inBuffer.position(inBuffer.position() + inLen); } k += token.p11.C_DecryptUpdate( session.id(), inAddr, inArray, inOfs, inLen, outAddr, outArray, (outOfs + k), (outLen - k)); } // update 'padBuffer' if using our own padding impl. if (paddingObj != null && newPadBufferLen != 0) { bufferInputBytes(inBuffer, newPadBufferLen); } } bytesBuffered += (inLen - k); if (!(outBuffer instanceof DirectBuffer) && !outBuffer.hasArray()) { outBuffer.put(outArray, outOfs, k); } else { outBuffer.position(outBuffer.position() + k); } return k; } catch (PKCS11Exception e) { // Reset input buffer to its original position for inBuffer.position(origPos); if (e.getErrorCode() == CKR_BUFFER_TOO_SMALL) { throw (ShortBufferException) (new ShortBufferException().initCause(e)); } reset(); throw new ProviderException("update() failed", e); } }