| sl@0 |      1 | /*
 | 
| sl@0 |      2 | * Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
 | 
| sl@0 |      3 | * All rights reserved.
 | 
| sl@0 |      4 | * This component and the accompanying materials are made available
 | 
| sl@0 |      5 | * under the terms of the License "Eclipse Public License v1.0"
 | 
| sl@0 |      6 | * which accompanies this distribution, and is available
 | 
| sl@0 |      7 | * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 | 
| sl@0 |      8 | *
 | 
| sl@0 |      9 | * Initial Contributors:
 | 
| sl@0 |     10 | * Nokia Corporation - initial contribution.
 | 
| sl@0 |     11 | *
 | 
| sl@0 |     12 | * Contributors:
 | 
| sl@0 |     13 | *
 | 
| sl@0 |     14 | * Description: 
 | 
| sl@0 |     15 | *
 | 
| sl@0 |     16 | */
 | 
| sl@0 |     17 | 
 | 
| sl@0 |     18 | 
 | 
| sl@0 |     19 | #include <x520ava.h>
 | 
| sl@0 |     20 | #include "X500dec.h"
 | 
| sl@0 |     21 | #include <asn1enc.h>
 | 
| sl@0 |     22 | #include <asn1dec.h>
 | 
| sl@0 |     23 | 
 | 
| sl@0 |     24 | 
 | 
| sl@0 |     25 | EXPORT_C CX520AttributeTypeAndValue* CX520AttributeTypeAndValue::NewL(const CX520AttributeTypeAndValue& aPair)
 | 
| sl@0 |     26 | 	{
 | 
| sl@0 |     27 | 	CX520AttributeTypeAndValue* self = CX520AttributeTypeAndValue::NewLC(aPair);
 | 
| sl@0 |     28 | 	CleanupStack::Pop();//self
 | 
| sl@0 |     29 | 	return self;
 | 
| sl@0 |     30 | 	}
 | 
| sl@0 |     31 | 
 | 
| sl@0 |     32 | EXPORT_C CX520AttributeTypeAndValue* CX520AttributeTypeAndValue::NewLC(const CX520AttributeTypeAndValue& aPair)
 | 
| sl@0 |     33 | 	{
 | 
| sl@0 |     34 | 	CX520AttributeTypeAndValue* self = new(ELeave) CX520AttributeTypeAndValue;
 | 
| sl@0 |     35 | 	CleanupStack::PushL(self);
 | 
| sl@0 |     36 | 	self->ConstructL(aPair);
 | 
| sl@0 |     37 | 	return self;
 | 
| sl@0 |     38 | 	}
 | 
| sl@0 |     39 | 
 | 
| sl@0 |     40 | EXPORT_C CX520AttributeTypeAndValue* CX520AttributeTypeAndValue::NewL(const TDesC8& aBinaryData)
 | 
| sl@0 |     41 | 	{
 | 
| sl@0 |     42 | 	TInt pos = 0;
 | 
| sl@0 |     43 | 	return CX520AttributeTypeAndValue::NewL(aBinaryData, pos);
 | 
| sl@0 |     44 | 	}
 | 
| sl@0 |     45 | 
 | 
| sl@0 |     46 | EXPORT_C CX520AttributeTypeAndValue* CX520AttributeTypeAndValue::NewLC(const TDesC8& aBinaryData)
 | 
| sl@0 |     47 | 	{
 | 
| sl@0 |     48 | 	TInt pos = 0;
 | 
| sl@0 |     49 | 	return CX520AttributeTypeAndValue::NewLC(aBinaryData, pos);
 | 
| sl@0 |     50 | 	}
 | 
| sl@0 |     51 | 
 | 
| sl@0 |     52 | EXPORT_C CX520AttributeTypeAndValue* CX520AttributeTypeAndValue::NewL(const TDesC8& aBinaryData, TInt& aPos)
 | 
| sl@0 |     53 | 	{
 | 
| sl@0 |     54 | 	CX520AttributeTypeAndValue* self = CX520AttributeTypeAndValue::NewLC(aBinaryData, aPos);
 | 
| sl@0 |     55 | 	CleanupStack::Pop();
 | 
| sl@0 |     56 | 	return self;
 | 
| sl@0 |     57 | 	}
 | 
| sl@0 |     58 | 
 | 
| sl@0 |     59 | EXPORT_C CX520AttributeTypeAndValue* CX520AttributeTypeAndValue::NewLC(const TDesC8& aBinaryData, TInt& aPos)
 | 
| sl@0 |     60 | 	{
 | 
| sl@0 |     61 | 	CX520AttributeTypeAndValue* self = new(ELeave) CX520AttributeTypeAndValue;
 | 
| sl@0 |     62 | 	CleanupStack::PushL(self);
 | 
| sl@0 |     63 | 	self->ConstructL(aBinaryData, aPos);
 | 
| sl@0 |     64 | 	return self;
 | 
| sl@0 |     65 | 	}
 | 
