cryptoservices/certificateandkeymgmt/wtlscert/wtlsnames.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     1 /*
       
     2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <wtlsnames.h>
       
    20 #include "wtlsdec.h"
       
    21 #include <x500dn.h>
       
    22 #include <utf.h>
       
    23 
       
    24 _LIT(KWTLSStructuredTextFieldSeparator, ";");
       
    25 _LIT(KWTLSStructuredTextAssignmentCharacter, "=");
       
    26 const TInt KWTLSTextHeaderLength = 3;
       
    27 
       
    28 EXPORT_C CWTLSName* CWTLSName::NewL(const TDesC8& aBinaryData)
       
    29 	{
       
    30 	TInt pos = 0;
       
    31 	return CWTLSName::NewL(aBinaryData, pos);
       
    32 	}
       
    33 
       
    34 EXPORT_C CWTLSName* CWTLSName::NewLC(const TDesC8& aBinaryData)
       
    35 	{
       
    36 	TInt pos = 0;
       
    37 	return CWTLSName::NewLC(aBinaryData, pos);
       
    38 	}
       
    39 
       
    40 EXPORT_C CWTLSName* CWTLSName::NewL(const TDesC8& aBinaryData, TInt& aPos)
       
    41 	{
       
    42 	CWTLSName* self = CWTLSName::NewLC(aBinaryData, aPos);
       
    43 	CleanupStack::Pop();
       
    44 	return self;
       
    45 	}
       
    46 
       
    47 EXPORT_C CWTLSName* CWTLSName::NewLC(const TDesC8& aBinaryData, TInt& aPos)
       
    48 	{
       
    49 	CWTLSName* self = new(ELeave) CWTLSName;
       
    50 	CleanupStack::PushL(self);
       
    51 	self->ConstructL(aBinaryData, aPos);
       
    52 	return self;
       
    53 	}
       
    54 
       
    55 EXPORT_C CWTLSName* CWTLSName::NewL(const CWTLSName& aName)
       
    56 	{
       
    57 	CWTLSName* self = CWTLSName::NewLC(aName);
       
    58 	CleanupStack::Pop();
       
    59 	return self;
       
    60 	}
       
    61 
       
    62 EXPORT_C CWTLSName* CWTLSName::NewLC(const CWTLSName& aName)	
       
    63 	{
       
    64 	CWTLSName* self = new(ELeave) CWTLSName;
       
    65 	CleanupStack::PushL(self);
       
    66 	self->ConstructL(aName);
       
    67 	return self;
       
    68 	}
       
    69 
       
    70 CWTLSName::CWTLSName() 	
       
    71 	{
       
    72 	}
       
    73 
       
    74 void CWTLSName::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
       
    75 	{
       
    76 	if ((aBinaryData.Length() - aPos) < 1)
       
    77 		{
       
    78 		User::Leave(KErrArgument);
       
    79 		}
       
    80 	iNameType = aBinaryData[aPos];
       
    81 	aPos++;
       
    82 	switch(iNameType)
       
    83 		{
       
    84 		case EWTLSText:
       
    85 			{
       
    86 			AllocTextDataL(aBinaryData, aPos);
       
    87 			break;
       
    88 			}
       
    89 		case EWTLSX500DN:
       
    90 			{
       
    91 			AllocNameDataL(aBinaryData, aPos);
       
    92 			break;
       
    93 			}
       
    94 		default:
       
    95 			{
       
    96 			User::Leave(KErrNotSupported);
       
    97 			}
       
    98 		}
       
    99 	}
       
   100 
       
   101 void CWTLSName::ConstructL(const CWTLSName& aName)
       
   102 	{
       
   103 	iNameType = aName.iNameType;
       
   104 	iNameData = aName.iNameData->AllocL();
       
   105 	}
       
   106 
       
   107 EXPORT_C CWTLSName::~CWTLSName() 	
       
   108 	{
       
   109 	delete iNameData;
       
   110 	}
       
   111 
       
   112 void CWTLSName::AllocTextDataL(const TDesC8& aBinaryData, TInt& aPos)
       
   113 	{
       
   114 	if ((aBinaryData.Length() - aPos) < KWTLSTextHeaderLength)
       
   115 		{
       
   116 		User::Leave(KErrArgument);
       
   117 		}
       
   118 	TInt nameLength = (aBinaryData[aPos+2] + KWTLSTextHeaderLength);
       
   119 	if ((aBinaryData.Length() ) < (aPos+nameLength))
       
   120 		{
       
   121 		User::Leave(KErrArgument);
       
   122 		}
       
   123 	iNameData = aBinaryData.Mid(aPos, nameLength).AllocL();
       
   124 	aPos += nameLength;
       
   125 	}
       
   126 
       
   127 void CWTLSName::AllocNameDataL(const TDesC8& aBinaryData, TInt& aPos)
       
   128 	{
       
   129 	if ((aBinaryData.Length() - aPos) < 1)
       
   130 		{
       
   131 		User::Leave(KErrArgument);
       
   132 		}
       
   133 	TUint8 nameLength = aBinaryData[aPos];
       
   134 	aPos++;
       
   135 	if (aBinaryData.Length() - (aPos + nameLength) < 0)
       
   136 		{
       
   137 		User::Leave(KErrArgument);
       
   138 		}
       
   139 	iNameData = aBinaryData.Mid(aPos, nameLength).AllocL();
       
   140 	aPos += nameLength;
       
   141 	}
       
   142 
       
   143 EXPORT_C TBool CWTLSName::ExactMatchL(const CWTLSName& aName) const	
       
   144 	{		
       
   145 //hmmm, in the absence of any matching rules, just match the bytes...
       
   146  	return (*(iNameData) == *(aName.iNameData));
       
   147 	}
       
   148 
       
   149 EXPORT_C TWTLSNameType CWTLSName::NameType() const
       
   150 	{
       
   151 	return iNameType;
       
   152 	}
       
   153 
       
   154 EXPORT_C TPtrC8 CWTLSName::NameData() const
       
   155 	{
       
   156 	return *iNameData;
       
   157 	}
       
   158 
       
   159 EXPORT_C HBufC* CWTLSName::DisplayNameL() const
       
   160 	{
       
   161 	switch (iNameType)
       
   162 		{
       
   163 		case EWTLSText:
       
   164 			{
       
   165 			CWTLSStructuredText* sText = NULL;
       
   166 			TRAPD(err, sText = CWTLSStructuredText::NewL(*iNameData));
       
   167 			if (err != KErrNone)
       
   168 				{
       
   169 				if (err != KErrArgument)
       
   170 					{
       
   171 					User::Leave(err);
       
   172 					}
       
   173 				else
       
   174 					{
       
   175 					CWTLSText* text = CWTLSText::NewLC(*iNameData);
       
   176 					HBufC* res = text->Name().AllocL();
       
   177 					CleanupStack::PopAndDestroy();//text
       
   178 					return res;
       
   179 					}
       
   180 				}
       
   181 			else
       
   182 				{
       
   183 				CleanupStack::PushL(sText);
       
   184 				HBufC* res = sText->DisplayNameL();
       
   185 				CleanupStack::PopAndDestroy();//sText
       
   186 				return res;
       
   187 				}
       
   188 			}
       
   189 		case EWTLSX500DN:
       
   190 			{
       
   191 			CX500DistinguishedName* dN = CX500DistinguishedName::NewLC(*iNameData);
       
   192 			HBufC* res = dN->DisplayNameL();
       
   193 			CleanupStack::PopAndDestroy();//dN
       
   194 			return res;
       
   195 			}
       
   196 		default:
       
   197 			{
       
   198 			User::Leave(KErrNotSupported);
       
   199 			return NULL;//never gets to here...
       
   200 			}
       
   201 		}
       
   202 	}
       
   203 
       
   204 //************************************************************************//
       
   205 //text name
       
   206 EXPORT_C CWTLSText* CWTLSText::NewL(const TDesC8& aBinaryData)
       
   207 	{
       
   208 	TInt pos = 0;
       
   209 	return CWTLSText::NewL(aBinaryData, pos);
       
   210 	}
       
   211 
       
   212 EXPORT_C CWTLSText* CWTLSText::NewLC(const TDesC8& aBinaryData)
       
   213 	{
       
   214 	TInt pos = 0;
       
   215 	return CWTLSText::NewLC(aBinaryData, pos);
       
   216 	}
       
   217 
       
   218 EXPORT_C CWTLSText* CWTLSText::NewL(const TDesC8& aBinaryData, TInt& aPos)
       
   219 	{
       
   220 	CWTLSText* self = CWTLSText::NewLC(aBinaryData, aPos);
       
   221 	CleanupStack::Pop();
       
   222 	return self;
       
   223 	}
       
   224 
       
   225 EXPORT_C CWTLSText* CWTLSText::NewLC(const TDesC8& aBinaryData, TInt& aPos)
       
   226 	{
       
   227 	CWTLSText* self = new(ELeave) CWTLSText;
       
   228 	CleanupStack::PushL(self);
       
   229 	self->ConstructL(aBinaryData, aPos);
       
   230 	return self;
       
   231 	}
       
   232 
       
   233 EXPORT_C CWTLSText::~CWTLSText() 	
       
   234 	{
       
   235 	delete iName;
       
   236 	}
       
   237 
       
   238 EXPORT_C TBool CWTLSText::ExactMatchL(const CWTLSText& aName) const
       
   239 	{
       
   240 //subtle difference between this byte-match and 
       
   241 //CWTLSName::ExactMatchL(...) is that this should successfully match 2 names that 
       
   242 //are the same which were encoded using different character sets...
       
   243 	return (*iName == *(aName.iName));
       
   244 	}
       
   245 
       
   246 EXPORT_C TPtrC CWTLSText::Name() const
       
   247 	{
       
   248 	return *iName;
       
   249 	}
       
   250 
       
   251 EXPORT_C TWTLSCharSet CWTLSText::CharacterSet() const
       
   252 	{
       
   253 	return iCharacterSet;
       
   254 	}
       
   255 
       
   256 CWTLSText::CWTLSText()
       
   257 	{
       
   258 	}
       
   259 
       
   260 void CWTLSText::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
       
   261 	{
       
   262 	if ((aBinaryData.Length() - aPos) < 3)
       
   263 		{
       
   264 		User::Leave(KErrArgument);
       
   265 		}
       
   266 	TWTLSDecUnsignedInteger decInt;
       
   267 	iCharacterSet = decInt.DecodeShortL(aBinaryData, aPos, 2);
       
   268 	TUint8 nameLength = aBinaryData[aPos];
       
   269 	aPos++;
       
   270 	if (aBinaryData.Length() < (aPos + nameLength))
       
   271 		{
       
   272 		User::Leave(KErrArgument);
       
   273 		}
       
   274 	TPtrC8 ptr = aBinaryData.Mid(aPos, nameLength);
       
   275 	//only works for latin-1 here...
       
   276 	iName = HBufC::NewL(ptr.Length());
       
   277 	switch (iCharacterSet)
       
   278 		{
       
   279 		case KWTLSLatin1CharSet://=latin-1
       
   280 			{
       
   281 			TPtr pRes = iName->Des();
       
   282 			pRes.Copy(ptr);
       
   283 			aPos+=nameLength;
       
   284 			break;
       
   285 			}
       
   286 		case KWTLSUTF8CharSet:
       
   287 			{
       
   288 			TPtr pRes = iName->Des();
       
   289 			User::LeaveIfError(CnvUtfConverter::ConvertToUnicodeFromUtf8(pRes, ptr));	
       
   290 			break;
       
   291 			}
       
   292 		default:
       
   293 			{
       
   294 			User::Leave(KErrNotSupported);
       
   295 			}
       
   296 		}
       
   297 	}
       
   298 
       
   299 TWTLSStructuredTextField::TWTLSStructuredTextField(const TDesC& aType, const TDesC& aValue)
       
   300 	:iType(aType), iValue(aValue)
       
   301 	{
       
   302 	}
       
   303 
       
   304 EXPORT_C TPtrC TWTLSStructuredTextField::Type() const
       
   305 	{
       
   306 	return iType;
       
   307 	}
       
   308 
       
   309 EXPORT_C TPtrC TWTLSStructuredTextField::Value() const
       
   310 	{
       
   311 	return iValue;
       
   312 	}
       
   313 
       
   314 //Structured text class
       
   315 EXPORT_C CWTLSStructuredText* CWTLSStructuredText::NewL(const TDesC8& aBinaryData)
       
   316 	{
       
   317 	TInt pos = 0;
       
   318 	return CWTLSStructuredText::NewL(aBinaryData, pos);
       
   319 	}
       
   320 
       
   321 EXPORT_C CWTLSStructuredText* CWTLSStructuredText::NewLC(const TDesC8& aBinaryData)
       
   322 	{
       
   323 	TInt pos = 0;
       
   324 	return CWTLSStructuredText::NewLC(aBinaryData, pos);
       
   325 	}
       
   326 
       
   327 EXPORT_C CWTLSStructuredText* CWTLSStructuredText::NewL(const TDesC8& aBinaryData, TInt& aPos)
       
   328 	{
       
   329 	CWTLSStructuredText* self = CWTLSStructuredText::NewLC(aBinaryData, aPos);
       
   330 	CleanupStack::Pop();
       
   331 	return self;
       
   332 	}
       
   333 
       
   334 EXPORT_C CWTLSStructuredText* CWTLSStructuredText::NewLC(const TDesC8& aBinaryData, TInt& aPos)
       
   335 	{
       
   336 	CWTLSStructuredText* self = new(ELeave) CWTLSStructuredText;
       
   337 	CleanupStack::PushL(self);
       
   338 	self->ConstructL(aBinaryData, aPos);
       
   339 	return self;
       
   340 	}
       
   341 
       
   342 EXPORT_C CWTLSStructuredText::~CWTLSStructuredText()
       
   343 	{
       
   344 	delete iFields;
       
   345 	}
       
   346 
       
   347 EXPORT_C HBufC* CWTLSStructuredText::DisplayNameL() const
       
   348 	{
       
   349 	if (iFields->Count() > 3)
       
   350 		{
       
   351 		return iFields->At(3).Value().AllocL();
       
   352 		}
       
   353 	else
       
   354 		{
       
   355 		return iFields->At(1).Value().AllocL();
       
   356 		}
       
   357 	}
       
   358 
       
   359 	//accessors for defined fields
       
   360 EXPORT_C TPtrC CWTLSStructuredText::ServiceName() const
       
   361 	{
       
   362 	//construction ensures iFields must have at least 3 elements
       
   363 	return iFields->At(0).Value();
       
   364 	}
       
   365 
       
   366 EXPORT_C TPtrC CWTLSStructuredText::Organization() const
       
   367 	{
       
   368 	//construction ensures iFields must have at least 3 elements
       
   369 	return iFields->At(1).Value();
       
   370 	}
       
   371 
       
   372 EXPORT_C TPtrC CWTLSStructuredText::Country() const
       
   373 	{
       
   374 	//construction ensures iFields must have at least 3 elements
       
   375 	return iFields->At(2).Value();
       
   376 	}
       
   377 
       
   378 EXPORT_C TInt CWTLSStructuredText::Count() const
       
   379 	{
       
   380 	return iFields->Count();
       
   381 	}
       
   382 
       
   383 EXPORT_C const TWTLSStructuredTextField* CWTLSStructuredText::FieldByName(const TDesC& aType) const
       
   384 	{
       
   385 	TInt count = iFields->Count();
       
   386 	for (TInt i = 0; i < count; i++)
       
   387 		{
       
   388 		TWTLSStructuredTextField* field = &(iFields->At(i));
       
   389 		if (field->Type() == aType)
       
   390 			{
       
   391 			return field;
       
   392 			}
       
   393 		}
       
   394 	return NULL;
       
   395 	}
       
   396 
       
   397 EXPORT_C const TWTLSStructuredTextField& CWTLSStructuredText::FieldByIndex(TInt aIndex) const
       
   398 	{
       
   399 	return iFields->At(aIndex);
       
   400 	}
       
   401 
       
   402 CWTLSStructuredText::CWTLSStructuredText()
       
   403 	{
       
   404 	}
       
   405 
       
   406 void CWTLSStructuredText::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
       
   407 	{
       
   408 	CWTLSText::ConstructL(aBinaryData, aPos);
       
   409 	iFields = new(ELeave) CArrayFixFlat<TWTLSStructuredTextField> (4);
       
   410 	TInt pos = 0;
       
   411 	TInt end = iName->Length();
       
   412 	AddFieldValueL(KWTLSServiceName, pos);
       
   413 	AddFieldValueL(KWTLSOrganizationName, pos);
       
   414 	AddFieldValueL(KWTLSCountryName, pos);
       
   415 	if (pos < end)
       
   416 		{
       
   417 		AddFieldValueL(KWTLSCommonName, pos);
       
   418 		}
       
   419 	while (pos < end)
       
   420 		{
       
   421 		AddFieldL(pos);
       
   422 		}
       
   423 	}
       
   424 
       
   425 void CWTLSStructuredText::AddFieldValueL(const TDesC& aFieldName, TInt& aPos)
       
   426 	{
       
   427 	TPtrC startOfData = iName->Right(iName->Length() - aPos);
       
   428 	TPtrC value = GetFieldL(startOfData, aPos);
       
   429 	TWTLSStructuredTextField field(aFieldName, value);
       
   430 	iFields->AppendL(field);
       
   431 	}
       
   432 
       
   433 void CWTLSStructuredText::AddFieldL(TInt& aPos)
       
   434 	{
       
   435 	TPtrC startOfData = iName->Right(iName->Length() - aPos);
       
   436 	TPtrC fieldData = GetFieldL(startOfData, aPos);
       
   437 	TInt fieldLength = fieldData.Length();
       
   438 	TInt endType = fieldData.FindF(KWTLSStructuredTextAssignmentCharacter);
       
   439 	if ((endType == KErrNotFound) || ((endType+1) == fieldLength))
       
   440 		{
       
   441 		User::Leave(KErrArgument);
       
   442 		}
       
   443 	TPtrC type = fieldData.Left(endType);
       
   444 	TPtrC value = fieldData.Right(	fieldLength - (endType+1)	);
       
   445 	TWTLSStructuredTextField field(type, value);
       
   446 	iFields->AppendL(field);
       
   447 	}
       
   448 
       
   449 TPtrC CWTLSStructuredText::GetFieldL(TDesC& aString, TInt& aPos)
       
   450 	{
       
   451 //aString = where we've got up to
       
   452 //aPos = start of this chunk of name data
       
   453 	TInt length = 0;
       
   454 	TBool done = GetSubFieldL(aString, length);
       
   455 	while (!done)
       
   456 		{
       
   457 		TPtrC remainder = aString.Right(aString.Length() - (length));
       
   458 		TInt increment = 0;
       
   459 		done = GetSubFieldL(remainder, increment);
       
   460 		length += increment;
       
   461 		}
       
   462 	if (length == 0)
       
   463 		{
       
   464 		//disallow zero-length field values
       
   465 		User::Leave(KErrArgument);
       
   466 		}
       
   467 	aPos += length;
       
   468 	if (length < aString.Length())
       
   469 		{
       
   470 		//if we're not on the last field, skip the ';' character
       
   471 		aPos++;
       
   472 		}
       
   473 	return aString.Left(length);
       
   474 	}
       
   475 
       
   476 TBool CWTLSStructuredText::GetSubFieldL(TDesC& aString, TInt& aPos)
       
   477 	{
       
   478 //fields in structured text are separated by ';'. If this character appears 
       
   479 //in the field text it's represented by ';;'.  so, the string 'symbian;systems' would
       
   480 //be encoded as 'symbian;;systems'. 
       
   481 
       
   482 //starting at the start of aString, this function sets 'aPos' to the position after the 
       
   483 //first occurrence of ';' in aString. If the character following ';' is also ';' it returns 
       
   484 //EFalse (meaning, this sub-field isn't a whole field), otherwise it returns ETrue.
       
   485 
       
   486 	aPos = aString.FindF(KWTLSStructuredTextFieldSeparator);	
       
   487 	if (aPos == KErrNotFound)
       
   488 		{
       
   489 		aPos = aString.Length();
       
   490 		}
       
   491 	else
       
   492 		{		
       
   493 		//separator char mustn't be last char
       
   494 		if (aPos == (aString.Length() -1))
       
   495 			{
       
   496 			User::Leave(KErrArgument);
       
   497 			}
       
   498 		else
       
   499 			{
       
   500 			//if the next char is ';', skip it and return EFalse
       
   501 			TPtrC next = aString.Mid(aPos + 1, 1);
       
   502 			if (next == KWTLSStructuredTextFieldSeparator)
       
   503 				{
       
   504 				aPos++;
       
   505 				return EFalse;
       
   506 				}
       
   507 			//if it isn't, that's the end of the field
       
   508 			}
       
   509 		}
       
   510 	return ETrue;
       
   511 	}