1418 lines
49 KiB
C++
1418 lines
49 KiB
C++
/*************************************************************************
|
|
*
|
|
* $RCSfile: securityenvironment_mscryptimpl.cxx,v $
|
|
*
|
|
* $Revision: 1.9 $
|
|
*
|
|
* last change: $Author: rt $ $Date: 2005-03-29 13:24:46 $
|
|
*
|
|
* The Contents of this file are made available subject to the terms of
|
|
* either of the following licenses
|
|
*
|
|
* - GNU Lesser General Public License Version 2.1
|
|
* - Sun Industry Standards Source License Version 1.1
|
|
*
|
|
* Sun Microsystems Inc., October, 2000
|
|
*
|
|
* GNU Lesser General Public License Version 2.1
|
|
* =============================================
|
|
* Copyright 2000 by Sun Microsystems, Inc.
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
* MA 02111-1307 USA
|
|
*
|
|
*
|
|
* Sun Industry Standards Source License Version 1.1
|
|
* =================================================
|
|
* The contents of this file are subject to the Sun Industry Standards
|
|
* Source License Version 1.1 (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.openoffice.org/license.html.
|
|
*
|
|
* Software provided under this License is provided on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
|
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
|
|
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
|
|
* See the License for the specific provisions governing your rights and
|
|
* obligations concerning the Software.
|
|
*
|
|
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
|
|
*
|
|
* Copyright: 2000 by Sun Microsystems, Inc.
|
|
*
|
|
* All Rights Reserved.
|
|
*
|
|
* Contributor(s): _______________________________________
|
|
*
|
|
*
|
|
************************************************************************/
|
|
|
|
#ifndef _SAL_CONFIG_H_
|
|
#include <sal/config.h>
|
|
#endif
|
|
|
|
#ifndef _XSECURITYENVIRONMENT_MSCRYPTIMPL_HXX_
|
|
#include "securityenvironment_mscryptimpl.hxx"
|
|
#endif
|
|
|
|
#ifndef _X509CERTIFICATE_NSSIMPL_HXX_
|
|
#include "x509certificate_mscryptimpl.hxx"
|
|
#endif
|
|
|
|
#ifndef _RTL_UUID_H_
|
|
#include <rtl/uuid.h>
|
|
#endif
|
|
|
|
#include "Windows.h"
|
|
#include "WinCrypt.h"
|
|
|
|
#include <xmlsec/xmlsec.h>
|
|
#include <xmlsec/keysmngr.h>
|
|
#include <xmlsec/crypto.h>
|
|
#include <xmlsec/base64.h>
|
|
|
|
#include <xmlsecurity/biginteger.hxx>
|
|
|
|
#include "xmlsec/keysmngr.h"
|
|
#include "xmlsec/mscrypto/akmngr.h"
|
|
|
|
//CP : added by CP
|
|
#include <rtl/locale.h>
|
|
#include <osl/nlsupport.h>
|
|
|
|
#ifndef _OSL_PROCESS_H_
|
|
#include <osl/process.h>
|
|
#endif
|
|
|
|
//CP : end
|
|
|
|
using namespace ::com::sun::star::uno ;
|
|
using namespace ::com::sun::star::lang ;
|
|
using ::com::sun::star::lang::XMultiServiceFactory ;
|
|
using ::com::sun::star::lang::XSingleServiceFactory ;
|
|
using ::rtl::OUString ;
|
|
|
|
using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
|
|
using ::com::sun::star::security::XCertificate ;
|
|
|
|
extern X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert ) ;
|
|
|
|
SecurityEnvironment_MSCryptImpl :: SecurityEnvironment_MSCryptImpl( const Reference< XMultiServiceFactory >& aFactory ) : m_hProv( NULL ) , m_pszContainer( NULL ) , m_hKeyStore( NULL ), m_hCertStore( NULL ), m_tSymKeyList() , m_tPubKeyList() , m_tPriKeyList(), m_xServiceManager( aFactory ), m_bEnableDefault( sal_False ) {
|
|
|
|
}
|
|
|
|
SecurityEnvironment_MSCryptImpl :: ~SecurityEnvironment_MSCryptImpl() {
|
|
|
|
if( m_hProv != NULL ) {
|
|
CryptReleaseContext( m_hProv, 0 ) ;
|
|
m_hProv = NULL ;
|
|
}
|
|
|
|
if( m_pszContainer != NULL ) {
|
|
//TODO: Don't know whether or not it should be released now.
|
|
m_pszContainer = NULL ;
|
|
}
|
|
|
|
if( m_hCertStore != NULL ) {
|
|
CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
|
|
m_hCertStore = NULL ;
|
|
}
|
|
|
|
if( m_hKeyStore != NULL ) {
|
|
CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
|
|
m_hKeyStore = NULL ;
|
|
}
|
|
|
|
if( !m_tSymKeyList.empty() ) {
|
|
std::list< HCRYPTKEY >::iterator symKeyIt ;
|
|
|
|
for( symKeyIt = m_tSymKeyList.begin() ; symKeyIt != m_tSymKeyList.end() ; symKeyIt ++ )
|
|
CryptDestroyKey( *symKeyIt ) ;
|
|
}
|
|
|
|
if( !m_tPubKeyList.empty() ) {
|
|
std::list< HCRYPTKEY >::iterator pubKeyIt ;
|
|
|
|
for( pubKeyIt = m_tPubKeyList.begin() ; pubKeyIt != m_tPubKeyList.end() ; pubKeyIt ++ )
|
|
CryptDestroyKey( *pubKeyIt ) ;
|
|
}
|
|
|
|
if( !m_tPriKeyList.empty() ) {
|
|
std::list< HCRYPTKEY >::iterator priKeyIt ;
|
|
|
|
for( priKeyIt = m_tPriKeyList.begin() ; priKeyIt != m_tPriKeyList.end() ; priKeyIt ++ )
|
|
CryptDestroyKey( *priKeyIt ) ;
|
|
}
|
|
|
|
}
|
|
|
|
/* XInitialization */
|
|
void SAL_CALL SecurityEnvironment_MSCryptImpl :: initialize( const Sequence< Any >& aArguments ) throw( Exception, RuntimeException ) {
|
|
//TODO
|
|
} ;
|
|
|
|
/* XServiceInfo */
|
|
OUString SAL_CALL SecurityEnvironment_MSCryptImpl :: getImplementationName() throw( RuntimeException ) {
|
|
return impl_getImplementationName() ;
|
|
}
|
|
|
|
/* XServiceInfo */
|
|
sal_Bool SAL_CALL SecurityEnvironment_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
|
|
Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
|
|
const OUString* pArray = seqServiceNames.getConstArray() ;
|
|
for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
|
|
if( *( pArray + i ) == serviceName )
|
|
return sal_True ;
|
|
}
|
|
return sal_False ;
|
|
}
|
|
|
|
/* XServiceInfo */
|
|
Sequence< OUString > SAL_CALL SecurityEnvironment_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) {
|
|
return impl_getSupportedServiceNames() ;
|
|
}
|
|
|
|
//Helper for XServiceInfo
|
|
Sequence< OUString > SecurityEnvironment_MSCryptImpl :: impl_getSupportedServiceNames() {
|
|
::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
|
|
Sequence< OUString > seqServiceNames( 1 ) ;
|
|
seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.SecurityEnvironment" ) ;
|
|
return seqServiceNames ;
|
|
}
|
|
|
|
OUString SecurityEnvironment_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) {
|
|
return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_MSCryptImpl" ) ;
|
|
}
|
|
|
|
//Helper for registry
|
|
Reference< XInterface > SAL_CALL SecurityEnvironment_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
|
|
return Reference< XInterface >( *new SecurityEnvironment_MSCryptImpl( aServiceManager ) ) ;
|
|
}
|
|
|
|
Reference< XSingleServiceFactory > SecurityEnvironment_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
|
|
return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
|
|
}
|
|
|
|
/* XUnoTunnel */
|
|
sal_Int64 SAL_CALL SecurityEnvironment_MSCryptImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier )
|
|
throw( RuntimeException )
|
|
{
|
|
if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) {
|
|
return ( sal_Int64 )this ;
|
|
}
|
|
return 0 ;
|
|
}
|
|
|
|
/* XUnoTunnel extension */
|
|
const Sequence< sal_Int8>& SecurityEnvironment_MSCryptImpl :: getUnoTunnelId() {
|
|
static Sequence< sal_Int8 >* pSeq = 0 ;
|
|
if( !pSeq ) {
|
|
::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
|
|
if( !pSeq ) {
|
|
static Sequence< sal_Int8> aSeq( 16 ) ;
|
|
rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ;
|
|
pSeq = &aSeq ;
|
|
}
|
|
}
|
|
return *pSeq ;
|
|
}
|
|
|
|
/* XUnoTunnel extension */
|
|
SecurityEnvironment_MSCryptImpl* SecurityEnvironment_MSCryptImpl :: getImplementation( const Reference< XInterface > xObj ) {
|
|
Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ;
|
|
if( xUT.is() ) {
|
|
return ( SecurityEnvironment_MSCryptImpl* )xUT->getSomething( getUnoTunnelId() ) ;
|
|
} else
|
|
return NULL ;
|
|
}
|
|
|
|
/* Native methods */
|
|
HCRYPTPROV SecurityEnvironment_MSCryptImpl :: getCryptoProvider() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
|
|
return m_hProv ;
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl :: setCryptoProvider( HCRYPTPROV aProv ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
|
|
if( m_hProv != NULL ) {
|
|
CryptReleaseContext( m_hProv, 0 ) ;
|
|
m_hProv = NULL ;
|
|
}
|
|
|
|
if( aProv != NULL ) {
|
|
/*- Replaced by direct adopt for WINNT support ----
|
|
if( !CryptContextAddRef( aProv, NULL, NULL ) )
|
|
throw Exception() ;
|
|
else
|
|
m_hProv = aProv ;
|
|
----*/
|
|
m_hProv = aProv ;
|
|
}
|
|
}
|
|
|
|
LPCTSTR SecurityEnvironment_MSCryptImpl :: getKeyContainer() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
|
|
return m_pszContainer ;
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl :: setKeyContainer( LPCTSTR aKeyContainer ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
|
|
//TODO: Don't know whether or not it should be copied.
|
|
m_pszContainer = aKeyContainer ;
|
|
}
|
|
|
|
|
|
HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCryptoSlot() throw( Exception , RuntimeException ) {
|
|
return m_hKeyStore ;
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl :: setCryptoSlot( HCERTSTORE aSlot) throw( Exception , RuntimeException ) {
|
|
if( m_hKeyStore != NULL ) {
|
|
CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
|
|
m_hKeyStore = NULL ;
|
|
}
|
|
|
|
if( aSlot != NULL ) {
|
|
m_hKeyStore = CertDuplicateStore( aSlot ) ;
|
|
}
|
|
}
|
|
|
|
HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCertDb() throw( Exception , RuntimeException ) {
|
|
return m_hCertStore ;
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl :: setCertDb( HCERTSTORE aCertDb ) throw( Exception , RuntimeException ) {
|
|
if( m_hCertStore != NULL ) {
|
|
CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
|
|
m_hCertStore = NULL ;
|
|
}
|
|
|
|
if( aCertDb != NULL ) {
|
|
m_hCertStore = CertDuplicateStore( aCertDb ) ;
|
|
}
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl :: adoptSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) {
|
|
HCRYPTKEY symkey ;
|
|
std::list< HCRYPTKEY >::iterator keyIt ;
|
|
|
|
if( aSymKey != NULL ) {
|
|
//First try to find the key in the list
|
|
for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; keyIt ++ ) {
|
|
if( *keyIt == aSymKey )
|
|
return ;
|
|
}
|
|
|
|
//If we do not find the key in the list, add a new node
|
|
/*- Replaced with directly adopt for WINNT 4.0 support ----
|
|
if( !CryptDuplicateKey( aSymKey, NULL, 0, &symkey ) )
|
|
throw RuntimeException() ;
|
|
----*/
|
|
symkey = aSymKey ;
|
|
|
|
try {
|
|
m_tSymKeyList.push_back( symkey ) ;
|
|
} catch ( Exception& ) {
|
|
CryptDestroyKey( symkey ) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl :: rejectSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) {
|
|
HCRYPTKEY symkey ;
|
|
std::list< HCRYPTKEY >::iterator keyIt ;
|
|
|
|
if( aSymKey != NULL ) {
|
|
for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; keyIt ++ ) {
|
|
if( *keyIt == aSymKey ) {
|
|
symkey = *keyIt ;
|
|
CryptDestroyKey( symkey ) ;
|
|
m_tSymKeyList.erase( keyIt ) ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getSymKey( unsigned int position ) throw( Exception , RuntimeException ) {
|
|
HCRYPTKEY symkey ;
|
|
std::list< HCRYPTKEY >::iterator keyIt ;
|
|
unsigned int pos ;
|
|
|
|
symkey = NULL ;
|
|
for( pos = 0, keyIt = m_tSymKeyList.begin() ; pos < position && keyIt != m_tSymKeyList.end() ; pos ++ , keyIt ++ ) ;
|
|
|
|
if( pos == position && keyIt != m_tSymKeyList.end() )
|
|
symkey = *keyIt ;
|
|
|
|
return symkey ;
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl :: adoptPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) {
|
|
HCRYPTKEY pubkey ;
|
|
std::list< HCRYPTKEY >::iterator keyIt ;
|
|
|
|
if( aPubKey != NULL ) {
|
|
//First try to find the key in the list
|
|
for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; keyIt ++ ) {
|
|
if( *keyIt == aPubKey )
|
|
return ;
|
|
}
|
|
|
|
//If we do not find the key in the list, add a new node
|
|
/*- Replaced with directly adopt for WINNT 4.0 support ----
|
|
if( !CryptDuplicateKey( aPubKey, NULL, 0, &pubkey ) )
|
|
throw RuntimeException() ;
|
|
----*/
|
|
pubkey = aPubKey ;
|
|
|
|
try {
|
|
m_tPubKeyList.push_back( pubkey ) ;
|
|
} catch ( Exception& ) {
|
|
CryptDestroyKey( pubkey ) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl :: rejectPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) {
|
|
HCRYPTKEY pubkey ;
|
|
std::list< HCRYPTKEY >::iterator keyIt ;
|
|
|
|
if( aPubKey != NULL ) {
|
|
for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; keyIt ++ ) {
|
|
if( *keyIt == aPubKey ) {
|
|
pubkey = *keyIt ;
|
|
CryptDestroyKey( pubkey ) ;
|
|
m_tPubKeyList.erase( keyIt ) ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPubKey( unsigned int position ) throw( Exception , RuntimeException ) {
|
|
HCRYPTKEY pubkey ;
|
|
std::list< HCRYPTKEY >::iterator keyIt ;
|
|
unsigned int pos ;
|
|
|
|
pubkey = NULL ;
|
|
for( pos = 0, keyIt = m_tPubKeyList.begin() ; pos < position && keyIt != m_tPubKeyList.end() ; pos ++ , keyIt ++ ) ;
|
|
|
|
if( pos == position && keyIt != m_tPubKeyList.end() )
|
|
pubkey = *keyIt ;
|
|
|
|
return pubkey ;
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl :: adoptPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) {
|
|
HCRYPTKEY prikey ;
|
|
std::list< HCRYPTKEY >::iterator keyIt ;
|
|
|
|
if( aPriKey != NULL ) {
|
|
//First try to find the key in the list
|
|
for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; keyIt ++ ) {
|
|
if( *keyIt == aPriKey )
|
|
return ;
|
|
}
|
|
|
|
//If we do not find the key in the list, add a new node
|
|
/*- Replaced with directly adopt for WINNT 4.0 support ----
|
|
if( !CryptDuplicateKey( aPriKey, NULL, 0, &prikey ) )
|
|
throw RuntimeException() ;
|
|
----*/
|
|
prikey = aPriKey ;
|
|
|
|
try {
|
|
m_tPriKeyList.push_back( prikey ) ;
|
|
} catch ( Exception& ) {
|
|
CryptDestroyKey( prikey ) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl :: rejectPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) {
|
|
HCRYPTKEY prikey ;
|
|
std::list< HCRYPTKEY >::iterator keyIt ;
|
|
|
|
if( aPriKey != NULL ) {
|
|
for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; keyIt ++ ) {
|
|
if( *keyIt == aPriKey ) {
|
|
prikey = *keyIt ;
|
|
CryptDestroyKey( prikey ) ;
|
|
m_tPriKeyList.erase( keyIt ) ;
|
|
break ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPriKey( unsigned int position ) throw( SecurityException , RuntimeException ) {
|
|
HCRYPTKEY prikey ;
|
|
std::list< HCRYPTKEY >::iterator keyIt ;
|
|
unsigned int pos ;
|
|
|
|
prikey = NULL ;
|
|
for( pos = 0, keyIt = m_tPriKeyList.begin() ; pos < position && keyIt != m_tPriKeyList.end() ; pos ++ , keyIt ++ ) ;
|
|
|
|
if( pos == position && keyIt != m_tPriKeyList.end() )
|
|
prikey = *keyIt ;
|
|
|
|
return prikey ;
|
|
}
|
|
|
|
//Methods from XSecurityEnvironment
|
|
Sequence< Reference < XCertificate > > SecurityEnvironment_MSCryptImpl :: getPersonalCertificates() throw( SecurityException , RuntimeException )
|
|
{
|
|
sal_Int32 length ;
|
|
X509Certificate_MSCryptImpl* xcert ;
|
|
std::list< X509Certificate_MSCryptImpl* > certsList ;
|
|
PCCERT_CONTEXT pCertContext ;
|
|
|
|
//firstly, we try to find private keys in given key store.
|
|
if( m_hKeyStore != NULL ) {
|
|
pCertContext = NULL ;
|
|
while( pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext ) ) {
|
|
xcert = MswcryCertContextToXCert( pCertContext ) ;
|
|
if( xcert != NULL )
|
|
certsList.push_back( xcert ) ;
|
|
}
|
|
}
|
|
|
|
//secondly, we try to find certificate from registered private keys.
|
|
if( !m_tPriKeyList.empty() ) {
|
|
//TODO: Don't know whether or not it is necessary ans possible.
|
|
}
|
|
|
|
//Thirdly, we try to find certificate from system default key store.
|
|
if( m_bEnableDefault ) {
|
|
HCERTSTORE hSystemKeyStore ;
|
|
DWORD dwKeySpec;
|
|
HCRYPTPROV hCryptProv;
|
|
|
|
/*
|
|
hSystemKeyStore = CertOpenStore(
|
|
CERT_STORE_PROV_SYSTEM ,
|
|
0 ,
|
|
NULL ,
|
|
CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG | CERT_STORE_OPEN_EXISTING_FLAG ,
|
|
L"MY"
|
|
) ;
|
|
*/
|
|
hSystemKeyStore = CertOpenSystemStore( 0, "MY" ) ;
|
|
if( hSystemKeyStore != NULL ) {
|
|
pCertContext = NULL ;
|
|
while( pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext ) ) {
|
|
// Add By CP for checking whether the certificate is a personal certificate or not.
|
|
if(!(CryptAcquireCertificatePrivateKey(pCertContext,
|
|
CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
|
|
NULL,
|
|
&hCryptProv,
|
|
&dwKeySpec,
|
|
NULL)))
|
|
{
|
|
// Not Privatekey found. SKIP this one; By CP
|
|
continue;
|
|
}
|
|
// then TODO : Check the personal cert is valid or not.
|
|
|
|
// end CP
|
|
xcert = MswcryCertContextToXCert( pCertContext ) ;
|
|
if( xcert != NULL )
|
|
certsList.push_back( xcert ) ;
|
|
}
|
|
}
|
|
|
|
CertCloseStore( hSystemKeyStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
|
|
length = certsList.size() ;
|
|
if( length != 0 ) {
|
|
int i ;
|
|
std::list< X509Certificate_MSCryptImpl* >::iterator xcertIt ;
|
|
Sequence< Reference< XCertificate > > certSeq( length ) ;
|
|
|
|
for( i = 0, xcertIt = certsList.begin(); xcertIt != certsList.end(); xcertIt ++, i++ ) {
|
|
certSeq[i] = *xcertIt ;
|
|
}
|
|
|
|
return certSeq ;
|
|
}
|
|
|
|
return Sequence< Reference< XCertificate > >() ;
|
|
}
|
|
|
|
|
|
Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: getCertificate( const OUString& issuerName, const Sequence< sal_Int8 >& serialNumber ) throw( SecurityException , RuntimeException ) {
|
|
unsigned int i ;
|
|
sal_Int8 found = 0 ;
|
|
LPSTR pszName ;
|
|
X509Certificate_MSCryptImpl *xcert = NULL ;
|
|
PCCERT_CONTEXT pCertContext = NULL ;
|
|
HCERTSTORE hCertStore = NULL ;
|
|
CRYPT_INTEGER_BLOB cryptSerialNumber ;
|
|
CERT_INFO certInfo ;
|
|
|
|
// By CP , for correct encoding
|
|
sal_uInt16 encoding ;
|
|
rtl_Locale *pLocale = NULL ;
|
|
osl_getProcessLocale( &pLocale ) ;
|
|
encoding = osl_getTextEncodingFromLocale( pLocale ) ;
|
|
// CP end
|
|
|
|
//Create cert info from issue and serial
|
|
rtl::OString oissuer = rtl::OUStringToOString( issuerName , encoding ) ;
|
|
pszName = ( char* )oissuer.getStr() ;
|
|
|
|
if( ! ( CertStrToName(
|
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
|
|
pszName ,
|
|
CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG,
|
|
NULL ,
|
|
NULL ,
|
|
&certInfo.Issuer.cbData, NULL ) )
|
|
) {
|
|
return NULL ;
|
|
}
|
|
|
|
if( !( certInfo.Issuer.pbData = ( BYTE* )malloc( certInfo.Issuer.cbData ) ) ) {
|
|
throw RuntimeException() ;
|
|
}
|
|
|
|
if( ! ( CertStrToName(
|
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
|
|
pszName ,
|
|
CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG,
|
|
NULL ,
|
|
( BYTE* )certInfo.Issuer.pbData ,
|
|
&certInfo.Issuer.cbData, NULL ) )
|
|
) {
|
|
free( certInfo.Issuer.pbData ) ;
|
|
return NULL ;
|
|
}
|
|
|
|
//Get the SerialNumber
|
|
cryptSerialNumber.cbData = serialNumber.getLength() ;
|
|
if( !( cryptSerialNumber.pbData = ( BYTE* )malloc( cryptSerialNumber.cbData ) ) )
|
|
{
|
|
free( certInfo.Issuer.pbData ) ;
|
|
throw 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 == NULL) continue ;
|
|
hCertStore = m_hKeyStore ;
|
|
break;
|
|
case 1:
|
|
if(m_hCertStore == NULL) continue ;
|
|
hCertStore = m_hCertStore ;
|
|
break;
|
|
case 2:
|
|
hCertStore = CertOpenSystemStore( 0, "MY" ) ;
|
|
if(hCertStore == NULL || !m_bEnableDefault) continue ;
|
|
break;
|
|
case 3:
|
|
hCertStore = CertOpenSystemStore( 0, "Root" ) ;
|
|
if(hCertStore == NULL || !m_bEnableDefault) continue ;
|
|
break;
|
|
case 4:
|
|
hCertStore = CertOpenSystemStore( 0, "Trust" ) ;
|
|
if(hCertStore == NULL || !m_bEnableDefault) continue ;
|
|
break;
|
|
case 5:
|
|
hCertStore = CertOpenSystemStore( 0, "CA" ) ;
|
|
if(hCertStore == NULL || !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,
|
|
NULL
|
|
) ;
|
|
|
|
if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
if( pCertContext != NULL ) break ; // Found the certificate.
|
|
|
|
}
|
|
|
|
if( cryptSerialNumber.pbData ) free( cryptSerialNumber.pbData ) ;
|
|
if( certInfo.Issuer.pbData ) free( certInfo.Issuer.pbData ) ;
|
|
|
|
if( pCertContext != NULL ) {
|
|
xcert = MswcryCertContextToXCert( pCertContext ) ;
|
|
if( pCertContext ) CertFreeCertificateContext( pCertContext ) ;
|
|
} else {
|
|
xcert = NULL ;
|
|
}
|
|
|
|
return xcert ;
|
|
}
|
|
|
|
Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: getCertificate( const OUString& issuerName, const OUString& serialNumber ) throw( SecurityException , RuntimeException ) {
|
|
Sequence< sal_Int8 > serial = numericStringToBigInteger( serialNumber ) ;
|
|
return getCertificate( issuerName, serial ) ;
|
|
}
|
|
|
|
Sequence< Reference < XCertificate > > SecurityEnvironment_MSCryptImpl :: buildCertificatePath( const Reference< XCertificate >& begin ) throw( SecurityException , RuntimeException ) {
|
|
PCCERT_CHAIN_CONTEXT pChainContext ;
|
|
PCCERT_CONTEXT pCertContext ;
|
|
const X509Certificate_MSCryptImpl* xcert ;
|
|
|
|
CERT_ENHKEY_USAGE enhKeyUsage ;
|
|
CERT_USAGE_MATCH certUsage ;
|
|
CERT_CHAIN_PARA chainPara ;
|
|
|
|
enhKeyUsage.cUsageIdentifier = 0 ;
|
|
enhKeyUsage.rgpszUsageIdentifier = NULL ;
|
|
certUsage.dwType = USAGE_MATCH_TYPE_AND ;
|
|
certUsage.Usage = enhKeyUsage ;
|
|
chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ;
|
|
chainPara.RequestedUsage = certUsage ;
|
|
|
|
Reference< XUnoTunnel > xCertTunnel( begin, UNO_QUERY ) ;
|
|
if( !xCertTunnel.is() ) {
|
|
throw RuntimeException() ;
|
|
}
|
|
|
|
xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ;
|
|
if( xcert == NULL ) {
|
|
throw RuntimeException() ;
|
|
}
|
|
|
|
pCertContext = xcert->getMswcryCert() ;
|
|
|
|
pChainContext = NULL ;
|
|
|
|
//Above all, we try to find the certificate in the given key store.
|
|
if( pCertContext != NULL ) {
|
|
if( !CertGetCertificateChain(
|
|
NULL ,
|
|
pCertContext ,
|
|
NULL ,
|
|
m_hKeyStore ,
|
|
&chainPara ,
|
|
0 ,
|
|
NULL ,
|
|
&pChainContext
|
|
)
|
|
) {
|
|
pChainContext = NULL ;
|
|
}
|
|
}
|
|
|
|
//firstly, we try to find the certificate in the given cert store.
|
|
if( pCertContext != NULL && pChainContext != NULL ) {
|
|
if( !CertGetCertificateChain(
|
|
NULL ,
|
|
pCertContext ,
|
|
NULL ,
|
|
m_hCertStore ,
|
|
&chainPara ,
|
|
0 ,
|
|
NULL ,
|
|
&pChainContext
|
|
)
|
|
) {
|
|
pChainContext = NULL ;
|
|
}
|
|
}
|
|
|
|
//Secondly, we try to find certificate from system default system store.
|
|
if( pCertContext != NULL && pChainContext != NULL ) {
|
|
HCERTSTORE hCollectionStore ;
|
|
|
|
hCollectionStore = CertOpenStore(
|
|
CERT_STORE_PROV_COLLECTION ,
|
|
0 ,
|
|
NULL ,
|
|
0 ,
|
|
NULL
|
|
) ;
|
|
|
|
if( hCollectionStore != NULL ) {
|
|
HCERTSTORE hSystemStore ;
|
|
|
|
//Add system key store to the collection.
|
|
hSystemStore = CertOpenSystemStore( 0, "MY" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
hSystemStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
1
|
|
) ;
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
|
|
//Add system root store to the collection.
|
|
hSystemStore = CertOpenSystemStore( 0, "Root" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
hSystemStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
2
|
|
) ;
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
|
|
//Add system trust store to the collection.
|
|
hSystemStore = CertOpenSystemStore( 0, "Trust" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
hSystemStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
3
|
|
) ;
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
|
|
//Add system CA store to the collection.
|
|
hSystemStore = CertOpenSystemStore( 0, "CA" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
hSystemStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
4
|
|
) ;
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
|
|
//Get the chain from the collection store.
|
|
if( !CertGetCertificateChain(
|
|
NULL ,
|
|
pCertContext ,
|
|
NULL ,
|
|
hCollectionStore ,
|
|
&chainPara ,
|
|
0 ,
|
|
NULL ,
|
|
&pChainContext
|
|
)
|
|
) {
|
|
pChainContext = NULL ;
|
|
}
|
|
|
|
CertCloseStore( hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
}
|
|
|
|
if( pChainContext != NULL && pChainContext->cChain > 0 ) {
|
|
PCCERT_CONTEXT pCertInChain ;
|
|
PCERT_SIMPLE_CHAIN pCertChain ;
|
|
X509Certificate_MSCryptImpl* pCert ;
|
|
|
|
pCertChain = pChainContext->rgpChain[0] ;
|
|
if( pCertChain->cElement ) {
|
|
Sequence< 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 = NULL ;
|
|
|
|
if( pCertInChain != NULL ) {
|
|
pCert = MswcryCertContextToXCert( pCertInChain ) ;
|
|
if( pCert != NULL )
|
|
xCertChain[i] = pCert ;
|
|
}
|
|
}
|
|
|
|
CertFreeCertificateChain( pChainContext ) ;
|
|
pChainContext = NULL ;
|
|
|
|
return xCertChain ;
|
|
}
|
|
}
|
|
|
|
return NULL ;
|
|
}
|
|
|
|
Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromRaw( const Sequence< sal_Int8 >& rawCertificate ) throw( SecurityException , RuntimeException ) {
|
|
X509Certificate_MSCryptImpl* xcert ;
|
|
|
|
if( rawCertificate.getLength() > 0 ) {
|
|
xcert = new X509Certificate_MSCryptImpl() ;
|
|
if( xcert == NULL )
|
|
throw RuntimeException() ;
|
|
|
|
xcert->setRawCert( rawCertificate ) ;
|
|
} else {
|
|
xcert = NULL ;
|
|
}
|
|
|
|
return xcert ;
|
|
}
|
|
|
|
Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromAscii( const OUString& asciiCertificate ) throw( SecurityException , RuntimeException ) {
|
|
xmlChar* chCert ;
|
|
xmlSecSize certSize ;
|
|
|
|
rtl::OString oscert = rtl::OUStringToOString( asciiCertificate , RTL_TEXTENCODING_ASCII_US ) ;
|
|
|
|
chCert = xmlStrndup( ( const xmlChar* )oscert.getStr(), ( int )oscert.getLength() ) ;
|
|
|
|
certSize = xmlSecBase64Decode( chCert, ( xmlSecByte* )chCert, xmlStrlen( chCert ) ) ;
|
|
|
|
Sequence< sal_Int8 > rawCert( certSize ) ;
|
|
for( unsigned int i = 0 ; i < certSize ; i ++ )
|
|
rawCert[i] = *( chCert + i ) ;
|
|
|
|
xmlFree( chCert ) ;
|
|
|
|
return createCertificateFromRaw( rawCert ) ;
|
|
}
|
|
|
|
sal_Int32 SecurityEnvironment_MSCryptImpl :: verifyCertificate( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& aCert ) throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException ) {
|
|
sal_Int32 validity ;
|
|
PCCERT_CHAIN_CONTEXT pChainContext ;
|
|
PCCERT_CONTEXT pCertContext ;
|
|
const X509Certificate_MSCryptImpl* xcert ;
|
|
FILETIME fTime ;
|
|
DWORD chainStatus ;
|
|
|
|
CERT_ENHKEY_USAGE enhKeyUsage ;
|
|
CERT_USAGE_MATCH certUsage ;
|
|
CERT_CHAIN_PARA chainPara ;
|
|
|
|
Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ;
|
|
if( !xCertTunnel.is() ) {
|
|
throw RuntimeException() ;
|
|
}
|
|
|
|
xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ;
|
|
if( xcert == NULL ) {
|
|
throw RuntimeException() ;
|
|
}
|
|
|
|
pCertContext = xcert->getMswcryCert() ;
|
|
|
|
//Get the current system time.
|
|
GetSystemTimeAsFileTime( &fTime ) ;
|
|
|
|
/*-
|
|
* Build and validate the certificate
|
|
*/
|
|
enhKeyUsage.cUsageIdentifier = 0 ;
|
|
enhKeyUsage.rgpszUsageIdentifier = NULL ;
|
|
certUsage.dwType = USAGE_MATCH_TYPE_AND ;
|
|
certUsage.Usage = enhKeyUsage ;
|
|
chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ;
|
|
chainPara.RequestedUsage = certUsage ;
|
|
|
|
pChainContext = NULL ;
|
|
|
|
//Above all, we try to find the certificate in the given key store.
|
|
if( pCertContext != NULL ) {
|
|
if( !CertGetCertificateChain(
|
|
NULL ,
|
|
pCertContext ,
|
|
&fTime ,
|
|
m_hKeyStore ,
|
|
&chainPara ,
|
|
CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_TIMESTAMP_TIME ,
|
|
NULL ,
|
|
&pChainContext
|
|
)
|
|
) {
|
|
pChainContext = NULL ;
|
|
}
|
|
}
|
|
|
|
//firstly, we try to find the certificate in the given cert store.
|
|
if( pCertContext != NULL && pChainContext != NULL ) {
|
|
if( !CertGetCertificateChain(
|
|
NULL ,
|
|
pCertContext ,
|
|
&fTime ,
|
|
m_hCertStore ,
|
|
&chainPara ,
|
|
CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_TIMESTAMP_TIME ,
|
|
NULL ,
|
|
&pChainContext
|
|
)
|
|
) {
|
|
pChainContext = NULL ;
|
|
}
|
|
}
|
|
|
|
//Secondly, we try to find certificate from system default system store.
|
|
if( pCertContext != NULL && pChainContext != NULL ) {
|
|
HCERTSTORE hCollectionStore ;
|
|
|
|
hCollectionStore = CertOpenStore(
|
|
CERT_STORE_PROV_COLLECTION ,
|
|
0 ,
|
|
NULL ,
|
|
0 ,
|
|
NULL
|
|
) ;
|
|
|
|
if( hCollectionStore != NULL ) {
|
|
HCERTSTORE hSystemStore ;
|
|
|
|
//Add system key store to the collection.
|
|
hSystemStore = CertOpenSystemStore( 0, "MY" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
hSystemStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
1
|
|
) ;
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
|
|
//Add system root store to the collection.
|
|
hSystemStore = CertOpenSystemStore( 0, "Root" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
hSystemStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
2
|
|
) ;
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
|
|
//Add system trust store to the collection.
|
|
hSystemStore = CertOpenSystemStore( 0, "Trust" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
hSystemStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
3
|
|
) ;
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
|
|
//Add system CA store to the collection.
|
|
hSystemStore = CertOpenSystemStore( 0, "CA" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
hSystemStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
4
|
|
) ;
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
|
|
//Get the chain from the collection store.
|
|
if( !CertGetCertificateChain(
|
|
NULL ,
|
|
pCertContext ,
|
|
&fTime ,
|
|
hCollectionStore ,
|
|
&chainPara ,
|
|
CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_TIMESTAMP_TIME ,
|
|
NULL ,
|
|
&pChainContext
|
|
)
|
|
) {
|
|
pChainContext = NULL ;
|
|
}
|
|
|
|
CertCloseStore( hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
}
|
|
|
|
if( pChainContext != NULL ) {
|
|
chainStatus = pChainContext->TrustStatus.dwErrorStatus ;
|
|
CertFreeCertificateChain( pChainContext ) ;
|
|
|
|
if( chainStatus == CERT_TRUST_NO_ERROR ) {
|
|
validity = !( ::com::sun::star::security::CertificateValidity::INVALID ) ;
|
|
} else {
|
|
validity = ::com::sun::star::security::CertificateValidity::INVALID ;
|
|
}
|
|
|
|
if( ( chainStatus & CERT_TRUST_IS_NOT_TIME_VALID ) == CERT_TRUST_IS_NOT_TIME_VALID ) {
|
|
validity |= ::com::sun::star::security::CertificateValidity::TIMEOUT ;
|
|
}
|
|
|
|
if( ( chainStatus & CERT_TRUST_IS_NOT_TIME_NESTED ) == CERT_TRUST_IS_NOT_TIME_NESTED ) {
|
|
validity |= ::com::sun::star::security::CertificateValidity::TIMEOUT ;
|
|
}
|
|
|
|
if( ( chainStatus & CERT_TRUST_IS_REVOKED ) == CERT_TRUST_IS_REVOKED ) {
|
|
validity |= ::com::sun::star::security::CertificateValidity::REVOKED ;
|
|
}
|
|
|
|
if( ( chainStatus & CERT_TRUST_IS_OFFLINE_REVOCATION ) == CERT_TRUST_IS_OFFLINE_REVOCATION ) {
|
|
validity |= ::com::sun::star::security::CertificateValidity::REVOKED ;
|
|
}
|
|
|
|
if( ( chainStatus & CERT_TRUST_IS_NOT_SIGNATURE_VALID ) == CERT_TRUST_IS_NOT_SIGNATURE_VALID ) {
|
|
validity |= ::com::sun::star::security::CertificateValidity::SIGNATURE_INVALID ;
|
|
}
|
|
|
|
if( ( chainStatus & CERT_TRUST_IS_UNTRUSTED_ROOT ) == CERT_TRUST_IS_UNTRUSTED_ROOT ) {
|
|
validity |= ::com::sun::star::security::CertificateValidity::ROOT_UNTRUSTED ;
|
|
}
|
|
|
|
if( ( chainStatus & CERT_TRUST_REVOCATION_STATUS_UNKNOWN ) == CERT_TRUST_REVOCATION_STATUS_UNKNOWN ) {
|
|
validity |= ::com::sun::star::security::CertificateValidity::UNKNOWN_REVOKATION ;
|
|
}
|
|
|
|
if( ( chainStatus & CERT_TRUST_INVALID_EXTENSION ) == CERT_TRUST_INVALID_EXTENSION ) {
|
|
validity |= ::com::sun::star::security::CertificateValidity::EXTENSION_INVALID ;
|
|
}
|
|
|
|
if( ( chainStatus & CERT_TRUST_IS_PARTIAL_CHAIN ) == CERT_TRUST_IS_PARTIAL_CHAIN ) {
|
|
validity |= ::com::sun::star::security::CertificateValidity::CHAIN_INCOMPLETE ;
|
|
}
|
|
} else {
|
|
validity = ::com::sun::star::security::CertificateValidity::INVALID ;
|
|
}
|
|
|
|
return validity ;
|
|
}
|
|
|
|
sal_Int32 SecurityEnvironment_MSCryptImpl :: getCertificateCharacters( const ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificate >& aCert ) throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException ) {
|
|
sal_Int32 characters ;
|
|
PCCERT_CONTEXT pCertContext ;
|
|
const X509Certificate_MSCryptImpl* xcert ;
|
|
|
|
Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ;
|
|
if( !xCertTunnel.is() ) {
|
|
throw RuntimeException() ;
|
|
}
|
|
|
|
xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ;
|
|
if( xcert == NULL ) {
|
|
throw 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 |= ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ;
|
|
} else {
|
|
characters &= ~ ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ;
|
|
}
|
|
|
|
//Secondly, make sentence whether or not the cert has a private key.
|
|
{
|
|
BOOL fCallerFreeProv ;
|
|
DWORD dwKeySpec ;
|
|
HCRYPTPROV hProv ;
|
|
if( CryptAcquireCertificatePrivateKey( pCertContext ,
|
|
0 ,
|
|
NULL ,
|
|
&( hProv ) ,
|
|
&( dwKeySpec ) ,
|
|
&( fCallerFreeProv ) )
|
|
) {
|
|
characters |= ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ;
|
|
|
|
if( hProv != NULL && fCallerFreeProv )
|
|
CryptReleaseContext( hProv, 0 ) ;
|
|
} else {
|
|
characters &= ~ ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ;
|
|
}
|
|
}
|
|
|
|
//Thirdly, make sentence whether or not the cert is trusted.
|
|
{
|
|
HCERTSTORE hCollectionStore ;
|
|
PCCERT_CONTEXT pTempCert ;
|
|
|
|
hCollectionStore = CertOpenStore(
|
|
CERT_STORE_PROV_COLLECTION ,
|
|
0 ,
|
|
NULL ,
|
|
0 ,
|
|
NULL
|
|
) ;
|
|
|
|
if( hCollectionStore != NULL ) {
|
|
HCERTSTORE hSystemStore ;
|
|
|
|
//Add system key store to the collection.
|
|
hSystemStore = CertOpenSystemStore( 0, "MY" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
hSystemStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
1
|
|
) ;
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
|
|
//Add system root store to the collection.
|
|
hSystemStore = CertOpenSystemStore( 0, "Root" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
hSystemStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
2
|
|
) ;
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
|
|
//Add system trust store to the collection.
|
|
hSystemStore = CertOpenSystemStore( 0, "Trust" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
CertAddStoreToCollection (
|
|
hCollectionStore ,
|
|
hSystemStore ,
|
|
CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
|
|
3
|
|
) ;
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
}
|
|
|
|
//Find the cert in the collection store.
|
|
pTempCert = CertFindCertificateInStore(
|
|
hCollectionStore ,
|
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
|
|
0 ,
|
|
CERT_FIND_SUBJECT_NAME,
|
|
&( pCertContext->pCertInfo->Subject ) ,
|
|
NULL
|
|
) ;
|
|
|
|
if( pTempCert != NULL && CertCompareCertificate( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, pCertContext->pCertInfo, pTempCert->pCertInfo ) ) {
|
|
characters |= ::com::sun::star::security::CertificateCharacters::TRUSTED ;
|
|
} else {
|
|
characters &= ~ ::com::sun::star::security::CertificateCharacters::TRUSTED ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return characters ;
|
|
}
|
|
|
|
void SecurityEnvironment_MSCryptImpl :: enableDefaultCrypt( sal_Bool enable ) throw( Exception, RuntimeException ) {
|
|
m_bEnableDefault = enable ;
|
|
}
|
|
|
|
sal_Bool SecurityEnvironment_MSCryptImpl :: defaultEnabled() throw( Exception, RuntimeException ) {
|
|
return m_bEnableDefault ;
|
|
}
|
|
|
|
X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert )
|
|
{
|
|
X509Certificate_MSCryptImpl* xcert ;
|
|
|
|
if( cert != NULL ) {
|
|
xcert = new X509Certificate_MSCryptImpl() ;
|
|
if( xcert != NULL ) {
|
|
xcert->setMswcryCert( cert ) ;
|
|
}
|
|
} else {
|
|
xcert = NULL ;
|
|
}
|
|
|
|
return xcert ;
|
|
}
|
|
|
|
::rtl::OUString SecurityEnvironment_MSCryptImpl::getSecurityEnvironmentInformation() throw( ::com::sun::star::uno::RuntimeException )
|
|
{
|
|
return rtl::OUString::createFromAscii("Microsoft Crypto API");
|
|
}
|
|
|
|
/* Native methods */
|
|
xmlSecKeysMngrPtr SecurityEnvironment_MSCryptImpl :: createKeysManager() throw( Exception, RuntimeException ) {
|
|
|
|
unsigned int i ;
|
|
HCRYPTKEY symKey ;
|
|
HCRYPTKEY pubKey ;
|
|
HCRYPTKEY priKey ;
|
|
xmlSecKeysMngrPtr pKeysMngr = NULL ;
|
|
|
|
/*-
|
|
* The following lines is based on the of xmlsec-mscrypto crypto engine
|
|
*/
|
|
pKeysMngr = xmlSecMSCryptoAppliedKeysMngrCreate( m_hKeyStore , m_hCertStore ) ;
|
|
if( pKeysMngr == NULL )
|
|
throw RuntimeException() ;
|
|
|
|
/*-
|
|
* Adopt symmetric key into keys manager
|
|
*/
|
|
for( i = 0 ; ( symKey = getSymKey( i ) ) != NULL ; i ++ ) {
|
|
if( xmlSecMSCryptoAppliedKeysMngrSymKeyLoad( pKeysMngr, symKey ) < 0 ) {
|
|
throw RuntimeException() ;
|
|
}
|
|
}
|
|
|
|
/*-
|
|
* Adopt asymmetric public key into keys manager
|
|
*/
|
|
for( i = 0 ; ( pubKey = getPubKey( i ) ) != NULL ; i ++ ) {
|
|
if( xmlSecMSCryptoAppliedKeysMngrPubKeyLoad( pKeysMngr, pubKey ) < 0 ) {
|
|
throw RuntimeException() ;
|
|
}
|
|
}
|
|
|
|
/*-
|
|
* Adopt asymmetric private key into keys manager
|
|
*/
|
|
for( i = 0 ; ( priKey = getPriKey( i ) ) != NULL ; i ++ ) {
|
|
if( xmlSecMSCryptoAppliedKeysMngrPriKeyLoad( pKeysMngr, priKey ) < 0 ) {
|
|
throw RuntimeException() ;
|
|
}
|
|
}
|
|
|
|
/*-
|
|
* Adopt system default certificate store.
|
|
*/
|
|
if( defaultEnabled() ) {
|
|
HCERTSTORE hSystemStore ;
|
|
|
|
//Add system key store into the keys manager.
|
|
hSystemStore = CertOpenSystemStore( 0, "MY" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
if( xmlSecMSCryptoAppliedKeysMngrAdoptKeyStore( pKeysMngr, hSystemStore ) < 0 ) {
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
throw RuntimeException() ;
|
|
}
|
|
}
|
|
|
|
//Add system root store into the keys manager.
|
|
hSystemStore = CertOpenSystemStore( 0, "Root" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
if( xmlSecMSCryptoAppliedKeysMngrAdoptTrustedStore( pKeysMngr, hSystemStore ) < 0 ) {
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
throw RuntimeException() ;
|
|
}
|
|
}
|
|
|
|
//Add system trusted store into the keys manager.
|
|
hSystemStore = CertOpenSystemStore( 0, "Trust" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, hSystemStore ) < 0 ) {
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
throw RuntimeException() ;
|
|
}
|
|
}
|
|
|
|
//Add system CA store into the keys manager.
|
|
hSystemStore = CertOpenSystemStore( 0, "CA" ) ;
|
|
if( hSystemStore != NULL ) {
|
|
if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, hSystemStore ) < 0 ) {
|
|
CertCloseStore( hSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
|
|
throw RuntimeException() ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return pKeysMngr ;
|
|
}
|
|
void SecurityEnvironment_MSCryptImpl :: destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) throw( Exception, RuntimeException ) {
|
|
if( pKeysMngr != NULL ) {
|
|
xmlSecKeysMngrDestroy( pKeysMngr ) ;
|
|
}
|
|
}
|