106b3ce53SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
306b3ce53SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
406b3ce53SAndrew Rist * or more contributor license agreements. See the NOTICE file
506b3ce53SAndrew Rist * distributed with this work for additional information
606b3ce53SAndrew Rist * regarding copyright ownership. The ASF licenses this file
706b3ce53SAndrew Rist * to you under the Apache License, Version 2.0 (the
806b3ce53SAndrew Rist * "License"); you may not use this file except in compliance
906b3ce53SAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
1106b3ce53SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
1306b3ce53SAndrew Rist * Unless required by applicable law or agreed to in writing,
1406b3ce53SAndrew Rist * software distributed under the License is distributed on an
1506b3ce53SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1606b3ce53SAndrew Rist * KIND, either express or implied. See the License for the
1706b3ce53SAndrew Rist * specific language governing permissions and limitations
1806b3ce53SAndrew Rist * under the License.
19cdf0e10cSrcweir *
2006b3ce53SAndrew Rist *************************************************************/
2106b3ce53SAndrew Rist
2206b3ce53SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_xmlsecurity.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #ifdef _MSC_VER
28cdf0e10cSrcweir #pragma warning(push,1)
29cdf0e10cSrcweir #endif
30cdf0e10cSrcweir #include "Windows.h"
31cdf0e10cSrcweir #include "WinCrypt.h"
32cdf0e10cSrcweir #ifdef _MSC_VER
33cdf0e10cSrcweir #pragma warning(pop)
34cdf0e10cSrcweir #endif
35cdf0e10cSrcweir #include <sal/config.h>
36cdf0e10cSrcweir #include <osl/thread.h>
37cdf0e10cSrcweir #include "securityenvironment_mscryptimpl.hxx"
38cdf0e10cSrcweir
39cdf0e10cSrcweir #ifndef _X509CERTIFICATE_NSSIMPL_HXX_
40cdf0e10cSrcweir #include "x509certificate_mscryptimpl.hxx"
41cdf0e10cSrcweir #endif
42cdf0e10cSrcweir #include <rtl/uuid.h>
43cdf0e10cSrcweir
44cdf0e10cSrcweir #include <xmlsec/xmlsec.h>
45cdf0e10cSrcweir #include <xmlsec/keysmngr.h>
46cdf0e10cSrcweir #include <xmlsec/crypto.h>
47cdf0e10cSrcweir #include <xmlsec/base64.h>
48cdf0e10cSrcweir
49cdf0e10cSrcweir #include <xmlsecurity/biginteger.hxx>
50cdf0e10cSrcweir
51cdf0e10cSrcweir #include "xmlsec/keysmngr.h"
52cdf0e10cSrcweir #include "xmlsec/mscrypto/akmngr.h"
53cdf0e10cSrcweir
54cdf0e10cSrcweir //CP : added by CP
55cdf0e10cSrcweir #include <rtl/locale.h>
56cdf0e10cSrcweir #include <osl/nlsupport.h>
57cdf0e10cSrcweir #include <osl/process.h>
58cdf0e10cSrcweir
59cdf0e10cSrcweir //CP : end
60cdf0e10cSrcweir #include <rtl/memory.h>
61cdf0e10cSrcweir
62cdf0e10cSrcweir #include "../diagnose.hxx"
63cdf0e10cSrcweir
64cdf0e10cSrcweir using namespace xmlsecurity;
65cdf0e10cSrcweir using namespace ::com::sun::star::uno ;
66cdf0e10cSrcweir using namespace ::com::sun::star::lang ;
67cdf0e10cSrcweir using ::com::sun::star::lang::XMultiServiceFactory ;
68cdf0e10cSrcweir using ::com::sun::star::lang::XSingleServiceFactory ;
69cdf0e10cSrcweir using ::rtl::OUString ;
70cdf0e10cSrcweir
71cdf0e10cSrcweir using ::com::sun::star::xml::crypto::XSecurityEnvironment ;
72cdf0e10cSrcweir using ::com::sun::star::security::XCertificate ;
73cdf0e10cSrcweir namespace css = ::com::sun::star;
74cdf0e10cSrcweir
75cdf0e10cSrcweir extern X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert ) ;
76cdf0e10cSrcweir
77cdf0e10cSrcweir struct CertErrorToString{
78cdf0e10cSrcweir DWORD error;
79cdf0e10cSrcweir char * name;
80cdf0e10cSrcweir };
81cdf0e10cSrcweir
82cdf0e10cSrcweir CertErrorToString arErrStrings[] =
83cdf0e10cSrcweir {
84cdf0e10cSrcweir { 0x00000000, "CERT_TRUST_NO_ERROR"},
85cdf0e10cSrcweir { 0x00000001, "CERT_TRUST_IS_NOT_TIME_VALID"},
86cdf0e10cSrcweir { 0x00000002, "CERT_TRUST_IS_NOT_TIME_NESTED"},
87cdf0e10cSrcweir { 0x00000004, "CERT_TRUST_IS_REVOKED" },
88cdf0e10cSrcweir { 0x00000008, "CERT_TRUST_IS_NOT_SIGNATURE_VALID" },
89cdf0e10cSrcweir { 0x00000010, "CERT_TRUST_IS_NOT_SIGNATURE_VALID"},
90cdf0e10cSrcweir { 0x00000020, "CERT_TRUST_IS_UNTRUSTED_ROOT"},
91cdf0e10cSrcweir { 0x00000040, "CERT_TRUST_REVOCATION_STATUS_UNKNOWN"},
92cdf0e10cSrcweir { 0x00000080, "CERT_TRUST_IS_CYCLIC"},
93cdf0e10cSrcweir { 0x00000100, "CERT_TRUST_INVALID_EXTENSION"},
94cdf0e10cSrcweir { 0x00000200, "CERT_TRUST_INVALID_POLICY_CONSTRAINTS"},
95cdf0e10cSrcweir { 0x00000400, "CERT_TRUST_INVALID_BASIC_CONSTRAINTS"},
96cdf0e10cSrcweir { 0x00000800, "CERT_TRUST_INVALID_NAME_CONSTRAINTS"},
97cdf0e10cSrcweir { 0x00001000, "CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT"},
98cdf0e10cSrcweir { 0x00002000, "CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT"},
99cdf0e10cSrcweir { 0x00004000, "CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT"},
100cdf0e10cSrcweir { 0x00008000, "CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT"},
101cdf0e10cSrcweir { 0x01000000, "CERT_TRUST_IS_OFFLINE_REVOCATION"},
102cdf0e10cSrcweir { 0x02000000, "CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY"},
103cdf0e10cSrcweir { 0x04000000, "CERT_TRUST_IS_EXPLICIT_DISTRUST"},
104cdf0e10cSrcweir { 0x08000000, "CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT"},
105cdf0e10cSrcweir //Chain errors
106cdf0e10cSrcweir { 0x00010000, "CERT_TRUST_IS_PARTIAL_CHAIN"},
107cdf0e10cSrcweir { 0x00020000, "CERT_TRUST_CTL_IS_NOT_TIME_VALID"},
108cdf0e10cSrcweir { 0x00040000, "CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID"},
109cdf0e10cSrcweir { 0x00080000, "CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE"}
110cdf0e10cSrcweir };
111cdf0e10cSrcweir
traceTrustStatus(DWORD err)112cdf0e10cSrcweir void traceTrustStatus(DWORD err)
113cdf0e10cSrcweir {
114cdf0e10cSrcweir int numErrors = sizeof(arErrStrings) / sizeof(CertErrorToString);
115cdf0e10cSrcweir xmlsec_trace("The certificate error status is: ");
116cdf0e10cSrcweir if (err == 0)
117cdf0e10cSrcweir xmlsec_trace("%s", arErrStrings[0].name);
118cdf0e10cSrcweir for (int i = 1; i < numErrors; i++)
119cdf0e10cSrcweir {
120cdf0e10cSrcweir if (arErrStrings[i].error & err)
121cdf0e10cSrcweir xmlsec_trace("%s", arErrStrings[i].name);
122cdf0e10cSrcweir }
123cdf0e10cSrcweir }
124cdf0e10cSrcweir
SecurityEnvironment_MSCryptImpl(const Reference<XMultiServiceFactory> & aFactory)1255ea637d9SJian Fang Zhang 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 ), m_hMySystemStore(NULL), m_hRootSystemStore(NULL), m_hTrustSystemStore(NULL), m_hCaSystemStore(NULL){
126cdf0e10cSrcweir
127cdf0e10cSrcweir }
128cdf0e10cSrcweir
~SecurityEnvironment_MSCryptImpl()129cdf0e10cSrcweir SecurityEnvironment_MSCryptImpl :: ~SecurityEnvironment_MSCryptImpl() {
130cdf0e10cSrcweir
131cdf0e10cSrcweir if( m_hProv != NULL ) {
132cdf0e10cSrcweir CryptReleaseContext( m_hProv, 0 ) ;
133cdf0e10cSrcweir m_hProv = NULL ;
134cdf0e10cSrcweir }
135cdf0e10cSrcweir
136cdf0e10cSrcweir if( m_pszContainer != NULL ) {
137cdf0e10cSrcweir //TODO: Don't know whether or not it should be released now.
138cdf0e10cSrcweir m_pszContainer = NULL ;
139cdf0e10cSrcweir }
140cdf0e10cSrcweir
141cdf0e10cSrcweir if( m_hCertStore != NULL ) {
142cdf0e10cSrcweir CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
143cdf0e10cSrcweir m_hCertStore = NULL ;
144cdf0e10cSrcweir }
145cdf0e10cSrcweir
146cdf0e10cSrcweir if( m_hKeyStore != NULL ) {
147cdf0e10cSrcweir CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
148cdf0e10cSrcweir m_hKeyStore = NULL ;
149cdf0e10cSrcweir }
150cdf0e10cSrcweir
1515ea637d9SJian Fang Zhang //i120675, close the store handles
1525ea637d9SJian Fang Zhang if( m_hMySystemStore != NULL ) {
1535ea637d9SJian Fang Zhang CertCloseStore( m_hMySystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
1545ea637d9SJian Fang Zhang m_hMySystemStore = NULL ;
1555ea637d9SJian Fang Zhang }
1565ea637d9SJian Fang Zhang
1575ea637d9SJian Fang Zhang if( m_hRootSystemStore != NULL ) {
1585ea637d9SJian Fang Zhang CertCloseStore( m_hRootSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
1595ea637d9SJian Fang Zhang m_hRootSystemStore = NULL ;
1605ea637d9SJian Fang Zhang }
1615ea637d9SJian Fang Zhang
1625ea637d9SJian Fang Zhang if( m_hTrustSystemStore != NULL ) {
1635ea637d9SJian Fang Zhang CertCloseStore( m_hTrustSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
1645ea637d9SJian Fang Zhang m_hTrustSystemStore = NULL ;
1655ea637d9SJian Fang Zhang }
1665ea637d9SJian Fang Zhang
1675ea637d9SJian Fang Zhang if( m_hCaSystemStore != NULL ) {
1685ea637d9SJian Fang Zhang CertCloseStore( m_hCaSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
1695ea637d9SJian Fang Zhang m_hCaSystemStore = NULL ;
1705ea637d9SJian Fang Zhang }
1715ea637d9SJian Fang Zhang
172cdf0e10cSrcweir if( !m_tSymKeyList.empty() ) {
173cdf0e10cSrcweir std::list< HCRYPTKEY >::iterator symKeyIt ;
174cdf0e10cSrcweir
175cdf0e10cSrcweir for( symKeyIt = m_tSymKeyList.begin() ; symKeyIt != m_tSymKeyList.end() ; symKeyIt ++ )
176cdf0e10cSrcweir CryptDestroyKey( *symKeyIt ) ;
177cdf0e10cSrcweir }
178cdf0e10cSrcweir
179cdf0e10cSrcweir if( !m_tPubKeyList.empty() ) {
180cdf0e10cSrcweir std::list< HCRYPTKEY >::iterator pubKeyIt ;
181cdf0e10cSrcweir
182cdf0e10cSrcweir for( pubKeyIt = m_tPubKeyList.begin() ; pubKeyIt != m_tPubKeyList.end() ; pubKeyIt ++ )
183cdf0e10cSrcweir CryptDestroyKey( *pubKeyIt ) ;
184cdf0e10cSrcweir }
185cdf0e10cSrcweir
186cdf0e10cSrcweir if( !m_tPriKeyList.empty() ) {
187cdf0e10cSrcweir std::list< HCRYPTKEY >::iterator priKeyIt ;
188cdf0e10cSrcweir
189cdf0e10cSrcweir for( priKeyIt = m_tPriKeyList.begin() ; priKeyIt != m_tPriKeyList.end() ; priKeyIt ++ )
190cdf0e10cSrcweir CryptDestroyKey( *priKeyIt ) ;
191cdf0e10cSrcweir }
192cdf0e10cSrcweir
193cdf0e10cSrcweir }
194cdf0e10cSrcweir
195cdf0e10cSrcweir /* XInitialization */
initialize(const Sequence<Any> &)196cdf0e10cSrcweir void SAL_CALL SecurityEnvironment_MSCryptImpl :: initialize( const Sequence< Any >& /*aArguments*/ ) throw( Exception, RuntimeException ) {
197cdf0e10cSrcweir //TODO
198cdf0e10cSrcweir } ;
199cdf0e10cSrcweir
200cdf0e10cSrcweir /* XServiceInfo */
getImplementationName()201cdf0e10cSrcweir OUString SAL_CALL SecurityEnvironment_MSCryptImpl :: getImplementationName() throw( RuntimeException ) {
202cdf0e10cSrcweir return impl_getImplementationName() ;
203cdf0e10cSrcweir }
204cdf0e10cSrcweir
205cdf0e10cSrcweir /* XServiceInfo */
supportsService(const OUString & serviceName)206cdf0e10cSrcweir sal_Bool SAL_CALL SecurityEnvironment_MSCryptImpl :: supportsService( const OUString& serviceName) throw( RuntimeException ) {
207cdf0e10cSrcweir Sequence< OUString > seqServiceNames = getSupportedServiceNames() ;
208cdf0e10cSrcweir const OUString* pArray = seqServiceNames.getConstArray() ;
209cdf0e10cSrcweir for( sal_Int32 i = 0 ; i < seqServiceNames.getLength() ; i ++ ) {
210cdf0e10cSrcweir if( *( pArray + i ) == serviceName )
211cdf0e10cSrcweir return sal_True ;
212cdf0e10cSrcweir }
213cdf0e10cSrcweir return sal_False ;
214cdf0e10cSrcweir }
215cdf0e10cSrcweir
216cdf0e10cSrcweir /* XServiceInfo */
getSupportedServiceNames()217cdf0e10cSrcweir Sequence< OUString > SAL_CALL SecurityEnvironment_MSCryptImpl :: getSupportedServiceNames() throw( RuntimeException ) {
218cdf0e10cSrcweir return impl_getSupportedServiceNames() ;
219cdf0e10cSrcweir }
220cdf0e10cSrcweir
221cdf0e10cSrcweir //Helper for XServiceInfo
impl_getSupportedServiceNames()222cdf0e10cSrcweir Sequence< OUString > SecurityEnvironment_MSCryptImpl :: impl_getSupportedServiceNames() {
223cdf0e10cSrcweir ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
224cdf0e10cSrcweir Sequence< OUString > seqServiceNames( 1 ) ;
225cdf0e10cSrcweir seqServiceNames.getArray()[0] = OUString::createFromAscii( "com.sun.star.xml.crypto.SecurityEnvironment" ) ;
226cdf0e10cSrcweir return seqServiceNames ;
227cdf0e10cSrcweir }
228cdf0e10cSrcweir
impl_getImplementationName()229cdf0e10cSrcweir OUString SecurityEnvironment_MSCryptImpl :: impl_getImplementationName() throw( RuntimeException ) {
230cdf0e10cSrcweir return OUString::createFromAscii( "com.sun.star.xml.security.bridge.xmlsec.SecurityEnvironment_MSCryptImpl" ) ;
231cdf0e10cSrcweir }
232cdf0e10cSrcweir
233cdf0e10cSrcweir //Helper for registry
impl_createInstance(const Reference<XMultiServiceFactory> & aServiceManager)234cdf0e10cSrcweir Reference< XInterface > SAL_CALL SecurityEnvironment_MSCryptImpl :: impl_createInstance( const Reference< XMultiServiceFactory >& aServiceManager ) throw( RuntimeException ) {
235cdf0e10cSrcweir return Reference< XInterface >( *new SecurityEnvironment_MSCryptImpl( aServiceManager ) ) ;
236cdf0e10cSrcweir }
237cdf0e10cSrcweir
impl_createFactory(const Reference<XMultiServiceFactory> & aServiceManager)238cdf0e10cSrcweir Reference< XSingleServiceFactory > SecurityEnvironment_MSCryptImpl :: impl_createFactory( const Reference< XMultiServiceFactory >& aServiceManager ) {
239cdf0e10cSrcweir return ::cppu::createSingleFactory( aServiceManager , impl_getImplementationName() , impl_createInstance , impl_getSupportedServiceNames() ) ;
240cdf0e10cSrcweir }
241cdf0e10cSrcweir
242cdf0e10cSrcweir /* XUnoTunnel */
getSomething(const Sequence<sal_Int8> & aIdentifier)243cdf0e10cSrcweir sal_Int64 SAL_CALL SecurityEnvironment_MSCryptImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier )
244cdf0e10cSrcweir throw( RuntimeException )
245cdf0e10cSrcweir {
246cdf0e10cSrcweir if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) {
247cdf0e10cSrcweir return ( sal_Int64 )this ;
248cdf0e10cSrcweir }
249cdf0e10cSrcweir return 0 ;
250cdf0e10cSrcweir }
251cdf0e10cSrcweir
252cdf0e10cSrcweir /* XUnoTunnel extension */
getUnoTunnelId()253cdf0e10cSrcweir const Sequence< sal_Int8>& SecurityEnvironment_MSCryptImpl :: getUnoTunnelId() {
254cdf0e10cSrcweir static Sequence< sal_Int8 >* pSeq = 0 ;
255cdf0e10cSrcweir if( !pSeq ) {
256cdf0e10cSrcweir ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
257cdf0e10cSrcweir if( !pSeq ) {
258cdf0e10cSrcweir static Sequence< sal_Int8> aSeq( 16 ) ;
259cdf0e10cSrcweir rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ;
260cdf0e10cSrcweir pSeq = &aSeq ;
261cdf0e10cSrcweir }
262cdf0e10cSrcweir }
263cdf0e10cSrcweir return *pSeq ;
264cdf0e10cSrcweir }
265cdf0e10cSrcweir
266cdf0e10cSrcweir /* XUnoTunnel extension */
getImplementation(const Reference<XInterface> xObj)267cdf0e10cSrcweir SecurityEnvironment_MSCryptImpl* SecurityEnvironment_MSCryptImpl :: getImplementation( const Reference< XInterface > xObj ) {
268cdf0e10cSrcweir Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ;
269cdf0e10cSrcweir if( xUT.is() ) {
270cdf0e10cSrcweir return ( SecurityEnvironment_MSCryptImpl* )xUT->getSomething( getUnoTunnelId() ) ;
271cdf0e10cSrcweir } else
272cdf0e10cSrcweir return NULL ;
273cdf0e10cSrcweir }
274cdf0e10cSrcweir
275cdf0e10cSrcweir /* Native methods */
getCryptoProvider()276cdf0e10cSrcweir HCRYPTPROV SecurityEnvironment_MSCryptImpl :: getCryptoProvider() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
277cdf0e10cSrcweir return m_hProv ;
278cdf0e10cSrcweir }
279cdf0e10cSrcweir
setCryptoProvider(HCRYPTPROV aProv)280cdf0e10cSrcweir void SecurityEnvironment_MSCryptImpl :: setCryptoProvider( HCRYPTPROV aProv ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
281cdf0e10cSrcweir if( m_hProv != NULL ) {
282cdf0e10cSrcweir CryptReleaseContext( m_hProv, 0 ) ;
283cdf0e10cSrcweir m_hProv = NULL ;
284cdf0e10cSrcweir }
285cdf0e10cSrcweir
286cdf0e10cSrcweir if( aProv != NULL ) {
287cdf0e10cSrcweir /*- Replaced by direct adopt for WINNT support ----
288cdf0e10cSrcweir if( !CryptContextAddRef( aProv, NULL, NULL ) )
289cdf0e10cSrcweir throw Exception() ;
290cdf0e10cSrcweir else
291cdf0e10cSrcweir m_hProv = aProv ;
292cdf0e10cSrcweir ----*/
293cdf0e10cSrcweir m_hProv = aProv ;
294cdf0e10cSrcweir }
295cdf0e10cSrcweir }
296cdf0e10cSrcweir
getKeyContainer()297cdf0e10cSrcweir LPCTSTR SecurityEnvironment_MSCryptImpl :: getKeyContainer() throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
298cdf0e10cSrcweir return m_pszContainer ;
299cdf0e10cSrcweir }
300cdf0e10cSrcweir
setKeyContainer(LPCTSTR aKeyContainer)301cdf0e10cSrcweir void SecurityEnvironment_MSCryptImpl :: setKeyContainer( LPCTSTR aKeyContainer ) throw( ::com::sun::star::uno::Exception , ::com::sun::star::uno::RuntimeException ) {
302cdf0e10cSrcweir //TODO: Don't know whether or not it should be copied.
303cdf0e10cSrcweir m_pszContainer = aKeyContainer ;
304cdf0e10cSrcweir }
305cdf0e10cSrcweir
306cdf0e10cSrcweir
getCryptoSlot()307cdf0e10cSrcweir HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCryptoSlot() throw( Exception , RuntimeException ) {
308cdf0e10cSrcweir return m_hKeyStore ;
309cdf0e10cSrcweir }
310cdf0e10cSrcweir
setCryptoSlot(HCERTSTORE aSlot)311cdf0e10cSrcweir void SecurityEnvironment_MSCryptImpl :: setCryptoSlot( HCERTSTORE aSlot) throw( Exception , RuntimeException ) {
312cdf0e10cSrcweir if( m_hKeyStore != NULL ) {
313cdf0e10cSrcweir CertCloseStore( m_hKeyStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
314cdf0e10cSrcweir m_hKeyStore = NULL ;
315cdf0e10cSrcweir }
316cdf0e10cSrcweir
317cdf0e10cSrcweir if( aSlot != NULL ) {
318cdf0e10cSrcweir m_hKeyStore = CertDuplicateStore( aSlot ) ;
319cdf0e10cSrcweir }
320cdf0e10cSrcweir }
321cdf0e10cSrcweir
getCertDb()322cdf0e10cSrcweir HCERTSTORE SecurityEnvironment_MSCryptImpl :: getCertDb() throw( Exception , RuntimeException ) {
323cdf0e10cSrcweir return m_hCertStore ;
324cdf0e10cSrcweir }
325cdf0e10cSrcweir
setCertDb(HCERTSTORE aCertDb)326cdf0e10cSrcweir void SecurityEnvironment_MSCryptImpl :: setCertDb( HCERTSTORE aCertDb ) throw( Exception , RuntimeException ) {
327cdf0e10cSrcweir if( m_hCertStore != NULL ) {
328cdf0e10cSrcweir CertCloseStore( m_hCertStore, CERT_CLOSE_STORE_FORCE_FLAG ) ;
329cdf0e10cSrcweir m_hCertStore = NULL ;
330cdf0e10cSrcweir }
331cdf0e10cSrcweir
332cdf0e10cSrcweir if( aCertDb != NULL ) {
333cdf0e10cSrcweir m_hCertStore = CertDuplicateStore( aCertDb ) ;
334cdf0e10cSrcweir }
335cdf0e10cSrcweir }
336cdf0e10cSrcweir
adoptSymKey(HCRYPTKEY aSymKey)337cdf0e10cSrcweir void SecurityEnvironment_MSCryptImpl :: adoptSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) {
338cdf0e10cSrcweir HCRYPTKEY symkey ;
339cdf0e10cSrcweir std::list< HCRYPTKEY >::iterator keyIt ;
340cdf0e10cSrcweir
341cdf0e10cSrcweir if( aSymKey != NULL ) {
342cdf0e10cSrcweir //First try to find the key in the list
343cdf0e10cSrcweir for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; keyIt ++ ) {
344cdf0e10cSrcweir if( *keyIt == aSymKey )
345cdf0e10cSrcweir return ;
346cdf0e10cSrcweir }
347cdf0e10cSrcweir
348cdf0e10cSrcweir //If we do not find the key in the list, add a new node
349cdf0e10cSrcweir /*- Replaced with directly adopt for WINNT 4.0 support ----
350cdf0e10cSrcweir if( !CryptDuplicateKey( aSymKey, NULL, 0, &symkey ) )
351cdf0e10cSrcweir throw RuntimeException() ;
352cdf0e10cSrcweir ----*/
353cdf0e10cSrcweir symkey = aSymKey ;
354cdf0e10cSrcweir
355cdf0e10cSrcweir try {
356cdf0e10cSrcweir m_tSymKeyList.push_back( symkey ) ;
357cdf0e10cSrcweir } catch ( Exception& ) {
358cdf0e10cSrcweir CryptDestroyKey( symkey ) ;
359cdf0e10cSrcweir }
360cdf0e10cSrcweir }
361cdf0e10cSrcweir }
362cdf0e10cSrcweir
rejectSymKey(HCRYPTKEY aSymKey)363cdf0e10cSrcweir void SecurityEnvironment_MSCryptImpl :: rejectSymKey( HCRYPTKEY aSymKey ) throw( Exception , RuntimeException ) {
364cdf0e10cSrcweir HCRYPTKEY symkey ;
365cdf0e10cSrcweir std::list< HCRYPTKEY >::iterator keyIt ;
366cdf0e10cSrcweir
367cdf0e10cSrcweir if( aSymKey != NULL ) {
368cdf0e10cSrcweir for( keyIt = m_tSymKeyList.begin() ; keyIt != m_tSymKeyList.end() ; keyIt ++ ) {
369cdf0e10cSrcweir if( *keyIt == aSymKey ) {
370cdf0e10cSrcweir symkey = *keyIt ;
371cdf0e10cSrcweir CryptDestroyKey( symkey ) ;
372cdf0e10cSrcweir m_tSymKeyList.erase( keyIt ) ;
373cdf0e10cSrcweir break ;
374cdf0e10cSrcweir }
375cdf0e10cSrcweir }
376cdf0e10cSrcweir }
377cdf0e10cSrcweir }
378cdf0e10cSrcweir
getSymKey(unsigned int position)379cdf0e10cSrcweir HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getSymKey( unsigned int position ) throw( Exception , RuntimeException ) {
380cdf0e10cSrcweir HCRYPTKEY symkey ;
381cdf0e10cSrcweir std::list< HCRYPTKEY >::iterator keyIt ;
382cdf0e10cSrcweir unsigned int pos ;
383cdf0e10cSrcweir
384cdf0e10cSrcweir symkey = NULL ;
385cdf0e10cSrcweir for( pos = 0, keyIt = m_tSymKeyList.begin() ; pos < position && keyIt != m_tSymKeyList.end() ; pos ++ , keyIt ++ ) ;
386cdf0e10cSrcweir
387cdf0e10cSrcweir if( pos == position && keyIt != m_tSymKeyList.end() )
388cdf0e10cSrcweir symkey = *keyIt ;
389cdf0e10cSrcweir
390cdf0e10cSrcweir return symkey ;
391cdf0e10cSrcweir }
392cdf0e10cSrcweir
adoptPubKey(HCRYPTKEY aPubKey)393cdf0e10cSrcweir void SecurityEnvironment_MSCryptImpl :: adoptPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) {
394cdf0e10cSrcweir HCRYPTKEY pubkey ;
395cdf0e10cSrcweir std::list< HCRYPTKEY >::iterator keyIt ;
396cdf0e10cSrcweir
397cdf0e10cSrcweir if( aPubKey != NULL ) {
398cdf0e10cSrcweir //First try to find the key in the list
399cdf0e10cSrcweir for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; keyIt ++ ) {
400cdf0e10cSrcweir if( *keyIt == aPubKey )
401cdf0e10cSrcweir return ;
402cdf0e10cSrcweir }
403cdf0e10cSrcweir
404cdf0e10cSrcweir //If we do not find the key in the list, add a new node
405cdf0e10cSrcweir /*- Replaced with directly adopt for WINNT 4.0 support ----
406cdf0e10cSrcweir if( !CryptDuplicateKey( aPubKey, NULL, 0, &pubkey ) )
407cdf0e10cSrcweir throw RuntimeException() ;
408cdf0e10cSrcweir ----*/
409cdf0e10cSrcweir pubkey = aPubKey ;
410cdf0e10cSrcweir
411cdf0e10cSrcweir try {
412cdf0e10cSrcweir m_tPubKeyList.push_back( pubkey ) ;
413cdf0e10cSrcweir } catch ( Exception& ) {
414cdf0e10cSrcweir CryptDestroyKey( pubkey ) ;
415cdf0e10cSrcweir }
416cdf0e10cSrcweir }
417cdf0e10cSrcweir }
418cdf0e10cSrcweir
rejectPubKey(HCRYPTKEY aPubKey)419cdf0e10cSrcweir void SecurityEnvironment_MSCryptImpl :: rejectPubKey( HCRYPTKEY aPubKey ) throw( Exception , RuntimeException ) {
420cdf0e10cSrcweir HCRYPTKEY pubkey ;
421cdf0e10cSrcweir std::list< HCRYPTKEY >::iterator keyIt ;
422cdf0e10cSrcweir
423cdf0e10cSrcweir if( aPubKey != NULL ) {
424cdf0e10cSrcweir for( keyIt = m_tPubKeyList.begin() ; keyIt != m_tPubKeyList.end() ; keyIt ++ ) {
425cdf0e10cSrcweir if( *keyIt == aPubKey ) {
426cdf0e10cSrcweir pubkey = *keyIt ;
427cdf0e10cSrcweir CryptDestroyKey( pubkey ) ;
428cdf0e10cSrcweir m_tPubKeyList.erase( keyIt ) ;
429cdf0e10cSrcweir break ;
430cdf0e10cSrcweir }
431cdf0e10cSrcweir }
432cdf0e10cSrcweir }
433cdf0e10cSrcweir }
434cdf0e10cSrcweir
getPubKey(unsigned int position)435cdf0e10cSrcweir HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPubKey( unsigned int position ) throw( Exception , RuntimeException ) {
436cdf0e10cSrcweir HCRYPTKEY pubkey ;
437cdf0e10cSrcweir std::list< HCRYPTKEY >::iterator keyIt ;
438cdf0e10cSrcweir unsigned int pos ;
439cdf0e10cSrcweir
440cdf0e10cSrcweir pubkey = NULL ;
441cdf0e10cSrcweir for( pos = 0, keyIt = m_tPubKeyList.begin() ; pos < position && keyIt != m_tPubKeyList.end() ; pos ++ , keyIt ++ ) ;
442cdf0e10cSrcweir
443cdf0e10cSrcweir if( pos == position && keyIt != m_tPubKeyList.end() )
444cdf0e10cSrcweir pubkey = *keyIt ;
445cdf0e10cSrcweir
446cdf0e10cSrcweir return pubkey ;
447cdf0e10cSrcweir }
448cdf0e10cSrcweir
adoptPriKey(HCRYPTKEY aPriKey)449cdf0e10cSrcweir void SecurityEnvironment_MSCryptImpl :: adoptPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) {
450cdf0e10cSrcweir HCRYPTKEY prikey ;
451cdf0e10cSrcweir std::list< HCRYPTKEY >::iterator keyIt ;
452cdf0e10cSrcweir
453cdf0e10cSrcweir if( aPriKey != NULL ) {
454cdf0e10cSrcweir //First try to find the key in the list
455cdf0e10cSrcweir for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; keyIt ++ ) {
456cdf0e10cSrcweir if( *keyIt == aPriKey )
457cdf0e10cSrcweir return ;
458cdf0e10cSrcweir }
459cdf0e10cSrcweir
460cdf0e10cSrcweir //If we do not find the key in the list, add a new node
461cdf0e10cSrcweir /*- Replaced with directly adopt for WINNT 4.0 support ----
462cdf0e10cSrcweir if( !CryptDuplicateKey( aPriKey, NULL, 0, &prikey ) )
463cdf0e10cSrcweir throw RuntimeException() ;
464cdf0e10cSrcweir ----*/
465cdf0e10cSrcweir prikey = aPriKey ;
466cdf0e10cSrcweir
467cdf0e10cSrcweir try {
468cdf0e10cSrcweir m_tPriKeyList.push_back( prikey ) ;
469cdf0e10cSrcweir } catch ( Exception& ) {
470cdf0e10cSrcweir CryptDestroyKey( prikey ) ;
471cdf0e10cSrcweir }
472cdf0e10cSrcweir }
473cdf0e10cSrcweir }
474cdf0e10cSrcweir
rejectPriKey(HCRYPTKEY aPriKey)475cdf0e10cSrcweir void SecurityEnvironment_MSCryptImpl :: rejectPriKey( HCRYPTKEY aPriKey ) throw( Exception , RuntimeException ) {
476cdf0e10cSrcweir HCRYPTKEY prikey ;
477cdf0e10cSrcweir std::list< HCRYPTKEY >::iterator keyIt ;
478cdf0e10cSrcweir
479cdf0e10cSrcweir if( aPriKey != NULL ) {
480cdf0e10cSrcweir for( keyIt = m_tPriKeyList.begin() ; keyIt != m_tPriKeyList.end() ; keyIt ++ ) {
481cdf0e10cSrcweir if( *keyIt == aPriKey ) {
482cdf0e10cSrcweir prikey = *keyIt ;
483cdf0e10cSrcweir CryptDestroyKey( prikey ) ;
484cdf0e10cSrcweir m_tPriKeyList.erase( keyIt ) ;
485cdf0e10cSrcweir break ;
486cdf0e10cSrcweir }
487cdf0e10cSrcweir }
488cdf0e10cSrcweir }
489cdf0e10cSrcweir }
490cdf0e10cSrcweir
getPriKey(unsigned int position)491cdf0e10cSrcweir HCRYPTKEY SecurityEnvironment_MSCryptImpl :: getPriKey( unsigned int position ) throw( Exception , RuntimeException ) {
492cdf0e10cSrcweir HCRYPTKEY prikey ;
493cdf0e10cSrcweir std::list< HCRYPTKEY >::iterator keyIt ;
494cdf0e10cSrcweir unsigned int pos ;
495cdf0e10cSrcweir
496cdf0e10cSrcweir prikey = NULL ;
497cdf0e10cSrcweir for( pos = 0, keyIt = m_tPriKeyList.begin() ; pos < position && keyIt != m_tPriKeyList.end() ; pos ++ , keyIt ++ ) ;
498cdf0e10cSrcweir
499cdf0e10cSrcweir if( pos == position && keyIt != m_tPriKeyList.end() )
500cdf0e10cSrcweir prikey = *keyIt ;
501cdf0e10cSrcweir
502cdf0e10cSrcweir return prikey ;
503cdf0e10cSrcweir }
504cdf0e10cSrcweir
505cdf0e10cSrcweir //Methods from XSecurityEnvironment
getPersonalCertificates()506cdf0e10cSrcweir Sequence< Reference < XCertificate > > SecurityEnvironment_MSCryptImpl :: getPersonalCertificates() throw( SecurityException , RuntimeException )
507cdf0e10cSrcweir {
508cdf0e10cSrcweir sal_Int32 length ;
509cdf0e10cSrcweir X509Certificate_MSCryptImpl* xcert ;
510cdf0e10cSrcweir std::list< X509Certificate_MSCryptImpl* > certsList ;
511cdf0e10cSrcweir PCCERT_CONTEXT pCertContext = NULL;
512cdf0e10cSrcweir
513cdf0e10cSrcweir //firstly, we try to find private keys in given key store.
514cdf0e10cSrcweir if( m_hKeyStore != NULL ) {
515cdf0e10cSrcweir pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext );
516cdf0e10cSrcweir while (pCertContext)
517cdf0e10cSrcweir {
518cdf0e10cSrcweir xcert = MswcryCertContextToXCert( pCertContext ) ;
519cdf0e10cSrcweir if( xcert != NULL )
520cdf0e10cSrcweir certsList.push_back( xcert ) ;
521cdf0e10cSrcweir pCertContext = CertEnumCertificatesInStore( m_hKeyStore, pCertContext );
522cdf0e10cSrcweir }
523cdf0e10cSrcweir }
524cdf0e10cSrcweir
525cdf0e10cSrcweir //secondly, we try to find certificate from registered private keys.
526cdf0e10cSrcweir if( !m_tPriKeyList.empty() ) {
527cdf0e10cSrcweir //TODO: Don't know whether or not it is necessary ans possible.
528cdf0e10cSrcweir }
529cdf0e10cSrcweir
530cdf0e10cSrcweir //Thirdly, we try to find certificate from system default key store.
531cdf0e10cSrcweir if( m_bEnableDefault ) {
532cdf0e10cSrcweir HCERTSTORE hSystemKeyStore ;
533cdf0e10cSrcweir DWORD dwKeySpec;
534cdf0e10cSrcweir HCRYPTPROV hCryptProv;
535cdf0e10cSrcweir
536cdf0e10cSrcweir /*
537cdf0e10cSrcweir hSystemKeyStore = CertOpenStore(
538cdf0e10cSrcweir CERT_STORE_PROV_SYSTEM ,
539cdf0e10cSrcweir 0 ,
540cdf0e10cSrcweir NULL ,
541cdf0e10cSrcweir CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG | CERT_STORE_OPEN_EXISTING_FLAG ,
542cdf0e10cSrcweir L"MY"
543cdf0e10cSrcweir ) ;
544cdf0e10cSrcweir */
545cdf0e10cSrcweir hSystemKeyStore = CertOpenSystemStore( 0, "MY" ) ;
546cdf0e10cSrcweir if( hSystemKeyStore != NULL ) {
547cdf0e10cSrcweir pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext );
548cdf0e10cSrcweir while (pCertContext)
549cdf0e10cSrcweir {
550cdf0e10cSrcweir // Add By CP for checking whether the certificate is a personal certificate or not.
551cdf0e10cSrcweir if(!(CryptAcquireCertificatePrivateKey(pCertContext,
552cdf0e10cSrcweir CRYPT_ACQUIRE_COMPARE_KEY_FLAG,
553cdf0e10cSrcweir NULL,
554cdf0e10cSrcweir &hCryptProv,
555cdf0e10cSrcweir &dwKeySpec,
556cdf0e10cSrcweir NULL)))
557cdf0e10cSrcweir {
558cdf0e10cSrcweir // Not Privatekey found. SKIP this one; By CP
559cdf0e10cSrcweir pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext );
560cdf0e10cSrcweir continue;
561cdf0e10cSrcweir }
562cdf0e10cSrcweir // then TODO : Check the personal cert is valid or not.
563cdf0e10cSrcweir
564cdf0e10cSrcweir // end CP
565cdf0e10cSrcweir xcert = MswcryCertContextToXCert( pCertContext ) ;
566cdf0e10cSrcweir if( xcert != NULL )
567cdf0e10cSrcweir certsList.push_back( xcert ) ;
568cdf0e10cSrcweir pCertContext = CertEnumCertificatesInStore( hSystemKeyStore, pCertContext );
569cdf0e10cSrcweir }
570cdf0e10cSrcweir }
571cdf0e10cSrcweir
572cdf0e10cSrcweir CertCloseStore( hSystemKeyStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
573cdf0e10cSrcweir }
574cdf0e10cSrcweir
575cdf0e10cSrcweir length = certsList.size() ;
576cdf0e10cSrcweir if( length != 0 ) {
577cdf0e10cSrcweir int i ;
578cdf0e10cSrcweir std::list< X509Certificate_MSCryptImpl* >::iterator xcertIt ;
579cdf0e10cSrcweir Sequence< Reference< XCertificate > > certSeq( length ) ;
580cdf0e10cSrcweir
581cdf0e10cSrcweir for( i = 0, xcertIt = certsList.begin(); xcertIt != certsList.end(); xcertIt ++, i++ ) {
582cdf0e10cSrcweir certSeq[i] = *xcertIt ;
583cdf0e10cSrcweir }
584cdf0e10cSrcweir
585cdf0e10cSrcweir return certSeq ;
586cdf0e10cSrcweir }
587cdf0e10cSrcweir
588cdf0e10cSrcweir return Sequence< Reference< XCertificate > >() ;
589cdf0e10cSrcweir }
590cdf0e10cSrcweir
591cdf0e10cSrcweir
getCertificate(const OUString & issuerName,const Sequence<sal_Int8> & serialNumber)592cdf0e10cSrcweir Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: getCertificate( const OUString& issuerName, const Sequence< sal_Int8 >& serialNumber ) throw( SecurityException , RuntimeException ) {
593cdf0e10cSrcweir unsigned int i ;
594cdf0e10cSrcweir // sal_Int8 found = 0 ;
595cdf0e10cSrcweir LPSTR pszName ;
596cdf0e10cSrcweir X509Certificate_MSCryptImpl *xcert = NULL ;
597cdf0e10cSrcweir PCCERT_CONTEXT pCertContext = NULL ;
598cdf0e10cSrcweir HCERTSTORE hCertStore = NULL ;
599cdf0e10cSrcweir CRYPT_INTEGER_BLOB cryptSerialNumber ;
600cdf0e10cSrcweir CERT_INFO certInfo ;
601cdf0e10cSrcweir
602cdf0e10cSrcweir // By CP , for correct encoding
603cdf0e10cSrcweir sal_uInt16 encoding ;
604cdf0e10cSrcweir rtl_Locale *pLocale = NULL ;
605cdf0e10cSrcweir osl_getProcessLocale( &pLocale ) ;
606cdf0e10cSrcweir encoding = osl_getTextEncodingFromLocale( pLocale ) ;
607cdf0e10cSrcweir // CP end
608cdf0e10cSrcweir
609cdf0e10cSrcweir //Create cert info from issue and serial
610cdf0e10cSrcweir rtl::OString oissuer = rtl::OUStringToOString( issuerName , encoding ) ;
611cdf0e10cSrcweir pszName = ( char* )oissuer.getStr() ;
612cdf0e10cSrcweir
613cdf0e10cSrcweir if( ! ( CertStrToName(
614cdf0e10cSrcweir X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
615cdf0e10cSrcweir pszName ,
616cdf0e10cSrcweir CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG,
617cdf0e10cSrcweir NULL ,
618cdf0e10cSrcweir NULL ,
619cdf0e10cSrcweir &certInfo.Issuer.cbData, NULL ) )
620cdf0e10cSrcweir ) {
621cdf0e10cSrcweir return NULL ;
622cdf0e10cSrcweir }
623cdf0e10cSrcweir
624cdf0e10cSrcweir certInfo.Issuer.pbData = ( BYTE* )malloc( certInfo.Issuer.cbData );
625cdf0e10cSrcweir if(!certInfo.Issuer.pbData)
626cdf0e10cSrcweir throw RuntimeException() ;
627cdf0e10cSrcweir
628cdf0e10cSrcweir if( ! ( CertStrToName(
629cdf0e10cSrcweir X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
630cdf0e10cSrcweir pszName ,
631cdf0e10cSrcweir CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG,
632cdf0e10cSrcweir NULL ,
633cdf0e10cSrcweir ( BYTE* )certInfo.Issuer.pbData ,
634cdf0e10cSrcweir &certInfo.Issuer.cbData, NULL ) )
635cdf0e10cSrcweir ) {
636cdf0e10cSrcweir free( certInfo.Issuer.pbData ) ;
637cdf0e10cSrcweir return NULL ;
638cdf0e10cSrcweir }
639cdf0e10cSrcweir
640cdf0e10cSrcweir //Get the SerialNumber
641cdf0e10cSrcweir cryptSerialNumber.cbData = serialNumber.getLength() ;
642cdf0e10cSrcweir cryptSerialNumber.pbData = ( BYTE* )malloc( cryptSerialNumber.cbData);
643cdf0e10cSrcweir if (!cryptSerialNumber.pbData)
644cdf0e10cSrcweir {
645cdf0e10cSrcweir free( certInfo.Issuer.pbData ) ;
646cdf0e10cSrcweir throw RuntimeException() ;
647cdf0e10cSrcweir }
648cdf0e10cSrcweir for( i = 0; i < cryptSerialNumber.cbData; i ++ )
649cdf0e10cSrcweir cryptSerialNumber.pbData[i] = serialNumber[ cryptSerialNumber.cbData - i - 1 ] ;
650cdf0e10cSrcweir
651cdf0e10cSrcweir certInfo.SerialNumber.cbData = cryptSerialNumber.cbData ;
652cdf0e10cSrcweir certInfo.SerialNumber.pbData = cryptSerialNumber.pbData ;
653cdf0e10cSrcweir
654cdf0e10cSrcweir // Get the Cert from all store.
655cdf0e10cSrcweir for( i = 0 ; i < 6 ; i ++ )
656cdf0e10cSrcweir {
657cdf0e10cSrcweir switch(i)
658cdf0e10cSrcweir {
659cdf0e10cSrcweir case 0:
660cdf0e10cSrcweir if(m_hKeyStore == NULL) continue ;
661cdf0e10cSrcweir hCertStore = m_hKeyStore ;
662cdf0e10cSrcweir break;
663cdf0e10cSrcweir case 1:
664cdf0e10cSrcweir if(m_hCertStore == NULL) continue ;
665cdf0e10cSrcweir hCertStore = m_hCertStore ;
666cdf0e10cSrcweir break;
667cdf0e10cSrcweir case 2:
668cdf0e10cSrcweir hCertStore = CertOpenSystemStore( 0, "MY" ) ;
669cdf0e10cSrcweir if(hCertStore == NULL || !m_bEnableDefault) continue ;
670cdf0e10cSrcweir break;
671cdf0e10cSrcweir case 3:
672cdf0e10cSrcweir hCertStore = CertOpenSystemStore( 0, "Root" ) ;
673cdf0e10cSrcweir if(hCertStore == NULL || !m_bEnableDefault) continue ;
674cdf0e10cSrcweir break;
675cdf0e10cSrcweir case 4:
676cdf0e10cSrcweir hCertStore = CertOpenSystemStore( 0, "Trust" ) ;
677cdf0e10cSrcweir if(hCertStore == NULL || !m_bEnableDefault) continue ;
678cdf0e10cSrcweir break;
679cdf0e10cSrcweir case 5:
680cdf0e10cSrcweir hCertStore = CertOpenSystemStore( 0, "CA" ) ;
681cdf0e10cSrcweir if(hCertStore == NULL || !m_bEnableDefault) continue ;
682cdf0e10cSrcweir break;
683cdf0e10cSrcweir default:
684cdf0e10cSrcweir i=6;
685cdf0e10cSrcweir continue;
686cdf0e10cSrcweir }
687cdf0e10cSrcweir
688cdf0e10cSrcweir /*******************************************************************************
689cdf0e10cSrcweir * This code reserved for remind us there are another way to find one cert by
690cdf0e10cSrcweir * IssuerName&serialnumber. You can use the code to replaced the function
691cdf0e10cSrcweir * CertFindCertificateInStore IF and ONLY IF you must find one special cert in
692cdf0e10cSrcweir * certStore but can not be found by CertFindCertificateInStore , then , you
693cdf0e10cSrcweir * should also change the same part in libxmlsec/.../src/mscrypto/x509vfy.c#875.
694cdf0e10cSrcweir * By Chandler Peng(chandler.peng@sun.com)
695cdf0e10cSrcweir *****/
696cdf0e10cSrcweir /*******************************************************************************
697cdf0e10cSrcweir pCertContext = NULL ;
698cdf0e10cSrcweir found = 0;
699cdf0e10cSrcweir do{
700cdf0e10cSrcweir // 1. enum the certs has same string in the issuer string.
701cdf0e10cSrcweir pCertContext = CertEnumCertificatesInStore( hCertStore , pCertContext ) ;
702cdf0e10cSrcweir if( pCertContext != NULL )
703cdf0e10cSrcweir {
704cdf0e10cSrcweir // 2. check the cert's issuer name .
705cdf0e10cSrcweir char* issuer = NULL ;
706cdf0e10cSrcweir DWORD cbIssuer = 0 ;
707cdf0e10cSrcweir
708cdf0e10cSrcweir cbIssuer = CertNameToStr(
709cdf0e10cSrcweir X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
710cdf0e10cSrcweir &( pCertContext->pCertInfo->Issuer ),
711cdf0e10cSrcweir CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
712cdf0e10cSrcweir NULL, 0
713cdf0e10cSrcweir ) ;
714cdf0e10cSrcweir
715cdf0e10cSrcweir if( cbIssuer == 0 ) continue ; // discard this cert;
716cdf0e10cSrcweir
717cdf0e10cSrcweir issuer = (char *)malloc( cbIssuer ) ;
718cdf0e10cSrcweir if( issuer == NULL ) // discard this cert;
719cdf0e10cSrcweir {
720cdf0e10cSrcweir free( cryptSerialNumber.pbData) ;
721cdf0e10cSrcweir free( certInfo.Issuer.pbData ) ;
722cdf0e10cSrcweir CertFreeCertificateContext( pCertContext ) ;
723cdf0e10cSrcweir if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
724cdf0e10cSrcweir throw RuntimeException() ;
725cdf0e10cSrcweir }
726cdf0e10cSrcweir
727cdf0e10cSrcweir cbIssuer = CertNameToStr(
728cdf0e10cSrcweir X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
729cdf0e10cSrcweir &( pCertContext->pCertInfo->Issuer ),
730cdf0e10cSrcweir CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
731cdf0e10cSrcweir issuer, cbIssuer
732cdf0e10cSrcweir ) ;
733cdf0e10cSrcweir
734cdf0e10cSrcweir if( cbIssuer <= 0 )
735cdf0e10cSrcweir {
736cdf0e10cSrcweir free( issuer ) ;
737cdf0e10cSrcweir continue ;// discard this cert;
738cdf0e10cSrcweir }
739cdf0e10cSrcweir
740cdf0e10cSrcweir if(strncmp(pszName , issuer , cbIssuer) != 0)
741cdf0e10cSrcweir {
742cdf0e10cSrcweir free( issuer ) ;
743cdf0e10cSrcweir continue ;// discard this cert;
744cdf0e10cSrcweir }
745cdf0e10cSrcweir free( issuer ) ;
746cdf0e10cSrcweir
747cdf0e10cSrcweir // 3. check the serial number.
748cdf0e10cSrcweir if( memcmp( cryptSerialNumber.pbData , pCertContext->pCertInfo->SerialNumber.pbData , cryptSerialNumber.cbData ) != 0 )
749cdf0e10cSrcweir {
750cdf0e10cSrcweir continue ;// discard this cert;
751cdf0e10cSrcweir }
752cdf0e10cSrcweir
753cdf0e10cSrcweir // 4. confirm and break;
754cdf0e10cSrcweir found = 1;
755cdf0e10cSrcweir break ;
756cdf0e10cSrcweir }
757cdf0e10cSrcweir
758cdf0e10cSrcweir }while(pCertContext);
759cdf0e10cSrcweir
760cdf0e10cSrcweir if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
761cdf0e10cSrcweir if( found != 0 ) break; // Found the certificate.
762cdf0e10cSrcweir ********************************************************************************/
763cdf0e10cSrcweir
764cdf0e10cSrcweir pCertContext = CertFindCertificateInStore(
765cdf0e10cSrcweir hCertStore,
766cdf0e10cSrcweir X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
767cdf0e10cSrcweir 0,
768cdf0e10cSrcweir CERT_FIND_SUBJECT_CERT,
769cdf0e10cSrcweir &certInfo,
770cdf0e10cSrcweir NULL
771cdf0e10cSrcweir ) ;
772cdf0e10cSrcweir
773cdf0e10cSrcweir if(i != 0 && i != 1) CertCloseStore( hCertStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
774cdf0e10cSrcweir if( pCertContext != NULL ) break ; // Found the certificate.
775cdf0e10cSrcweir
776cdf0e10cSrcweir }
777cdf0e10cSrcweir
778cdf0e10cSrcweir if( cryptSerialNumber.pbData ) free( cryptSerialNumber.pbData ) ;
779cdf0e10cSrcweir if( certInfo.Issuer.pbData ) free( certInfo.Issuer.pbData ) ;
780cdf0e10cSrcweir
781cdf0e10cSrcweir if( pCertContext != NULL ) {
782cdf0e10cSrcweir xcert = MswcryCertContextToXCert( pCertContext ) ;
783cdf0e10cSrcweir if( pCertContext ) CertFreeCertificateContext( pCertContext ) ;
784cdf0e10cSrcweir } else {
785cdf0e10cSrcweir xcert = NULL ;
786cdf0e10cSrcweir }
787cdf0e10cSrcweir
788cdf0e10cSrcweir return xcert ;
789cdf0e10cSrcweir }
790cdf0e10cSrcweir
getCertificate(const OUString & issuerName,const OUString & serialNumber)791cdf0e10cSrcweir Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: getCertificate( const OUString& issuerName, const OUString& serialNumber ) throw( SecurityException , RuntimeException ) {
792cdf0e10cSrcweir Sequence< sal_Int8 > serial = numericStringToBigInteger( serialNumber ) ;
793cdf0e10cSrcweir return getCertificate( issuerName, serial ) ;
794cdf0e10cSrcweir }
795cdf0e10cSrcweir
buildCertificatePath(const Reference<XCertificate> & begin)796cdf0e10cSrcweir Sequence< Reference < XCertificate > > SecurityEnvironment_MSCryptImpl :: buildCertificatePath( const Reference< XCertificate >& begin ) throw( SecurityException , RuntimeException ) {
797cdf0e10cSrcweir PCCERT_CHAIN_CONTEXT pChainContext ;
798cdf0e10cSrcweir PCCERT_CONTEXT pCertContext ;
799cdf0e10cSrcweir const X509Certificate_MSCryptImpl* xcert ;
800cdf0e10cSrcweir
801cdf0e10cSrcweir CERT_ENHKEY_USAGE enhKeyUsage ;
802cdf0e10cSrcweir CERT_USAGE_MATCH certUsage ;
803cdf0e10cSrcweir CERT_CHAIN_PARA chainPara ;
804cdf0e10cSrcweir
805cdf0e10cSrcweir enhKeyUsage.cUsageIdentifier = 0 ;
806cdf0e10cSrcweir enhKeyUsage.rgpszUsageIdentifier = NULL ;
807cdf0e10cSrcweir certUsage.dwType = USAGE_MATCH_TYPE_AND ;
808cdf0e10cSrcweir certUsage.Usage = enhKeyUsage ;
809cdf0e10cSrcweir chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ;
810cdf0e10cSrcweir chainPara.RequestedUsage = certUsage ;
811cdf0e10cSrcweir
812cdf0e10cSrcweir Reference< XUnoTunnel > xCertTunnel( begin, UNO_QUERY ) ;
813cdf0e10cSrcweir if( !xCertTunnel.is() ) {
814cdf0e10cSrcweir throw RuntimeException() ;
815cdf0e10cSrcweir }
816cdf0e10cSrcweir
817cdf0e10cSrcweir xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ;
818cdf0e10cSrcweir if( xcert == NULL ) {
819cdf0e10cSrcweir throw RuntimeException() ;
820cdf0e10cSrcweir }
821cdf0e10cSrcweir
822cdf0e10cSrcweir pCertContext = xcert->getMswcryCert() ;
823cdf0e10cSrcweir
824cdf0e10cSrcweir pChainContext = NULL ;
825cdf0e10cSrcweir
826cdf0e10cSrcweir BOOL bChain = FALSE;
827cdf0e10cSrcweir if( pCertContext != NULL )
828cdf0e10cSrcweir {
829cdf0e10cSrcweir HCERTSTORE hAdditionalStore = NULL;
830cdf0e10cSrcweir HCERTSTORE hCollectionStore = NULL;
831cdf0e10cSrcweir if (m_hCertStore && m_hKeyStore)
832cdf0e10cSrcweir {
833cdf0e10cSrcweir //Merge m_hCertStore and m_hKeyStore into one store.
834cdf0e10cSrcweir hCollectionStore = CertOpenStore(
835cdf0e10cSrcweir CERT_STORE_PROV_COLLECTION ,
836cdf0e10cSrcweir 0 ,
837cdf0e10cSrcweir NULL ,
838cdf0e10cSrcweir 0 ,
839cdf0e10cSrcweir NULL
840cdf0e10cSrcweir ) ;
841cdf0e10cSrcweir if (hCollectionStore != NULL)
842cdf0e10cSrcweir {
843cdf0e10cSrcweir CertAddStoreToCollection (
844cdf0e10cSrcweir hCollectionStore ,
845cdf0e10cSrcweir m_hCertStore ,
846cdf0e10cSrcweir CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
847cdf0e10cSrcweir 0) ;
848cdf0e10cSrcweir CertAddStoreToCollection (
849cdf0e10cSrcweir hCollectionStore ,
850cdf0e10cSrcweir m_hCertStore ,
851cdf0e10cSrcweir CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
852cdf0e10cSrcweir 0) ;
853cdf0e10cSrcweir hAdditionalStore = hCollectionStore;
854cdf0e10cSrcweir }
855cdf0e10cSrcweir
856cdf0e10cSrcweir }
857cdf0e10cSrcweir
858cdf0e10cSrcweir //if the merge of both stores failed then we add only m_hCertStore
859cdf0e10cSrcweir if (hAdditionalStore == NULL && m_hCertStore)
860cdf0e10cSrcweir hAdditionalStore = m_hCertStore;
861cdf0e10cSrcweir else if (hAdditionalStore == NULL && m_hKeyStore)
862cdf0e10cSrcweir hAdditionalStore = m_hKeyStore;
863cdf0e10cSrcweir else
864cdf0e10cSrcweir hAdditionalStore = NULL;
865cdf0e10cSrcweir
866cdf0e10cSrcweir //CertGetCertificateChain searches by default in MY, CA, ROOT and TRUST
867cdf0e10cSrcweir bChain = CertGetCertificateChain(
868cdf0e10cSrcweir NULL ,
869cdf0e10cSrcweir pCertContext ,
870cdf0e10cSrcweir NULL , //use current system time
871cdf0e10cSrcweir hAdditionalStore,
872cdf0e10cSrcweir &chainPara ,
873cdf0e10cSrcweir CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_TIMESTAMP_TIME ,
874cdf0e10cSrcweir NULL ,
875cdf0e10cSrcweir &pChainContext);
876cdf0e10cSrcweir if (!bChain)
877cdf0e10cSrcweir pChainContext = NULL;
878cdf0e10cSrcweir
879cdf0e10cSrcweir //Close the additional store
880cdf0e10cSrcweir CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG);
881cdf0e10cSrcweir }
882cdf0e10cSrcweir
883cdf0e10cSrcweir if(bChain && pChainContext != NULL && pChainContext->cChain > 0 )
884cdf0e10cSrcweir {
885cdf0e10cSrcweir PCCERT_CONTEXT pCertInChain ;
886cdf0e10cSrcweir PCERT_SIMPLE_CHAIN pCertChain ;
887cdf0e10cSrcweir X509Certificate_MSCryptImpl* pCert ;
888cdf0e10cSrcweir
889cdf0e10cSrcweir pCertChain = pChainContext->rgpChain[0] ;
890cdf0e10cSrcweir if( pCertChain->cElement ) {
891cdf0e10cSrcweir Sequence< Reference< XCertificate > > xCertChain( pCertChain->cElement ) ;
892cdf0e10cSrcweir
893cdf0e10cSrcweir for( unsigned int i = 0 ; i < pCertChain->cElement ; i ++ ) {
894cdf0e10cSrcweir if( pCertChain->rgpElement[i] )
895cdf0e10cSrcweir pCertInChain = pCertChain->rgpElement[i]->pCertContext ;
896cdf0e10cSrcweir else
897cdf0e10cSrcweir pCertInChain = NULL ;
898cdf0e10cSrcweir
899cdf0e10cSrcweir if( pCertInChain != NULL ) {
900cdf0e10cSrcweir pCert = MswcryCertContextToXCert( pCertInChain ) ;
901cdf0e10cSrcweir if( pCert != NULL )
902cdf0e10cSrcweir xCertChain[i] = pCert ;
903cdf0e10cSrcweir }
904cdf0e10cSrcweir }
905cdf0e10cSrcweir
906cdf0e10cSrcweir CertFreeCertificateChain( pChainContext ) ;
907cdf0e10cSrcweir pChainContext = NULL ;
908cdf0e10cSrcweir
909cdf0e10cSrcweir return xCertChain ;
910cdf0e10cSrcweir }
911cdf0e10cSrcweir }
912cdf0e10cSrcweir if (pChainContext)
913cdf0e10cSrcweir CertFreeCertificateChain(pChainContext);
914cdf0e10cSrcweir
915cdf0e10cSrcweir return Sequence< Reference < XCertificate > >();
916cdf0e10cSrcweir }
917cdf0e10cSrcweir
createCertificateFromRaw(const Sequence<sal_Int8> & rawCertificate)918cdf0e10cSrcweir Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromRaw( const Sequence< sal_Int8 >& rawCertificate ) throw( SecurityException , RuntimeException ) {
919cdf0e10cSrcweir X509Certificate_MSCryptImpl* xcert ;
920cdf0e10cSrcweir
921cdf0e10cSrcweir if( rawCertificate.getLength() > 0 ) {
922cdf0e10cSrcweir xcert = new X509Certificate_MSCryptImpl() ;
923cdf0e10cSrcweir if( xcert == NULL )
924cdf0e10cSrcweir throw RuntimeException() ;
925cdf0e10cSrcweir
926cdf0e10cSrcweir xcert->setRawCert( rawCertificate ) ;
927cdf0e10cSrcweir } else {
928cdf0e10cSrcweir xcert = NULL ;
929cdf0e10cSrcweir }
930cdf0e10cSrcweir
931cdf0e10cSrcweir return xcert ;
932cdf0e10cSrcweir }
933cdf0e10cSrcweir
createCertificateFromAscii(const OUString & asciiCertificate)934cdf0e10cSrcweir Reference< XCertificate > SecurityEnvironment_MSCryptImpl :: createCertificateFromAscii( const OUString& asciiCertificate ) throw( SecurityException , RuntimeException ) {
935cdf0e10cSrcweir xmlChar* chCert ;
936cdf0e10cSrcweir xmlSecSize certSize ;
937cdf0e10cSrcweir
938cdf0e10cSrcweir rtl::OString oscert = rtl::OUStringToOString( asciiCertificate , RTL_TEXTENCODING_ASCII_US ) ;
939cdf0e10cSrcweir
940cdf0e10cSrcweir chCert = xmlStrndup( ( const xmlChar* )oscert.getStr(), ( int )oscert.getLength() ) ;
941cdf0e10cSrcweir
942cdf0e10cSrcweir certSize = xmlSecBase64Decode( chCert, ( xmlSecByte* )chCert, xmlStrlen( chCert ) ) ;
943cdf0e10cSrcweir
944cdf0e10cSrcweir Sequence< sal_Int8 > rawCert( certSize ) ;
945cdf0e10cSrcweir for( unsigned int i = 0 ; i < certSize ; i ++ )
946cdf0e10cSrcweir rawCert[i] = *( chCert + i ) ;
947cdf0e10cSrcweir
948cdf0e10cSrcweir xmlFree( chCert ) ;
949cdf0e10cSrcweir
950cdf0e10cSrcweir return createCertificateFromRaw( rawCert ) ;
951cdf0e10cSrcweir }
952cdf0e10cSrcweir
953cdf0e10cSrcweir
getCertStoreForIntermediatCerts(const Sequence<Reference<::com::sun::star::security::XCertificate>> & seqCerts)954cdf0e10cSrcweir HCERTSTORE getCertStoreForIntermediatCerts(
955cdf0e10cSrcweir const Sequence< Reference< ::com::sun::star::security::XCertificate > >& seqCerts)
956cdf0e10cSrcweir {
957cdf0e10cSrcweir HCERTSTORE store = NULL;
958cdf0e10cSrcweir store = CertOpenStore(
959cdf0e10cSrcweir CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL);
960cdf0e10cSrcweir if (store == NULL)
961cdf0e10cSrcweir return NULL;
962cdf0e10cSrcweir
963cdf0e10cSrcweir for (int i = 0; i < seqCerts.getLength(); i++)
964cdf0e10cSrcweir {
965cdf0e10cSrcweir xmlsec_trace("Added temporary certificate: \n%s",
966cdf0e10cSrcweir OUStringToOString(seqCerts[i]->getSubjectName(),
967cdf0e10cSrcweir osl_getThreadTextEncoding()).getStr());
968cdf0e10cSrcweir
969cdf0e10cSrcweir
970cdf0e10cSrcweir Sequence<sal_Int8> data = seqCerts[i]->getEncoded();
971cdf0e10cSrcweir PCCERT_CONTEXT cert = CertCreateCertificateContext(
972cdf0e10cSrcweir X509_ASN_ENCODING, ( const BYTE* )&data[0], data.getLength());
973cdf0e10cSrcweir //Adding the certificate creates a copy and not just increases the ref count
974cdf0e10cSrcweir //Therefore we free later the certificate that we now add
975cdf0e10cSrcweir CertAddCertificateContextToStore(store, cert, CERT_STORE_ADD_ALWAYS, NULL);
976cdf0e10cSrcweir CertFreeCertificateContext(cert);
977cdf0e10cSrcweir }
978cdf0e10cSrcweir return store;
979cdf0e10cSrcweir }
980cdf0e10cSrcweir
981cdf0e10cSrcweir //We return only valid or invalid, as long as the API documentation expresses
982cdf0e10cSrcweir //explicitly that all validation steps are carried out even if one or several
983cdf0e10cSrcweir //errors occur. See also
984cdf0e10cSrcweir //http://wiki.services.openoffice.org/wiki/Certificate_Path_Validation#Validation_status
verifyCertificate(const Reference<::com::sun::star::security::XCertificate> & aCert,const Sequence<Reference<::com::sun::star::security::XCertificate>> & seqCerts)985cdf0e10cSrcweir sal_Int32 SecurityEnvironment_MSCryptImpl :: verifyCertificate(
986cdf0e10cSrcweir const Reference< ::com::sun::star::security::XCertificate >& aCert,
987cdf0e10cSrcweir const Sequence< Reference< ::com::sun::star::security::XCertificate > >& seqCerts)
988cdf0e10cSrcweir throw( ::com::sun::star::uno::SecurityException, ::com::sun::star::uno::RuntimeException )
989cdf0e10cSrcweir {
990*d0962c00SArrigo Marchiori sal_Int32 validity = ::com::sun::star::security::CertificateValidity::INVALID;
991cdf0e10cSrcweir PCCERT_CHAIN_CONTEXT pChainContext = NULL;
992cdf0e10cSrcweir PCCERT_CONTEXT pCertContext = NULL;
993cdf0e10cSrcweir const X509Certificate_MSCryptImpl* xcert = NULL;
994cdf0e10cSrcweir
995cdf0e10cSrcweir Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ;
996cdf0e10cSrcweir if( !xCertTunnel.is() ) {
997cdf0e10cSrcweir throw RuntimeException() ;
998cdf0e10cSrcweir }
999cdf0e10cSrcweir
1000cdf0e10cSrcweir xmlsec_trace("Start verification of certificate: \n %s",
1001cdf0e10cSrcweir OUStringToOString(
1002cdf0e10cSrcweir aCert->getSubjectName(), osl_getThreadTextEncoding()).getStr());
1003cdf0e10cSrcweir
1004cdf0e10cSrcweir xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ;
1005cdf0e10cSrcweir if( xcert == NULL ) {
1006cdf0e10cSrcweir throw RuntimeException() ;
1007cdf0e10cSrcweir }
1008cdf0e10cSrcweir
1009cdf0e10cSrcweir pCertContext = xcert->getMswcryCert() ;
1010cdf0e10cSrcweir
1011cdf0e10cSrcweir CERT_ENHKEY_USAGE enhKeyUsage ;
1012cdf0e10cSrcweir CERT_USAGE_MATCH certUsage ;
1013cdf0e10cSrcweir CERT_CHAIN_PARA chainPara ;
1014cdf0e10cSrcweir rtl_zeroMemory(&chainPara, sizeof(CERT_CHAIN_PARA));
1015cdf0e10cSrcweir
1016cdf0e10cSrcweir //Prepare parameter for CertGetCertificateChain
1017cdf0e10cSrcweir enhKeyUsage.cUsageIdentifier = 0 ;
1018cdf0e10cSrcweir enhKeyUsage.rgpszUsageIdentifier = NULL ;
1019cdf0e10cSrcweir certUsage.dwType = USAGE_MATCH_TYPE_AND ;
1020cdf0e10cSrcweir certUsage.Usage = enhKeyUsage ;
1021cdf0e10cSrcweir chainPara.cbSize = sizeof( CERT_CHAIN_PARA ) ;
1022cdf0e10cSrcweir chainPara.RequestedUsage = certUsage ;
1023cdf0e10cSrcweir
1024cdf0e10cSrcweir
1025cdf0e10cSrcweir HCERTSTORE hCollectionStore = NULL;
1026cdf0e10cSrcweir HCERTSTORE hIntermediateCertsStore = NULL;
1027cdf0e10cSrcweir BOOL bChain = FALSE;
1028cdf0e10cSrcweir if( pCertContext != NULL )
1029cdf0e10cSrcweir {
1030cdf0e10cSrcweir hIntermediateCertsStore =
1031cdf0e10cSrcweir getCertStoreForIntermediatCerts(seqCerts);
1032cdf0e10cSrcweir
1033cdf0e10cSrcweir //Merge m_hCertStore and m_hKeyStore and the store of the intermediate
1034cdf0e10cSrcweir //certificates into one store.
1035cdf0e10cSrcweir hCollectionStore = CertOpenStore(
1036cdf0e10cSrcweir CERT_STORE_PROV_COLLECTION ,
1037cdf0e10cSrcweir 0 ,
1038cdf0e10cSrcweir NULL ,
1039cdf0e10cSrcweir 0 ,
1040cdf0e10cSrcweir NULL
1041cdf0e10cSrcweir ) ;
1042cdf0e10cSrcweir if (hCollectionStore != NULL)
1043cdf0e10cSrcweir {
1044cdf0e10cSrcweir CertAddStoreToCollection (
1045cdf0e10cSrcweir hCollectionStore ,
1046cdf0e10cSrcweir m_hCertStore ,
1047cdf0e10cSrcweir CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
1048cdf0e10cSrcweir 0) ;
1049cdf0e10cSrcweir CertAddStoreToCollection (
1050cdf0e10cSrcweir hCollectionStore ,
1051cdf0e10cSrcweir m_hCertStore ,
1052cdf0e10cSrcweir CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG ,
1053cdf0e10cSrcweir 0) ;
1054cdf0e10cSrcweir CertAddStoreToCollection (
1055cdf0e10cSrcweir hCollectionStore,
1056cdf0e10cSrcweir hIntermediateCertsStore,
1057cdf0e10cSrcweir CERT_PHYSICAL_STORE_ADD_ENABLE_FLAG,
1058cdf0e10cSrcweir 0);
1059cdf0e10cSrcweir
1060cdf0e10cSrcweir }
1061cdf0e10cSrcweir
1062cdf0e10cSrcweir //CertGetCertificateChain searches by default in MY, CA, ROOT and TRUST
1063cdf0e10cSrcweir //We do not check revocation of the root. In most cases there are none.
1064cdf0e10cSrcweir //Then we would get CERT_TRUST_REVOCATION_STATUS_UNKNOWN
1065cdf0e10cSrcweir xmlsec_trace("Verifying cert using revocation information.");
1066cdf0e10cSrcweir bChain = CertGetCertificateChain(
1067cdf0e10cSrcweir NULL ,
1068cdf0e10cSrcweir pCertContext ,
1069cdf0e10cSrcweir NULL , //use current system time
1070cdf0e10cSrcweir hCollectionStore,
1071cdf0e10cSrcweir &chainPara ,
1072cdf0e10cSrcweir CERT_CHAIN_REVOCATION_CHECK_CHAIN | CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT,
1073cdf0e10cSrcweir NULL ,
1074cdf0e10cSrcweir &pChainContext);
1075cdf0e10cSrcweir
1076cdf0e10cSrcweir if (bChain && pChainContext->cChain > 0)
1077cdf0e10cSrcweir {
1078cdf0e10cSrcweir xmlsec_trace("Overall error status (all chains):");
1079cdf0e10cSrcweir traceTrustStatus(pChainContext->TrustStatus.dwErrorStatus);
1080cdf0e10cSrcweir //highest quality chains come first
1081cdf0e10cSrcweir PCERT_SIMPLE_CHAIN pSimpleChain = pChainContext->rgpChain[0];
1082cdf0e10cSrcweir xmlsec_trace("Error status of first chain: ");
1083cdf0e10cSrcweir traceTrustStatus(pSimpleChain->TrustStatus.dwErrorStatus);
1084cdf0e10cSrcweir
1085cdf0e10cSrcweir //CERT_TRUST_REVOCATION_STATUS_UNKNOWN is also set if a certificate
1086cdf0e10cSrcweir //has no AIA(OCSP) or CRLDP extension and there is no CRL locally installed.
1087cdf0e10cSrcweir DWORD revocationFlags = CERT_TRUST_REVOCATION_STATUS_UNKNOWN |
1088cdf0e10cSrcweir CERT_TRUST_IS_OFFLINE_REVOCATION;
1089cdf0e10cSrcweir DWORD otherErrorsMask = ~revocationFlags;
1090cdf0e10cSrcweir if( !(pSimpleChain->TrustStatus.dwErrorStatus & otherErrorsMask))
1091cdf0e10cSrcweir
1092cdf0e10cSrcweir {
1093cdf0e10cSrcweir //No errors except maybe those caused by missing revocation information
1094cdf0e10cSrcweir //Check if there are errors
1095cdf0e10cSrcweir if ( pSimpleChain->TrustStatus.dwErrorStatus & revocationFlags)
1096cdf0e10cSrcweir {
1097cdf0e10cSrcweir //No revocation information. Because MSDN documentation is not
1098cdf0e10cSrcweir //clear about if all other tests are performed if an error occurrs,
1099cdf0e10cSrcweir //we test again, without requiring revocation checking.
1100cdf0e10cSrcweir CertFreeCertificateChain(pChainContext);
1101cdf0e10cSrcweir pChainContext = NULL;
1102cdf0e10cSrcweir xmlsec_trace("Checking again but without requiring revocation information.");
1103cdf0e10cSrcweir bChain = CertGetCertificateChain(
1104cdf0e10cSrcweir NULL ,
1105cdf0e10cSrcweir pCertContext ,
1106cdf0e10cSrcweir NULL , //use current system time
1107cdf0e10cSrcweir hCollectionStore,
1108cdf0e10cSrcweir &chainPara ,
1109cdf0e10cSrcweir 0,
1110cdf0e10cSrcweir NULL ,
1111cdf0e10cSrcweir &pChainContext);
1112cdf0e10cSrcweir if (bChain
1113cdf0e10cSrcweir && pChainContext->cChain > 0
1114cdf0e10cSrcweir && pChainContext->rgpChain[0]->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR)
1115cdf0e10cSrcweir {
1116cdf0e10cSrcweir xmlsec_trace("Certificate is valid.\n");
1117cdf0e10cSrcweir validity = ::com::sun::star::security::CertificateValidity::VALID;
1118cdf0e10cSrcweir }
1119cdf0e10cSrcweir else
1120cdf0e10cSrcweir {
1121cdf0e10cSrcweir xmlsec_trace("Certificate is invalid.\n");
1122cdf0e10cSrcweir }
1123cdf0e10cSrcweir }
1124cdf0e10cSrcweir else
1125cdf0e10cSrcweir {
1126cdf0e10cSrcweir //valid and revocation information available
1127cdf0e10cSrcweir xmlsec_trace("Certificate is valid.\n");
1128cdf0e10cSrcweir validity = ::com::sun::star::security::CertificateValidity::VALID;
1129cdf0e10cSrcweir }
1130cdf0e10cSrcweir }
1131cdf0e10cSrcweir else
1132cdf0e10cSrcweir {
1133cdf0e10cSrcweir //invalid
1134cdf0e10cSrcweir xmlsec_trace("Certificate is invalid.\n");
1135cdf0e10cSrcweir validity = ::com::sun::star::security::CertificateValidity::INVALID ;
1136cdf0e10cSrcweir }
1137cdf0e10cSrcweir }
1138cdf0e10cSrcweir else
1139cdf0e10cSrcweir {
1140cdf0e10cSrcweir xmlsec_trace("CertGetCertificateChaine failed.\n");
1141cdf0e10cSrcweir }
1142cdf0e10cSrcweir }
1143cdf0e10cSrcweir
1144cdf0e10cSrcweir if (pChainContext)
1145cdf0e10cSrcweir {
1146cdf0e10cSrcweir CertFreeCertificateChain(pChainContext);
1147cdf0e10cSrcweir pChainContext = NULL;
1148cdf0e10cSrcweir }
1149cdf0e10cSrcweir
1150cdf0e10cSrcweir //Close the additional store, do not destroy the contained certs
1151cdf0e10cSrcweir CertCloseStore(hCollectionStore, CERT_CLOSE_STORE_CHECK_FLAG);
1152cdf0e10cSrcweir //Close the temporary store containing the intermediate certificates and make
1153cdf0e10cSrcweir //sure all certificates are deleted.
1154cdf0e10cSrcweir CertCloseStore(hIntermediateCertsStore, CERT_CLOSE_STORE_CHECK_FLAG);
1155cdf0e10cSrcweir
1156cdf0e10cSrcweir return validity ;
1157cdf0e10cSrcweir }
1158cdf0e10cSrcweir
getCertificateCharacters(const::com::sun::star::uno::Reference<::com::sun::star::security::XCertificate> & aCert)1159cdf0e10cSrcweir 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 ) {
1160cdf0e10cSrcweir sal_Int32 characters ;
1161cdf0e10cSrcweir PCCERT_CONTEXT pCertContext ;
1162cdf0e10cSrcweir const X509Certificate_MSCryptImpl* xcert ;
1163cdf0e10cSrcweir
1164cdf0e10cSrcweir Reference< XUnoTunnel > xCertTunnel( aCert, UNO_QUERY ) ;
1165cdf0e10cSrcweir if( !xCertTunnel.is() ) {
1166cdf0e10cSrcweir throw RuntimeException() ;
1167cdf0e10cSrcweir }
1168cdf0e10cSrcweir
1169cdf0e10cSrcweir xcert = ( X509Certificate_MSCryptImpl* )xCertTunnel->getSomething( X509Certificate_MSCryptImpl::getUnoTunnelId() ) ;
1170cdf0e10cSrcweir if( xcert == NULL ) {
1171cdf0e10cSrcweir throw RuntimeException() ;
1172cdf0e10cSrcweir }
1173cdf0e10cSrcweir
1174cdf0e10cSrcweir pCertContext = xcert->getMswcryCert() ;
1175cdf0e10cSrcweir
1176cdf0e10cSrcweir characters = 0x00000000 ;
1177cdf0e10cSrcweir
1178cdf0e10cSrcweir //Firstly, make sentence whether or not the cert is self-signed.
1179cdf0e10cSrcweir if( CertCompareCertificateName( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, &(pCertContext->pCertInfo->Subject), &(pCertContext->pCertInfo->Issuer) ) ) {
1180cdf0e10cSrcweir characters |= ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ;
1181cdf0e10cSrcweir } else {
1182cdf0e10cSrcweir characters &= ~ ::com::sun::star::security::CertificateCharacters::SELF_SIGNED ;
1183cdf0e10cSrcweir }
1184cdf0e10cSrcweir
1185cdf0e10cSrcweir //Secondly, make sentence whether or not the cert has a private key.
1186cdf0e10cSrcweir {
1187cdf0e10cSrcweir BOOL fCallerFreeProv ;
1188cdf0e10cSrcweir DWORD dwKeySpec ;
1189cdf0e10cSrcweir HCRYPTPROV hProv ;
1190cdf0e10cSrcweir if( CryptAcquireCertificatePrivateKey( pCertContext ,
1191cdf0e10cSrcweir 0 ,
1192cdf0e10cSrcweir NULL ,
1193cdf0e10cSrcweir &( hProv ) ,
1194cdf0e10cSrcweir &( dwKeySpec ) ,
1195cdf0e10cSrcweir &( fCallerFreeProv ) )
1196cdf0e10cSrcweir ) {
1197cdf0e10cSrcweir characters |= ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ;
1198cdf0e10cSrcweir
1199cdf0e10cSrcweir if( hProv != NULL && fCallerFreeProv )
1200cdf0e10cSrcweir CryptReleaseContext( hProv, 0 ) ;
1201cdf0e10cSrcweir } else {
1202cdf0e10cSrcweir characters &= ~ ::com::sun::star::security::CertificateCharacters::HAS_PRIVATE_KEY ;
1203cdf0e10cSrcweir }
1204cdf0e10cSrcweir }
1205cdf0e10cSrcweir return characters ;
1206cdf0e10cSrcweir }
1207cdf0e10cSrcweir
enableDefaultCrypt(sal_Bool enable)1208cdf0e10cSrcweir void SecurityEnvironment_MSCryptImpl :: enableDefaultCrypt( sal_Bool enable ) throw( Exception, RuntimeException ) {
1209cdf0e10cSrcweir m_bEnableDefault = enable ;
1210cdf0e10cSrcweir }
1211cdf0e10cSrcweir
defaultEnabled()1212cdf0e10cSrcweir sal_Bool SecurityEnvironment_MSCryptImpl :: defaultEnabled() throw( Exception, RuntimeException ) {
1213cdf0e10cSrcweir return m_bEnableDefault ;
1214cdf0e10cSrcweir }
1215cdf0e10cSrcweir
MswcryCertContextToXCert(PCCERT_CONTEXT cert)1216cdf0e10cSrcweir X509Certificate_MSCryptImpl* MswcryCertContextToXCert( PCCERT_CONTEXT cert )
1217cdf0e10cSrcweir {
1218cdf0e10cSrcweir X509Certificate_MSCryptImpl* xcert ;
1219cdf0e10cSrcweir
1220cdf0e10cSrcweir if( cert != NULL ) {
1221cdf0e10cSrcweir xcert = new X509Certificate_MSCryptImpl() ;
1222cdf0e10cSrcweir if( xcert != NULL ) {
1223cdf0e10cSrcweir xcert->setMswcryCert( cert ) ;
1224cdf0e10cSrcweir }
1225cdf0e10cSrcweir } else {
1226cdf0e10cSrcweir xcert = NULL ;
1227cdf0e10cSrcweir }
1228cdf0e10cSrcweir
1229cdf0e10cSrcweir return xcert ;
1230cdf0e10cSrcweir }
1231cdf0e10cSrcweir
getSecurityEnvironmentInformation()1232cdf0e10cSrcweir ::rtl::OUString SecurityEnvironment_MSCryptImpl::getSecurityEnvironmentInformation() throw( ::com::sun::star::uno::RuntimeException )
1233cdf0e10cSrcweir {
1234cdf0e10cSrcweir return rtl::OUString::createFromAscii("Microsoft Crypto API");
1235cdf0e10cSrcweir }
1236cdf0e10cSrcweir
1237cdf0e10cSrcweir /* Native methods */
createKeysManager()1238cdf0e10cSrcweir xmlSecKeysMngrPtr SecurityEnvironment_MSCryptImpl :: createKeysManager() throw( Exception, RuntimeException ) {
1239cdf0e10cSrcweir
1240cdf0e10cSrcweir unsigned int i ;
1241cdf0e10cSrcweir HCRYPTKEY symKey ;
1242cdf0e10cSrcweir HCRYPTKEY pubKey ;
1243cdf0e10cSrcweir HCRYPTKEY priKey ;
1244cdf0e10cSrcweir xmlSecKeysMngrPtr pKeysMngr = NULL ;
1245cdf0e10cSrcweir
1246cdf0e10cSrcweir /*-
1247cdf0e10cSrcweir * The following lines is based on the of xmlsec-mscrypto crypto engine
1248cdf0e10cSrcweir */
1249cdf0e10cSrcweir pKeysMngr = xmlSecMSCryptoAppliedKeysMngrCreate( m_hKeyStore , m_hCertStore ) ;
1250cdf0e10cSrcweir if( pKeysMngr == NULL )
1251cdf0e10cSrcweir throw RuntimeException() ;
1252cdf0e10cSrcweir
1253cdf0e10cSrcweir /*-
1254cdf0e10cSrcweir * Adopt symmetric key into keys manager
1255cdf0e10cSrcweir */
1256cdf0e10cSrcweir for( i = 0 ; ( symKey = getSymKey( i ) ) != NULL ; i ++ ) {
1257cdf0e10cSrcweir if( xmlSecMSCryptoAppliedKeysMngrSymKeyLoad( pKeysMngr, symKey ) < 0 ) {
1258cdf0e10cSrcweir throw RuntimeException() ;
1259cdf0e10cSrcweir }
1260cdf0e10cSrcweir }
1261cdf0e10cSrcweir
1262cdf0e10cSrcweir /*-
1263cdf0e10cSrcweir * Adopt asymmetric public key into keys manager
1264cdf0e10cSrcweir */
1265cdf0e10cSrcweir for( i = 0 ; ( pubKey = getPubKey( i ) ) != NULL ; i ++ ) {
1266cdf0e10cSrcweir if( xmlSecMSCryptoAppliedKeysMngrPubKeyLoad( pKeysMngr, pubKey ) < 0 ) {
1267cdf0e10cSrcweir throw RuntimeException() ;
1268cdf0e10cSrcweir }
1269cdf0e10cSrcweir }
1270cdf0e10cSrcweir
1271cdf0e10cSrcweir /*-
1272cdf0e10cSrcweir * Adopt asymmetric private key into keys manager
1273cdf0e10cSrcweir */
1274cdf0e10cSrcweir for( i = 0 ; ( priKey = getPriKey( i ) ) != NULL ; i ++ ) {
1275cdf0e10cSrcweir if( xmlSecMSCryptoAppliedKeysMngrPriKeyLoad( pKeysMngr, priKey ) < 0 ) {
1276cdf0e10cSrcweir throw RuntimeException() ;
1277cdf0e10cSrcweir }
1278cdf0e10cSrcweir }
1279cdf0e10cSrcweir
1280cdf0e10cSrcweir /*-
1281cdf0e10cSrcweir * Adopt system default certificate store.
1282cdf0e10cSrcweir */
1283cdf0e10cSrcweir if( defaultEnabled() ) {
1284cdf0e10cSrcweir //Add system key store into the keys manager.
12855ea637d9SJian Fang Zhang m_hMySystemStore = CertOpenSystemStore( 0, "MY" ) ;
12865ea637d9SJian Fang Zhang if( m_hMySystemStore != NULL ) {
12875ea637d9SJian Fang Zhang if( xmlSecMSCryptoAppliedKeysMngrAdoptKeyStore( pKeysMngr, m_hMySystemStore ) < 0 ) {
12885ea637d9SJian Fang Zhang CertCloseStore( m_hMySystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
12895ea637d9SJian Fang Zhang m_hMySystemStore = NULL;
1290cdf0e10cSrcweir throw RuntimeException() ;
1291cdf0e10cSrcweir }
1292cdf0e10cSrcweir }
1293cdf0e10cSrcweir
1294cdf0e10cSrcweir //Add system root store into the keys manager.
12955ea637d9SJian Fang Zhang m_hRootSystemStore = CertOpenSystemStore( 0, "Root" ) ;
12965ea637d9SJian Fang Zhang if( m_hRootSystemStore != NULL ) {
12975ea637d9SJian Fang Zhang if( xmlSecMSCryptoAppliedKeysMngrAdoptTrustedStore( pKeysMngr, m_hRootSystemStore ) < 0 ) {
12985ea637d9SJian Fang Zhang CertCloseStore( m_hRootSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
12995ea637d9SJian Fang Zhang m_hRootSystemStore = NULL;
1300cdf0e10cSrcweir throw RuntimeException() ;
1301cdf0e10cSrcweir }
1302cdf0e10cSrcweir }
1303cdf0e10cSrcweir
1304cdf0e10cSrcweir //Add system trusted store into the keys manager.
13055ea637d9SJian Fang Zhang m_hTrustSystemStore = CertOpenSystemStore( 0, "Trust" ) ;
13065ea637d9SJian Fang Zhang if( m_hTrustSystemStore != NULL ) {
13075ea637d9SJian Fang Zhang if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, m_hTrustSystemStore ) < 0 ) {
13085ea637d9SJian Fang Zhang CertCloseStore( m_hTrustSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
13095ea637d9SJian Fang Zhang m_hTrustSystemStore = NULL;
1310cdf0e10cSrcweir throw RuntimeException() ;
1311cdf0e10cSrcweir }
1312cdf0e10cSrcweir }
1313cdf0e10cSrcweir
1314cdf0e10cSrcweir //Add system CA store into the keys manager.
13155ea637d9SJian Fang Zhang m_hCaSystemStore = CertOpenSystemStore( 0, "CA" ) ;
13165ea637d9SJian Fang Zhang if( m_hCaSystemStore != NULL ) {
13175ea637d9SJian Fang Zhang if( xmlSecMSCryptoAppliedKeysMngrAdoptUntrustedStore( pKeysMngr, m_hCaSystemStore ) < 0 ) {
13185ea637d9SJian Fang Zhang CertCloseStore( m_hCaSystemStore, CERT_CLOSE_STORE_CHECK_FLAG ) ;
13195ea637d9SJian Fang Zhang m_hCaSystemStore = NULL;
1320cdf0e10cSrcweir throw RuntimeException() ;
1321cdf0e10cSrcweir }
1322cdf0e10cSrcweir }
1323cdf0e10cSrcweir }
1324cdf0e10cSrcweir
1325cdf0e10cSrcweir return pKeysMngr ;
1326cdf0e10cSrcweir }
destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr)1327cdf0e10cSrcweir void SecurityEnvironment_MSCryptImpl :: destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) throw( Exception, RuntimeException ) {
1328cdf0e10cSrcweir if( pKeysMngr != NULL ) {
1329cdf0e10cSrcweir xmlSecKeysMngrDestroy( pKeysMngr ) ;
1330cdf0e10cSrcweir }
1331cdf0e10cSrcweir }
1332