os/security/cryptoservices/certificateandkeymgmt/x509/x509gn.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 <x509gn.h>
sl@0
    20
#include "asn1dec.h"
sl@0
    21
sl@0
    22
/*
sl@0
    23
 * __SECURITY_PLATSEC_ARCH__: Changes for platform security
sl@0
    24
 *
sl@0
    25
 * If this macro is defined, the represenation of TPtrC arrays is changed from
sl@0
    26
 * using CPtrCArray to RArray<TPtrC>.  This is because CPtrCArray is supplied by
sl@0
    27
 * bafl.dll, which is not trusted for TCB.  x509 needs to be trusted for TCB so
sl@0
    28
 * it can be used by software install, hence this dependency was removed.
sl@0
    29
 *
sl@0
    30
 * This changes is implmented as a series of macros for the basic operations,
sl@0
    31
 * to minimise the amount of conditional compilation.
sl@0
    32
 */
sl@0
    33
sl@0
    34
sl@0
    35
#define REP_INIT_L		/* do nothing */
sl@0
    36
#define REP_FINAL 		iRep.Close()
sl@0
    37
#define REP_APPEND_L(X)	User::LeaveIfError(iRep.Append(X))
sl@0
    38
#define REP_COUNT		iRep.Count()
sl@0
    39
#define REP_AT(X)		iRep[X]
sl@0
    40
#define REP_VAL			iRep
sl@0
    41
#define REP_VAL_TYPE	RArray<TPtrC>
sl@0
    42
sl@0
    43
sl@0
    44
_LIT(KX509RFC822HostDomainSeparator,"@");
sl@0
    45
_LIT(KX509SubdomainSeparator,".");
sl@0
    46
_LIT(KX509URISchemeSpecificStart, "//");
sl@0
    47
_LIT(KX509URIUserPasswordEnd, "@");
sl@0
    48
_LIT(KX509URIPortStart, ":");
sl@0
    49
_LIT(KX509URIurlPathStart, "/");
sl@0
    50
sl@0
    51
const TInt KX509URISchemeSpecificStartLength = 2;
sl@0
    52
const TInt KX509URIUserPasswordEndLength = 1;
sl@0
    53
const TInt KX509MaxDNSNameLabelLength = 63;
sl@0
    54
sl@0
    55
//superclass: common functionality for DNS names & RFC 822 email addresses
sl@0
    56
EXPORT_C CX509DomainName::~CX509DomainName()
sl@0
    57
	{
sl@0
    58
	REP_FINAL;
sl@0
    59
	delete iName;
sl@0
    60
	}
sl@0
    61
sl@0
    62
CX509DomainName::CX509DomainName()
sl@0
    63
	{
sl@0
    64
	}
sl@0
    65
sl@0
    66
EXPORT_C TPtrC CX509DomainName::Name() const 
sl@0
    67
	{
sl@0
    68
	return *iName;
sl@0
    69
	}
sl@0
    70
sl@0
    71
EXPORT_C TBool CX509DomainName::IsWithinSubtree(const CX509DomainName& aName) const
sl@0
    72
   	{
sl@0
    73
   	TInt myCount = REP_COUNT;
sl@0
    74
   	TInt otherCount = aName.REP_COUNT;
sl@0
    75
   	if (otherCount > myCount)
sl@0
    76
   		{
sl@0
    77
   		return EFalse;
sl@0
    78
   		}
sl@0
    79
   	for (TInt i = otherCount-1; i >= 0; i--)
sl@0
    80
   		{
sl@0
    81
   		myCount--;
sl@0
    82
   		if ( KErrNotFound == REP_AT(myCount).MatchF(aName.REP_AT(i)) )
sl@0
    83
   			{
sl@0
    84
   			return EFalse;
sl@0
    85
   			}
sl@0
    86
   		}
sl@0
    87
   	return ETrue;
sl@0
    88
   	}
sl@0
    89
sl@0
    90
TBool CX509DomainName::AddDomainL(TInt& aPos)
sl@0
    91
	{
sl@0
    92
	TInt end = iName->Length();
sl@0
    93
	FOREVER
sl@0
    94
		{
sl@0
    95
		if (!(AddSubdomainL(aPos)))
sl@0
    96
			{
sl@0
    97
			return EFalse;
sl@0
    98
			}
sl@0
    99
		if (aPos == end)
sl@0
   100
			{
sl@0
   101
			break;
sl@0
   102
			}
sl@0
   103
		AddSubdomainSeparatorL(aPos);
sl@0
   104
		}
sl@0
   105
	return ETrue;
sl@0
   106
	}
