Update ooo320-m1
[ooovba.git] / xmlsecurity / source / xmlsec / mscrypt / x509certificate_mscryptimpl.cxx
blobfdc929c0f2da73d49ca626cb84e380766f3a8b52
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: x509certificate_mscryptimpl.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmlsecurity.hxx"
33 #include <sal/config.h>
34 #include <rtl/uuid.h>
35 #include "x509certificate_mscryptimpl.hxx"
36 #include "certificateextension_xmlsecimpl.hxx"
38 //MM : added by MM
39 #include "oid.hxx"
40 //MM : end
42 //CP : added by CP
43 #include <rtl/locale.h>
44 #include <osl/nlsupport.h>
45 #include <osl/process.h>
46 #include <utility>
48 //CP : end
50 using namespace ::com::sun::star::uno ;
51 using namespace ::com::sun::star::security ;
52 using ::rtl::OUString ;
54 using ::com::sun::star::security::XCertificate ;
55 using ::com::sun::star::util::DateTime ;
57 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
59 /*Resturns the index withing rRawString where sTypeName starts and where it ends.
60 The starting index is pair.first. The ending index in pair.second points
61 one char after the last character of the type.
62 sTypeName can be
63 "S" or "CN" (without ""). Do not use spaces at the beginning of the type name.
64 If the type name is not found then pair.first and pair.second are -1.
66 std::pair< sal_Int32, sal_Int32 >
67 findTypeInDN(const OUString& rRawString, const OUString& sTypeName)
69 std::pair< sal_Int32, sal_Int32 > retVal;
70 bool bInEscape = false;
71 bool bInValue = false;
72 bool bFound = false;
73 sal_Int32 nTypeNameStart = 0;
74 sal_Int32 length = rRawString.getLength();
76 for (sal_Int32 i = 0; i < length; i++)
78 sal_Unicode c = rRawString[i];
80 if (c == '=')
82 if (! bInValue)
84 OUString sType = rRawString.copy(nTypeNameStart, i - nTypeNameStart);
85 sType = sType.trim();
86 if (sType.equalsIgnoreAsciiCase(sTypeName))
88 bFound = true;
89 break;
93 else if (c == '"')
95 if (!bInEscape)
97 //If this is the quote is the first of the couple which enclose the
98 //whole value, because the value contains special characters
99 //then we just drop it. That is, this character must be followed by
100 //a character which is not '"'.
101 if ( i + 1 < length && rRawString[i+1] == '"')
102 bInEscape = true;
103 else
104 bInValue = !bInValue; //value is enclosed in " "
106 else
108 //This quote is escaped by a preceding quote and therefore is
109 //part of the value
110 bInEscape = false;
113 else if (c == ',')
115 //The comma separate the attribute value pairs.
116 //If the comma is not part of a value (the value would then be enclosed in '"'),
117 //then we have reached the end of the value
118 if (!bInValue)
120 //The next char is the start of the new type
121 nTypeNameStart = i + 1;
126 //Found the Type Name, but there can still be spaces after the last comma
127 //and the beginning of the type.
128 if (bFound)
130 while (true)
132 sal_Unicode c = rRawString[nTypeNameStart];
133 if (c != ' ' && c != '\t')
134 //found
135 break;
136 nTypeNameStart ++;
138 // search end (one after last letter)
139 sal_Int32 nTypeNameEnd = nTypeNameStart;
140 nTypeNameEnd++;
141 while (true)
143 sal_Unicode c = rRawString[nTypeNameEnd];
144 if (c == ' ' || c == '\t' || c == '=')
145 break;
146 nTypeNameEnd++;
148 retVal = std::make_pair(nTypeNameStart, nTypeNameEnd);
150 else
152 retVal = std::make_pair(-1, -1);
154 return retVal;
159 MS Crypto uses the 'S' tag (equal to the 'ST' tag in NSS), but the NSS can't recognise
160 it, so the 'S' tag should be changed to 'ST' tag. However I am not sure if this is necessary
161 anymore, because we provide always the signers certificate when signing. So libmlsec can find
162 the private key based on the provided certificate (X509Certificate element) and does not need
163 the issuer name (X509IssuerName element). The issuer name in the xml signature has also no
164 effect for the signature nor the certificate validation.
165 In many RFCs, for example 4519, on speaks of 'ST'. However, the certificate does not contain
166 strings for type names. Instead it uses OIDs.
169 OUString replaceTagSWithTagST(OUString oldDN)
171 std::pair<sal_Int32, sal_Int32 > pairIndex = findTypeInDN(oldDN, OUSTR("S"));
173 if (pairIndex.first != -1)
175 OUString newDN = oldDN.copy(0, pairIndex.first);
176 newDN += OUSTR("ST");
177 newDN += oldDN.copy(pairIndex.second);
178 return newDN;
180 return oldDN;
182 /* end */
184 X509Certificate_MSCryptImpl :: X509Certificate_MSCryptImpl() :
185 m_pCertContext( NULL )
189 X509Certificate_MSCryptImpl :: ~X509Certificate_MSCryptImpl() {
190 if( m_pCertContext != NULL ) {
191 CertFreeCertificateContext( m_pCertContext ) ;
195 //Methods from XCertificate
196 sal_Int16 SAL_CALL X509Certificate_MSCryptImpl :: getVersion() throw ( ::com::sun::star::uno::RuntimeException) {
197 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) {
198 return ( char )m_pCertContext->pCertInfo->dwVersion ;
199 } else {
200 return -1 ;
204 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl :: getSerialNumber() throw ( ::com::sun::star::uno::RuntimeException) {
205 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) {
206 Sequence< sal_Int8 > serial( m_pCertContext->pCertInfo->SerialNumber.cbData ) ;
207 for( unsigned int i = 0 ; i < m_pCertContext->pCertInfo->SerialNumber.cbData ; i ++ )
208 serial[i] = *( m_pCertContext->pCertInfo->SerialNumber.pbData + m_pCertContext->pCertInfo->SerialNumber.cbData - i - 1 ) ;
210 return serial ;
211 } else {
212 return NULL ;
216 ::rtl::OUString SAL_CALL X509Certificate_MSCryptImpl :: getIssuerName() throw ( ::com::sun::star::uno::RuntimeException) {
217 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) {
218 char* issuer ;
219 DWORD cbIssuer ;
221 cbIssuer = CertNameToStr(
222 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
223 &( m_pCertContext->pCertInfo->Issuer ),
224 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
225 NULL, 0
228 // Here the cbIssuer count the last 0x00 , take care.
229 if( cbIssuer != 0 ) {
230 issuer = new char[ cbIssuer ] ;
231 if( issuer == NULL )
232 throw RuntimeException() ;
234 cbIssuer = CertNameToStr(
235 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
236 &( m_pCertContext->pCertInfo->Issuer ),
237 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
238 issuer, cbIssuer
241 if( cbIssuer <= 0 ) {
242 delete issuer ;
243 throw RuntimeException() ;
246 // By CP , for correct encoding
247 sal_uInt16 encoding ;
248 rtl_Locale *pLocale = NULL ;
249 osl_getProcessLocale( &pLocale ) ;
250 encoding = osl_getTextEncodingFromLocale( pLocale ) ;
251 // CP end
253 if(issuer[cbIssuer-1] == 0) cbIssuer--; //delimit the last 0x00;
254 OUString xIssuer(issuer , cbIssuer ,encoding ) ; //By CP
255 delete issuer ;
257 return replaceTagSWithTagST(xIssuer);
258 } else {
259 return OUString() ;
261 } else {
262 return OUString() ;
266 ::rtl::OUString SAL_CALL X509Certificate_MSCryptImpl :: getSubjectName() throw ( ::com::sun::star::uno::RuntimeException) {
267 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) {
268 char* subject ;
269 DWORD cbSubject ;
271 cbSubject = CertNameToStr(
272 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
273 &( m_pCertContext->pCertInfo->Subject ),
274 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
275 NULL, 0
278 if( cbSubject != 0 ) {
279 subject = new char[ cbSubject ] ;
280 if( subject == NULL )
281 throw RuntimeException() ;
283 cbSubject = CertNameToStr(
284 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING ,
285 &( m_pCertContext->pCertInfo->Subject ),
286 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG ,
287 subject, cbSubject
290 if( cbSubject <= 0 ) {
291 delete subject ;
292 throw RuntimeException() ;
295 // By CP , for correct encoding
296 sal_uInt16 encoding ;
297 rtl_Locale *pLocale = NULL ;
298 osl_getProcessLocale( &pLocale ) ;
299 encoding = osl_getTextEncodingFromLocale( pLocale ) ;
300 // CP end
302 if(subject[cbSubject-1] == 0) cbSubject--; //delimit the last 0x00;
303 OUString xSubject(subject , cbSubject ,encoding ) ; //By CP
304 delete subject ;
306 return replaceTagSWithTagST(xSubject);
307 } else {
308 return OUString() ;
310 } else {
311 return OUString() ;
315 ::com::sun::star::util::DateTime SAL_CALL X509Certificate_MSCryptImpl :: getNotValidBefore() throw ( ::com::sun::star::uno::RuntimeException ) {
316 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) {
317 SYSTEMTIME explTime ;
318 DateTime dateTime ;
319 FILETIME localFileTime;
321 if (FileTimeToLocalFileTime(&( m_pCertContext->pCertInfo->NotBefore ), &localFileTime))
323 if( FileTimeToSystemTime( &localFileTime, &explTime ) ) {
324 //Convert the time to readable local time
325 dateTime.HundredthSeconds = explTime.wMilliseconds / 100 ;
326 dateTime.Seconds = explTime.wSecond ;
327 dateTime.Minutes = explTime.wMinute ;
328 dateTime.Hours = explTime.wHour ;
329 dateTime.Day = explTime.wDay ;
330 dateTime.Month = explTime.wMonth ;
331 dateTime.Year = explTime.wYear ;
335 return dateTime ;
336 } else {
337 return DateTime() ;
341 ::com::sun::star::util::DateTime SAL_CALL X509Certificate_MSCryptImpl :: getNotValidAfter() throw ( ::com::sun::star::uno::RuntimeException) {
342 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) {
343 SYSTEMTIME explTime ;
344 DateTime dateTime ;
345 FILETIME localFileTime;
347 if (FileTimeToLocalFileTime(&( m_pCertContext->pCertInfo->NotAfter ), &localFileTime))
349 if( FileTimeToSystemTime( &localFileTime, &explTime ) ) {
350 //Convert the time to readable local time
351 dateTime.HundredthSeconds = explTime.wMilliseconds / 100 ;
352 dateTime.Seconds = explTime.wSecond ;
353 dateTime.Minutes = explTime.wMinute ;
354 dateTime.Hours = explTime.wHour ;
355 dateTime.Day = explTime.wDay ;
356 dateTime.Month = explTime.wMonth ;
357 dateTime.Year = explTime.wYear ;
361 return dateTime ;
362 } else {
363 return DateTime() ;
367 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl :: getIssuerUniqueID() throw ( ::com::sun::star::uno::RuntimeException) {
368 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) {
369 Sequence< sal_Int8 > issuerUid( m_pCertContext->pCertInfo->IssuerUniqueId.cbData ) ;
370 for( unsigned int i = 0 ; i < m_pCertContext->pCertInfo->IssuerUniqueId.cbData; i ++ )
371 issuerUid[i] = *( m_pCertContext->pCertInfo->IssuerUniqueId.pbData + i ) ;
373 return issuerUid ;
374 } else {
375 return NULL ;
379 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl :: getSubjectUniqueID() throw ( ::com::sun::star::uno::RuntimeException ) {
380 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) {
381 Sequence< sal_Int8 > subjectUid( m_pCertContext->pCertInfo->SubjectUniqueId.cbData ) ;
382 for( unsigned int i = 0 ; i < m_pCertContext->pCertInfo->SubjectUniqueId.cbData; i ++ )
383 subjectUid[i] = *( m_pCertContext->pCertInfo->SubjectUniqueId.pbData + i ) ;
385 return subjectUid ;
386 } else {
387 return NULL ;
391 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > > SAL_CALL X509Certificate_MSCryptImpl :: getExtensions() throw ( ::com::sun::star::uno::RuntimeException ) {
392 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL && m_pCertContext->pCertInfo->cExtension != 0 ) {
393 CertificateExtension_XmlSecImpl* xExtn ;
394 CERT_EXTENSION* pExtn ;
395 Sequence< Reference< XCertificateExtension > > xExtns( m_pCertContext->pCertInfo->cExtension ) ;
397 for( unsigned int i = 0; i < m_pCertContext->pCertInfo->cExtension; i++ ) {
398 pExtn = &(m_pCertContext->pCertInfo->rgExtension[i]) ;
400 xExtn = new CertificateExtension_XmlSecImpl() ;
401 if( xExtn == NULL )
402 throw RuntimeException() ;
404 xExtn->setCertExtn( pExtn->Value.pbData, pExtn->Value.cbData, ( unsigned char* )pExtn->pszObjId, strlen( pExtn->pszObjId ), sal::static_int_cast<sal_Bool>(pExtn->fCritical) ) ;
406 xExtns[i] = xExtn ;
409 return xExtns ;
410 } else {
411 return NULL ;
415 ::com::sun::star::uno::Reference< ::com::sun::star::security::XCertificateExtension > SAL_CALL X509Certificate_MSCryptImpl :: findCertificateExtension( const ::com::sun::star::uno::Sequence< sal_Int8 >& /*oid*/ ) throw (::com::sun::star::uno::RuntimeException) {
416 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL && m_pCertContext->pCertInfo->cExtension != 0 ) {
417 CertificateExtension_XmlSecImpl* xExtn ;
418 CERT_EXTENSION* pExtn ;
419 Sequence< Reference< XCertificateExtension > > xExtns( m_pCertContext->pCertInfo->cExtension ) ;
421 xExtn = NULL ;
422 for( unsigned int i = 0; i < m_pCertContext->pCertInfo->cExtension; i++ ) {
423 pExtn = &( m_pCertContext->pCertInfo->rgExtension[i] ) ;
425 //TODO: Compare the oid
426 if( 0 ) {
427 xExtn = new CertificateExtension_XmlSecImpl() ;
428 if( xExtn == NULL )
429 throw RuntimeException() ;
431 xExtn->setCertExtn( pExtn->Value.pbData, pExtn->Value.cbData, ( unsigned char* )pExtn->pszObjId, strlen( pExtn->pszObjId ), sal::static_int_cast<sal_Bool>(pExtn->fCritical) ) ;
435 return xExtn ;
436 } else {
437 return NULL ;
442 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl :: getEncoded() throw ( ::com::sun::star::uno::RuntimeException) {
443 if( m_pCertContext != NULL && m_pCertContext->cbCertEncoded > 0 ) {
444 Sequence< sal_Int8 > rawCert( m_pCertContext->cbCertEncoded ) ;
446 for( unsigned int i = 0 ; i < m_pCertContext->cbCertEncoded ; i ++ )
447 rawCert[i] = *( m_pCertContext->pbCertEncoded + i ) ;
449 return rawCert ;
450 } else {
451 return NULL ;
455 //Helper methods
456 void X509Certificate_MSCryptImpl :: setMswcryCert( const CERT_CONTEXT* cert ) {
457 if( m_pCertContext != NULL ) {
458 CertFreeCertificateContext( m_pCertContext ) ;
459 m_pCertContext = NULL ;
462 if( cert != NULL ) {
463 m_pCertContext = CertDuplicateCertificateContext( cert ) ;
467 const CERT_CONTEXT* X509Certificate_MSCryptImpl :: getMswcryCert() const {
468 if( m_pCertContext != NULL ) {
469 return m_pCertContext ;
470 } else {
471 return NULL ;
475 void X509Certificate_MSCryptImpl :: setRawCert( Sequence< sal_Int8 > rawCert ) throw ( ::com::sun::star::uno::RuntimeException) {
476 if( m_pCertContext != NULL ) {
477 CertFreeCertificateContext( m_pCertContext ) ;
478 m_pCertContext = NULL ;
481 if( rawCert.getLength() != 0 ) {
482 m_pCertContext = CertCreateCertificateContext( X509_ASN_ENCODING, ( const BYTE* )&rawCert[0], rawCert.getLength() ) ;
486 /* XUnoTunnel */
487 sal_Int64 SAL_CALL X509Certificate_MSCryptImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw( RuntimeException ) {
488 if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) {
489 return ( sal_Int64 )this ;
491 return 0 ;
494 /* XUnoTunnel extension */
495 const Sequence< sal_Int8>& X509Certificate_MSCryptImpl :: getUnoTunnelId() {
496 static Sequence< sal_Int8 >* pSeq = 0 ;
497 if( !pSeq ) {
498 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ;
499 if( !pSeq ) {
500 static Sequence< sal_Int8> aSeq( 16 ) ;
501 rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ;
502 pSeq = &aSeq ;
505 return *pSeq ;
508 /* XUnoTunnel extension */
509 X509Certificate_MSCryptImpl* X509Certificate_MSCryptImpl :: getImplementation( const Reference< XInterface > xObj ) {
510 Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ;
511 if( xUT.is() ) {
512 return ( X509Certificate_MSCryptImpl* )xUT->getSomething( getUnoTunnelId() ) ;
513 } else
514 return NULL ;
517 // MM : added by MM
518 ::rtl::OUString findOIDDescription(char *oid)
520 OUString ouOID = OUString::createFromAscii( oid );
521 for (int i=0; i<nOID; i++)
523 OUString item = OUString::createFromAscii( OIDs[i].oid );
524 if (ouOID == item)
526 return OUString::createFromAscii( OIDs[i].desc );
530 return OUString() ;
533 ::com::sun::star::uno::Sequence< sal_Int8 > getThumbprint(const CERT_CONTEXT* pCertContext, DWORD dwPropId)
535 if( pCertContext != NULL )
537 DWORD cbData = 20;
538 unsigned char fingerprint[20];
539 if (CertGetCertificateContextProperty(pCertContext, dwPropId, (void*)fingerprint, &cbData))
541 Sequence< sal_Int8 > thumbprint( cbData ) ;
542 for( unsigned int i = 0 ; i < cbData ; i ++ )
544 thumbprint[i] = fingerprint[i];
547 return thumbprint;
549 else
551 DWORD e = GetLastError();
552 cbData = e;
556 return NULL;
559 ::rtl::OUString SAL_CALL X509Certificate_MSCryptImpl::getSubjectPublicKeyAlgorithm()
560 throw ( ::com::sun::star::uno::RuntimeException)
562 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL )
564 CRYPT_ALGORITHM_IDENTIFIER algorithm = m_pCertContext->pCertInfo->SubjectPublicKeyInfo.Algorithm;
565 return findOIDDescription( algorithm.pszObjId ) ;
567 else
569 return OUString() ;
573 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl::getSubjectPublicKeyValue()
574 throw ( ::com::sun::star::uno::RuntimeException)
576 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL )
578 CRYPT_BIT_BLOB publicKey = m_pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey;
580 Sequence< sal_Int8 > key( publicKey.cbData ) ;
581 for( unsigned int i = 0 ; i < publicKey.cbData ; i++ )
583 key[i] = *(publicKey.pbData + i) ;
586 return key;
588 else
590 return NULL ;
594 ::rtl::OUString SAL_CALL X509Certificate_MSCryptImpl::getSignatureAlgorithm()
595 throw ( ::com::sun::star::uno::RuntimeException)
597 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL )
599 CRYPT_ALGORITHM_IDENTIFIER algorithm = m_pCertContext->pCertInfo->SignatureAlgorithm;
600 return findOIDDescription( algorithm.pszObjId ) ;
602 else
604 return OUString() ;
608 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl::getSHA1Thumbprint()
609 throw ( ::com::sun::star::uno::RuntimeException)
611 return getThumbprint(m_pCertContext, CERT_SHA1_HASH_PROP_ID);
614 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl::getMD5Thumbprint()
615 throw ( ::com::sun::star::uno::RuntimeException)
617 return getThumbprint(m_pCertContext, CERT_MD5_HASH_PROP_ID);
620 sal_Int32 SAL_CALL X509Certificate_MSCryptImpl::getCertificateUsage( )
621 throw ( ::com::sun::star::uno::RuntimeException)
623 sal_Int32 usage =
624 CERT_DATA_ENCIPHERMENT_KEY_USAGE |
625 CERT_DIGITAL_SIGNATURE_KEY_USAGE |
626 CERT_KEY_AGREEMENT_KEY_USAGE |
627 CERT_KEY_CERT_SIGN_KEY_USAGE |
628 CERT_KEY_ENCIPHERMENT_KEY_USAGE |
629 CERT_NON_REPUDIATION_KEY_USAGE |
630 CERT_OFFLINE_CRL_SIGN_KEY_USAGE;
632 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL && m_pCertContext->pCertInfo->cExtension != 0 )
634 CERT_EXTENSION* pExtn = CertFindExtension(
635 szOID_KEY_USAGE,
636 m_pCertContext->pCertInfo->cExtension,
637 m_pCertContext->pCertInfo->rgExtension);
639 if (pExtn != NULL)
641 CERT_KEY_USAGE_RESTRICTION_INFO keyUsage;
642 DWORD length = sizeof(CERT_KEY_USAGE_RESTRICTION_INFO);
644 bool rc = CryptDecodeObject(
645 X509_ASN_ENCODING,
646 X509_KEY_USAGE,
647 pExtn->Value.pbData,
648 pExtn->Value.cbData,
649 CRYPT_DECODE_NOCOPY_FLAG,
650 (void *)&keyUsage,
651 &length);
653 if (rc && keyUsage.RestrictedKeyUsage.cbData!=0)
655 usage = (sal_Int32)keyUsage.RestrictedKeyUsage.pbData;
660 return usage;
663 // MM : end