diff options
Diffstat (limited to 'src/java/org/apache/fop/pdf/PDFEncryptionJCE.java')
-rw-r--r-- | src/java/org/apache/fop/pdf/PDFEncryptionJCE.java | 99 |
1 files changed, 89 insertions, 10 deletions
diff --git a/src/java/org/apache/fop/pdf/PDFEncryptionJCE.java b/src/java/org/apache/fop/pdf/PDFEncryptionJCE.java index 2fe9f29e0..8fd8d3444 100644 --- a/src/java/org/apache/fop/pdf/PDFEncryptionJCE.java +++ b/src/java/org/apache/fop/pdf/PDFEncryptionJCE.java @@ -449,14 +449,13 @@ public final class PDFEncryptionJCE extends PDFObject implements PDFEncryption { private class Rev5Engine extends InitializationEngine { - // private SecureRandom random = new SecureRandom(); - private byte[] userValidationSalt = new byte[8]; - private byte[] userKeySalt = new byte[8]; - private byte[] ownerValidationSalt = new byte[8]; - private byte[] ownerKeySalt = new byte[8]; - private byte[] ueValue; - private byte[] oeValue; - private final boolean encryptMetadata; + protected byte[] userValidationSalt = new byte[8]; + protected byte[] userKeySalt = new byte[8]; + protected byte[] ownerValidationSalt = new byte[8]; + protected byte[] ownerKeySalt = new byte[8]; + protected byte[] ueValue; + protected byte[] oeValue; + protected final boolean encryptMetadata; Rev5Engine(EncryptionSettings encryptionSettings) { super(encryptionSettings); @@ -563,7 +562,7 @@ public final class PDFEncryptionJCE extends PDFObject implements PDFEncryption { /** * Algorithm 3.8-2 (page 20, Adobe Supplement to the ISO 32000, BaseVersion: 1.7, ExtensionLevel: 3) */ - private void computeUEValue() { + protected void computeUEValue() { digest.reset(); byte[] prepared = preparedUserPassword; byte[] concatenated = new byte[prepared.length + 8]; @@ -577,7 +576,7 @@ public final class PDFEncryptionJCE extends PDFObject implements PDFEncryption { /** * Algorithm 3.9-2 (page 20, Adobe Supplement to the ISO 32000, BaseVersion: 1.7, ExtensionLevel: 3) */ - private void computeOEValue() { + protected void computeOEValue() { digest.reset(); byte[] prepared = preparedOwnerPassword; byte[] concatenated = new byte[prepared.length + 56]; @@ -615,6 +614,86 @@ public final class PDFEncryptionJCE extends PDFObject implements PDFEncryption { } } + private class Rev6Engine extends Rev5Engine { + + private MessageDigest digest384; + private MessageDigest digest512; + + Rev6Engine(EncryptionSettings encryptionSettings) { + super(encryptionSettings); + try { + digest384 = MessageDigest.getInstance("SHA-384"); + digest512 = MessageDigest.getInstance("SHA-512"); + } catch (NoSuchAlgorithmException e) { + throw new UnsupportedOperationException(e.getMessage()); + } + } + + @Override + protected void computeUValue() { + byte[] userBytes = new byte[16]; + random.nextBytes(userBytes); + System.arraycopy(userBytes, 0, userValidationSalt, 0, 8); + System.arraycopy(userBytes, 8, userKeySalt, 0, 8); + digest.reset(); + byte[] prepared = preparedUserPassword; + byte[] concatenated = new byte[prepared.length + 8]; + System.arraycopy(prepared, 0, concatenated, 0, prepared.length); + System.arraycopy(userValidationSalt, 0, concatenated, prepared.length, 8); + digest.update(concatenated); + byte[] block = digest.digest(); + int blockSize = 32; + byte[] key = new byte[16]; + byte[] iv = new byte[16]; + int length = prepared.length + blockSize; + byte[] data = new byte[length * 64]; + for (int i = 0; i < 64 || i < data[length * 64 - 1] + 32; i++) { + System.arraycopy(block, 0, key, 0, 16); + System.arraycopy(block, 16, iv, 0, 16); + for (int j = 0; j < 64; j++) { + System.arraycopy(prepared, 0, data, j * length, prepared.length); + System.arraycopy(block, 0, data, j * length + prepared.length, blockSize); + } + try { + final Cipher cipher = PDFEncryptionJCE.initCipher(key, false, iv); + data = cipher.doFinal(data); + } catch (IllegalBlockSizeException e) { + throw new IllegalStateException(e.getMessage()); + } catch (BadPaddingException e) { + throw new IllegalStateException(e.getMessage()); + } + int sum = 0; + for (int k = 0; k < 16; k++) { + sum += data[k]; + } + blockSize = 32 + (sum % 3) * 16; + switch (blockSize) { + case 32: + digest.reset(); + digest.update(data); + block = digest.digest(); + break; + case 48: + digest384.reset(); + digest384.update(data); + block = digest384.digest(); + break; + case 64: + digest512.reset(); + digest512.update(data); + block = digest512.digest(); + break; + default: + // not possible + break; + } + length = prepared.length + blockSize; + data = new byte[length * 64]; + } + } + + } + private class EncryptionFilter extends PDFFilter { private int streamNumber; |