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  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #ifndef INCLUDED_XMLSECURITY_INC_XMLSIGNATUREHELPER_HXX
21 #define INCLUDED_XMLSECURITY_INC_XMLSIGNATUREHELPER_HXX
22 
23 #include <tools/link.hxx>
24 #include <rtl/ustring.hxx>
25 #include <rtl/ref.hxx>
26 #include <svl/sigstruct.hxx>
27 #include "xmlsecuritydllapi.h"
28 #include "xmlsignaturehelper.hxx"
29 #include "xsecctl.hxx"
30 
31 class DateTime;
32 class UriBindingHelper;
33 
34 namespace com {
35 namespace sun {
36 namespace star {
37 namespace io {
38     class XOutputStream;
39     class XInputStream; }
40 namespace embed {
41     class XStorage; }
42 }}}
43 
44 namespace com { namespace sun { namespace star { namespace graphic { class XGraphic; } } } }
45 namespace com { namespace sun { namespace star { namespace uno { class XComponentContext; } } } }
46 namespace com { namespace sun { namespace star { namespace xml { namespace crypto { class XXMLSecurityContext; } } } } }
47 namespace com { namespace sun { namespace star { namespace xml { namespace sax { class XDocumentHandler; } } } } }
48 namespace com { namespace sun { namespace star { namespace xml { namespace sax { class XWriter; } } } } }
49 
50 /**********************************************************
51  XMLSignatureHelper
52 
53  Helper class for the XML Security framework
54 
55  Functions:
56  1. help to create a security context;
57  2. help to listen signature creation result;
58  3. help to listen signature verify result;
59  4. help to indicate which signature to verify.
60 
61  **********************************************************/
62 
63 class XMLSECURITY_DLLPUBLIC XMLSignatureHelper
64 {
65 private:
66     css::uno::Reference< css::uno::XComponentContext > mxCtx;
67     rtl::Reference<UriBindingHelper> mxUriBinding;
68 
69     rtl::Reference<XSecController> mpXSecController;
70     bool                        mbError;
71     bool mbODFPre1_2;
72     Link<LinkParamNone*,bool>   maStartVerifySignatureHdl;
73 
74 private:
75     XMLSignatureHelper(const XMLSignatureHelper&) = delete;
76 
77 public:
78     XMLSignatureHelper(const css::uno::Reference< css::uno::XComponentContext >& mrCtx );
79     ~XMLSignatureHelper();
80 
81     void StartVerifySignatureElement();
82 
83     // Set the storage which should be used by the default UriBinding
84     // Must be set before StartMission().
85     //sODFVersion indicates  the ODF version
86     void        SetStorage( const css::uno::Reference < css::embed::XStorage >& rxStorage, const OUString& sODFVersion );
87 
88                 // Argument for the Link is a uno::Reference< xml::sax::XAttributeList >*
89                 // Return 1 to verify, 0 to skip.
90                 // Default handler will verify all.
91     void        SetStartVerifySignatureHdl( const Link<LinkParamNone*,bool>& rLink );
92 
93                 // After signing/verifying, get information about signatures
94     SignatureInformation  GetSignatureInformation( sal_Int32 nSecurityId ) const;
95     SignatureInformations GetSignatureInformations() const;
96 
97                 // See XSecController for documentation
98     void        StartMission(const css::uno::Reference<css::xml::crypto::XXMLSecurityContext>& xSecurityContext);
99     void        EndMission();
100     sal_Int32   GetNewSecurityId();
101     /** sets data that describes the certificate.
102 
103         It is absolutely necessary that the parameter ouX509IssuerName is set. It contains
104         the base64 encoded certificate, which is DER encoded. The XMLSec needs it to find
105         the private key. Although issuer name and certificate should be sufficient to identify
106         the certificate the implementation in XMLSec is broken, both for Windows and mozilla.
107         The reason is that they use functions to find the certificate which take as parameter
108         the DER encoded ASN.1 issuer name. The issuer name is a DName, where most attributes
109         are of type DirectoryName, which is a choice of 5 string types. This information is
110         not contained in the issuer string and while it is converted to the ASN.1 name the
111         conversion function must assume a particular type, which is often wrong. For example,
112         the Windows function CertStrToName will use a T.61 string if the string does not contain
113         special characters. So if the certificate uses simple characters but encodes the
114         issuer attributes in Utf8, then CertStrToName will use T.61. The resulting DER encoded
115         ASN.1 name now contains different bytes which indicate the string type. The functions
116         for finding the certificate apparently use memcmp - hence they fail to find the
117         certificate.
118      */
119     void SetX509Certificate(sal_Int32 nSecurityId, const OUString& ouX509IssuerName,
120         const OUString& ouX509SerialNumber, const OUString& ouX509Cert, const OUString& ouX509CertDigest,
121         svl::crypto::SignatureMethodAlgorithm eAlgorithmID);
122 
123     void AddEncapsulatedX509Certificate(const OUString& ouEncapsulatedX509Certificate);
124 
125     void SetGpgCertificate(sal_Int32 nSecurityId, const OUString& ouGpgCertDigest,
126         const OUString& ouGpgCert, const OUString& ouGpgOwner);
127 
128     void        SetDateTime( sal_Int32 nSecurityId, const DateTime& rDateTime );
129     void SetDescription(sal_Int32 nSecurityId, const OUString& rDescription);
130     void SetSignatureLineId(sal_Int32 nSecurityId, const OUString& rSignatureLineId);
131     void
132     SetSignatureLineValidGraphic(sal_Int32 nSecurityId,
133                                  const css::uno::Reference<css::graphic::XGraphic>& xValidGraphic);
134     void SetSignatureLineInvalidGraphic(
135         sal_Int32 nSecurityId, const css::uno::Reference<css::graphic::XGraphic>& xInvalidGraphic);
136 
137     void        AddForSigning( sal_Int32 securityId, const OUString& uri, bool bBinary, bool bXAdESCompliantIfODF );
138     void        CreateAndWriteSignature( const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler, bool bXAdESCompliantIfODF );
139     bool        ReadAndVerifySignature( const css::uno::Reference< css::io::XInputStream >& xInputStream );
140 
141     // MT: ??? I think only for adding/removing, not for new signatures...
142     // MM: Yes, but if you want to insert a new signature into an existing signature file, those function
143     //     will be very useful, see Mission 3 in the new "multisigdemo" program   :-)
144     css::uno::Reference< css::xml::sax::XWriter> CreateDocumentHandlerWithHeader( const css::uno::Reference< css::io::XOutputStream >& xOutputStream );
145     static void CloseDocumentHandler( const css::uno::Reference< css::xml::sax::XDocumentHandler>& xDocumentHandler );
146     static void ExportSignature(
147         const css::uno::Reference< css::xml::sax::XDocumentHandler >& xDocumentHandler,
148         const SignatureInformation& signatureInfo,
149         bool bXAdESCompliantIfODF );
150 
151     /// Read and verify OOXML signatures.
152     bool ReadAndVerifySignatureStorage(const css::uno::Reference<css::embed::XStorage>& xStorage, bool bCacheLastSignature = true);
153     /// Read and verify a single OOXML signature.
154     bool ReadAndVerifySignatureStorageStream(const css::uno::Reference<css::io::XInputStream>& xInputStream);
155     /// Adds or removes an OOXML digital signature relation to _rels/.rels if there wasn't any before.
156     void EnsureSignaturesRelation(const css::uno::Reference<css::embed::XStorage>& xStorage, bool bAdd);
157     /// Given that xStorage is an OOXML _xmlsignatures storage, create origin.sigs and its relations.
158     void ExportSignatureRelations(const css::uno::Reference<css::embed::XStorage>& xStorage, int nSignatureCount);
159     /// Given that xSignatureStorage is an OOXML _xmlsignatures storage, create and write a new signature.
160     void CreateAndWriteOOXMLSignature(const css::uno::Reference<css::embed::XStorage>& xRootStorage, const css::uno::Reference<css::embed::XStorage>& xSignatureStorage, int nSignatureIndex);
161     /// Similar to CreateAndWriteOOXMLSignature(), but used to write the signature to the persistent storage, not the temporary one.
162     void ExportOOXMLSignature(const css::uno::Reference<css::embed::XStorage>& xRootStorage, const css::uno::Reference<css::embed::XStorage>& xSignatureStorage, const SignatureInformation& rInformation, int nSignatureIndex);
163     /// Given that xStorage is an OOXML root storage, advertise signatures in its [Content_Types].xml stream.
164     void ExportSignatureContentTypes(const css::uno::Reference<css::embed::XStorage>& xStorage, int nSignatureCount);
165 };
166 
167 #endif // INCLUDED_XMLSECURITY_INC_XMLSIGNATUREHELPER_HXX
168 
169 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
170