protected int engineDoFinal(
      byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset)
      throws IllegalBlockSizeException, BadPaddingException {
    if (input != null) {
      bOut.write(input, inputOffset, inputLen);
    }

    if (cipher instanceof RSABlindedEngine) {
      if (bOut.size() > cipher.getInputBlockSize() + 1) {
        throw new ArrayIndexOutOfBoundsException("too much data for RSA block");
      }
    } else {
      if (bOut.size() > cipher.getInputBlockSize()) {
        throw new ArrayIndexOutOfBoundsException("too much data for RSA block");
      }
    }

    byte[] out;

    try {
      byte[] bytes = bOut.toByteArray();
      bOut.reset();

      out = cipher.processBlock(bytes, 0, bytes.length);
    } catch (InvalidCipherTextException e) {
      throw new BadPaddingException(e.getMessage());
    }

    for (int i = 0; i != out.length; i++) {
      output[outputOffset + i] = out[i];
    }

    return out.length;
  }
  protected byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) {
    bOut.write(input, inputOffset, inputLen);

    if (cipher instanceof RSABlindedEngine) {
      if (bOut.size() > cipher.getInputBlockSize() + 1) {
        throw new ArrayIndexOutOfBoundsException("too much data for RSA block");
      }
    } else {
      if (bOut.size() > cipher.getInputBlockSize()) {
        throw new ArrayIndexOutOfBoundsException("too much data for RSA block");
      }
    }

    return null;
  }
 protected int engineGetBlockSize() {
   try {
     return cipher.getInputBlockSize();
   } catch (NullPointerException e) {
     throw new IllegalStateException("RSA Cipher not initialised");
   }
 }