vpnengine/dmadpki/src/dmadstorecert.cpp
changeset 0 33413c0669b9
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Implementation of CDmAdCert.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "dmadutil.h"
       
    20 #include "dmadstorecert.h"
       
    21 #include "vpnlogger.h"
       
    22 #include "dmadcertxmldefs.h"
       
    23 #include "XppImpl.h"
       
    24 #include "XwImpl.h"
       
    25 #include <vpnlogmessages.rsg>
       
    26 
       
    27 CDmAdCert* CDmAdCert::NewL(RPKIServiceAPI& aPkiServiceApi)
       
    28     {
       
    29     TRACE("CDmAdCert::NewL");
       
    30     
       
    31     CDmAdCert* self = NewLC(aPkiServiceApi);
       
    32     CleanupStack::Pop(self);
       
    33     return self;
       
    34     }
       
    35 
       
    36 CDmAdCert* CDmAdCert::NewLC(RPKIServiceAPI& aPkiServiceApi)
       
    37     {
       
    38     CDmAdCert* self = new (ELeave) CDmAdCert(aPkiServiceApi);
       
    39     CleanupStack::PushL(self);
       
    40     self->ConstructL();
       
    41     return self;
       
    42     }
       
    43 
       
    44 void CDmAdCert::ConstructL()
       
    45     {
       
    46     TRACE("CDmAdCert::ConstructL");
       
    47     iCertLuidMapping = new (ELeave) CArrayPtrFlat<CDmAdCertLuidMappingElem>(4);
       
    48     BuildCertLuidMappingTableL();
       
    49     }
       
    50     
       
    51 CDmAdCert::CDmAdCert(RPKIServiceAPI& aPkiServiceApi) : iPkiServiceApi(&aPkiServiceApi)
       
    52     {
       
    53     }
       
    54     
       
    55 CDmAdCert::~CDmAdCert()
       
    56     {
       
    57     TRACE("CDmAdCert::~CDmAdCert");
       
    58     CDmAdCertLuidMappingElem::CleanupOperationDeleteCArrayPtr(iCertLuidMapping);    
       
    59     }
       
    60     
       
    61 TBool CDmAdCert::FindL(const TDesC8& aLuid)
       
    62     {
       
    63     TRACE("CDmAdCert::FindL");
       
    64     if (!FindCertLuidMappingElemL(aLuid))
       
    65         {
       
    66         return EFalse;
       
    67         }
       
    68     else
       
    69         {
       
    70         return ETrue;
       
    71         }
       
    72     }
       
    73     
       
    74 HBufC8* CDmAdCert::AddL(const CDmAdCertParms& aParms)
       
    75     {    
       
    76     TRACE("CDmAdCert::AddL");
       
    77     
       
    78     TPKICertificateOwnerType ownerType = aParms.Type();
       
    79 
       
    80     HBufC8* certRef = BuildCertRefL(aParms.Content(), EFalse);
       
    81     CleanupStack::PushL(certRef);
       
    82     CDmAdCertLuidMappingElem* certLuidMappingElem = FindCertLuidMappingElemL(*certRef);
       
    83     if (certLuidMappingElem)
       
    84         {
       
    85         DEBUG_LOG(_L("Element already exists"));
       
    86         User::Leave(KErrAlreadyExists);
       
    87         }
       
    88     CleanupStack::PopAndDestroy(certRef); 
       
    89     
       
    90 
       
    91     TInt status = KErrNone;
       
    92     if (ownerType == EPKIUserCertificate)
       
    93         {
       
    94         DEBUG_LOG(_L("Attaching user certificate"));        
       
    95         
       
    96         TKeyListEntry* keyListEntry = new (ELeave) TKeyListEntry;
       
    97         CleanupStack::PushL(keyListEntry);
       
    98         
       
    99         TPKIKeyIdentifier keyId = aParms.KeyId();
       
   100         DEBUG_LOG(_L("Key id:"));
       
   101         DEBUG_LOG_HEX(keyId);
       
   102         
       
   103         
       
   104         User::LeaveIfError(iPkiServiceApi->KeyDetails(keyId,
       
   105 						   *keyListEntry));
       
   106         
       
   107         TInt keyLength = keyListEntry->iKeySize;
       
   108         
       
   109         DEBUG_LOG(_L("Key info:"));
       
   110         DEBUG_LOG1(_L("Object name: %S"), &(keyListEntry->iObjectName));
       
   111         DEBUG_LOG_HEX(keyListEntry->iSubjectKeyId);
       
   112         DEBUG_LOG1(_L("Key size: %d"), keyListEntry->iKeySize);
       
   113         DEBUG_LOG1(_L("Algorithm: %d"), keyListEntry->iKeyAlgorithm);
       
   114 
       
   115         
       
   116         
       
   117         CleanupStack::PopAndDestroy(); //keyListEntry
       
   118         
       
   119         status = iPkiServiceApi->AttachCertificate(keyId,
       
   120                                                    aParms.Deletable(),
       
   121                                                    keyLength,
       
   122                                                    EPKIRSA,
       
   123                                                    aParms.Content());
       
   124         }
       
   125     else
       
   126         {
       
   127         status = iPkiServiceApi->StoreCertificate(ownerType,
       
   128                                                   aParms.Deletable(),
       
   129                                                   0, //Key length is undefined
       
   130                                                   EPKIRSA,
       
   131                                                   aParms.Content());            
       
   132         }
       
   133 
       
   134     if (status != KErrNone)
       
   135         {
       
   136         DEBUG_LOG1(_L("Operation failed with %d"), status);       
       
   137         User::Leave(status);
       
   138         }
       
   139 
       
   140     certRef = BuildCertRefL(aParms.Content(), ETrue);
       
   141     CleanupStack::PushL(certRef);
       
   142     UpdateL(*certRef, aParms);
       
   143     CleanupStack::Pop(certRef);
       
   144     return certRef;
       
   145     }
       
   146 
       
   147 void CDmAdCert::UpdateL(const TDesC8& aLuid, const CDmAdCertParms& aParms)
       
   148     {
       
   149     TRACE("CDmAdCert::UpdateL");
       
   150     HBufC8* issuerName;
       
   151     HBufC8* serialNumber;
       
   152     GetIssuerAndSerialFromCertRefLC(aLuid, issuerName, serialNumber);
       
   153 
       
   154     if (aParms.Type() == EPKICACertificate) // CA cert
       
   155         {
       
   156         UpdateTrustedL(*issuerName, *serialNumber, aParms);
       
   157         UpdateApplicabilityL(*issuerName, *serialNumber, aParms);
       
   158         }
       
   159     
       
   160     CleanupStack::PopAndDestroy(2); //serialNumber, issuerName
       
   161     }
       
   162     
       
   163 void CDmAdCert::FetchL(const TDesC8& aLuid, CDmAdCertParms& aParms)
       
   164     {
       
   165     TRACE("CDmAdCert::FetchL");
       
   166     HBufC8* issuerName;
       
   167     HBufC8* serialNumber;
       
   168     GetIssuerAndSerialFromCertRefLC(aLuid, issuerName, serialNumber);
       
   169     
       
   170     //TInt certSize = 1024;
       
   171     TInt certSize = 4096;
       
   172     HBufC8* certBuf = NULL;
       
   173     TPtr8 certBufDesc(NULL, 0);
       
   174     TBool errBufferTooShortOccurred = EFalse;
       
   175     for (;;)
       
   176         {
       
   177         if (certBuf)
       
   178             {
       
   179             CleanupStack::PopAndDestroy(certBuf);
       
   180             }
       
   181         certBuf = HBufC8::NewLC(certSize);
       
   182         certBufDesc.Set(certBuf->Des());
       
   183     
       
   184         // Both user and device certificate stores needs to be used for
       
   185         // certificate reading. Set certificate store type to STORETYPE_ANY.
       
   186         TPkiServiceStoreType certStoreType(EPkiStoreTypeAny);
       
   187         User::LeaveIfError(iPkiServiceApi->CertStoreType(certStoreType));
       
   188         User::LeaveIfError(iPkiServiceApi->SetStoreType(STORE_CERTSTORE, EPkiStoreTypeAny));        
       
   189         TInt err = iPkiServiceApi->ReadCertificate(*issuerName,
       
   190                                                    *serialNumber,
       
   191                                                    certBufDesc);
       
   192                 
       
   193         // Set previous store type back
       
   194         User::LeaveIfError(iPkiServiceApi->SetStoreType(STORE_CERTSTORE, certStoreType));                
       
   195         
       
   196         if (err == KErrNone)
       
   197             {
       
   198             break;
       
   199             }
       
   200         else if (err == KPKIErrBufferTooShort)
       
   201             {
       
   202             if (errBufferTooShortOccurred)
       
   203                 {
       
   204                 DEBUG_LOG(_L("Buffer too short"));                
       
   205                 User::Leave(KErrGeneral);
       
   206                 }
       
   207             errBufferTooShortOccurred = ETrue;
       
   208             User::LeaveIfError(iPkiServiceApi->GetRequiredBufferSize(certSize));
       
   209             }
       
   210         else
       
   211             {
       
   212             DEBUG_LOG1(_L("Fetch failed with %d"), err);            
       
   213             User::Leave(err);
       
   214             }
       
   215         }
       
   216 
       
   217     aParms.SetContentL(*certBuf);
       
   218     ReadCertDetailsL(*issuerName, *serialNumber, aParms);
       
   219 
       
   220     CleanupStack::PopAndDestroy(3); //certBuf, serialNumber, issuerName
       
   221     }
       
   222     
       
   223 void CDmAdCert::DeleteL(const TDesC8& aLuid)
       
   224     {
       
   225     TRACE("CDmAdCert::DeleteL");
       
   226     HBufC8* issuerName;
       
   227     HBufC8* serialNumber;
       
   228     GetIssuerAndSerialFromCertRefLC(aLuid, issuerName, serialNumber);
       
   229     while (FindCertLuidMappingElemL(aLuid))
       
   230         {
       
   231         User::LeaveIfError(iPkiServiceApi->RemoveCertificate(*issuerName,
       
   232                                                              *serialNumber));
       
   233         
       
   234         RemoveCertLuidMappingElem(aLuid);
       
   235         }
       
   236     CleanupStack::PopAndDestroy(2); //serialNumber, issuerName
       
   237     }
       
   238 
       
   239 void CDmAdCert::ListL(RPointerArray<HBufC8>& aLuidList)
       
   240     {
       
   241     TRACE("CDmAdCert::ListL");
       
   242     for (TInt i=0; i<iCertLuidMapping->Count(); ++i)
       
   243         {
       
   244         CDmAdCertLuidMappingElem* certLuidMappingElem = iCertLuidMapping->At(i);
       
   245                 
       
   246         HBufC8* luidElem = certLuidMappingElem->Luid().AllocLC();
       
   247         aLuidList.AppendL(luidElem);
       
   248         CleanupStack::Pop(luidElem);
       
   249         }
       
   250     }
       
   251     
       
   252 //------------------------------------------------------------------------
       
   253 
       
   254 void CDmAdCert::ReadCertDetailsL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber, CDmAdCertParms& aParms)
       
   255     {
       
   256     TRACE("CDmAdCert::ReadCertDetailsL");
       
   257     TCertificateListEntry* entry = new (ELeave) TCertificateListEntry();
       
   258     CleanupStack::PushL(entry);
       
   259     
       
   260     User::LeaveIfError(iPkiServiceApi->CertificateDetails(aIssuerName,
       
   261                                                           aSerialNumber,
       
   262                                                           *entry)); 
       
   263     
       
   264     aParms.SetType(entry->iOwnerType);    
       
   265     aParms.SetDeletable(entry->iIsDeletable);
       
   266        
       
   267     TBool trusted = ETrue;
       
   268     if (entry->iOwnerType == EPKICACertificate) // CA cert
       
   269         {
       
   270         User::LeaveIfError(iPkiServiceApi->Trusted(aIssuerName,
       
   271                                                    aSerialNumber,
       
   272                                                    trusted));        
       
   273         }
       
   274     aParms.SetTrusted(trusted);
       
   275 
       
   276     if (entry->iOwnerType == EPKICACertificate) // CA cert
       
   277         {
       
   278         RArray<TUid> applications;
       
   279         CleanupClosePushL(applications);
       
   280         
       
   281         iPkiServiceApi->ApplicationsL(aIssuerName,
       
   282                                       aSerialNumber,
       
   283                                       applications);
       
   284         aParms.SetApplicabilityL(applications);                                      
       
   285         CleanupStack::PopAndDestroy(); //applications
       
   286         }    
       
   287         
       
   288     CleanupStack::PopAndDestroy(); // entry        
       
   289     }
       
   290     
       
   291 void CDmAdCert::UpdateTrustedL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber, const CDmAdCertParms& aParms)
       
   292     {
       
   293     TRACE("CDmAdCert::UpdateTrustedL");
       
   294     
       
   295     User::LeaveIfError(iPkiServiceApi->SetTrust(aIssuerName,
       
   296                                                 aSerialNumber,
       
   297                                                 aParms.Trusted()));
       
   298     }
       
   299 
       
   300 void CDmAdCert::UpdateApplicabilityL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber, const CDmAdCertParms& aParms)
       
   301     {
       
   302     TRACE("CDmAdCert::UpdateApplicabilityL");
       
   303     
       
   304     const RArray<TUid>& applications = aParms.Applicability();   
       
   305     if (applications.Count() > 0)
       
   306         {
       
   307         iPkiServiceApi->SetApplicabilityL(aIssuerName,
       
   308                                           aSerialNumber,
       
   309                                           applications);
       
   310         }
       
   311     }
       
   312 
       
   313 TPtrC8 CDmAdCert::AppendCertLuidMappingElemL(const TDesC8& aIssuerName, const TDesC8& aSerialNumber)
       
   314     {
       
   315     TRACE("CDmAdCert::AppendCertLuidMappingElemL");
       
   316     TPtrC8 luid(KNullDesC8);
       
   317     
       
   318     CDmAdCertLuidMappingElem* certLuidMappingElem = CDmAdCertLuidMappingElem::NewLC(aIssuerName, aSerialNumber);
       
   319     luid.Set(certLuidMappingElem->Luid());
       
   320     
       
   321     iCertLuidMapping->AppendL(certLuidMappingElem);
       
   322     CleanupStack::Pop(certLuidMappingElem);
       
   323     
       
   324     return luid;
       
   325     }
       
   326 
       
   327 void CDmAdCert::RemoveCertLuidMappingElem(const TDesC8& aLuid)
       
   328     {
       
   329     TRACE("CDmAdCert::RemoveCertLuidMappingElem");
       
   330     for (TInt i=0; i<iCertLuidMapping->Count(); ++i)
       
   331         {
       
   332         CDmAdCertLuidMappingElem* certLuidMappingElem = iCertLuidMapping->At(i);
       
   333         if (certLuidMappingElem->Luid().Compare(aLuid) == 0)
       
   334             {
       
   335             iCertLuidMapping->Delete(i);
       
   336             i--;
       
   337             delete certLuidMappingElem;
       
   338             break;
       
   339             }
       
   340         }
       
   341     }
       
   342 
       
   343 CDmAdCertLuidMappingElem* CDmAdCert::FindCertLuidMappingElemL(const TDesC8& aLuid)
       
   344     {
       
   345     TRACE("CDmAdCert::FindCertLuidMappingElemL");
       
   346     for (TInt i=0; i<iCertLuidMapping->Count(); ++i)
       
   347         {
       
   348         CDmAdCertLuidMappingElem* certLuidMappingElem = iCertLuidMapping->At(i);
       
   349         if (certLuidMappingElem->Luid().Compare(aLuid) == 0)
       
   350             {
       
   351             return certLuidMappingElem;
       
   352             }
       
   353         }
       
   354     return NULL;
       
   355     }
       
   356 
       
   357 void CDmAdCert::BuildCertLuidMappingTableL()
       
   358     {
       
   359     TRACE("CDmAdCert::BuildCertLuidMappingTableL");
       
   360     CArrayFix<TCertificateListEntry>* certList;
       
   361     iPkiServiceApi->ListCertificatesL(certList);
       
   362     CleanupStack::PushL(certList);
       
   363 
       
   364     for (TInt i=0; i<certList->Count(); ++i)
       
   365         {
       
   366         TCertificateListEntry& entry = certList->At(i);
       
   367         AppendCertLuidMappingElemL(entry.iTrustedAuthority, entry.iSerialNumber);
       
   368         }
       
   369     
       
   370     CleanupStack::PopAndDestroy(certList); 
       
   371     }
       
   372 
       
   373 HBufC8* CDmAdCert::BuildCertRefL(const TDesC8& aCertificateDer, TBool aAppend)
       
   374     {
       
   375     TRACE("CDmAdCert::BuildCertRefL");
       
   376     
       
   377     CX509Certificate* certCx509 = CX509Certificate::NewL(aCertificateDer);
       
   378     CleanupStack::PushL(certCx509);
       
   379 
       
   380     const TPtrC8 issuerName(*(certCx509->DataElementEncoding(CX509Certificate::EIssuerName)));
       
   381     const TPtrC8 serialNumber(*(certCx509->DataElementEncoding(CX509Certificate::ESerialNumber)));
       
   382 
       
   383     HBufC8* certRef = 0;
       
   384     if (aAppend)
       
   385         {
       
   386         TPtrC8 luid(AppendCertLuidMappingElemL(issuerName, serialNumber));
       
   387         certRef = luid.AllocL();
       
   388         }
       
   389     else
       
   390         {
       
   391         certRef = CDmAdCertLuidMappingElem::BuildLuidL(issuerName, serialNumber);
       
   392         }
       
   393 
       
   394     CleanupStack::PopAndDestroy(certCx509);
       
   395     return certRef;
       
   396     }
       
   397 
       
   398 void CDmAdCert::GetIssuerAndSerialFromCertRefLC(const TDesC8&  aCertRef,
       
   399                                                 HBufC8*&       aIssuerName,
       
   400                                                 HBufC8*&       aSerialNumber)
       
   401     {
       
   402     CDmAdCertLuidMappingElem* certLuidMappingElem = FindCertLuidMappingElemL(aCertRef);
       
   403     if (!certLuidMappingElem)
       
   404         {
       
   405         DEBUG_LOG(_L("Mapping not found"));        
       
   406         User::Leave(KErrNotFound);
       
   407         }
       
   408 
       
   409     HBufC8* issuerNameHBuf = certLuidMappingElem->IssuerName().AllocLC();
       
   410     HBufC8* serialNumberHBuf = certLuidMappingElem->SerialNumber().AllocLC();
       
   411     
       
   412     aIssuerName = issuerNameHBuf;
       
   413     aSerialNumber = serialNumberHBuf;
       
   414     }
       
   415 
       
   416 HBufC8* CDmAdCert::CertSubjectNameL(const TDesC8& aCertificateDer)
       
   417     {
       
   418     CX509Certificate* certCx509 = CX509Certificate::NewLC(aCertificateDer);
       
   419     HBufC16* subjectName16 = certCx509->SubjectName().DisplayNameL();
       
   420     CleanupStack::PushL(subjectName16);    
       
   421     HBufC8* subjectName8 = HBufC8::NewL(subjectName16->Length());
       
   422     subjectName8->Des().Copy(*subjectName16);
       
   423     CleanupStack::PopAndDestroy(2, certCx509);
       
   424     return subjectName8;
       
   425     }