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
GetResMgr(void)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
GetLocaleData(void)61 const LocaleDataWrapper& GetLocaleData( void )
62 {
63 if (!pSysLocale)
64 pSysLocale = new SvtSysLocale;
65 return pSysLocale->GetLocaleData();
66 }
67
GetDateTime(const::com::sun::star::util::DateTime & _rDT)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
GetDateTimeString(const::com::sun::star::util::DateTime & _rDT)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
GetDateTimeString(const rtl::OUString & _rDate,const rtl::OUString & _rTime)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
GetDateString(const::com::sun::star::util::DateTime & _rDT)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 */
GetDNForCertDetailsView(const OUString & rRawString)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
parseDN(const OUString & rRawString)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
parseDN(const OUString & rRawString)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
GetContentPart(const String & _rRawString)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
GetHexString(const::com::sun::star::uno::Sequence<sal_Int8> & _rSeq,const char * _pSep,sal_uInt16 _nLineBreak)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
ShrinkToFitWidth(Control & _rCtrl,long _nOffs)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
AlignAfterImage(const FixedImage & _rImage,Control & _rCtrl,long _nXOffset)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
AlignAfterImage(const FixedImage & _rImage,FixedInfo & _rFI,long _nXOffset)414 void AlignAfterImage( const FixedImage& _rImage, FixedInfo& _rFI, long _nXOffset )
415 {
416 AlignAfterImage( _rImage, static_cast< Control& >( _rFI ), _nXOffset );
417 ShrinkToFitWidth( _rFI );
418 }
419
AlignAndFitImageAndControl(FixedImage & _rImage,FixedInfo & _rFI,long _nXOffset)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