| sl@0 |     66 | 
 | 
| sl@0 |     67 | EXPORT_C CX520AttributeTypeAndValue* CX520AttributeTypeAndValue::NewL(RReadStream& aStream)
 | 
| sl@0 |     68 | 	{
 | 
| sl@0 |     69 | 	CX520AttributeTypeAndValue* self = CX520AttributeTypeAndValue::NewLC(aStream);
 | 
| sl@0 |     70 | 	CleanupStack::Pop();//self
 | 
| sl@0 |     71 | 	return self;
 | 
| sl@0 |     72 | 	}
 | 
| sl@0 |     73 | 
 | 
| sl@0 |     74 | EXPORT_C CX520AttributeTypeAndValue* CX520AttributeTypeAndValue::NewLC(RReadStream& aStream)
 | 
| sl@0 |     75 | 	{
 | 
| sl@0 |     76 | 	CX520AttributeTypeAndValue* self = new(ELeave) CX520AttributeTypeAndValue;
 | 
| sl@0 |     77 | 	CleanupStack::PushL(self);
 | 
| sl@0 |     78 | 	self->InternalizeL(aStream);
 | 
| sl@0 |     79 | 	return self;
 | 
| sl@0 |     80 | 	}
 | 
| sl@0 |     81 | 
 | 
| sl@0 |     82 | /** Allocates and initializes a new attribute-value pair object from 
 | 
| sl@0 |     83 | 	type and value.
 | 
| sl@0 |     84 | 	@param aType Type of the value (see TAttributeType enum).
 | 
| sl@0 |     85 | 	@param aValue String value of the attribute.
 | 
| sl@0 |     86 | 	@return Pointer to a newly allocated and initialized attribute-value pair.
 | 
| sl@0 |     87 | 	@see CX520AttributeTypeAndValue::NewLC */
 | 
| sl@0 |     88 | EXPORT_C CX520AttributeTypeAndValue* CX520AttributeTypeAndValue::NewL(TAttributeType aType, const TDesC8& aValue)
 | 
| sl@0 |     89 | 	{
 | 
| sl@0 |     90 | 	CX520AttributeTypeAndValue* self = CX520AttributeTypeAndValue::NewLC(aType, aValue);
 | 
| sl@0 |     91 | 	CleanupStack::Pop(); // self
 | 
| sl@0 |     92 | 	return self;
 | 
| sl@0 |     93 | 	}
 | 
| sl@0 |     94 | 
 | 
| sl@0 |     95 | /** Allocates and initializes a new attribute-value pair object from 
 | 
| sl@0 |     96 | 	type and value. Pushes the newly allocated object onto the 
 | 
| sl@0 |     97 | 	cleanup stack.
 | 
| sl@0 |     98 | 	@param aType Type of the value (see TAttributeType enum).
 | 
| sl@0 |     99 | 	@param aValue String value of the attribute.
 | 
| sl@0 |    100 | 	@return Pointer to a newly allocated and initialized attribute-value pair.
 | 
| sl@0 |    101 | 	@see CX520AttributeTypeAndValue::NewL */
 | 
| sl@0 |    102 | EXPORT_C CX520AttributeTypeAndValue* CX520AttributeTypeAndValue::NewLC(
 | 
| sl@0 |    103 | 											TAttributeType aType, 
 | 
| sl@0 |    104 | 											const TDesC8& aValue)
 | 
| sl@0 |    105 | 	{
 | 
| sl@0 |    106 | 	CX520AttributeTypeAndValue* self = new(ELeave) CX520AttributeTypeAndValue;
 | 
| sl@0 |    107 | 	CleanupStack::PushL(self);
 | 
| sl@0 |    108 | 	self->ConstructL(aType, aValue);
 | 
| sl@0 |    109 | 	return self;
 | 
| sl@0 |    110 | 	}
 | 
| sl@0 |    111 | 
 | 
| sl@0 |    112 | CX520AttributeTypeAndValue::CX520AttributeTypeAndValue()
 | 
| sl@0 |    113 | 	:iType(NULL), iValue(NULL)
 | 
| sl@0 |    114 | 	{
 | 
| sl@0 |    115 | 	}
 | 
| sl@0 |    116 | 
 | 
| sl@0 |    117 | void CX520AttributeTypeAndValue::ConstructL(const CX520AttributeTypeAndValue& aPair)
 | 
| sl@0 |    118 | 	{
 | 
| sl@0 |    119 | 	iType = aPair.iType->AllocL();
 | 
| sl@0 |    120 | 	iValue = aPair.iValue->AllocL();
 | 
| sl@0 |    121 | 	}
 | 
| sl@0 |    122 | 
 | 
| sl@0 |    123 | void CX520AttributeTypeAndValue::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
 | 
| sl@0 |    124 | 	{
 | 
| sl@0 |    125 | 	TASN1DecGeneric dec(aBinaryData.Right(aBinaryData.Length() - aPos));
 | 
| sl@0 |    126 | 	dec.InitL();
 | 
| sl@0 |    127 | 	TInt end = aPos + dec.LengthDER();
 | 
| sl@0 |    128 | 	aPos += dec.LengthDERHeader();
 | 
| sl@0 |    129 | 
 | 
| sl@0 |    130 | 	//first element must be the id
 | 
| sl@0 |    131 | 	TASN1DecObjectIdentifier encOID;
 | 
| sl@0 |    132 | 	iType = encOID.DecodeDERL(aBinaryData, aPos);
 | 
| sl@0 |    133 | 	//second is the data
 | 
| sl@0 |    134 | 	TASN1DecGeneric second(aBinaryData.Right(aBinaryData.Length() - aPos));
 | 
| sl@0 |    135 | 	second.InitL();
 | 
| sl@0 |    136 | 
 | 
| sl@0 |    137 | 	iValue = second.Encoding().AllocL();;
 | 
| sl@0 |    138 | 	aPos += second.LengthDER();
 | 
| sl@0 |    139 | 
 | 
| sl@0 |    140 | 	if (aPos != end)
 | 
| sl@0 |    141 | 		{
 | 
| sl@0 |    142 | 		User::Leave(KErrArgument);
 | 
| sl@0 |    143 | 		}
 | 
| sl@0 |    144 | 	}
 | 
| sl@0 |    145 | 
 | 
| sl@0 |    146 | void CX520AttributeTypeAndValue::ConstructL(TAttributeType aType, const TDesC8& aValue)
 | 
