vpnengine/pkiservice/src/mapdescriptor.cpp
changeset 1 c9c2ad51f972
child 38 9f4e37332ce5
--- /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 <x509cert.h>
+#include <asymmetric.h>
+
+#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<CX509GeneralName> *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<TUid> &aApplications) 
+    {
+    iApplUids.Close();
+    for(TInt i=0; i<aApplications.Count();i++)
+        { 
+        iApplUids.Append(aApplications[i]);
+        }
+    }
+
+TPtrC CMapDescriptor::Label() const
+    {
+    return iLabel;
+    }
+
+const TPKIKeyIdentifier& CMapDescriptor::CertificateKeyId() const
+    {    
+    return iKeyId;
+    }
+
+TUint CMapDescriptor::KeySize() const
+    {
+    return iKeySize;
+    }
+
+TPKICertificateOwnerType CMapDescriptor::OwnerType() const
+    {
+    return iOwnerType;
+    }
+
+TPtrC8 CMapDescriptor::TrustedAuthority() const
+    {
+    if (iIssuerName == NULL)
+        {
+        return KEmptyDescriptor();
+        }
+    else
+        {
+        return *iIssuerName;
+        }
+    }
+
+TPtrC8 CMapDescriptor::IdentitySubjectName() const
+    {
+    if (iSubjectName == NULL)
+        {
+        return KEmptyDescriptor();
+        }
+    else
+        {
+        return *iSubjectName;
+        }
+    }
+
+TPtrC8 CMapDescriptor::SerialNumber() const
+    {
+    if (iSerialNumber == NULL)
+        {
+        return KEmptyDescriptor();
+        }
+    else
+        {
+        return *iSerialNumber;
+        }
+    }
+
+TPKIKeyAlgorithm CMapDescriptor::KeyAlgorithm() const
+    {
+    return iKeyAlgorithm;
+    }
+
+TBool CMapDescriptor::Deletable() const
+    {
+    return iIsDeletable;
+    }
+
+TTime CMapDescriptor::EndTime() const
+    {
+    return iEndTime;
+    }
+
+CMapDescriptor::TValidity CMapDescriptor::CertValidity() const 
+    {
+    TTimeIntervalSeconds tolerance(120); 
+    TTime currentTime;
+    currentTime.UniversalTime();
+
+    if (iEndTime <= currentTime)
+        {
+        return EExpired;
+        }
+
+    if (iStartTime >= 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;
+}