diff -r 000000000000 -r 33413c0669b9 vpnengine/ikepolparser/src/ikepolparser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/ikepolparser/src/ikepolparser.cpp Thu Dec 17 09:14:51 2009 +0200 @@ -0,0 +1,2499 @@ +/* +* Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: IKE policy parser main module +* +*/ + + + +#include +#include +#include "ikepolparser.h" + +// +// EXPORTed functions +// + +//--------------------------------------------------------------------------- +// +// IKE Policy Parsing +// +//--------------------------------------------------------------------------- + +// +//CIkeData -> contains the ike data +// +CIkeData::CIkeData() : iIkeVersion(1) + { + } + +EXPORT_C CIkeData* CIkeData::NewL() + { + return new (ELeave) CIkeData(); + } + +EXPORT_C CIkeData* CIkeData::NewL(const CIkeData *aData) + { + CIkeData* self = new (ELeave) CIkeData(); + CleanupStack::PushL(self); + self->ConstructL(aData); + CleanupStack::Pop(self); + return self; + } + +EXPORT_C void CIkeData::ConstructL(const CIkeData *aData) + { + CopyL(aData); + } + +EXPORT_C CIkeData::~CIkeData() + { + delete iRemoteIdentity; + delete iEAPRealmPrefix; + delete iEAPManualRealm; + delete iEAPManualUserName; + delete iCRACKLAMUserName; + delete iCRACKLAMPassword; + delete iClientCertType; + delete iFQDNAddr; + Empty(); + } + +EXPORT_C void CIkeData::CopyL(const CIkeData* aData) + { + if ( aData == NULL ) + { + User::Leave( KErrNoMemory ); + } + + Empty(); //Free the previous info + iAddr = aData->iAddr; //Peer host address + iMask = aData->iMask; //Peer host mask + if (aData->iFQDNAddr) + iFQDNAddr=TStringData::NewL(aData->iFQDNAddr->GetData()); + iMode = aData->iMode; + iNotify = aData->iNotify; + iFQDN.Copy(aData->iFQDN); + iIdType = aData->iIdType; + iGroupDesc_II = aData->iGroupDesc_II; + iAcceptPartialRemoteId = aData->iAcceptPartialRemoteId; + iIkeVersion = aData->iIkeVersion; + iCommit = aData->iCommit; + iIpsecExpires = aData->iIpsecExpires; + iAlwaysSendCert = aData->iAlwaysSendCert; + iInitialContact = aData->iInitialContact; //INITIAL-CONTACT sending + iResponderLifetime = aData->iResponderLifetime; //RESPONDER_LIFETIME sending + iReplayStatus = aData->iReplayStatus; //RESPONDER_LIFETIME sending + iCRACKLAMType = aData->iCRACKLAMType; //CRACK LAM type + if (aData->iCRACKLAMUserName) + iCRACKLAMUserName=TStringData::NewL(aData->iCRACKLAMUserName->GetData()); + if (aData->iCRACKLAMPassword) + iCRACKLAMPassword=TStringData::NewL(aData->iCRACKLAMPassword->GetData()); + iUseInternalAddr = aData->iUseInternalAddr; + iUseNatProbing = aData->iUseNatProbing; + iEspUdpPort = aData->iEspUdpPort; + iNatKeepAlive = aData->iNatKeepAlive; + iDscp = aData->iDscp; + iDPDHeartBeat = aData->iDPDHeartBeat; + iRekeyingThreshold = aData->iRekeyingThreshold; + iUseXauth = aData->iUseXauth; + iUseCfgMode = aData->iUseCfgMode; + iUseMobIke = aData->iUseMobIke; + + iRemoteIdType = aData->iRemoteIdType; + iSkipRemoteIdCheck = aData->iSkipRemoteIdCheck; + if ( aData->iRemoteIdentity ) + iRemoteIdentity = TStringData::NewL(aData->iRemoteIdentity->GetData()); + iEAPProtocol = aData->iEAPProtocol; + iEAPHideIdentity = aData->iEAPHideIdentity; + if ( aData->iEAPRealmPrefix ) + iEAPRealmPrefix = TStringData::NewL( + aData->iEAPRealmPrefix->GetData()); + if ( aData->iEAPManualRealm ) + iEAPManualRealm = TStringData::NewL( + aData->iEAPManualRealm->GetData()); + if ( aData->iEAPManualUserName ) + iEAPManualUserName = TStringData::NewL( + aData->iEAPManualUserName->GetData()); + if (aData->iClientCertType) + iClientCertType = TStringData::NewL(aData->iClientCertType->GetData()); + + iNumProp = aData->iNumProp; + TProposalData* prop = NULL; + TProposalData* prev = NULL; + TProposalData* tmp_prop = aData->iPropList; + for (TInt i=0; i < iNumProp; i++) + { + prop = new (ELeave) TProposalData; + *prop = *tmp_prop; + if (prev) + prev->iNext = prop; + else //first + iPropList = prop; + + prop->iPrev = prev; + prev = prop; + tmp_prop = tmp_prop->iNext; + } + if (prop) + prop->iNext = NULL; + + iPresharedKey = aData->iPresharedKey; + iCA = aData->iCA; + iOwnCert = aData->iOwnCert; + iPrivKey = aData->iPrivKey; + iPeerCert = aData->iPeerCert; + + if ( aData->iCAList ) + { + TInt count( aData->iCAList->Count() ); + iCAList = new (ELeave) CArrayFixFlat(count); + + for ( TInt x(0); x < count; x++ ) + { + TCertInfo* ca_copy = new (ELeave) TCertInfo; + CleanupStack::PushL(ca_copy); + *ca_copy = *(aData->iCAList->At(x)); + iCAList->AppendL(ca_copy); + CleanupStack::Pop(ca_copy); + } + } + } + +void CIkeData::Empty() + { + TProposalData* prop = iPropList; + TProposalData* next_prop; + while (prop) + { + next_prop = prop->iNext; + delete prop; + prop = next_prop; + } + if ( iCAList ) + { + for (TInt i(0); iCount(); ++i) + { + delete iCAList->At(i); + iCAList->At(i) = NULL; + } + iCAList->Reset(); + delete iCAList; + iCAList = NULL; + } + } + + +// +// CIkeDataArray +// +CIkeDataArray::CIkeDataArray(TInt aGranularity) + :CArrayFixFlat(aGranularity) + { + } + +EXPORT_C CIkeDataArray* CIkeDataArray::NewL(TInt aGranularity) + { + ASSERT(aGranularity); + return new (ELeave) CIkeDataArray(aGranularity); + } + +CIkeDataArray::CIkeDataArray(CIkeDataArray* aData) + :CArrayFixFlat(aData ? aData->Count() : 0) + { + } + +EXPORT_C CIkeDataArray* CIkeDataArray::NewL(CIkeDataArray* aData) + { + User::LeaveIfNull(aData); + ASSERT(aData->Count()); + CIkeDataArray* self = new (ELeave) CIkeDataArray(aData); + CleanupStack::PushL(self); + self->ConstructL(aData); + CleanupStack::Pop(self); + return self; + } + +EXPORT_C void CIkeDataArray::ConstructL(CIkeDataArray *aData) + { + CopyL(aData); + } + +EXPORT_C CIkeDataArray::~CIkeDataArray() + { + Empty(); + } + +//Constructs this from the data in aData +EXPORT_C void CIkeDataArray::CopyL(CIkeDataArray* aData) + { + User::LeaveIfNull(aData); + CIkeData* ike_data(NULL); + for (TInt i(0); i < aData->Count(); i++) + { + ike_data = CIkeData::NewL(aData->At(i)); + AppendL(ike_data); + } + iMaxLifetimeKB = aData->iMaxLifetimeKB; + iMaxLifetimeSec = aData->iMaxLifetimeSec; + iMaxRetrans = aData->iMaxRetrans; + iMaxTraceFileSize = aData->iMaxTraceFileSize; + } + +EXPORT_C void CIkeDataArray::Empty() + { + for (TInt i(0); i < Count(); i++) + { + delete At(i); + } + Reset(); + } + + + +// +//TIKEParser -> parses the ike data from a descriptor or writes it to a file +// +// Symbian change - start +#ifdef __VC32__ +#pragma warning(disable : 4097) // typedef-name used as synonym for class-name +#endif +// Symbian change - end +EXPORT_C TIkeParser::TIkeParser() : TLex(), iVersion(0) +{ + +} + +EXPORT_C TIkeParser::TIkeParser(const TDesC &aStr, TInt aVersion) : TLex(aStr), iVersion(aVersion) +{ + +} + +//Parses the Main ike file +EXPORT_C void TIkeParser::MainParseL(CIkeDataArray *aIkeList) +{ + TPtrC ikeHostSeparator = IKE_HOST_SEPARATOR; + DoMainParseL(aIkeList, ikeHostSeparator); +} + +EXPORT_C void TIkeParser::ParseIKESectionsL(CIkeDataArray *aIkeList) +{ + TPtrC ikeSeparator = IKE_SEPARATOR; + DoMainParseL(aIkeList, ikeSeparator); +} + +void TIkeParser::DoMainParseL(CIkeDataArray* aIkeList, TPtrC& aSectionName) +{ + ASSERT( aIkeList ); + + TPtrC token(NULL,0); + + while (!Eos()) + { + token.Set(NextToken()); + if (token.Compare(aSectionName)==0) + { + CIkeData* ike_piece = CIkeData::NewL(); + CleanupStack::PushL(ike_piece); + ParseIkePieceL(ike_piece, SEC_PARSER_VERSION, //Always the latest because is generated by the program itself + aSectionName); + aIkeList->AppendL(ike_piece); + CleanupStack::Pop(ike_piece); + } + else if (token.Compare(IKE_GENERAL_SEPARATOR)==0) + { + //Always the latest because is generated by the program itself + User::LeaveIfError(ParseGeneralData(aIkeList)); + } + } +} + + +//Only 2 sections of general data (max lifetimes) +TInt TIkeParser::ParseGeneralData(CIkeDataArray* aIkeList) +{ + ASSERT(aIkeList); + + TLex sub_num; //Used for number conversion + TInt err = KErrNone; + TPtrC token(NULL,0); + while (!Eos() && err==KErrNone) + { + Mark(); + token.Set(NextToken()); + if (token.CompareF(_L("ISAKMP_SA_MAX_LIFETIME_SEC:")) == 0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(aIkeList->iMaxLifetimeSec,EDecimal)!=KErrNone) + err = KSecParserErrMaxLifetimeSec; + } + else if (token.CompareF(_L("ISAKMP_SA_MAX_LIFETIME_KB:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(aIkeList->iMaxLifetimeKB,EDecimal)!=KErrNone) + err = KSecParserErrMaxLifetimeKB; + } + else if (token.CompareF(_L("ISAKMP_MAX_RETRANS:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(aIkeList->iMaxRetrans)!=KErrNone) + err = KSecParserErrMaxRetrans; + } + else if (token.CompareF(_L("TRACE_FILE_SIZE:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(aIkeList->iMaxTraceFileSize)!=KErrNone) + err = KSecParserErrMaxRetrans; + } + + else if (token.Compare(IKE_HOST_SEPARATOR)==0) //END of general section + { + UnGetToMark(); //Ungets the token + return KErrNone; + } + else if (token.Compare(IKE_GENERAL_SEPARATOR)==0)//END of general section + { + UnGetToMark(); //Ungets the token + return KErrNone; + } + else if (token.Compare(IKE_SEPARATOR)==0)//END of general section + { + UnGetToMark(); //Ungets the token + return KErrNone; + } + //others ignored + } + + return err; +} + +void TIkeParser::ParseIkePieceL(CIkeData* aIkeData, TInt aVersion, TPtrC& aSectionName) +{ + TInt pos = Remainder().Find(aSectionName); + if (pos != KErrNotFound) + { + TPtr ike_ptr((TUint16*)Remainder().Ptr(),pos, pos); //Until the next section + + TIkeParser parser(ike_ptr, aVersion); + parser.ParseL(aIkeData); + Assign(Remainder().Mid(pos)); //rest of the text to parse + } + else //No more tags + { + TIkeParser parser(Remainder(), aVersion); + parser.ParseL(aIkeData); + Assign(Remainder().Mid(Remainder().Length())); + } +} + +EXPORT_C void TIkeParser::ParseL(CIkeData* aConf) +{ + ASSERT(aConf); + + TInt err = KErrNone; + TInt errCA= KErrNone; + TPtrC token(NULL,0); + TLex sub_num; //Used for number conversion + + while (!Eos() && err==KErrNone) + { + //General Data + token.Set(NextToken()); + if (token.CompareF(_L("ADDR:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + + err = aConf->iAddr.Input(token); + if (err != KErrNone) + { + err = KSecParserErrPeerAddr; + aConf->iFQDNAddr = TStringData::NewL(token); + } + if (iVersion >= 2) //Incorporated in version 2 + { + token.Set(NextToken()); + err = aConf->iMask.Input(token); + if (err != KErrNone) + err = KSecParserErrPeerMask; + } + } + else if (token.CompareF(_L("DNS_SERVER:"))==0) + { + token.Set(NextToken()); + + err = aConf->iDnsServer.Input(token); + if (err != KErrNone) + { + err = KSecParserErrUnknown; + } + } + else if (token.CompareF(_L("MODE:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("Main"))==0) + aConf->iMode = IKE_PARSER_MAIN; + else if (token.CompareF(_L("Aggressive"))==0) + aConf->iMode = IKE_PARSER_AGGRESSIVE; + else + err = KSecParserErrMode; + } + else if (token.CompareF(_L("IKE_VERSION:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + sub_num.Val(aConf->iIkeVersion, EDecimal); + if ( aConf->iIkeVersion != 2 ) + aConf->iIkeVersion = 1; // IKE version 1 is currently the default + } + else if (token.CompareF(_L("SEND_NOTIFICATION:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iNotify = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iNotify = EFalse; + else + err = KSecParserErrNotify; + } + else if (token.CompareF(_L("FQDN:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iFQDN.Copy(token); + } + else if (token.CompareF(_L("ID_TYPE:"))==0) //CompareF ignores case + { + // Specifies IKE Phase 1 Identity type. Integer value specified in rfc2407 + sub_num = NextToken(); + if ( sub_num.Val(aConf->iIdType, EDecimal)!= KErrNone ) + aConf->iIdType = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("REMOTE_ID_TYPE:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if ( sub_num.Val(aConf->iRemoteIdType, EDecimal)!= KErrNone ) + aConf->iRemoteIdType = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("REMOTE_IDENTITY:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iRemoteIdentity = TStringData::NewL(token); + } + else if (token.CompareF(_L("ACCEPT_PARTIAL_REMOTE_ID:"))==0) //CompareF ignores case + { + aConf->iAcceptPartialRemoteId = EFalse; + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iAcceptPartialRemoteId = ETrue; + } + else if (token.CompareF(_L("SKIP_REMOTE_ID_CHECK:"))==0) //CompareF ignores case + { + aConf->iSkipRemoteIdCheck = EFalse; + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iSkipRemoteIdCheck = ETrue; + } + else if (token.CompareF(_L("GROUP_DESCRIPTION_II:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("MODP_768"))==0) + aConf->iGroupDesc_II = IKE_PARSER_MODP_768; + else if (token.CompareF(_L("MODP_1024"))==0) + aConf->iGroupDesc_II = IKE_PARSER_MODP_1024; + else if (token.CompareF(_L("MODP_1536"))==0) + aConf->iGroupDesc_II = IKE_PARSER_MODP_1536; + else if (token.CompareF(_L("MODP_2048"))==0) + aConf->iGroupDesc_II = IKE_PARSER_MODP_2048; + else + { + err = KSecParserErrGroupDesc_II; + } + } + else if (token.CompareF(_L("USE_COMMIT:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iCommit = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iCommit = EFalse; + else + err = KSecParserErrCommit; + } + else if (token.CompareF(_L("IPSEC_EXPIRE:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iIpsecExpires = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iIpsecExpires = EFalse; + else + err = KSecParserErrIpsecExpire; + } + else if (token.CompareF(_L("SEND_CERT:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iAlwaysSendCert = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iAlwaysSendCert = EFalse; + else + err = KSecParserErrSendCert; + } + else if (token.CompareF(_L("INITIAL_CONTACT:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iInitialContact = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iInitialContact = EFalse; + else + err = KSecParserErrInitialContact; + } + else if (token.CompareF(_L("RESPONDER_LIFETIME:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iResponderLifetime = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iResponderLifetime = EFalse; + else + err = KSecParserErrResponderLifetime; + } + else if (token.CompareF(_L("REPLAY_STATUS:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iReplayStatus = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iReplayStatus = EFalse; + else + err = KSecParserErrReplayStatus; + } + else if (token.CompareF(_L("CRACK_LAM_TYPE:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + + //There is no difference between SECUREID nowadays. So both values are + //mapped to IKE_PARSER_CRACK_PASSWORD + if (token.CompareF(_L("PASSWORD"))==0 || token.CompareF(_L("SECURID"))==0) + aConf->iCRACKLAMType = IKE_PARSER_CRACK_PASSWORD; + else + { + err = KSecParserErrCRACKLAMType; + } + } + else if (token.CompareF(_L("CRACK_LAM_USERNAME:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iCRACKLAMUserName = TStringData::NewL(token); + } + else if (token.CompareF(_L("CRACK_LAM_PASSWORD:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iCRACKLAMPassword = TStringData::NewL(token); + } + else if (token.CompareF(_L("OWN_CERT_TYPE:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iClientCertType = TStringData::NewL(token); + } + else if (token.CompareF(_L("USE_INTERNAL_ADDR:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iUseInternalAddr = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iUseInternalAddr = EFalse; + else + err = KSecParserErrUseIntAddr; + } + else if (token.CompareF(_L("USE_NAT_PROBE:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iUseNatProbing = ETrue; + else if (token.CompareF(_L("False"))==0) + aConf->iUseNatProbing = EFalse; + else + err = KSecParserErrUseNATProbe; + } + else if (token.CompareF(_L("ESP_UDP_PORT:"))==0) //CompareF ignores case + { + // Specifies port value for IPSEC ESP encapsulation + sub_num = NextToken(); + if ( sub_num.Val(aConf->iEspUdpPort) != KErrNone ) + aConf->iEspUdpPort = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("NAT_KEEPALIVE:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if ( sub_num.Val(aConf->iNatKeepAlive) != KErrNone ) + aConf->iNatKeepAlive = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("DSCP_VALUE:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if ( sub_num.Val(aConf->iDscp, EDecimal) != KErrNone ) + aConf->iDscp = 0; // In error situation, set id value to reserved (= Not defined) + aConf->iDscp <<= 2; + } + else if (token.CompareF(_L("DPD_HEARTBEAT:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if ( sub_num.Val(aConf->iDPDHeartBeat) != KErrNone ) + aConf->iDPDHeartBeat = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("REKEYING_THRESHOLD:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if ( sub_num.Val(aConf->iRekeyingThreshold) != KErrNone ) + aConf->iRekeyingThreshold = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("USE_XAUTH:"))==0) //CompareF ignores case + { + aConf->iUseXauth = EFalse; + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iUseXauth = ETrue; + } + else if (token.CompareF(_L("USE_MODE_CFG:"))==0) //CompareF ignores case + { + aConf->iUseCfgMode = EFalse; + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iUseCfgMode = ETrue; + } + else if (token.CompareF(_L("USE_MOBIKE:"))==0) //CompareF ignores case + { + aConf->iUseMobIke = EFalse; + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iUseMobIke = ETrue; + } + else if (token.CompareF(_L("EAP_PROTOCOL:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if ( sub_num.Val(aConf->iEAPProtocol, EDecimal)!= KErrNone ) + aConf->iEAPProtocol = 0; // In error situation, set id value to reserved (= Not defined) + } + else if (token.CompareF(_L("EAP_REALM_PREFIX:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iEAPRealmPrefix = TStringData::NewL(token); + } + else if (token.CompareF(_L("EAP_MANUAL_REALM:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iEAPManualRealm = TStringData::NewL(token); + } + else if (token.CompareF(_L("EAP_MANUAL_USERNAME:"))==0) //CompareF ignores case + { + token.Set(GetRestOfLine()); + aConf->iEAPManualUserName = TStringData::NewL(token); + } + else if (token.CompareF(_L("EAP_HIDE_IDENTITY:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("True"))==0) + aConf->iEAPHideIdentity = ETrue; + else aConf->iEAPHideIdentity = EFalse; + } + + else if (token.CompareF(_L("PROPOSALS:"))==0) //CompareF ignores case + err = ParseProposals(aConf); + //Preshared Keys List + else if (token.CompareF(_L("PRESHARED_KEYS:"))==0) //CompareF ignores case + err = ParsePresharedKeys(aConf); + //CAs Data + else if (token.CompareF(_L("CAs:"))==0) //CompareF ignores case + { + err = ParseCAs(aConf); + if (!err) + aConf->iCAFound=ETrue; + } //Own Certs List + else if (token.CompareF(_L("OWN_CERTS:"))==0) //CompareF ignores case + err = ParseOwnCerts(aConf); + //PeerCerts List + else if (token.CompareF(_L("PEER_CERTS:"))==0) //CompareF ignores case + err = ParsePeerCerts(aConf); + } + if ( err == KErrNone ) + errCA=CheckPolicy(aConf); + if (errCA) + err=errCA; + User::LeaveIfError(err); +} + +TInt TIkeParser::CheckPolicy(CIkeData* aConf) +{ + TInt errno=KErrNone; + if (aConf->iCARequired && !aConf->iCAFound) + errno=KSecParserErrCA; + return errno; +} + +EXPORT_C TInt TIkeParser::BufferAppend(HBufC8*& aPolBfr, const TDesC8& aText) +{ + TInt err = KErrNone; + // Make sure that we have enough space for the new text + + TInt spaceLeft = aPolBfr->Des().MaxLength() - aPolBfr->Des().Length(); + if (aText.Length() > spaceLeft) + { + // Allocate enough space for the new text + some additional + // free space so that allocations are not too frequent + + TInt newMaxLength = aPolBfr->Des().MaxLength() + + aText.Length() + KIkePolicyBufferSizeIncrement; + HBufC8* tempBfr = aPolBfr->ReAlloc(newMaxLength); + if (tempBfr) + { + aPolBfr = tempBfr; + } + else + { + return KErrNoMemory; + } + } + aPolBfr->Des().Append(aText); + return err; +} + + +//Writes one Host Info. +EXPORT_C TInt TIkeParser::MainWrite(CIkeData *aConf, HBufC8*& aPolBfr) +{ + + TBuf8 buf; + buf.Copy(IKE_HOST_SEPARATOR); + TInt err = BufferAppend(aPolBfr, buf); + + if (err != KErrNone) + return err; + err = BufferAppend(aPolBfr, (_L8("\n"))); + if (err != KErrNone) + return err; + return Write(aConf, aPolBfr); +} + +//Writes some IKE General Data. ("Old Version" no trace file size) +EXPORT_C TInt TIkeParser::GeneralInfoWrite(TUint32 aMaxLifetimeSec, + TUint32 aMaxLifetimeKB, TInt aMaxRetrans, HBufC8*& aPolBfr) +{ + return GeneralInfoWrite(aMaxLifetimeSec, aMaxLifetimeKB, + aMaxRetrans, 0, aPolBfr); +} + +//Writes some IKE General Data. ("New Version") +EXPORT_C TInt TIkeParser::GeneralInfoWrite(TUint32 aMaxLifetimeSec, + TUint32 aMaxLifetimeKB, TInt aMaxRetrans, + TInt aMaxTraceFileSize, HBufC8*& aPolBfr) +{ + TBuf8<40> line; + + TBuf8 buf; + buf.Copy(IKE_GENERAL_SEPARATOR); + TInt err = BufferAppend(aPolBfr, buf); + + if (err != KErrNone) + return err; + err = BufferAppend(aPolBfr, (_L8("\n"))); + if (err != KErrNone) + return err; + + line.Format(_L8("ISAKMP_SA_MAX_LIFETIME_SEC: %u\n"),aMaxLifetimeSec); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Format(_L8("ISAKMP_SA_MAX_LIFETIME_KB: %u\n"),aMaxLifetimeKB); + err = BufferAppend(aPolBfr, line); + + line.Format(_L8("ISAKMP_MAX_RETRANS: %u\n"),aMaxRetrans); + err = BufferAppend(aPolBfr, line); + + line.Format(_L8("TRACE_FILE_SIZE: %u\n"), aMaxTraceFileSize); + err = BufferAppend(aPolBfr, line); + + return err; + +} + + +EXPORT_C TInt TIkeParser::Write(CIkeData* aConf, HBufC8*& aPolBfr) +{ + ASSERT(aConf); + + TBuf8<1024> line; + TInt err = KErrNone; + TBuf<39> addr_buf; + TBuf<39> mask_buf; + + TBuf8<39> addr8; + TBuf8<39> mask8; + + line.Append(_L8("ADDR: ")); + if (!aConf->iAddr.IsUnspecified()) + aConf->iAddr.OutputWithScope(addr_buf); + else + addr_buf.Copy(_L("0.0.0.0")); + if (!aConf->iMask.IsUnspecified()) + aConf->iMask.OutputWithScope(mask_buf); + else //only happens with version 1 (no mask) + mask_buf.Copy(_L("255.255.255.255")); + + addr8.Copy(addr_buf); + line.Append(addr8); + line.Append(_L(" ")); + mask8.Copy(mask_buf); + line.Append(mask8); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + + + if (!aConf->iDnsServer.IsUnspecified()) + { + aConf->iDnsServer.OutputWithScope(addr_buf); + line = _L8("DNS_SERVER: "); + addr8.Copy(addr_buf); + line.Append(addr8); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + + } + + + + + if ( (aConf->iMode == IKE_PARSER_MAIN) || (aConf->iMode == IKE_PARSER_AGGRESSIVE) ) + { + line.Copy(_L8("MODE: ")); + line.Append(TextMode(aConf->iMode)); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + if ( aConf->iIkeVersion != 0 ) + { + line.Format(_L8("IKE_VERSION: %d\n"), aConf->iIkeVersion); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + line.Copy(_L8("SEND_NOTIFICATION: ")); + if (aConf->iNotify) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + if (aConf->iFQDN.Length() > 0) + { + line.Copy(_L8("FQDN: ")); + line.Append(aConf->iFQDN); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if (aConf->iIdType != 0) + { + line.Format(_L8("ID_TYPE: %d\n"), aConf->iIdType); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + if ( aConf->iRemoteIdentity ) + { + line.Copy(_L8("REMOTE_IDENTITY: ")); + line.Append(aConf->iRemoteIdentity->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if (aConf->iRemoteIdType != 0) + { + line.Format(_L8("REMOTE_ID_TYPE: %d\n"), aConf->iRemoteIdType); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + line.Copy(_L8("ACCEPT_PARTIAL_REMOTE_ID: ")); + if (aConf->iAcceptPartialRemoteId) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("SKIP_REMOTE_ID_CHECK: ")); + if (aConf->iSkipRemoteIdCheck) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + if (aConf->iGroupDesc_II != 0) + { + line.Copy(_L8("GROUP_DESCRIPTION_II: ")); + line.Append(TextGroupDesc(aConf->iGroupDesc_II)); + line.Append(_L("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + line.Copy(_L8("USE_COMMIT: ")); + if (aConf->iCommit) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("IPSEC_EXPIRE: ")); + if (aConf->iIpsecExpires) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("SEND_CERT: ")); + if (aConf->iAlwaysSendCert) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("INITIAL_CONTACT: ")); + if (aConf->iInitialContact) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("RESPONDER_LIFETIME: ")); + if (aConf->iResponderLifetime) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("REPLAY_STATUS: ")); + if (aConf->iReplayStatus) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + if ( aConf->iCRACKLAMType == IKE_PARSER_CRACK_PASSWORD ) + { + line.Copy(_L8("CRACK_LAM_TYPE: ")); + line.Append(TextLAMType(aConf->iCRACKLAMType)); + line.Append(_L("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + //IKE Private (Nokia VPN specific) extensions + line.Copy(_L8("USE_INTERNAL_ADDR: ")); + if (aConf->iUseInternalAddr) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("USE_NAT_PROBE: ")); + if (aConf->iUseNatProbing) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + if (aConf->iEspUdpPort != 0) + { + line.Format(_L8("ESP_UDP_PORT: %d\n"), aConf->iEspUdpPort); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + line.Format(_L8("NAT_KEEPALIVE: %d\n"), aConf->iNatKeepAlive); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Format(_L8("DSCP_VALUE: %d\n"), aConf->iDscp >> 2); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Format(_L8("DPD_HEARTBEAT: %d\n"), aConf->iDPDHeartBeat); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Format(_L8("REKEYING_THRESHOLD: %d\n"), aConf->iRekeyingThreshold); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("USE_XAUTH: ")); + if (aConf->iUseXauth) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("USE_MODE_CFG: ")); + if (aConf->iUseCfgMode) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + line.Copy(_L8("USE_MOBIKE: ")); + if (aConf->iUseMobIke) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + if ( aConf->iCRACKLAMUserName ) + { + line.Copy(_L8("CRACK_LAM_USERNAME: ")); + line.Append(aConf->iCRACKLAMUserName->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if ( aConf->iCRACKLAMPassword ) + { + line.Copy(_L8("CRACK_LAM_PASSWORD: ")); + line.Append(aConf->iCRACKLAMPassword->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if ( aConf->iClientCertType ) + { + line.Copy(_L8("OWN_CERT_TYPE: ")); + line.Append(aConf->iClientCertType->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + if ( aConf->iEAPProtocol != 0 ) + { + line.Format(_L8("EAP_PROTOCOL: %d\n"), aConf->iEAPProtocol); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + line.Copy(_L8("EAP_HIDE_IDENTITY: ")); + if (aConf->iEAPHideIdentity) + line.Append(_L("TRUE\n")); + else + line.Append(_L("FALSE\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if ( aConf->iEAPRealmPrefix ) + { + line.Copy(_L8("EAP_REALM_PREFIX: ")); + line.Append(aConf->iEAPRealmPrefix->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if ( aConf->iEAPManualRealm ) + { + line.Copy(_L8("EAP_MANUAL_REALM: ")); + line.Append(aConf->iEAPManualRealm->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + if ( aConf->iEAPManualUserName ) + { + line.Copy(_L8("EAP_MANUAL_USERNAME: ")); + line.Append(aConf->iEAPManualUserName->GetData()); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + //Proposals + line.Format(_L8("PROPOSALS: %d\n"), aConf->iNumProp); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + TProposalData* prop = aConf->iPropList; + for (TInt i=0; iiNumProp; i++) + { + line.Copy(_L8("ENC_ALG: ")); + line.Append(TextEncrAlg(prop->iEncrAlg, prop->iEncrKeyLth)); + line.Append(_L8("\nAUTH_METHOD: ")); + line.Append(TextAuthMethod(prop->iAuthMeth)); + line.Append(_L8("\nHASH_ALG: ")); + line.Append(TextHashAlg(prop->iHashAlg)); + line.Append(_L8("\nGROUP_DESCRIPTION: ")); + line.Append(TextGroupDesc(prop->iGroupDesc)); + line.Append(_L8("\nGROUP_TYPE: ")); + line.Append(TextGroupType(prop->iGroupType)); + line.AppendFormat(_L8("\nLIFETIME_KBYTES: %d"),prop->iLifetimeKb); + line.AppendFormat(_L8("\nLIFETIME_SECONDS: %d"),prop->iLifetimeSec); + line.Append(_L8("\nPRF: ")); + line.Append(TextPRF(prop->iPRF)); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + prop = prop->iNext; + } + + if (aConf->iPresharedKey.iKey.Length() > 0) + { + line.Copy(_L8("PRESHARED_KEYS:\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + line.Copy(_L("FORMAT: ")); + line.Append(TextFormat(aConf->iPresharedKey.iFormat)); + line.AppendFormat(_L8("\nKEY: %d "),aConf->iPresharedKey.iKey.Length()); + line.Append(aConf->iPresharedKey.iKey); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + // + //CAS + //Support for multiple CAs + // + if ( aConf->iCAList ) + { + TInt ca_count = aConf->iCAList->Count(); + line.Copy(_L("CAs: ")); + line.AppendNum(ca_count); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + + for (TInt i=0; i < ca_count; i++) + { + line.Copy(_L(" FORMAT: ")); + line.Append(CertFormat(aConf->iCAList->At(i)->iFormat)); + line.Append(_L("\n DATA: ")); + line.Append(aConf->iCAList->At(i)->iData); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + } + + //Own Certs + if (aConf->iOwnCert.iOwnCertExists) + { + line.Copy(_L8("OWN_CERTS:\n")); + if (aConf->iOwnCert.iData.Length() > 0) + { + line.Append(_L8(" FORMAT: ")); + line.Append(CertFormat(aConf->iOwnCert.iFormat)); + line.Append(_L8("\n DATA: ")); + line.Append(aConf->iOwnCert.iData); + line.Append(_L8("\n PRIVATE_KEY_FORMAT: ")); + line.Append(CertFormat(aConf->iPrivKey.iFormat)); + line.Append(_L8("\n PRIVATE_KEY_DATA: ")); + line.Append(aConf->iPrivKey.iData); + line.Append(_L8("\n")); + line.AppendFormat(_L8("\n PRIVATE_KEY_LENGTH: %d"), aConf->iOwnCert.iPrivateKeyLength); + } + + // Always included + line.Append(_L8("\n SUBJECT_DN_SUFFIX: ")); + line.Append(aConf->iOwnCert.iSubjectDnSuffix); + TInt identityType; + if (aConf->iOwnCert.iIdentityAsRfc822Name == EIdentityAsRfc822NameUndefined) + { + identityType = 2; + } + else if (aConf->iOwnCert.iIdentityAsRfc822Name == EIdentityAsRfc822NameNo) + { + identityType = 0; + } + else + { + identityType = 1; + } + line.AppendFormat(_L8("\n IDENTITY_AS_RFC822NAME: %d"), identityType); + + line.Append(_L8("\n RFC822NAME_FQDN: ")); + line.Append(aConf->iOwnCert.iRfc822NameFqdn); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + //Peer Certs + if (aConf->iPeerCert.iData.Length() > 0) + { + line.Format(_L8("PEER_CERTS:")); + line.Append(_L8(" FORMAT: ")); + line.Append(CertFormat(aConf->iPeerCert.iFormat)); + line.Append(_L8("\n DATA: ")); + line.Append(aConf->iPeerCert.iData); + line.Append(_L8("\n")); + err = BufferAppend(aPolBfr, line); + if (err != KErrNone) + return err; + } + + return KErrNone; +} + +TInt TIkeParser::ParseProposals(CIkeData* aConf) +{ + ASSERT(aConf); + + TLex sub_num = NextToken(); //Used for number conversion + if (sub_num.Val(aConf->iNumProp) != KErrNone) + return KSecParserErrProposal; + + if (aConf->iNumProp == 0) + { + aConf->iPropList = NULL; + return KErrNone; + } + + TPtrC token(NULL,0); + TProposalData* prev_prop = NULL; + TInt err = KErrNone; + TInt authMethodFound=0; + //At least one proposal! + for (TInt i=0; iiNumProp; i++) //All the proposals + { + TProposalData* prop = NULL; + prop = new TProposalData; + if (!prop) + return KErrNoMemory; + + prop->iNext = NULL; + if (i==0) //First proposal + aConf->iPropList = prop; + else + prev_prop->iNext = prop; + + prop->iPrev = prev_prop; + authMethodFound=0; + token.Set(NextToken()); + + if (token.CompareF(_L("ENC_ALG:"))==0) //CompareF ignores case + { + prop->iEncrKeyLth = 0; // = Use Default key length + token.Set(NextToken()); + if (token.CompareF(_L("DES-CBC"))==0) + prop->iEncrAlg = IKE_PARSER_DES_CBC; + else if (token.CompareF(_L("3DES-CBC"))==0) + prop->iEncrAlg = IKE_PARSER_DES3_CBC; + else if (token.CompareF(_L("AES128-CBC"))==0) + { + prop->iEncrKeyLth = 128; + prop->iEncrAlg = IKE_PARSER_AES_CBC; + } + else if (token.CompareF(_L("AES192-CBC"))==0) + { + prop->iEncrKeyLth = 192; + prop->iEncrAlg = IKE_PARSER_AES_CBC; + } + else if (token.CompareF(_L("AES256-CBC"))==0) + { + prop->iEncrKeyLth = 256; + prop->iEncrAlg = IKE_PARSER_AES_CBC; + } + else + { + err = KSecParserErrEncrAlg; + break; + } + } + else + { + err = KSecParserErrEncrAlg; + break; + } + + token.Set(NextToken()); + if (token.CompareF(_L("AUTH_METHOD:"))==0) //CompareF ignores case + { + authMethodFound=1; + token.Set(NextToken()); + if (token.CompareF(_L("RSA_SIGNATURES"))==0) + { + prop->iAuthMeth = IKE_PARSER_RSA_SIG; + aConf->iCARequired=ETrue; + } + else if (token.CompareF(_L("DSS_SIGNATURES"))==0) + { + prop->iAuthMeth = IKE_PARSER_DSS_SIG; + aConf->iCARequired=ETrue; + } + else if (token.CompareF(_L("RSA_ENCRYPT"))==0) + { + prop->iAuthMeth = IKE_PARSER_RSA_ENCR; + aConf->iCARequired=ETrue; + } + else if (token.CompareF(_L("RSA_REV_ENCRYPT"))==0) + { + prop->iAuthMeth = IKE_PARSER_RSA_REV_ENCR; + aConf->iCARequired=ETrue; + } + else if (token.CompareF(_L("PRE-SHARED"))==0) + prop->iAuthMeth = IKE_PARSER_PRE_SHARED; + else if (token.CompareF(_L("IKE-CRACK"))==0) + { + prop->iAuthMeth = IKE_PARSER_CRACK; + aConf->iCARequired=ETrue; + } + else + { + err = KSecParserErrAuthMethod; + break; + //ErrorL(R_PARSE_ERROR_AUTH_METHOD); + } + } + else + { + if (aConf->iEAPProtocol<1) + { + err = KSecParserErrAuthMethod; + break; + } + } + if (aConf->iEAPProtocol>0) + prop->iAuthMeth=IKE_PARSER_PRE_SHARED; + if (authMethodFound==1) + token.Set(NextToken()); + if (token.CompareF(_L("HASH_ALG:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("MD5"))==0) + prop->iHashAlg = IKE_PARSER_MD5; + else if (token.CompareF(_L("SHA1"))==0) + prop->iHashAlg = IKE_PARSER_SHA1; + else + { + err = KSecParserErrHashAlg; + break; + } + } + else + { + err = KSecParserErrHashAlg; + break; + } + token.Set(NextToken()); + if (token.CompareF(_L("GROUP_DESCRIPTION:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("MODP_768"))==0) + prop->iGroupDesc = IKE_PARSER_MODP_768; + else if (token.CompareF(_L("MODP_1024"))==0) + prop->iGroupDesc = IKE_PARSER_MODP_1024; + else if (token.CompareF(_L("MODP_1536"))==0) + prop->iGroupDesc = IKE_PARSER_MODP_1536; + else if (token.CompareF(_L("MODP_2048"))==0) + prop->iGroupDesc = IKE_PARSER_MODP_2048; + else + { + err = KSecParserErrGroupDesc; + break; + } + } + else + { + err = KSecParserErrGroupDesc; + break; + } + + token.Set(NextToken()); + if (token.CompareF(_L("GROUP_TYPE:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("MODP"))==0) + prop->iGroupType = IKE_PARSER_MODP; + else if(token.CompareF(_L("DEFAULT"))==0) + prop->iGroupType = IKE_PARSER_DEFAULT; + else + { + err = KSecParserErrGroupType; + break; + } + } + else + { + err = KSecParserErrGroupType; + break; + } + + token.Set(NextToken()); + if (token.CompareF(_L("LIFETIME_KBYTES:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(prop->iLifetimeKb,EDecimal)!=KErrNone) + { + err = KSecParserErrLifeBytes; + break; + } + token.Set(NextToken()); + } + else + { + prop->iLifetimeKb=0; + } + if (token.CompareF(_L("LIFETIME_SECONDS:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(prop->iLifetimeSec,EDecimal)!=KErrNone) + { + err = KSecParserErrLifeSecs; + break; + } + } + else + { + err = KSecParserErrLifeSecs; + break; + } + + Mark(); + + token.Set(NextToken()); + + // PRF is an optional parameter, so if it doesn't exist, just use + // the default value and unget to mark (so that the rest of the parsing + // won't fail). + if (token.CompareF(_L("PRF:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("3DES-CBC-MAC"))==0) + prop->iPRF = IKE_PARSER_DES3_CBC_MAC; + else if (token.CompareF(_L("NONE"))==0) + prop->iPRF = IKE_PARSER_NONE; + else + { + err = KSecParserErrPRF; + break; + } + } + else + { + prop->iPRF = IKE_PARSER_NONE; + UnGetToMark(); + } + + prev_prop = prop; //Save as previous proposal + } //Proposals loop + + return err; +} + + +TInt TIkeParser::ParsePresharedKeys(CIkeData* aConf) +{ + ASSERT(aConf); + + TPtrC token(NULL, 0); + TLex sub_num; //Used for number conversion + TInt j = 0; + TInt num=0; + + TPresharedKeyData *key = &aConf->iPresharedKey; + token.Set(NextToken()); + + if (token.CompareF(_L("FORMAT:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("HEX_FORMAT"))==0) + key->iFormat = HEX_KEY; + else if (token.CompareF(_L("STRING_FORMAT"))==0) + key->iFormat = STRING_KEY; + else + return KSecParserErrPreFormat; + } + else + return KSecParserErrPreKey; + + token.Set(NextToken()); + if (token.CompareF(_L("KEY:"))==0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(num)!=KErrNone) + return KSecParserErrPreKey; + + if (num > KMaxPresharedKeyLength) + { + //Key is too long for our buffer. + return KSecParserErrPreKey; + } + + if (key->iFormat == HEX_KEY && (num % 2) != 0) + { + //HEX encoded keys must contains even number of characters. + //(Because each byte is expressed by two characters.) + return KSecParserErrPreKey; + } + } + else + return KSecParserErrPreKey; + + SkipSpaceAndMark(); + + if (key->iFormat == STRING_KEY) + { + for (j = 0; j < num && (!Eos()) ; j++) //Parse the key char to char because it contains blanks + key->iKey.Append(Get()); + } + else if (key->iFormat == HEX_KEY) + { + //Make sure that key contains a valid hex decim number. + for (j = 0; j < num && (!Eos()) ; j++) + { + TChar c = Get(); + if (c >= TChar('0') && c <= TChar('9') || + c >= TChar('a') && c <= TChar('f') || + c >= TChar('A') && c <= TChar('F')) + { + key->iKey.Append(c); + } + else + { + return KSecParserErrPreKey; + } + + } + } + + if (jiFormat = PEM_CERT; + else if (aToken.CompareF(_L("BIN"))==0) + aCA->iFormat = BIN_CERT; + else if (aToken.CompareF(_L("NAME"))==0) + aCA->iFormat = CA_NAME; + else if (aToken.CompareF(_L("KEYID"))==0) + aCA->iFormat = KEY_ID; + else if (aToken.CompareF(_L("APPLUID"))==0) + aCA->iFormat = APPL_UID; + else + return KSecParserErrCA; + } + else + { + return KSecParserErrCA; + } + + aToken.Set(NextToken()); + if ( aToken.CompareF(_L("DATA:")) == 0) //CompareF ignores case + { + switch(aCA->iFormat) + { + case CA_NAME: //falls through + case APPL_UID: + { + aCA->iData = GetRestOfLine(); //ASCII format CA name or Appl uid list + // Check if data contains empty attributes + if( KErrNotFound != aCA->iData.FindF(_L("=,")) || KErrNotFound != aCA->iData.FindF(_L("=\"\""))) + { + return KSecParserErrCA; + } + } + break; + case BIN_CERT: + return ParseFileName(aCA->iData); + //No break needed + default: + aCA->iData = NextToken(); //PEM cert or Key identifier + break; + } + + return KErrNone; + } + else + { + return KSecParserErrCA; + } +} + +void TIkeParser::ParseCAListL(CIkeData* aConf, TInt aCACount, TPtrC& aToken) +{ + ASSERT(aConf); + + aConf->iCAList = new (ELeave) CArrayFixFlat(aCACount); + + while ( aCACount ) + { + TCertInfo* ca_name = new (ELeave) TCertInfo; + CleanupStack::PushL(ca_name); + User::LeaveIfError(ParseCAItem(aConf, ca_name, aToken)); + aConf->iCAList->AppendL(ca_name); + CleanupStack::Pop(ca_name); + + aCACount--; + if ( aCACount ) + aToken.Set(NextToken()); // Enter to next "FORMAT" tag + } +} + +/**--------------------------------------------------------------- + * + * Parse CAs section in host (=IKE) configuration. + * There is two possibilities: + * CAs: + * FORMAT: BIN + * DATA: jps-SecurID-1_0-ca.cer + * This supports only one CA (This format may be removed later) + * CAs: 2 + * FORMAT: BIN + * DATA: jps-SecurID-1_0-ca.cer + * FORMAT: BIN + * DATA: jps-SecurID-1_1-ca.cer + * This supports several CA:s. Exact CA count is in line CAs: x + * + *----------------------------------------------------------------*/ +TInt TIkeParser::ParseCAs(CIkeData* aConf) +{ + TInt ca_count = 0; + TPtrC token(NULL, 0); + token.Set(NextToken()); + + if ( token.CompareF(_L("FORMAT:")) == 0 ) //CompareF ignores case + { + ca_count = 1; + } + else + { + TLex sub_num = token; + if ( (sub_num.Val(ca_count) != KErrNone) || (ca_count == 0) ) + { + return KSecParserErrCA; + } + token.Set(NextToken()); // Enter to the first "FORMAT" tag + } + + TInt err = KErrNone; + TRAP(err, ParseCAListL(aConf, ca_count, token);) + return err; +} + +TInt TIkeParser::ParseOwnCerts(CIkeData* aConf) +{ + ASSERT(aConf); + + TPtrC token(NULL,0); + + TInt nMandatoryFields=0; + TInt err=KErrNone; + TBool endOfSection=EFalse; + TOwnCertInfo *own_cert = &aConf->iOwnCert; + own_cert->iOwnCertExists = 0; + TCertInfo *priv_key = &aConf->iPrivKey; + + while (!endOfSection && err==KErrNone) + { + Mark(); + token.Set(NextToken()); + + if (token.CompareF(_L("FORMAT:"))==0) //CompareF ignores case + { + nMandatoryFields++; + token.Set(NextToken()); + if (token.CompareF(_L("BIN"))==0) + own_cert->iFormat = BIN_CERT; + else if (token.CompareF(_L("NAME"))==0) + own_cert->iFormat = CA_NAME; + else + err=KSecParserErrOwnCerts; + } + + else if (token.CompareF(_L("DATA:"))==0) //CompareF ignores case + { + nMandatoryFields++; + err = ParseFileName(own_cert->iData); + } + + //Private key part + else if (token.CompareF(_L("PRIVATE_KEY_FORMAT:"))==0) //CompareF ignores case + { + nMandatoryFields++; + token.Set(NextToken()); + if (token.CompareF(_L("PEM"))==0) + priv_key->iFormat = PEM_CERT; + else if (token.CompareF(_L("BIN"))==0) + priv_key->iFormat = BIN_CERT; + else + err=KSecParserErrOwnCerts; + } + + else if (token.CompareF(_L("PRIVATE_KEY_DATA:"))==0) //CompareF ignores case + { + nMandatoryFields++; + err = ParseFileName(priv_key->iData); + } + // new stuff // error codes? + else if (token.CompareF(_L("SUBJECT_DN_SUFFIX:"))==0) //CompareF ignores case + { + nMandatoryFields++; + own_cert->iSubjectDnSuffix = GetRestOfLine(); + // Check if data contains empty attributes + if( KErrNotFound != own_cert->iSubjectDnSuffix.FindF(_L("=,")) || + KErrNotFound != own_cert->iSubjectDnSuffix.FindF(_L("=\"\""))) + { + return KSecParserErrOwnCerts; + } + } + + else if (token.CompareF(_L("IDENTITY_AS_RFC822NAME:"))==0) //CompareF ignores case + { + nMandatoryFields++; + token.Set(NextToken()); + if (token.CompareF(_L("1"))==0) + own_cert->iIdentityAsRfc822Name=EIdentityAsRfc822NameYes; + else if (token.CompareF(_L("0"))==0) + own_cert->iIdentityAsRfc822Name=EIdentityAsRfc822NameNo; + else + own_cert->iIdentityAsRfc822Name=EIdentityAsRfc822NameUndefined; + } + else if (token.CompareF(_L("RFC822NAME_FQDN:"))==0) //CompareF ignores case + { + nMandatoryFields++; + own_cert->iRfc822NameFqdn = NextToken(); + } + + else if (token.CompareF(_L("PRIVATE_KEY_LENGTH:"))==0) //CompareF ignores case + { + nMandatoryFields++; + TLex sub_num = NextToken(); + if (sub_num.Val(own_cert->iPrivateKeyLength)!=KErrNone) + err= KSecParserErrOwnCerts; + } + else + { + UnGetToMark(); // current token didn't belong to this section + endOfSection=ETrue; + } + } + if (nMandatoryFields<1) // Some mandatory fields are missing + { + err= KSecParserErrOwnCerts; + } + else + { + own_cert->iOwnCertExists = 1; // Write Own Certs + } + return err; +} + + +TInt TIkeParser::ParsePeerCerts(CIkeData* aConf) +{ + ASSERT(aConf); + + TPtrC token(NULL, 0); + + TCertInfo *peer_cert = &aConf->iPeerCert; + token.Set(NextToken()); + if (token.CompareF(_L("FORMAT:"))==0) //CompareF ignores case + { + token.Set(NextToken()); + if (token.CompareF(_L("PEM"))==0) + peer_cert->iFormat = PEM_CERT; + else if (token.CompareF(_L("BIN"))==0) + peer_cert->iFormat = BIN_CERT; + else + return KSecParserErrPreFormat; + } + else + return KSecParserErrPreKey; + + token.Set(NextToken()); + if (token.CompareF(_L("DATA:"))==0) //CompareF ignores case + peer_cert->iData = NextToken(); //Filename or PEM cert + else + return KSecParserErrPreKey; + + return KErrNone; +} + +TBufC<16> TIkeParser::TextMode(const TInt aMode) +{ + TBufC<16> ret; + + switch (aMode) + { + case IKE_PARSER_MAIN: + ret=_L("Main"); + break; + case IKE_PARSER_AGGRESSIVE: + ret=_L("Aggressive"); + break; + default: + break; + } + + return ret; +} + +TBufC<16> TIkeParser::TextEncrAlg(const TInt aAlg, const TInt aKeyLth) +{ + TBufC<16> ret; + + switch (aAlg) + { + case IKE_PARSER_DES_CBC: + ret=_L("DES-CBC"); + break; + case IKE_PARSER_DES3_CBC: + ret=_L("3DES-CBC"); + break; + case IKE_PARSER_AES_CBC: + if ( aKeyLth == 256 ) + ret=_L("AES256-CBC"); + else if ( aKeyLth == 192 ) + ret=_L("AES192-CBC"); + else ret=_L("AES128-CBC"); + break; + default: + break; + } + + return ret; +} + +TBufC<16> TIkeParser::TextAuthMethod(const TInt aMethod) +{ + TBufC<16> ret; + + switch (aMethod) + { + case IKE_PARSER_RSA_SIG: + ret=_L("RSA_SIGNATURES"); + break; + case IKE_PARSER_DSS_SIG: + ret=_L("DSS_SIGNATURES"); + break; + case IKE_PARSER_RSA_ENCR: + ret=_L("RSA_ENCRYPT"); + break; + case IKE_PARSER_RSA_REV_ENCR: + ret=_L("RSA_REV_ENCRYPT"); + break; + case IKE_PARSER_PRE_SHARED: + ret=_L("PRE-SHARED"); + break; + case IKE_PARSER_CRACK: + ret=_L("IKE-CRACK"); + break; + default: + break; + } + + return ret; +} + +TBufC<16> TIkeParser::TextHashAlg(const TInt aAlg) +{ + TBufC<16> ret; + + switch (aAlg) + { + case IKE_PARSER_MD5: + ret=_L("MD5"); + break; + case IKE_PARSER_SHA1: + ret=_L("SHA1"); + break; + default: + break; + } + + return ret; +} + +TBufC<16> TIkeParser::TextGroupDesc(const TInt aDesc) +{ + TBufC<16> ret; + + switch (aDesc) + { + case IKE_PARSER_MODP_768: + ret=_L("MODP_768"); + break; + case IKE_PARSER_MODP_1024: + ret=_L("MODP_1024"); + break; + case IKE_PARSER_MODP_1536: + ret=_L("MODP_1536"); + break; + case IKE_PARSER_MODP_2048: + ret=_L("MODP_2048"); + break; + default: + break; + } + return ret; +} + +TBufC<16> TIkeParser::TextGroupType(const TInt aType) +{ + TBufC<16> ret; + + switch (aType) + { + case IKE_PARSER_DEFAULT: + ret=_L("DEFAULT"); + break; + case IKE_PARSER_MODP: + ret=_L("MODP"); + break; + default: + break; + } + return ret; +} + +TBufC<16> TIkeParser::TextPRF(const TInt aPRF) +{ + TBufC<16> ret; + + switch (aPRF) + { + case IKE_PARSER_NONE: + ret=_L("NONE"); + break; + case IKE_PARSER_DES3_CBC_MAC: + ret=_L("3DES-CBC-MAC"); + break; + default: + break; + } + return ret; +} + +TBufC<16> TIkeParser::TextFormat(const TKeyFormat aFormat) +{ + TBufC<16> ret; + + switch (aFormat) + { + case HEX_KEY: + ret=_L("HEX_FORMAT"); + break; + case STRING_KEY: + default: + ret=_L("STRING_FORMAT"); + break; + } + return ret; +} + +TBufC<16> TIkeParser::CertFormat(TCertFormat aFormat) +{ + TBufC<16> ret; + + switch (aFormat) + { + case PEM_CERT: + ret=_L("PEM"); + break; + case BIN_CERT: + ret=_L("BIN"); + break; + case CA_NAME: + ret=_L("NAME"); + break; + case KEY_ID: + ret=_L("KEYID"); + break; + case APPL_UID: + ret=_L("APPLUID"); + break; + default: + break; + } + + return ret; +} + +TBufC<16> TIkeParser::TextLAMType(const TUint8 aLAMType) +{ + TBufC<16> ret; + + switch (aLAMType) + { + case IKE_PARSER_CRACK_PASSWORD: + ret=_L("PASSWORD"); + break; + default: + break; + } + + return ret; +} + + +TPtrC TIkeParser::GetRestOfLine() +{ + TChar chr=Get(); + while(chr.IsSpace() && chr!='\n' && chr!='\r') + chr=Get(); + UnGet(); + Mark(); + chr=Get(); // Fix for empty rest of line + while(!Eos() && chr!='\n' && chr!='\r') + chr=Get(); + if (!Eos()) + UnGet(); + return MarkedToken(); +} + + +TInt TIkeParser::ParseFileName(TDes& aFileName) +{ + //Get the rest of the line + //Trim trailing white spaces from the file name + TPtrC fileName = GetRestOfLine(); + HBufC* fileNameCopy = fileName.Alloc(); + if (fileNameCopy == NULL) + { + return KErrNoMemory; + } + fileNameCopy->Des().TrimRight(); + fileName.Set(fileName.Left(fileNameCopy->Length())); + delete fileNameCopy; + + aFileName = fileName; + + return KErrNone; +} + + +TBool TSecParser::CheckVersion() +{ + TPtrC token(NULL, 0); + TLex version_num; + + token.Set(NextToken()); + if (token.Compare(_L("SECURITY_FILE_VERSION:"))==0) + { + version_num = NextToken(); + if (version_num.Val(iVersion)!=KErrNone) + return EFalse; + if ((iVersion < FIRST_SEC_PARSER_VERSION) || (iVersion > SEC_PARSER_VERSION)) + return EFalse; + } + else + return EFalse; + + return ETrue; +} + +void TSecParser::ParseInfoL(CSecurityPiece* aPiece_data) +{ + ASSERT(aPiece_data); + + HBufC* buf = HBufC::NewLC(MAX_INFO_SIZE); + TPtr ptr = buf->Des(); + TChar ch = Get(); + TInt i=0; + + ch = Get(); + while (((ch==' ') || (ch=='\n')) && (!Eos())) + ch = Get(); + while ((ch!='[') && (!Eos()) && i < MAX_INFO_SIZE) + { + ptr.Append(ch); + i++; + ch = Get(); + } + + if (i == MAX_INFO_SIZE) //The rest is ignored + { + ch = Get(); + while ( (ch != '[') && (!Eos()) ) + ch = Get(); + } + + if (ch =='[') + { + UnGet(); // the '[' + if (ptr.Length() > 0) //If empty no \n + ptr.SetLength(ptr.Length() - 1); //eliminates the \n at the end + } + aPiece_data->SetInfoL(ptr); + CleanupStack::PopAndDestroy(buf); +} + +TInt TSecParser::ParseGeneral(CGeneralData *aGeneralData) +{ + TInt err; + TInt pos = Remainder().Find(_L("[")); //The segment is until the next tag or Eos() + if (pos!=KErrNotFound) + { + + TPtr gen_ptr((TUint16 *)Remainder().Ptr(),pos, pos); //Until the next section + + TGeneralParser parser(gen_ptr); + err = parser.Parse(aGeneralData); + Assign(Remainder().Mid(pos)); //rest of the text to parse + } + else //No more tags + { + TGeneralParser parser(Remainder()); + err = parser.Parse(aGeneralData); + } + + return (err); +} + + +void TSecParser::NextTag() +{ + while (!Eos()) + if (Get() == '[' ) + { + UnGet(); //Next tag found + return; + } + +} + +//Puts the security file data into string format to be saved to disk. +EXPORT_C TInt TSecParser::Write(CSecurityPiece *aPiece_data, HBufC8*& aPolBfr) +{ + TInt err; + + err = WriteVersion(aPolBfr); + if (err != KErrNone) + return err; + + err = WriteInfo(aPiece_data, aPolBfr); + if (err != KErrNone) + return err; + + return err = WriteIke(aPiece_data, aPolBfr); +} + +TInt TSecParser::WriteVersion(HBufC8*& aPolBfr) +{ + TBuf8<32> buf; + buf.Format(_L8("SECURITY_FILE_VERSION: %d\n"), SEC_PARSER_VERSION); + return TIkeParser::BufferAppend(aPolBfr, buf); +} + +TInt TSecParser::WriteInfo(CSecurityPiece* aPiece_data, HBufC8*& aPolBfr) +{ + ASSERT(aPiece_data); + + TInt err; + + TBuf8 buf = _L8("[INFO]\n"); + err = TIkeParser::BufferAppend(aPolBfr, buf); + if (err != KErrNone) + return err; + + buf.Copy(aPiece_data->Info()->Des()); + err = TIkeParser::BufferAppend(aPolBfr, buf); + if (err != KErrNone) + return err; + return TIkeParser::BufferAppend(aPolBfr, (_L8("\n"))); +} + +TInt TSecParser::WriteIke(CSecurityPiece* aPiece_data, HBufC8*& aPolBfr) +{ + ASSERT(aPiece_data); + + TBuf8<6> buf = _L8("[IKE]\n"); + TInt err = TIkeParser::BufferAppend(aPolBfr, buf); + if (err != KErrNone) + return err; + return TIkeParser::Write(aPiece_data->IkeData(), aPolBfr); +} + + +// +//CSecurityPiece +// + +EXPORT_C void CSecurityPiece::ConstructL(TInt aSize) +{ + iInfo = HBufC::NewL(aSize); + iIkeData = CIkeData::NewL(); + iGeneralData = new (ELeave) CGeneralData(); +} + +EXPORT_C void CSecurityPiece::SetInfoL(const TDesC &aDes) +{ + if (aDes.Length() > iInfo->Des().MaxLength()) + iInfo = iInfo->ReAllocL(aDes.Length()); //ReAllocs if needed + + iInfo->Des().Copy(aDes); +} + +EXPORT_C CSecurityPiece::~CSecurityPiece() +{ + delete iInfo; + delete iIkeData; + delete iGeneralData; +} + + + + +EXPORT_C CGeneralData::CGeneralData() +{ +} + +EXPORT_C CGeneralData::CGeneralData(CGeneralData* aData) +{ + ASSERT(aData); + iDeactivationTimeout = aData->iDeactivationTimeout; +} + +EXPORT_C TGeneralParser::TGeneralParser(const TDesC &aStr) : TLex(aStr) + { + } + +EXPORT_C TInt TGeneralParser::Parse(CGeneralData* aData) +{ + ASSERT(aData); + + TLex sub_num; //Used for number conversion + TInt err = KErrNone; + TPtrC token(NULL,0); + while (!Eos() && err==KErrNone) + { + Mark(); + token.Set(NextToken()); + if (token.CompareF(_L("POLICY_AUTO_DEACTIVATION_TIMEOUT:")) == 0) //CompareF ignores case + { + sub_num = NextToken(); + if (sub_num.Val(aData->iDeactivationTimeout)!=KErrNone) + err = KErrGeneral; //change ?? + } + } + return err; +} + + +EXPORT_C TInt TSecParser::ParseGeneralData(CGeneralData* aData) +{ + TPtrC token(NULL, 0); + TInt ret; + + if (!CheckVersion()) + return KErrNotSupported; //Invalid file or version + while (!Eos()) + { + token.Set(NextToken()); + if (token.Compare(_L("[GENERAL]"))==0) + { + ret = ParseGeneral(aData); + if (ret !=KErrNone) + return ret; + } + else //Unknown Tag Ignored + NextTag(); + + } + + return KErrNone; +} + +// +// IkeParser +// +EXPORT_C RArray* IkeParser::GetApplUidListL( + const TDesC16& aApplUidString) + { + // + // Build application UID array from Application Uid text string + // + RArray* applUidList = new (ELeave) RArray(1); + CleanupStack::PushL( applUidList ); + TLex ApplUids(aApplUidString); + TUint32 Uid; + TUid ApplUid; + IkeParser::NextHexaDigit(ApplUids); + + while ( !ApplUids.Eos() ) + { + if ( ApplUids.Val(Uid, EHex) != KErrNone ) + { + break; // Error + } + ApplUid.iUid = Uid; + User::LeaveIfError( applUidList->Append(ApplUid) ); + IkeParser::NextHexaDigit(ApplUids); + } + CleanupStack::Pop( applUidList ); + return applUidList; + } + +EXPORT_C HBufC8* IkeParser::TextToHexOctetsL(const TDesC16& aTextString) +{ + TInt Lth = (aTextString.Length() + 1)/2; + HBufC8* HexOctets = HBufC8::NewL((Lth | 3) + 1); + if ( DeHex(aTextString.Ptr(), aTextString.Length(), (TUint8*)HexOctets->Ptr()) ) + HexOctets->Des().SetLength(Lth); + + return HexOctets; +} + +EXPORT_C TBool IkeParser::TextToHexOctets(const TDesC16& aTextString, TDes8& aHexOctets) +{ + TBool Status; + TInt Lth = ((aTextString.Length() + 1)/2); + if ( aHexOctets.MaxLength() >= Lth ) + { + Status = DeHex(aTextString.Ptr(), aTextString.Length(), (TUint8*)aHexOctets.Ptr()); + if ( !Status ) + Lth = 0; + } + else + { + Status = EFalse; + Lth = 0; + } + aHexOctets.SetLength(Lth); + + return Status; +} + +TBool IkeParser::DeHex(const TUint16* aUcStr, TInt aStrLen, TUint8* aDstBfr) +{ + TBool Status = ETrue; + TUint8 d1, d2; + + while ( (aStrLen > 0) && Status ) + { + d1 = (TUint8)(*aUcStr & 0xff); + Status &= HexVal(d1); + aUcStr ++; + if ( aStrLen > 1 ) + { + d2 = (TUint8)(*aUcStr & 0xff); + Status &= HexVal(d2); + } + else d2 = 0; + aUcStr ++; + aStrLen -= 2; + *aDstBfr++ = (TUint8)(d1 * 16 + d2); + } + return Status; +} + +TBool IkeParser::HexVal(TUint8& c) +{ + TBool Status = ( c >= 'a' && c <= 'f'); + if ( Status ) + c = (TUint8)(c - 'a' + 10); + else + { + Status = (c >= 'A' && c <= 'F'); + if ( Status ) + c = (TUint8)(c - 'A' + 10); + else + { + Status = (c >= '0' && c <= '9'); + if ( Status ) + c = (TUint8)(c - '0'); + } + } + return Status; +} + +void IkeParser::NextHexaDigit(TLex& aUidString) +{ + TChar ch; + + while ( !aUidString.Eos() ) + { + ch = aUidString.Peek(); + if ( ch.IsHexDigit() ) + { + break; + } + aUidString.Inc(); + } +}