| sl@0 |    147 | 	{
 | 
| sl@0 |    148 | 	// iType is string representation of OID corresponding to the aType.
 | 
| sl@0 |    149 | 	TPtrC ptr;
 | 
| sl@0 |    150 | 	TInt maxlen = 64; // a reasonable default
 | 
| sl@0 |    151 | 	TTagType type = EASN1PrintableString; // the default for all except email, unstructured name and domain component
 | 
| sl@0 |    152 | 	switch(aType)
 | 
| sl@0 |    153 | 		{
 | 
| sl@0 |    154 | 		case ECommonName: 
 | 
| sl@0 |    155 | 			ptr.Set(KX520CommonName); 
 | 
| sl@0 |    156 | 			maxlen = KX520MaxCNLength;
 | 
| sl@0 |    157 | 			break;
 | 
| sl@0 |    158 | 		case ELocalityName:
 | 
| sl@0 |    159 | 			ptr.Set(KX520LocalityName);
 | 
| sl@0 |    160 | 			maxlen = KX520MaxLLength;
 | 
| sl@0 |    161 | 			break;
 | 
| sl@0 |    162 | 		case EStateOrProvinceName:
 | 
| sl@0 |    163 | 			ptr.Set(KX520StateOrProvinceName);
 | 
| sl@0 |    164 | 			maxlen = KX520MaxSOPLength;
 | 
| sl@0 |    165 | 			break;
 | 
| sl@0 |    166 | 		case EPostalCode:
 | 
| sl@0 |    167 | 			ptr.Set(KX520PostalCode);
 | 
| sl@0 |    168 | 			maxlen = KX520MaxPostalCodeLength;
 | 
| sl@0 |    169 | 			break;
 | 
| sl@0 |    170 | 		case EOrganizationName:
 | 
| sl@0 |    171 | 			ptr.Set(KX520OrganizationName);
 | 
| sl@0 |    172 | 			maxlen = KX520MaxOLength;
 | 
| sl@0 |    173 | 			break;
 | 
| sl@0 |    174 | 		case EOrganizationalUnitName:
 | 
| sl@0 |    175 | 			ptr.Set(KX520OrganizationalUnitName);
 | 
| sl@0 |    176 | 			maxlen = KX520MaxOULength;
 | 
| sl@0 |    177 | 			break;
 | 
| sl@0 |    178 | 		case ETitle:
 | 
| sl@0 |    179 | 			ptr.Set(KX520Title);
 | 
| sl@0 |    180 | 			maxlen = KX520MaxTLength;
 | 
| sl@0 |    181 | 			break;
 | 
| sl@0 |    182 | 		case EDNQualifier:
 | 
| sl@0 |    183 | 			ptr.Set(KX520DNQualifier);
 | 
| sl@0 |    184 | 			maxlen = 64; // no information was found on this one, so set to a safe minimum
 | 
| sl@0 |    185 | 			break;
 | 
| sl@0 |    186 | 		case ECountryName:
 | 
| sl@0 |    187 | 			ptr.Set(KX520CountryName);
 | 
| sl@0 |    188 | 			maxlen = KX520MaxCNLength;
 | 
| sl@0 |    189 | 			break;
 | 
| sl@0 |    190 | 		case EGivenName:
 | 
| sl@0 |    191 | 			ptr.Set(KX520GivenName);
 | 
| sl@0 |    192 | 			maxlen = KX520MaxGNLength;
 | 
| sl@0 |    193 | 			break;
 | 
| sl@0 |    194 | 		case ESurname:
 | 
| sl@0 |    195 | 			ptr.Set(KX520Surname);
 | 
| sl@0 |    196 | 			maxlen = KX520MaxSLength;
 | 
| sl@0 |    197 | 			break;
 | 
| sl@0 |    198 | 		case EInitials:
 | 
| sl@0 |    199 | 			ptr.Set(KX520Initials);
 | 
| sl@0 |    200 | 			maxlen = KX520MaxILength;
 | 
| sl@0 |    201 | 			break;
 | 
| sl@0 |    202 | 		case EGenerationQualifier:
 | 
| sl@0 |    203 | 			ptr.Set(KX520GenerationQualifier);
 | 
| sl@0 |    204 | 			maxlen = KX520MaxGQLength;
 | 
| sl@0 |    205 | 			break;
 | 
| sl@0 |    206 | 		case EPKCS9EmailAddress:
 | 
| sl@0 |    207 | 			ptr.Set(KPKCS9EmailAddress);
 | 
| sl@0 |    208 | 			maxlen = KPKCS9MaxEmailAddressLength;
 | 
| sl@0 |    209 | 			type = EASN1IA5String;
 | 
| sl@0 |    210 | 			break;
 | 
| sl@0 |    211 | 		case ESerialNumber:
 | 
| sl@0 |    212 | 			ptr.Set(KX520SerialNumber);
 | 
| sl@0 |    213 | 			maxlen = KX520MaxSNLength;
 | 
| sl@0 |    214 | 			break;
 | 
| sl@0 |    215 | 		case ERFC2247DomainComponent:
 | 
| sl@0 |    216 | 			ptr.Set(KRFC2247DomainComponent);
 | 
| sl@0 |    217 | 			maxlen = KRFC2247MaxDomainComponentLength;
 | 
| sl@0 |    218 | 			type = EASN1IA5String;
 | 
| sl@0 |    219 | 			break;
 | 
| sl@0 |    220 | 		case ERFC2256Street:
 | 
| sl@0 |    221 | 			ptr.Set(KRFC2256Street);
 | 
| sl@0 |    222 | 			maxlen = KRFC2256StreetLength;
 | 
| sl@0 |    223 | 			break;
 | 
| sl@0 |    224 | 		case EPKCS9UnstructuredName:
 | 
| sl@0 |    225 | 			{
 | 
| sl@0 |    226 | 			ptr.Set(KPKCS9UnstructuredName);
 | 
| sl@0 |    227 | 			maxlen = KPKCS9MaxUnstructuredNameLength;
 | 
| sl@0 |    228 | 			// Determine the encoded value. It could be a IA5String or a UTF8String
 | 
| sl@0 |    229 | 			TASN1DecGeneric decoderGeneric(aValue);
 | 
| sl@0 |    230 | 			decoderGeneric.InitL();
 | 
| sl@0 |    231 | 			type = decoderGeneric.Tag();	
 | 
| sl@0 |    232 | 			break;	
 | 
| sl@0 |    233 | 			}
 | 
| sl@0 |    234 | 		case EX520Description:
 | 
| sl@0 |    235 | 			{
 | 
| sl@0 |    236 | 			ptr.Set(KX520Description);
 | 
| sl@0 |    237 | 			maxlen = KX520MaxDescriptionLength;
 | 
| sl@0 |    238 | 			break;
 | 
| sl@0 |    239 | 			}
 | 
| sl@0 |    240 | 		default:
 | 
| sl@0 |    241 | 			User::Leave(KErrArgument);
 | 
| sl@0 |    242 | 		}
 | 
| sl@0 |    243 | 	// Verify if the passed length is within limits
 | 
| sl@0 |    244 | 	if(aValue.Length() > maxlen)
 | 
| sl@0 |    245 | 		User::Leave(KErrArgument);
 | 
| sl@0 |    246 | 
 | 
| sl@0 |    247 | 	// Allocate OID string for iType
 | 
| sl@0 |    248 | 	iType = ptr.AllocL();
 | 
| sl@0 |    249 | 
 | 
| sl@0 |    250 | 	// iValue must be stored in ASN.1-encoded form
 | 
| sl@0 |    251 | 	CASN1EncOctetString* enc = CASN1EncOctetString::NewLC(aValue);
 | 
| sl@0 |    252 | 	enc->SetTag(type, EUniversal);
 | 
| sl@0 |    253 | 	TUint len = enc->LengthDER();
 | 
| sl@0 |    254 | 	HBufC8* buf = HBufC8::NewMaxLC(len);
 | 
| sl@0 |    255 | 	TUint pos = 0;
 | 
| sl@0 |    256 | 	TPtr8 bufptr(buf->Des());
 | 
| sl@0 |    257 | 	enc->WriteDERL(bufptr, pos);
 | 
| sl@0 |    258 | 	iValue = bufptr.AllocL();
 | 
| sl@0 |    259 | 	CleanupStack::PopAndDestroy(2);
 | 
| sl@0 |    260 | 	}
 | 
| sl@0 |    261 | 
 | 
| sl@0 |    262 | EXPORT_C const TPtrC CX520AttributeTypeAndValue::Type() const
 | 
| sl@0 |    263 | 	{
 | 
| sl@0 |    264 | 	return iType->Des();
 | 
| sl@0 |    265 | 	}
 | 
| sl@0 |    266 | 
 | 
| sl@0 |    267 | EXPORT_C const TPtrC8 CX520AttributeTypeAndValue::EncodedValue() const
 | 
| sl@0 |    268 | 	{
 | 
| sl@0 |    269 | 	return iValue->Des();
 | 
| sl@0 |    270 | 	}
 | 
| sl@0 |    271 | 
 | 
| sl@0 |    272 | EXPORT_C HBufC* CX520AttributeTypeAndValue::ValueL() const
 | 
| sl@0 |    273 | 	{
 | 
| sl@0 |    274 | 	if (iType->Des() == KX520CountryName)
 | 
| sl@0 |    275 | 		{
 | 
| sl@0 |    276 | 		TASN1DecPrintableString encPString;
 | 
| sl@0 |    277 | 		TInt pos = 0;
 | 
| sl@0 |    278 | 		HBufC* res = encPString.DecodeDERL(iValue->Des(), pos);
 | 
| sl@0 |    279 | 		CleanupStack::PushL(res);
 | 
| sl@0 |    280 | 		if (res->Length() > KX520MaxCLength)
 | 
| sl@0 |    281 | 			{
 | 
| sl@0 |    282 | 			User::Leave(KErrArgument);
 | 
| sl@0 |    283 | 			}
 | 
| sl@0 |    284 | 		CleanupStack::Pop();
 | 
| sl@0 |    285 | 		return res;
 | 
| sl@0 |    286 | 		}
 | 
| sl@0 |    287 | 	if (iType->Des() == KX520DNQualifier)
 | 
| sl@0 |    288 | 		{
 | 
| sl@0 |    289 | 		TInt pos = 0;
 | 
| sl@0 |    290 | 		TASN1DecPrintableString encPString;
 | 
| sl@0 |    291 | 		HBufC* res = encPString.DecodeDERL(iValue->Des(), pos);
 | 
| sl@0 |    292 | 		return res;
 | 
| sl@0 |    293 | 		}
 | 
| sl@0 |    294 | 	if (iType->Des() == KPKCS9EmailAddress)
 | 
| sl@0 |    295 | 		{
 | 
| sl@0 |    296 | 		TASN1DecIA5String encIA5String;
 | 
| sl@0 |    297 | 		TInt pos = 0;
 | 
| sl@0 |    298 | 		HBufC* res = encIA5String.DecodeDERL(iValue->Des(), pos);
 | 
| sl@0 |    299 | 		CleanupStack::PushL(res);
 | 
| sl@0 |    300 | 		if (res->Length() > KPKCS9MaxEmailAddressLength)
 | 
| sl@0 |    301 | 			{
 | 
| sl@0 |    302 | 			User::Leave(KErrArgument);
 | 
| sl@0 |    303 | 			}
 | 
| sl@0 |    304 | 		CleanupStack::Pop();
 | 
| sl@0 |    305 | 		return res;
 | 
| sl@0 |    306 | 		}
 | 
| sl@0 |    307 | 	if (iType->Des() == KRFC2247DomainComponent)
 | 
| sl@0 |    308 | 		{
 | 
| sl@0 |    309 | 		TASN1DecIA5String encIA5String;
 | 
| sl@0 |    310 | 		TInt pos = 0;
 | 
| sl@0 |    311 | 		HBufC* res = encIA5String.DecodeDERL(iValue->Des(), pos);
 | 
| sl@0 |    312 | 		CleanupStack::PushL(res);
 | 
| sl@0 |    313 | 		if (res->Length() > KRFC2247MaxDomainComponentLength)
 | 
| sl@0 |    314 | 			{
 | 
| sl@0 |    315 | 			User::Leave(KErrArgument);
 | 
| sl@0 |    316 | 			}
 | 
| sl@0 |    317 | 		CleanupStack::Pop();
 | 
| sl@0 |    318 | 		return res;
 | 
| sl@0 |    319 | 		}
 | 
| sl@0 |    320 | 	if (iType->Des() == KX520SerialNumber)
 | 
| sl@0 |    321 | 		{
 | 
| sl@0 |    322 | 		TASN1DecPrintableString encPString;
 | 
| sl@0 |    323 | 		TInt pos = 0;
 | 
| sl@0 |    324 | 		HBufC* res = encPString.DecodeDERL(iValue->Des(), pos);
 | 
| sl@0 |    325 | 		CleanupStack::PushL(res);
 | 
| sl@0 |    326 | 		if (res->Length() > KX520MaxSNLength)
 | 
| sl@0 |    327 | 			{
 | 
| sl@0 |    328 | 			User::Leave(KErrArgument);
 | 
| sl@0 |    329 | 			}
 | 
| sl@0 |    330 | 		CleanupStack::Pop();
 | 
| sl@0 |    331 | 		return res;
 | 
| sl@0 |    332 | 		}
 | 
| sl@0 |    333 | 	TInt maxLength = 0;
 | 
| sl@0 |    334 | 	if (iType->Des() == KPKCS9UnstructuredName)
 | 
| sl@0 |    335 | 		{
 | 
| sl@0 |    336 | 		TASN1DecGeneric decoderGeneric(iValue->Des());
 | 
| sl@0 |    337 | 		decoderGeneric.InitL();
 | 
| sl@0 |    338 | 		// The encoded value should be a IA5String
 | 
| sl@0 |    339 | 		if (decoderGeneric.Tag() == EASN1IA5String)
 | 
| sl@0 |    340 | 			{
 | 
| sl@0 |    341 | 			TASN1DecIA5String encIA5String;
 | 
| sl@0 |    342 | 			TInt pos = 0;
 | 
| sl@0 |    343 | 			HBufC* res = encIA5String.DecodeDERL(iValue->Des(), pos);
 | 
| sl@0 |    344 | 			CleanupStack::PushL(res);
 | 
| sl@0 |    345 | 			if (res->Length() > KPKCS9MaxUnstructuredNameLength)
 | 
| sl@0 |    346 | 				{
 | 
| sl@0 |    347 | 				User::Leave(KErrArgument);
 | 
| sl@0 |    348 | 				}
 | 
| sl@0 |    349 | 			CleanupStack::Pop();
 | 
| sl@0 |    350 | 			return res;					
 | 
| sl@0 |    351 | 			}
 | 
| sl@0 |    352 | 		// But it could also be a UTF8String to support internationalization issues
 | 
| sl@0 |    353 | 		else
 | 
| sl@0 |    354 | 			{
 | 
| sl@0 |    355 | 			maxLength = KPKCS9MaxUnstructuredNameLength;	
 | 
| sl@0 |    356 | 			}
 | 
| sl@0 |    357 | 		}	
 | 
| sl@0 |    358 | 	if (iType->Des() == KX520OrganizationName)
 | 
| sl@0 |    359 | 		{
 | 
| sl@0 |    360 | 		maxLength = KX520MaxOLength;
 | 
| sl@0 |    361 | 		}
 | 
| sl@0 |    362 | 	if (iType->Des() == KX520OrganizationalUnitName)
 | 
| sl@0 |    363 | 		{
 | 
| sl@0 |    364 | 		maxLength = KX520MaxOULength;
 | 
| sl@0 |    365 | 		}
 | 
| sl@0 |    366 | 	if (iType->Des() == KX520LocalityName)
 | 
| sl@0 |    367 | 		{
 | 
| sl@0 |    368 | 		maxLength = KX520MaxLLength;
 | 
| sl@0 |    369 | 		}
 | 
| sl@0 |    370 | 	if (iType->Des() == KX520StateOrProvinceName)
 | 
| sl@0 |    371 | 		{
 | 
| sl@0 |    372 | 		maxLength = KX520MaxSOPLength;
 | 
| sl@0 |    373 | 		}
 | 
| sl@0 |    374 | 	if (iType->Des() == KX520Title)
 | 
| sl@0 |    375 | 		{
 | 
| sl@0 |    376 | 		maxLength = KX520MaxTLength;
 | 
| sl@0 |    377 | 		}
 | 
| sl@0 |    378 | 	if (iType->Des() == KX520CommonName)
 | 
| sl@0 |    379 | 		{
 | 
| sl@0 |    380 | 		maxLength = KX520MaxCNLength;
 | 
| sl@0 |    381 | 		}
 | 
| sl@0 |    382 | 	if (iType->Des() == KX520Surname)
 | 
| sl@0 |    383 | 		{
 | 
| sl@0 |    384 | 		maxLength = KX520MaxSLength;
 | 
| sl@0 |    385 | 		}
 | 
| sl@0 |    386 | 	if (iType->Des() == KX520GivenName)
 | 
| sl@0 |    387 | 		{
 | 
| sl@0 |    388 | 		maxLength = KX520MaxGNLength;
 | 
| sl@0 |    389 | 		}
 | 
| sl@0 |    390 | 	if (iType->Des() == KX520Initials)
 | 
| sl@0 |    391 | 		{
 | 
| sl@0 |    392 | 		maxLength = KX520MaxILength;
 | 
| sl@0 |    393 | 		}
 | 
| sl@0 |    394 | 	if (iType->Des() == KX520GenerationQualifier)
 | 
| sl@0 |    395 | 		{
 | 
| sl@0 |    396 | 		maxLength = KX520MaxGQLength;
 | 
| sl@0 |    397 | 		}
 | 
| sl@0 |    398 | 	if (iType->Des() == KX520PostalCode)
 | 
| sl@0 |    399 | 		{
 | 
| sl@0 |    400 | 		maxLength = KX520MaxPostalCodeLength;
 | 
| sl@0 |    401 | 		}
 | 
| sl@0 |    402 | 	if (iType->Des() == KRFC2256Street)
 | 
| sl@0 |    403 | 		{
 | 
| sl@0 |    404 | 		maxLength = KRFC2256StreetLength;
 | 
| sl@0 |    405 | 		}
 | 
| sl@0 |    406 | 	if (iType->Des() == KX520Description)
 | 
| sl@0 |    407 | 		{
 | 
| sl@0 |    408 | 		maxLength = KX520MaxDescriptionLength;
 | 
| sl@0 |    409 | 		}
 | 
| sl@0 |    410 | 	if (maxLength == 0)
 | 
| sl@0 |    411 | 		{
 | 
| sl@0 |    412 | 		User::Leave(KErrNotSupported);
 | 
| sl@0 |    413 | 		}
 | 
| sl@0 |    414 | 	TASN1DecX500DirectoryString encDString;
 | 
| sl@0 |    415 | 	TInt pos = 0;
 | 
| sl@0 |    416 | 	HBufC* res = encDString.DecodeDERL(iValue->Des(), pos, maxLength);
 | 
| sl@0 |    417 | 	return res;
 | 
| sl@0 |    418 | 	}
 | 