sl@0
   107
sl@0
   108
TBool CX509DomainName::AddSubdomainL(TInt& aPos)
sl@0
   109
	{
sl@0
   110
	TBool res = EFalse;
sl@0
   111
	TInt end = iName->Length();
sl@0
   112
	if (aPos >= end)
sl@0
   113
		{
sl@0
   114
		return res;
sl@0
   115
		}
sl@0
   116
	TPtrC whatsLeft(&(iName->operator[] (aPos)), end - aPos);
sl@0
   117
	TInt subdomainEnd = whatsLeft.FindF(KX509SubdomainSeparator);
sl@0
   118
	if (subdomainEnd == 0)
sl@0
   119
		{
sl@0
   120
		return res;
sl@0
   121
		}
sl@0
   122
	if (subdomainEnd == KErrNotFound)
sl@0
   123
		{
sl@0
   124
		subdomainEnd = end - aPos;
sl@0
   125
		}
sl@0
   126
	TPtrC subdomain(&whatsLeft[0], subdomainEnd);
sl@0
   127
	if (IsValidString(subdomain))
sl@0
   128
		{
sl@0
   129
		REP_APPEND_L(subdomain);
sl@0
   130
		res = ETrue;
sl@0
   131
		}
sl@0
   132
	aPos = aPos + subdomainEnd;
sl@0
   133
	return res;
sl@0
   134
	}
sl@0
   135
sl@0
   136
TBool CX509DomainName::AddSubdomainSeparatorL(TInt& aPos)
sl@0
   137
	{
sl@0
   138
	TBool res = EFalse;
sl@0
   139
	TInt end = iName->Length();
sl@0
   140
	if (end <= aPos)
sl@0
   141
		{
sl@0
   142
		return res;
sl@0
   143
		}
sl@0
   144
	TPtrC whatsLeft(&(iName->operator[] (aPos)), end - aPos);
sl@0
   145
	TInt separatorEnd = whatsLeft.FindF(KX509SubdomainSeparator);
sl@0
   146
	if (separatorEnd == 0)
sl@0
   147
		{
sl@0
   148
		TPtrC separator(&whatsLeft[0], 1);
sl@0
   149
		REP_APPEND_L(separator);
sl@0
   150
		aPos++;
sl@0
   151
		res = ETrue;
sl@0
   152
		}
sl@0
   153
	return res;
sl@0
   154
	}
sl@0
   155
sl@0
   156
TBool CX509DomainName::IsValidString(const TDesC& aStr) const
sl@0
   157
	{
sl@0
   158
	TInt pos=0;
sl@0
   159
	TInt end=aStr.Length()-1;
sl@0
   160
	if (end < 0)
sl@0
   161
		{
sl@0
   162
		return ETrue;	
sl@0
   163
		}
sl@0
   164
	while (pos<end && IsValidChar(aStr[pos]))
sl@0
   165
		{
sl@0
   166
		pos++;
sl@0
   167
		}
sl@0
   168
	return (pos==end && IsValidChar(aStr[end]));
sl@0
   169
	}
sl@0
   170
sl@0
   171
TBool CX509DomainName::IsAlpha(const TChar& aChar) const 
sl@0
   172
	{
sl@0
   173
	return (	((aChar >= 97) && (aChar <= 122))	||
sl@0
   174
				((aChar >= 65) && (aChar <= 90))	);
sl@0
   175
	}
sl@0
   176
sl@0
   177
TBool CX509DomainName::IsAlphaOrNum(const TChar& aChar) const
sl@0
   178
	{
sl@0
   179
	return ((IsAlpha(aChar)) ||
sl@0
   180
			((aChar >= 48) && (aChar <= 57)) || (aChar == 42));
sl@0
   181
	}
sl@0
   182
sl@0
   183
TBool CX509DomainName::IsValidChar(const TChar& aChar) const
sl@0
   184
	{
sl@0
   185
	//default implementation: must be letter, number or hyphen
sl@0
   186
	return ((IsAlphaOrNum(aChar)) ||
sl@0
   187
			(aChar == 45) || (aChar == 42));
sl@0
   188
	}
sl@0
   189
sl@0
   190
//RFC 822 email address
sl@0
   191
//subtree
sl@0
   192
EXPORT_C CX509RFC822NameSubtree* CX509RFC822NameSubtree::NewL(const TDesC8& aBinaryData)
sl@0
   193
	{
sl@0
   194
	CX509RFC822NameSubtree* self = CX509RFC822NameSubtree::NewLC(aBinaryData);
sl@0
   195
	CleanupStack::Pop();//self
sl@0
   196
	return self;
sl@0
   197
	}
