- Revise uses of getSomething to use getFromUnoTunnel Where that is impossible, use getSomething_cast to unify casting, and minimize number of places doing low-level transformations. The change keeps the existing tunnel references that last for the duration of the pointers' life, because sometimes destroying such reference may destroy the pointed object, and result in use after free. Change-Id: I291c33223582c34cd2c763aa8aacf0ae899ca4c0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122101 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
1056 lines
38 KiB
C++
1056 lines
38 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <sal/config.h>
|
|
|
|
#include <cstddef>
|
|
#include <string.h>
|
|
|
|
#if !defined WIN32_LEAN_AND_MEAN
|
|
# define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#include <Windows.h>
|
|
#include <WinCrypt.h>
|
|
#include <sal/macros.h>
|
|
#include <osl/thread.h>
|
|
#include "securityenvironment_mscryptimpl.hxx"
|
|
|
|
#include "x509certificate_mscryptimpl.hxx"
|
|
#include <comphelper/servicehelper.hxx>
|
|
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
|
|
#include <com/sun/star/uno/XComponentContext.hpp>
|
|
#include <cppuhelper/supportsservice.hxx>
|
|
#include <xmlsec-wrapper.h>
|
|
#include "akmngr.hxx"
|
|
|
|
#include <biginteger.hxx>
|
|
|
|
#include <comphelper/windowserrorstring.hxx>
|
|
#include <sal/log.hxx>
|
|
#include <rtl/locale.h>
|
|
#include <rtl/ref.hxx>
|
|
#include <osl/nlsupport.h>
|
|
#include <osl/process.h>
|
|
#include <o3tl/char16_t2wchar_t.hxx>
|
|
#include <svl/cryptosign.hxx>
|
|
|
|
using namespace ::com::sun::star;
|
|
using namespace ::com::sun::star::lang ;
|
|
using ::com::sun::star::lang::XMultiServiceFactory ;
|
|
using ::com::sun::star::lang::XSingleServiceFactory ;
|
|
|
|
using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
|
|
using ::com::sun::star::security::XCertificate ;
|
|
|
|
static rtl::Reference<X509Certificate_MSCryptImpl> MswcryCertContextToXCert( PCCERT_CONTEXT cert ) ;
|
|
|
|
namespace {
|
|
|
|
struct CertErrorToString{
|
|
DWORD error;
|
|
char const * name;
|
|
};
|
|
|
|
}
|
|
|
|
CertErrorToString const arErrStrings[] =
|
|
{
|
|
{ 0x00000000, "CERT_TRUST_NO_ERROR"},
|
|
{ 0x00000001, "CERT_TRUST_IS_NOT_TIME_VALID"},
|
|
{ 0x00000002, "CERT_TRUST_IS_NOT_TIME_NESTED"},
|
|
{ 0x00000004, "CERT_TRUST_IS_REVOKED" },
|
|
{ 0x00000008, "CERT_TRUST_IS_NOT_SIGNATURE_VALID" },
|
|
{ 0x00000010, "CERT_TRUST_IS_NOT_SIGNATURE_VALID"},
|
|
{ 0x00000020, "CERT_TRUST_IS_UNTRUSTED_ROOT"},
|
|
{ 0x00000040, "CERT_TRUST_REVOCATION_STATUS_UNKNOWN"},
|
|
{ 0x00000080, "CERT_TRUST_IS_CYCLIC"},
|
|
{ 0x00000100, "CERT_TRUST_INVALID_EXTENSION"},
|
|
{ 0x00000200, "CERT_TRUST_INVALID_POLICY_CONSTRAINTS"},
|
|
{ 0x00000400, "CERT_TRUST_INVALID_BASIC_CONSTRAINTS"},
|
|
{ 0x00000800, "CERT_TRUST_INVALID_NAME_CONSTRAINTS"},
|
|
{ 0x00001000, "CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT"},
|
|
{ 0x00002000, "CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT"},
|
|
{ 0x00004000, "CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT"},
|
|
{ 0x00008000, "CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT"},
|
|
{ 0x01000000, "CERT_TRUST_IS_OFFLINE_REVOCATION"},
|
|
{ 0x02000000, "CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY"},
|
|
{ 0x04000000, "CERT_TRUST_IS_EXPLICIT_DISTRUST"},
|
|
{ 0x08000000, "CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT"},
|
|
//Chain errors
|
|
{ 0x00010000, "CERT_TRUST_IS_PARTIAL_CHAIN"},
|
|
{ 0x00020000, "CERT_TRUST_CTL_IS_NOT_TIME_VALID"},
|
|
{ 0x00040000, "CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID"},
|
|
{ 0x00080000, "CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE"}
|
|
};
|
|
|
|
static void traceTrustStatus(DWORD err)
|
|
{
|
|
if (err == 0)
|
|
SAL_INFO("xmlsecurity.xmlsec", " " << arErrStrings[0].name);
|
|
for (std::size_t i = 1; i < SAL_N_ELEMENTS(arErrStrings); i++)
|
|
{
|
|
if (arErrStrings[i].error & err)
|
|
SAL_INFO("xmlsecurity.xmlsec", " " << arErrStrings[i].name);
|
|
}
|
|
}
|
|
|
|
SecurityEnvironment_MSCryptImpl::SecurityEnvironment_MSCryptImpl( const uno::Reference< uno::XComponentContext >& xContext ) : m_hProv( NULL ) , m_pszContainer( nullptr ) , m_hKeyStore( nullptr ), m_hCertStore( nullptr ), m_hMySystemStore(nullptr), m_hRootSystemStore(nullptr), m_hTrustSystemStore(nullptr), m_hCaSystemStore(nullptr), m_bEnableDefault( false ){
|
|
|
|
m_xServiceManager.set(xContext, uno::UNO_QUERY);
|
|
}
|
|
|
|
SecurityEnvironment_MSCryptImpl::~SecurityEnvironment_MSCryptImpl() {
|
|
|
|
if( m_hProv != NULL ) {
|
|
CryptReleaseContext( m_hProv, 0 ) ;
|
|
m_hProv = NULL ;
|
|
}
|
|
|
|
if( m_pszContainer != nullptr ) {
|
|
//TODO: Don't know whether or not it should be released now.
|
|
m_pszContainer = nullptr ;
|
|
}
|
|
|
|
if( m_hCertStore != nullptr ) {
|
|
CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
|
|
m_hCertStore = nullptr ;
|
|
}
|
|
|
|
if( m_hKeyStore != nullptr ) {
|
|
CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
|
|
m_hKeyStore = nullptr ;
|
|
}
|
|
|
|
//i120675, close the store handles
|
|
if( m_hMySystemStore != nullptr ) {
|
|
CertCloseStore( m_hMySystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
m_hMySystemStore = nullptr ;
|
|
}
|
|
|
|
if( m_hRootSystemStore != nullptr ) {
|
|
CertCloseStore( m_hRootSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
m_hRootSystemStore = nullptr ;
|
|
}
|
|
|
|
if( m_hTrustSystemStore != nullptr ) {
|
|
CertCloseStore( m_hTrustSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
m_hTrustSystemStore = nullptr ;
|
|
}
|
|
|
|
if( m_hCaSystemStore != nullptr ) {
|
|
CertCloseStore( m_hCaSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
m_hCaSystemStore = nullptr ;
|
|
}
|
|
}
|
|
|
|
/* XServiceInfo */
|
|
OUString SAL_CALL SecurityEnvironment_MSCryptImpl::getImplementationName() {
|
|
return "com.sun.star.xml.crypto.SecurityEnvironment";
|
|
}
|
|
|
|
/* XServiceInfo */
|
|
sal_Bool SAL_CALL SecurityEnvironment_MSCryptImpl::supportsService( const OUString& serviceName) {
|
|
return cppu::supportsService(this, serviceName);
|
|
}
|
|
/* XServiceInfo */
|
|
uno::Sequence< OUString > SAL_CALL SecurityEnvironment_MSCryptImpl::getSupportedServiceNames() {
|
|
return { "com.sun.star.xml.crypto.SecurityEnvironment" };
|
|
}
|
|
|
|
/* XUnoTunnel */
|
|
UNO3_GETIMPLEMENTATION_IMPL(SecurityEnvironment_MSCryptImpl);
|
|
|
|
HCRYPTPROV SecurityEnvironment_MSCryptImpl::getCryptoProvider() {
|
|
return m_hProv ;
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl::setCryptoProvider( HCRYPTPROV aProv ) {
|
|
if( m_hProv != NULL ) {
|
|
CryptReleaseContext( m_hProv, 0 ) ;
|
|
m_hProv = NULL ;
|
|
}
|
|
|
|
if( aProv != NULL ) {
|
|
m_hProv = aProv ;
|
|
}
|
|
}
|
|
|
|
LPCTSTR SecurityEnvironment_MSCryptImpl::getKeyContainer() {
|
|
return m_pszContainer ;
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl::setKeyContainer( LPCTSTR aKeyContainer ) {
|
|
//TODO: Don't know whether or not it should be copied.
|
|
m_pszContainer = aKeyContainer ;
|
|
}
|
|
|
|
|
|
HCERTSTORE SecurityEnvironment_MSCryptImpl::getCryptoSlot() {
|
|
return m_hKeyStore ;
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl::setCryptoSlot( HCERTSTORE aSlot) {
|
|
if( m_hKeyStore != nullptr ) {
|
|
CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
|
|
m_hKeyStore = nullptr ;
|
|
}
|
|
|
|
if( aSlot != nullptr ) {
|
|
m_hKeyStore = CertDuplicateStore( aSlot ) ;
|
|
}
|
|
}
|
|
|
|
HCERTSTORE SecurityEnvironment_MSCryptImpl::getCertDb() {
|
|
return m_hCertStore ;
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl::setCertDb( HCERTSTORE aCertDb ) {
|
|
if( m_hCertStore != nullptr ) {
|
|
CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
|
|
m_hCertStore = nullptr ;
|
|
}
|
|
|
|
if( aCertDb != nullptr ) {
|
|
m_hCertStore = CertDuplicateStore( aCertDb ) ;
|
|
}
|
|
}
|
|
|
|
#ifdef SAL_LOG_INFO
|
|
|
|
// Based on sample code from MSDN
|
|
|
|
static OUString get_system_name(const void *pvSystemStore,
|
|
DWORD dwFlags)
|
|
{
|
|
LPCWSTR ppwszSystemName;
|
|
if (dwFlags & CERT_SYSTEM_STORE_RELOCATE_FLAG)
|
|
{
|
|
_CERT_SYSTEM_STORE_RELOCATE_PARA const * pRelocatePara;
|
|
pRelocatePara = static_cast<_CERT_SYSTEM_STORE_RELOCATE_PARA const *>(pvSystemStore);
|
|
ppwszSystemName = pRelocatePara->pwszSystemStore;
|
|
}
|
|
else
|
|
{
|
|
ppwszSystemName = static_cast<LPCWSTR>(pvSystemStore);
|
|
}
|
|
return OUString(o3tl::toU(ppwszSystemName));
|
|
}
|
|
|
|
extern "C" {
|
|
|
|
static BOOL WINAPI cert_enum_physical_store_callback(const void *,
|
|
DWORD dwFlags,
|
|
LPCWSTR pwszStoreName,
|
|
PCERT_PHYSICAL_STORE_INFO,
|
|
void *,
|
|
void *)
|
|
{
|
|
OUString name(o3tl::toU(pwszStoreName));
|
|
if (dwFlags & CERT_PHYSICAL_STORE_PREDEFINED_ENUM_FLAG)
|
|
name += " (implicitly created)";
|
|
SAL_INFO("xmlsecurity.xmlsec", " Physical store: " << name);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static BOOL WINAPI cert_enum_system_store_callback(const void *pvSystemStore,
|
|
DWORD dwFlags,
|
|
PCERT_SYSTEM_STORE_INFO,
|
|
void *,
|
|
void *)
|
|
{
|
|
SAL_INFO("xmlsecurity.xmlsec", "System store: " << get_system_name(pvSystemStore, dwFlags));
|
|
|
|
if (!CertEnumPhysicalStore(pvSystemStore,
|
|
dwFlags,
|
|
nullptr,
|
|
cert_enum_physical_store_callback))
|
|
{
|
|
DWORD dwErr = GetLastError();
|
|
if (!(ERROR_FILE_NOT_FOUND == dwErr ||
|
|
ERROR_NOT_SUPPORTED == dwErr))
|
|
{
|
|
SAL_WARN("xmlsecurity.xmlsec", "CertEnumPhysicalStore failed:" << WindowsErrorString(GetLastError()));
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
//Methods from XSecurityEnvironment
|
|
uno::Sequence< uno::Reference < XCertificate > > SecurityEnvironment_MSCryptImpl::getPersonalCertificates()
|
|
{
|
|
sal_Int32 length ;
|
|
rtl::Reference<X509Certificate_MSCryptImpl> xcert ;
|
|
std::vector< rtl::Reference<X509Certificate_MSCryptImpl> > certsList ;
|
|
PCCERT_CONTEXT pCertContext = nullptr;
|
|
|
|
//firstly, we try to find private keys in given key store.
|
|
if( m_hKeyStore != nullptr ) {
|
|
pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext );
|
|
while (pCertContext)
|
|
{
|
|
xcert = MswcryCertContextToXCert( pCertContext ) ;
|
|
if( xcert.is() )
|
|
certsList.push_back( xcert ) ;
|
|
pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext );
|
|
}
|
|
}
|
|
|
|
//Thirdly, we try to find certificate from system default key store.
|
|
if( m_bEnableDefault ) {
|
|
HCERTSTORE hSystemKeyStore ;
|
|
DWORD dwKeySpec;
|
|
NCRYPT_KEY_HANDLE hCryptKey;
|
|
|
|
#ifdef SAL_LOG_INFO
|
|
CertEnumSystemStore(CERT_SYSTEM_STORE_CURRENT_USER, nullptr, nullptr, cert_enum_system_store_callback);
|
|
#endif
|
|
|
|
hSystemKeyStore = CertOpenSystemStoreW( 0, L"MY" ) ;
|
|
if( hSystemKeyStore != nullptr ) {
|
|
pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext );
|
|
while (pCertContext)
|
|
{
|
|
// for checking whether the certificate is a personal certificate or not.
|
|
DWORD dwFlags = CRYPT_ACQUIRE_COMPARE_KEY_FLAG | CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG;
|
|
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE* phCryptProvOrNCryptKey = &hCryptKey;
|
|
if(!(CryptAcquireCertificatePrivateKey(pCertContext,
|
|
dwFlags,
|
|
nullptr,
|
|
phCryptProvOrNCryptKey,
|
|
&dwKeySpec,
|
|
nullptr)))
|
|
{
|
|
// Not Privatekey found. SKIP this one.
|
|
pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext );
|
|
continue;
|
|
}
|
|
// then TODO : Check the personal cert is valid or not.
|
|
|
|
xcert = MswcryCertContextToXCert( pCertContext ) ;
|
|
if( xcert.is() )
|
|
certsList.push_back( xcert ) ;
|
|
pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext );
|
|
}
|
|
}
|
|
|
|
CertCloseStore( hSystemKeyStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
|
|
length = certsList.size() ;
|
|
if( length != 0 ) {
|
|
int i = 0;
|
|
uno::Sequence< uno::Reference< XCertificate > > certSeq( length ) ;
|
|
|
|
for( const auto& rXCert : certsList ) {
|
|
certSeq[i] = rXCert ;
|
|
++i;
|
|
}
|
|
|
|
return certSeq ;
|
|
}
|
|
|
|
return uno::Sequence< uno::Reference< XCertificate > >() ;
|
|
}
|
|
|
|
|
|
uno::Reference< XCertificate > SecurityEnvironment_MSCryptImpl::getCertificate( const OUString& issuerName, const uno::Sequence< sal_Int8 >& serialNumber ) {
|
|
unsigned int i ;
|
|
rtl::Reference<X509Certificate_MSCryptImpl> xcert ;
|
|
PCCERT_CONTEXT pCertContext = nullptr ;
|
|
HCERTSTORE hCertStore = nullptr ;
|
|
CRYPT_INTEGER_BLOB cryptSerialNumber ;
|
|
CERT_INFO certInfo ;
|
|
|
|
// for correct encoding
|
|
rtl_Locale *pLocale = nullptr ;
|
|
osl_getProcessLocale( &pLocale ) ;
|
|
|
|
//Create cert info from issue and serial
|
|
LPCWSTR pszName = o3tl::toW( issuerName.getStr() );
|
|
|
|
if( ! ( CertStrToNameW(
|
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
|
|
pszName ,
|
|
CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG,
|
|
nullptr ,
|
|
nullptr ,
|
|
&certInfo.Issuer.cbData, nullptr ) )
|
|
) {
|
|
return nullptr ;
|
|
}
|
|
|
|
certInfo.Issuer.pbData = static_cast<BYTE*>(malloc( certInfo.Issuer.cbData ));
|
|
if(!certInfo.Issuer.pbData)
|
|
throw uno::RuntimeException() ;
|
|
|
|
if( ! ( CertStrToNameW(
|
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
|
|
pszName ,
|
|
CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG,
|
|
nullptr ,
|
|
certInfo.Issuer.pbData ,
|
|
&certInfo.Issuer.cbData, nullptr ) )
|
|
) {
|
|
free( certInfo.Issuer.pbData ) ;
|
|
return nullptr ;
|
|
}
|
|
|
|
//Get the SerialNumber
|
|
cryptSerialNumber.cbData = serialNumber.getLength() ;
|
|
cryptSerialNumber.pbData = static_cast<BYTE*>(malloc( cryptSerialNumber.cbData));
|
|
if (!cryptSerialNumber.pbData)
|
|
{
|
|
free( certInfo.Issuer.pbData ) ;
|
|
throw uno::RuntimeException() ;
|
|
}
|
|
for( i = 0; i < cryptSerialNumber.cbData; i ++ )
|
|
cryptSerialNumber.pbData[i] = serialNumber[ cryptSerialNumber.cbData - i - 1 ] ;
|
|
|
|
certInfo.SerialNumber.cbData = cryptSerialNumber.cbData ;
|
|
certInfo.SerialNumber.pbData = cryptSerialNumber.pbData ;
|
|
|
|
// Get the Cert from all store.
|
|
for( i = 0 ; i < 6 ; i ++ )
|
|
{
|
|
switch(i)
|
|
{
|
|
case 0:
|
|
if(m_hKeyStore == nullptr) continue ;
|
|
hCertStore = m_hKeyStore ;
|
|
break;
|
|
case 1:
|
|
if(m_hCertStore == nullptr) continue ;
|
|
hCertStore = m_hCertStore ;
|
|
break;
|
|
case 2:
|
|
hCertStore = CertOpenSystemStoreW( 0, L"MY" ) ;
|
|
if(hCertStore == nullptr || !m_bEnableDefault) continue ;
|
|
break;
|
|
case 3:
|
|
hCertStore = CertOpenSystemStoreW( 0, L"Root" ) ;
|
|
if(hCertStore == nullptr || !m_bEnableDefault) continue ;
|
|
break;
|
|
case 4:
|
|
hCertStore = CertOpenSystemStoreW( 0, L"Trust" ) ;
|
|
if(hCertStore == nullptr || !m_bEnableDefault) continue ;
|
|
break;
|
|
case 5:
|
|
hCertStore = CertOpenSystemStoreW( 0, L"CA" ) ;
|
|
if(hCertStore == nullptr || !m_bEnableDefault) continue ;
|
|
break;
|
|
default:
|
|
i=6;
|
|
continue;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* This code reserved for remind us there are another way to find one cert by
|
|
* IssuerName&serialnumber. You can use the code to replaced the function
|
|
* CertFindCertificateInStore IF and ONLY IF you must find one special cert in
|
|
* certStore but can not be found by CertFindCertificateInStore , then , you
|
|
* should also change the same part in libxmlsec/.../src/mscrypto/x509vfy.c#875.
|
|
* By Chandler Peng(chandler.peng@sun.com)
|
|
*****/
|
|
/*******************************************************************************
|
|
pCertContext = NULL ;
|
|
found = 0;
|
|
do{
|
|
// 1. enum the certs has same string in the issuer string.
|
|
pCertContext = CertEnumCertificatesInStore( hCertStore , pCertContext ) ;
|
|
if( pCertContext != NULL )
|
|
{
|
|
// 2. check the cert's issuer name .
|
|
char* issuer = NULL ;
|
|
DWORD cbIssuer = 0 ;
|
|
|
|
cbIssuer = CertNameToStr(
|
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
|
|
&( pCertContext->pCertInfo->Issuer ),
|
|
CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
|
|
NULL, 0
|
|
) ;
|
|
|
|
if( cbIssuer == 0 ) continue ; // discard this cert;
|
|
|
|
issuer = (char *)malloc( cbIssuer ) ;
|
|
if( issuer == NULL ) // discard this cert;
|
|
{
|
|
free( cryptSerialNumber.pbData) ;
|
|
free( certInfo.Issuer.pbData ) ;
|
|
CertFreeCertificateContext( pCertContext ) ;
|
|
if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
throw RuntimeException() ;
|
|
}
|
|
|
|
cbIssuer = CertNameToStr(
|
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
|
|
&( pCertContext->pCertInfo->Issuer ),
|
|
CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
|
|
issuer, cbIssuer
|
|
) ;
|
|
|
|
if( cbIssuer <= 0 )
|
|
{
|
|
free( issuer ) ;
|
|
continue ;// discard this cert;
|
|
}
|
|
|
|
if(strncmp(pszName , issuer , cbIssuer) != 0)
|
|
{
|
|
free( issuer ) ;
|
|
continue ;// discard this cert;
|
|
}
|
|
free( issuer ) ;
|
|
|
|
// 3. check the serial number.
|
|
if( memcmp( cryptSerialNumber.pbData , pCertContext->pCertInfo->SerialNumber.pbData , cryptSerialNumber.cbData ) != 0 )
|
|
{
|
|
continue ;// discard this cert;
|
|
}
|
|
|
|
// 4. confirm and break;
|
|
found = 1;
|
|
break ;
|
|
}
|
|
|
|
}while(pCertContext);
|
|
|
|
if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
if( found != 0 ) break; // Found the certificate.
|
|
********************************************************************************/
|
|
|
|
pCertContext = CertFindCertificateInStore(
|
|
hCertStore,
|
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
|
0,
|
|
CERT_FIND_SUBJECT_CERT,
|
|
&certInfo,
|
|
nullptr
|
|
) ;
|
|
|
|
if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
if( pCertContext != nullptr ) break ; // Found the certificate.
|
|
|
|
}
|
|
|
|
free(cryptSerialNumber.pbData);
|
|
free(certInfo.Issuer.pbData);
|
|
|
|
if( pCertContext != nullptr ) {
|
|
xcert = MswcryCertContextToXCert(pCertContext);
|
|
CertFreeCertificateContext(pCertContext);
|
|
}
|
|
|
|
return xcert ;
|
|
}
|
|
|
|
uno::Reference< XCertificate > SecurityEnvironment_MSCryptImpl::getCertificate( const OUString& issuerName, const OUString& serialNumber ) {
|
|
uno::Sequence< sal_Int8 > serial = xmlsecurity::numericStringToBigInteger( serialNumber ) ;
|
|
return getCertificate( issuerName, serial ) ;
|
|
}
|
|
|
|
uno::Sequence< uno::Reference < XCertificate > > SecurityEnvironment_MSCryptImpl::buildCertificatePath( const uno::Reference< XCertificate >& begin ) {
|
|
PCCERT_CHAIN_CONTEXT pChainContext ;
|
|
PCCERT_CONTEXT pCertContext ;
|
|
|
|
CERT_ENHKEY_USAGE enhKeyUsage ;
|
|
CERT_USAGE_MATCH certUsage ;
|
|
CERT_CHAIN_PARA chainPara ;
|
|
|
|
enhKeyUsage.cUsageIdentifier = 0 ;
|
|
enhKeyUsage.rgpszUsageIdentifier = nullptr ;
|
|
certUsage.dwType = USAGE_MATCH_TYPE_AND ;
|
|
certUsage.Usage = enhKeyUsage ;
|
|
chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ;
|
|
chainPara.RequestedUsage = certUsage ;
|
|
|
|
uno::Reference< XUnoTunnel > xCertTunnel( begin, uno::UNO_QUERY_THROW ) ;
|
|
const auto* xcert = comphelper::getFromUnoTunnel<X509Certificate_MSCryptImpl>(xCertTunnel);
|
|
if( xcert == nullptr ) {
|
|
throw uno::RuntimeException() ;
|
|
}
|
|
|
|
pCertContext = xcert->getMswcryCert() ;
|
|
|
|
pChainContext = nullptr ;
|
|
|
|
bool bChain = false;
|
|
if( pCertContext != nullptr )
|
|
{
|
|
HCERTSTORE hAdditionalStore = nullptr;
|
|
HCERTSTORE hCollectionStore = nullptr;
|
|
if (m_hCertStore && m_hKeyStore)
|
|
{
|
|
//Merge m_hCertStore and m_hKeyStore into one store.
|
|
hCollectionStore = CertOpenStore(
|
|
CERT_STORE_PROV_COLLECTION ,
|
|
0 ,
|
|
NULL ,
|
|
0 ,
|
|
nullptr
|
|
) ;
|
|
if (hCollectionStore != nullptr)
|
|
{
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
m_hCertStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
0) ;
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
m_hCertStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
0) ;
|
|
hAdditionalStore = hCollectionStore;
|
|
}
|
|
|
|
}
|
|
|
|
//if the merge of both stores failed then we add only m_hCertStore
|
|
if (hAdditionalStore == nullptr && m_hCertStore)
|
|
hAdditionalStore = m_hCertStore;
|
|
else if (hAdditionalStore == nullptr && m_hKeyStore)
|
|
hAdditionalStore = m_hKeyStore;
|
|
else
|
|
hAdditionalStore = nullptr;
|
|
|
|
//CertGetCertificateChain searches by default in MY, CA, ROOT and TRUST
|
|
bChain = CertGetCertificateChain(
|
|
nullptr ,
|
|
pCertContext ,
|
|
nullptr , //use current system time
|
|
hAdditionalStore,
|
|
&chainPara ,
|
|
CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_TIMESTAMP_TIME ,
|
|
nullptr ,
|
|
&pChainContext);
|
|
if (!bChain)
|
|
pChainContext = nullptr;
|
|
|
|
//Close the additional store
|
|
CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG);
|
|
}
|
|
|
|
if(bChain && pChainContext != nullptr && pChainContext->cChain > 0 )
|
|
{
|
|
PCCERT_CONTEXT pCertInChain ;
|
|
PCERT_SIMPLE_CHAIN pCertChain ;
|
|
rtl::Reference<X509Certificate_MSCryptImpl> pCert ;
|
|
|
|
pCertChain = pChainContext->rgpChain[0] ;
|
|
if( pCertChain->cElement ) {
|
|
uno::Sequence< uno::Reference< XCertificate > > xCertChain( pCertChain->cElement ) ;
|
|
|
|
for( unsigned int i = 0 ; i < pCertChain->cElement ; i ++ ) {
|
|
if( pCertChain->rgpElement[i] )
|
|
pCertInChain = pCertChain->rgpElement[i]->pCertContext ;
|
|
else
|
|
pCertInChain = nullptr ;
|
|
|
|
if( pCertInChain != nullptr ) {
|
|
pCert = MswcryCertContextToXCert( pCertInChain ) ;
|
|
if( pCert.is() )
|
|
xCertChain[i] = pCert ;
|
|
}
|
|
}
|
|
|
|
CertFreeCertificateChain( pChainContext ) ;
|
|
pChainContext = nullptr ;
|
|
|
|
return xCertChain ;
|
|
}
|
|
}
|
|
if (pChainContext)
|
|
CertFreeCertificateChain(pChainContext);
|
|
|
|
return uno::Sequence< uno::Reference < XCertificate > >();
|
|
}
|
|
|
|
uno::Reference< XCertificate > SecurityEnvironment_MSCryptImpl::createCertificateFromRaw( const uno::Sequence< sal_Int8 >& rawCertificate ) {
|
|
rtl::Reference<X509Certificate_MSCryptImpl> xcert ;
|
|
|
|
if( rawCertificate.getLength() > 0 ) {
|
|
xcert = new X509Certificate_MSCryptImpl() ;
|
|
xcert->setRawCert( rawCertificate ) ;
|
|
}
|
|
|
|
return xcert ;
|
|
}
|
|
|
|
uno::Reference< XCertificate > SecurityEnvironment_MSCryptImpl::createCertificateFromAscii( const OUString& asciiCertificate ) {
|
|
|
|
OString oscert = OUStringToOString( asciiCertificate , RTL_TEXTENCODING_ASCII_US ) ;
|
|
|
|
xmlChar* chCert = xmlStrndup( reinterpret_cast<const xmlChar*>(oscert.getStr()), static_cast<int>(oscert.getLength()) ) ;
|
|
|
|
xmlSecSize certSize = xmlSecBase64Decode( chCert, chCert, xmlStrlen( chCert ) ) ;
|
|
|
|
uno::Sequence< sal_Int8 > rawCert( certSize ) ;
|
|
for( xmlSecSize i = 0 ; i < certSize ; i ++ )
|
|
rawCert[i] = *( chCert + i ) ;
|
|
|
|
xmlFree( chCert ) ;
|
|
|
|
return createCertificateFromRaw( rawCert ) ;
|
|
}
|
|
|
|
|
|
static HCERTSTORE getCertStoreForIntermediatCerts(
|
|
const uno::Sequence< uno::Reference< css::security::XCertificate > >& seqCerts)
|
|
{
|
|
HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, nullptr);
|
|
if (store == nullptr)
|
|
return nullptr;
|
|
|
|
for (int i = 0; i < seqCerts.getLength(); i++)
|
|
{
|
|
SAL_INFO("xmlsecurity.xmlsec", "Added temporary certificate: " << seqCerts[i]->getSubjectName());
|
|
|
|
uno::Sequence<sal_Int8> data = seqCerts[i]->getEncoded();
|
|
PCCERT_CONTEXT cert = CertCreateCertificateContext(
|
|
X509_ASN_ENCODING, reinterpret_cast<const BYTE*>(&data[0]), data.getLength());
|
|
//Adding the certificate creates a copy and not just increases the ref count
|
|
//Therefore we free later the certificate that we now add
|
|
CertAddCertificateContextToStore(store, cert, CERT_STORE_ADD_ALWAYS, nullptr);
|
|
CertFreeCertificateContext(cert);
|
|
}
|
|
return store;
|
|
}
|
|
|
|
//We return only valid or invalid, as long as the API documentation expresses
|
|
//explicitly that all validation steps are carried out even if one or several
|
|
//errors occur. See also
|
|
//http://wiki.openoffice.org/wiki/Certificate_Path_Validation#Validation_status
|
|
sal_Int32 SecurityEnvironment_MSCryptImpl::verifyCertificate(
|
|
const uno::Reference< css::security::XCertificate >& aCert,
|
|
const uno::Sequence< uno::Reference< css::security::XCertificate > >& seqCerts)
|
|
{
|
|
sal_Int32 validity = css::security::CertificateValidity::INVALID;
|
|
PCCERT_CHAIN_CONTEXT pChainContext = nullptr;
|
|
PCCERT_CONTEXT pCertContext = nullptr;
|
|
|
|
uno::Reference< XUnoTunnel > xCertTunnel( aCert, uno::UNO_QUERY_THROW ) ;
|
|
|
|
SAL_INFO("xmlsecurity.xmlsec", "Start verification of certificate: " << aCert->getSubjectName());
|
|
|
|
const auto* xcert = comphelper::getFromUnoTunnel<X509Certificate_MSCryptImpl>(xCertTunnel);
|
|
if( xcert == nullptr ) {
|
|
throw uno::RuntimeException() ;
|
|
}
|
|
|
|
pCertContext = xcert->getMswcryCert() ;
|
|
|
|
CERT_ENHKEY_USAGE enhKeyUsage ;
|
|
CERT_USAGE_MATCH certUsage ;
|
|
CERT_CHAIN_PARA chainPara = {};
|
|
|
|
//Prepare parameter for CertGetCertificateChain
|
|
enhKeyUsage.cUsageIdentifier = 0 ;
|
|
enhKeyUsage.rgpszUsageIdentifier = nullptr ;
|
|
certUsage.dwType = USAGE_MATCH_TYPE_AND ;
|
|
certUsage.Usage = enhKeyUsage ;
|
|
chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ;
|
|
chainPara.RequestedUsage = certUsage ;
|
|
|
|
|
|
HCERTSTORE hCollectionStore = nullptr;
|
|
HCERTSTORE hIntermediateCertsStore = nullptr;
|
|
bool bChain = false;
|
|
if( pCertContext != nullptr )
|
|
{
|
|
hIntermediateCertsStore =
|
|
getCertStoreForIntermediatCerts(seqCerts);
|
|
|
|
//Merge m_hCertStore and m_hKeyStore and the store of the intermediate
|
|
//certificates into one store.
|
|
hCollectionStore = CertOpenStore(
|
|
CERT_STORE_PROV_COLLECTION ,
|
|
0 ,
|
|
NULL ,
|
|
0 ,
|
|
nullptr
|
|
) ;
|
|
if (hCollectionStore != nullptr)
|
|
{
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
m_hCertStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
0) ;
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
m_hCertStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
0) ;
|
|
CertAddStoreToCollection (
|
|
hCollectionStore,
|
|
hIntermediateCertsStore,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG,
|
|
0);
|
|
|
|
}
|
|
|
|
//CertGetCertificateChain searches by default in MY, CA, ROOT and TRUST
|
|
//We do not check revocation of the root. In most cases there are none.
|
|
//Then we would get CERT_TRUST_REVOCATION_STATUS_UNKNOWN
|
|
SAL_INFO("xmlsecurity.xmlsec", "Verifying cert using revocation information.");
|
|
bChain = CertGetCertificateChain(
|
|
nullptr ,
|
|
pCertContext ,
|
|
nullptr , //use current system time
|
|
hCollectionStore,
|
|
&chainPara ,
|
|
CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT,
|
|
nullptr ,
|
|
&pChainContext);
|
|
|
|
if (bChain && pChainContext->cChain > 0)
|
|
{
|
|
SAL_INFO("xmlsecurity.xmlsec", "Overall error status (all chains):");
|
|
traceTrustStatus(pChainContext->TrustStatus.dwErrorStatus);
|
|
//highest quality chains come first
|
|
PCERT_SIMPLE_CHAIN pSimpleChain = pChainContext->rgpChain[0];
|
|
SAL_INFO("xmlsecurity.xmlsec", "Error status of first chain:");
|
|
traceTrustStatus(pSimpleChain->TrustStatus.dwErrorStatus);
|
|
|
|
//CERT_TRUST_REVOCATION_STATUS_UNKNOWN is also set if a certificate
|
|
//has no AIA(OCSP) or CRLDP extension and there is no CRL locally installed.
|
|
DWORD revocationFlags = CERT_TRUST_REVOCATION_STATUS_UNKNOWN |
|
|
CERT_TRUST_IS_OFFLINE_REVOCATION;
|
|
DWORD otherErrorsMask = ~revocationFlags;
|
|
if( !(pSimpleChain->TrustStatus.dwErrorStatus & otherErrorsMask))
|
|
|
|
{
|
|
//No errors except maybe those caused by missing revocation information
|
|
//Check if there are errors
|
|
if ( pSimpleChain->TrustStatus.dwErrorStatus & revocationFlags)
|
|
{
|
|
//No revocation information. Because MSDN documentation is not
|
|
//clear about if all other tests are performed if an error occurs,
|
|
//we test again, without requiring revocation checking.
|
|
CertFreeCertificateChain(pChainContext);
|
|
pChainContext = nullptr;
|
|
SAL_INFO("xmlsecurity.xmlsec", "Checking again but without requiring revocation information.");
|
|
bChain = CertGetCertificateChain(
|
|
nullptr ,
|
|
pCertContext ,
|
|
nullptr , //use current system time
|
|
hCollectionStore,
|
|
&chainPara ,
|
|
0,
|
|
nullptr ,
|
|
&pChainContext);
|
|
if (bChain
|
|
&& pChainContext->cChain > 0
|
|
&& pChainContext->rgpChain[0]->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR)
|
|
{
|
|
SAL_INFO("xmlsecurity.xmlsec", "Certificate is valid.");
|
|
validity = css::security::CertificateValidity::VALID;
|
|
}
|
|
else
|
|
{
|
|
SAL_INFO("xmlsecurity.xmlsec", "Certificate is invalid.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//valid and revocation information available
|
|
SAL_INFO("xmlsecurity.xmlsec", "Certificate is valid.");
|
|
validity = css::security::CertificateValidity::VALID;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//invalid
|
|
SAL_INFO("xmlsecurity.xmlsec", "Certificate is invalid.");
|
|
validity = css::security::CertificateValidity::INVALID ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SAL_INFO("xmlsecurity.xmlsec", "CertGetCertificateChain failed.");
|
|
}
|
|
}
|
|
|
|
if (pChainContext)
|
|
{
|
|
CertFreeCertificateChain(pChainContext);
|
|
pChainContext = nullptr;
|
|
}
|
|
|
|
//Close the additional store, do not destroy the contained certs
|
|
CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG);
|
|
//Close the temporary store containing the intermediate certificates and make
|
|
//sure all certificates are deleted.
|
|
CertCloseStore(hIntermediateCertsStore, CERT_CLOSE_STORE_CHECK_FLAG);
|
|
|
|
return validity ;
|
|
}
|
|
|
|
sal_Int32 SecurityEnvironment_MSCryptImpl::getCertificateCharacters( const css::uno::Reference< css::security::XCertificate >& aCert ) {
|
|
sal_Int32 characters ;
|
|
PCCERT_CONTEXT pCertContext ;
|
|
|
|
uno::Reference< XUnoTunnel > xCertTunnel( aCert, uno::UNO_QUERY_THROW ) ;
|
|
const auto* xcert = comphelper::getFromUnoTunnel<X509Certificate_MSCryptImpl>(xCertTunnel);
|
|
if( xcert == nullptr ) {
|
|
throw uno::RuntimeException() ;
|
|
}
|
|
|
|
pCertContext = xcert->getMswcryCert() ;
|
|
|
|
characters = 0x00000000 ;
|
|
|
|
//Firstly, make sentence whether or not the cert is self-signed.
|
|
if( CertCompareCertificateName( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &(pCertContext->pCertInfo->Subject), &(pCertContext->pCertInfo->Issuer) ) ) {
|
|
characters |= css::security::CertificateCharacters::SELF_SIGNED ;
|
|
} else {
|
|
characters &= ~ css::security::CertificateCharacters::SELF_SIGNED ;
|
|
}
|
|
|
|
//Secondly, make sentence whether or not the cert has a private key.
|
|
{
|
|
BOOL fCallerFreeProv ;
|
|
DWORD dwKeySpec ;
|
|
NCRYPT_KEY_HANDLE hKey = 0;
|
|
DWORD dwFlags = CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG;
|
|
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE* phCryptProvOrNCryptKey = &hKey;
|
|
if( CryptAcquireCertificatePrivateKey( pCertContext ,
|
|
dwFlags,
|
|
nullptr ,
|
|
phCryptProvOrNCryptKey,
|
|
&dwKeySpec,
|
|
&fCallerFreeProv )
|
|
) {
|
|
characters |= css::security::CertificateCharacters::HAS_PRIVATE_KEY ;
|
|
|
|
if (hKey && fCallerFreeProv)
|
|
NCryptFreeObject(hKey);
|
|
} else {
|
|
characters &= ~ css::security::CertificateCharacters::HAS_PRIVATE_KEY ;
|
|
}
|
|
}
|
|
return characters ;
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl::enableDefaultCrypt( bool enable ) {
|
|
m_bEnableDefault = enable ;
|
|
}
|
|
|
|
bool SecurityEnvironment_MSCryptImpl::defaultEnabled() {
|
|
return m_bEnableDefault ;
|
|
}
|
|
|
|
static rtl::Reference<X509Certificate_MSCryptImpl> MswcryCertContextToXCert( PCCERT_CONTEXT cert )
|
|
{
|
|
rtl::Reference<X509Certificate_MSCryptImpl> xcert ;
|
|
|
|
if( cert != nullptr ) {
|
|
xcert = new X509Certificate_MSCryptImpl() ;
|
|
xcert->setMswcryCert( cert ) ;
|
|
}
|
|
|
|
return xcert ;
|
|
}
|
|
|
|
OUString SecurityEnvironment_MSCryptImpl::getSecurityEnvironmentInformation()
|
|
{
|
|
return "Microsoft Crypto API";
|
|
}
|
|
|
|
xmlSecKeysMngrPtr SecurityEnvironment_MSCryptImpl::createKeysManager() {
|
|
|
|
/*-
|
|
* The following lines is based on the of xmlsec-mscrypto crypto engine
|
|
*/
|
|
xmlSecKeysMngrPtr pKeysMngr = xmlsecurity::MSCryptoAppliedKeysMngrCreate() ;
|
|
if( pKeysMngr == nullptr )
|
|
throw uno::RuntimeException() ;
|
|
|
|
/*-
|
|
* Adopt system default certificate store.
|
|
*/
|
|
if( defaultEnabled() ) {
|
|
//Add system key store into the keys manager.
|
|
m_hMySystemStore = CertOpenSystemStoreW( 0, L"MY" ) ;
|
|
if( m_hMySystemStore != nullptr ) {
|
|
if( xmlsecurity::MSCryptoAppliedKeysMngrAdoptKeyStore( pKeysMngr, m_hMySystemStore ) < 0 ) {
|
|
CertCloseStore( m_hMySystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
m_hMySystemStore = nullptr;
|
|
throw uno::RuntimeException() ;
|
|
}
|
|
m_hMySystemStore = nullptr;
|
|
}
|
|
|
|
//Add system root store into the keys manager.
|
|
m_hRootSystemStore = CertOpenSystemStoreW( 0, L"Root" ) ;
|
|
if( m_hRootSystemStore != nullptr ) {
|
|
if( xmlsecurity::MSCryptoAppliedKeysMngrAdoptTrustedStore( pKeysMngr, m_hRootSystemStore ) < 0 ) {
|
|
CertCloseStore( m_hRootSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
m_hRootSystemStore = nullptr;
|
|
throw uno::RuntimeException() ;
|
|
}
|
|
m_hRootSystemStore = nullptr;
|
|
}
|
|
|
|
//Add system trusted store into the keys manager.
|
|
m_hTrustSystemStore = CertOpenSystemStoreW( 0, L"Trust" ) ;
|
|
if( m_hTrustSystemStore != nullptr ) {
|
|
if( xmlsecurity::MSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, m_hTrustSystemStore ) < 0 ) {
|
|
CertCloseStore( m_hTrustSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
m_hTrustSystemStore = nullptr;
|
|
throw uno::RuntimeException() ;
|
|
}
|
|
m_hTrustSystemStore = nullptr;
|
|
}
|
|
|
|
//Add system CA store into the keys manager.
|
|
m_hCaSystemStore = CertOpenSystemStoreW( 0, L"CA" ) ;
|
|
if( m_hCaSystemStore != nullptr ) {
|
|
if( xmlsecurity::MSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, m_hCaSystemStore ) < 0 ) {
|
|
CertCloseStore( m_hCaSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
m_hCaSystemStore = nullptr;
|
|
throw uno::RuntimeException() ;
|
|
}
|
|
m_hCaSystemStore = nullptr;
|
|
}
|
|
}
|
|
|
|
return pKeysMngr ;
|
|
}
|
|
void SecurityEnvironment_MSCryptImpl::destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) {
|
|
if( pKeysMngr != nullptr ) {
|
|
xmlSecKeysMngrDestroy( pKeysMngr ) ;
|
|
}
|
|
}
|
|
|
|
extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
|
|
com_sun_star_xml_crypto_SecurityEnvironment_get_implementation(
|
|
uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
|
|
{
|
|
return cppu::acquire(new SecurityEnvironment_MSCryptImpl(pCtx));
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|