vpnengine/ikecert/src/ikev1pkiservice.cpp
changeset 0 33413c0669b9
child 25 735de8341ce4
equal deleted inserted replaced
-1:000000000000 0:33413c0669b9
       
     1 /*
       
     2 * Copyright (c) 2005-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:   PKI store and Certificate verification interface class
       
    15 *                implementation for IKEv1 plug-in
       
    16 *
       
    17 */
       
    18 
       
    19 #include <x500dn.h>
       
    20 #include <x509cert.h>
       
    21 #include <asn1dec.h>
       
    22 #include <utf.h>
       
    23 
       
    24 #include "ikedebug.h"
       
    25 #include "ikev1pkiservice.h"
       
    26 #include "utlcrypto.h"
       
    27 #include "ikecert.h"
       
    28 #include "ikecaelem.h"
       
    29 #include "ikepublickey.h"
       
    30 #include "ikecalist.h"
       
    31 #include "ikepkiutils.h"
       
    32 #include "pkcs10.h"
       
    33 #include "vpnapidefs.h"
       
    34 #include "pkiutil.h"
       
    35 #include "ikecertconst.h"
       
    36 
       
    37 //
       
    38 // CIkeV1PkiService Class
       
    39 //
       
    40 _LIT8(KEmptyString, "");
       
    41 
       
    42 
       
    43 EXPORT_C CIkeV1PkiService* CIkeV1PkiService::NewL(
       
    44     CIkeData*             aIkeData,
       
    45     MIkeDebug&            aDebug
       
    46 )
       
    47 {
       
    48     CIkeV1PkiService* self =
       
    49         new (ELeave) CIkeV1PkiService(aIkeData, aDebug);
       
    50 
       
    51     CleanupStack::PushL(self);
       
    52     self->ConstructL();
       
    53     CleanupStack::Pop(self);
       
    54     return self;
       
    55 }
       
    56 
       
    57 
       
    58 CIkeV1PkiService::CIkeV1PkiService(
       
    59     CIkeData*            aIkeData,
       
    60     MIkeDebug&           aDebug
       
    61 ) :
       
    62     iOperation(KNoOperation),
       
    63     iIkeData(aIkeData),
       
    64     iCertPtr(NULL, 0),
       
    65     iCertBfrSize(2048),
       
    66     iDebug(aDebug)
       
    67 {
       
    68 }
       
    69 
       
    70 
       
    71 void CIkeV1PkiService::ConstructL()
       
    72 {
       
    73     User::LeaveIfError(iPkiService.Connect());
       
    74     
       
    75     // Set certificate store type to device certificate store,
       
    76     // if Own_cert_type is defined as "DEVICE"
       
    77     if ( iIkeData->iClientCertType != NULL )
       
    78     {
       
    79         TPtrC16 certStoreType = iIkeData->iClientCertType->GetData();
       
    80         if ( certStoreType.CompareF(_L("DEVICE")) == 0 )
       
    81         {
       
    82 			User::LeaveIfError(iPkiService.SetStoreType(EPkiStoreTypeDevice));            
       
    83         }
       
    84         else
       
    85         {
       
    86 			User::LeaveIfError(iPkiService.SetStoreType(EPkiStoreTypeUser));                    
       
    87         }
       
    88     }
       
    89 
       
    90     iTrustedCAList   = new (ELeave) CIkeCaList(2);
       
    91     iReadCertificate = HBufC8::NewL(iCertBfrSize);
       
    92     
       
    93 
       
    94     //The code assumes that these are not NULL.
       
    95     //Reallocated, when needed
       
    96     iSubjName = HBufC8::NewL(2);
       
    97     iRfc822Name = HBufC8::NewL(2);
       
    98 }
       
    99 
       
   100 
       
   101 EXPORT_C CIkeV1PkiService::~CIkeV1PkiService()
       
   102 {
       
   103     if ( iApplUidList )
       
   104     {
       
   105         iApplUidList->Reset();
       
   106         delete iApplUidList;
       
   107     }
       
   108     
       
   109     if ( iCaCertList )
       
   110     {
       
   111         iCaCertList->Reset();
       
   112         delete iCaCertList;
       
   113     }
       
   114 
       
   115     delete iTrustedCAList;
       
   116 
       
   117     iCasTrustedByPeer.Reset();
       
   118     iCasTrustedByPeer.Close();
       
   119 
       
   120     delete iCaName;
       
   121     delete iCa1Name;
       
   122     delete iCa2Name;
       
   123    
       
   124     delete iReadCertificate;
       
   125     delete iSubjName;
       
   126     delete iRfc822Name;
       
   127 
       
   128     
       
   129     iPkiService.Close();
       
   130 }
       
   131 
       
   132 
       
   133 EXPORT_C TBool CIkeV1PkiService::ImportCACertsL(
       
   134     CArrayFixFlat<TCertInfo*> *aCAList
       
   135 )
       
   136 {
       
   137     DEBUG_LOG(_L("-> CIkeV1PkiService::ImportCACertsL"));
       
   138 
       
   139     //
       
   140     // Build trusted CA certificate list into CIkeV1PkiService object
       
   141     // aCAList call parameter array contains the list of trusted CA:s
       
   142     // (names in ASCII format).
       
   143     // Read corresponding certificate from PKI store and if found,
       
   144     // add a new element (=CIkeCaElem) into CIkeCaList
       
   145     //
       
   146     TBool Status = EFalse;
       
   147 
       
   148     if ( aCAList && aCAList->Count() )
       
   149     {
       
   150         delete iCaName;
       
   151 
       
   152         iCaName     = NULL;
       
   153         iCaName     = HBufC8::NewL(256);
       
   154         iCaNameList = aCAList;
       
   155         iCurrIndex  = 0;
       
   156         iOperation  = KBuildingCaList;
       
   157 
       
   158         Status = GetNextCaElemL();
       
   159     }
       
   160 
       
   161     return Status;
       
   162 }
       
   163 
       
   164 
       
   165 //
       
   166 // CIkeV1PkiService::ReadCertWithNameL
       
   167 // This method is used to read a certificate from the PKI store.
       
   168 // Input parameters:
       
   169 // -- const TDesC8& Trusted CA name
       
   170 // -- TBool  aGetCACert
       
   171 //    ETrue = Read a CA certificate; EFalse read an user certificate
       
   172 // Output parameters:
       
   173 // -- X509 certificate into iReadCertificate buffer
       
   174 //
       
   175 EXPORT_C TInt CIkeV1PkiService::ReadUserCertWithNameL(
       
   176     const TDesC8& aTrustedCaName, CIkeData* aIkeData, TBool aDnType)
       
   177 
       
   178 {
       
   179     iIkeData = aIkeData;
       
   180     
       
   181     delete iCaName;
       
   182     iCaName = NULL;
       
   183     iCaName = HBufC8::NewL(aTrustedCaName.Length());
       
   184     iCaName->Des().Copy(aTrustedCaName);
       
   185     
       
   186     delete iReadCertificate;
       
   187     iReadCertificate=NULL;
       
   188     
       
   189     TInt Status = ReadCertificateL(*iCaName, EFalse);
       
   190 
       
   191     iUserCertDerType=aDnType;
       
   192     return Status;
       
   193 }
       
   194 EXPORT_C TInt CIkeV1PkiService::ReadChainL(CIkeData* aIkeData, const HBufC8* aCAName)
       
   195 {
       
   196     iIkeData = aIkeData;
       
   197     delete iReadCertificate;
       
   198     iReadCertificate=NULL;
       
   199     //read own certificate
       
   200     TInt Status = ReadCertificateL(KEmptyString, EFalse);
       
   201     TInt StatusICA1 = KErrNotFound;
       
   202     TInt StatusICA2 = KErrNotFound;
       
   203     TInt StatusICA = KErrNotFound;
       
   204        
       
   205     if ( Status == KErrNone )
       
   206         {
       
   207         iReadCertificateOrig = HBufC8::NewL(iReadCertificate->Length());
       
   208         TPtr8 iReadCertCopy(iReadCertificateOrig->Des());
       
   209         iReadCertCopy.Copy(iReadCertificate->Des());
       
   210         delete iCaName;
       
   211         iCaName = NULL;
       
   212         iCaName =  IkeCert::GetCertificateFieldDERL(iReadCertificate, KIssuerName);
       
   213         
       
   214         //Read ICA2
       
   215         StatusICA2 = ReadCertificateL(KEmptyString, ETrue);
       
   216        
       
   217         if ( StatusICA2 != KErrNone)
       
   218             {
       
   219             delete iReadCertificateOrig;
       
   220             iReadCertificateOrig=NULL;
       
   221             return KErrNotFound;
       
   222             }
       
   223         }
       
   224     if ( Status == KErrNone && StatusICA2 == KErrNone)
       
   225         {
       
   226         
       
   227         delete iCaName;
       
   228         iCaName = NULL;
       
   229         iCaName =  IkeCert::GetCertificateFieldDERL(iReadCertificate, KIssuerName);
       
   230         delete iCa2Name;
       
   231         iCa2Name=NULL;
       
   232         iCa2Name = GetCertificate();
       
   233         
       
   234         CX500DistinguishedName* dn=NULL;
       
   235         CX500DistinguishedName* asn1DnNameofICaName = NULL;
       
   236         dn = CX500DistinguishedName::NewLC(*aCAName);
       
   237         asn1DnNameofICaName = CX500DistinguishedName::NewLC(*iCaName);
       
   238                
       
   239         if (  asn1DnNameofICaName->ExactMatchL(*dn)  )
       
   240             
       
   241             {
       
   242              StatusICA=KErrNone;
       
   243              //read ICA1
       
   244              StatusICA1 = ReadCertificateL(KEmptyString, ETrue);
       
   245              if ( StatusICA1 != KErrNone)
       
   246                  {
       
   247                  delete iReadCertificateOrig;
       
   248                  iReadCertificateOrig=NULL;
       
   249                  
       
   250                  CleanupStack::PopAndDestroy(asn1DnNameofICaName);
       
   251                  asn1DnNameofICaName=NULL;
       
   252                  
       
   253                  CleanupStack::PopAndDestroy(dn);
       
   254                  dn=NULL;
       
   255                  
       
   256                  return KErrNotFound;
       
   257                  }
       
   258             }
       
   259         else
       
   260             {
       
   261             StatusICA1 = ReadCertificateL(KEmptyString, ETrue);
       
   262             if ( StatusICA1 == KErrNotFound)
       
   263                 {
       
   264                 delete iReadCertificateOrig;
       
   265                 iReadCertificateOrig=NULL;
       
   266                              
       
   267                 CleanupStack::PopAndDestroy(asn1DnNameofICaName);
       
   268                 asn1DnNameofICaName=NULL;
       
   269 
       
   270                 CleanupStack::PopAndDestroy(dn);
       
   271                 dn=NULL;
       
   272             
       
   273                 return KVpnErrInvalidCaCertFile;
       
   274                 }
       
   275             else
       
   276 	            StatusICA1=KErrNone;
       
   277             }
       
   278         CleanupStack::PopAndDestroy(asn1DnNameofICaName);
       
   279         asn1DnNameofICaName=NULL;
       
   280         
       
   281         CleanupStack::PopAndDestroy(dn);
       
   282         dn=NULL;
       
   283        
       
   284         }
       
   285  
       
   286     if ( Status == KErrNone && StatusICA1 == KErrNone && StatusICA2 == KErrNone)
       
   287         {
       
   288         if ( StatusICA == KErrNotFound )
       
   289            {
       
   290            delete iCaName;
       
   291            iCaName = NULL;
       
   292            iCaName =  IkeCert::GetCertificateFieldDERL(iReadCertificate, KIssuerName);
       
   293            }
       
   294         delete iCa1Name;
       
   295         iCa1Name=NULL;
       
   296         iCa1Name = GetCertificate();
       
   297         
       
   298         CX500DistinguishedName* dn=NULL;
       
   299         CX500DistinguishedName* asn1DnNameofICaName = NULL;
       
   300         
       
   301         dn = CX500DistinguishedName::NewLC(*aCAName);
       
   302         
       
   303         asn1DnNameofICaName = CX500DistinguishedName::NewLC(*iCaName);
       
   304         
       
   305         if ( asn1DnNameofICaName->ExactMatchL(*dn) )
       
   306            {
       
   307            delete iCaName;
       
   308            iCaName=NULL;
       
   309            iCaName=HBufC8::NewL(aCAName->Length());
       
   310            iCaName->Des().Copy(*aCAName);
       
   311            
       
   312            TInt Status = ReadCertificateL(KEmptyString, ETrue);
       
   313            
       
   314            delete iCaName;
       
   315            iCaName = NULL;
       
   316            iCaName =  IkeCert::GetCertificateFieldDERL(iCa2Name, KSubjectName);
       
   317            
       
   318            delete iReadCertificate;
       
   319            iReadCertificate=iReadCertificateOrig;
       
   320            iReadCertificateOrig=NULL;
       
   321            
       
   322            CleanupStack::PopAndDestroy(asn1DnNameofICaName);
       
   323            asn1DnNameofICaName=NULL;
       
   324            
       
   325            CleanupStack::PopAndDestroy(dn);
       
   326            dn=NULL;
       
   327           
       
   328            if ( Status!=KErrNone )
       
   329                return KVpnErrInvalidCaCertFile;
       
   330            else    
       
   331 	           return KErrNone;
       
   332            }
       
   333         else
       
   334            {
       
   335            delete iReadCertificate;
       
   336            
       
   337            iReadCertificate=iReadCertificateOrig;
       
   338            iReadCertificateOrig=NULL;
       
   339            delete iReadCertificateOrig; 
       
   340            
       
   341            delete iReadCertificate;
       
   342            iReadCertificate=NULL;
       
   343            
       
   344            CleanupStack::PopAndDestroy(asn1DnNameofICaName);
       
   345            asn1DnNameofICaName=NULL;
       
   346            
       
   347            CleanupStack::PopAndDestroy(dn);
       
   348            dn=NULL;
       
   349            
       
   350            return KErrNotFound;
       
   351            }
       
   352         }
       
   353      return KErrNotFound;
       
   354 }
       
   355 
       
   356 //
       
   357 // CIkeV1PkiService::Ikev1SignatureL
       
   358 // This method is used to compute IKEv1 signature with a specified private key.
       
   359 // Actually a signature computed happens by referring the related certificate
       
   360 // when the PKI store produces the signature with corresponding private key.
       
   361 // Parameters:
       
   362 // -- const TDesC8& aTrustedAuthority
       
   363 //    Trusted CA name coded either in ASN1 (DN) format or ASCII format
       
   364 // -- CIkeData* aHostData
       
   365 //    Related IKE configuration section. Used to get IdentitySubjectName or
       
   366 //    Identity Rfc822 Name information for actual PKI service ReadCertificateL
       
   367 //    method call
       
   368 // -- const TDesC8& aHashIn
       
   369 //    Hash data signed (in matter of fact the hash data is simply
       
   370 //    encrypted with private key)
       
   371 // Return:
       
   372 // -- TInt, sign length
       
   373 //
       
   374 EXPORT_C TInt CIkeV1PkiService::Ikev1SignatureL(
       
   375     const TDesC8&  aTrustedCaName,
       
   376     CIkeData*      aIkeData,
       
   377     const TDesC8&  aHashIn,
       
   378     TDes8&         aSignature
       
   379 )
       
   380 {
       
   381     iIkeData = aIkeData;
       
   382     return ComputeSignatureL(aTrustedCaName, aHashIn, aSignature, EFalse);
       
   383 }
       
   384 
       
   385 
       
   386 EXPORT_C CIkeCaList* CIkeV1PkiService::CaList()
       
   387 {
       
   388     return iTrustedCAList;
       
   389 }
       
   390 
       
   391 
       
   392 EXPORT_C HBufC8* CIkeV1PkiService::GetCertificate()
       
   393 {
       
   394     HBufC8* Cert = iReadCertificate;
       
   395     iReadCertificate = NULL;
       
   396     return Cert;
       
   397 }
       
   398 
       
   399 
       
   400 EXPORT_C HBufC8* CIkeV1PkiService::GetTrustedCA()
       
   401 {
       
   402     HBufC8* Cert = iCaName;
       
   403     iCaName = NULL;
       
   404     return Cert;
       
   405 }
       
   406 
       
   407 
       
   408 EXPORT_C HBufC8* CIkeV1PkiService::GetTrustedICA1()
       
   409 {
       
   410     HBufC8* Cert = iCa1Name;
       
   411     iCa1Name = NULL;
       
   412     return Cert;
       
   413 }
       
   414 
       
   415 EXPORT_C HBufC8* CIkeV1PkiService::GetTrustedICA2()
       
   416 {
       
   417     HBufC8* Cert = iCa2Name;
       
   418     iCa2Name = NULL;
       
   419     return Cert;
       
   420 }
       
   421 
       
   422 TInt CIkeV1PkiService::ComputeSignatureL(
       
   423     const TDesC8&  aTrustedAuthority,
       
   424     const TDesC8&  aHashIn,
       
   425     TDes8&         aSignature,
       
   426     TBool          aRsaSignature
       
   427 )
       
   428 {
       
   429     DEBUG_LOG(_L("-> CIkeV1PkiService::ComputeSignatureL"));
       
   430 
       
   431     TPKIKeyAlgorithm keyAlgorithm = EPKIRSA;
       
   432     TUint keySize = InitUserCertIdentDataL();
       
   433     HBufC8* Asn1EncodedHash = NULL;
       
   434     TPtrC8 hashIn(aHashIn);
       
   435 
       
   436     if ( aRsaSignature )
       
   437     {
       
   438         //
       
   439         // Build PKCS1v15 format signature (ASN1 encoded)
       
   440         //
       
   441         Asn1EncodedHash = IkeCert::BuildPkcs1v15HashL(aHashIn);
       
   442         
       
   443         ASSERT( Asn1EncodedHash != NULL );        
       
   444         hashIn.Set(Asn1EncodedHash->Des());
       
   445     }
       
   446 
       
   447     TInt SignLth = 0;
       
   448     TInt err = iPkiService.Sign(aTrustedAuthority, *iSubjName, *iRfc822Name,
       
   449                                 EX509DigitalSignature, keySize,
       
   450                                 keyAlgorithm, hashIn, aSignature);
       
   451 
       
   452     if (err == KErrNone)
       
   453     {
       
   454         SignLth = aSignature.Length();
       
   455     }
       
   456 
       
   457     DEBUG_LOG2(_L("Sign returned %d, length=%d"), err, SignLth);
       
   458     User::LeaveIfError(err);
       
   459 
       
   460     delete Asn1EncodedHash;
       
   461     return SignLth;
       
   462 }
       
   463 
       
   464 
       
   465 TInt CIkeV1PkiService::ReadCertificateL(
       
   466     const TDesC8& aTrustedAuthority, TBool aGetCACert
       
   467 )
       
   468 {
       
   469     //
       
   470     // Read certificate from PKI store using pkiserviceapi
       
   471     //
       
   472     DEBUG_LOG(
       
   473         _L("-> ReadCertificateL(aTrustedAuthority, aGetCACert)")
       
   474     );
       
   475 
       
   476     TInt Status = KErrNone;
       
   477     TPKIKeyAlgorithm keyAlgorithm = EPKIRSA;
       
   478     TPKICertificateOwnerType ownerType;
       
   479     TUint keySize = 0;
       
   480 
       
   481     if (aGetCACert)
       
   482     {
       
   483         DEBUG_LOG(_L("Reading CA certificate"));
       
   484 
       
   485         ownerType = EPKICACertificate;
       
   486 
       
   487         //Init CA cert ident data.
       
   488         //aTrustedAuthority (issuer) checking for CA certs is not supported.
       
   489         if ( aTrustedAuthority.Length() == 0 )
       
   490             {
       
   491             delete iSubjName;
       
   492             iSubjName = NULL;
       
   493             iSubjName = iCaName->AllocL();
       
   494             iRfc822Name->Des().Zero();
       
   495             } 
       
   496       }
       
   497     else
       
   498     {
       
   499         DEBUG_LOG(_L("Reading User certificate"));
       
   500         ownerType = EPKIUserCertificate;
       
   501         keySize = InitUserCertIdentDataL();
       
   502     }
       
   503 
       
   504     for (;;)    // Only for easy exits...
       
   505     {
       
   506         if ( iReallocated )
       
   507         {
       
   508             //
       
   509             // Allocate a new buffer for ASN1 coded certificate read from
       
   510             // PKI store. Buffer size is now asked from pkiserviceapi
       
   511             //
       
   512             delete iReadCertificate;
       
   513             iReadCertificate = NULL;
       
   514             TInt RealCertSize;
       
   515             
       
   516             if ( iPkiService.GetRequiredBufferSize(RealCertSize) == KErrNone )
       
   517                 iCertBfrSize = (RealCertSize | 0x3) + 1;
       
   518             // Try double size in error case
       
   519             else iCertBfrSize = (iCertBfrSize << 1);
       
   520         }
       
   521         
       
   522         if ( !iReadCertificate )
       
   523         {
       
   524             iReadCertificate=NULL;
       
   525             iReadCertificate = HBufC8::NewL(iCertBfrSize);
       
   526         }
       
   527         
       
   528         iCertPtr.Set(iReadCertificate->Des());
       
   529         iCertPtr.Zero();
       
   530 
       
   531         TRequestStatus status;
       
   532         iPkiService.ReadCertificateL(aTrustedAuthority,
       
   533                                      *iSubjName, *iRfc822Name,
       
   534                                      ownerType, keySize,
       
   535                                      keyAlgorithm, iCertPtr,
       
   536                                      &iResArray, status);
       
   537 
       
   538 
       
   539         User::WaitForRequest(status);
       
   540         Status = status.Int();
       
   541         iPkiService.Finalize(iResArray);
       
   542         iResArray = NULL;
       
   543         
       
   544         if ( (Status == KPKIErrBufferTooShort) && !iReallocated )
       
   545         {
       
   546             //
       
   547             // Certificate buffer was too small try to read once more if
       
   548             // not already tried
       
   549             //
       
   550             iReallocated = ETrue;
       
   551         }
       
   552         else
       
   553         {
       
   554             if ( Status == KErrNone )
       
   555             {
       
   556                 //iReadCertificate->Des().SetLength(iCertPtr.Length());
       
   557                 iReallocated = EFalse;
       
   558             }
       
   559             break;
       
   560         }
       
   561         
       
   562     }
       
   563 
       
   564     DEBUG_LOG(
       
   565         _L("<- ReadCertificateL(aTrustedAuthority, aGetCACert)")
       
   566     );
       
   567 
       
   568     return Status;
       
   569 }
       
   570 
       
   571 
       
   572 TUint CIkeV1PkiService::InitUserCertIdentDataL()
       
   573 {
       
   574     DEBUG_LOG(_L("-> CIkeV1PkiService::InitUserCertIdentDataL"));
       
   575     __ASSERT_ALWAYS(iIkeData != NULL, User::Invariant());
       
   576 
       
   577     TUint keySize = 0;        // Default: Length is undefined
       
   578 
       
   579     if ( !iReallocated )
       
   580     {
       
   581         //
       
   582         //  Get possible user identity information from current IKE policy
       
   583         //  section and convert it from 16-bit Unicode into UTF-8 format
       
   584         //
       
   585         TInt Lth = 3*( iIkeData->iOwnCert.iSubjectDnSuffix.Length() );
       
   586 
       
   587         if ( Lth )
       
   588         {
       
   589             delete iSubjName;
       
   590             iSubjName = NULL;
       
   591             iSubjName = HBufC8::NewL(Lth);
       
   592 
       
   593             TPtr8   dn8 = iSubjName->Des();
       
   594             TPtrC16 dn16( iIkeData->iOwnCert.iSubjectDnSuffix );
       
   595 
       
   596             if ( 0 != CnvUtfConverter::ConvertFromUnicodeToUtf8(
       
   597                 dn8, dn16 ) )
       
   598             {
       
   599                 User::Leave(KErrCorrupt);
       
   600             }
       
   601         }
       
   602         else
       
   603         {
       
   604             iSubjName->Des().Zero();
       
   605         }
       
   606 
       
   607         Lth = iIkeData->iOwnCert.iRfc822NameFqdn.Length();
       
   608 
       
   609         if ( Lth )
       
   610         {
       
   611             delete iRfc822Name;
       
   612             iRfc822Name = NULL;
       
   613             iRfc822Name = HBufC8::NewL(Lth);
       
   614             iRfc822Name->Des().Copy(iIkeData->iOwnCert.iRfc822NameFqdn);
       
   615         }
       
   616         else
       
   617         {
       
   618             iRfc822Name->Des().Zero();
       
   619         }
       
   620 
       
   621         if ( iIkeData->iOwnCert.iPrivateKeyLength )
       
   622         {
       
   623             keySize = iIkeData->iOwnCert.iPrivateKeyLength;
       
   624         }
       
   625     }
       
   626 
       
   627     DEBUG_LOG(_L("<- CIkeV1PkiService::InitUserCertIdentDataL"));
       
   628     return keySize;
       
   629 }
       
   630 
       
   631 
       
   632 TBool CIkeV1PkiService::GetNextCaElemL()
       
   633 {
       
   634     //
       
   635     // Get next CA certificate from PKI store using current CA name in
       
   636     // iCaNameList.
       
   637     //
       
   638     DEBUG_LOG(_L("-> CIkeV1PkiService::GetNextCaElemL"));
       
   639 
       
   640     TCertInfo* CertInfo;
       
   641     TBool Ret;
       
   642 
       
   643     Ret = EFalse;
       
   644     TInt Status;
       
   645 
       
   646     while ( iCurrIndex < iCaNameList->Count() )
       
   647     {
       
   648         CertInfo = iCaNameList->At(iCurrIndex);
       
   649         
       
   650         if ( CertInfo->iFormat == CA_NAME )
       
   651         {
       
   652             TPtr8   dn8 = iCaName->Des();
       
   653             TPtrC16 dn16( CertInfo->iData );
       
   654 
       
   655             if ( 0 != CnvUtfConverter::ConvertFromUnicodeToUtf8(
       
   656                 dn8, dn16
       
   657             ) )
       
   658             {
       
   659                 User::Leave(KErrCorrupt);
       
   660             }
       
   661 
       
   662             Status = ReadCertificateL(KEmptyString, ETrue);
       
   663             Ret |= AddNextCaElemL(Status);
       
   664         }
       
   665         else if ( CertInfo->iFormat == KEY_ID )
       
   666         {
       
   667             Status = GetCertificateWithKeyIdL(CertInfo->iData);
       
   668             Ret |= AddNextCaElemL(Status);
       
   669         }
       
   670         else if ( CertInfo->iFormat == APPL_UID )
       
   671         {
       
   672             Ret |= GetApplUidListL(CertInfo->iData);
       
   673         }
       
   674         else
       
   675         {
       
   676             Ret |= EFalse;
       
   677             iCurrIndex ++;
       
   678             DEBUG_LOG1(
       
   679                 _L("Unsupported CA certificate element format = %d"),
       
   680                 CertInfo->iFormat
       
   681             );
       
   682         }
       
   683 
       
   684     }
       
   685 
       
   686     iCaNameList = NULL;
       
   687 
       
   688     DEBUG_LOG(_L("<- CIkeV1PkiService::GetNextCaElemL"));
       
   689     return Ret;
       
   690 }
       
   691 
       
   692 
       
   693 TBool CIkeV1PkiService::AddNextCaElemL(TInt& aStatus)
       
   694 {
       
   695     DEBUG_LOG(_L("-> CIkeV1PkiService::AddNextCaElemL()"));
       
   696     
       
   697     //
       
   698     // CA has been read PKI store. Build and add a new CIkeCaElem to CIkeCaList
       
   699     //
       
   700 #ifdef _DEBUG    
       
   701     CertReadCompleted(ETrue, aStatus, __LINE__);
       
   702 #endif // _DEBUG    
       
   703 
       
   704     if (aStatus == KErrNotFound)
       
   705     {
       
   706         DEBUG_LOG(_L(" Leave: status == KErrNotFound"));
       
   707         User::Leave(KVpnErrInvalidCaCertFile);
       
   708     }
       
   709 
       
   710     TBool Ret;
       
   711     
       
   712     if ( aStatus == KErrNone )
       
   713     {
       
   714         ASSERT(iReadCertificate);
       
   715         HBufC8* CaCert = iReadCertificate; // Link CA buffer to CIkeCaElem
       
   716         CaCert->Des().SetLength(iCertPtr.Length());
       
   717         iReadCertificate = NULL;
       
   718         CleanupStack::PushL(CaCert);
       
   719         CIkeCaElem* CaElem = CIkeCaElem::NewL(CaCert);
       
   720         CleanupStack::Pop(CaCert);
       
   721         CleanupStack::PushL(CaElem);
       
   722         iTrustedCAList->AppendL(CaElem);
       
   723         CleanupStack::Pop(CaElem);
       
   724 
       
   725         if ( iOperation == KProcessingApplUidList )
       
   726             iListIndex ++;
       
   727         else iCurrIndex ++;
       
   728 
       
   729         Ret = ETrue;
       
   730     }
       
   731     else
       
   732     {
       
   733         if ( iOperation == KProcessingApplUidList )
       
   734             iListIndex ++;
       
   735         else iCurrIndex ++;
       
   736 
       
   737         Ret = EFalse;
       
   738     }
       
   739 
       
   740     DEBUG_LOG(_L("<- CIkeV1PkiService::AddNextCaElemL()"));
       
   741     
       
   742     return Ret;
       
   743 }
       
   744 
       
   745 TInt CIkeV1PkiService::GetNextCertificateL()
       
   746 {
       
   747     DEBUG_LOG(_L("-> CIkeV1PkiService::GetNextCertificateL"));
       
   748     //
       
   749     // Get next user certificate from PKI store using either Key
       
   750     // identifier or CA name as read argument
       
   751     //
       
   752     TInt Status = KErrNotFound;
       
   753     if ( iCasTrustedByPeer.Count() > 0 )
       
   754     {
       
   755         CIkeCaElem* CaElem = iCasTrustedByPeer[0];
       
   756         iCasTrustedByPeer.Remove(0);
       
   757         iOperation = KReadingCertificate;
       
   758         
       
   759         HBufC8* CaName = IkeCert::GetCertificateFieldDERL(
       
   760             CaElem->Certificate(), KSubjectName
       
   761         );
       
   762         
       
   763         if ( CaName )
       
   764         {
       
   765             delete iCaName;
       
   766             iCaName = CaName;
       
   767             ReadCertificateL(*iCaName, EFalse);
       
   768             Status = KErrNone;
       
   769         }
       
   770 
       
   771     }
       
   772 
       
   773     DEBUG_LOG(_L("<- CIkeV1PkiService::GetNextCertificateL"));
       
   774     return Status;
       
   775 }
       
   776 
       
   777 
       
   778 TBool CIkeV1PkiService::CertificateReadL(TInt& aStatus)
       
   779 {
       
   780     //
       
   781     // A Certificate has been read PKI store.
       
   782     // Build X509 certificate object from certificate data
       
   783     //
       
   784 #ifdef _DEBUG
       
   785     CertReadCompleted(EFalse, aStatus, __LINE__);
       
   786 #endif // _DEBUG    
       
   787     TBool Status = ETrue;
       
   788     
       
   789     if ( aStatus == KErrNone )
       
   790     {
       
   791         iReallocated = EFalse;
       
   792         iReadCertificate->Des().SetLength(iCertPtr.Length());
       
   793     }
       
   794     else
       
   795     {
       
   796         if ( (aStatus == KPKIErrBufferTooShort) && !iReallocated )
       
   797         {
       
   798             //
       
   799             // Certificate buffer was too small try to read once more if
       
   800             // not already tried
       
   801             //
       
   802             Status  = EFalse;
       
   803             aStatus = KErrNone;
       
   804             iReallocated = ETrue;
       
   805             ReadCertificateL(*iCaName, EFalse);
       
   806         }
       
   807 
       
   808         if ( (aStatus != KErrNone) && ( aStatus != KPKIErrBufferTooShort) )
       
   809         {
       
   810             //
       
   811             // User certificate not found from PKI store, try to read next
       
   812             //
       
   813             iReallocated = EFalse;
       
   814             aStatus = GetNextCertificateL();
       
   815             
       
   816             if ( aStatus == KErrNone )
       
   817             {
       
   818                 Status = EFalse;
       
   819             }
       
   820         }
       
   821     }
       
   822 
       
   823     return Status;
       
   824 }
       
   825 
       
   826 
       
   827 TInt CIkeV1PkiService::ReadCertificateL(const TPKIKeyIdentifier& aKeyIdentifier)
       
   828 {
       
   829     //
       
   830     // Read certificate from PKI store using pkiserviceapi
       
   831     //    
       
   832     TRequestStatus status;
       
   833 
       
   834     for (;;)    // Only for easy exits...
       
   835     {
       
   836         if ( iReallocated )
       
   837         {
       
   838             //
       
   839             // Allocate a new buffer for ASN1 coded certificate read from
       
   840             // PKI store. Buffer size is now asked from pkiserviceapi
       
   841             //
       
   842             delete iReadCertificate;
       
   843             iReadCertificate = NULL;
       
   844             TInt RealCertSize;
       
   845             
       
   846             if ( iPkiService.GetRequiredBufferSize(RealCertSize) == KErrNone )
       
   847                 iCertBfrSize = (RealCertSize | 0x3) + 1;
       
   848             // Try double size in error case
       
   849             else iCertBfrSize = (iCertBfrSize << 1);
       
   850         }
       
   851 
       
   852         if ( !iReadCertificate )
       
   853             iReadCertificate = HBufC8::NewL(iCertBfrSize);
       
   854             
       
   855         iCertPtr.Set((TUint8*)iReadCertificate->Ptr(), 0, iCertBfrSize);
       
   856 
       
   857         iPkiService.ReadCertificateL(aKeyIdentifier, iCertPtr,
       
   858                                      &iResArray, status);
       
   859                     
       
   860         User::WaitForRequest(status);
       
   861         iPkiService.Finalize(iResArray);
       
   862         iResArray = NULL;
       
   863   
       
   864         if ( (status.Int() == KPKIErrBufferTooShort) && !iReallocated )
       
   865         {
       
   866             //
       
   867             // Certificate buffer was too small try to read once more if
       
   868             // not already tried
       
   869             //
       
   870             iReallocated = ETrue;
       
   871         }
       
   872         else
       
   873         {
       
   874             if ( status.Int() == KErrNone )
       
   875             {
       
   876                 iReadCertificate->Des().SetLength(iCertPtr.Length());
       
   877                 iReallocated = EFalse;
       
   878             }
       
   879             break;
       
   880         }
       
   881         
       
   882     }
       
   883 
       
   884     return status.Int();
       
   885 }
       
   886 
       
   887 
       
   888 TInt CIkeV1PkiService::ReadCertificateListL()
       
   889 {
       
   890     //
       
   891     // Read certificate list with Application UID:s
       
   892     //
       
   893     if ( iCaCertList )
       
   894     {
       
   895         iCaCertList->Reset();
       
   896         delete iCaCertList;
       
   897         iCaCertList = NULL;
       
   898     }
       
   899     
       
   900     iOperation  = KBuildingApplUidList;
       
   901 
       
   902     iPkiService.ListApplicableCertificatesL(
       
   903         (const RArray<TUid>&)(*iApplUidList), iCaCertList
       
   904     );
       
   905 
       
   906     return KErrNone;
       
   907 }
       
   908 
       
   909 
       
   910 TInt CIkeV1PkiService::GetCertificateWithKeyIdL(const TDesC16& aKeyIdString)
       
   911 {
       
   912     TInt Status;
       
   913     
       
   914     if ( IkeParser::TextToHexOctets(aKeyIdString, iCertKeyId) )
       
   915         Status = ReadCertificateL(iCertKeyId);
       
   916     else Status = KErrArgument;
       
   917 
       
   918     return Status;
       
   919 }
       
   920 
       
   921 
       
   922 TBool CIkeV1PkiService::GetApplUidListL(const TDesC16& aApplUidString)
       
   923 {
       
   924     //
       
   925     // Build application UID array to get trusted CA certificate list
       
   926     // from PKI service.
       
   927     //
       
   928     if ( iApplUidList )
       
   929     {
       
   930         iApplUidList->Reset();
       
   931         delete iApplUidList;
       
   932         iApplUidList = NULL;
       
   933     }
       
   934 
       
   935     iApplUidList = IkeParser::GetApplUidListL(aApplUidString);
       
   936 
       
   937     TBool Status = (iApplUidList->Count() != 0);
       
   938     
       
   939     if ( Status )
       
   940     {
       
   941         TInt Ret = ReadCertificateListL();
       
   942         Status = ( Ret == KErrNone);
       
   943         iListIndex = 0;
       
   944         
       
   945         Status = ApplUidCertListCompletedL(Ret);
       
   946     }
       
   947 
       
   948     return Status;
       
   949 }
       
   950 
       
   951 
       
   952 TBool CIkeV1PkiService::ApplUidCertListCompletedL(TInt aStatus)
       
   953 {
       
   954     DEBUG_LOG2(
       
   955         _L("Certificate list read completed, status= %d, list elem count= %d"),
       
   956         aStatus, iCaCertList->Count()
       
   957     );
       
   958     DEBUG_LOG1(
       
   959         _L(" APPL UID(s) = %S\n"), &iCaNameList->At(iCurrIndex)->iData
       
   960     );
       
   961   
       
   962     TBool Ret;
       
   963   
       
   964     if ( (aStatus == KErrNone) && iCaCertList->Count() )
       
   965     {
       
   966         //
       
   967         // Start to read in trusted CA certificates provided in list
       
   968         //
       
   969         iOperation = KProcessingApplUidList;
       
   970         Ret = ReadNextInListL();
       
   971     }
       
   972     else
       
   973     {
       
   974         //
       
   975         // No trusted CA certificates found with current application
       
   976         // UID:s. Continue processing CA elements
       
   977         //
       
   978         Ret = EFalse;
       
   979         iOperation = KBuildingCaList;
       
   980         iCurrIndex ++;
       
   981         
       
   982     }
       
   983 
       
   984     return Ret;
       
   985 }
       
   986 
       
   987 
       
   988 TBool CIkeV1PkiService::ReadNextInListL()
       
   989 {
       
   990     TBool Status = EFalse;
       
   991     
       
   992     TInt Ret;
       
   993     
       
   994     while ( iListIndex < iCaCertList->Count() )
       
   995     {
       
   996         Ret = ReadCertificateL(iCaCertList->At(iListIndex).iSubjectKeyId);
       
   997         if ( AddNextCaElemL(Ret) )
       
   998             Status = ETrue;
       
   999     }
       
  1000     
       
  1001     iCurrIndex ++;
       
  1002 
       
  1003     return Status;
       
  1004 }
       
  1005 
       
  1006 
       
  1007 #ifdef _DEBUG
       
  1008 
       
  1009 void CIkeV1PkiService::CertReadCompleted(TBool aCaCert, TInt aStatus, TInt aLine )
       
  1010 {
       
  1011   TBuf<320>DebugMsg;
       
  1012   if ( aCaCert )
       
  1013   {
       
  1014         ASSERT( iCurrIndex < iCaNameList->Count() );
       
  1015      DebugMsg.Format(_L("Trusted CA certificate read completed with status = %d (line = %d)"),
       
  1016                      aStatus, aLine);
       
  1017      DebugMsg.AppendFormat(_L(" ; Search criteria: "));
       
  1018      TCertInfo* CertInfo = iCaNameList->At(iCurrIndex);
       
  1019      switch ( CertInfo->iFormat )
       
  1020      {
       
  1021        case CA_NAME:
       
  1022          DebugMsg.AppendFormat(_L("CA_NAME = %S\n"), &CertInfo->iData);
       
  1023          break;
       
  1024        case KEY_ID:
       
  1025          DebugMsg.AppendFormat(_L("KEY_ID = %S\n"), &CertInfo->iData);
       
  1026          break;
       
  1027        default:
       
  1028          TBuf<48> KeyIdString;
       
  1029                 ASSERT( iListIndex < iCaCertList->Count() );
       
  1030          HexToString(iCaCertList->At(iListIndex).iSubjectKeyId, KeyIdString);
       
  1031          DebugMsg.AppendFormat(_L("APPL_UID/<KEY_ID> = %S\n"), &KeyIdString);
       
  1032          break;
       
  1033      }
       
  1034   }
       
  1035   else
       
  1036   {
       
  1037      DEBUG_LOG2(_L("End user certificate read completed with status = %d (line = %d)\n"),
       
  1038                      aStatus, aLine);
       
  1039   }
       
  1040     DEBUG_LOG(DebugMsg);
       
  1041 }
       
  1042 
       
  1043 void CIkeV1PkiService::HexToString(const TDesC8& aKeyId, TDes16& aKeyIdString)
       
  1044 {
       
  1045   TInt i = 0;
       
  1046   TUint x;
       
  1047   TUint y;
       
  1048 
       
  1049   while (i < aKeyId.Length())
       
  1050   {
       
  1051     x = (TUint)aKeyId[i];
       
  1052     for ( TInt j = 4; j >= 0; j -= 4 )
       
  1053     {
       
  1054           y  = (x >> j) & 0xf;
       
  1055         TChar ch(y);
       
  1056             if ( y < 0xa )
       
  1057            ch += 0x30;
       
  1058         else if ( (y > 9) && (y < 0x10) )
       
  1059              ch += (0x61 - 0xa);
       
  1060         else ch += (0x30 - ch);
       
  1061         aKeyIdString.Append(ch);
       
  1062     }
       
  1063     i ++;
       
  1064   }
       
  1065 }
       
  1066 
       
  1067 #endif //_DEBUG