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