1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_xmlsecurity.hxx" 30 #include <sal/config.h> 31 #include <rtl/uuid.h> 32 #include "x509certificate_mscryptimpl.hxx" 33 #include "certificateextension_xmlsecimpl.hxx" 34 #include "sanextension_mscryptimpl.hxx" 35 36 //MM : added by MM 37 #include "oid.hxx" 38 //MM : end 39 40 //CP : added by CP 41 #include <rtl/locale.h> 42 #include <osl/nlsupport.h> 43 #include <osl/process.h> 44 #include <utility> 45 46 //CP : end 47 48 using namespace ::com::sun::star::uno ; 49 using namespace ::com::sun::star::security ; 50 using ::rtl::OUString ; 51 52 using ::com::sun::star::security::XCertificate ; 53 using ::com::sun::star::util::DateTime ; 54 55 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 56 57 /*Resturns the index withing rRawString where sTypeName starts and where it ends. 58 The starting index is pair.first. The ending index in pair.second points 59 one char after the last character of the type. 60 sTypeName can be 61 "S" or "CN" (without ""). Do not use spaces at the beginning of the type name. 62 If the type name is not found then pair.first and pair.second are -1. 63 */ 64 std::pair< sal_Int32, sal_Int32 > 65 findTypeInDN(const OUString& rRawString, const OUString& sTypeName) 66 { 67 std::pair< sal_Int32, sal_Int32 > retVal; 68 bool bInEscape = false; 69 bool bInValue = false; 70 bool bFound = false; 71 sal_Int32 nTypeNameStart = 0; 72 sal_Int32 length = rRawString.getLength(); 73 74 for (sal_Int32 i = 0; i < length; i++) 75 { 76 sal_Unicode c = rRawString[i]; 77 78 if (c == '=') 79 { 80 if (! bInValue) 81 { 82 OUString sType = rRawString.copy(nTypeNameStart, i - nTypeNameStart); 83 sType = sType.trim(); 84 if (sType.equalsIgnoreAsciiCase(sTypeName)) 85 { 86 bFound = true; 87 break; 88 } 89 } 90 } 91 else if (c == '"') 92 { 93 if (!bInEscape) 94 { 95 //If this is the quote is the first of the couple which enclose the 96 //whole value, because the value contains special characters 97 //then we just drop it. That is, this character must be followed by 98 //a character which is not '"'. 99 if ( i + 1 < length && rRawString[i+1] == '"') 100 bInEscape = true; 101 else 102 bInValue = !bInValue; //value is enclosed in " " 103 } 104 else 105 { 106 //This quote is escaped by a preceding quote and therefore is 107 //part of the value 108 bInEscape = false; 109 } 110 } 111 else if (c == ',' || c == '+') 112 { 113 //The comma separate the attribute value pairs. 114 //If the comma is not part of a value (the value would then be enclosed in '"'), 115 //then we have reached the end of the value 116 if (!bInValue) 117 { 118 //The next char is the start of the new type 119 nTypeNameStart = i + 1; 120 } 121 } 122 } 123 124 //Found the Type Name, but there can still be spaces after the last comma 125 //and the beginning of the type. 126 if (bFound) 127 { 128 while (true) 129 { 130 sal_Unicode c = rRawString[nTypeNameStart]; 131 if (c != ' ' && c != '\t') 132 //found 133 break; 134 nTypeNameStart ++; 135 } 136 // search end (one after last letter) 137 sal_Int32 nTypeNameEnd = nTypeNameStart; 138 nTypeNameEnd++; 139 while (true) 140 { 141 sal_Unicode c = rRawString[nTypeNameEnd]; 142 if (c == ' ' || c == '\t' || c == '=') 143 break; 144 nTypeNameEnd++; 145 } 146 retVal = std::make_pair(nTypeNameStart, nTypeNameEnd); 147 } 148 else 149 { 150 retVal = std::make_pair(-1, -1); 151 } 152 return retVal; 153 } 154 155 156 /* 157 MS Crypto uses the 'S' tag (equal to the 'ST' tag in NSS), but the NSS can't recognise 158 it, so the 'S' tag should be changed to 'ST' tag. However I am not sure if this is necessary 159 anymore, because we provide always the signers certificate when signing. So libmlsec can find 160 the private key based on the provided certificate (X509Certificate element) and does not need 161 the issuer name (X509IssuerName element). The issuer name in the xml signature has also no 162 effect for the signature nor the certificate validation. 163 In many RFCs, for example 4519, on speaks of 'ST'. However, the certificate does not contain 164 strings for type names. Instead it uses OIDs. 165 */ 166 167 OUString replaceTagSWithTagST(OUString oldDN) 168 { 169 std::pair<sal_Int32, sal_Int32 > pairIndex = findTypeInDN(oldDN, OUSTR("S")); 170 171 if (pairIndex.first != -1) 172 { 173 OUString newDN = oldDN.copy(0, pairIndex.first); 174 newDN += OUSTR("ST"); 175 newDN += oldDN.copy(pairIndex.second); 176 return newDN; 177 } 178 return oldDN; 179 } 180 /* end */ 181 182 X509Certificate_MSCryptImpl :: X509Certificate_MSCryptImpl() : 183 m_pCertContext( NULL ) 184 { 185 } 186 187 X509Certificate_MSCryptImpl :: ~X509Certificate_MSCryptImpl() { 188 if( m_pCertContext != NULL ) { 189 CertFreeCertificateContext( m_pCertContext ) ; 190 } 191 } 192 193 //Methods from XCertificate 194 sal_Int16 SAL_CALL X509Certificate_MSCryptImpl :: getVersion() throw ( ::com::sun::star::uno::RuntimeException) { 195 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { 196 return ( char )m_pCertContext->pCertInfo->dwVersion ; 197 } else { 198 return -1 ; 199 } 200 } 201 202 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl :: getSerialNumber() throw ( ::com::sun::star::uno::RuntimeException) { 203 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { 204 Sequence< sal_Int8 > serial( m_pCertContext->pCertInfo->SerialNumber.cbData ) ; 205 for( unsigned int i = 0 ; i < m_pCertContext->pCertInfo->SerialNumber.cbData ; i ++ ) 206 serial[i] = *( m_pCertContext->pCertInfo->SerialNumber.pbData + m_pCertContext->pCertInfo->SerialNumber.cbData - i - 1 ) ; 207 208 return serial ; 209 } else { 210 return Sequence< sal_Int8 >(); 211 } 212 } 213 214 ::rtl::OUString SAL_CALL X509Certificate_MSCryptImpl :: getIssuerName() throw ( ::com::sun::star::uno::RuntimeException) { 215 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { 216 char* issuer ; 217 DWORD cbIssuer ; 218 219 cbIssuer = CertNameToStr( 220 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , 221 &( m_pCertContext->pCertInfo->Issuer ), 222 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG , 223 NULL, 0 224 ) ; 225 226 // Here the cbIssuer count the last 0x00 , take care. 227 if( cbIssuer != 0 ) { 228 issuer = new char[ cbIssuer ] ; 229 if( issuer == NULL ) 230 throw RuntimeException() ; 231 232 cbIssuer = CertNameToStr( 233 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , 234 &( m_pCertContext->pCertInfo->Issuer ), 235 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG , 236 issuer, cbIssuer 237 ) ; 238 239 if( cbIssuer <= 0 ) { 240 delete [] issuer ; 241 throw RuntimeException() ; 242 } 243 244 // By CP , for correct encoding 245 sal_uInt16 encoding ; 246 rtl_Locale *pLocale = NULL ; 247 osl_getProcessLocale( &pLocale ) ; 248 encoding = osl_getTextEncodingFromLocale( pLocale ) ; 249 // CP end 250 251 if(issuer[cbIssuer-1] == 0) cbIssuer--; //delimit the last 0x00; 252 OUString xIssuer(issuer , cbIssuer ,encoding ) ; //By CP 253 delete [] issuer ; 254 255 return replaceTagSWithTagST(xIssuer); 256 } else { 257 return OUString() ; 258 } 259 } else { 260 return OUString() ; 261 } 262 } 263 264 ::rtl::OUString SAL_CALL X509Certificate_MSCryptImpl :: getSubjectName() throw ( ::com::sun::star::uno::RuntimeException) 265 { 266 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) 267 { 268 wchar_t* subject ; 269 DWORD cbSubject ; 270 271 cbSubject = CertNameToStrW( 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 276 ) ; 277 278 if( cbSubject != 0 ) 279 { 280 subject = new wchar_t[ cbSubject ] ; 281 if( subject == NULL ) 282 throw RuntimeException() ; 283 284 cbSubject = CertNameToStrW( 285 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING , 286 &( m_pCertContext->pCertInfo->Subject ), 287 CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG , 288 subject, cbSubject 289 ) ; 290 291 if( cbSubject <= 0 ) { 292 delete [] subject ; 293 throw RuntimeException() ; 294 } 295 296 OUString xSubject(reinterpret_cast<const sal_Unicode*>(subject)); 297 delete [] subject ; 298 299 return replaceTagSWithTagST(xSubject); 300 } else 301 { 302 return OUString() ; 303 } 304 } 305 else 306 { 307 return OUString() ; 308 } 309 } 310 311 ::com::sun::star::util::DateTime SAL_CALL X509Certificate_MSCryptImpl :: getNotValidBefore() throw ( ::com::sun::star::uno::RuntimeException ) { 312 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { 313 SYSTEMTIME explTime ; 314 DateTime dateTime ; 315 FILETIME localFileTime; 316 317 if (FileTimeToLocalFileTime(&( m_pCertContext->pCertInfo->NotBefore ), &localFileTime)) 318 { 319 if( FileTimeToSystemTime( &localFileTime, &explTime ) ) { 320 //Convert the time to readable local time 321 dateTime.HundredthSeconds = explTime.wMilliseconds / 100 ; 322 dateTime.Seconds = explTime.wSecond ; 323 dateTime.Minutes = explTime.wMinute ; 324 dateTime.Hours = explTime.wHour ; 325 dateTime.Day = explTime.wDay ; 326 dateTime.Month = explTime.wMonth ; 327 dateTime.Year = explTime.wYear ; 328 } 329 } 330 331 return dateTime ; 332 } else { 333 return DateTime() ; 334 } 335 } 336 337 ::com::sun::star::util::DateTime SAL_CALL X509Certificate_MSCryptImpl :: getNotValidAfter() throw ( ::com::sun::star::uno::RuntimeException) { 338 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { 339 SYSTEMTIME explTime ; 340 DateTime dateTime ; 341 FILETIME localFileTime; 342 343 if (FileTimeToLocalFileTime(&( m_pCertContext->pCertInfo->NotAfter ), &localFileTime)) 344 { 345 if( FileTimeToSystemTime( &localFileTime, &explTime ) ) { 346 //Convert the time to readable local time 347 dateTime.HundredthSeconds = explTime.wMilliseconds / 100 ; 348 dateTime.Seconds = explTime.wSecond ; 349 dateTime.Minutes = explTime.wMinute ; 350 dateTime.Hours = explTime.wHour ; 351 dateTime.Day = explTime.wDay ; 352 dateTime.Month = explTime.wMonth ; 353 dateTime.Year = explTime.wYear ; 354 } 355 } 356 357 return dateTime ; 358 } else { 359 return DateTime() ; 360 } 361 } 362 363 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl :: getIssuerUniqueID() throw ( ::com::sun::star::uno::RuntimeException) { 364 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { 365 Sequence< sal_Int8 > issuerUid( m_pCertContext->pCertInfo->IssuerUniqueId.cbData ) ; 366 for( unsigned int i = 0 ; i < m_pCertContext->pCertInfo->IssuerUniqueId.cbData; i ++ ) 367 issuerUid[i] = *( m_pCertContext->pCertInfo->IssuerUniqueId.pbData + i ) ; 368 369 return issuerUid ; 370 } else { 371 return Sequence< sal_Int8 >(); 372 } 373 } 374 375 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl :: getSubjectUniqueID() throw ( ::com::sun::star::uno::RuntimeException ) { 376 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) { 377 Sequence< sal_Int8 > subjectUid( m_pCertContext->pCertInfo->SubjectUniqueId.cbData ) ; 378 for( unsigned int i = 0 ; i < m_pCertContext->pCertInfo->SubjectUniqueId.cbData; i ++ ) 379 subjectUid[i] = *( m_pCertContext->pCertInfo->SubjectUniqueId.pbData + i ) ; 380 381 return subjectUid ; 382 } else { 383 return Sequence< sal_Int8 >(); 384 } 385 } 386 387 ::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 ) { 388 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL && m_pCertContext->pCertInfo->cExtension != 0 ) { 389 CertificateExtension_XmlSecImpl* xExtn ; 390 CERT_EXTENSION* pExtn ; 391 Sequence< Reference< XCertificateExtension > > xExtns( m_pCertContext->pCertInfo->cExtension ) ; 392 393 for( unsigned int i = 0; i < m_pCertContext->pCertInfo->cExtension; i++ ) { 394 pExtn = &(m_pCertContext->pCertInfo->rgExtension[i]) ; 395 396 397 ::rtl::OUString objId = ::rtl::OUString::createFromAscii( pExtn->pszObjId ); 398 399 if ( objId.equalsAscii("2.5.29.17") ) 400 xExtn = (CertificateExtension_XmlSecImpl*) new SanExtensionImpl() ; 401 else 402 xExtn = new CertificateExtension_XmlSecImpl() ; 403 if( xExtn == NULL ) 404 throw RuntimeException() ; 405 406 xExtn->setCertExtn( pExtn->Value.pbData, pExtn->Value.cbData, ( unsigned char* )pExtn->pszObjId, strlen( pExtn->pszObjId ), sal::static_int_cast<sal_Bool>(pExtn->fCritical) ) ; 407 408 xExtns[i] = xExtn ; 409 } 410 411 return xExtns ; 412 } else { 413 return Sequence< Reference< XCertificateExtension > >(); 414 } 415 } 416 417 ::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) { 418 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL && m_pCertContext->pCertInfo->cExtension != 0 ) { 419 CertificateExtension_XmlSecImpl* xExtn ; 420 CERT_EXTENSION* pExtn ; 421 Sequence< Reference< XCertificateExtension > > xExtns( m_pCertContext->pCertInfo->cExtension ) ; 422 423 xExtn = NULL ; 424 for( unsigned int i = 0; i < m_pCertContext->pCertInfo->cExtension; i++ ) { 425 pExtn = &( m_pCertContext->pCertInfo->rgExtension[i] ) ; 426 427 //TODO: Compare the oid 428 if( 0 ) { 429 xExtn = new CertificateExtension_XmlSecImpl() ; 430 if( xExtn == NULL ) 431 throw RuntimeException() ; 432 433 xExtn->setCertExtn( pExtn->Value.pbData, pExtn->Value.cbData, ( unsigned char* )pExtn->pszObjId, strlen( pExtn->pszObjId ), sal::static_int_cast<sal_Bool>(pExtn->fCritical) ) ; 434 } 435 } 436 437 return xExtn ; 438 } else { 439 return NULL ; 440 } 441 } 442 443 444 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl :: getEncoded() throw ( ::com::sun::star::uno::RuntimeException) { 445 if( m_pCertContext != NULL && m_pCertContext->cbCertEncoded > 0 ) { 446 Sequence< sal_Int8 > rawCert( m_pCertContext->cbCertEncoded ) ; 447 448 for( unsigned int i = 0 ; i < m_pCertContext->cbCertEncoded ; i ++ ) 449 rawCert[i] = *( m_pCertContext->pbCertEncoded + i ) ; 450 451 return rawCert ; 452 } else { 453 return Sequence< sal_Int8 >(); 454 } 455 } 456 457 //Helper methods 458 void X509Certificate_MSCryptImpl :: setMswcryCert( const CERT_CONTEXT* cert ) { 459 if( m_pCertContext != NULL ) { 460 CertFreeCertificateContext( m_pCertContext ) ; 461 m_pCertContext = NULL ; 462 } 463 464 if( cert != NULL ) { 465 m_pCertContext = CertDuplicateCertificateContext( cert ) ; 466 } 467 } 468 469 const CERT_CONTEXT* X509Certificate_MSCryptImpl :: getMswcryCert() const { 470 if( m_pCertContext != NULL ) { 471 return m_pCertContext ; 472 } else { 473 return NULL ; 474 } 475 } 476 477 void X509Certificate_MSCryptImpl :: setRawCert( Sequence< sal_Int8 > rawCert ) throw ( ::com::sun::star::uno::RuntimeException) { 478 if( m_pCertContext != NULL ) { 479 CertFreeCertificateContext( m_pCertContext ) ; 480 m_pCertContext = NULL ; 481 } 482 483 if( rawCert.getLength() != 0 ) { 484 m_pCertContext = CertCreateCertificateContext( X509_ASN_ENCODING, ( const sal_uInt8* )&rawCert[0], rawCert.getLength() ) ; 485 } 486 } 487 488 /* XUnoTunnel */ 489 sal_Int64 SAL_CALL X509Certificate_MSCryptImpl :: getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw( RuntimeException ) { 490 if( aIdentifier.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) { 491 return ( sal_Int64 )this ; 492 } 493 return 0 ; 494 } 495 496 /* XUnoTunnel extension */ 497 const Sequence< sal_Int8>& X509Certificate_MSCryptImpl :: getUnoTunnelId() { 498 static Sequence< sal_Int8 >* pSeq = 0 ; 499 if( !pSeq ) { 500 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ) ; 501 if( !pSeq ) { 502 static Sequence< sal_Int8> aSeq( 16 ) ; 503 rtl_createUuid( ( sal_uInt8* )aSeq.getArray() , 0 , sal_True ) ; 504 pSeq = &aSeq ; 505 } 506 } 507 return *pSeq ; 508 } 509 510 /* XUnoTunnel extension */ 511 X509Certificate_MSCryptImpl* X509Certificate_MSCryptImpl :: getImplementation( const Reference< XInterface > xObj ) { 512 Reference< XUnoTunnel > xUT( xObj , UNO_QUERY ) ; 513 if( xUT.is() ) { 514 return ( X509Certificate_MSCryptImpl* )xUT->getSomething( getUnoTunnelId() ) ; 515 } else 516 return NULL ; 517 } 518 519 // MM : added by MM 520 ::rtl::OUString findOIDDescription(char *oid) 521 { 522 OUString ouOID = OUString::createFromAscii( oid ); 523 for (int i=0; i<nOID; i++) 524 { 525 OUString item = OUString::createFromAscii( OIDs[i].oid ); 526 if (ouOID == item) 527 { 528 return OUString::createFromAscii( OIDs[i].desc ); 529 } 530 } 531 532 return OUString() ; 533 } 534 535 ::com::sun::star::uno::Sequence< sal_Int8 > getThumbprint(const CERT_CONTEXT* pCertContext, DWORD dwPropId) 536 { 537 if( pCertContext != NULL ) 538 { 539 DWORD cbData = 20; 540 unsigned char fingerprint[20]; 541 if (CertGetCertificateContextProperty(pCertContext, dwPropId, (void*)fingerprint, &cbData)) 542 { 543 Sequence< sal_Int8 > thumbprint( cbData ) ; 544 for( unsigned int i = 0 ; i < cbData ; i ++ ) 545 { 546 thumbprint[i] = fingerprint[i]; 547 } 548 549 return thumbprint; 550 } 551 else 552 { 553 DWORD e = GetLastError(); 554 cbData = e; 555 } 556 } 557 558 return Sequence< sal_Int8 >(); 559 } 560 561 ::rtl::OUString SAL_CALL X509Certificate_MSCryptImpl::getSubjectPublicKeyAlgorithm() 562 throw ( ::com::sun::star::uno::RuntimeException) 563 { 564 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) 565 { 566 CRYPT_ALGORITHM_IDENTIFIER algorithm = m_pCertContext->pCertInfo->SubjectPublicKeyInfo.Algorithm; 567 return findOIDDescription( algorithm.pszObjId ) ; 568 } 569 else 570 { 571 return OUString() ; 572 } 573 } 574 575 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl::getSubjectPublicKeyValue() 576 throw ( ::com::sun::star::uno::RuntimeException) 577 { 578 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) 579 { 580 CRYPT_BIT_BLOB publicKey = m_pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey; 581 582 Sequence< sal_Int8 > key( publicKey.cbData ) ; 583 for( unsigned int i = 0 ; i < publicKey.cbData ; i++ ) 584 { 585 key[i] = *(publicKey.pbData + i) ; 586 } 587 588 return key; 589 } 590 else 591 { 592 return Sequence< sal_Int8 >(); 593 } 594 } 595 596 ::rtl::OUString SAL_CALL X509Certificate_MSCryptImpl::getSignatureAlgorithm() 597 throw ( ::com::sun::star::uno::RuntimeException) 598 { 599 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL ) 600 { 601 CRYPT_ALGORITHM_IDENTIFIER algorithm = m_pCertContext->pCertInfo->SignatureAlgorithm; 602 return findOIDDescription( algorithm.pszObjId ) ; 603 } 604 else 605 { 606 return OUString() ; 607 } 608 } 609 610 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl::getSHA1Thumbprint() 611 throw ( ::com::sun::star::uno::RuntimeException) 612 { 613 return getThumbprint(m_pCertContext, CERT_SHA1_HASH_PROP_ID); 614 } 615 616 ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL X509Certificate_MSCryptImpl::getMD5Thumbprint() 617 throw ( ::com::sun::star::uno::RuntimeException) 618 { 619 return getThumbprint(m_pCertContext, CERT_MD5_HASH_PROP_ID); 620 } 621 622 sal_Int32 SAL_CALL X509Certificate_MSCryptImpl::getCertificateUsage( ) 623 throw ( ::com::sun::star::uno::RuntimeException) 624 { 625 sal_Int32 usage = 626 CERT_DATA_ENCIPHERMENT_KEY_USAGE | 627 CERT_DIGITAL_SIGNATURE_KEY_USAGE | 628 CERT_KEY_AGREEMENT_KEY_USAGE | 629 CERT_KEY_CERT_SIGN_KEY_USAGE | 630 CERT_KEY_ENCIPHERMENT_KEY_USAGE | 631 CERT_NON_REPUDIATION_KEY_USAGE | 632 CERT_OFFLINE_CRL_SIGN_KEY_USAGE; 633 634 if( m_pCertContext != NULL && m_pCertContext->pCertInfo != NULL && m_pCertContext->pCertInfo->cExtension != 0 ) 635 { 636 CERT_EXTENSION* pExtn = CertFindExtension( 637 szOID_KEY_USAGE, 638 m_pCertContext->pCertInfo->cExtension, 639 m_pCertContext->pCertInfo->rgExtension); 640 641 if (pExtn != NULL) 642 { 643 CERT_KEY_USAGE_RESTRICTION_INFO keyUsage; 644 DWORD length = sizeof(CERT_KEY_USAGE_RESTRICTION_INFO); 645 646 bool rc = CryptDecodeObject( 647 X509_ASN_ENCODING, 648 X509_KEY_USAGE, 649 pExtn->Value.pbData, 650 pExtn->Value.cbData, 651 CRYPT_DECODE_NOCOPY_FLAG, 652 (void *)&keyUsage, 653 &length); 654 655 if (rc && keyUsage.RestrictedKeyUsage.cbData!=0) 656 { 657 usage = (sal_Int32)keyUsage.RestrictedKeyUsage.pbData; 658 } 659 } 660 } 661 662 return usage; 663 } 664 665 // MM : end 666 667