private void testJceAvailability(int keyBitLength) throws EncryptionUnsupportedByPlatformException, PDFParseException {
  final byte[] junkBuffer=new byte[16];
  Arrays.fill(junkBuffer,(byte)0xAE);
  final byte[] junkKey=new byte[getSaltedContentKeyByteLength(keyBitLength / 8)];
  Arrays.fill(junkKey,(byte)0xAE);
  try {
    createAndInitialiseContentCipher(ByteBuffer.wrap(junkBuffer),junkKey);
  }
 catch (  PDFParseException e) {
    throw new PDFParseException("Internal error; " + "failed to produce test cipher: " + e.getMessage());
  }
catch (  NoSuchAlgorithmException e) {
    throw new EncryptionUnsupportedByPlatformException("JCE does not offer required cipher",e);
  }
catch (  NoSuchPaddingException e) {
    throw new EncryptionUnsupportedByPlatformException("JCE does not offer required padding",e);
  }
catch (  InvalidKeyException e) {
    throw new EncryptionUnsupportedByPlatformException("JCE does accept key size of " + (getSaltedContentKeyByteLength() * 8) + " bits- could it be a policy restriction?",e);
  }
catch (  InvalidAlgorithmParameterException e) {
    throw new EncryptionUnsupportedByPlatformException("JCE did not accept cipher parameter",e);
  }
  try {
    createMD5Digest();
  }
 catch (  NoSuchAlgorithmException e) {
    throw new EncryptionUnsupportedByPlatformException("No MD5 digest available from JCE",e);
  }
  if (encryptionAlgorithm != EncryptionAlgorithm.RC4) {
    final Cipher rc4;
    try {
      rc4=createRC4Cipher();
    }
 catch (    GeneralSecurityException e) {
      throw new EncryptionUnsupportedByPlatformException("JCE did not offer RC4 cipher",e);
    }
    final byte[] rc4JunkKey=new byte[5];
    Arrays.fill(junkKey,(byte)0xAE);
    try {
      initDecryption(rc4,createRC4Key(rc4JunkKey));
    }
 catch (    InvalidKeyException ex) {
      throw new EncryptionUnsupportedByPlatformException("JCE did not accept 40-bit RC4 key; " + "policy problem?",ex);
    }
  }
}

private void testJceAvailability ( int keyBitLength ) throws EncryptionUnsupportedByPlatformException , PDFParseException { final byte [ ] junkBuffer = new byte [ 16 ] ; Arrays . fill ( junkBuffer , ( byte ) 0xAE ) ; final byte [ ] junkKey = new byte [ getSaltedContentKeyByteLength ( keyBitLength / 8 ) ] ; Arrays . fill ( junkKey , ( byte ) 0xAE ) ; try { createAndInitialiseContentCipher ( ByteBuffer . wrap ( junkBuffer ) , junkKey ) ; } catch ( PDFParseException e ) { throw new PDFParseException ( "Internal error; " + "failed to produce test cipher: " + e . getMessage ( ) ) ; } catch ( NoSuchAlgorithmException e ) { throw new EncryptionUnsupportedByPlatformException ( "JCE does not offer required cipher" , e ) ; } catch ( NoSuchPaddingException e ) { throw new EncryptionUnsupportedByPlatformException ( "JCE does not offer required padding" , e ) ; } catch ( InvalidKeyException e ) { throw new EncryptionUnsupportedByPlatformException ( "JCE does accept key size of " + ( getSaltedContentKeyByteLength ( ) * 8 ) + " bits- could it be a policy restriction?" , e ) ; } catch ( InvalidAlgorithmParameterException e ) { throw new EncryptionUnsupportedByPlatformException ( "JCE did not accept cipher parameter" , e ) ; } try { createMD5Digest ( ) ; } catch ( NoSuchAlgorithmException e ) { throw new EncryptionUnsupportedByPlatformException ( "No MD5 digest available from JCE" , e ) ; } if ( encryptionAlgorithm != EncryptionAlgorithm . RC4 ) { final Cipher rc4 ; try { rc4 = createRC4Cipher ( ) ; } catch ( GeneralSecurityException e ) { throw new EncryptionUnsupportedByPlatformException ( "JCE did not offer RC4 cipher" , e ) ; } final byte [ ] rc4JunkKey = new byte [ 5 ] ; Arrays . fill ( junkKey , ( byte ) 0xAE ) ; try { initDecryption ( rc4 , createRC4Key ( rc4JunkKey ) ) ; } catch ( InvalidKeyException ex ) { throw new EncryptionUnsupportedByPlatformException ( "JCE did not accept 40-bit RC4 key; " + "policy problem?" , ex ) ; } } }
test that the platform ( i . e . , the jce ) can offer us all of the ciphers at the key length we need for content decryption . this shouldn ' t be a problem on the java 5 platform unless a particularly restrictive policy file is in place . calling this on construction should avoid problems like these being exposed as pdfparseexceptions as they ' re used during decryption and key establishment .
