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