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