1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_xmlsecurity.hxx" 30 31 #include "resourcemanager.hxx" 32 33 #include <vcl/svapp.hxx> 34 #include <vcl/fixed.hxx> 35 #include <svtools/stdctrl.hxx> 36 #include <svl/solar.hrc> 37 #include <unotools/syslocale.hxx> 38 #include <rtl/ustring.h> 39 #include <rtl/ustrbuf.h> 40 #include <vector> 41 42 using ::rtl::OUString; 43 using namespace std; 44 45 namespace XmlSec 46 { 47 static ResMgr* pResMgr = 0; 48 static SvtSysLocale* pSysLocale = 0; 49 50 ResMgr* GetResMgr( void ) 51 { 52 if( !pResMgr ) 53 { 54 ByteString aName( "xmlsec" ); 55 // pResMgr = ResMgr::CreateResMgr( aName.GetBuffer(), Application::GetSettings().GetUILanguage() ); 56 // LanguageType aLang( LANGUAGE_ENGLISH_US ); 57 // pResMgr = ResMgr::CreateResMgr( aName.GetBuffer(), aLang ); 58 // MT: Change to Locale 59 pResMgr = ResMgr::CreateResMgr( aName.GetBuffer() ); 60 } 61 62 return pResMgr; 63 } 64 65 const LocaleDataWrapper& GetLocaleData( void ) 66 { 67 if (!pSysLocale) 68 pSysLocale = new SvtSysLocale; 69 return pSysLocale->GetLocaleData(); 70 } 71 72 DateTime GetDateTime( const ::com::sun::star::util::DateTime& _rDT ) 73 { 74 return DateTime( 75 Date( _rDT.Day, _rDT.Month, _rDT.Year ), 76 Time( _rDT.Hours, _rDT.Minutes, _rDT.Seconds, _rDT.HundredthSeconds ) ); 77 } 78 79 String GetDateTimeString( const ::com::sun::star::util::DateTime& _rDT ) 80 { 81 // --> PB 2004-10-12 #i20172# String with date and time information 82 DateTime aDT( GetDateTime( _rDT ) ); 83 const LocaleDataWrapper& rLoDa = GetLocaleData(); 84 String sRet( rLoDa.getDate( aDT ) ); 85 sRet += ' '; 86 sRet += rLoDa.getTime( aDT ); 87 return sRet; 88 } 89 90 String GetDateTimeString( const rtl::OUString& _rDate, const rtl::OUString& _rTime ) 91 { 92 String sDay( _rDate, 6, 2 ); 93 String sMonth( _rDate, 4, 2 ); 94 String sYear( _rDate, 0, 4 ); 95 96 String sHour( _rTime, 0, 2 ); 97 String sMin( _rTime, 4, 2 ); 98 String sSec( _rTime, 6, 2 ); 99 100 101 Date aDate( (sal_uInt16)sDay.ToInt32(), (sal_uInt16) sMonth.ToInt32(), (sal_uInt16)sYear.ToInt32() ); 102 Time aTime( sHour.ToInt32(), sMin.ToInt32(), sSec.ToInt32(), 0 ); 103 const LocaleDataWrapper& rLoDa = GetLocaleData(); 104 String aStr( rLoDa.getDate( aDate ) ); 105 aStr.AppendAscii( " " ); 106 aStr += rLoDa.getTime( aTime ); 107 return aStr; 108 } 109 110 String GetDateString( const ::com::sun::star::util::DateTime& _rDT ) 111 { 112 return GetLocaleData().getDate( GetDateTime( _rDT ) ); 113 } 114 115 /* 116 Creates two strings based on the distinguished name which are displayed in the 117 certificate details view. The first string contains only the values of the attribute 118 and valudes pairs, which are separated by commas. All escape characters ('"') are 119 removed. 120 The second string is for the details view at the bottom. It shows the attribute/value 121 pairs on different lines. All escape characters ('"') are removed. 122 */ 123 pair< OUString, OUString> GetDNForCertDetailsView( const OUString & rRawString) 124 { 125 vector< pair< OUString, OUString > > vecAttrValueOfDN = parseDN(rRawString); 126 ::rtl::OUStringBuffer s1, s2; 127 OUString sEqual(RTL_CONSTASCII_USTRINGPARAM(" = ")); 128 typedef vector< pair < OUString, OUString > >::const_iterator CIT; 129 for (CIT i = vecAttrValueOfDN.begin(); i < vecAttrValueOfDN.end(); i ++) 130 { 131 if (i != vecAttrValueOfDN.begin()) 132 { 133 s1.append(static_cast<sal_Unicode>(',')); 134 s2.append(static_cast<sal_Unicode>('\n')); 135 } 136 s1.append(i->second); 137 s2.append(i->first); 138 s2.append(sEqual); 139 s2.append(i->second); 140 } 141 return make_pair(s1.makeStringAndClear(), s2.makeStringAndClear()); 142 } 143 144 /* 145 Whenever the attribute value contains special characters, such as '"' or ',' (without '') 146 then the value will be enclosed in double quotes by the respective Windows or NSS function 147 which we use to retrieve, for example, the subject name. If double quotes appear in the value then 148 they are escaped with a double quote. This function removes the escape characters. 149 */ 150 #ifdef WNT 151 vector< pair< OUString, OUString> > parseDN(const OUString& rRawString) 152 { 153 vector< pair<OUString, OUString> > retVal; 154 bool bInEscape = false; 155 bool bInValue = false; 156 bool bInType = true; 157 sal_Int32 nTypeNameStart = 0; 158 OUString sType; 159 ::rtl::OUStringBuffer sbufValue; 160 sal_Int32 length = rRawString.getLength(); 161 162 for (sal_Int32 i = 0; i < length; i++) 163 { 164 sal_Unicode c = rRawString[i]; 165 166 if (c == '=') 167 { 168 if (! bInValue) 169 { 170 sType = rRawString.copy(nTypeNameStart, i - nTypeNameStart); 171 sType = sType.trim(); 172 bInType = false; 173 } 174 else 175 { 176 sbufValue.append(c); 177 } 178 } 179 else if (c == '"') 180 { 181 if (!bInEscape) 182 { 183 //If this is the quote is the first of the couple which enclose the 184 //whole value, because the value contains special characters 185 //then we just drop it. That is, this character must be followed by 186 //a character which is not '"'. 187 if ( i + 1 < length && rRawString[i+1] == '"') 188 bInEscape = true; 189 else 190 bInValue = !bInValue; //value is enclosed in " " 191 } 192 else 193 { 194 //This quote is escaped by a preceding quote and therefore is 195 //part of the value 196 sbufValue.append(c); 197 bInEscape = false; 198 } 199 } 200 else if (c == ',' || c == '+') 201 { 202 //The comma separate the attribute value pairs. 203 //If the comma is not part of a value (the value would then be enclosed in '"'), 204 //then we have reached the end of the value 205 if (!bInValue) 206 { 207 OSL_ASSERT(sType.getLength()); 208 retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear())); 209 sType = OUString(); 210 //The next char is the start of the new type 211 nTypeNameStart = i + 1; 212 bInType = true; 213 } 214 else 215 { 216 //The whole string is enclosed because it contains special characters. 217 //The enclosing '"' are not part of certificate but will be added by 218 //the function (Windows or NSS) which retrieves DN 219 sbufValue.append(c); 220 } 221 } 222 else 223 { 224 if (!bInType) 225 sbufValue.append(c); 226 } 227 } 228 if (sbufValue.getLength()) 229 { 230 OSL_ASSERT(sType.getLength()); 231 retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear())); 232 } 233 return retVal; 234 } 235 #else 236 vector< pair< OUString, OUString> > parseDN(const OUString& rRawString) 237 { 238 vector< pair<OUString, OUString> > retVal; 239 //bInEscape == true means that the preceding character is an escape character 240 bool bInEscape = false; 241 bool bInValue = false; 242 bool bInType = true; 243 sal_Int32 nTypeNameStart = 0; 244 OUString sType; 245 ::rtl::OUStringBuffer sbufValue; 246 sal_Int32 length = rRawString.getLength(); 247 248 for (sal_Int32 i = 0; i < length; i++) 249 { 250 sal_Unicode c = rRawString[i]; 251 252 if (c == '=') 253 { 254 if (! bInValue) 255 { 256 sType = rRawString.copy(nTypeNameStart, i - nTypeNameStart); 257 sType = sType.trim(); 258 bInType = false; 259 } 260 else 261 { 262 sbufValue.append(c); 263 } 264 } 265 else if (c == '\\') 266 { 267 if (!bInEscape) 268 { 269 bInEscape = true; 270 } 271 else 272 { // bInEscape is true 273 sbufValue.append(c); 274 bInEscape = false; 275 } 276 } 277 else if (c == '"') 278 { 279 //an unescaped '"' is either at the beginning or end of the value 280 if (!bInEscape) 281 { 282 if ( !bInValue) 283 bInValue = true; 284 else if (bInValue) 285 bInValue = false; 286 } 287 else 288 { 289 //This quote is escaped by a preceding quote and therefore is 290 //part of the value 291 sbufValue.append(c); 292 bInEscape = false; 293 } 294 } 295 else if (c == ',' || c == '+') 296 { 297 //The comma separate the attribute value pairs. 298 //If the comma is not part of a value (the value would then be enclosed in '"'), 299 //then we have reached the end of the value 300 if (!bInValue) 301 { 302 OSL_ASSERT(sType.getLength()); 303 retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear())); 304 sType = OUString(); 305 //The next char is the start of the new type 306 nTypeNameStart = i + 1; 307 bInType = true; 308 } 309 else 310 { 311 //The whole string is enclosed because it contains special characters. 312 //The enclosing '"' are not part of certificate but will be added by 313 //the function (Windows or NSS) which retrieves DN 314 sbufValue.append(c); 315 } 316 } 317 else 318 { 319 if (!bInType) 320 { 321 sbufValue.append(c); 322 bInEscape = false; 323 } 324 } 325 } 326 if (sbufValue.getLength()) 327 { 328 OSL_ASSERT(sType.getLength()); 329 retVal.push_back(make_pair(sType, sbufValue.makeStringAndClear())); 330 } 331 return retVal; 332 } 333 334 #endif 335 336 String GetContentPart( const String& _rRawString ) 337 { 338 char const * aIDs[] = { "CN", "OU", "O", "E", NULL }; 339 OUString retVal; 340 int i = 0; 341 vector< pair< OUString, OUString > > vecAttrValueOfDN = parseDN(_rRawString); 342 while ( aIDs[i] ) 343 { 344 OUString sPartId = OUString::createFromAscii( aIDs[i++] ); 345 typedef vector< pair < OUString, OUString > >::const_iterator CIT; 346 for (CIT idn = vecAttrValueOfDN.begin(); idn != vecAttrValueOfDN.end(); idn++) 347 { 348 if (idn->first.equals(sPartId)) 349 { 350 retVal = idn->second; 351 break; 352 } 353 } 354 if (retVal.getLength()) 355 break; 356 } 357 return retVal; 358 } 359 360 String GetHexString( const ::com::sun::star::uno::Sequence< sal_Int8 >& _rSeq, const char* _pSep, sal_uInt16 _nLineBreak ) 361 { 362 const sal_Int8* pSerNumSeq = _rSeq.getConstArray(); 363 int nCnt = _rSeq.getLength(); 364 String aStr; 365 const char pHexDigs[ 17 ] = "0123456789ABCDEF"; 366 char pBuffer[ 3 ] = " "; 367 sal_uInt8 nNum; 368 sal_uInt16 nBreakStart = _nLineBreak? _nLineBreak : 1; 369 sal_uInt16 nBreak = nBreakStart; 370 for( int i = 0 ; i < nCnt ; ++i ) 371 { 372 nNum = sal_uInt8( pSerNumSeq[ i ] ); 373 374 //MM : exchange the buffer[0] and buffer[1], which make it consistent with Mozilla and Windows 375 pBuffer[ 1 ] = pHexDigs[ nNum & 0x0F ]; 376 nNum >>= 4; 377 pBuffer[ 0 ] = pHexDigs[ nNum ]; 378 aStr.AppendAscii( pBuffer ); 379 380 --nBreak; 381 if( nBreak ) 382 aStr.AppendAscii( _pSep ); 383 else 384 { 385 nBreak = nBreakStart; 386 aStr.AppendAscii( "\n" ); 387 } 388 } 389 390 return aStr; 391 } 392 393 long ShrinkToFitWidth( Control& _rCtrl, long _nOffs ) 394 { 395 long nWidth = _rCtrl.GetTextWidth( _rCtrl.GetText() ); 396 Size aSize( _rCtrl.GetSizePixel() ); 397 nWidth += _nOffs; 398 aSize.Width() = nWidth; 399 _rCtrl.SetSizePixel( aSize ); 400 return nWidth; 401 } 402 403 void AlignAfterImage( const FixedImage& _rImage, Control& _rCtrl, long _nXOffset ) 404 { 405 Point aPos( _rImage.GetPosPixel() ); 406 Size aSize( _rImage.GetSizePixel() ); 407 long n = aPos.X(); 408 n += aSize.Width(); 409 n += _nXOffset; 410 aPos.X() = n; 411 n = aPos.Y(); 412 n += aSize.Height() / 2; // y-position is in the middle of the image 413 n -= _rCtrl.GetSizePixel().Height() / 2; // center Control 414 aPos.Y() = n; 415 _rCtrl.SetPosPixel( aPos ); 416 } 417 418 void AlignAfterImage( const FixedImage& _rImage, FixedInfo& _rFI, long _nXOffset ) 419 { 420 AlignAfterImage( _rImage, static_cast< Control& >( _rFI ), _nXOffset ); 421 ShrinkToFitWidth( _rFI ); 422 } 423 424 void AlignAndFitImageAndControl( FixedImage& _rImage, FixedInfo& _rFI, long _nXOffset ) 425 { 426 _rImage.SetSizePixel( _rImage.GetImage().GetSizePixel() ); 427 AlignAfterImage( _rImage, _rFI, _nXOffset ); 428 } 429 } 430 431 432