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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <com/sun/star/security/CertificateValidity.hpp>
22 #include <com/sun/star/security/XCertificateExtension.hpp>
23 #include <com/sun/star/security/XSanExtension.hpp>
24 #include <com/sun/star/security/ExtAltNameType.hpp>
25 #include <com/sun/star/task/XInteractionAbort.hpp>
26 #include <com/sun/star/task/XInteractionApprove.hpp>
27 #include <com/sun/star/task/XInteractionRequest.hpp>
28 #include <com/sun/star/ucb/CertificateValidationRequest.hpp>
29 #include <com/sun/star/uno/Reference.hxx>
31 #include <comphelper/lok.hxx>
32 #include <comphelper/sequence.hxx>
33 #include <com/sun/star/uno/Sequence.hxx>
34 #include <svl/zforlist.hxx>
35 #include <unotools/resmgr.hxx>
36 #include <vcl/svapp.hxx>
37 #include <vcl/settings.hxx>
40 #include "getcontinuations.hxx"
41 #include "sslwarndlg.hxx"
42 #include "unknownauthdlg.hxx"
48 #define OID_SUBJECT_ALTERNATIVE_NAME "2.5.29.17"
51 using namespace com::sun::star
;
56 getContentPart( const OUString
& _rRawString
)
58 // search over some parts to find a string
59 static char const * aIDs
[] = { "CN=", "OU=", "O=", "E=", nullptr };
64 OUString sPartId
= OUString::createFromAscii( aIDs
[i
++] );
65 sal_Int32 nContStart
= _rRawString
.indexOf( sPartId
);
66 if ( nContStart
!= -1 )
68 nContStart
+= sPartId
.getLength();
69 sal_Int32 nContEnd
= _rRawString
.indexOf( ',', nContStart
);
71 sPart
= _rRawString
.copy( nContStart
, nContEnd
- nContStart
);
73 sPart
= _rRawString
.copy( nContStart
);
82 const OUString
& hostName
, const uno::Sequence
< OUString
>& certHostNames
)
84 for ( const OUString
& element
: certHostNames
){
85 if (element
.isEmpty())
88 if (hostName
.equalsIgnoreAsciiCase( element
))
91 if (element
.startsWith("*") &&
92 hostName
.getLength() >= element
.getLength() )
94 OUString cmpStr
= element
.copy( 1 );
95 if ( hostName
.matchIgnoreAsciiCase(
96 cmpStr
, hostName
.getLength() - cmpStr
.getLength()) )
105 getLocalizedDatTimeStr(
106 uno::Reference
< uno::XComponentContext
> const & xContext
,
107 util::DateTime
const & rDateTime
)
109 OUString aDateTimeStr
;
110 Date
aDate( Date::EMPTY
);
111 tools::Time
aTime( tools::Time::EMPTY
);
113 aDate
= Date( rDateTime
.Day
, rDateTime
.Month
, rDateTime
.Year
);
114 aTime
= tools::Time( rDateTime
.Hours
, rDateTime
.Minutes
, rDateTime
.Seconds
);
116 LanguageType eUILang
= Application::GetSettings().GetUILanguageTag().getLanguageType();
117 SvNumberFormatter
*pNumberFormatter
= new SvNumberFormatter( xContext
, eUILang
);
119 const Color
* pColor
= nullptr;
120 const Date
& rNullDate
= pNumberFormatter
->GetNullDate();
122 = pNumberFormatter
->GetStandardFormat( SvNumFormatType::DATE
, eUILang
);
124 pNumberFormatter
->GetOutputString( aDate
- rNullDate
, nFormat
, aTmpStr
, &pColor
);
125 aDateTimeStr
= aTmpStr
+ " ";
127 nFormat
= pNumberFormatter
->GetStandardFormat( SvNumFormatType::TIME
, eUILang
);
128 pNumberFormatter
->GetOutputString(
129 aTime
.GetTimeInDays(), nFormat
, aTmpStr
, &pColor
);
130 aDateTimeStr
+= aTmpStr
;
136 executeUnknownAuthDialog(
137 weld::Window
* pParent
,
138 uno::Reference
< uno::XComponentContext
> const & xContext
,
139 const uno::Reference
< security::XCertificate
>& rXCert
)
141 SolarMutexGuard aGuard
;
143 UnknownAuthDialog
aDialog(pParent
, rXCert
, xContext
);
145 // Get correct resource string
148 std::vector
< OUString
> aArguments
;
149 aArguments
.push_back( getContentPart( rXCert
->getSubjectName()) );
151 std::locale
aResLocale(Translate::Create("uui"));
153 aMessage
= Translate::get(STR_UUI_UNKNOWNAUTH_UNTRUSTED
, aResLocale
);
154 aMessage
= UUIInteractionHelper::replaceMessageWithArguments(
155 aMessage
, aArguments
);
156 aDialog
.setDescriptionText( aMessage
);
158 return static_cast<bool>(aDialog
.run());
161 enum class SslWarnType
{
162 DOMAINMISMATCH
, EXPIRED
, INVALID
166 executeSSLWarnDialog(
167 weld::Window
* pParent
,
168 uno::Reference
< uno::XComponentContext
> const & xContext
,
169 const uno::Reference
< security::XCertificate
>& rXCert
,
171 const OUString
& hostName
)
173 SolarMutexGuard aGuard
;
175 SSLWarnDialog
aDialog(pParent
, rXCert
, xContext
);
177 // Get correct resource string
178 std::vector
< OUString
> aArguments_1
;
179 char const * pMessageKey
= nullptr;
180 char const * pTitleKey
= nullptr;
184 case SslWarnType::DOMAINMISMATCH
:
185 pMessageKey
= STR_UUI_SSLWARN_DOMAINMISMATCH
;
186 pTitleKey
= STR_UUI_SSLWARN_DOMAINMISMATCH_TITLE
;
187 aArguments_1
.push_back( hostName
);
188 aArguments_1
.push_back(
189 getContentPart( rXCert
->getSubjectName()) );
190 aArguments_1
.push_back( hostName
);
192 case SslWarnType::EXPIRED
:
193 pMessageKey
= STR_UUI_SSLWARN_EXPIRED
;
194 pTitleKey
= STR_UUI_SSLWARN_EXPIRED_TITLE
;
195 aArguments_1
.push_back(
196 getContentPart( rXCert
->getSubjectName()) );
197 aArguments_1
.push_back(
198 getLocalizedDatTimeStr( xContext
,
199 rXCert
->getNotValidAfter() ) );
200 aArguments_1
.push_back(
201 getLocalizedDatTimeStr( xContext
,
202 rXCert
->getNotValidAfter() ) );
204 case SslWarnType::INVALID
:
205 pMessageKey
= STR_UUI_SSLWARN_INVALID
;
206 pTitleKey
= STR_UUI_SSLWARN_INVALID_TITLE
;
208 default: assert(false);
211 std::locale
aResLocale(Translate::Create("uui"));
213 OUString aMessage_1
= Translate::get(pMessageKey
, aResLocale
);
214 aMessage_1
= UUIInteractionHelper::replaceMessageWithArguments(
215 aMessage_1
, aArguments_1
);
216 aDialog
.setDescription1Text( aMessage_1
);
218 OUString aTitle
= Translate::get(pTitleKey
, aResLocale
);
219 aDialog
.set_title(aTitle
);
221 return static_cast<bool>(aDialog
.run());
225 handleCertificateValidationRequest_(
226 weld::Window
* pParent
,
227 uno::Reference
< uno::XComponentContext
> const & xContext
,
228 ucb::CertificateValidationRequest
const & rRequest
,
229 uno::Sequence
< uno::Reference
< task::XInteractionContinuation
> > const &
232 uno::Reference
< task::XInteractionApprove
> xApprove
;
233 uno::Reference
< task::XInteractionAbort
> xAbort
;
234 getContinuations(rContinuations
, &xApprove
, &xAbort
);
236 if ( comphelper::LibreOfficeKit::isActive() && xApprove
.is() )
242 sal_Int32 failures
= rRequest
.CertificateValidity
;
243 bool trustCert
= true;
245 if ( ((failures
& security::CertificateValidity::UNTRUSTED
)
246 == security::CertificateValidity::UNTRUSTED
) ||
247 ((failures
& security::CertificateValidity::ISSUER_UNTRUSTED
)
248 == security::CertificateValidity::ISSUER_UNTRUSTED
) ||
249 ((failures
& security::CertificateValidity::ROOT_UNTRUSTED
)
250 == security::CertificateValidity::ROOT_UNTRUSTED
) )
252 trustCert
= executeUnknownAuthDialog( pParent
,
254 rRequest
.Certificate
);
257 uno::Sequence
< uno::Reference
< security::XCertificateExtension
> > extensions
= rRequest
.Certificate
->getExtensions();
258 uno::Reference
< security::XSanExtension
> sanExtension
;
259 auto pExtension
= std::find_if(extensions
.begin(), extensions
.end(),
260 [](const uno::Reference
< security::XCertificateExtension
>& element
) {
261 OString
aId ( reinterpret_cast<const char *>(element
->getExtensionId().getConstArray()), element
->getExtensionId().getLength());
262 return aId
== OID_SUBJECT_ALTERNATIVE_NAME
;
264 if (pExtension
!= extensions
.end())
266 sanExtension
= uno::Reference
<security::XSanExtension
>(*pExtension
, uno::UNO_QUERY
);
269 std::vector
<security::CertAltNameEntry
> altNames
;
270 if (sanExtension
.is())
272 altNames
= comphelper::sequenceToContainer
<std::vector
<security::CertAltNameEntry
>>(sanExtension
->getAlternativeNames());
275 OUString certHostName
= getContentPart( rRequest
.Certificate
->getSubjectName() );
276 uno::Sequence
< OUString
> certHostNames(altNames
.size() + 1);
278 certHostNames
[0] = certHostName
;
280 for (size_t n
= 0; n
< altNames
.size(); ++n
)
282 if (altNames
[n
].Type
== security::ExtAltNameType_DNS_NAME
)
284 altNames
[n
].Value
>>= certHostNames
[n
+1];
288 if ( (!isDomainMatch(
293 trustCert
= executeSSLWarnDialog( pParent
,
295 rRequest
.Certificate
,
296 SslWarnType::DOMAINMISMATCH
,
300 else if ( (((failures
& security::CertificateValidity::TIME_INVALID
)
301 == security::CertificateValidity::TIME_INVALID
) ||
302 ((failures
& security::CertificateValidity::NOT_TIME_NESTED
)
303 == security::CertificateValidity::NOT_TIME_NESTED
)) &&
306 trustCert
= executeSSLWarnDialog( pParent
,
308 rRequest
.Certificate
,
309 SslWarnType::EXPIRED
,
313 else if ( (((failures
& security::CertificateValidity::REVOKED
)
314 == security::CertificateValidity::REVOKED
) ||
315 ((failures
& security::CertificateValidity::SIGNATURE_INVALID
)
316 == security::CertificateValidity::SIGNATURE_INVALID
) ||
317 ((failures
& security::CertificateValidity::EXTENSION_INVALID
)
318 == security::CertificateValidity::EXTENSION_INVALID
) ||
319 ((failures
& security::CertificateValidity::INVALID
)
320 == security::CertificateValidity::INVALID
)) &&
323 trustCert
= executeSSLWarnDialog( pParent
,
325 rRequest
.Certificate
,
326 SslWarnType::INVALID
,
345 UUIInteractionHelper::handleCertificateValidationRequest(
346 uno::Reference
< task::XInteractionRequest
> const & rRequest
)
348 uno::Any
aAnyRequest(rRequest
->getRequest());
350 ucb::CertificateValidationRequest aCertificateValidationRequest
;
351 if (aAnyRequest
>>= aCertificateValidationRequest
)
353 uno::Reference
<awt::XWindow
> xParent
= getParentXWindow();
354 handleCertificateValidationRequest_(Application::GetFrameWeld(xParent
),
356 aCertificateValidationRequest
,
357 rRequest
->getContinuations());
364 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */