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