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