sl@0
   198
sl@0
   199
EXPORT_C CX509RFC822NameSubtree* CX509RFC822NameSubtree::NewLC(const TDesC8& aBinaryData)
sl@0
   200
	{
sl@0
   201
	CX509RFC822NameSubtree* self = new(ELeave) CX509RFC822NameSubtree;
sl@0
   202
	CleanupStack::PushL(self);
sl@0
   203
	self->ConstructL(aBinaryData);
sl@0
   204
	return self;
sl@0
   205
	}
sl@0
   206
sl@0
   207
void CX509RFC822NameSubtree::ConstructL(const TDesC8& aBinaryData)
sl@0
   208
	{
sl@0
   209
	TInt pos = 0;
sl@0
   210
	TASN1DecIA5String encStr;
sl@0
   211
	iName = encStr.DecodeDERL(aBinaryData, pos);
sl@0
   212
	REP_INIT_L;
sl@0
   213
	//now, parse your data
sl@0
   214
	pos = 0;	
sl@0
   215
	AddLocalHostL(pos);
sl@0
   216
	AddSubdomainSeparatorL(pos);
sl@0
   217
	if (!(AddDomainL(pos)))
sl@0
   218
		{
sl@0
   219
		User::Leave(KErrArgument);
sl@0
   220
		}
sl@0
   221
	}
sl@0
   222
sl@0
   223
TBool CX509RFC822NameSubtree::AddLocalHostL(TInt& aPos)
sl@0
   224
	{
sl@0
   225
	TInt localHostLength = iName->FindF(KX509RFC822HostDomainSeparator);
sl@0
   226
	if ((localHostLength != KErrNotFound) && (localHostLength > 0))
sl@0
   227
		{
sl@0
   228
		TPtrC localHost(&(iName->operator[] (aPos)), localHostLength);		
sl@0
   229
		//the local host name is not checked here as it caused defect PDEF108960 
sl@0
   230
		//and for compatability with IE and Firefox.
sl@0
   231
		REP_APPEND_L(localHost);
sl@0
   232
		aPos = aPos + localHostLength;
sl@0
   233
		aPos++;		//skip the @ symbol
sl@0
   234
		return ETrue;
sl@0
   235
		}
sl@0
   236
	return EFalse;	//local host not found
sl@0
   237
	}
sl@0
   238
sl@0
   239
sl@0
   240
EXPORT_C const REP_VAL_TYPE& CX509RFC822NameSubtree::Rep() const
sl@0
   241
	{
sl@0
   242
	return REP_VAL;
sl@0
   243
	}
sl@0
   244
sl@0
   245
TBool CX509RFC822NameSubtree::IsValidChar(const TChar& aChar) const
sl@0
   246
	{
sl@0
   247
	//we permit "." here, 'cos it's allowed in local host names
sl@0
   248
	//and must have been stripped out by domain parsing code,
sl@0
   249
	//since it's the separator char
sl@0
   250
	return (	(aChar == 33)						||
sl@0
   251
				((aChar >= 35) && (aChar <= 40))	||
sl@0
   252
				(aChar == 42)						||
sl@0
   253
				(aChar == 43)						||
sl@0
   254
				((aChar >= 45) && (aChar <= 57))	||
sl@0
   255
				(aChar == 61)						||
sl@0
   256
				(aChar == 63)						||
sl@0
   257
				((aChar >= 65) && (aChar <= 90))	||
sl@0
   258
				((aChar >= 94) && (aChar <= 126))	);
sl@0
   259
	}
sl@0
   260
sl@0
   261
//full rfc 822 name: exactly as subtree, but requires local host and full domain name
sl@0
   262
EXPORT_C CX509RFC822Name* CX509RFC822Name::NewL(const TDesC8& aBinaryData)
sl@0
   263
	{
sl@0
   264
	CX509RFC822Name* self = CX509RFC822Name::NewLC(aBinaryData);
sl@0
   265
	CleanupStack::Pop();//self
sl@0
   266
	return self;
sl@0
   267
	}
sl@0
   268
sl@0
   269
EXPORT_C CX509RFC822Name* CX509RFC822Name::NewLC(const TDesC8& aBinaryData)
sl@0
   270
	{
sl@0
   271
	CX509RFC822Name* self = new(ELeave) CX509RFC822Name;
sl@0
   272
	CleanupStack::PushL(self);
sl@0
   273
	self->ConstructL(aBinaryData);
sl@0
   274
	return self;
sl@0
   275
	}
