1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 #include <rtl/ustring.hxx>
13 #include <string_view>
15 #include <vcl/dllapi.h>
16 #include <pdf/IPDFEncryptor.hxx>
20 class EncryptionHashTransporter
;
22 /** Algorithm 2.B: Computing a hash (revision 6 and later)
24 * Described in ISO 32000-2:2020(E) - 7.6.4.3.4
26 VCL_DLLPUBLIC
std::vector
<sal_uInt8
>
27 computeHashR6(const sal_uInt8
* pPassword
, size_t nPasswordLength
,
28 std::vector
<sal_uInt8
> const& rValidationSalt
,
29 std::vector
<sal_uInt8
> const& rUserKey
= std::vector
<sal_uInt8
>());
31 /** Algorithm 11: Authenticating the user password (Security handlers of revision 6)
33 * Described in ISO 32000-2:2020(E) - 7.6.4.4.10
35 VCL_DLLPUBLIC
bool validateUserPassword(const sal_uInt8
* pUserPass
, size_t nPasswordLength
,
36 std::vector
<sal_uInt8
>& U
);
38 /** Algorithm 12: Authenticating the owner password (Security handlers of revision 6)
40 * Described in ISO 32000-2:2020(E) - 7.6.4.4.11
42 VCL_DLLPUBLIC
bool validateOwnerPassword(const sal_uInt8
* pUserPass
, size_t nPasswordLength
,
43 std::vector
<sal_uInt8
>& U
, std::vector
<sal_uInt8
>& O
);
45 /** Generates the encryption key - random data 32-byte */
46 VCL_DLLPUBLIC
std::vector
<sal_uInt8
> generateKey();
48 /** Algorithm 8: U and UE
50 * Computing the encryption dictionary’s U (user password) and UE (user encryption) values
51 * (Security handlers of revision 6)
53 * Described in ISO 32000-2:2020(E) - 7.6.4.4.7
55 VCL_DLLPUBLIC
void generateUandUE(const sal_uInt8
* pUserPass
, size_t nPasswordLength
,
56 std::vector
<sal_uInt8
>& rFileEncryptionKey
,
57 std::vector
<sal_uInt8
>& U
, std::vector
<sal_uInt8
>& UE
);
59 /** Algorithm 9: O and OE
61 * Computing the encryption dictionary’s O (owner password) and OE (owner encryption) values
62 * (Security handlers of revision 6)
64 * Described in ISO 32000-2:2020(E) - 7.6.4.4.8
66 VCL_DLLPUBLIC
void generateOandOE(const sal_uInt8
* pUserPass
, size_t nPasswordLength
,
67 std::vector
<sal_uInt8
>& rFileEncryptionKey
,
68 std::vector
<sal_uInt8
>& U
, std::vector
<sal_uInt8
>& O
,
69 std::vector
<sal_uInt8
>& OE
);
71 /** Algorithm 8 step b) in reverse
73 * Described in ISO 32000-2:2020(E) - 7.6.4.4.7
75 * - compute the hash with password and user key salt
76 * - decrypt with hash as key and zero IV
78 VCL_DLLPUBLIC
std::vector
<sal_uInt8
> decryptKey(const sal_uInt8
* pUserPass
, size_t nPasswordLength
,
79 std::vector
<sal_uInt8
>& U
,
80 std::vector
<sal_uInt8
>& UE
);
82 /** Algorithm 13: Validating the permissions (Security handlers of revision 6)
84 * Described in ISO 32000-2:2020(E) - 7.6.4.4.12
86 VCL_DLLPUBLIC
std::vector
<sal_uInt8
> decryptPerms(std::vector
<sal_uInt8
>& rPermsEncrypted
,
87 std::vector
<sal_uInt8
>& rFileEncryptionKey
);
89 /** Algorithm 10 step f)
91 * Computing the encryption dictionary’s Perms (permissions) value (Security handlers of revision 6)
93 * Described in ISO 32000-2:2020(E) - 7.6.4.4.9
95 VCL_DLLPUBLIC
std::vector
<sal_uInt8
> encryptPerms(std::vector
<sal_uInt8
>& rPerms
,
96 std::vector
<sal_uInt8
>& rFileEncryptionKey
);
98 /** Algorithm 10 steps a) - e)
100 * Computing the encryption dictionary’s Perms (permissions) value (Security handlers of revision 6)
102 * Described in ISO 32000-2:2020(E) - 7.6.4.4.9
104 VCL_DLLPUBLIC
std::vector
<sal_uInt8
> createPerms(sal_Int32 nAccessPermissions
,
105 bool bEncryptMetadata
);
107 /** Padding as described in Internet RFC 8018
109 * Described in ISO 32000-2:2020(E) - 7.6.3.1
111 VCL_DLLPUBLIC
size_t addPaddingToVector(std::vector
<sal_uInt8
>& rVector
, size_t nBlockSize
);
113 class EncryptionContext
;
115 /** IPDFEncryptor implementation of PDF encryption version 5 revision 6 added in PDF 2.0
117 * The complete algorithm is defined in PDF 2.0 specification ISO 32000-2:2020(E)
119 class VCL_DLLPUBLIC PDFEncryptorR6
: public IPDFEncryptor
121 std::unique_ptr
<EncryptionContext
> m_pEncryptionContext
;
122 sal_Int32 m_nAccessPermissions
= 0;
128 sal_Int32
getVersion() override
{ return 5; }
129 sal_Int32
getRevision() override
{ return 6; }
130 sal_Int32
getAccessPermissions() override
{ return m_nAccessPermissions
; }
131 bool isMetadataEncrypted() override
{ return true; }
132 /** Key length - AES 256 bit */
133 sal_Int32
getKeyLength() override
{ return 256 / 8; }
135 std::vector
<sal_uInt8
> getEncryptedAccessPermissions(std::vector
<sal_uInt8
>& rKey
) override
;
137 static void initEncryption(EncryptionHashTransporter
& rEncryptionHashTransporter
,
138 const OUString
& i_rOwnerPassword
, const OUString
& i_rUserPassword
);
140 bool prepareEncryption(
141 const css::uno::Reference
<css::beans::XMaterialHolder
>& xEncryptionMaterialHolder
,
142 PDFEncryptionProperties
& rProperties
) override
;
144 void setupKeysAndCheck(PDFEncryptionProperties
& rProperties
) override
;
146 sal_uInt64
calculateSizeIncludingHeader(sal_uInt64 nSize
) override
;
148 void setupEncryption(std::vector
<sal_uInt8
>& rEncryptionKey
, sal_Int32 nObject
) override
;
150 /** Encrypts using Algorithm 1.A: Encryption of data using the AES algorithms
152 * Described in ISO 32000-2:2020(E) - 7.6.3.3
154 void encrypt(const void* pInput
, sal_uInt64 nInputSize
, std::vector
<sal_uInt8
>& rOutput
,
155 sal_uInt64 nOutputsSize
) override
;
157 void encryptWithIV(const void* pInput
, sal_uInt64 nInputSize
, std::vector
<sal_uInt8
>& rOutput
,
158 std::vector
<sal_uInt8
>& rIV
);
163 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */