diff -r 33413c0669b9 -r c9c2ad51f972 vpnengine/pkiservice/src/mapdescriptor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vpnengine/pkiservice/src/mapdescriptor.cpp Thu Jan 07 13:26:15 2010 +0200 @@ -0,0 +1,562 @@ +/* +* Copyright (c) 2006-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: +* A data object for CPKIMapper class thar holds the information +* required to map API set to use the storage model which is not +* native for that API. +* +*/ +#include +#include + +#include "mapdescriptor.h" +#include "pkiserviceclientservercommon.h" +#include "pkiserviceassert.h" +#include "pkcs10.h" + +_LIT8(KEmptyDescriptor, ""); + +CMapDescriptor* CMapDescriptor::NewL(const TDesC& aLabel, + const CX509Certificate& aCertificate, + TPKICertificateOwnerType aOwnerType, + TPkiServiceStoreType aCertStoreType) + { + CMapDescriptor* self = new (ELeave) CMapDescriptor; + CleanupStack::PushL(self); + self->ConstructL(aLabel, aCertificate, + aOwnerType, aCertStoreType); + CleanupStack::Pop(self); + + return self; + } + + +void CMapDescriptor::ConstructL(const TDesC& aLabel, + const CX509Certificate& aCertificate, + TPKICertificateOwnerType aOwnerType, + TPkiServiceStoreType aCertStoreType) + { + iLabel = aLabel; + iCertStoreType = aCertStoreType; + iOwnerType = aOwnerType; + + + iIssuerName = aCertificate.DataElementEncoding(CX509Certificate::EIssuerName)->AllocL(); + iSubjectName = aCertificate.DataElementEncoding(CX509Certificate::ESubjectName)->AllocL(); + + // Copy rfc822 name from subjectAlt name + const CX509CertExtension* subjAltName = aCertificate.Extension(KSubjectAltName); + if(subjAltName != NULL) + { + CX509AltNameExt* subjectAlt = CX509AltNameExt::NewLC(subjAltName->Data()); + if(subjectAlt != NULL) + { + const CArrayPtrFlat *nameArray; + nameArray = &subjectAlt->AltName(); + // Search rfc822 + for(TInt i = 0; i < nameArray->Count(); i++) + { + if(nameArray->At(i)->Tag() == EX509RFC822Name) + { + TPtrC8 data = nameArray->At(i)->Data(); + iRfc822Name = data.Right(data.Length() - 2).AllocL(); + break; + } + } + } + CleanupStack::PopAndDestroy(subjectAlt); + } + + + + + // Serial number + const TPtrC8* serial = aCertificate.DataElementEncoding(CX509Certificate::ESerialNumber); + if(serial != NULL) + { + iSerialNumber = serial->AllocL(); + } + else + { + iSerialNumber = KEmptyDescriptor().AllocL(); + } + + // Validity period + iStartTime = aCertificate.ValidityPeriod().Start(); + iEndTime = aCertificate.ValidityPeriod().Finish(); + + if (EPKICACertificate == iOwnerType) + { + iKeyId = aCertificate.SubjectKeyIdentifierL(); + } + else + { + iKeyId = aCertificate.KeyIdentifierL(); + } + + const CSubjectPublicKeyInfo& publicKeyInfo = aCertificate.PublicKey(); + const TPtrC8 keyData = publicKeyInfo.KeyData(); + + TX509KeyFactory keyFactory; + switch(publicKeyInfo.AlgorithmId()) + { + case ERSA: + { + iKeyAlgorithm = EPKIRSA; + const CRSAPublicKey* keyRSA = keyFactory.RSAPublicKeyL( keyData ); + const TInteger& n = keyRSA->N(); + iKeySize = n.BitCount(); + delete keyRSA; + } + break; + case EDSA: + { + iKeyAlgorithm = EPKIDSA; + TPtrC8 params = publicKeyInfo.EncodedParams(); + const CDSAPublicKey* keyDSA = keyFactory.DSAPublicKeyL( params, keyData ); + const TInteger& y = keyDSA->Y(); + iKeySize = y.BitCount(); + delete keyDSA; + } + break; + default: + User::Leave(KErrNotSupported); + break; + } + + + } + + +CMapDescriptor::~CMapDescriptor() + { + delete iIssuerName; + delete iSubjectName; + delete iRfc822Name; + delete iSerialNumber; + iApplUids.Close(); + } + +TBool CMapDescriptor::IsMatchingL(TSecurityObjectDescriptor &aDesc, + const TBool aInfoOnly, + TPkiServiceStoreType aCertStoreType) const + { + TBool match(EFalse); + + LOG(Log::Printf(_L("Matching"))); + LOG_1(" Pure informational: %d", aInfoOnly); + + LOG(Log::Printf(_L("Matching: certificate %S"), &iLabel)); + for(;;) + { + if (aDesc.iOwnerType != EPKICACertificate && + aCertStoreType != EPkiStoreTypeAny) + { + if (iCertStoreType != aCertStoreType) + { + LOG(Log::Printf(_L(" Store doesn't match, aborting"))); + match = EFalse; + break; + } + } + else + { + LOG(Log::Printf(_L("Skipping store check, not relevant"))); + } + + + if (aDesc.iSubjectKeyIdUsed) + { + if(iKeyId == aDesc.iSubjectKeyId) + { + match = ETrue; + } + else + { + match = EFalse; + break; + } + } + + if(aDesc.iTrustedAuthorityUsed) + { + if(iIssuerName == NULL) + { + match = EFalse; + break; + } + else + { + CX500DistinguishedName* dnSuffix1 = CX500DistinguishedName::NewLC(*iIssuerName); + CX500DistinguishedName* dnSuffix2; + TInt popCount = 3; + + // ASN1 or plain text + if((aDesc.iTrustedAuthority[0] != 0x30) + || ((aDesc.iTrustedAuthority[1] != 0x81) + && (aDesc.iTrustedAuthority[1] != 0x82) + && ((aDesc.iTrustedAuthority[1] + 2) != aDesc.iTrustedAuthority.Length()))) + { + HBufC8* name2Der; + CPkcs10Req::BuildDistinguishedNameDerFromTextL(name2Der, + aDesc.iTrustedAuthority, + EFalse, KNullDesC8); + CleanupStack::PushL(name2Der); + + dnSuffix2 = CX500DistinguishedName::NewLC(*name2Der); + } + else + { + dnSuffix2 = CX500DistinguishedName::NewLC(aDesc.iTrustedAuthority); + popCount = 2; + } + + + if(MatchL(*dnSuffix1, *dnSuffix2)) + { + match = ETrue; + CleanupStack::PopAndDestroy(popCount); + } + else + { + match = EFalse; + CleanupStack::PopAndDestroy(popCount); + break; + } + } + } + if(aDesc.iOwnerTypeUsed) + { + if(iOwnerType == aDesc.iOwnerType) + { + match = ETrue; + } + else + { + match = EFalse; + break; + } + } + if(aDesc.iSerialNumberUsed) + { + if ((iSerialNumber != NULL) && ((*iSerialNumber).Compare(aDesc.iSerialNumber) == 0)) + { + match = ETrue; + } + else + { + match = EFalse; + break; + } + } + + if(aDesc.iIdentitySubjectNameUsed) + { + if(iSubjectName == NULL) + { + match = EFalse; + break; + } + else + { + CX500DistinguishedName* dnSuffix1 = CX500DistinguishedName::NewLC(*iSubjectName); + CX500DistinguishedName* dnSuffix2; + TInt popCount = 3; + // ASN1 or plain text + if((aDesc.iIdentitySubjectName[0] != 0x30) + || ((aDesc.iIdentitySubjectName[1] != 0x81) + && (aDesc.iIdentitySubjectName[1] != 0x82) + && ((aDesc.iIdentitySubjectName[1] + 2) != aDesc.iIdentitySubjectName.Length()))) + { + HBufC8* name2Der; + CPkcs10Req::BuildDistinguishedNameDerFromTextL(name2Der, + aDesc.iIdentitySubjectName, + EFalse, KNullDesC8); + CleanupStack::PushL(name2Der); + + dnSuffix2 = CX500DistinguishedName::NewLC(*name2Der); + } + else + { + dnSuffix2 = CX500DistinguishedName::NewLC(aDesc.iIdentitySubjectName); + popCount = 2; + } + + if(MatchL(*dnSuffix1, *dnSuffix2)) + { + CleanupStack::PopAndDestroy(popCount); + match = ETrue; + } + else + { + CleanupStack::PopAndDestroy(popCount); + match = EFalse; + break; + } + } + } + + if(aDesc.iIdentityRfc822NameUsed) + { + if(iRfc822Name == NULL) + { + match = EFalse; + break; + } + else + { + TInt bytes = aDesc.iIdentityRfc822Name.Length(); + TPtrC8 tail = (*iRfc822Name).Right(bytes); + if (tail.CompareF(aDesc.iIdentityRfc822Name) == 0) + { + match = ETrue; + } + else + { + match = EFalse; + break; + } + } + } + + if(aDesc.iKeySizeUsed) + { + if(iKeySize == aDesc.iKeySize) + { + match = ETrue; + } + else + { + match = EFalse; + break; + } + } + + if (match && !aInfoOnly) + { + TValidity val = CertValidity(); + // Treat future certificates as valid + if((val == EValid) || (val == ENotValidYet)) + { + match = ETrue; + } + else + { + LOG_("Matching: Expired, and not an informational request"); + match = EFalse; + break; + } + } + + break; + } + + return match; + } + +TBool CMapDescriptor::IsEqual(CMapDescriptor &aDesc) + { + TBool match = EFalse; + + for(;;) + { + if((iIssuerName != NULL) && + (aDesc.iIssuerName != NULL) && + (iIssuerName->Des().Compare(*aDesc.iIssuerName) == 0)) + { + match = ETrue; + } + else + { + match = EFalse; + break; + } + + if((iSerialNumber != NULL) && (aDesc.iSerialNumber != NULL) && (iSerialNumber->Des().Compare(*aDesc.iSerialNumber) == 0)) + { + match = ETrue; + } + else + { + match = EFalse; + break; + } + + break; + } + + return match; + } + + +void CMapDescriptor::SetMapTrusted(const TBool &aTrusted) + { + iIsTrusted = aTrusted; + } + +void CMapDescriptor::SetMapDeletable(TBool aDeletable) + { + iIsDeletable = aDeletable; + } + +void CMapDescriptor::SetMapApplications(const RArray &aApplications) + { + iApplUids.Close(); + for(TInt i=0; i= currentTime + tolerance) + { + return ENotValidYet; + } + + return EValid; + } + +TBool CMapDescriptor::IsApplicable(TUid aApplUid) const + { + TBool isApplicable = EFalse; + for (TInt i = 0; i < iApplUids.Count(); ++i) + { + if (aApplUid == iApplUids[i]) + { + isApplicable = ETrue; + break; + } + } + return isApplicable; + } + +TBool CMapDescriptor::MatchL(const CX500DistinguishedName& aDn1, const CX500DistinguishedName& aDn2) const +{ + if((aDn1.Count() == 0) || (aDn2.Count() == 0)) + { + return EFalse; + } + + if (aDn1.Count() < aDn2.Count()) + { + return EFalse; + } + else + { + // For each field in aDn2, aDn1 must contain a field with the same value + for (TInt i = 0; i < aDn2.Count(); i++) + { + if (!HasElementL(aDn1, aDn2.Element(i))) + { + return EFalse; + } + } + } + + return ETrue; +} + +TBool CMapDescriptor::HasElementL(const CX500DistinguishedName& aDn, const CX520AttributeTypeAndValue& aElement) const +{ + for (TInt i = 0; i < aDn.Count(); i++) + { + if (aElement.ExactMatchL(aDn.Element(i))) + { + return ETrue; + } + } + return EFalse; +}