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