| sl@0 |    419 | 
 | 
| sl@0 |    420 | TBool CX520AttributeTypeAndValue::IsCaseInSensitiveL(const TDesC8& aSource) const
 | 
| sl@0 |    421 | 	{
 | 
| sl@0 |    422 | 	TPtr attribute = iType->Des();
 | 
| sl@0 |    423 | 	TBool caseInsensitiveAttr = (attribute == KPKCS9EmailAddress || attribute == KPKCS9UnstructuredName || attribute == KX520Description);
 | 
| sl@0 |    424 | 	TASN1DecGeneric gen(aSource);
 | 
| sl@0 |    425 | 	gen.InitL();
 | 
| sl@0 |    426 | 	return ((gen.Tag() == EASN1PrintableString) || caseInsensitiveAttr);
 | 
| sl@0 |    427 | 	}
 | 
| sl@0 |    428 | 
 | 
| sl@0 |    429 | 
 | 
| sl@0 |    430 | EXPORT_C CASN1EncSequence* CX520AttributeTypeAndValue::EncodeASN1LC() const
 | 
| sl@0 |    431 | 	{
 | 
| sl@0 |    432 | 	CASN1EncSequence *seq = CASN1EncSequence::NewLC();
 | 
| sl@0 |    433 | 	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(Type());
 | 
| sl@0 |    434 | 	seq->AddAndPopChildL(oid);
 | 
| sl@0 |    435 | 
 | 
| sl@0 |    436 | 	// The current ASN.1 base encoding class assumes that ASN.1 type, 
 | 
| sl@0 |    437 | 	// length, and contents are stored and can be written to a buffer
 | 
| sl@0 |    438 | 	// separately. Therefore it is difficult, if not impossible, to 
 | 
| sl@0 |    439 | 	// store raw ASN.1 encoding data in a tree of ASN.1 encoding 
 | 
| sl@0 |    440 | 	// objects. That is why we are forced first to decode the raw value, 
 | 
| sl@0 |    441 | 	// and then re-encode it so that we know what type and length it 
 | 
| sl@0 |    442 | 	// has.
 | 
| sl@0 |    443 | 	TASN1DecGeneric decoderGeneric(EncodedValue());
 | 
| sl@0 |    444 | 	decoderGeneric.InitL();
 | 
| sl@0 |    445 | 	TASN1DecOctetString decoderOctetString;
 | 
| sl@0 |    446 | 	HBufC8* valBuf = decoderOctetString.DecodeDERL(decoderGeneric);
 | 
| sl@0 |    447 | 	CleanupStack::PushL(valBuf);
 | 
| sl@0 |    448 | 	CASN1EncOctetString* val = CASN1EncOctetString::NewLC(*valBuf);
 | 
| sl@0 |    449 | 	val->SetTag(decoderGeneric.Tag(), decoderGeneric.Class());
 | 
| sl@0 |    450 | 	seq->AddAndPopChildL(val);
 | 
| sl@0 |    451 | 	CleanupStack::PopAndDestroy(valBuf);
 | 
| sl@0 |    452 | 	return seq;
 | 
| sl@0 |    453 | 	}
 | 