sl@0
   276
sl@0
   277
void CX509RFC822Name::ConstructL(const TDesC8& aBinaryData)
sl@0
   278
	{
sl@0
   279
	TInt pos = 0;
sl@0
   280
	TASN1DecIA5String encStr;
sl@0
   281
	iName = encStr.DecodeDERL(aBinaryData, pos);
sl@0
   282
	REP_INIT_L;
sl@0
   283
	//now, parse your data
sl@0
   284
	pos = 0;	
sl@0
   285
	if (! ((AddLocalHostL(pos)) && (AddDomainL(pos))) )
sl@0
   286
		{
sl@0
   287
		User::Leave(KErrArgument);
sl@0
   288
		}
sl@0
   289
	}
sl@0
   290
sl@0
   291
//DNS Name subtree
sl@0
   292
EXPORT_C CX509DNSNameSubtree* CX509DNSNameSubtree::NewL(const TDesC8& aBinaryData)
sl@0
   293
	{
sl@0
   294
	CX509DNSNameSubtree* self = CX509DNSNameSubtree::NewLC(aBinaryData);
sl@0
   295
	CleanupStack::Pop();//self
sl@0
   296
	return self;
sl@0
   297
	}
sl@0
   298
sl@0
   299
EXPORT_C CX509DNSNameSubtree* CX509DNSNameSubtree::NewLC(const TDesC8& aBinaryData)
sl@0
   300
	{
sl@0
   301
	CX509DNSNameSubtree* self = new(ELeave) CX509DNSNameSubtree;
sl@0
   302
	CleanupStack::PushL(self);
sl@0
   303
	self->ConstructL(aBinaryData);
sl@0
   304
	return self;
sl@0
   305
	}
sl@0
   306
sl@0
   307
void CX509DNSNameSubtree::ConstructL(const TDesC8& aBinaryData)
sl@0
   308
	{
sl@0
   309
	TInt pos = 0;
sl@0
   310
	TASN1DecIA5String encStr;
sl@0
   311
	iName = encStr.DecodeDERL(aBinaryData, pos);
sl@0
   312
	REP_INIT_L;
sl@0
   313
	pos = 0;
sl@0
   314
	AddSubdomainSeparatorL(pos);//a subtree may start with a period
sl@0
   315
	if (!(AddDomainL(pos)))
sl@0
   316
		{
sl@0
   317
		User::Leave(KErrArgument);
sl@0
   318
		}
sl@0
   319
	}
sl@0
   320
sl@0
   321
EXPORT_C const REP_VAL_TYPE& CX509DNSNameSubtree::Rep() const
sl@0
   322
	{
sl@0
   323
	return REP_VAL;
sl@0
   324
	}
sl@0
   325
sl@0
   326
TBool CX509DNSNameSubtree::IsValidString(const TDesC& aStr) const
sl@0
   327
	{
sl@0
   328
	//must be <= 63 chars long
sl@0
   329
	//must start with letter, end with letter or number
sl@0
   330
	TInt len = aStr.Length();
sl@0
   331
	return (	(len <= KX509MaxDNSNameLabelLength) &&
sl@0
   332
				(IsAlphaOrNum(aStr[0]))				&&
sl@0
   333
				(IsAlphaOrNum(aStr[len-1]))			&&
sl@0
   334
				(CX509DomainName::IsValidString(aStr))				);
sl@0
   335
	}
sl@0
   336
sl@0
   337
//dns name: exactly as subtree but requires full domain name
sl@0
   338
EXPORT_C CX509DNSName* CX509DNSName::NewL(const TDesC8& aBinaryData)
sl@0
   339
	{
sl@0
   340
	CX509DNSName* self = CX509DNSName::NewLC(aBinaryData);
sl@0
   341
	CleanupStack::Pop();//self
sl@0
   342
	return self;
sl@0
   343
	}
sl@0
   344
sl@0
   345
EXPORT_C CX509DNSName* CX509DNSName::NewLC(const TDesC8& aBinaryData)
sl@0
   346
	{
sl@0
   347
	CX509DNSName* self = new(ELeave) CX509DNSName;
sl@0
   348
	CleanupStack::PushL(self);
sl@0
   349
	self->ConstructL(aBinaryData);
sl@0
   350
	return self;
sl@0
   351
	}
sl@0
   352
sl@0
   353
EXPORT_C CX509DNSName* CX509DNSName::NewL(const CX509DNSName& aName)
sl@0
   354
	{
sl@0
   355
	CX509DNSName* self = CX509DNSName::NewLC(aName);
sl@0
   356
	CleanupStack::Pop();//self
sl@0
   357
	return self;
sl@0
   358
	}
