wim/WimServer/src/WimCertHandler.cpp
changeset 0 164170e6151a
child 5 3b17fc5c9564
equal deleted inserted replaced
-1:000000000000 0:164170e6151a
       
     1 /*
       
     2 * Copyright (c) 2002-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:  Certificate management methods
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include    "Wimi.h"            // wimi definitions
       
    22 #include    "WimCertHandler.h"
       
    23 #include    "WimMemMgmt.h"
       
    24 #include    "WimSession.h"
       
    25 #include    "WimResponse.h"
       
    26 #include    "WimUtilityFuncs.h"
       
    27 #include    <asn1enc.h>         // asn.1 encoding
       
    28 #include    <asn1dec.h>         // asn.1 decoding
       
    29 #include    <x509cert.h>        // cx509certificate
       
    30 #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    31 #include    <x509keys.h>        // cx509rsapublickey
       
    32 #else
       
    33 #include    <x509keys.h>        // cx509rsapublickey
       
    34 #include    <x509keyencoder.h>        // cx509rsapublickey
       
    35 #endif
       
    36 #include    <wtlscert.h>        // cwtlscertificate
       
    37 #include    <wtlskeys.h>        // cwtlsrsapublickey
       
    38 #include    "WimTrace.h"
       
    39 #include    "WimCallbackImpl.h"
       
    40 #include    "WimCleanup.h"
       
    41 
       
    42 // ============================ MEMBER FUNCTIONS ===============================
       
    43 
       
    44 // -----------------------------------------------------------------------------
       
    45 // CWimCertHandler::CWimCertHandler
       
    46 // C++ default constructor can NOT contain any code, that
       
    47 // might leave.
       
    48 // -----------------------------------------------------------------------------
       
    49 //
       
    50 CWimCertHandler::CWimCertHandler()
       
    51     {
       
    52     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::CWimCertHandler | Begin"));
       
    53     }
       
    54 
       
    55 // -----------------------------------------------------------------------------
       
    56 // CWimCertHandler::ConstructL
       
    57 // Symbian 2nd phase constructor can leave.
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 void CWimCertHandler::ConstructL()
       
    61     {
       
    62     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::ConstructL | Begin"));
       
    63     iWimUtilFuncs = CWimUtilityFuncs::NewL();
       
    64     }
       
    65 
       
    66 // -----------------------------------------------------------------------------
       
    67 // CWimCertHandler::NewL
       
    68 // Two-phased constructor.
       
    69 // -----------------------------------------------------------------------------
       
    70 //
       
    71 CWimCertHandler* CWimCertHandler::NewL() 
       
    72     {
       
    73     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::NewL | Begin"));
       
    74     CWimCertHandler* self = new( ELeave ) CWimCertHandler;
       
    75     CleanupStack::PushL( self );
       
    76     self->ConstructL();
       
    77     CleanupStack::Pop( self );
       
    78     return self;
       
    79     }
       
    80 
       
    81     
       
    82 // Destructor
       
    83 CWimCertHandler::~CWimCertHandler()
       
    84     {
       
    85     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::~CWimCertHandler | Begin"));
       
    86     delete iWimUtilFuncs;
       
    87 
       
    88     for( TInt index = 0; index < iCertRefLst.Count(); ++index )
       
    89         {
       
    90         WIMI_Ref_t* ref = reinterpret_cast< WIMI_Ref_t* >( iCertRefLst[ index ] );
       
    91         _WIMTRACE2(_L("WIM | WIMServer | CWimCertHandler::~CWimCertHandler, -ref 0x%08x"), ref);
       
    92         free_WIMI_Ref_t( ref );
       
    93         iCertRefLst[ index ] = 0;
       
    94         }
       
    95     iCertRefLst.Reset();
       
    96     }
       
    97 
       
    98 // -----------------------------------------------------------------------------
       
    99 // CWimCertHandler::GetCertificatesFromWimL
       
   100 // Fetches certificates from WIM card.
       
   101 // -----------------------------------------------------------------------------
       
   102 //
       
   103 void CWimCertHandler::GetCertificatesFromWimL(
       
   104     const RMessage2& aMessage, 
       
   105     CWimMemMgmt* aWimMgmt )
       
   106     {
       
   107     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::GetCertificatesFromWimL | Begin"));
       
   108     WIMI_STAT callStatus = WIMI_Ok;
       
   109     TUint8 certNum = 0;
       
   110     WIMI_Ref_t* temp = NULL;
       
   111 
       
   112     HBufC8* certRefLst = iWimUtilFuncs->DesLC( 0, aMessage );
       
   113     HBufC8* certInfoLst = iWimUtilFuncs->DesLC( 1, aMessage );
       
   114 
       
   115     TWimEntryType certEntryType = ( TWimEntryType ) aMessage.Int2();
       
   116 
       
   117     TUint32* pCertRefLst = ( TUint32* )( certRefLst->Des().Ptr() );
       
   118     TWimCertInfo* pCertInfoLst = ( TWimCertInfo* )( certInfoLst->Des().Ptr() );
       
   119 
       
   120     temp = aWimMgmt->WimRef();
       
   121     if ( !temp )
       
   122         { 
       
   123         temp = WIMI_GetWIMRef( 0 );
       
   124         aWimMgmt->SetWIMRef( temp );    // takes ownership
       
   125         }
       
   126 
       
   127     if ( temp )
       
   128         {
       
   129         if ( EWimEntryTypeAll == certEntryType || 
       
   130              EWimEntryTypeCA == certEntryType )
       
   131             {
       
   132             callStatus = GetCertificateFromWimRefL( temp, WIMI_CU_CA,
       
   133                                                     certNum, pCertRefLst,
       
   134                                                     pCertInfoLst, aMessage );
       
   135 
       
   136             }
       
   137         if ( callStatus == WIMI_Ok && ( EWimEntryTypeAll == certEntryType || 
       
   138                                    EWimEntryTypePersonal == certEntryType ) )
       
   139             {
       
   140             callStatus = GetCertificateFromWimRefL( temp, WIMI_CU_Client,
       
   141                                                     certNum, pCertRefLst,
       
   142                                                     pCertInfoLst, aMessage );
       
   143 
       
   144             }
       
   145         
       
   146         //record the ref for sanity checking, deallocate old refs first
       
   147         for( TInt index = 0; index < iCertRefLst.Count(); ++index )
       
   148             {
       
   149             WIMI_Ref_t* ref = reinterpret_cast< WIMI_Ref_t* >( iCertRefLst[ index ] );
       
   150             _WIMTRACE2(_L("WIM | WIMServer | CWimCertHandler::GetCertificatesFromWimL, -ref 0x%08x"), ref);
       
   151             free_WIMI_Ref_t( ref );
       
   152             iCertRefLst[ index ] = 0;
       
   153             }
       
   154         iCertRefLst.Reset();
       
   155         for( TInt index = 0; index < certNum; ++index )
       
   156             {
       
   157             _WIMTRACE2(_L("WIM | WIMServer | CWimCertHandler::GetCertificatesFromWimL, +ref 0x%08x"), pCertRefLst[ index ]);
       
   158             iCertRefLst.AppendL( pCertRefLst[ index ] );
       
   159             }
       
   160         
       
   161         aMessage.WriteL( 0, certRefLst->Des() );
       
   162         aMessage.WriteL( 1, certInfoLst->Des() );
       
   163         }
       
   164     else
       
   165         {
       
   166         callStatus = WIMI_ERR_OutOfMemory;
       
   167         }
       
   168     CleanupStack::PopAndDestroy( 2, certRefLst );   // certInfoLst, certRefLst
       
   169     aMessage.Complete( CWimUtilityFuncs::MapWIMError( callStatus ) );
       
   170     }
       
   171 
       
   172 // -----------------------------------------------------------------------------
       
   173 // CWimCertHandler::GetCertificateFromWimRefL
       
   174 // Fetches certificate from the WIM card.
       
   175 // -----------------------------------------------------------------------------
       
   176 //
       
   177 WIMI_STAT CWimCertHandler::GetCertificateFromWimRefL(
       
   178     WIMI_Ref_t* aTmpWimRef,
       
   179     TInt8 aUsage,
       
   180     TUint8& aCertNum,
       
   181     TUint32* aCertRefLst,
       
   182     TWimCertInfo* aCertInfoLst,
       
   183     const RMessage2& aMessage )
       
   184     {
       
   185     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::GetCertificateFromWimRefL | Begin"));
       
   186     TUint8 tempCrtCount;
       
   187     WIMI_RefList_t refList = NULL;
       
   188     WIMI_STAT callStatus = WIMI_Ok;
       
   189 
       
   190     if ( aTmpWimRef )
       
   191         {
       
   192         callStatus = WIMI_GetCertificateListByWIM( aTmpWimRef, 
       
   193                                                    aUsage, 
       
   194                                                    &tempCrtCount, 
       
   195                                                    &refList );
       
   196 
       
   197         if ( callStatus == WIMI_Ok )
       
   198             {
       
   199             // If the certifcate length is 0,
       
   200             // the step increases by 1.
       
   201             TInt step = 0;
       
   202             TInt err = KErrNone;
       
   203             for ( TUint8 certIndex = 0; certIndex < tempCrtCount; certIndex++ )
       
   204                 {
       
   205                 TInt current = aCertNum + certIndex - step;
       
   206                 err = CopyCertificateInfo( aCertInfoLst[current], refList[certIndex], aMessage );
       
   207 
       
   208                 if ( err == KErrNone )
       
   209                     {
       
   210                     // transfers ownership of refList item to aCertRefLst
       
   211                     aCertRefLst[current] = reinterpret_cast< TUint32 >( refList[certIndex] );
       
   212                     refList[certIndex] = NULL;
       
   213                     }
       
   214                 else // KErrArgument
       
   215                     {
       
   216                     // ingore certificate info and continue with the next
       
   217                 	step++;
       
   218                     free_WIMI_Ref_t( refList[certIndex] );
       
   219                     }
       
   220                 }
       
   221             //variable step is equal to the number of certificate in CDF whose 
       
   222             //length is set as 0.     
       
   223             aCertNum = static_cast< TUint8 >( aCertNum + tempCrtCount - step );
       
   224 
       
   225             // Because list items are moved to aCertRefLst, only refList array
       
   226             // needs to be freed. Cannot use free_WIMI_RefList_t() as it would
       
   227             // delete also items contained in refList.
       
   228             WSL_OS_Free( refList );
       
   229             }
       
   230         }
       
   231 
       
   232     return callStatus;
       
   233     }
       
   234 
       
   235 // -----------------------------------------------------------------------------
       
   236 // CWimCertHandler::CopyCertificateInfo
       
   237 // Copies certificate information to client's allocated memory area.
       
   238 // This function MAY NOT leave.
       
   239 // -----------------------------------------------------------------------------
       
   240 //
       
   241 TInt CWimCertHandler::CopyCertificateInfo(
       
   242     TWimCertInfo& aCertInfo,
       
   243     WIMI_Ref_t* aCert,
       
   244     const RMessage2& /*aMessage*/ )
       
   245     {
       
   246     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::CopyCertificateInfo | Begin"));
       
   247     WIMI_Ref_t* tempRef = NULL;
       
   248     WIMI_BinData_t ptLabel;
       
   249     WIMI_BinData_t ptKeyID;
       
   250     WIMI_BinData_t ptCAID;
       
   251     WIMI_BinData_t ptIssuerHash;
       
   252     WIMI_BinData_t ptTrustedUsage;
       
   253     TUint8 uiCDFRefs;
       
   254     TUint8 usage;
       
   255     TUint8 type;
       
   256     TUint16 certLen;
       
   257     TUint8 modifiable = 0;
       
   258     WIMI_STAT callStatus = WIMI_GetCertificateInfo( 
       
   259                                 aCert,
       
   260                                 &tempRef,
       
   261                                 &ptLabel,
       
   262                                 &ptKeyID, /* Key Id (hash)*/
       
   263                                 &ptCAID,
       
   264                                 &ptIssuerHash,
       
   265                                 &ptTrustedUsage,
       
   266                                 &uiCDFRefs,
       
   267                                 &usage,  /* 0 = client, 1 = CA */
       
   268                                 &type,   /* WTLSCert(1), 
       
   269                                             X509Cert(2), 
       
   270                                             X968Cert(3), 
       
   271                                             CertURL(4) */ 
       
   272                                 &certLen,   /* cert. content or URL length */
       
   273                                 &modifiable );
       
   274 
       
   275     if ( callStatus == WIMI_Ok )
       
   276         {
       
   277         free_WIMI_Ref_t( tempRef );
       
   278 
       
   279         // To make sure the length of the certificate is not zero
       
   280         _WIMTRACE2(_L("WIM | WIMServer | CWimCertHandler::CopyCertificateInfoL | certLen %d"), certLen);
       
   281         if ( certLen == 0 )
       
   282             {
       
   283             WSL_OS_Free( ptLabel.pb_buf );
       
   284             WSL_OS_Free( ptKeyID.pb_buf );
       
   285             WSL_OS_Free( ptCAID.pb_buf );
       
   286             WSL_OS_Free( ptIssuerHash.pb_buf );
       
   287             WSL_OS_Free( ptTrustedUsage.pb_buf );
       
   288         	return KErrArgument;
       
   289             }
       
   290 
       
   291         // it is x509cert
       
   292         if ( type == 2 && certLen != 0 )
       
   293             {
       
   294             //use this rough sanity checking for temp
       
   295             if ( certLen < 10 )
       
   296                 {
       
   297                 _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::CopyCertificateInfoL | cert is malformated, return KErrArgument"));
       
   298                 WSL_OS_Free( ptLabel.pb_buf );
       
   299                 WSL_OS_Free( ptKeyID.pb_buf );
       
   300                 WSL_OS_Free( ptCAID.pb_buf );
       
   301                 WSL_OS_Free( ptIssuerHash.pb_buf );
       
   302                 WSL_OS_Free( ptTrustedUsage.pb_buf );
       
   303                 return KErrArgument;
       
   304                 }
       
   305             }
       
   306         _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::CopyCertificateInfoL | X509 check ok"));
       
   307 
       
   308         aCertInfo.iLabel.Copy(
       
   309             TPtr8(
       
   310                 ptLabel.pb_buf, 
       
   311                 ptLabel.ui_buf_length, 
       
   312                 ptLabel.ui_buf_length ) );
       
   313 
       
   314         aCertInfo.iKeyId.Copy(
       
   315             TPtr8(
       
   316                 ptKeyID.pb_buf, 
       
   317                 ptKeyID.ui_buf_length, 
       
   318                 ptKeyID.ui_buf_length ) );
       
   319         
       
   320         aCertInfo.iCAId.Copy(
       
   321             TPtr8(
       
   322                 ptCAID.pb_buf, 
       
   323                 ptCAID.ui_buf_length, 
       
   324                 ptCAID.ui_buf_length ) );
       
   325         
       
   326         aCertInfo.iIssuerHash.Copy(
       
   327             TPtr8(
       
   328                 ptIssuerHash.pb_buf, 
       
   329                 ptIssuerHash.ui_buf_length, 
       
   330                 ptIssuerHash.ui_buf_length ) );
       
   331 
       
   332         aCertInfo.iUsage = usage;
       
   333         aCertInfo.iType = type;
       
   334         aCertInfo.iCertlen = certLen;
       
   335         aCertInfo.iModifiable = modifiable;
       
   336         
       
   337         // Certificate location
       
   338         aCertInfo.iCDFRefs = iWimUtilFuncs->MapCertLocation( uiCDFRefs );
       
   339 
       
   340         //Allocate enough memory for OID
       
   341         aCertInfo.iTrustedUsageLength = ptTrustedUsage.ui_buf_length * 16;
       
   342 
       
   343         WSL_OS_Free( ptLabel.pb_buf );
       
   344         WSL_OS_Free( ptKeyID.pb_buf );
       
   345         WSL_OS_Free( ptCAID.pb_buf );
       
   346         WSL_OS_Free( ptIssuerHash.pb_buf );
       
   347         WSL_OS_Free( ptTrustedUsage.pb_buf );
       
   348         }
       
   349 
       
   350     return KErrNone;
       
   351     }
       
   352 
       
   353 // -----------------------------------------------------------------------------
       
   354 // CWimCertHandler::GetExtrasFromWimL
       
   355 // Fetches certificate's extra info from WIM card. In this case it is
       
   356 // trusted usage info.
       
   357 // -----------------------------------------------------------------------------
       
   358 //
       
   359 void CWimCertHandler::GetExtrasFromWimL(
       
   360     const RMessage2& aMessage, 
       
   361     CWimMemMgmt* aWimMgmt )
       
   362     {
       
   363     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::GetExtrasFromWimL | Begin"));
       
   364 
       
   365     WIMI_STAT callStatus = WIMI_Ok;
       
   366     TInt8 certUsage = 0;
       
   367     
       
   368     HBufC8* keyIdBuf = iWimUtilFuncs->DesLC( 0, aMessage );
       
   369     TPtrC8 keyIdHash = keyIdBuf->Des();
       
   370 
       
   371     WIMI_Ref_t* wimTempRef = aWimMgmt->WimRef();
       
   372     if ( !wimTempRef )
       
   373         { 
       
   374         wimTempRef = WIMI_GetWIMRef( 0 );
       
   375         aWimMgmt->SetWIMRef( wimTempRef );  // takes ownership
       
   376         }
       
   377 
       
   378     if ( wimTempRef )
       
   379         {
       
   380         TWimEntryType certEntryType = static_cast< TWimEntryType >( aMessage.Int2() );
       
   381         switch ( certEntryType )
       
   382             {
       
   383             case EWimEntryTypeCA:
       
   384                 {
       
   385                 certUsage = WIMI_CU_CA;
       
   386                 break;
       
   387                 }
       
   388             case EWimEntryTypeAll: //Flow through
       
   389             case EWimEntryTypePersonal:
       
   390                 {
       
   391                 certUsage = WIMI_CU_Client;
       
   392                 break;
       
   393                 }
       
   394             default:
       
   395                 {
       
   396                 callStatus = WIMI_ERR_BadParameters;
       
   397                 break;
       
   398                 }
       
   399             }
       
   400 
       
   401         if ( callStatus == WIMI_Ok )
       
   402             {
       
   403             callStatus = GetExtrasFromWimRefL( wimTempRef,
       
   404                                                certUsage,
       
   405                                                keyIdHash,
       
   406                                                aMessage );
       
   407             }
       
   408         }
       
   409     else
       
   410         {
       
   411         callStatus = WIMI_ERR_BadReference;
       
   412         }
       
   413 
       
   414     CleanupStack::PopAndDestroy( keyIdBuf );
       
   415     aMessage.Complete( CWimUtilityFuncs::MapWIMError( callStatus ) );
       
   416     }
       
   417 
       
   418 // -----------------------------------------------------------------------------
       
   419 // CWimCertHandler::GetExtrasFromWimRefL
       
   420 // Fetches extra information (e.g. certs trusted usage) from the WIM card.
       
   421 // -----------------------------------------------------------------------------
       
   422 //
       
   423 WIMI_STAT CWimCertHandler::GetExtrasFromWimRefL(
       
   424     WIMI_Ref_t* aTmpWimRef,
       
   425     TInt8 aUsage,
       
   426     TDesC8& aKeyHash,
       
   427     const RMessage2& aMessage )
       
   428     {
       
   429     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::GetExtrasFromWimRefL | Begin"));
       
   430   
       
   431     TUint8 tempCertCount = 0;
       
   432     WIMI_RefList_t certRefList = NULL;
       
   433     WIMI_STAT callStatus = WIMI_Ok;
       
   434     TInt certIndex = 0;
       
   435     TPtrC8 keyHash;
       
   436 
       
   437     if ( aTmpWimRef )
       
   438         {
       
   439         // List all certificates (by WIM and usage)
       
   440         callStatus = WIMI_GetCertificateListByWIM( aTmpWimRef, 
       
   441                                                    aUsage, 
       
   442                                                    &tempCertCount, 
       
   443                                                    &certRefList );
       
   444         }
       
   445     else
       
   446         {
       
   447         callStatus = WIMI_ERR_BadReference;
       
   448         }
       
   449     CleanupPushWimRefListL( certRefList );
       
   450     
       
   451     if ( callStatus == WIMI_Ok )
       
   452         {
       
   453         WIMI_Ref_t* tempRef = NULL;
       
   454         WIMI_BinData_t ptLabel;
       
   455         WIMI_BinData_t ptKeyID;
       
   456         WIMI_BinData_t ptCAID;
       
   457         WIMI_BinData_t ptIssuerHash;
       
   458         WIMI_BinData_t ptTrustedUsage;
       
   459         TUint8 uiCDFRefs;
       
   460         TUint8 usage;
       
   461         TUint8 certType;
       
   462         TUint16 certLen;
       
   463         TUint8 modifiable = 0;
       
   464 
       
   465         for ( TInt i = 0; i < tempCertCount; i++ )
       
   466             {
       
   467             // Get info for each certificate until we find valid cert
       
   468             callStatus = WIMI_GetCertificateInfo( certRefList[i],
       
   469                                                   &tempRef,
       
   470                                                   &ptLabel,
       
   471                                                   &ptKeyID,
       
   472                                                   &ptCAID,
       
   473                                                   &ptIssuerHash,
       
   474                                                   &ptTrustedUsage,
       
   475                                                   &uiCDFRefs,
       
   476                                                   &usage,
       
   477                                                   &certType,   
       
   478                                                   &certLen,
       
   479                                                   &modifiable );
       
   480             if ( callStatus == WIMI_Ok )
       
   481                 {
       
   482                 free_WIMI_Ref_t( tempRef );
       
   483 
       
   484                 // Code MAY NOT leave before ptLabel.pb_buf, ptKeyID.pb_buf,
       
   485                 // ptCAID.pb_buf, ptIssuerHash.pt_buf, and ptTrustedUsage.pb_buf
       
   486                 // are deallocated.
       
   487 
       
   488                 keyHash.Set( ptKeyID.pb_buf, ptKeyID.ui_buf_length );
       
   489 
       
   490                 // Compare given and fetched key hash
       
   491                 if ( keyHash.Compare( aKeyHash ) == 0 &&
       
   492                      certType == WIMI_CT_X509 ) //Match
       
   493                     {
       
   494                     certIndex = i; // Found one
       
   495                     i = tempCertCount; // Stop looping
       
   496                     callStatus = WIMI_Ok;
       
   497                     }
       
   498                 else // Cert not supported
       
   499                     {
       
   500                     callStatus = WIMI_ERR_UnsupportedCertificate;
       
   501                     }
       
   502 
       
   503                 WSL_OS_Free( ptLabel.pb_buf );
       
   504                 WSL_OS_Free( ptKeyID.pb_buf );
       
   505                 WSL_OS_Free( ptCAID.pb_buf );
       
   506                 WSL_OS_Free( ptIssuerHash.pb_buf );
       
   507                 WSL_OS_Free( ptTrustedUsage.pb_buf );
       
   508                 // Code can leave after this point.
       
   509                 }
       
   510             }
       
   511 
       
   512         if ( callStatus == WIMI_Ok )
       
   513             {
       
   514             CopyCertExtrasInfoL( certRefList[certIndex], aMessage );
       
   515             }
       
   516 
       
   517         CleanupStack::PopAndDestroy( certRefList );
       
   518         }
       
   519 
       
   520     return callStatus;
       
   521     }
       
   522 
       
   523 // -----------------------------------------------------------------------------
       
   524 // CWimCertHandler::CopyCertExtrasInfoL
       
   525 // Copies certs extra information to client's allocated memory area.
       
   526 // -----------------------------------------------------------------------------
       
   527 //
       
   528 void CWimCertHandler::CopyCertExtrasInfoL(
       
   529     WIMI_Ref_t* aCert,
       
   530     const RMessage2& aMessage )
       
   531     {
       
   532     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::CopyCertExtrasInfoL | Begin"));
       
   533     TUint8 pushedItemCount = 0;
       
   534     WIMI_Ref_t* tempref = NULL;
       
   535     WIMI_BinData_t ptLabel;
       
   536     WIMI_BinData_t ptKeyID;
       
   537     WIMI_BinData_t ptCAID;
       
   538     WIMI_BinData_t ptIssuerHash;
       
   539     WIMI_BinData_t ptTrustedUsage;
       
   540     TUint8 uiCDFRefs;
       
   541     TUint8 usage;
       
   542     TUint8 type;
       
   543     TUint16 certlen;
       
   544     TUint8 modifiable = 0;
       
   545     TBool found = ETrue;
       
   546 
       
   547     TCertExtrasInfo certExtraInfo;
       
   548     certExtraInfo.iCDFRefs = 0;
       
   549     certExtraInfo.iTrustedUsage = NULL;
       
   550 
       
   551     WIMI_STAT callStatus = WIMI_GetCertificateInfo( 
       
   552                                 aCert,
       
   553                                 &tempref,
       
   554                                 &ptLabel,
       
   555                                 &ptKeyID, /* Key Id (hash)*/
       
   556                                 &ptCAID,
       
   557                                 &ptIssuerHash,
       
   558                                 &ptTrustedUsage,
       
   559                                 &uiCDFRefs,
       
   560                                 &usage,  /* 0 = client, 1 = CA */
       
   561                                 &type,   
       
   562                                 &certlen,   /* cert. content or URL length */
       
   563                                 &modifiable); 
       
   564     if ( callStatus == WIMI_Ok )
       
   565         {
       
   566         free_WIMI_Ref_t( tempref );
       
   567         WSL_OS_Free( ptLabel.pb_buf );
       
   568         WSL_OS_Free( ptKeyID.pb_buf );
       
   569         WSL_OS_Free( ptCAID.pb_buf );
       
   570         WSL_OS_Free( ptIssuerHash.pb_buf );
       
   571 
       
   572         CleanupPushWimBufL( ptTrustedUsage );
       
   573         pushedItemCount++;
       
   574 
       
   575         TPtrC8 undecodedUsage;
       
   576         undecodedUsage.Set( ptTrustedUsage.pb_buf ); 
       
   577 
       
   578         if ( ptTrustedUsage.ui_buf_length == 0 ) // No OIDs
       
   579             {
       
   580             found = EFalse;
       
   581             }
       
   582 
       
   583         // DECODE OIDs
       
   584         TASN1DecObjectIdentifier decoder;
       
   585         RPointerArray<HBufC> decodedOIDArray;
       
   586         CleanupResetAndDestroyPushL( decodedOIDArray );
       
   587         pushedItemCount++;
       
   588         HBufC* decodedOIDs = NULL;
       
   589         TInt oidsLength = 0;    // length of total OID buffer
       
   590         TInt err;
       
   591 
       
   592         for ( TInt position = 0; found; )   //Loop until no OIDs found anymore
       
   593             {
       
   594             if ( undecodedUsage.Length() > position ) //Don't go over buffer
       
   595                 {
       
   596                 TRAP( err, decodedOIDs = decoder.DecodeDERL( undecodedUsage, position ) );
       
   597                 if ( err == KErrNone ) //Found OID
       
   598                     {
       
   599                     CleanupStack::PushL( decodedOIDs );
       
   600                     if ( decodedOIDs->Length() )
       
   601                         {
       
   602                         found = ETrue;
       
   603                         decodedOIDArray.AppendL( decodedOIDs );
       
   604                         oidsLength += decodedOIDs->Length();
       
   605                         CleanupStack::Pop( decodedOIDs );
       
   606                         }
       
   607                     else    // Not found OID from buffer
       
   608                         {
       
   609                         found = EFalse;    
       
   610                         CleanupStack::PopAndDestroy( decodedOIDs );
       
   611                         }
       
   612                     decodedOIDs = NULL;
       
   613                     }
       
   614                 else    // Error in OID parsing -> Not found OID
       
   615                     {
       
   616                     found = EFalse;
       
   617                     }
       
   618                 }
       
   619             else    // undecoded OID buffer seeked through
       
   620                 {
       
   621                 found = EFalse;
       
   622                 }
       
   623             }
       
   624 
       
   625         _LIT( KDelimeter16, " " ); //Delimeter between OIDs
       
   626         TInt trustedUsagesBufMaxLength = oidsLength + decodedOIDArray.Count();
       
   627         TPtr trustedUsage( NULL, 0, trustedUsagesBufMaxLength );
       
   628 
       
   629         if ( oidsLength > 0 ) // OID's found
       
   630             {
       
   631             // Alloc new buffer for all OID's
       
   632             HBufC* trustedUsagesBuf = HBufC::NewLC( trustedUsagesBufMaxLength );
       
   633             pushedItemCount++;
       
   634 
       
   635             trustedUsage.Set( trustedUsagesBuf->Des() );
       
   636        
       
   637             // Add OID's to one buffer from separate buffers
       
   638             for ( TInt i = 0; i < decodedOIDArray.Count(); i++ )
       
   639                 {
       
   640                 if ( i == 0 ) //First one
       
   641                     {
       
   642                     trustedUsage.Copy( decodedOIDArray[i]->Des() );
       
   643                     }
       
   644                 else // Append other OIDs, with delimeter
       
   645                     {
       
   646                     trustedUsage.Append( KDelimeter16 );
       
   647                     trustedUsage.Append( decodedOIDArray[i]->Des() );
       
   648                     }
       
   649                 }
       
   650             }
       
   651 
       
   652         TPckgBuf<TCertExtrasInfo> wimCertExtraPckg( certExtraInfo );
       
   653         aMessage.ReadL( 1, wimCertExtraPckg );
       
   654         
       
   655         wimCertExtraPckg().iCDFRefs = iWimUtilFuncs->MapCertLocation( uiCDFRefs );
       
   656         
       
   657         if ( oidsLength > 0 ) // OID's found, write buffer to client
       
   658             {
       
   659             aMessage.WriteL( 3, trustedUsage );
       
   660             }
       
   661         aMessage.WriteL( 1, wimCertExtraPckg );
       
   662 
       
   663         CleanupStack::PopAndDestroy( pushedItemCount, ptTrustedUsage.pb_buf );
       
   664         }
       
   665     }
       
   666 
       
   667 // -----------------------------------------------------------------------------
       
   668 // CWimCertHandler::GetCerticateCountL
       
   669 // Fetches count of certicates in certain WIM card.
       
   670 // -----------------------------------------------------------------------------
       
   671 //
       
   672 void CWimCertHandler::GetCerticateCountL(
       
   673     const RMessage2& aMessage, 
       
   674     CWimMemMgmt* aWimMgmt ) const
       
   675     {
       
   676     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::GetCerticateCountL | Begin"));
       
   677     WIMI_STAT callStatus = WIMI_Ok;
       
   678     TWimEntryType certEntryType = ( TWimEntryType )aMessage.Int1();
       
   679     
       
   680     __ASSERT_ALWAYS( certEntryType != EWimEntryTypeAll ||
       
   681         certEntryType != EWimEntryTypeCA ||
       
   682         certEntryType != EWimEntryTypePersonal, User::Leave( KErrArgument ) );
       
   683 
       
   684     WIMI_Ref_t* wimRef = NULL;
       
   685     TUint8 certCount = 0;
       
   686 
       
   687     wimRef = aWimMgmt->WimRef();
       
   688     if ( !wimRef )
       
   689         {
       
   690         wimRef = WIMI_GetWIMRef( 0 );
       
   691         aWimMgmt->SetWIMRef( wimRef );  // takes ownership
       
   692         }
       
   693 
       
   694     if ( wimRef )
       
   695         {
       
   696         if ( EWimEntryTypeAll == certEntryType || 
       
   697             EWimEntryTypeCA == certEntryType )
       
   698             {
       
   699             callStatus = GetCertificateCountByWIM( wimRef, 
       
   700                                                    certCount, 
       
   701                                                    WIMI_CU_CA );            
       
   702             }
       
   703 
       
   704         if ( callStatus == WIMI_Ok && ( EWimEntryTypeAll == certEntryType || 
       
   705                                      EWimEntryTypePersonal == certEntryType ) )
       
   706             {
       
   707             callStatus = GetCertificateCountByWIM( wimRef, 
       
   708                                                    certCount, 
       
   709                                                    WIMI_CU_Client );
       
   710             }
       
   711         }
       
   712     else
       
   713         {
       
   714         callStatus = WIMI_ERR_OutOfMemory;
       
   715         }
       
   716 
       
   717     if ( callStatus == WIMI_Ok )
       
   718         {
       
   719         _WIMTRACE2(_L("WIM | WIMServer | CWimCertHandler::GetCerticateCountL | count=%d"), certCount);
       
   720         TPckgBuf<TUint8> pckg( certCount );
       
   721         aMessage.WriteL( 0, pckg );
       
   722         }
       
   723     aMessage.Complete( CWimUtilityFuncs::MapWIMError( callStatus ) );
       
   724     }
       
   725 
       
   726 // -----------------------------------------------------------------------------
       
   727 // CWimCertHandler::GetCertificateCountByWIM
       
   728 // Fetches count of certicates in certain WIM card.
       
   729 // This function MAY NOT leave.
       
   730 // -----------------------------------------------------------------------------
       
   731 //
       
   732 WIMI_STAT CWimCertHandler::GetCertificateCountByWIM(
       
   733     WIMI_Ref_t* aRef, 
       
   734     TUint8& aCertCount, 
       
   735     TUint8 aUsage ) const
       
   736     {
       
   737     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::GetCertificateCountByWIM | Begin"));
       
   738     
       
   739     // Get the number of certificates from smart card.
       
   740     TUint8 certNum = 0;
       
   741     WIMI_RefList_t refList ;
       
   742     WIMI_STAT callStatus = WIMI_GetCertificateListByWIM( aRef, 
       
   743                                                          aUsage,
       
   744                                                          &certNum, 
       
   745                                                          &refList );
       
   746 
       
   747     if ( callStatus != WIMI_Ok )   
       
   748         {
       
   749     	return callStatus;
       
   750         }
       
   751     
       
   752     // Find out how many certificate has zero length
       
   753     TInt certLenZero = 0;
       
   754     TInt certMalformat = 0;
       
   755     for ( TInt i = 0; i < certNum ; i++ )
       
   756 	    {
       
   757 	    WIMI_Ref_t* tempRef = NULL;
       
   758 	    WIMI_BinData_t ptLabel;
       
   759 	    WIMI_BinData_t ptKeyID;
       
   760 	    WIMI_BinData_t ptCAID;
       
   761 	    WIMI_BinData_t ptIssuerHash;
       
   762 	    WIMI_BinData_t ptTrustedUsage;
       
   763 	    TUint8 uiCDFRefs;
       
   764 	    TUint8 usage;
       
   765 	    TUint8 type;
       
   766 	    TUint16 certLen;
       
   767 	    TUint8 modifiable = 0;
       
   768 	    callStatus = WIMI_GetCertificateInfo( 
       
   769 	                                refList[i],
       
   770 	                                &tempRef,
       
   771 	                                &ptLabel,
       
   772 	                                &ptKeyID, /* Key Id (hash)*/
       
   773 	                                &ptCAID,
       
   774 	                                &ptIssuerHash,
       
   775 	                                &ptTrustedUsage,
       
   776 	                                &uiCDFRefs,
       
   777 	                                &usage,  /* 0 = client, 1 = CA */
       
   778 	                                &type,   /* WTLSCert(1), 
       
   779 	                                            X509Cert(2), 
       
   780 	                                            X968Cert(3), 
       
   781 	                                            CertURL(4) */ 
       
   782 	                                &certLen,   /* cert. content or URL length */
       
   783 	                                &modifiable );
       
   784 
       
   785 	    if ( callStatus == WIMI_Ok )
       
   786 	        {
       
   787 	        free_WIMI_Ref_t( tempRef );
       
   788 	        
       
   789 	        if ( certLen == 0 )
       
   790 	            {
       
   791 	            certLenZero++;
       
   792 	            }
       
   793 
       
   794             // it is x509cert
       
   795             if ( type == 2 && certLen != 0 )
       
   796                 {
       
   797 
       
   798                 //use this rough sanity checking
       
   799                 if ( certLen < 10 )
       
   800                     {
       
   801                     certMalformat++;
       
   802                     }
       
   803                 }
       
   804 
       
   805             WSL_OS_Free( ptLabel.pb_buf );
       
   806             WSL_OS_Free( ptKeyID.pb_buf );
       
   807             WSL_OS_Free( ptCAID.pb_buf );
       
   808             WSL_OS_Free( ptIssuerHash.pb_buf );
       
   809             WSL_OS_Free( ptTrustedUsage.pb_buf );
       
   810 	        }
       
   811 	    }
       
   812 
       
   813     // only return the number of ceritifcates that have non-zero length
       
   814     if ( callStatus == WIMI_Ok )
       
   815         {
       
   816         aCertCount = static_cast< TUint8 >( aCertCount + certNum - certLenZero - certMalformat );
       
   817         }
       
   818 
       
   819     free_WIMI_RefList_t( refList );
       
   820 
       
   821     return callStatus;
       
   822     }
       
   823 
       
   824 // -----------------------------------------------------------------------------
       
   825 // CWimCertHandler::StoreCertificateL
       
   826 // Stores certificate to the WIM card.
       
   827 // -----------------------------------------------------------------------------
       
   828 //
       
   829 void CWimCertHandler::StoreCertificateL( 
       
   830     TWimServRqst /*aOpcode*/,
       
   831     const RMessage2& aMessage ) const
       
   832     {
       
   833     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::StoreCertificateL | Begin"));
       
   834     aMessage.Complete( KErrNotSupported );
       
   835     }
       
   836 
       
   837 // -----------------------------------------------------------------------------
       
   838 // CWimCertHandler::RemoveCertificateL
       
   839 // Removes certificate from a WIM card.
       
   840 // -----------------------------------------------------------------------------
       
   841 //
       
   842 void CWimCertHandler::RemoveCertificateL( 
       
   843     const RMessage2& aMessage,
       
   844     CWimMemMgmt* /*aWimMgmt*/ ) const
       
   845     {
       
   846     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::RemoveCertificateL | Begin"));
       
   847     aMessage.Complete( KErrNotSupported );
       
   848     }
       
   849 
       
   850 // -----------------------------------------------------------------------------
       
   851 // CWimCertHandler::SanityCheck
       
   852 // -----------------------------------------------------------------------------
       
   853 //
       
   854 TBool CWimCertHandler::SanityCheck( TUint32 aCertRef )
       
   855     {
       
   856     TInt certNum = iCertRefLst.Count();
       
   857     if ( certNum == 0 )
       
   858         {
       
   859         return EFalse;
       
   860         }
       
   861     
       
   862     for ( TInt index = 0; index < certNum; ++index )
       
   863         {
       
   864         if( aCertRef == iCertRefLst[ index ] )
       
   865             {
       
   866             return ETrue;
       
   867             }
       
   868         }
       
   869     return EFalse;
       
   870     }
       
   871 
       
   872 // -----------------------------------------------------------------------------
       
   873 // CWimCertHandler::GetCertificateDetailsL
       
   874 // Fetches certificate details.
       
   875 // -----------------------------------------------------------------------------
       
   876 //
       
   877 void CWimCertHandler::GetCertificateDetailsL(
       
   878     TWimServRqst aOpCode, 
       
   879     const RMessage2& aMessage ) 
       
   880     {
       
   881     _WIMTRACE(_L("WIM | WIMServer | CWimCertHandler::GetCertificateDetailsL | Begin"));
       
   882     TBool IsOk = SanityCheck( (TUint32)aMessage.Ptr0() );
       
   883     if ( ! IsOk  )
       
   884         {
       
   885         aMessage.Panic(_L("WIM"), KErrBadHandle );
       
   886         return;
       
   887         }
       
   888     
       
   889     //capability checking
       
   890     TUint8 usage = 255;
       
   891     WIMI_STAT callStatus = ResolveCertUsage( aMessage, usage );
       
   892     if ( WIMI_Ok == callStatus )
       
   893         {
       
   894         if( !CheckReadCapsForUsage( aMessage, usage  ) )
       
   895               {
       
   896               aMessage.Complete(KErrPermissionDenied);  
       
   897               return;
       
   898               }
       
   899         }
       
   900 
       
   901     //capabilty ok, go to fetch the details of the certificate.
       
   902     WIMI_Ref_pt pCertRef = const_cast<WIMI_Ref_pt>( aMessage.Ptr0() );
       
   903     CWimResponse* responseID = new( ELeave ) CWimResponse( aMessage );
       
   904     CleanupStack::PushL( responseID );
       
   905     TWimReqTrId* trId = iWimUtilFuncs->TrIdLC( responseID, EWimMgmtReq );
       
   906     responseID->iOpcode = aOpCode;
       
   907     CleanupStack::Pop( 2, responseID ); // trId, responseID
       
   908 
       
   909     WIMI_STAT certReqStatus = WIMI_CertificateReq( trId, pCertRef );
       
   910     if ( certReqStatus != WIMI_Ok )
       
   911         {
       
   912         responseID->iStatus = certReqStatus;
       
   913         responseID->CompleteMsgAndDelete();
       
   914         delete trId;
       
   915         }
       
   916     }
       
   917 
       
   918 // -----------------------------------------------------------------------------
       
   919 // CWimCertHandler::ResolveCertUsage
       
   920 // Resolves usage (CA/User) for a certificate.
       
   921 // -----------------------------------------------------------------------------
       
   922 //
       
   923 WIMI_STAT CWimCertHandler::ResolveCertUsage( const RMessage2& aMsg,
       
   924                                         TUint8& aUsage )
       
   925     {
       
   926     _WIMTRACE(_L("CWimServer::ResolveCertUsage | Begin"));
       
   927 
       
   928     // aMsg.Ptr0 contains reference to certificate
       
   929     
       
   930     WIMI_Ref_pt pCertRef = const_cast< WIMI_Ref_pt >( aMsg.Ptr0() );
       
   931     _WIMTRACE2(_L("CWimServer::ResolveCertUsage | Begin aMsg.Ptr0() = %d"), aMsg.Ptr0());
       
   932 
       
   933     WIMI_STAT callStatus = GetCertificateInfo( pCertRef, aUsage );
       
   934 
       
   935     _WIMTRACE(_L("CWimServer::ResolveCertUsage | End"));
       
   936     return callStatus;
       
   937     }
       
   938 
       
   939 // -----------------------------------------------------------------------------
       
   940 // CWimCertHandler::GetCertificateInfo
       
   941 // Fetches certificate info. Wrapper for WIMI call.
       
   942 // -----------------------------------------------------------------------------
       
   943 //
       
   944 WIMI_STAT CWimCertHandler::GetCertificateInfo( WIMI_Ref_pt aCertRef,
       
   945                                           TUint8& aUsage )
       
   946     {
       
   947     _WIMTRACE(_L("CWimServer::GetCertificateInfo | Begin"));
       
   948 
       
   949     WIMI_Ref_pt     pWimRef = NULL;
       
   950     WIMI_BinData_t  ptLabel;
       
   951     WIMI_BinData_t  ptKeyID;
       
   952     WIMI_BinData_t  ptCAID;
       
   953     WIMI_BinData_t  ptIssuerHash;
       
   954     WIMI_BinData_t  ptTrustedUsage;
       
   955     TUint8          uiCDFRefs;
       
   956     TUint8          type;
       
   957     TUint16         certLen;
       
   958     TUint8          modifiable = 0;
       
   959     _WIMTRACE(_L("CWimServer::GetCertificateInfo | Begin 1"));
       
   960     WIMI_STAT callStatus = WIMI_GetCertificateInfo(
       
   961                                 aCertRef,
       
   962                                 &pWimRef,
       
   963                                 &ptLabel,
       
   964                                 &ptKeyID, // Key Id (hash)
       
   965                                 &ptCAID,
       
   966                                 &ptIssuerHash,
       
   967                                 &ptTrustedUsage,
       
   968                                 &uiCDFRefs,
       
   969                                 &aUsage,  // 0 = client, 1 = CA
       
   970                                 &type,    // WTLSCert(1),
       
   971                                           // X509Cert(2),
       
   972                                           // X968Cert(3),
       
   973                                           // CertURL(4)
       
   974                                 &certLen, // cert. content or URL length
       
   975                                 &modifiable );
       
   976     _WIMTRACE(_L("CWimServer::GetCertificateInfo | Begin 2"));
       
   977     // Don't need references anymore
       
   978     if ( callStatus == WIMI_Ok )
       
   979         {
       
   980         free_WIMI_Ref_t( pWimRef );
       
   981         WSL_OS_Free( ptLabel.pb_buf );
       
   982         WSL_OS_Free( ptKeyID.pb_buf );
       
   983         WSL_OS_Free( ptCAID.pb_buf );
       
   984         WSL_OS_Free( ptIssuerHash.pb_buf );
       
   985         WSL_OS_Free( ptTrustedUsage.pb_buf );
       
   986         }
       
   987 
       
   988     _WIMTRACE(_L("CWimServer::GetCertificateInfo | End"));
       
   989     return callStatus;
       
   990     }
       
   991 
       
   992 // -----------------------------------------------------------------------------
       
   993 // CWimCertHandler::GetCertificateInfo
       
   994 // Fetches certificate info. Wrapper for WIMI call.
       
   995 // -----------------------------------------------------------------------------
       
   996 //
       
   997 TBool CWimCertHandler::CheckReadCapsForUsage( const RMessage2& aMsg,
       
   998                                TUint8 aUsage )
       
   999     {
       
  1000     TBool result = EFalse;
       
  1001     
       
  1002     switch ( aUsage )
       
  1003         {
       
  1004         case WIMI_CU_CA:
       
  1005             {
       
  1006             // CA certificate reading doesn't require any capability.
       
  1007             _WIMTRACE(_L("CWimCertHandler::CheckReadCapsForUsage: CA cert read req, OK."));
       
  1008             result = ETrue;
       
  1009             break;
       
  1010             }
       
  1011         case WIMI_CU_Client:
       
  1012             {
       
  1013             // User certificate reading requires ReadUserData capability.
       
  1014             if ( aMsg.HasCapability( ECapabilityReadUserData ))
       
  1015                 {
       
  1016                 result = ETrue;
       
  1017                 _WIMTRACE(_L("CWimCertHandler::CheckReadCapsForUsage: User cert read capa PASS"));
       
  1018                 }
       
  1019             else
       
  1020                 {
       
  1021                 result = EFalse;
       
  1022                 _WIMTRACE(_L("CWimCertHandler::CheckReadCapsForUsage: User cert read capa FAIL"));
       
  1023                 }
       
  1024             break;
       
  1025             }
       
  1026         default:
       
  1027             {
       
  1028             _WIMTRACE(_L("CWimCertHandler::CheckReadCapsAccordingToUsage: FAIL:Unknown usage."));
       
  1029             result = EFalse;
       
  1030             break;
       
  1031             }
       
  1032         }
       
  1033     _WIMTRACE(_L("CWimCertHandler::CheckReadCapsForUsage | End"));
       
  1034     return result;
       
  1035     }
       
  1036 
       
  1037 // -----------------------------------------------------------------------------
       
  1038 // CWimCertHandler::ExportPublicKeyL
       
  1039 // Export public key from certificate.
       
  1040 // -----------------------------------------------------------------------------
       
  1041 //
       
  1042 void CWimCertHandler::ExportPublicKeyL( const RMessage2& aMessage ) const
       
  1043     {
       
  1044     _WIMTRACE(_L("WIM | WIMServer | CWimPublicKeyHandler::ExportPublicKeyParamsL | Begin"));
       
  1045 
       
  1046     TUint8 certType = 0;
       
  1047 
       
  1048     TPckgBuf<TExportPublicKey> keyExportPckg;
       
  1049     aMessage.ReadL( 0, keyExportPckg );
       
  1050     
       
  1051     HBufC8* publicKeyBuf = HBufC8::NewLC( KPublicKeyLength );
       
  1052 
       
  1053     TBuf8<KKeyIdLen> keyIdBuf = keyExportPckg().iKeyId;
       
  1054 
       
  1055     WIMI_STAT callStatus = WIMI_Ok;
       
  1056     WIMI_BinData_t ptCertData;
       
  1057     ptCertData.pb_buf = NULL;
       
  1058     ptCertData.ui_buf_length = 0;
       
  1059     WIMI_Ref_t* pCert = NULL;
       
  1060     WIMI_TransactId_t trId = ( void* )EInitializationCertListHashing;
       
  1061     TUint8 certCount = 0;
       
  1062     WIMI_RefList_t certRefList = NULL;
       
  1063 
       
  1064     // Check firs the Client certs
       
  1065     callStatus = WIMI_GetCertificateListByKeyHash( ( TUint8* )keyIdBuf.Ptr(),
       
  1066                                                    WIMI_CU_Client,
       
  1067                                                    &certCount,
       
  1068                                                    &certRefList );
       
  1069     if ( callStatus == WIMI_Ok )
       
  1070         {
       
  1071         if ( certCount == 0 ) // Not found client certs
       
  1072             {
       
  1073             free_WIMI_RefList_t( certRefList );
       
  1074             certRefList = NULL;
       
  1075 
       
  1076             // Check CA certs
       
  1077             callStatus = WIMI_GetCertificateListByKeyHash(
       
  1078                                                     ( TUint8* )keyIdBuf.Ptr(),
       
  1079                                                     WIMI_CU_CA,
       
  1080                                                     &certCount,
       
  1081                                                     &certRefList );
       
  1082             }
       
  1083         }
       
  1084 
       
  1085     if ( callStatus == WIMI_Ok )
       
  1086         {
       
  1087         CleanupPushWimRefListL( certRefList );
       
  1088         if ( certCount == 0 ) // No certificates found for key
       
  1089             {
       
  1090             CleanupStack::PopAndDestroy( certRefList );
       
  1091             callStatus = WIMI_ERR_CertNotFound;
       
  1092             }
       
  1093         }
       
  1094 
       
  1095     if ( callStatus == WIMI_Ok )
       
  1096         {
       
  1097         WIMI_Ref_t* tempRef = NULL;
       
  1098         WIMI_BinData_t ptLabel;
       
  1099         WIMI_BinData_t ptKeyID;
       
  1100         WIMI_BinData_t ptCAID;
       
  1101         WIMI_BinData_t ptIssuerHash;
       
  1102         WIMI_BinData_t ptTrustedUsage;
       
  1103         TUint8 uiCDFRefs;
       
  1104         TUint8 usage;
       
  1105 
       
  1106         TUint16 certLen;
       
  1107         TUint8 modifiable = 0;
       
  1108 
       
  1109         for ( TInt i = 0; i < certCount; i++ )
       
  1110             {
       
  1111             // Get info for each certificate until we find valid cert
       
  1112             callStatus = WIMI_GetCertificateInfo( certRefList[i],
       
  1113                                                   &tempRef,
       
  1114                                                   &ptLabel,
       
  1115                                                   &ptKeyID,
       
  1116                                                   &ptCAID,
       
  1117                                                   &ptIssuerHash,
       
  1118                                                   &ptTrustedUsage,
       
  1119                                                   &uiCDFRefs,
       
  1120                                                   &usage,
       
  1121                                                   &certType,   
       
  1122                                                   &certLen,
       
  1123                                                   &modifiable );
       
  1124             if ( callStatus == WIMI_Ok )
       
  1125                 {
       
  1126                 WSL_OS_Free( ptLabel.pb_buf );
       
  1127                 WSL_OS_Free( ptKeyID.pb_buf );
       
  1128                 WSL_OS_Free( ptCAID.pb_buf );
       
  1129                 WSL_OS_Free( ptIssuerHash.pb_buf );
       
  1130                 WSL_OS_Free( ptTrustedUsage.pb_buf );
       
  1131                 free_WIMI_Ref_t( tempRef );
       
  1132 
       
  1133                 // Certificate has to be WTLS or X509, not URL
       
  1134                 if ( certType == WIMI_CT_X509 || certType == WIMI_CT_WTLS )
       
  1135                     {
       
  1136                     pCert = certRefList[i]; // Found one
       
  1137                     i = certCount; // Stop looping
       
  1138                     }
       
  1139                 else // Cert not supported
       
  1140                     {
       
  1141                     callStatus = WIMI_ERR_UnsupportedCertificate;
       
  1142                     }
       
  1143                 }
       
  1144             }
       
  1145     
       
  1146         // Retrieve certificate data from WIM
       
  1147         if ( callStatus == WIMI_Ok )
       
  1148             {
       
  1149             callStatus = WIMI_CertificateReqT( trId, pCert, &ptCertData );
       
  1150             if ( callStatus == WIMI_Ok )
       
  1151                 {
       
  1152                 CleanupPushWimBufL( ptCertData );
       
  1153 
       
  1154                 TPtrC8 certPtr( ptCertData.pb_buf, ptCertData.ui_buf_length );
       
  1155                 TPtr8 publicKeyPtr = publicKeyBuf->Des();
       
  1156 
       
  1157                 TRAPD( parseOk, ParseCertPublicKeyL( certPtr, publicKeyPtr, certType ) );
       
  1158                 if ( parseOk )
       
  1159                     {
       
  1160                     aMessage.WriteL( 1, publicKeyPtr );
       
  1161                     }
       
  1162                 else
       
  1163                     {
       
  1164                     callStatus = WIMI_ERR_CertParseError;
       
  1165                     }
       
  1166 
       
  1167                 CleanupStack::PopAndDestroy( ptCertData.pb_buf );
       
  1168                 }
       
  1169             }
       
  1170         
       
  1171         CleanupStack::PopAndDestroy( certRefList );
       
  1172         }
       
  1173 
       
  1174     CleanupStack::PopAndDestroy( publicKeyBuf );
       
  1175 
       
  1176     aMessage.Complete( CWimUtilityFuncs::MapWIMError( callStatus ) );
       
  1177     }
       
  1178 
       
  1179 // -----------------------------------------------------------------------------
       
  1180 // CWimCertHandler::ParseCertPublicKeyL
       
  1181 // Parse public key from certificate.
       
  1182 // -----------------------------------------------------------------------------
       
  1183 //
       
  1184 void CWimCertHandler::ParseCertPublicKeyL(
       
  1185     const TDesC8& aCertData,
       
  1186     TDes8& aPublicKey,
       
  1187     const TUint8 aCertType ) const
       
  1188     {
       
  1189     CCertificate* certificate = NULL;
       
  1190     CRSAPublicKey* publicKey = NULL;
       
  1191 
       
  1192     switch ( aCertType )
       
  1193         {
       
  1194         case WIMI_CT_WTLS:
       
  1195             {
       
  1196             certificate = CWTLSCertificate::NewLC( aCertData );
       
  1197             publicKey = CWTLSRSAPublicKey::NewLC( certificate->PublicKey().KeyData() );
       
  1198             break;
       
  1199             }
       
  1200     
       
  1201         case WIMI_CT_X509:
       
  1202             {
       
  1203             certificate = CX509Certificate::NewLC( aCertData );
       
  1204             publicKey = CX509RSAPublicKey::NewLC( certificate->PublicKey().KeyData() );
       
  1205             break;
       
  1206             }
       
  1207         default:
       
  1208             {
       
  1209             _WIMTRACE2(_L("WIM|WIMServer|CWimCertHandler::ParseCertPublicKeyL, type %d not supported"), aCertType);
       
  1210             User::Leave( KErrNotSupported );
       
  1211             break;
       
  1212             }
       
  1213         }
       
  1214 
       
  1215     TX509RSAKeyEncoder encoder( *publicKey, ESHA1 );
       
  1216     CASN1EncBase* encoded = encoder.EncodeKeyLC();
       
  1217 
       
  1218     TUint pos = 0;
       
  1219     aPublicKey.SetLength( KPublicKeyLength );
       
  1220     // Check that Max. length is not exceeded
       
  1221     if ( encoded->LengthDER() > static_cast< TUint >( KPublicKeyLength ) )
       
  1222         {
       
  1223         _WIMTRACE(_L("WIM|WIMServer|CWimCertHandler::ParseCertPublicKeyL, too long public key"));
       
  1224         User::Leave( KErrBadDescriptor );
       
  1225         }
       
  1226     // Write encoded key to prealloced buffer
       
  1227     encoded->WriteDERL( aPublicKey, pos );
       
  1228 
       
  1229     CleanupStack::PopAndDestroy( 3, certificate );  // encoded, publicKey, certificate
       
  1230     }
       
  1231 
       
  1232 //  End of File