| sl@0 |    454 | 
 | 
| sl@0 |    455 | EXPORT_C CASN1EncSequence* CX520AttributeTypeAndValue::EncodeASN1L() const
 | 
| sl@0 |    456 | 	{
 | 
| sl@0 |    457 | 	CASN1EncSequence *seq = EncodeASN1LC();
 | 
| sl@0 |    458 | 	CleanupStack::Pop(seq);
 | 
| sl@0 |    459 | 	return seq;
 | 
| sl@0 |    460 | 	}
 | 
| sl@0 |    461 | 
 | 
| sl@0 |    462 | EXPORT_C CX520AttributeTypeAndValue::~CX520AttributeTypeAndValue()
 | 
| sl@0 |    463 | 	{
 | 
| sl@0 |    464 | 	delete iType;
 | 
| sl@0 |    465 | 	delete iValue;
 | 
| sl@0 |    466 | 	}
 | 
| sl@0 |    467 | 
 | 
| sl@0 |    468 | EXPORT_C TBool CX520AttributeTypeAndValue::ExactMatchL(const CX520AttributeTypeAndValue& aElement) const
 | 
| sl@0 |    469 | 	{
 | 
| sl@0 |    470 | 	TBool res = EFalse;
 | 
| sl@0 |    471 | 	if (*(iType) != *(aElement.iType))
 | 
| sl@0 |    472 | 		{
 | 
| sl@0 |    473 | 		return res;
 | 
| sl@0 |    474 | 		}
 | 
| sl@0 |    475 | 	HBufC* lhs = this->ValueL();
 | 
| sl@0 |    476 | 	CleanupStack::PushL(lhs);
 | 
| sl@0 |    477 | 	HBufC* rhs = aElement.ValueL();
 | 
| sl@0 |    478 | 
 | 
| sl@0 |    479 | 	TPtr plhs = lhs->Des();
 | 
| sl@0 |    480 | 	TPtr prhs = rhs->Des();
 | 
| sl@0 |    481 | 	plhs.TrimAll();
 | 
| sl@0 |    482 | 	prhs.TrimAll();
 | 
| sl@0 |    483 | 
 | 
| sl@0 |    484 | 
 | 
| sl@0 |    485 | 	// DEF124902: Certificate name matching done in accordance to RFC3280
 | 
| sl@0 |    486 | 	// RFC3280: Printable String and Email address(of value type 'IA5String') will 
 | 
| sl@0 |    487 |  	// be compared case-insensitively.  
 | 
| sl@0 |    488 |  	
 | 
| sl@0 |    489 |     if (IsCaseInSensitiveL(iValue->Des()))
 | 
| sl@0 |    490 |  	    {
 | 
| sl@0 |    491 |  	     //case insensitive comparison for Printable String and IA5String (EmailAdress only).
 | 
| sl@0 |    492 |  	     res = (plhs.CompareF(prhs) == 0);
 | 
| sl@0 |    493 |  	    }
 | 
| sl@0 |    494 |     else
 | 
| sl@0 |    495 | 	    {
 | 
| sl@0 |    496 | 	     // case-sensitive comparison for strings other than printable string 
 | 
| sl@0 |    497 | 	     // Exception: This may include IA5Stings other than 'EmailAddress' attiribute types.
 | 
| sl@0 |    498 |  	     res = (plhs.Compare(prhs) == 0);
 | 
| sl@0 |    499 | 	    }
 | 
| sl@0 |    500 | 	CleanupStack::PopAndDestroy();
 | 
| sl@0 |    501 | 	delete rhs;
 | 
| sl@0 |    502 | 	return res; 
 | 
| sl@0 |    503 | 	}
 | 