sl@0
   359
sl@0
   360
EXPORT_C CX509DNSName* CX509DNSName::NewLC(const CX509DNSName& aName)
sl@0
   361
	{	
sl@0
   362
	CX509DNSName* self = new(ELeave) CX509DNSName;
sl@0
   363
	CleanupStack::PushL(self);
sl@0
   364
	self->ConstructL(aName);
sl@0
   365
	return self;	
sl@0
   366
	}
sl@0
   367
sl@0
   368
sl@0
   369
EXPORT_C CX509DNSName* CX509DNSName::NewL(const TDesC& aNameString)
sl@0
   370
	{
sl@0
   371
	CX509DNSName* self = CX509DNSName::NewLC(aNameString);
sl@0
   372
	CleanupStack::Pop();//self
sl@0
   373
	return self;	
sl@0
   374
	}
sl@0
   375
sl@0
   376
EXPORT_C CX509DNSName* CX509DNSName::NewLC(const TDesC& aNameString)
sl@0
   377
	{
sl@0
   378
	CX509DNSName* self = new(ELeave) CX509DNSName;
sl@0
   379
	CleanupStack::PushL(self);
sl@0
   380
	self->ConstructL(aNameString);
sl@0
   381
	return self;
sl@0
   382
	}
sl@0
   383
sl@0
   384
void CX509DNSName::ConstructL(const TDesC& aNameString)
sl@0
   385
	{
sl@0
   386
	TInt pos = 0;
sl@0
   387
	REP_INIT_L;
sl@0
   388
	iName = aNameString.AllocL();
sl@0
   389
	AddSubdomainSeparatorL(pos);//a subtree may start with a period
sl@0
   390
	if (!(AddDomainL(pos)))
sl@0
   391
		{
sl@0
   392
		User::Leave(KErrArgument);
sl@0
   393
		}
sl@0
   394
	}
sl@0
   395
sl@0
   396
void CX509DNSName::ConstructL(const TDesC8& aBinaryData)
sl@0
   397
	{
sl@0
   398
	TInt pos = 0;
sl@0
   399
	TASN1DecIA5String encStr;
sl@0
   400
	iName = encStr.DecodeDERL(aBinaryData, pos);
sl@0
   401
	ParseNameL();
sl@0
   402
	}
sl@0
   403
sl@0
   404
void CX509DNSName::ConstructL(const CX509DNSName& aName)
sl@0
   405
	{
sl@0
   406
	iName = aName.iName->AllocL();
sl@0
   407
	ParseNameL();
sl@0
   408
	}
sl@0
   409
sl@0
   410
void CX509DNSName::ParseNameL()
sl@0
   411
	{
sl@0
   412
	REP_INIT_L;
sl@0
   413
	TInt pos = 0;
sl@0
   414
	if  (!AddDomainL(pos))
sl@0
   415
		{
sl@0
   416
		User::Leave(KErrArgument);
sl@0
   417
		}
sl@0
   418
	}
sl@0
   419
sl@0
   420
//URI: must be of 'ip-based' form (rfc 1738 section 3.1)
sl@0
   421
//_and_ contain a domain name (not an IP address)
sl@0
   422
EXPORT_C CX509IPBasedURI* CX509IPBasedURI::NewL(const TDesC8& aBinaryData)
sl@0
   423
	{
sl@0
   424
	CX509IPBasedURI* self = CX509IPBasedURI::NewLC(aBinaryData);
sl@0
   425
	CleanupStack::Pop();//self
sl@0
   426
	return self;
sl@0
   427
	}
sl@0
   428
sl@0
   429
EXPORT_C CX509IPBasedURI* CX509IPBasedURI::NewLC(const TDesC8& aBinaryData)
sl@0
   430
	{
sl@0
   431
	CX509IPBasedURI* self = new(ELeave) CX509IPBasedURI;
sl@0
   432
	CleanupStack::PushL(self);
sl@0
   433
	self->ConstructL(aBinaryData);
sl@0
   434
	return self;
sl@0
   435
	}
sl@0
   436
sl@0
   437
void CX509IPBasedURI::ConstructL(const TDesC8& aBinaryData)
sl@0
   438
	{
sl@0
   439
	TInt pos = 0;
sl@0
   440
	TASN1DecIA5String encStr;
sl@0
   441
	iName = encStr.DecodeDERL(aBinaryData, pos);
sl@0
   442
	iHost = CX509DNSName::NewL(ExtractHostNameL());
sl@0
   443
	}
