vpnengine/pkiservice/src/pkimapper.cpp
changeset 0 33413c0669b9
child 1 c9c2ad51f972
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2006-2009 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: 
       
    15 * CPKIMapper class holds the information required to map API set to 
       
    16 * use the storage model which is not native for that API.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 #include <x500dn.h>
       
    22 #include <x509cert.h>
       
    23 
       
    24 #include "PKIMapper.h"
       
    25 #include "pkcs10.h"
       
    26 #include "log_r6.h"
       
    27 #include "pkiserviceassert.h"
       
    28 
       
    29 
       
    30 CMapDescriptor::CMapDescriptor(TSecurityObjectDescriptor &aDesc)
       
    31     {
       
    32     this->iSubjectKeyId = aDesc.iSubjectKeyId;
       
    33     this->iOwnerType = aDesc.iOwnerType;
       
    34     this->iKeySize = aDesc.iKeySize;            
       
    35     this->iKeyAlgorithm = aDesc.iKeyAlgorithm;      
       
    36     this->iIsDeletable = aDesc.iIsDeletable;      
       
    37     }
       
    38 
       
    39 CMapDescriptor& CMapDescriptor::operator=(CMapDescriptor& aMapDesc)
       
    40 {
       
    41     delete this->iTrustedAuthority;
       
    42     this->iTrustedAuthority = NULL;
       
    43     if(aMapDesc.iTrustedAuthority != NULL)
       
    44         {
       
    45         this->iTrustedAuthority     = aMapDesc.iTrustedAuthority->Des().AllocL();           // Cert TrustedAuthority
       
    46         }
       
    47     delete this->iIdentitySubjectName;
       
    48     this->iIdentitySubjectName = NULL;
       
    49     if(aMapDesc.iIdentitySubjectName != NULL)
       
    50         {
       
    51         this->iIdentitySubjectName  = aMapDesc.iIdentitySubjectName->Des().AllocL();        // Identity subject name
       
    52         }
       
    53     delete this->iIdentityRfc822Name;
       
    54     this->iIdentityRfc822Name = NULL;
       
    55     if(aMapDesc.iIdentityRfc822Name != NULL)
       
    56         {
       
    57         this->iIdentityRfc822Name   = aMapDesc.iIdentityRfc822Name->Des().AllocL();         // Identity subjectAltName rfc822 name
       
    58         }
       
    59     delete this->iSerialNumber;
       
    60     this->iSerialNumber = NULL;
       
    61     if(aMapDesc.iSerialNumber != NULL)
       
    62         {
       
    63         this->iSerialNumber         = aMapDesc.iSerialNumber->Des().AllocL();               // Serialnumber
       
    64         }
       
    65         
       
    66     this->iSubjectKeyId         = aMapDesc.iSubjectKeyId;                               // SHA1 hash of the corresponding private key
       
    67     this->iOwnerType            = aMapDesc.iOwnerType;                                  // User, CA or peer. If user certificate, at least key usage must be set
       
    68     this->iKeyUsageDer          = aMapDesc.iKeyUsageDer;                                // Der format flags
       
    69     this->iObjectName           = aMapDesc.iObjectName;
       
    70     this->iKeySize              = aMapDesc.iKeySize;                                    // Key size
       
    71     this->iKeyAlgorithm         = aMapDesc.iKeyAlgorithm;                               // RSA, DSA
       
    72     this->iStartTime            = aMapDesc.iStartTime;
       
    73     this->iEndTime              = aMapDesc.iEndTime;
       
    74     this->iIsDeletable          = aMapDesc.iIsDeletable;
       
    75     TInt i;
       
    76     for(i=0;i<aMapDesc.iApplUids.Count();i++)
       
    77         {
       
    78         this->iApplUids.Append(aMapDesc.iApplUids[i]);
       
    79         }
       
    80         
       
    81     this->iCertStoreType        = aMapDesc.iCertStoreType;
       
    82     return *this;
       
    83 }
       
    84 
       
    85 
       
    86 TBool CMapDescriptor::IsMatchingL(TSecurityObjectDescriptor &aDesc, 
       
    87                                   const TBool aInfoOnly, 
       
    88                                   TPkiServiceStoreType aCertStoreType) const
       
    89     {
       
    90     TBool match(EFalse);
       
    91 
       
    92     LOG(Log::Printf(_L("Matching")));
       
    93     LOG_1(" Pure informational: %d", aInfoOnly);
       
    94 
       
    95     LOG(Log::Printf(_L("Matching: certificate %S"), &iObjectName));
       
    96     for(;;)
       
    97         {
       
    98         if (aDesc.iOwnerType != EPKICACertificate &&
       
    99             aCertStoreType != EPkiStoreTypeAny) 
       
   100             {            
       
   101             if (iCertStoreType != aCertStoreType)
       
   102                 {
       
   103                 LOG(Log::Printf(_L("    Store doesn't match, aborting")));
       
   104                 match = EFalse;
       
   105                 break;                
       
   106                 }
       
   107             }
       
   108         else 
       
   109             {
       
   110             LOG(Log::Printf(_L("Skipping store check, not relevant")));
       
   111             }
       
   112                     
       
   113 			
       
   114         if (aDesc.iSubjectKeyIdUsed)
       
   115             {            
       
   116 			if(iSubjectKeyId == aDesc.iSubjectKeyId)
       
   117 				{
       
   118 				match = ETrue;
       
   119 				}
       
   120 			else
       
   121 				{
       
   122 				match = EFalse;
       
   123 				break;
       
   124 				}
       
   125 			}
       
   126 			
       
   127         if(aDesc.iTrustedAuthorityUsed)
       
   128             {
       
   129             if(iTrustedAuthority == NULL)
       
   130                 {
       
   131                 match = EFalse;
       
   132                 break;
       
   133                 }
       
   134             else
       
   135                 {
       
   136                 CX500DistinguishedName* dnSuffix1 = CX500DistinguishedName::NewLC(*iTrustedAuthority);
       
   137                 CX500DistinguishedName* dnSuffix2;
       
   138                 TInt popCount = 3;
       
   139 
       
   140                 // ASN1 or plain text
       
   141                 if((aDesc.iTrustedAuthority[0] != 0x30)
       
   142                    || ((aDesc.iTrustedAuthority[1] != 0x81)
       
   143                    && (aDesc.iTrustedAuthority[1] != 0x82)
       
   144                    && ((aDesc.iTrustedAuthority[1] + 2) != aDesc.iTrustedAuthority.Length())))
       
   145                     {
       
   146                     HBufC8* name2Der;
       
   147                     CPkcs10Req::BuildDistinguishedNameDerFromTextL(name2Der,
       
   148                                                                    aDesc.iTrustedAuthority,
       
   149                                                                    EFalse, KNullDesC8);
       
   150                     CleanupStack::PushL(name2Der);
       
   151 
       
   152                     dnSuffix2 = CX500DistinguishedName::NewLC(*name2Der);
       
   153                     }
       
   154                 else
       
   155                     {
       
   156                     dnSuffix2 = CX500DistinguishedName::NewLC(aDesc.iTrustedAuthority);
       
   157                     popCount = 2;
       
   158                     }
       
   159 
       
   160 
       
   161                 if(PkiUtil::MatchL(*dnSuffix1, *dnSuffix2))
       
   162                     {
       
   163                     match = ETrue;
       
   164                     CleanupStack::PopAndDestroy(popCount);
       
   165                     }
       
   166                 else
       
   167                     {
       
   168                     match = EFalse;
       
   169                     CleanupStack::PopAndDestroy(popCount);
       
   170                     break;
       
   171                     }
       
   172                 }
       
   173             }
       
   174         if(aDesc.iOwnerTypeUsed)
       
   175             {
       
   176             if(iOwnerType == aDesc.iOwnerType)
       
   177                 {
       
   178                 match = ETrue;
       
   179                 }
       
   180             else
       
   181                 {
       
   182                 match = EFalse;
       
   183                 break;
       
   184                 }
       
   185             }
       
   186         if(aDesc.iSerialNumberUsed)
       
   187             {
       
   188             if ((iSerialNumber != NULL) && ((*iSerialNumber).Compare(aDesc.iSerialNumber) == 0))
       
   189                 {
       
   190                 match = ETrue;
       
   191                 }
       
   192             else
       
   193                 {
       
   194                 match = EFalse;
       
   195                 break;
       
   196                 }
       
   197             }
       
   198 
       
   199         if(aDesc.iIdentitySubjectNameUsed)
       
   200             {
       
   201             if(iIdentitySubjectName == NULL)
       
   202                 {
       
   203                 match = EFalse;
       
   204                 break;
       
   205                 }
       
   206             else
       
   207                 {
       
   208                 CX500DistinguishedName* dnSuffix1 = CX500DistinguishedName::NewLC(*iIdentitySubjectName);
       
   209                 CX500DistinguishedName* dnSuffix2;
       
   210                 TInt popCount = 3;
       
   211                 // ASN1 or plain text
       
   212                 if((aDesc.iIdentitySubjectName[0] != 0x30)
       
   213                    || ((aDesc.iIdentitySubjectName[1] != 0x81)
       
   214                    && (aDesc.iIdentitySubjectName[1] != 0x82)
       
   215                    && ((aDesc.iIdentitySubjectName[1] + 2) != aDesc.iIdentitySubjectName.Length())))
       
   216                     {
       
   217                     HBufC8* name2Der;
       
   218                     CPkcs10Req::BuildDistinguishedNameDerFromTextL(name2Der,
       
   219                                                                    aDesc.iIdentitySubjectName,
       
   220                                                                    EFalse, KNullDesC8);
       
   221                     CleanupStack::PushL(name2Der);
       
   222 
       
   223                     dnSuffix2 = CX500DistinguishedName::NewLC(*name2Der);
       
   224                     }
       
   225                 else
       
   226                     {
       
   227                     dnSuffix2 = CX500DistinguishedName::NewLC(aDesc.iIdentitySubjectName);
       
   228                     popCount = 2;
       
   229                     }
       
   230 
       
   231                 if(PkiUtil::MatchL(*dnSuffix1, *dnSuffix2))
       
   232                     {
       
   233                     CleanupStack::PopAndDestroy(popCount);
       
   234                     match = ETrue;
       
   235                     }
       
   236                 else
       
   237                     {
       
   238                     CleanupStack::PopAndDestroy(popCount);
       
   239                     match = EFalse;
       
   240                     break;
       
   241                     }
       
   242                 }
       
   243             }
       
   244 
       
   245         if(aDesc.iIdentityRfc822NameUsed)
       
   246             {
       
   247             if(iIdentityRfc822Name == NULL)
       
   248                 {
       
   249                 match = EFalse;
       
   250                 break;
       
   251                 }
       
   252             else
       
   253                 {
       
   254                 TInt bytes = aDesc.iIdentityRfc822Name.Length();
       
   255                 TPtrC8 tail = (*iIdentityRfc822Name).Right(bytes);
       
   256                 if (tail.CompareF(aDesc.iIdentityRfc822Name) == 0)
       
   257                     {
       
   258                     match = ETrue;
       
   259                     }
       
   260                 else
       
   261                     {
       
   262                     match = EFalse;
       
   263                     break;
       
   264                     }
       
   265                 }
       
   266             }
       
   267 
       
   268         if(aDesc.iKeyUsageUsed)
       
   269             {
       
   270             CX509KeyUsageExt* tempUsage = NULL;
       
   271             if(iKeyUsageDer.Length() != 0)
       
   272                 {
       
   273                 tempUsage = CX509KeyUsageExt::NewL(iKeyUsageDer);
       
   274                 }
       
   275             if((tempUsage == NULL) || tempUsage->IsSet(aDesc.iKeyUsage))       
       
   276                 {
       
   277                 delete tempUsage;
       
   278                 match = ETrue;
       
   279                 }
       
   280             else
       
   281                 {
       
   282                 delete tempUsage;
       
   283                 match = EFalse;
       
   284                 break;
       
   285                 }
       
   286             }
       
   287             
       
   288         if(aDesc.iKeySizeUsed)
       
   289             {
       
   290             if(iKeySize == aDesc.iKeySize)
       
   291                 {
       
   292                 match = ETrue;
       
   293                 }
       
   294             else
       
   295                 {
       
   296                 match = EFalse;
       
   297                 break;
       
   298                 }
       
   299             }
       
   300             
       
   301         if (match && !aInfoOnly)
       
   302             {            
       
   303             TValidity  val = CPKIMapper::CertValidity(iStartTime, iEndTime);
       
   304             // Treat future certificates as valid
       
   305             if((val == EValid) || (val == ENotValidYet))
       
   306                 {
       
   307                 match = ETrue;
       
   308                 }
       
   309             else
       
   310                 {
       
   311                 LOG_("Matching: Expired, and not an informational request");
       
   312                 match = EFalse;
       
   313                 break;
       
   314                 }
       
   315             }
       
   316             
       
   317         break;
       
   318         }
       
   319 		
       
   320     return match;
       
   321     }
       
   322 
       
   323 TBool CMapDescriptor::IsEqual(CMapDescriptor &aDesc)
       
   324     {
       
   325     TBool match = EFalse;
       
   326 
       
   327     for(;;)
       
   328         {
       
   329         if((iTrustedAuthority != NULL) && (aDesc.iTrustedAuthority != NULL) && (iTrustedAuthority->Des().Compare(*aDesc.iTrustedAuthority) == 0))
       
   330             {
       
   331             match = ETrue;
       
   332             }
       
   333         else
       
   334             {
       
   335             match = EFalse;
       
   336             break;
       
   337             }
       
   338         
       
   339         if((iSerialNumber != NULL) && (aDesc.iSerialNumber != NULL) && (iSerialNumber->Des().Compare(*aDesc.iSerialNumber) == 0))
       
   340             {
       
   341                 match = ETrue;
       
   342                 }
       
   343             else
       
   344                 {
       
   345                 match = EFalse;
       
   346                 break;
       
   347                 }
       
   348             
       
   349         break;
       
   350         }
       
   351 
       
   352     return match;
       
   353     }
       
   354     
       
   355     
       
   356 void CMapDescriptor::SetCertStoreType(TPkiServiceStoreType aCertStoreType)
       
   357     {
       
   358     iCertStoreType = aCertStoreType;
       
   359     }
       
   360 
       
   361 CPKIMapper* CPKIMapper::NewL()
       
   362     {
       
   363     CPKIMapper* self = new (ELeave) CPKIMapper();
       
   364     CleanupStack::PushL(self);
       
   365     self->ConstructL();
       
   366     CleanupStack::Pop(self);
       
   367     return self;
       
   368     }
       
   369 
       
   370 CPKIMapper::~CPKIMapper()
       
   371     {
       
   372     if ( iMapping )
       
   373         {
       
   374         iMapping->ResetAndDestroy();
       
   375         delete iMapping;
       
   376         }
       
   377     }
       
   378 
       
   379 
       
   380 CPKIMapper::CPKIMapper()
       
   381     {
       
   382     }
       
   383 
       
   384 void CPKIMapper::ConstructL()
       
   385     {
       
   386     LOG_("CPKIMapper::ConstructL");
       
   387     // Allocate mapping vector. Approx granularity 20 
       
   388     iMapping = new (ELeave) RPointerArray<CMapDescriptor>(20);
       
   389     }
       
   390 
       
   391 void CPKIMapper::SetCacheCreated()
       
   392     {
       
   393     iCacheCreated = ETrue;
       
   394     }
       
   395 TBool CPKIMapper::CacheCreated()
       
   396     {
       
   397     return iCacheCreated;
       
   398     }
       
   399     
       
   400 TInt CPKIMapper::AddMapping(CMapDescriptor& aMap)
       
   401     {
       
   402     // Insert as first element, so that newest object will be found first
       
   403     return iMapping->Insert(&aMap, 0);
       
   404     }
       
   405 
       
   406 void CPKIMapper::LogMap(CMapDescriptor &aDescriptor) const 
       
   407     {
       
   408     TInt len = aDescriptor.iSubjectKeyId.Length();
       
   409     LOG(Log::Printf(_L("====CertificateObject====\n")));
       
   410     LOG(Log::Printf(_L("ObjectName: %S\n"), &(aDescriptor.iObjectName)));
       
   411     LOG(Log::Printf(_L("KeyId:")));
       
   412     LOG(Log::HexDump(NULL, NULL, aDescriptor.iSubjectKeyId.Ptr(), len));
       
   413     }
       
   414 
       
   415     
       
   416 void CPKIMapper::DeleteMapping(TInt aIndex)
       
   417     {
       
   418     // Delete mapping at index
       
   419     LOG(Log::Printf(_L("Delete mapping entry")));
       
   420     LogMap(*(*iMapping)[aIndex]);
       
   421     delete (*iMapping)[aIndex]; 
       
   422     iMapping->Remove(aIndex);
       
   423     iMapping->Compress();
       
   424     }
       
   425 
       
   426 TInt CPKIMapper::DeleteMapping(CMapDescriptor &aDesc)
       
   427     {
       
   428     TInt status(KErrNotFound);
       
   429     
       
   430     for(TInt i(0); i < iMapping->Count(); i++)
       
   431         {
       
   432         if((*iMapping)[i]->IsEqual(aDesc))
       
   433             {
       
   434             DeleteMapping(i);
       
   435             status = KErrNone;
       
   436             break;
       
   437             }
       
   438         }
       
   439     return status;
       
   440     }
       
   441 
       
   442 TInt CPKIMapper::CertCount()
       
   443     {
       
   444     TInt count(0);    
       
   445     
       
   446     for(TInt i(0); i < iMapping->Count(); i++)
       
   447         {
       
   448         CMapDescriptor* mapping = (*iMapping)[i];
       
   449         count++;
       
   450         if (CertValidity(mapping->iStartTime, mapping->iEndTime) == EExpired)
       
   451             {
       
   452             // do not count expider certificates
       
   453             count--;
       
   454             }                
       
   455         }
       
   456     iCount = count;
       
   457     return count;            
       
   458     }
       
   459 
       
   460 TInt CPKIMapper::ApplicableCertCount(const RArray<TUid>& aUidArray)
       
   461 {
       
   462     TInt count(0);
       
   463     TBool uidMatch(EFalse);
       
   464     
       
   465     for(TInt i(0); i < iMapping->Count(); i++)
       
   466         {
       
   467         CMapDescriptor* mapping = (*iMapping)[i];
       
   468         if(mapping->iOwnerType == EPKICACertificate)
       
   469             {
       
   470             if(CertValidity(mapping->iStartTime, mapping->iEndTime) != EExpired)
       
   471                 {
       
   472                 uidMatch = EFalse;
       
   473                 for(TInt j = 0; j < mapping->iApplUids.Count(); j++)
       
   474                     {
       
   475                     for(TInt k = 0; k < aUidArray.Count(); k++)
       
   476                         {
       
   477                         if(mapping->iApplUids[j].iUid == aUidArray[k].iUid)
       
   478                             {
       
   479                             uidMatch = ETrue;
       
   480                             break;
       
   481                             }
       
   482                         }
       
   483                     if(uidMatch)
       
   484                         {
       
   485                         count++;
       
   486                         break;
       
   487                         }
       
   488                     }
       
   489                 }
       
   490             }
       
   491         }
       
   492     iCount = count;
       
   493     return count;
       
   494 }
       
   495 
       
   496 
       
   497 TInt CPKIMapper::GetCertListL(const RMessage2 &aMessage, TPkiServiceStoreType aStoreType, 
       
   498                               TBool aDescUsed)
       
   499 {
       
   500     TInt pos = 0;
       
   501     TInt iLast = 0;
       
   502     TInt iFirst = 0;
       
   503 
       
   504     if(aDescUsed)
       
   505         {
       
   506         aMessage.ReadL(1, iCurrentDescriptor);
       
   507         TSecurityObjectDescriptor& secDesc = iCurrentDescriptor();
       
   508         TInt status = ResolveCertMappingL(
       
   509             iCurrentDescriptor(), iObjectName, iFirst, EFalse, aStoreType);
       
   510         if(status == KErrNone)
       
   511             {
       
   512             iCount = 1;
       
   513             iLast = iFirst + 1;
       
   514             }
       
   515         }
       
   516     else
       
   517         {
       
   518         iLast = iMapping->Count();
       
   519         }
       
   520     
       
   521     CBufFlat* list = CBufFlat::NewL(sizeof(TCertificateListEntry));
       
   522     CleanupStack::PushL(list);
       
   523     list->ResizeL(iCount * sizeof(TCertificateListEntry));
       
   524     TCertificateListEntry certInfo;
       
   525     
       
   526     for(TInt i = iFirst; i < iLast; i++)
       
   527         {
       
   528         CMapDescriptor* mapping = (*iMapping)[i];
       
   529         if(CertValidity(mapping->iStartTime, mapping->iEndTime) != EExpired)
       
   530             {
       
   531             certInfo.iObjectName = mapping->iObjectName;
       
   532             certInfo.iOwnerType = mapping->iOwnerType;
       
   533             if(mapping->iTrustedAuthority != NULL)
       
   534                 {
       
   535                 certInfo.iTrustedAuthority = *(mapping->iTrustedAuthority);
       
   536                 }
       
   537             if(mapping->iIdentitySubjectName != NULL)
       
   538                 {
       
   539                 certInfo.iIdentitySubjectName = *(mapping->iIdentitySubjectName);
       
   540                 }
       
   541             if(mapping->iSerialNumber != NULL)
       
   542                 {
       
   543                 certInfo.iSerialNumber = *(mapping->iSerialNumber);
       
   544                 }
       
   545             certInfo.iSubjectKeyId = mapping->iSubjectKeyId;
       
   546             certInfo.iKeySize = mapping->iKeySize;                   // Key size
       
   547             certInfo.iKeyAlgorithm = mapping->iKeyAlgorithm;         // RSA, DSA
       
   548             certInfo.iIsDeletable = mapping->iIsDeletable;           // IsDeletable
       
   549 
       
   550             list->Write(pos * sizeof(TCertificateListEntry),
       
   551                         (TAny*)&certInfo,
       
   552                         sizeof(TCertificateListEntry));
       
   553             pos++;
       
   554             if(pos >= iCount)
       
   555                 {
       
   556                 break;
       
   557                 }
       
   558             }            
       
   559         }
       
   560     TPtr8 ptrList = list->Ptr(0);
       
   561     aMessage.WriteL(0, ptrList);
       
   562 
       
   563     CleanupStack::PopAndDestroy(1); // list
       
   564     return KErrNone;
       
   565 }
       
   566 
       
   567 
       
   568 void CPKIMapper::GetApplicableCertListL(const RMessage2& aMessage, const RArray<TUid>& aUidArray)
       
   569 {
       
   570     TBool uidMatch = EFalse;
       
   571     TInt pos(0);
       
   572     
       
   573     CBufFlat* list = CBufFlat::NewL(sizeof(TCertificateListEntry));
       
   574     CleanupStack::PushL(list);
       
   575     list->ResizeL(iCount * sizeof(TCertificateListEntry));
       
   576     TCertificateListEntry certInfo;
       
   577 
       
   578     for(TInt i = 0; (i < iMapping->Count()) && (pos < iCount); i++)
       
   579         {
       
   580         CMapDescriptor* mapping = (*iMapping)[i];
       
   581         if(mapping->iOwnerType == EPKICACertificate)
       
   582             {
       
   583             if(CertValidity(mapping->iStartTime, mapping->iEndTime) != EExpired)
       
   584                 {
       
   585                 uidMatch = EFalse;
       
   586                 for(TInt j = 0; j < mapping->iApplUids.Count(); j++)
       
   587                     {
       
   588                     for(TInt k = 0; k < aUidArray.Count(); k++)
       
   589                         {
       
   590                         if(mapping->iApplUids[j].iUid == aUidArray[k].iUid)
       
   591                             {
       
   592                             uidMatch = ETrue;
       
   593                             break;
       
   594                             }
       
   595                         }
       
   596                     if(uidMatch)
       
   597                         {
       
   598                         certInfo.iObjectName = mapping->iObjectName;
       
   599                         certInfo.iOwnerType = mapping->iOwnerType;
       
   600                         if(mapping->iTrustedAuthority != NULL)
       
   601                             {
       
   602                             certInfo.iTrustedAuthority = *(mapping->iTrustedAuthority);
       
   603                             }
       
   604                         if(mapping->iIdentitySubjectName != NULL)
       
   605                             {
       
   606                             certInfo.iIdentitySubjectName = *(mapping->iIdentitySubjectName);
       
   607                             }
       
   608                         if(mapping->iSerialNumber != NULL)
       
   609                             {
       
   610                             certInfo.iSerialNumber = *(mapping->iSerialNumber);
       
   611                             }
       
   612                         certInfo.iSubjectKeyId = mapping->iSubjectKeyId;
       
   613                         certInfo.iKeySize = mapping->iKeySize;                   // Key size
       
   614                         certInfo.iKeyAlgorithm = mapping->iKeyAlgorithm;         // RSA, DSA
       
   615                         certInfo.iIsDeletable = mapping->iIsDeletable;           // IsDeletable
       
   616 
       
   617                         list->Write(pos * sizeof(TCertificateListEntry),
       
   618                                     (TAny*)&certInfo,
       
   619                                     sizeof(TCertificateListEntry));
       
   620                         pos++;
       
   621                         break;
       
   622                         }
       
   623                     }
       
   624                 }
       
   625             }
       
   626         }
       
   627     TPtr8 ptrList = list->Ptr(0);
       
   628     aMessage.WriteL(0, ptrList);
       
   629 
       
   630     CleanupStack::PopAndDestroy(1); // list
       
   631 }
       
   632 
       
   633 
       
   634 
       
   635 CMapDescriptor& CPKIMapper::GetMapDescriptorAtIndex(TInt aIndex)
       
   636 {
       
   637     PKISERVICE_ASSERT(aIndex < iMapping->Count());
       
   638     return *(*iMapping)[aIndex];
       
   639 }
       
   640 
       
   641 
       
   642 void CPKIMapper::GetCertificateKeyIdL(TSecurityObjectDescriptor &aDescriptor, TPKIKeyIdentifier &aKeyId,
       
   643                                       TPkiServiceStoreType aStoreType) const
       
   644     {
       
   645     LOG(Log::Printf(_L("-> CPKIMapper::GetCertificateKeyIdL"), aStoreType));
       
   646     aKeyId.Zero();
       
   647     
       
   648     TInt index;    
       
   649     
       
   650     TFileName* fileName = new (ELeave) TFileName;
       
   651     CleanupDeletePushL(fileName);
       
   652     fileName->Zero();
       
   653     
       
   654     TInt status = ResolveCertMappingL(aDescriptor, *fileName, index, EFalse, aStoreType);    
       
   655 
       
   656     CleanupStack::PopAndDestroy(fileName);
       
   657     
       
   658     
       
   659     if(status == KErrNone)
       
   660         {
       
   661         aKeyId.Copy((*iMapping)[index]->iSubjectKeyId);
       
   662         }
       
   663     else
       
   664         {
       
   665         LOG(Log::Printf(_L("ResolveKeyMapping: key NOT found\n")));
       
   666         LogSearchArguments(aDescriptor);
       
   667         }    
       
   668     LOG(Log::Printf(_L("<- CPKIMapper::GetCertificateKeyIdL"), aStoreType));        
       
   669     }
       
   670 
       
   671 /**
       
   672     Check whether the given label is unique among all VPN certs.
       
   673     @return True only if the given label doesn't exist
       
   674 */
       
   675 TBool CPKIMapper::LabelIsUnique(const TDesC& aLabel) const
       
   676     {
       
   677     for (TInt i(0); i < iMapping->Count(); i++) 
       
   678         {
       
   679         if ((*iMapping)[i]->iObjectName.Compare(aLabel) == 0) 
       
   680             {
       
   681             return EFalse;
       
   682             }
       
   683         }
       
   684     return ETrue;
       
   685     }
       
   686 
       
   687 /**
       
   688     Check whether the given certificate already exists among VPN certs.
       
   689     @return True only if the given certificate does not exist in VPN's cert list.
       
   690 */
       
   691 TBool CPKIMapper::CertificateIsUniqueL(const TDesC8& aCertData)
       
   692     {
       
   693     TBool ret(ETrue);
       
   694     
       
   695     LOG(Log::Printf(_L("Verifying the uniqueness of certificate:")));
       
   696 
       
   697     CX509Certificate* certificate = CX509Certificate::NewLC(aCertData);
       
   698     const TPtrC8* issuername = certificate->DataElementEncoding(CX509Certificate::EIssuerName);
       
   699     const TPtrC8* subjectname = certificate->DataElementEncoding(CX509Certificate::ESubjectName);
       
   700     
       
   701     HBufC* issuerdispname = certificate->IssuerName().DisplayNameL();
       
   702     CleanupStack::PushL(issuerdispname);
       
   703     HBufC* subjectdispname = certificate->SubjectName().DisplayNameL();
       
   704     CleanupStack::PushL(subjectdispname);
       
   705     
       
   706     TInt count(iMapping->Count());
       
   707 
       
   708     for (TInt i(0); i < count; i++) 
       
   709         {
       
   710         CMapDescriptor* mapitem = (*iMapping)[i];
       
   711 
       
   712         //  Use subject name for uniqueness criterion
       
   713         if (mapitem->iIdentitySubjectName)
       
   714             {
       
   715             if (subjectname->Compare(*(mapitem->iIdentitySubjectName)) == 0) 
       
   716                 {
       
   717                 LOG(Log::Printf(_L("Found an existing cert that matches subject")));
       
   718                 if (issuername->Compare(*(mapitem->iTrustedAuthority)) == 0) 
       
   719                     {
       
   720                     ret = EFalse;
       
   721                     break;
       
   722                     }
       
   723                 }
       
   724             }
       
   725         else if (mapitem->iTrustedAuthority && (subjectname->Compare(*issuername) == 0))
       
   726             {
       
   727             if (subjectname->Compare(*(mapitem->iTrustedAuthority)) == 0) 
       
   728                 {
       
   729                 LOG(Log::Printf(_L("Found an existing cert that matches subject (CA)")));
       
   730                 ret = EFalse;
       
   731                 break;
       
   732                 }
       
   733             }
       
   734         }
       
   735 
       
   736     CleanupStack::PopAndDestroy(3, certificate); // issuerdispname, subjectdispname
       
   737 
       
   738     return ret;
       
   739     }
       
   740     
       
   741 /**
       
   742     Generates an unique label name for a certificate, based on its subject name.
       
   743     @param1 The binary data describing the certificate
       
   744     @param2 Return value for the generated unique name
       
   745     @param3 Certificate owner type -- currently not supported.
       
   746     @return none
       
   747 */
       
   748 void CPKIMapper::GenerateUniqueNameL(
       
   749     const TDesC8 &aCertData, TDes& aName, 
       
   750     TCertificateOwnerType /*aOwnerType*/ )
       
   751     {
       
   752     LOG(Log::Printf(_L("CPKIMapper::GenerateUniqueNameL() entry")));
       
   753 
       
   754     CX509Certificate* certificate = CX509Certificate::NewLC(aCertData);
       
   755 
       
   756     HBufC* baseline = certificate->SubjectName().DisplayNameL();
       
   757     CleanupStack::PushL(baseline);
       
   758     // +5 for (999) suffix
       
   759     HBufC* variation = HBufC::NewLC(baseline->Length() + 5);
       
   760     variation->Des().Append(*baseline);
       
   761     
       
   762     if (baseline->Length() == 0)
       
   763         {
       
   764         TPtr ptr = variation->Des();
       
   765         ptr.Format(_L("(1)"));
       
   766         }
       
   767 
       
   768     // See whether the initial label is already unique    
       
   769     TInt iter(2);
       
   770     while (!LabelIsUnique(*variation)) 
       
   771         {
       
   772         // Iterate a new version of the label
       
   773         if (iter > 999) 
       
   774             {
       
   775             // too long name, just go with the previous.
       
   776             break;
       
   777             }
       
   778         TPtr ptr = variation->Des();
       
   779         ptr.Format(_L("%S(%d)"), &(*baseline), iter);
       
   780         iter++;
       
   781         }
       
   782 
       
   783     // Sanity check for string lengths
       
   784     aName = variation->Left(MAX_FILENAME_LENGTH);
       
   785 
       
   786     CleanupStack::PopAndDestroy(3); //variation, baseline, certificate
       
   787 
       
   788     LOG(Log::Printf(_L("CPKIMapper::GenerateUniqueNameL() exit")));
       
   789     }
       
   790 
       
   791 TInt CPKIMapper::ResolveCertMappingL(TSecurityObjectDescriptor &aDescriptor, TDes16 &aFilename, 
       
   792                                      TInt &aIndex, const TBool aInfoOnly, 
       
   793                                      TPkiServiceStoreType aStoreType) const   
       
   794     {
       
   795     TInt i;
       
   796     TInt status = KErrNotFound;
       
   797     TInt foundIndex = -1;
       
   798     TTime furthestEndTime = TTime(0);
       
   799 
       
   800     LOG(Log::Printf(_L("Resolving cert mapping, STORETYPE: %d\n"), aStoreType));
       
   801 
       
   802     LOG(LogSearchArguments(aDescriptor));
       
   803 
       
   804     // Scan available mappings
       
   805     for(i = 0; i < iMapping->Count(); i++)
       
   806         {
       
   807         // Bypass entry in case that function leaves
       
   808         // (issuer/subject name can be invalid)
       
   809         CMapDescriptor* mapping = (*iMapping)[i];
       
   810         if(mapping->IsMatchingL(aDescriptor, aInfoOnly, aStoreType))
       
   811             {
       
   812             // If we found a match, process it further
       
   813             _LIT(KMidp2Label, "MIDP2");
       
   814             TBuf<12> buf;
       
   815             buf.Append(KMidp2Label);
       
   816             // Discard all MIDP2 certificates to avoid label-mapping problem
       
   817             if (buf.Compare(mapping->iObjectName) != 0)
       
   818                 {
       
   819                 if(mapping->iEndTime > furthestEndTime)
       
   820                     {
       
   821                     furthestEndTime = mapping->iEndTime;
       
   822                     foundIndex = i;
       
   823                     LOG(Log::Printf(_L("Resolve cert mapping: Tentatively found a suitable one")));
       
   824                     // Continue to search the longest lasting certificate
       
   825                     }
       
   826                 }
       
   827             else 
       
   828                 {
       
   829                 LOG(Log::Printf(_L("Found a cert, but it was a MIDP2 one - continuing search")));
       
   830                 }
       
   831             }
       
   832         }
       
   833     
       
   834     if(foundIndex == -1)
       
   835         {
       
   836         LOG(Log::Printf(_L("Resolve cert mapping: No matching certificate found")));       
       
   837         status = KErrNotFound;
       
   838         }
       
   839     else
       
   840         {
       
   841         aFilename.Zero();
       
   842         status = KErrNone;
       
   843         if(status == KErrNone)
       
   844             {
       
   845             aFilename.Append((*iMapping)[foundIndex]->iObjectName);
       
   846             status = KErrNone;
       
   847             aIndex = foundIndex;
       
   848             }
       
   849         LOG(Log::Printf(_L("ResolveCertMapping: certificate found\n")));
       
   850         LogSearchArguments(aDescriptor);
       
   851         LOG(Log::Printf(_L("ResolveCertMapping: Object info\n")));
       
   852         LogMap(*(*iMapping)[aIndex]);
       
   853         }
       
   854     return status;
       
   855     }    
       
   856   
       
   857 
       
   858 TValidity CPKIMapper::CertValidity(const TTime &aStartTime,  const TTime &aEndTime) 
       
   859     {
       
   860     TTimeIntervalSeconds tolerance(120); 
       
   861     TTime currentTime;
       
   862     currentTime.UniversalTime();
       
   863 
       
   864     if (aEndTime <= currentTime)
       
   865         {
       
   866         return EExpired;
       
   867         }
       
   868 
       
   869     if (aStartTime >= currentTime + tolerance)
       
   870         {
       
   871         return ENotValidYet;
       
   872         }
       
   873 
       
   874     return EValid;
       
   875     }
       
   876 
       
   877 void CPKIMapper::LogSearchArguments(TSecurityObjectDescriptor &aDescriptor) const
       
   878     {
       
   879     TBuf<256> temp;
       
   880     LOG(Log::Printf(_L("====Object Search arguments====\n")));
       
   881     if(aDescriptor.iTrustedAuthorityUsed)
       
   882         {
       
   883         temp.Copy(aDescriptor.iTrustedAuthority);
       
   884         if((aDescriptor.iTrustedAuthority[0] != 0x30)
       
   885            || ((aDescriptor.iTrustedAuthority[1] != 0x81)
       
   886                && (aDescriptor.iTrustedAuthority[1] != 0x82)
       
   887                && ((aDescriptor.iTrustedAuthority[1] + 2) != aDescriptor.iTrustedAuthority.Length())))
       
   888             {
       
   889             LOG(Log::Printf(_L("Trusted authority: %S\n"), &temp));
       
   890             }
       
   891         else
       
   892             {
       
   893             LOG(Log::Printf(_L("Trusted authority:")));
       
   894             LOG(Log::HexDump(NULL, NULL, aDescriptor.iTrustedAuthority.Ptr(), aDescriptor.iTrustedAuthority.Length()));
       
   895             }
       
   896         }
       
   897     if(aDescriptor.iIdentitySubjectNameUsed)
       
   898         {
       
   899         temp.Copy(aDescriptor.iIdentitySubjectName);
       
   900         if((aDescriptor.iIdentitySubjectName[0] != 0x30)
       
   901            || ((aDescriptor.iIdentitySubjectName[1] != 0x81)
       
   902                && (aDescriptor.iIdentitySubjectName[1] != 0x82)
       
   903                && ((aDescriptor.iIdentitySubjectName[1] + 2) != aDescriptor.iIdentitySubjectName.Length())))
       
   904             {
       
   905             LOG(Log::Printf(_L("SubjectName: %S\n"), &temp));
       
   906             }
       
   907         else
       
   908             {
       
   909             LOG(Log::Printf(_L("SubjectName:")));
       
   910             LOG(Log::HexDump(NULL, NULL, aDescriptor.iIdentitySubjectName.Ptr(), aDescriptor.iIdentitySubjectName.Length()));
       
   911             }
       
   912         }
       
   913     if(aDescriptor.iIdentityRfc822NameUsed)
       
   914         {
       
   915         temp.Copy(aDescriptor.iIdentityRfc822Name);
       
   916         LOG(Log::Printf(_L("Rfc822Name: %S\n"), &temp));
       
   917         }
       
   918     if(aDescriptor.iSerialNumberUsed)
       
   919         {
       
   920         LOG(Log::Printf(_L("SerialNumber:")));
       
   921         LOG(Log::HexDump(NULL, NULL, aDescriptor.iSerialNumber.Ptr(), aDescriptor.iSerialNumber.Length()));
       
   922         }
       
   923     if(aDescriptor.iSubjectKeyIdUsed)
       
   924         {
       
   925         LOG(Log::Printf(_L("KeyId:")));
       
   926         LOG(Log::HexDump(NULL, NULL, aDescriptor.iSubjectKeyId.Ptr(), aDescriptor.iSubjectKeyId.Length()));
       
   927         }
       
   928     if(aDescriptor.iOwnerTypeUsed)
       
   929         {
       
   930         LOG(Log::Printf(_L("OwnerType: %d\n"), aDescriptor.iOwnerType));
       
   931         }
       
   932     if(aDescriptor.iKeyUsageUsed)
       
   933         {
       
   934         LOG(Log::Printf(_L("KeyUsage:")));
       
   935         LOG(Log::HexDump(NULL, NULL, aDescriptor.iKeyUsageDer.Ptr(), aDescriptor.iKeyUsageDer.Length()));
       
   936         }
       
   937     if(aDescriptor.iKeySizeUsed)
       
   938         {
       
   939         LOG(Log::Printf(_L("KeySize: %d\n"), aDescriptor.iKeySize));
       
   940         }
       
   941     if(aDescriptor.iKeyAlgorithmUsed)
       
   942         {
       
   943         LOG(Log::Printf(_L("KeyAlgorithm: %d\n"), aDescriptor.iKeyAlgorithm));
       
   944         }
       
   945     }   
       
   946 
       
   947 TBool PkiUtil::MatchL(const CX500DistinguishedName& aDn1, const CX500DistinguishedName& aDn2)
       
   948 {
       
   949     if((aDn1.Count() == 0) || (aDn2.Count() == 0))
       
   950         {
       
   951         return EFalse;
       
   952         }
       
   953     
       
   954     if (aDn1.Count() < aDn2.Count())
       
   955         {
       
   956         return EFalse;
       
   957         }
       
   958     else
       
   959         {
       
   960         // For each field in aDn2, aDn1 must contain a field with the same value
       
   961         for (TInt i = 0; i < aDn2.Count(); i++)
       
   962             {
       
   963             if (!HasElementL(aDn1, aDn2.Element(i)))
       
   964                 {
       
   965                 return EFalse;
       
   966                 }
       
   967             }
       
   968         }
       
   969 
       
   970     return ETrue;
       
   971 }
       
   972 
       
   973 TBool PkiUtil::HasElementL(const CX500DistinguishedName& aDn, const CX520AttributeTypeAndValue& aElement)
       
   974 {
       
   975     for (TInt i = 0; i < aDn.Count(); i++)
       
   976         {
       
   977         if (aElement.ExactMatchL(aDn.Element(i)))
       
   978             {
       
   979             return ETrue;
       
   980             }
       
   981         }
       
   982     return EFalse;
       
   983 }
       
   984