cryptoservices/certificateandkeymgmt/x509/x509gn.cpp
changeset 8 35751d3474b7
parent 0 2c201484c85f
--- a/cryptoservices/certificateandkeymgmt/x509/x509gn.cpp	Tue Jul 21 01:04:32 2009 +0100
+++ b/cryptoservices/certificateandkeymgmt/x509/x509gn.cpp	Thu Sep 10 14:01:51 2009 +0300
@@ -1,712 +1,712 @@
-/*
-* Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: 
-*
-*/
-
-
-#include <x509gn.h>
-#include "asn1dec.h"
-
-/*
- * __SECURITY_PLATSEC_ARCH__: Changes for platform security
- *
- * If this macro is defined, the represenation of TPtrC arrays is changed from
- * using CPtrCArray to RArray<TPtrC>.  This is because CPtrCArray is supplied by
- * bafl.dll, which is not trusted for TCB.  x509 needs to be trusted for TCB so
- * it can be used by software install, hence this dependency was removed.
- *
- * This changes is implmented as a series of macros for the basic operations,
- * to minimise the amount of conditional compilation.
- */
-
-
-#define REP_INIT_L		/* do nothing */
-#define REP_FINAL 		iRep.Close()
-#define REP_APPEND_L(X)	User::LeaveIfError(iRep.Append(X))
-#define REP_COUNT		iRep.Count()
-#define REP_AT(X)		iRep[X]
-#define REP_VAL			iRep
-#define REP_VAL_TYPE	RArray<TPtrC>
-
-
-_LIT(KX509RFC822HostDomainSeparator,"@");
-_LIT(KX509SubdomainSeparator,".");
-_LIT(KX509URISchemeSpecificStart, "//");
-_LIT(KX509URIUserPasswordEnd, "@");
-_LIT(KX509URIPortStart, ":");
-_LIT(KX509URIurlPathStart, "/");
-
-const TInt KX509URISchemeSpecificStartLength = 2;
-const TInt KX509URIUserPasswordEndLength = 1;
-const TInt KX509MaxDNSNameLabelLength = 63;
-
-//superclass: common functionality for DNS names & RFC 822 email addresses
-EXPORT_C CX509DomainName::~CX509DomainName()
-	{
-	REP_FINAL;
-	delete iName;
-	}
-
-CX509DomainName::CX509DomainName()
-	{
-	}
-
-EXPORT_C TPtrC CX509DomainName::Name() const 
-	{
-	return *iName;
-	}
-
-EXPORT_C TBool CX509DomainName::IsWithinSubtree(const CX509DomainName& aName) const
-   	{
-   	TInt myCount = REP_COUNT;
-   	TInt otherCount = aName.REP_COUNT;
-   	if (otherCount > myCount)
-   		{
-   		return EFalse;
-   		}
-   	for (TInt i = otherCount-1; i >= 0; i--)
-   		{
-   		myCount--;
-   		if ( KErrNotFound == REP_AT(myCount).MatchF(aName.REP_AT(i)) )
-   			{
-   			return EFalse;
-   			}
-   		}
-   	return ETrue;
-   	}
-
-TBool CX509DomainName::AddDomainL(TInt& aPos)
-	{
-	TInt end = iName->Length();
-	FOREVER
-		{
-		if (!(AddSubdomainL(aPos)))
-			{
-			return EFalse;
-			}
-		if (aPos == end)
-			{
-			break;
-			}
-		AddSubdomainSeparatorL(aPos);
-		}
-	return ETrue;
-	}
-
-TBool CX509DomainName::AddSubdomainL(TInt& aPos)
-	{
-	TBool res = EFalse;
-	TInt end = iName->Length();
-	if (aPos >= end)
-		{
-		return res;
-		}
-	TPtrC whatsLeft(&(iName->operator[] (aPos)), end - aPos);
-	TInt subdomainEnd = whatsLeft.FindF(KX509SubdomainSeparator);
-	if (subdomainEnd == 0)
-		{
-		return res;
-		}
-	if (subdomainEnd == KErrNotFound)
-		{
-		subdomainEnd = end - aPos;
-		}
-	TPtrC subdomain(&whatsLeft[0], subdomainEnd);
-	if (IsValidString(subdomain))
-		{
-		REP_APPEND_L(subdomain);
-		res = ETrue;
-		}
-	aPos = aPos + subdomainEnd;
-	return res;
-	}
-
-TBool CX509DomainName::AddSubdomainSeparatorL(TInt& aPos)
-	{
-	TBool res = EFalse;
-	TInt end = iName->Length();
-	if (end <= aPos)
-		{
-		return res;
-		}
-	TPtrC whatsLeft(&(iName->operator[] (aPos)), end - aPos);
-	TInt separatorEnd = whatsLeft.FindF(KX509SubdomainSeparator);
-	if (separatorEnd == 0)
-		{
-		TPtrC separator(&whatsLeft[0], 1);
-		REP_APPEND_L(separator);
-		aPos++;
-		res = ETrue;
-		}
-	return res;
-	}
-
-TBool CX509DomainName::IsValidString(const TDesC& aStr) const
-	{
-	TInt pos=0;
-	TInt end=aStr.Length()-1;
-	if (end < 0)
-		{
-		return ETrue;	
-		}
-	while (pos<end && IsValidChar(aStr[pos]))
-		{
-		pos++;
-		}
-	return (pos==end && IsValidChar(aStr[end]));
-	}
-
-TBool CX509DomainName::IsAlpha(const TChar& aChar) const 
-	{
-	return (	((aChar >= 97) && (aChar <= 122))	||
-				((aChar >= 65) && (aChar <= 90))	);
-	}
-
-TBool CX509DomainName::IsAlphaOrNum(const TChar& aChar) const
-	{
-	return ((IsAlpha(aChar)) ||
-			((aChar >= 48) && (aChar <= 57)) || (aChar == 42));
-	}
-
-TBool CX509DomainName::IsValidChar(const TChar& aChar) const
-	{
-	//default implementation: must be letter, number or hyphen
-	return ((IsAlphaOrNum(aChar)) ||
-			(aChar == 45) || (aChar == 42));
-	}
-
-//RFC 822 email address
-//subtree
-EXPORT_C CX509RFC822NameSubtree* CX509RFC822NameSubtree::NewL(const TDesC8& aBinaryData)
-	{
-	CX509RFC822NameSubtree* self = CX509RFC822NameSubtree::NewLC(aBinaryData);
-	CleanupStack::Pop();//self
-	return self;
-	}
-
-EXPORT_C CX509RFC822NameSubtree* CX509RFC822NameSubtree::NewLC(const TDesC8& aBinaryData)
-	{
-	CX509RFC822NameSubtree* self = new(ELeave) CX509RFC822NameSubtree;
-	CleanupStack::PushL(self);
-	self->ConstructL(aBinaryData);
-	return self;
-	}
-
-void CX509RFC822NameSubtree::ConstructL(const TDesC8& aBinaryData)
-	{
-	TInt pos = 0;
-	TASN1DecIA5String encStr;
-	iName = encStr.DecodeDERL(aBinaryData, pos);
-	REP_INIT_L;
-	//now, parse your data
-	pos = 0;	
-	AddLocalHostL(pos);
-	AddSubdomainSeparatorL(pos);
-	if (!(AddDomainL(pos)))
-		{
-		User::Leave(KErrArgument);
-		}
-	}
-
-TBool CX509RFC822NameSubtree::AddLocalHostL(TInt& aPos)
-	{
-	TInt localHostLength = iName->FindF(KX509RFC822HostDomainSeparator);
-	if ((localHostLength != KErrNotFound) && (localHostLength > 0))
-		{
-		TPtrC localHost(&(iName->operator[] (aPos)), localHostLength);		
-		//the local host name is not checked here as it caused defect PDEF108960 
-		//and for compatability with IE and Firefox.
-		REP_APPEND_L(localHost);
-		aPos = aPos + localHostLength;
-		aPos++;		//skip the @ symbol
-		return ETrue;
-		}
-	return EFalse;	//local host not found
-	}
-
-
-EXPORT_C const REP_VAL_TYPE& CX509RFC822NameSubtree::Rep() const
-	{
-	return REP_VAL;
-	}
-
-TBool CX509RFC822NameSubtree::IsValidChar(const TChar& aChar) const
-	{
-	//we permit "." here, 'cos it's allowed in local host names
-	//and must have been stripped out by domain parsing code,
-	//since it's the separator char
-	return (	(aChar == 33)						||
-				((aChar >= 35) && (aChar <= 40))	||
-				(aChar == 42)						||
-				(aChar == 43)						||
-				((aChar >= 45) && (aChar <= 57))	||
-				(aChar == 61)						||
-				(aChar == 63)						||
-				((aChar >= 65) && (aChar <= 90))	||
-				((aChar >= 94) && (aChar <= 126))	);
-	}
-
-//full rfc 822 name: exactly as subtree, but requires local host and full domain name
-EXPORT_C CX509RFC822Name* CX509RFC822Name::NewL(const TDesC8& aBinaryData)
-	{
-	CX509RFC822Name* self = CX509RFC822Name::NewLC(aBinaryData);
-	CleanupStack::Pop();//self
-	return self;
-	}
-
-EXPORT_C CX509RFC822Name* CX509RFC822Name::NewLC(const TDesC8& aBinaryData)
-	{
-	CX509RFC822Name* self = new(ELeave) CX509RFC822Name;
-	CleanupStack::PushL(self);
-	self->ConstructL(aBinaryData);
-	return self;
-	}
-
-void CX509RFC822Name::ConstructL(const TDesC8& aBinaryData)
-	{
-	TInt pos = 0;
-	TASN1DecIA5String encStr;
-	iName = encStr.DecodeDERL(aBinaryData, pos);
-	REP_INIT_L;
-	//now, parse your data
-	pos = 0;	
-	if (! ((AddLocalHostL(pos)) && (AddDomainL(pos))) )
-		{
-		User::Leave(KErrArgument);
-		}
-	}
-
-//DNS Name subtree
-EXPORT_C CX509DNSNameSubtree* CX509DNSNameSubtree::NewL(const TDesC8& aBinaryData)
-	{
-	CX509DNSNameSubtree* self = CX509DNSNameSubtree::NewLC(aBinaryData);
-	CleanupStack::Pop();//self
-	return self;
-	}
-
-EXPORT_C CX509DNSNameSubtree* CX509DNSNameSubtree::NewLC(const TDesC8& aBinaryData)
-	{
-	CX509DNSNameSubtree* self = new(ELeave) CX509DNSNameSubtree;
-	CleanupStack::PushL(self);
-	self->ConstructL(aBinaryData);
-	return self;
-	}
-
-void CX509DNSNameSubtree::ConstructL(const TDesC8& aBinaryData)
-	{
-	TInt pos = 0;
-	TASN1DecIA5String encStr;
-	iName = encStr.DecodeDERL(aBinaryData, pos);
-	REP_INIT_L;
-	pos = 0;
-	AddSubdomainSeparatorL(pos);//a subtree may start with a period
-	if (!(AddDomainL(pos)))
-		{
-		User::Leave(KErrArgument);
-		}
-	}
-
-EXPORT_C const REP_VAL_TYPE& CX509DNSNameSubtree::Rep() const
-	{
-	return REP_VAL;
-	}
-
-TBool CX509DNSNameSubtree::IsValidString(const TDesC& aStr) const
-	{
-	//must be <= 63 chars long
-	//must start with letter, end with letter or number
-	TInt len = aStr.Length();
-	return (	(len <= KX509MaxDNSNameLabelLength) &&
-				(IsAlphaOrNum(aStr[0]))				&&
-				(IsAlphaOrNum(aStr[len-1]))			&&
-				(CX509DomainName::IsValidString(aStr))				);
-	}
-
-//dns name: exactly as subtree but requires full domain name
-EXPORT_C CX509DNSName* CX509DNSName::NewL(const TDesC8& aBinaryData)
-	{
-	CX509DNSName* self = CX509DNSName::NewLC(aBinaryData);
-	CleanupStack::Pop();//self
-	return self;
-	}
-
-EXPORT_C CX509DNSName* CX509DNSName::NewLC(const TDesC8& aBinaryData)
-	{
-	CX509DNSName* self = new(ELeave) CX509DNSName;
-	CleanupStack::PushL(self);
-	self->ConstructL(aBinaryData);
-	return self;
-	}
-
-EXPORT_C CX509DNSName* CX509DNSName::NewL(const CX509DNSName& aName)
-	{
-	CX509DNSName* self = CX509DNSName::NewLC(aName);
-	CleanupStack::Pop();//self
-	return self;
-	}
-
-EXPORT_C CX509DNSName* CX509DNSName::NewLC(const CX509DNSName& aName)
-	{	
-	CX509DNSName* self = new(ELeave) CX509DNSName;
-	CleanupStack::PushL(self);
-	self->ConstructL(aName);
-	return self;	
-	}
-
-
-EXPORT_C CX509DNSName* CX509DNSName::NewL(const TDesC& aNameString)
-	{
-	CX509DNSName* self = CX509DNSName::NewLC(aNameString);
-	CleanupStack::Pop();//self
-	return self;	
-	}
-
-EXPORT_C CX509DNSName* CX509DNSName::NewLC(const TDesC& aNameString)
-	{
-	CX509DNSName* self = new(ELeave) CX509DNSName;
-	CleanupStack::PushL(self);
-	self->ConstructL(aNameString);
-	return self;
-	}
-
-void CX509DNSName::ConstructL(const TDesC& aNameString)
-	{
-	TInt pos = 0;
-	REP_INIT_L;
-	iName = aNameString.AllocL();
-	AddSubdomainSeparatorL(pos);//a subtree may start with a period
-	if (!(AddDomainL(pos)))
-		{
-		User::Leave(KErrArgument);
-		}
-	}
-
-void CX509DNSName::ConstructL(const TDesC8& aBinaryData)
-	{
-	TInt pos = 0;
-	TASN1DecIA5String encStr;
-	iName = encStr.DecodeDERL(aBinaryData, pos);
-	ParseNameL();
-	}
-
-void CX509DNSName::ConstructL(const CX509DNSName& aName)
-	{
-	iName = aName.iName->AllocL();
-	ParseNameL();
-	}
-
-void CX509DNSName::ParseNameL()
-	{
-	REP_INIT_L;
-	TInt pos = 0;
-	if  (!AddDomainL(pos))
-		{
-		User::Leave(KErrArgument);
-		}
-	}
-
-//URI: must be of 'ip-based' form (rfc 1738 section 3.1)
-//_and_ contain a domain name (not an IP address)
-EXPORT_C CX509IPBasedURI* CX509IPBasedURI::NewL(const TDesC8& aBinaryData)
-	{
-	CX509IPBasedURI* self = CX509IPBasedURI::NewLC(aBinaryData);
-	CleanupStack::Pop();//self
-	return self;
-	}
-
-EXPORT_C CX509IPBasedURI* CX509IPBasedURI::NewLC(const TDesC8& aBinaryData)
-	{
-	CX509IPBasedURI* self = new(ELeave) CX509IPBasedURI;
-	CleanupStack::PushL(self);
-	self->ConstructL(aBinaryData);
-	return self;
-	}
-
-void CX509IPBasedURI::ConstructL(const TDesC8& aBinaryData)
-	{
-	TInt pos = 0;
-	TASN1DecIA5String encStr;
-	iName = encStr.DecodeDERL(aBinaryData, pos);
-	iHost = CX509DNSName::NewL(ExtractHostNameL());
-	}
-
-EXPORT_C CX509IPBasedURI::~CX509IPBasedURI()
-	{
-	delete iName;
-	delete iHost;
-	}
-
-CX509IPBasedURI::CX509IPBasedURI()
-	:iHost(NULL), iName(NULL)
-	{
-	}
-
-EXPORT_C const CX509DNSName& CX509IPBasedURI::Host() const
-	{
-	return *iHost;
-	}
-
-EXPORT_C TPtrC CX509IPBasedURI::Name() const
-	{
-	return iName->Des();
-	}
-
-TPtrC CX509IPBasedURI::ExtractHostNameL() const
-	{
-	TInt hostStart;
-	TInt hostEnd;
-	TInt len = iName->Length();
-	TInt schemeSpecificStart = (iName->FindF(KX509URISchemeSpecificStart) + KX509URISchemeSpecificStartLength);
-	TInt userPasswordEnd = (iName->FindF(KX509URIUserPasswordEnd)) + KX509URIUserPasswordEndLength;
-	hostStart = ((userPasswordEnd == 0)? schemeSpecificStart : userPasswordEnd);
-	if (hostStart == KErrNotFound)
-		{
-		User::Leave(KErrArgument);
-		}
-	TPtrC whatsLeft(&(iName->operator[](hostStart)), len - hostStart);
-	TInt newlen = whatsLeft.Length();
-	TInt portStart = whatsLeft.FindF(KX509URIPortStart);
-	TInt urlPathStart = whatsLeft.FindF(KX509URIurlPathStart);
-	if (portStart == KErrNotFound)
-		{
-		if (urlPathStart == KErrNotFound)
-			{
-			hostEnd = newlen;
-			}
-		else
-			{
-			hostEnd = urlPathStart;
-			}
-		}
-	else
-		{
-		if (urlPathStart == KErrNotFound)
-			{
-			hostEnd = portStart;
-			}
-		else //both are there, choose the first one
-			{
-			hostEnd = ((urlPathStart > portStart)? portStart: urlPathStart);
-			}
-		}
-	TPtrC host(&(iName->operator[](hostStart)), hostEnd);
-	return host;
-	}
-
-//IP Address
-//subnet mask
-EXPORT_C CX509IPSubnetMask* CX509IPSubnetMask::NewL(const TDesC8& aBinaryData)
-	{
-	CX509IPSubnetMask* self = CX509IPSubnetMask::NewLC(aBinaryData);
-	CleanupStack::Pop();//self;
-	return self;
-	}
-
-EXPORT_C CX509IPSubnetMask* CX509IPSubnetMask::NewLC(const TDesC8& aBinaryData)
-	{
-	CX509IPSubnetMask* self = new(ELeave) CX509IPSubnetMask;
-	CleanupStack::PushL(self);
-	self->ConstructL(aBinaryData);
-	return self;
-	}
-
-void CX509IPSubnetMask::ConstructL(const TDesC8& aBinaryData)
-	{
-	//!!!need to correct this when we have octet strings going!!!
-	TASN1DecGeneric encAddr(aBinaryData);
-	encAddr.InitL();
-	iName = encAddr.GetContentDER().AllocL();// = CASN1OctetString::DecodeDERL(aBinaryData, pos);
-	TInt len = iName->Length();
-	if (!((len == 8) || (len == 32)))
-		{
-		User::Leave(KErrArgument);
-		}
-	}
-
-EXPORT_C CX509IPSubnetMask::~CX509IPSubnetMask()
-	{
-	delete iName;
-	}
-
-EXPORT_C TPtrC8 CX509IPSubnetMask::BaseAddress() const
-	{
-	TInt half = iName->Length()/2;
-	TPtrC8 ptr(&(iName->operator [] (0)), half);
-	return ptr;
-	}
-
-EXPORT_C TPtrC8 CX509IPSubnetMask::Mask() const
-	{
-	TInt half = iName->Length()/2;
-	TPtrC8 ptr(&(iName->operator [] (half)), half);
-	return ptr;
-	}
-
-CX509IPSubnetMask::CX509IPSubnetMask()
-	:iName(NULL)
-	{
-	}
-
-//ip address
-EXPORT_C CX509IPAddress* CX509IPAddress::NewL(const TDesC8& aBinaryData)
-	{
-	CX509IPAddress* self = CX509IPAddress::NewLC(aBinaryData);
-	CleanupStack::Pop();//self
-	return self;
-	}
-
-EXPORT_C CX509IPAddress* CX509IPAddress::NewLC(const TDesC8& aBinaryData)
-	{
-	CX509IPAddress* self = new(ELeave) CX509IPAddress;
-	CleanupStack::PushL(self);
-	self->ConstructL(aBinaryData);
-	return self;
-	}
-
-void CX509IPAddress::ConstructL(const TDesC8& aBinaryData)
-	{
-	TASN1DecGeneric encAddr(aBinaryData);
-	encAddr.InitL();
-	iName = encAddr.GetContentDER().AllocL();
-	TInt len = iName->Length();
-	if (!(len == 4 || len == 16))
-		{
-		User::Leave(KErrArgument);
-		}
-	}
-
-EXPORT_C CX509IPAddress::~CX509IPAddress()
-	{
-	delete iName;
-	}
-
-EXPORT_C TBool CX509IPAddress::IsWithinSubtree(const CX509IPSubnetMask& aName) const
-	{
-	TInt addrLen = iName->Length();
-	if (((aName.iName->Length())/2) !=  addrLen)
-		{
-		return EFalse;
-		}
-	for (TInt i = 0; i < addrLen; i++)
-		{
-		//stop stupid compiler warning
-		TUint8 masked = (TUint8) ((iName->operator [] (i)) & (aName.iName->operator [] (i + addrLen)));
-		if (masked != (aName.iName->operator [] (i)))
-			{
-			return EFalse;
-			}
-		}
-	return ETrue;
-	}
-
-EXPORT_C TPtrC8 CX509IPAddress::Address() const
-	{
-	return iName->Des();
-	}
-
-CX509IPAddress::CX509IPAddress()
-	:iName(NULL)
-	{
-	}
-
-//*******************X.509 General Name**********************//
-EXPORT_C CX509GeneralName* CX509GeneralName::NewL(const TDesC8& aBinaryData)
-	{
-	TInt pos = 0;
-	return CX509GeneralName::NewL(aBinaryData, pos);
-	}
-
-EXPORT_C CX509GeneralName* CX509GeneralName::NewLC(const TDesC8& aBinaryData)
-	{
-	TInt pos = 0;
-	return CX509GeneralName::NewLC(aBinaryData, pos);
-	}
-
-EXPORT_C CX509GeneralName* CX509GeneralName::NewL(const TDesC8& aBinaryData, TInt& aPos)
-	{
-	CX509GeneralName* self = CX509GeneralName::NewLC(aBinaryData, aPos);
-	CleanupStack::Pop();
-	return self;
-	}
-
-EXPORT_C CX509GeneralName* CX509GeneralName::NewLC(const TDesC8& aBinaryData, TInt& aPos)
-	{
-	CX509GeneralName* self = new(ELeave) CX509GeneralName;
-	CleanupStack::PushL(self);
-	self->ConstructL(aBinaryData, aPos);
-	return self;
-	}
-
-EXPORT_C CX509GeneralName* CX509GeneralName::NewL(const CX509GeneralName& aName)
-	{
-	CX509GeneralName* self = CX509GeneralName::NewLC(aName);
-	CleanupStack::Pop();
-	return self;
-	}
-
-EXPORT_C CX509GeneralName* CX509GeneralName::NewLC(const CX509GeneralName& aName)
-	{
-	CX509GeneralName* self = new(ELeave) CX509GeneralName(aName.iTag);
-	CleanupStack::PushL(self);
-	self->ConstructL(aName.iData->Des());
-	return self;
-	}
-
-void CX509GeneralName::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
-	{
-	TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos));
-	gen.InitL();
-	aPos += gen.LengthDER();//add on header info
-	if (gen.Class() != EContextSpecific)
-		{
-		User::Leave(KErrArgument);
-		}
-	iData = gen.Tag() == 4 ? gen.GetContentDER().AllocL(): gen.Encoding().AllocL();
-	iTag = gen.Tag();
-	}
-
-void CX509GeneralName::ConstructL(const TDesC8& aData)
-	{
-	iData = aData.AllocL();
-	}
-
-CX509GeneralName::CX509GeneralName(TGNType aType)
-	:iTag(aType)
-	{
-	}
-
-CX509GeneralName::CX509GeneralName()
-	{
-	}
-
-EXPORT_C TGNType CX509GeneralName::Tag() const
-	{
-	return iTag;
-	}
-
-EXPORT_C TPtrC8 CX509GeneralName::Data() const
-	{
-	return iData->Des();
-	}
-
-EXPORT_C TBool CX509GeneralName::ExactMatch(const CX509GeneralName& /*aName*/) const
-	{
-	return EFalse;
-	}
-
-EXPORT_C CX509GeneralName::~CX509GeneralName()
-	{
-	delete iData;
-	}
+/*
+* Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+#include <x509gn.h>
+#include "asn1dec.h"
+
+/*
+ * __SECURITY_PLATSEC_ARCH__: Changes for platform security
+ *
+ * If this macro is defined, the represenation of TPtrC arrays is changed from
+ * using CPtrCArray to RArray<TPtrC>.  This is because CPtrCArray is supplied by
+ * bafl.dll, which is not trusted for TCB.  x509 needs to be trusted for TCB so
+ * it can be used by software install, hence this dependency was removed.
+ *
+ * This changes is implmented as a series of macros for the basic operations,
+ * to minimise the amount of conditional compilation.
+ */
+
+
+#define REP_INIT_L		/* do nothing */
+#define REP_FINAL 		iRep.Close()
+#define REP_APPEND_L(X)	User::LeaveIfError(iRep.Append(X))
+#define REP_COUNT		iRep.Count()
+#define REP_AT(X)		iRep[X]
+#define REP_VAL			iRep
+#define REP_VAL_TYPE	RArray<TPtrC>
+
+
+_LIT(KX509RFC822HostDomainSeparator,"@");
+_LIT(KX509SubdomainSeparator,".");
+_LIT(KX509URISchemeSpecificStart, "//");
+_LIT(KX509URIUserPasswordEnd, "@");
+_LIT(KX509URIPortStart, ":");
+_LIT(KX509URIurlPathStart, "/");
+
+const TInt KX509URISchemeSpecificStartLength = 2;
+const TInt KX509URIUserPasswordEndLength = 1;
+const TInt KX509MaxDNSNameLabelLength = 63;
+
+//superclass: common functionality for DNS names & RFC 822 email addresses
+EXPORT_C CX509DomainName::~CX509DomainName()
+	{
+	REP_FINAL;
+	delete iName;
+	}
+
+CX509DomainName::CX509DomainName()
+	{
+	}
+
+EXPORT_C TPtrC CX509DomainName::Name() const 
+	{
+	return *iName;
+	}
+
+EXPORT_C TBool CX509DomainName::IsWithinSubtree(const CX509DomainName& aName) const
+   	{
+   	TInt myCount = REP_COUNT;
+   	TInt otherCount = aName.REP_COUNT;
+   	if (otherCount > myCount)
+   		{
+   		return EFalse;
+   		}
+   	for (TInt i = otherCount-1; i >= 0; i--)
+   		{
+   		myCount--;
+   		if ( KErrNotFound == REP_AT(myCount).MatchF(aName.REP_AT(i)) )
+   			{
+   			return EFalse;
+   			}
+   		}
+   	return ETrue;
+   	}
+
+TBool CX509DomainName::AddDomainL(TInt& aPos)
+	{
+	TInt end = iName->Length();
+	FOREVER
+		{
+		if (!(AddSubdomainL(aPos)))
+			{
+			return EFalse;
+			}
+		if (aPos == end)
+			{
+			break;
+			}
+		AddSubdomainSeparatorL(aPos);
+		}
+	return ETrue;
+	}
+
+TBool CX509DomainName::AddSubdomainL(TInt& aPos)
+	{
+	TBool res = EFalse;
+	TInt end = iName->Length();
+	if (aPos >= end)
+		{
+		return res;
+		}
+	TPtrC whatsLeft(&(iName->operator[] (aPos)), end - aPos);
+	TInt subdomainEnd = whatsLeft.FindF(KX509SubdomainSeparator);
+	if (subdomainEnd == 0)
+		{
+		return res;
+		}
+	if (subdomainEnd == KErrNotFound)
+		{
+		subdomainEnd = end - aPos;
+		}
+	TPtrC subdomain(&whatsLeft[0], subdomainEnd);
+	if (IsValidString(subdomain))
+		{
+		REP_APPEND_L(subdomain);
+		res = ETrue;
+		}
+	aPos = aPos + subdomainEnd;
+	return res;
+	}
+
+TBool CX509DomainName::AddSubdomainSeparatorL(TInt& aPos)
+	{
+	TBool res = EFalse;
+	TInt end = iName->Length();
+	if (end <= aPos)
+		{
+		return res;
+		}
+	TPtrC whatsLeft(&(iName->operator[] (aPos)), end - aPos);
+	TInt separatorEnd = whatsLeft.FindF(KX509SubdomainSeparator);
+	if (separatorEnd == 0)
+		{
+		TPtrC separator(&whatsLeft[0], 1);
+		REP_APPEND_L(separator);
+		aPos++;
+		res = ETrue;
+		}
+	return res;
+	}
+
+TBool CX509DomainName::IsValidString(const TDesC& aStr) const
+	{
+	TInt pos=0;
+	TInt end=aStr.Length()-1;
+	if (end < 0)
+		{
+		return ETrue;	
+		}
+	while (pos<end && IsValidChar(aStr[pos]))
+		{
+		pos++;
+		}
+	return (pos==end && IsValidChar(aStr[end]));
+	}
+
+TBool CX509DomainName::IsAlpha(const TChar& aChar) const 
+	{
+	return (	((aChar >= 97) && (aChar <= 122))	||
+				((aChar >= 65) && (aChar <= 90))	);
+	}
+
+TBool CX509DomainName::IsAlphaOrNum(const TChar& aChar) const
+	{
+	return ((IsAlpha(aChar)) ||
+			((aChar >= 48) && (aChar <= 57)) || (aChar == 42));
+	}
+
+TBool CX509DomainName::IsValidChar(const TChar& aChar) const
+	{
+	//default implementation: must be letter, number or hyphen
+	return ((IsAlphaOrNum(aChar)) ||
+			(aChar == 45) || (aChar == 42));
+	}
+
+//RFC 822 email address
+//subtree
+EXPORT_C CX509RFC822NameSubtree* CX509RFC822NameSubtree::NewL(const TDesC8& aBinaryData)
+	{
+	CX509RFC822NameSubtree* self = CX509RFC822NameSubtree::NewLC(aBinaryData);
+	CleanupStack::Pop();//self
+	return self;
+	}
+
+EXPORT_C CX509RFC822NameSubtree* CX509RFC822NameSubtree::NewLC(const TDesC8& aBinaryData)
+	{
+	CX509RFC822NameSubtree* self = new(ELeave) CX509RFC822NameSubtree;
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData);
+	return self;
+	}
+
+void CX509RFC822NameSubtree::ConstructL(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	TASN1DecIA5String encStr;
+	iName = encStr.DecodeDERL(aBinaryData, pos);
+	REP_INIT_L;
+	//now, parse your data
+	pos = 0;	
+	AddLocalHostL(pos);
+	AddSubdomainSeparatorL(pos);
+	if (!(AddDomainL(pos)))
+		{
+		User::Leave(KErrArgument);
+		}
+	}
+
+TBool CX509RFC822NameSubtree::AddLocalHostL(TInt& aPos)
+	{
+	TInt localHostLength = iName->FindF(KX509RFC822HostDomainSeparator);
+	if ((localHostLength != KErrNotFound) && (localHostLength > 0))
+		{
+		TPtrC localHost(&(iName->operator[] (aPos)), localHostLength);		
+		//the local host name is not checked here as it caused defect PDEF108960 
+		//and for compatability with IE and Firefox.
+		REP_APPEND_L(localHost);
+		aPos = aPos + localHostLength;
+		aPos++;		//skip the @ symbol
+		return ETrue;
+		}
+	return EFalse;	//local host not found
+	}
+
+
+EXPORT_C const REP_VAL_TYPE& CX509RFC822NameSubtree::Rep() const
+	{
+	return REP_VAL;
+	}
+
+TBool CX509RFC822NameSubtree::IsValidChar(const TChar& aChar) const
+	{
+	//we permit "." here, 'cos it's allowed in local host names
+	//and must have been stripped out by domain parsing code,
+	//since it's the separator char
+	return (	(aChar == 33)						||
+				((aChar >= 35) && (aChar <= 40))	||
+				(aChar == 42)						||
+				(aChar == 43)						||
+				((aChar >= 45) && (aChar <= 57))	||
+				(aChar == 61)						||
+				(aChar == 63)						||
+				((aChar >= 65) && (aChar <= 90))	||
+				((aChar >= 94) && (aChar <= 126))	);
+	}
+
+//full rfc 822 name: exactly as subtree, but requires local host and full domain name
+EXPORT_C CX509RFC822Name* CX509RFC822Name::NewL(const TDesC8& aBinaryData)
+	{
+	CX509RFC822Name* self = CX509RFC822Name::NewLC(aBinaryData);
+	CleanupStack::Pop();//self
+	return self;
+	}
+
+EXPORT_C CX509RFC822Name* CX509RFC822Name::NewLC(const TDesC8& aBinaryData)
+	{
+	CX509RFC822Name* self = new(ELeave) CX509RFC822Name;
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData);
+	return self;
+	}
+
+void CX509RFC822Name::ConstructL(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	TASN1DecIA5String encStr;
+	iName = encStr.DecodeDERL(aBinaryData, pos);
+	REP_INIT_L;
+	//now, parse your data
+	pos = 0;	
+	if (! ((AddLocalHostL(pos)) && (AddDomainL(pos))) )
+		{
+		User::Leave(KErrArgument);
+		}
+	}
+
+//DNS Name subtree
+EXPORT_C CX509DNSNameSubtree* CX509DNSNameSubtree::NewL(const TDesC8& aBinaryData)
+	{
+	CX509DNSNameSubtree* self = CX509DNSNameSubtree::NewLC(aBinaryData);
+	CleanupStack::Pop();//self
+	return self;
+	}
+
+EXPORT_C CX509DNSNameSubtree* CX509DNSNameSubtree::NewLC(const TDesC8& aBinaryData)
+	{
+	CX509DNSNameSubtree* self = new(ELeave) CX509DNSNameSubtree;
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData);
+	return self;
+	}
+
+void CX509DNSNameSubtree::ConstructL(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	TASN1DecIA5String encStr;
+	iName = encStr.DecodeDERL(aBinaryData, pos);
+	REP_INIT_L;
+	pos = 0;
+	AddSubdomainSeparatorL(pos);//a subtree may start with a period
+	if (!(AddDomainL(pos)))
+		{
+		User::Leave(KErrArgument);
+		}
+	}
+
+EXPORT_C const REP_VAL_TYPE& CX509DNSNameSubtree::Rep() const
+	{
+	return REP_VAL;
+	}
+
+TBool CX509DNSNameSubtree::IsValidString(const TDesC& aStr) const
+	{
+	//must be <= 63 chars long
+	//must start with letter, end with letter or number
+	TInt len = aStr.Length();
+	return (	(len <= KX509MaxDNSNameLabelLength) &&
+				(IsAlphaOrNum(aStr[0]))				&&
+				(IsAlphaOrNum(aStr[len-1]))			&&
+				(CX509DomainName::IsValidString(aStr))				);
+	}
+
+//dns name: exactly as subtree but requires full domain name
+EXPORT_C CX509DNSName* CX509DNSName::NewL(const TDesC8& aBinaryData)
+	{
+	CX509DNSName* self = CX509DNSName::NewLC(aBinaryData);
+	CleanupStack::Pop();//self
+	return self;
+	}
+
+EXPORT_C CX509DNSName* CX509DNSName::NewLC(const TDesC8& aBinaryData)
+	{
+	CX509DNSName* self = new(ELeave) CX509DNSName;
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData);
+	return self;
+	}
+
+EXPORT_C CX509DNSName* CX509DNSName::NewL(const CX509DNSName& aName)
+	{
+	CX509DNSName* self = CX509DNSName::NewLC(aName);
+	CleanupStack::Pop();//self
+	return self;
+	}
+
+EXPORT_C CX509DNSName* CX509DNSName::NewLC(const CX509DNSName& aName)
+	{	
+	CX509DNSName* self = new(ELeave) CX509DNSName;
+	CleanupStack::PushL(self);
+	self->ConstructL(aName);
+	return self;	
+	}
+
+
+EXPORT_C CX509DNSName* CX509DNSName::NewL(const TDesC& aNameString)
+	{
+	CX509DNSName* self = CX509DNSName::NewLC(aNameString);
+	CleanupStack::Pop();//self
+	return self;	
+	}
+
+EXPORT_C CX509DNSName* CX509DNSName::NewLC(const TDesC& aNameString)
+	{
+	CX509DNSName* self = new(ELeave) CX509DNSName;
+	CleanupStack::PushL(self);
+	self->ConstructL(aNameString);
+	return self;
+	}
+
+void CX509DNSName::ConstructL(const TDesC& aNameString)
+	{
+	TInt pos = 0;
+	REP_INIT_L;
+	iName = aNameString.AllocL();
+	AddSubdomainSeparatorL(pos);//a subtree may start with a period
+	if (!(AddDomainL(pos)))
+		{
+		User::Leave(KErrArgument);
+		}
+	}
+
+void CX509DNSName::ConstructL(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	TASN1DecIA5String encStr;
+	iName = encStr.DecodeDERL(aBinaryData, pos);
+	ParseNameL();
+	}
+
+void CX509DNSName::ConstructL(const CX509DNSName& aName)
+	{
+	iName = aName.iName->AllocL();
+	ParseNameL();
+	}
+
+void CX509DNSName::ParseNameL()
+	{
+	REP_INIT_L;
+	TInt pos = 0;
+	if  (!AddDomainL(pos))
+		{
+		User::Leave(KErrArgument);
+		}
+	}
+
+//URI: must be of 'ip-based' form (rfc 1738 section 3.1)
+//_and_ contain a domain name (not an IP address)
+EXPORT_C CX509IPBasedURI* CX509IPBasedURI::NewL(const TDesC8& aBinaryData)
+	{
+	CX509IPBasedURI* self = CX509IPBasedURI::NewLC(aBinaryData);
+	CleanupStack::Pop();//self
+	return self;
+	}
+
+EXPORT_C CX509IPBasedURI* CX509IPBasedURI::NewLC(const TDesC8& aBinaryData)
+	{
+	CX509IPBasedURI* self = new(ELeave) CX509IPBasedURI;
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData);
+	return self;
+	}
+
+void CX509IPBasedURI::ConstructL(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	TASN1DecIA5String encStr;
+	iName = encStr.DecodeDERL(aBinaryData, pos);
+	iHost = CX509DNSName::NewL(ExtractHostNameL());
+	}
+
+EXPORT_C CX509IPBasedURI::~CX509IPBasedURI()
+	{
+	delete iName;
+	delete iHost;
+	}
+
+CX509IPBasedURI::CX509IPBasedURI()
+	:iHost(NULL), iName(NULL)
+	{
+	}
+
+EXPORT_C const CX509DNSName& CX509IPBasedURI::Host() const
+	{
+	return *iHost;
+	}
+
+EXPORT_C TPtrC CX509IPBasedURI::Name() const
+	{
+	return iName->Des();
+	}
+
+TPtrC CX509IPBasedURI::ExtractHostNameL() const
+	{
+	TInt hostStart;
+	TInt hostEnd;
+	TInt len = iName->Length();
+	TInt schemeSpecificStart = (iName->FindF(KX509URISchemeSpecificStart) + KX509URISchemeSpecificStartLength);
+	TInt userPasswordEnd = (iName->FindF(KX509URIUserPasswordEnd)) + KX509URIUserPasswordEndLength;
+	hostStart = ((userPasswordEnd == 0)? schemeSpecificStart : userPasswordEnd);
+	if (hostStart == KErrNotFound)
+		{
+		User::Leave(KErrArgument);
+		}
+	TPtrC whatsLeft(&(iName->operator[](hostStart)), len - hostStart);
+	TInt newlen = whatsLeft.Length();
+	TInt portStart = whatsLeft.FindF(KX509URIPortStart);
+	TInt urlPathStart = whatsLeft.FindF(KX509URIurlPathStart);
+	if (portStart == KErrNotFound)
+		{
+		if (urlPathStart == KErrNotFound)
+			{
+			hostEnd = newlen;
+			}
+		else
+			{
+			hostEnd = urlPathStart;
+			}
+		}
+	else
+		{
+		if (urlPathStart == KErrNotFound)
+			{
+			hostEnd = portStart;
+			}
+		else //both are there, choose the first one
+			{
+			hostEnd = ((urlPathStart > portStart)? portStart: urlPathStart);
+			}
+		}
+	TPtrC host(&(iName->operator[](hostStart)), hostEnd);
+	return host;
+	}
+
+//IP Address
+//subnet mask
+EXPORT_C CX509IPSubnetMask* CX509IPSubnetMask::NewL(const TDesC8& aBinaryData)
+	{
+	CX509IPSubnetMask* self = CX509IPSubnetMask::NewLC(aBinaryData);
+	CleanupStack::Pop();//self;
+	return self;
+	}
+
+EXPORT_C CX509IPSubnetMask* CX509IPSubnetMask::NewLC(const TDesC8& aBinaryData)
+	{
+	CX509IPSubnetMask* self = new(ELeave) CX509IPSubnetMask;
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData);
+	return self;
+	}
+
+void CX509IPSubnetMask::ConstructL(const TDesC8& aBinaryData)
+	{
+	//!!!need to correct this when we have octet strings going!!!
+	TASN1DecGeneric encAddr(aBinaryData);
+	encAddr.InitL();
+	iName = encAddr.GetContentDER().AllocL();// = CASN1OctetString::DecodeDERL(aBinaryData, pos);
+	TInt len = iName->Length();
+	if (!((len == 8) || (len == 32)))
+		{
+		User::Leave(KErrArgument);
+		}
+	}
+
+EXPORT_C CX509IPSubnetMask::~CX509IPSubnetMask()
+	{
+	delete iName;
+	}
+
+EXPORT_C TPtrC8 CX509IPSubnetMask::BaseAddress() const
+	{
+	TInt half = iName->Length()/2;
+	TPtrC8 ptr(&(iName->operator [] (0)), half);
+	return ptr;
+	}
+
+EXPORT_C TPtrC8 CX509IPSubnetMask::Mask() const
+	{
+	TInt half = iName->Length()/2;
+	TPtrC8 ptr(&(iName->operator [] (half)), half);
+	return ptr;
+	}
+
+CX509IPSubnetMask::CX509IPSubnetMask()
+	:iName(NULL)
+	{
+	}
+
+//ip address
+EXPORT_C CX509IPAddress* CX509IPAddress::NewL(const TDesC8& aBinaryData)
+	{
+	CX509IPAddress* self = CX509IPAddress::NewLC(aBinaryData);
+	CleanupStack::Pop();//self
+	return self;
+	}
+
+EXPORT_C CX509IPAddress* CX509IPAddress::NewLC(const TDesC8& aBinaryData)
+	{
+	CX509IPAddress* self = new(ELeave) CX509IPAddress;
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData);
+	return self;
+	}
+
+void CX509IPAddress::ConstructL(const TDesC8& aBinaryData)
+	{
+	TASN1DecGeneric encAddr(aBinaryData);
+	encAddr.InitL();
+	iName = encAddr.GetContentDER().AllocL();
+	TInt len = iName->Length();
+	if (!(len == 4 || len == 16))
+		{
+		User::Leave(KErrArgument);
+		}
+	}
+
+EXPORT_C CX509IPAddress::~CX509IPAddress()
+	{
+	delete iName;
+	}
+
+EXPORT_C TBool CX509IPAddress::IsWithinSubtree(const CX509IPSubnetMask& aName) const
+	{
+	TInt addrLen = iName->Length();
+	if (((aName.iName->Length())/2) !=  addrLen)
+		{
+		return EFalse;
+		}
+	for (TInt i = 0; i < addrLen; i++)
+		{
+		//stop stupid compiler warning
+		TUint8 masked = (TUint8) ((iName->operator [] (i)) & (aName.iName->operator [] (i + addrLen)));
+		if (masked != (aName.iName->operator [] (i)))
+			{
+			return EFalse;
+			}
+		}
+	return ETrue;
+	}
+
+EXPORT_C TPtrC8 CX509IPAddress::Address() const
+	{
+	return iName->Des();
+	}
+
+CX509IPAddress::CX509IPAddress()
+	:iName(NULL)
+	{
+	}
+
+//*******************X.509 General Name**********************//
+EXPORT_C CX509GeneralName* CX509GeneralName::NewL(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CX509GeneralName::NewL(aBinaryData, pos);
+	}
+
+EXPORT_C CX509GeneralName* CX509GeneralName::NewLC(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CX509GeneralName::NewLC(aBinaryData, pos);
+	}
+
+EXPORT_C CX509GeneralName* CX509GeneralName::NewL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CX509GeneralName* self = CX509GeneralName::NewLC(aBinaryData, aPos);
+	CleanupStack::Pop();
+	return self;
+	}
+
+EXPORT_C CX509GeneralName* CX509GeneralName::NewLC(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CX509GeneralName* self = new(ELeave) CX509GeneralName;
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData, aPos);
+	return self;
+	}
+
+EXPORT_C CX509GeneralName* CX509GeneralName::NewL(const CX509GeneralName& aName)
+	{
+	CX509GeneralName* self = CX509GeneralName::NewLC(aName);
+	CleanupStack::Pop();
+	return self;
+	}
+
+EXPORT_C CX509GeneralName* CX509GeneralName::NewLC(const CX509GeneralName& aName)
+	{
+	CX509GeneralName* self = new(ELeave) CX509GeneralName(aName.iTag);
+	CleanupStack::PushL(self);
+	self->ConstructL(aName.iData->Des());
+	return self;
+	}
+
+void CX509GeneralName::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	TASN1DecGeneric gen(aBinaryData.Right(aBinaryData.Length() - aPos));
+	gen.InitL();
+	aPos += gen.LengthDER();//add on header info
+	if (gen.Class() != EContextSpecific)
+		{
+		User::Leave(KErrArgument);
+		}
+	iData = gen.Tag() == 4 ? gen.GetContentDER().AllocL(): gen.Encoding().AllocL();
+	iTag = gen.Tag();
+	}
+
+void CX509GeneralName::ConstructL(const TDesC8& aData)
+	{
+	iData = aData.AllocL();
+	}
+
+CX509GeneralName::CX509GeneralName(TGNType aType)
+	:iTag(aType)
+	{
+	}
+
+CX509GeneralName::CX509GeneralName()
+	{
+	}
+
+EXPORT_C TGNType CX509GeneralName::Tag() const
+	{
+	return iTag;
+	}
+
+EXPORT_C TPtrC8 CX509GeneralName::Data() const
+	{
+	return iData->Des();
+	}
+
+EXPORT_C TBool CX509GeneralName::ExactMatch(const CX509GeneralName& /*aName*/) const
+	{
+	return EFalse;
+	}
+
+EXPORT_C CX509GeneralName::~CX509GeneralName()
+	{
+	delete iData;
+	}