sl@0
   444
sl@0
   445
EXPORT_C CX509IPBasedURI::~CX509IPBasedURI()
sl@0
   446
	{
sl@0
   447
	delete iName;
sl@0
   448
	delete iHost;
sl@0
   449
	}
sl@0
   450
sl@0
   451
CX509IPBasedURI::CX509IPBasedURI()
sl@0
   452
	:iHost(NULL), iName(NULL)
sl@0
   453
	{
sl@0
   454
	}
sl@0
   455
sl@0
   456
EXPORT_C const CX509DNSName& CX509IPBasedURI::Host() const
sl@0
   457
	{
sl@0
   458
	return *iHost;
sl@0
   459
	}
sl@0
   460
sl@0
   461
EXPORT_C TPtrC CX509IPBasedURI::Name() const
sl@0
   462
	{
sl@0
   463
	return iName->Des();
sl@0
   464
	}
sl@0
   465
sl@0
   466
TPtrC CX509IPBasedURI::ExtractHostNameL() const
sl@0
   467
	{
sl@0
   468
	TInt hostStart;
sl@0
   469
	TInt hostEnd;
sl@0
   470
	TInt len = iName->Length();
sl@0
   471
	TInt schemeSpecificStart = (iName->FindF(KX509URISchemeSpecificStart) + KX509URISchemeSpecificStartLength);
sl@0
   472
	TInt userPasswordEnd = (iName->FindF(KX509URIUserPasswordEnd)) + KX509URIUserPasswordEndLength;
sl@0
   473
	hostStart = ((userPasswordEnd == 0)? schemeSpecificStart : userPasswordEnd);
sl@0
   474
	if (hostStart == KErrNotFound)
sl@0
   475
		{
sl@0
   476
		User::Leave(KErrArgument);
sl@0
   477
		}
sl@0
   478
	TPtrC whatsLeft(&(iName->operator[](hostStart)), len - hostStart);
sl@0
   479
	TInt newlen = whatsLeft.Length();
sl@0
   480
	TInt portStart = whatsLeft.FindF(KX509URIPortStart);
sl@0
   481
	TInt urlPathStart = whatsLeft.FindF(KX509URIurlPathStart);
sl@0
   482
	if (portStart == KErrNotFound)
sl@0
   483
		{
sl@0
   484
		if (urlPathStart == KErrNotFound)
sl@0
   485
			{
sl@0
   486
			hostEnd = newlen;
sl@0
   487
			}
sl@0
   488
		else
sl@0
   489
			{
sl@0
   490
			hostEnd = urlPathStart;
sl@0
   491
			}
sl@0
   492
		}
sl@0
   493
	else
sl@0
   494
		{
sl@0
   495
		if (urlPathStart == KErrNotFound)
sl@0
   496
			{
sl@0
   497
			hostEnd = portStart;
sl@0
   498
			}
sl@0
   499
		else //both are there, choose the first one
sl@0
   500
			{
sl@0
   501
			hostEnd = ((urlPathStart > portStart)? portStart: urlPathStart);
sl@0
   502
			}
sl@0
   503
		}
sl@0
   504
	TPtrC host(&(iName->operator[](hostStart)), hostEnd);
sl@0
   505
	return host;
sl@0
   506
	}
sl@0
   507
sl@0
   508
//IP Address
sl@0
   509
//subnet mask
sl@0
   510
EXPORT_C CX509IPSubnetMask* CX509IPSubnetMask::NewL(const TDesC8& aBinaryData)
sl@0
   511
	{
sl@0
   512
	CX509IPSubnetMask* self = CX509IPSubnetMask::NewLC(aBinaryData);
sl@0
   513
	CleanupStack::Pop();//self;
sl@0
   514
	return self;
sl@0
   515
	}
sl@0
   516
sl@0
   517
EXPORT_C CX509IPSubnetMask* CX509IPSubnetMask::NewLC(const TDesC8& aBinaryData)
sl@0
   518
	{
sl@0
   519
	CX509IPSubnetMask* self = new(ELeave) CX509IPSubnetMask;
sl@0
   520
	CleanupStack::PushL(self);
sl@0
   521
	self->ConstructL(aBinaryData);
sl@0
   522
	return self;
sl@0
   523
	}
sl@0
   524
sl@0
   525
