wim/WimServer/src/WimSignTextHandler.cpp
changeset 0 164170e6151a
equal deleted inserted replaced
-1:000000000000 0:164170e6151a
       
     1 /*
       
     2 * Copyright (c) 2003 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:  Services for Sign Text operation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include    "WimServer.h"
       
    22 #include    "Wimi.h"            // WIMI definitions
       
    23 #include    "WimClsv.h"
       
    24 #include    "WimSignTextHandler.h"
       
    25 #include    "WimSecurityDlgHandler.h"
       
    26 #include    "WimCallbackImpl.h"
       
    27 #include    "WimTrace.h"
       
    28 #include    "WimCleanup.h"
       
    29 #include    <secdlg.h>
       
    30 
       
    31 #ifdef _DEBUG
       
    32 _LIT( KWimSignTextPanic, "WimSignText" );
       
    33 #endif
       
    34 
       
    35 //In secdlg.h Maxlength is defined as 32, which disobeies WIM standard.
       
    36 //According to WIM standard Pin length should be 4~8
       
    37 const TInt KWIMMaxPINLength = 8;
       
    38 // ============================ MEMBER FUNCTIONS ===============================
       
    39 
       
    40 // -----------------------------------------------------------------------------
       
    41 // CWimSignTextHandler::CWimSignTextHandler
       
    42 // C++ default constructor can NOT contain any code, that
       
    43 // might leave.
       
    44 // -----------------------------------------------------------------------------
       
    45 //
       
    46 CWimSignTextHandler::CWimSignTextHandler() : CActive( EPriorityStandard )
       
    47     {
       
    48     _WIMTRACE(_L("WIM | WIMServer | CWimSignTextHandler::CWimSignTextHandler | Begin"));
       
    49     }
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // CWimSignTextHandler::ConstructL
       
    53 // Symbian 2nd phase constructor can leave.
       
    54 // -----------------------------------------------------------------------------
       
    55 //
       
    56 void CWimSignTextHandler::ConstructL()
       
    57     {
       
    58     _WIMTRACE(_L("WIM | WIMServer | CWimSignTextHandler::ConstructL | Begin"));
       
    59     CActiveScheduler::Add( this );
       
    60     iWimUtilFuncs = CWimUtilityFuncs::NewL();
       
    61     iWimSecDlg = CWimSecurityDlgHandler::NewL();
       
    62     }
       
    63 
       
    64 // -----------------------------------------------------------------------------
       
    65 // CWimAuthObjHandler::NewL
       
    66 // Two-phased constructor.
       
    67 // -----------------------------------------------------------------------------
       
    68 //
       
    69 CWimSignTextHandler* CWimSignTextHandler::NewL()
       
    70     {
       
    71     _WIMTRACE(_L("WIM | WIMServer | CWimSignTextHandler::NewL | Begin"));
       
    72     CWimSignTextHandler* self = new( ELeave ) CWimSignTextHandler;
       
    73     CleanupStack::PushL( self );
       
    74     self->ConstructL();
       
    75     CleanupStack::Pop( self );
       
    76     return self;
       
    77     }
       
    78 
       
    79 // Destructor
       
    80 CWimSignTextHandler::~CWimSignTextHandler()
       
    81     {
       
    82     _WIMTRACE(_L("WIM | WIMServer | CWimSignTextHandler::~CWimAuthObjHandler | Begin"));
       
    83     Cancel();
       
    84     CleanUp();      // frees iSigningDataBuf, iSigningDataPtr, and iKeyReference
       
    85     delete iWimUtilFuncs;
       
    86     delete iWimSecDlg;
       
    87     // iResponseID and iTrId are deleted in callback functions
       
    88     }
       
    89 
       
    90 // -----------------------------------------------------------------------------
       
    91 // CWimSignTextHandler::SignTextL
       
    92 // Sign given text. Response is handled in CWimCallback if operation is given
       
    93 // to card. Otherwise message is completed here with error value.
       
    94 // -----------------------------------------------------------------------------
       
    95 //
       
    96 void CWimSignTextHandler::SignTextL( const RMessage2& aMessage )
       
    97     {
       
    98     _WIMTRACE(_L("WIM | WIMServer | CWimSignTextHandler::SignTextL | Begin"));
       
    99 
       
   100     __ASSERT_DEBUG( iResponseID == NULL, User::Panic( KWimSignTextPanic, KErrGeneral ) );
       
   101     iResponseID = new( ELeave ) CWimResponse( aMessage );
       
   102     iResponseID->iOpcode = ESignTextReq;
       
   103 
       
   104     __ASSERT_DEBUG( iTrId == NULL, User::Panic( KWimSignTextPanic, KErrGeneral ) );
       
   105     iTrId = iWimUtilFuncs->TrIdLC( iResponseID, EWimMgmtReq );
       
   106     CleanupStack::Pop( iTrId );
       
   107 
       
   108     TPckgBuf<TKeySignParameters> signPckg;
       
   109     aMessage.ReadL( 1, signPckg );
       
   110 
       
   111     // Data to be signed
       
   112     iSigningDataBuf = iWimUtilFuncs->DesLC( 2, aMessage );
       
   113     CleanupStack::Pop( iSigningDataBuf );
       
   114     
       
   115     iSigningDataPtr = new( ELeave ) TPtr8( iSigningDataBuf->Des() );
       
   116     
       
   117     // Key ID
       
   118     TBuf8<KKeyIdLen> keyIdBuf = signPckg().iKeyId;
       
   119     TPtr8 keyIdHash( const_cast<TUint8*>( keyIdBuf.Ptr() ), keyIdBuf.Length() );
       
   120     WIMI_Ref_t* keyRef;
       
   121     WIMI_GetKeyByHash( ( TUint8* )keyIdHash.Ptr(), &keyRef );
       
   122     iKeyReference = ( TAny* )keyRef; // Key reference
       
   123 
       
   124     iRetry = EFalse;
       
   125     GetPinParamsL( iPinParams ); // Get PIN parameters
       
   126 
       
   127     AskPin(); // Ask PIN
       
   128     }
       
   129 
       
   130 // -----------------------------------------------------------------------------
       
   131 // CWimSignTextHandler::AskPin
       
   132 // Ask PIN from user
       
   133 // -----------------------------------------------------------------------------
       
   134 //
       
   135 void CWimSignTextHandler::AskPin()
       
   136     {
       
   137     TBool IsWIMOpen = EFalse;
       
   138     iSigningState = EAskPin;
       
   139     iStatus = KRequestPending;
       
   140     SetActive();
       
   141     
       
   142    	_WIMTRACE(_L("WIM | WIMServer | CWimSignTextHandler::AskPin "));
       
   143     WIMI_Ref_pt pWimRefTemp = NULL;
       
   144     pWimRefTemp = WIMI_GetWIMRef( 0 );
       
   145  
       
   146     if ( pWimRefTemp )  // Close the WIM
       
   147        {
       
   148        if ( WIMI_IsWIMOpened( pWimRefTemp ) )
       
   149            {
       
   150        	   IsWIMOpen = ETrue;
       
   151            }
       
   152        free_WIMI_Ref_t( pWimRefTemp );
       
   153        }
       
   154     
       
   155     if( IsWIMOpen )
       
   156     	{
       
   157     	TRequestStatus* status = &iStatus;
       
   158         User::RequestComplete( status, KErrNone );
       
   159     	}
       
   160     else
       
   161     	{
       
   162     	iWimSecDlg->EnterPIN( iRetry,
       
   163         	                  iPinParams,
       
   164         	                  iSigningPin, 
       
   165         	                  iStatus );	
       
   166     	}
       
   167     }
       
   168 
       
   169 // -----------------------------------------------------------------------------
       
   170 // CWimSignTextHandler::GetPinParamsL
       
   171 // Get parameters for PIN. iKeyReferense has to be set before this function
       
   172 // is used.
       
   173 // -----------------------------------------------------------------------------
       
   174 //
       
   175 void CWimSignTextHandler::GetPinParamsL( TPINParams& aPinParams ) const
       
   176     {
       
   177     TInt pushed = 0;
       
   178     TPINLabel pinLabel;    // The label that identifies the PIN
       
   179 	TPINLabel tokenLabel;  // The label of the token
       
   180 	TUint8 minLength = 0;  // The minimum length of the PIN
       
   181 
       
   182     WIMI_STAT status = WIMI_Ok;
       
   183 
       
   184     // WIMI_GetKeyInfo()
       
   185     WIMI_Ref_t* pWimRef;    
       
   186     TUint8 keyType;
       
   187     TUint8 keyNumber;
       
   188     TUint8 pinNumber;
       
   189     TUint16 usage;
       
   190     TUint16 keyLength;
       
   191     WIMI_BinData_t ptKeyLabel;
       
   192     WIMI_BinData_t ptKeyId;
       
   193     // WIMI_GetPINList()
       
   194     WIMI_Ref_pt pPinRef = NULL;
       
   195     TUint16 pinNum;
       
   196     WIMI_RefList_t pinRefLst;
       
   197     // WIMI_GetPINStatus()
       
   198     TUint8 flags;
       
   199     WIMI_BinData_t ptPinLabel;
       
   200     WIMI_Ref_t* cmeWimRef = NULL;
       
   201     // WIMI_GetWIMInfo()
       
   202     TUint16 wimFlags;
       
   203     TUint8 seSet;
       
   204     TUint8 version;
       
   205     WIMI_BinData_t ptWimID;
       
   206     WIMI_BinData_t ptManufacturerID;
       
   207     WIMI_BinData_t ptWimLabel;
       
   208     TUint8 reader = 0; 
       
   209     TBool sim; 
       
   210 
       
   211     // Get PIN number by Key reference
       
   212     status = WIMI_GetKeyInfo( iKeyReference,
       
   213                               &pWimRef,
       
   214                               NULL,
       
   215                               &keyType,
       
   216                               &keyNumber,
       
   217                               &pinNumber,
       
   218                               &usage,
       
   219                               &ptKeyId,
       
   220                               &ptKeyLabel,
       
   221                               &keyLength );
       
   222     if ( status != WIMI_Ok )
       
   223         {
       
   224         User::Leave( CWimUtilityFuncs::MapWIMError( status ) );
       
   225         }
       
   226 
       
   227     // TODO: leaving PushL functions should not be used
       
   228 
       
   229     CleanupPushWimRefL( pWimRef );
       
   230     pushed++;
       
   231     CleanupPushWimBufL( ptKeyId );
       
   232     pushed++;
       
   233     CleanupPushWimBufL( ptKeyLabel );
       
   234     pushed++;
       
   235     
       
   236     // Get PIN references
       
   237     status = WIMI_GetPINList( pWimRef, &pinNum, &pinRefLst );
       
   238     if ( status == WIMI_Ok )
       
   239         {
       
   240         // Select right reference by PIN number
       
   241         pPinRef = pinRefLst[pinNumber];
       
   242         }
       
   243     CleanupPushWimRefListL( pinRefLst );
       
   244     pushed++;
       
   245 
       
   246     if ( pPinRef )
       
   247         {
       
   248         // Get PIN info (label, min length etc.)
       
   249         status = WIMI_GetPINStatus( pPinRef,
       
   250                                     &cmeWimRef,
       
   251                                     &flags,
       
   252                                     &minLength,
       
   253                                     &pinNumber,
       
   254                                     &ptPinLabel );
       
   255         if ( status != WIMI_Ok )
       
   256             {
       
   257             User::Leave( CWimUtilityFuncs::MapWIMError( status ) );
       
   258             }
       
   259         CleanupPushWimRefL( cmeWimRef );
       
   260         pushed++;
       
   261         CleanupPushWimBufL( ptPinLabel );
       
   262         pushed++;
       
   263 
       
   264         HBufC8* pinLabelBuf = HBufC8::NewLC( ptPinLabel.ui_buf_length );
       
   265         pushed++;
       
   266 
       
   267         TPtr8 pinPtr = pinLabelBuf->Des();
       
   268         pinPtr.Copy( ptPinLabel.pb_buf, ptPinLabel.ui_buf_length );
       
   269         pinLabel.Copy( pinPtr );
       
   270         }
       
   271     else
       
   272         {
       
   273         User::Leave( KErrArgument );
       
   274         }
       
   275 
       
   276     // Get token label
       
   277     status = WIMI_GetWIMInfo( cmeWimRef,
       
   278                               &wimFlags,
       
   279                               &seSet,
       
   280                               &ptWimID,
       
   281                               &ptManufacturerID,
       
   282                               &ptWimLabel,
       
   283                               &reader, 
       
   284                               &pPinRef, 
       
   285                               &sim, 
       
   286                               &version );
       
   287     if ( status != WIMI_Ok )
       
   288         {
       
   289         User::Leave( CWimUtilityFuncs::MapWIMError( status ) );
       
   290         }
       
   291     CleanupPushWimBufL( ptWimLabel );
       
   292     pushed++;
       
   293     CleanupPushWimBufL( ptWimID );
       
   294     pushed++;
       
   295     CleanupPushWimBufL( ptManufacturerID );
       
   296     pushed++;
       
   297 
       
   298     HBufC8* wimLabelBuf = HBufC8::NewLC( ptWimID.ui_buf_length );
       
   299     pushed++;
       
   300 
       
   301     TPtr8 wimLabelPtr( wimLabelBuf->Des() );
       
   302     wimLabelPtr.Copy( ptWimLabel.pb_buf, ptWimLabel.ui_buf_length );
       
   303 
       
   304     tokenLabel.Copy( wimLabelPtr ); // Copy token label
       
   305     
       
   306     aPinParams.iPINLabel = pinLabel;
       
   307     aPinParams.iTokenLabel = tokenLabel;
       
   308     aPinParams.iMinLength = minLength;
       
   309     aPinParams.iMaxLength = KWIMMaxPINLength; // Use max value
       
   310 
       
   311     CleanupStack::PopAndDestroy( pushed, pWimRef );
       
   312     }
       
   313 
       
   314 // -----------------------------------------------------------------------------
       
   315 // CWimSignTextHandler::ContinueSigningL
       
   316 // Continues signing operation after signing PIN has asked from user.
       
   317 // Call WIMI and return error code in iStatus in case digital signature
       
   318 // can not be done e.g. wrong PIN has entered.
       
   319 // -----------------------------------------------------------------------------
       
   320 //
       
   321 void CWimSignTextHandler::ContinueSigningL()
       
   322     {
       
   323     _WIMTRACE(_L("WIM|WIMServer|CWimSignTextHandler::ContinueSigningL|Begin"));
       
   324 
       
   325     WIMI_BinData_t pPin;
       
   326 
       
   327     // Copy signing PIN to 8 bit buffer
       
   328     HBufC8* signingPinBuf = HBufC8::NewLC( iSigningPin.Length() );
       
   329     TPtr8 signingPin = signingPinBuf->Des();
       
   330     signingPin.Copy( iSigningPin );
       
   331     pPin.pb_buf = ( TUint8* )signingPin.Ptr();
       
   332     pPin.ui_buf_length = ( TUint16 )signingPin.Length();
       
   333 
       
   334     iStatus = KRequestPending;
       
   335     TRequestStatus* status = &iStatus;
       
   336     iSigningState = ECallbackResponse;
       
   337     SetActive();
       
   338 
       
   339     iResponseID->iStatus = WIMI_SignReq( iTrId,
       
   340                                          ( TUint8* )iSigningDataPtr->Ptr(),
       
   341                                          ( TUint8 )iSigningDataPtr->Length(),
       
   342                                          iKeyReference,
       
   343                                          &pPin );
       
   344 
       
   345     CleanupStack::PopAndDestroy( signingPinBuf );
       
   346     
       
   347     // Some error in WIMI (no connection to card etc.) 
       
   348     // Request not completed by callback function
       
   349     if ( iResponseID->iStatus != WIMI_Ok )
       
   350         {
       
   351         iSigningState = EWimiError;
       
   352         User::RequestComplete( status, iResponseID->iStatus );
       
   353         }
       
   354     }
       
   355 
       
   356 // -----------------------------------------------------------------------------
       
   357 // CWimSignTextHandler::CleanUp
       
   358 // Clean up member data
       
   359 // -----------------------------------------------------------------------------
       
   360 //
       
   361 void CWimSignTextHandler::CleanUp()
       
   362     {
       
   363     if( iSigningDataBuf )
       
   364         {
       
   365         delete iSigningDataBuf;
       
   366         iSigningDataBuf = NULL;	
       
   367         }
       
   368     
       
   369     if( iSigningDataPtr )
       
   370         {
       
   371         delete iSigningDataPtr;
       
   372         iSigningDataPtr = NULL;	
       
   373         }
       
   374     
       
   375     WIMI_Ref_t* keyRef = iKeyReference;
       
   376     free_WIMI_Ref_t( keyRef );
       
   377     }
       
   378 
       
   379 // -----------------------------------------------------------------------------
       
   380 // CWimSignTextHandler::RunL
       
   381 // Handle digital signature operation as state machine. Handle different
       
   382 // states here.
       
   383 // -----------------------------------------------------------------------------
       
   384 //
       
   385 void CWimSignTextHandler::RunL()
       
   386     {
       
   387     _WIMTRACE2(_L("WIM|WIMServer|CWimSignTextHandler::RunL|status=%d"), iStatus.Int());
       
   388 
       
   389     switch ( iSigningState )
       
   390         {
       
   391         // PIN asked
       
   392         case EAskPin:
       
   393             {       
       
   394             iRetry = ETrue; // Next is retry
       
   395 
       
   396             if ( iStatus.Int() != KErrNone ) // Cancelled or other error
       
   397                 {
       
   398                 if( iResponseID )
       
   399                     {
       
   400                     if( iStatus.Int() == KErrCancel )
       
   401 	                	{
       
   402 	                	iResponseID->iStatus = WIMI_ERR_UserCancelled;
       
   403 	                	}
       
   404                     else
       
   405 	                	{
       
   406 	                	iResponseID->iStatus = ( TUint16 )iStatus.Int();	
       
   407 	                	}
       
   408                     iResponseID->CompleteMsgAndDelete();
       
   409                     iResponseID = NULL;	
       
   410                     }
       
   411                 
       
   412                 if( iTrId )
       
   413                     {
       
   414                     delete iTrId;
       
   415                     iTrId = NULL;	
       
   416                     }
       
   417                 
       
   418                 CleanUp();
       
   419                 }
       
   420             else  // User entered PIN without errors
       
   421                 {
       
   422                 CWimCallBack::SetSignTextRequestStatus( &iStatus );
       
   423                 ContinueSigningL(); // Continue digital signature operation
       
   424                 }
       
   425             break;
       
   426             }
       
   427         
       
   428         // We come here from CWimCallBack::SignResp()
       
   429         case ECallbackResponse:
       
   430             {
       
   431             CWimCallBack::SetSignTextRequestStatus( NULL );
       
   432 
       
   433             if ( iStatus.Int() == WIMI_ERR_BadPIN ) // Wrong PIN, continue
       
   434                 {
       
   435                 AskPin(); // Ask PIN again and continue
       
   436                 }
       
   437             // If PIN is blocked show note
       
   438             else if ( iStatus.Int() == WIMI_ERR_PINBlocked )
       
   439                 {
       
   440                 iSigningState = EShowPinBlocked;
       
   441                 iWimSecDlg->ShowPINBlocked( iPinParams, iStatus );
       
   442                 SetActive();
       
   443                 }
       
   444              else if ( iStatus.Int() == WIMI_ERR_CardIOError )
       
   445                     {
       
   446                     iSigningState = EShowCardIsRemoved;
       
   447 	                  iStatus = KRequestPending;
       
   448                     TRequestStatus* status = &iStatus;
       
   449                     SetActive();
       
   450                     User::RequestComplete( status, KErrNone );
       
   451                 	  }
       
   452             else // Response completed in callbacks, just finalize operation 
       
   453                 {
       
   454                 iStatus = KRequestPending;
       
   455                 iSigningState = ESigningDone;
       
   456                 TRequestStatus* status = &iStatus;
       
   457                 SetActive();
       
   458                 User::RequestComplete( status, KErrNone );
       
   459                 }
       
   460             break;
       
   461             }
       
   462 
       
   463         // PIN Blocked note showed to user
       
   464         case EShowPinBlocked:
       
   465             {
       
   466             // Complete message here with KErrLocked
       
   467             if( iResponseID )
       
   468                 {
       
   469                 iResponseID->iStatus = WIMI_ERR_PINBlocked;
       
   470                 iResponseID->CompleteMsgAndDelete();
       
   471                 iResponseID = NULL;	
       
   472                 }
       
   473             
       
   474             if( iTrId )
       
   475                 {
       
   476                 delete iTrId;
       
   477                 iTrId = NULL;	
       
   478                 }
       
   479             
       
   480             iStatus = KRequestPending;
       
   481             iSigningState = ESigningDone;
       
   482             TRequestStatus* status = &iStatus;
       
   483             SetActive();
       
   484             User::RequestComplete( status, KErrNone );
       
   485             break;
       
   486             }
       
   487         case EShowCardIsRemoved:
       
   488                {
       
   489                if( iResponseID )
       
   490                         {
       
   491                         iResponseID->iStatus = WIMI_ERR_CardIOError;
       
   492                     	iResponseID->CompleteMsgAndDelete();
       
   493                     	iResponseID = NULL;	
       
   494                         }
       
   495                 	if( iTrId )
       
   496                 		{
       
   497                 		delete iTrId;
       
   498                     	iTrId = NULL;	
       
   499                 		}
       
   500                
       
   501                iStatus = KRequestPending;
       
   502                iSigningState = ESigningDone;
       
   503                TRequestStatus* status = &iStatus;
       
   504                SetActive();
       
   505                User::RequestComplete( status, KErrNone );
       
   506                break;
       
   507                }            
       
   508         // WIMI error. Message is not completed in callback function.
       
   509         // So, complete it here
       
   510         case EWimiError:
       
   511             {
       
   512             CWimCallBack::SetSignTextRequestStatus( NULL );
       
   513             
       
   514             if( iResponseID )
       
   515                 {
       
   516                 iResponseID->iStatus = ( TUint16 )iStatus.Int();
       
   517                 iResponseID->CompleteMsgAndDelete();
       
   518                 iResponseID = NULL;	
       
   519                 }
       
   520             if ( iTrId )
       
   521                 {
       
   522                 delete iTrId;
       
   523                 iTrId = NULL;	
       
   524                 }
       
   525            
       
   526             CleanUp();
       
   527             break;
       
   528             }
       
   529         
       
   530         // Text is signed, handle response in callback functions
       
   531         case ESigningDone:
       
   532             {
       
   533             CleanUp();
       
   534             iResponseID = NULL;
       
   535             iTrId = NULL;
       
   536             break;
       
   537             }    
       
   538 
       
   539         default:
       
   540             {
       
   541             CleanUp();
       
   542             break;
       
   543             }
       
   544         }
       
   545     }
       
   546 
       
   547 // -----------------------------------------------------------------------------
       
   548 // CWimSignTextHandler::DoCancel
       
   549 // Asyncronous call cancelled.
       
   550 // -----------------------------------------------------------------------------
       
   551 //
       
   552 void CWimSignTextHandler::DoCancel()
       
   553     {
       
   554     _WIMTRACE(_L("WIM|WIMServer|CWimSignTextHandler::DoCancel|Begin"));
       
   555     }
       
   556 
       
   557 // -----------------------------------------------------------------------------
       
   558 // CWimSignTextHandler::RunError
       
   559 // RunL leaved, handle error here.
       
   560 // -----------------------------------------------------------------------------
       
   561 //
       
   562 TInt CWimSignTextHandler::RunError( TInt aError )
       
   563     {
       
   564     CWimCallBack::SetSignTextRequestStatus( NULL );
       
   565     if( iResponseID )
       
   566         {
       
   567         iResponseID->iStatus = ( TUint16 )aError;
       
   568         iResponseID->CompleteMsgAndDelete();
       
   569         iResponseID = NULL;	
       
   570         }
       
   571     if( iTrId )
       
   572         {
       
   573    	    delete iTrId;
       
   574         iTrId = NULL;
       
   575         }
       
   576     
       
   577     CleanUp();
       
   578     return KErrNone;
       
   579     }
       
   580 
       
   581 //  End of File