xref: /AOO41X/main/xmlsecurity/source/xmlsec/mscrypt/x509certificate_mscryptimpl.cxx (revision 06b3ce531745799678cf4bb887ef37436d81238b)
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