void CX509IPSubnetMask::ConstructL(const TDesC8& aBinaryData)
sl@0
   526
	{
sl@0
   527
	//!!!need to correct this when we have octet strings going!!!
sl@0
   528
	TASN1DecGeneric encAddr(aBinaryData);
sl@0
   529
	encAddr.InitL();
sl@0
   530
	iName = encAddr.GetContentDER().AllocL();// = CASN1OctetString::DecodeDERL(aBinaryData, pos);
sl@0
   531
	TInt len = iName->Length();
sl@0
   532
	if (!((len == 8) || (len == 32)))
sl@0
   533
		{
sl@0
   534
		User::Leave(KErrArgument);
sl@0
   535
		}
sl@0
   536
	}
sl@0
   537
sl@0
   538
EXPORT_C CX509IPSubnetMask::~CX509IPSubnetMask()
sl@0
   539
	{
sl@0
   540
	delete iName;
sl@0
   541
	}
sl@0
   542
sl@0
   543
EXPORT_C TPtrC8 CX509IPSubnetMask::BaseAddress() const
sl@0
   544
	{
sl@0
   545
	TInt half = iName->Length()/2;
sl@0
   546
	TPtrC8 ptr(&(iName->operator [] (0)), half);
sl@0
   547
	return ptr;
sl@0
   548
	}
sl@0
   549
sl@0
   550
EXPORT_C TPtrC8 CX509IPSubnetMask::Mask() const
sl@0
   551
	{
sl@0
   552
	TInt half = iName->Length()/2;
sl@0
   553
	TPtrC8 ptr(&(iName->operator [] (half)), half);
sl@0
   554
	return ptr;
sl@0
   555
	}
sl@0
   556
sl@0
   557
CX509IPSubnetMask::CX509IPSubnetMask()
sl@0
   558
	:iName(NULL)
sl@0
   559
	{
sl@0
   560
	}
sl@0
   561
sl@0
   562
//ip address
sl@0
   563
EXPORT_C CX509IPAddress* CX509IPAddress::NewL(const TDesC8& aBinaryData)
sl@0
   564
	{
sl@0
   565
	CX509IPAddress* self = CX509IPAddress::NewLC(aBinaryData);
sl@0
   566
	CleanupStack::Pop();//self
sl@0
   567
	return self;
sl@0
   568
	}
sl@0
   569
sl@0
   570
EXPORT_C CX509IPAddress* CX509IPAddress::NewLC(const TDesC8& aBinaryData)
sl@0
   571
	{
sl@0
   572
	CX509IPAddress* self = new(ELeave) CX509IPAddress;
sl@0
   573
	CleanupStack::PushL(self);
sl@0
   574
	self->ConstructL(aBinaryData);
sl@0
   575
	return self;
sl@0
   576
	}
sl@0
   577
sl@0
   578
void CX509IPAddress::ConstructL(const TDesC8& aBinaryData)
sl@0
   579
	{
sl@0
   580
	TASN1DecGeneric encAddr(aBinaryData);
sl@0
   581
	encAddr.InitL();
sl@0
   582
	iName = encAddr.GetContentDER().AllocL();
sl@0
   583
	TInt len = iName->Length();
sl@0
   584
	if (!(len == 4 || len == 16))
sl@0
   585
		{
sl@0
   586
		User::Leave(KErrArgument);
sl@0
   587
		}
sl@0
   588
	}
sl@0
   589
sl@0
   590
EXPORT_C CX509IPAddress::~CX509IPAddress()
sl@0
   591
	{
sl@0
   592
	delete iName;
sl@0
   593
	}
sl@0
   594
sl@0
   595
EXPORT_C TBool CX509IPAddress::IsWithinSubtree(const CX509IPSubnetMask& aName) const
sl@0
   596
	{
sl@0
   597
	TInt addrLen = iName->Length();
sl@0
   598
	if (((aName.iName->Length())/2) !=  addrLen)
sl@0
   599
		{
sl@0
   600
		return EFalse;
sl@0
   601
		}
sl@0
   602
	for (TInt i = 0; i < addrLen; i++)
sl@0
   603
		{
sl@0
   604
		//stop stupid compiler warning
sl@0
   605
		TUint8 masked = (TUint8) ((iName->operator [] (i)) & (aName.iName->operator [] (i + addrLen)));
sl@0
   606
		if (masked != (aName.iName->operator [] (i)))
sl@0
   607
			{
sl@0
   608
			return EFalse;
sl@0
   609
			}
sl@0
   610
		}
sl@0
   611
	return ETrue;
sl@0
   612
	}
sl@0
   613
sl@0
   614
EXPORT_C TPtrC8 CX509IPAddress::Address() const
sl@0
   615
	{
sl@0
   616
	return iName->Des();
sl@0
   617
	}
sl@0
   618
sl@0
   619
