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