| sl@0 |    504 | 
 | 
| sl@0 |    505 | void CX520AttributeTypeAndValue::ExternalizeL(RWriteStream& aStream) const
 | 
| sl@0 |    506 | 	{
 | 
| sl@0 |    507 | 	aStream.WriteInt32L(iType->Des().Length());
 | 
| sl@0 |    508 | 	aStream << *iType;
 | 
| sl@0 |    509 | 	aStream.WriteInt32L(iValue->Des().Length());
 | 
| sl@0 |    510 | 	aStream << *iValue;
 | 
| sl@0 |    511 | 	}
 | 
| sl@0 |    512 | 
 | 
| sl@0 |    513 | void CX520AttributeTypeAndValue::InternalizeL(RReadStream& aStream)
 | 
| sl@0 |    514 | 	{
 | 
| sl@0 |    515 | 	TInt maxlen;
 | 
| sl@0 |    516 | 	maxlen = aStream.ReadInt32L();
 | 
| sl@0 |    517 | 	iType = HBufC::NewL(aStream,maxlen);
 | 
| sl@0 |    518 | 	maxlen = aStream.ReadInt32L();
 | 
| sl@0 |    519 | 	iValue = HBufC8::NewL(aStream,maxlen);
 | 
| sl@0 |    520 | 	}
 |