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 >
findTypeInDN(const OUString & rRawString,const OUString & sTypeName)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
replaceTagSWithTagST(OUString oldDN)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
X509Certificate_MSCryptImpl()178 X509Certificate_MSCryptImpl :: X509Certificate_MSCryptImpl() :
179 m_pCertContext( NULL )
180 {
181 }
182
~X509Certificate_MSCryptImpl()183 X509Certificate_MSCryptImpl :: ~X509Certificate_MSCryptImpl() {
184 if( m_pCertContext != NULL ) {
185 CertFreeCertificateContext( m_pCertContext ) ;
186 }
187 }
188
189 //Methods from XCertificate
getVersion()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
getSerialNumber()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
getIssuerName()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
getSubjectName()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
getNotValidBefore()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
getNotValidAfter()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
getIssuerUniqueID()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
getSubjectUniqueID()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
getExtensions()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
findCertificateExtension(const::com::sun::star::uno::Sequence<sal_Int8> &)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
getEncoded()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
setMswcryCert(const CERT_CONTEXT * cert)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
getMswcryCert() const465 const CERT_CONTEXT* X509Certificate_MSCryptImpl :: getMswcryCert() const {
466 if( m_pCertContext != NULL ) {
467 return m_pCertContext ;
468 } else {
469 return NULL ;
470 }
471 }
472
setRawCert(Sequence<sal_Int8> rawCert)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 */
getSomething(const Sequence<sal_Int8> & aIdentifier)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 */
getUnoTunnelId()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 */
getImplementation(const Reference<XInterface> xObj)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
findOIDDescription(char * oid)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
getThumbprint(const CERT_CONTEXT * pCertContext,DWORD dwPropId)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
getSubjectPublicKeyAlgorithm()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
getSubjectPublicKeyValue()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
getSignatureAlgorithm()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
getSHA1Thumbprint()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
getMD5Thumbprint()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
getCertificateUsage()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