LibreOffice Module ucb (master)  1
certvalidation_handler.cxx
Go to the documentation of this file.
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  */
12 
13 #include <com/sun/star/security/CertificateContainer.hpp>
14 #include <com/sun/star/security/XCertificate.hpp>
15 #include <com/sun/star/security/XCertificateContainer.hpp>
16 #include <com/sun/star/xml/crypto/SEInitializer.hpp>
17 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
18 
19 #include <rtl/ref.hxx>
20 #include <comphelper/sequence.hxx>
22 
24 
25 #define STD_TO_OUSTR( str ) OUString( str.c_str(), str.length( ), RTL_TEXTENCODING_UTF8 )
26 
27 using namespace std;
28 using namespace com::sun::star;
29 
30 namespace cmis
31 {
32  bool CertValidationHandler::validateCertificate( vector< string > aCertificates )
33  {
34  bool bValidate = false;
35  if ( !aCertificates.empty() && m_xEnv.is() )
36  {
37  uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
38  try
39  {
40  xSEInitializer = xml::crypto::SEInitializer::create( m_xContext );
41  }
42  catch ( uno::Exception const & )
43  {
44  }
45 
46  if ( xSEInitializer.is() )
47  {
48  uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext(
49  xSEInitializer->createSecurityContext( OUString() ) );
50 
51  uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv(
52  xSecurityContext->getSecurityEnvironment() );
53 
54  vector< string >::iterator pIt = aCertificates.begin();
55  string sCert = *pIt;
56  // We need to get rid of the PEM header/footer lines
57  OUString sCleanCert = STD_TO_OUSTR( sCert );
58  sCleanCert = sCleanCert.replaceAll( "-----BEGIN CERTIFICATE-----", "" );
59  sCleanCert = sCleanCert.replaceAll( "-----END CERTIFICATE-----", "" );
60  uno::Reference< security::XCertificate > xCert(
61  xSecurityEnv->createCertificateFromAscii(
62  sCleanCert ) );
63 
64  uno::Reference< security::XCertificateContainer > xCertificateContainer;
65  try
66  {
67  xCertificateContainer = security::CertificateContainer::create( m_xContext );
68  }
69  catch ( uno::Exception const & )
70  {
71  }
72 
73  if ( xCertificateContainer.is( ) )
74  {
75  security::CertificateContainerStatus status(
76  xCertificateContainer->hasCertificate(
77  m_sHostname, xCert->getSubjectName() ) );
78 
79  if ( status != security::CertificateContainerStatus_NOCERT )
80  return status == security::CertificateContainerStatus_TRUSTED;
81  }
82 
83  // If we had no certificate, ask what to do
84  std::vector< uno::Reference< security::XCertificate > > vecCerts;
85 
86  for ( ++pIt; pIt != aCertificates.end(); ++pIt )
87  {
88  sCert = *pIt;
89  uno::Reference< security::XCertificate> xImCert(
90  xSecurityEnv->createCertificateFromAscii(
91  STD_TO_OUSTR( sCert ) ) );
92  if ( xImCert.is() )
93  vecCerts.push_back( xImCert );
94  }
95 
96  sal_Int64 certValidity = xSecurityEnv->verifyCertificate( xCert,
97  ::comphelper::containerToSequence( vecCerts ) );
98 
99  uno::Reference< task::XInteractionHandler > xIH(
100  m_xEnv->getInteractionHandler() );
101  if ( xIH.is() )
102  {
105  sal_Int32( certValidity ), xCert, m_sHostname ) );
106  xIH->handle( xRequest.get() );
108  = xRequest->getSelection();
109 
110  if ( xSelection.is() )
111  {
112  uno::Reference< task::XInteractionApprove > xApprove(
113  xSelection.get(), uno::UNO_QUERY );
114  bValidate = xApprove.is();
115 
116  // Store the decision in the container
117  xCertificateContainer->addCertificate(
118  m_sHostname, xCert->getSubjectName(), bValidate );
119  }
120  }
121  }
122  }
123  return bValidate;
124  }
125 }
126 
127 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
#define STD_TO_OUSTR(str)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
const uno::Reference< uno::XComponentContext > m_xContext