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