CX509IPAddress::CX509IPAddress()
sl@0
   620
	:iName(NULL)
sl@0
   621
	{
sl@0
   622
	}
sl@0
   623
sl@0
   624
//*******************X.509 General Name**********************//
sl@0
   625
EXPORT_C CX509GeneralName* CX509GeneralName::NewL(const TDesC8& aBinaryData)
sl@0
   626
	{
sl@0
   627
	TInt pos = 0;
sl@0
   628
	return CX509GeneralName::NewL(aBinaryData, pos);
sl@0
   629
	}
sl@0
   630
sl@0
   631
EXPORT_C CX509GeneralName* CX509GeneralName::NewLC(const TDesC8& aBinaryData)
sl@0
   632
	{
sl@0
   633
	TInt pos = 0;
sl@0
   634
	return CX509GeneralName::NewLC(aBinaryData, pos);
sl@0
   635
	}
sl@0
   636
sl@0
   637
EXPORT_C CX509GeneralName* CX509GeneralName::NewL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   638
	{
sl@0
   639
	CX509GeneralName* self = CX509GeneralName::NewLC(aBinaryData, aPos);
sl@0
   640
	CleanupStack::Pop();
sl@0
   641
	return self;
sl@0
   642
	}
sl@0
   643
sl@0
   644
EXPORT_C CX509GeneralName* CX509GeneralName::NewLC(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   645
	{
sl@0
   646
	CX509GeneralName* self = new(ELeave) CX509GeneralName;
sl@0
   647
	CleanupStack::PushL(self);
sl@0
   648
	self->ConstructL(aBinaryData, aPos);
sl@0
   649
	return self;
sl@0
   650
	}
sl@0
   651
sl@0
   652
EXPORT_C CX509GeneralName* CX509GeneralName::NewL(const CX509GeneralName& aName)
sl@0
   653
	{
sl@0
   654
	CX509GeneralName* self = CX509GeneralName::NewLC(aName);
sl@0
   655
	CleanupStack::Pop();
sl@0
   656
	return self;
sl@0
   657
	}
sl@0
   658
sl@0
   659
EXPORT_C CX509GeneralName* CX509GeneralName::NewLC(const CX509GeneralName& aName)
sl@0
   660
	{
sl@0
   661
	CX509GeneralName* self = new(ELeave) CX509GeneralName(aName.iTag);
sl@0
   662
	CleanupStack::PushL(self);
sl@0
   663
	self->ConstructL(aName.iData->Des());
sl@0
   664
	return self;
sl@0
   665
	}
sl@0
   666
sl@0
   667
void CX509GeneralName::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
sl@0
   668
	{
sl@0
   669
	TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos));
sl@0
   670
	gen.InitL();
sl@0
   671
	aPos += gen.LengthDER();//add on header info
sl@0
   672
	if (gen.Class() != EContextSpecific)
sl@0
   673
		{
sl@0
   674
		User::Leave(KErrArgument);
sl@0
   675
		}
sl@0
   676
	iData = gen.Tag() == 4 ? gen.GetContentDER().AllocL(): gen.Encoding().AllocL();
sl@0
   677
	iTag = gen.Tag();
sl@0
   678
	}
sl@0
   679
sl@0
   680
void CX509GeneralName::ConstructL(const TDesC8& aData)
sl@0
   681
	{
sl@0
   682
	iData = aData.AllocL();
sl@0
   683
	}
sl@0
   684
sl@0
   685
CX509GeneralName::CX509GeneralName(TGNType aType)
sl@0
   686
	:iTag(aType)
sl@0
   687
	{
sl@0
   688
	}
sl@0
   689
sl@0
   690
CX509GeneralName::CX509GeneralName()
sl@0
   691
	{
sl@0
   692
	}
sl@0
   693
sl@0
   694
EXPORT_C TGNType CX509GeneralName::Tag() const
sl@0
   695
	{
sl@0
   696
	return iTag;
sl@0
   697
	}
sl@0
   698
sl@0
   699
EXPORT_C TPtrC8 CX509GeneralName::Data() const
sl@0
   700
	{
sl@0
   701
	return iData->Des();
sl@0
   702
	}
sl@0
   703
sl@0
   704
EXPORT_C TBool CX509GeneralName::ExactMatch(const CX509GeneralName& /*aName*/) const
sl@0
   705
	{
sl@0
   706
	return EFalse;
sl@0
   707
	}
sl@0
   708
sl@0
   709
EXPORT_C CX509GeneralName::~CX509GeneralName()
sl@0
   710
	{
sl@0
   711
	delete iData;
sl@0
   712
	}