os/security/cryptoservices/certificateandkeymgmt/x500/x520ava.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
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
	}