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