/src/libreoffice/include/svl/cryptosign.hxx
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | */ |
9 | | |
10 | | #pragma once |
11 | | |
12 | | #include <sal/types.h> |
13 | | |
14 | | #include <utility> |
15 | | #include <vector> |
16 | | |
17 | | #include <rtl/strbuf.hxx> |
18 | | #include <rtl/ustring.hxx> |
19 | | |
20 | | #include <com/sun/star/uno/Reference.hxx> |
21 | | |
22 | | #include <svl/svldllapi.h> |
23 | | |
24 | | // Is this length truly the maximum possible, or just a number that |
25 | | // seemed large enough when the author tested this (with some type of |
26 | | // certificates)? I suspect the latter. |
27 | | |
28 | | // Used to be 0x4000 = 16384, but a sample signed PDF (produced by |
29 | | // some other software) provided by the customer has a signature |
30 | | // content that is 30000 bytes. The SampleSignedPDFDocument.pdf from |
31 | | // Adobe has one that is 21942 bytes. So let's be careful. Pity this |
32 | | // can't be dynamic, at least not without restructuring the code. Also |
33 | | // note that the checks in the code for this being too small |
34 | | // apparently are broken, if this overflows you end up with an invalid |
35 | | // PDF. Need to fix that. |
36 | | |
37 | 0 | #define MAX_SIGNATURE_CONTENT_LENGTH 50000 |
38 | | |
39 | | namespace com::sun::star::security { class XCertificate; } |
40 | | class SvStream; |
41 | | struct SignatureInformation; |
42 | | |
43 | | namespace svl::crypto { |
44 | | class SigningContext; |
45 | | |
46 | | /// Converts a hex-encoded string into a byte array. |
47 | | SVL_DLLPUBLIC std::vector<unsigned char> DecodeHexString(std::string_view rHex); |
48 | | |
49 | | /// Helper to cryptographically sign and verify |
50 | | /// arbitrary data blocks. |
51 | | class SVL_DLLPUBLIC Signing |
52 | | { |
53 | | public: |
54 | | |
55 | | Signing(svl::crypto::SigningContext& rSigningContext) : |
56 | 0 | m_rSigningContext(rSigningContext) |
57 | 0 | { |
58 | 0 | } |
59 | | |
60 | | /// Add a range to sign. |
61 | | /// Note: for efficiency this takes a naked pointer, which must remain valid |
62 | | /// until this object is discarded. |
63 | | void AddDataRange(const void* pData, sal_Int32 size) |
64 | 0 | { |
65 | 0 | m_dataBlocks.emplace_back(pData, size); |
66 | 0 | } |
67 | | |
68 | 0 | void SetSignTSA(const OUString& tsa) { m_aSignTSA = tsa; } |
69 | 0 | void SetSignPassword(const OUString& password) { m_aSignPassword = password; } |
70 | | |
71 | | /// Signs one or more data blocks (as a single, contiguous, array). |
72 | | /// Returns the signature (in PKCS#7 format) as string (hex). |
73 | | bool Sign(OStringBuffer& rCMSHexBuffer); |
74 | | |
75 | | /// Verify and get Signature Information given a byte array. |
76 | | static bool Verify(const std::vector<unsigned char>& aData, |
77 | | const bool bNonDetached, |
78 | | const std::vector<unsigned char>& aSignature, |
79 | | SignatureInformation& rInformation); |
80 | | |
81 | | /// Verify and get Signature Information given a signature and stream. |
82 | | static bool Verify(SvStream& rStream, |
83 | | const std::vector<std::pair<size_t, size_t>>& aByteRanges, |
84 | | const bool bNonDetached, |
85 | | const std::vector<unsigned char>& aSignature, |
86 | | SignatureInformation& rInformation); |
87 | | static void appendHex(sal_Int8 nInt, OStringBuffer& rBuffer); |
88 | | |
89 | | private: |
90 | | /// The certificate to use for signing. |
91 | | [[maybe_unused]] svl::crypto::SigningContext& m_rSigningContext; |
92 | | |
93 | | /// Data blocks (pointer-size pairs). |
94 | | std::vector<std::pair<const void*, sal_Int32>> m_dataBlocks; |
95 | | OUString m_aSignTSA; |
96 | | OUString m_aSignPassword; |
97 | | }; |
98 | | |
99 | | /// Wrapper around a certificate: allows either an actual signing or extracting enough info, so a |
100 | | /// 3rd-party can sign our document. |
101 | | /// |
102 | | /// The following states are supported: |
103 | | /// - actual signing: set m_xCertificate |
104 | | /// - hash extract before external signing: don't set anything, m_nSignatureTime and m_aDigest will |
105 | | /// be set |
106 | | /// - signature serialization after external signing: set m_nSignatureTime and m_aSignatureValue |
107 | | class SVL_DLLPUBLIC SigningContext |
108 | | { |
109 | | public: |
110 | | /// If set, the certificate used for signing. |
111 | | css::uno::Reference<css::security::XCertificate> m_xCertificate; |
112 | | /// If m_xCertificate is not set, the time that would be used, in milliseconds since the epoch |
113 | | /// (1970-01-01 UTC). |
114 | | sal_Int64 m_nSignatureTime = 0; |
115 | | /// SHA-256 digest of the to-be signed document. |
116 | | std::vector<unsigned char> m_aDigest; |
117 | | /// PKCS#7 data, produced externally. |
118 | | std::vector<unsigned char> m_aSignatureValue; |
119 | | }; |
120 | | |
121 | | /// Used for visual signing: an XCertificate or a signer name. |
122 | | class SVL_DLLPUBLIC CertificateOrName |
123 | | { |
124 | | public: |
125 | | /// If set, the certificate used for signing. |
126 | | css::uno::Reference<css::security::XCertificate> m_xCertificate; |
127 | | /// Otherwise we don't have a certificate but have a name to be featured on the visual |
128 | | /// signature. |
129 | | OUString m_aName; |
130 | | |
131 | | /// Returns if a certificate or a name is set. |
132 | | bool Is() const; |
133 | | }; |
134 | | |
135 | | } |
136 | | |
137 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
138 | | |