os/security/cryptoservices/certificateandkeymgmt/certstore/CCheckedCertStore.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
#include "CCheckedCertStore.h"
sl@0
    20
sl@0
    21
#include <signed.h>
sl@0
    22
#include <x509cert.h>
sl@0
    23
#include <x509certext.h>
sl@0
    24
#include <wtlscert.h>
sl@0
    25
#include <x509keys.h>
sl@0
    26
#include <securityerr.h>
sl@0
    27
sl@0
    28
#include "certificateapps.h"
sl@0
    29
sl@0
    30
_LIT(KPanicCategory, "CCheckedCertStore");
sl@0
    31
#define assert(x) __ASSERT_ALWAYS((x), User::Panic(KPanicCategory, 1));
sl@0
    32
sl@0
    33
/////////////////////////////////////////////////////////////////////
sl@0
    34
//	CCheckedCertStore
sl@0
    35
/////////////////////////////////////////////////////////////////////
sl@0
    36
sl@0
    37
CCheckedCertStore::~CCheckedCertStore()
sl@0
    38
    {
sl@0
    39
    Cancel();
sl@0
    40
    Cleanup();
sl@0
    41
    
sl@0
    42
	// Release the cert store - no need to release the token since this would
sl@0
    43
	// have been done as part of MCTTokenInterface::Release()
sl@0
    44
    iCertStore.Release();
sl@0
    45
sl@0
    46
	iFs.Close();
sl@0
    47
    }
sl@0
    48
sl@0
    49
CCheckedCertStore::CCheckedCertStore(MCTCertStore& aTokenIF, RProperty& aProperty)
sl@0
    50
:	CActive(EPriorityStandard), 
sl@0
    51
	iCertStore(aTokenIF),
sl@0
    52
	iPSCertstoreChangePropertyRef(aProperty)	
sl@0
    53
    {
sl@0
    54
	// need to add reference since we now have the token
sl@0
    55
	iCertStore.Token().AddRef();
sl@0
    56
    }
sl@0
    57
sl@0
    58
CCheckedCertStore::CCheckedCertStore(MCTWritableCertStore& aTokenIF, RProperty& aProperty)
sl@0
    59
:	CActive(EPriorityStandard),
sl@0
    60
	iCertStore(aTokenIF),
sl@0
    61
	iWritableCertStore(&aTokenIF),
sl@0
    62
	iPSCertstoreChangePropertyRef(aProperty)
sl@0
    63
    {
sl@0
    64
	// need to add reference since we now have the token
sl@0
    65
	iCertStore.Token().AddRef();
sl@0
    66
    }
sl@0
    67
sl@0
    68
/*static*/ CCheckedCertStore* CCheckedCertStore::NewCheckedCertStoreL(MCTTokenInterface* aTokenIF, RProperty& aProperty)
sl@0
    69
    {
sl@0
    70
    assert(aTokenIF);
sl@0
    71
	MCTCertStore& tokenInterface = static_cast<MCTCertStore&>(*aTokenIF);
sl@0
    72
	CCheckedCertStore* me = new (ELeave) CCheckedCertStore(tokenInterface, aProperty);
sl@0
    73
    CleanupReleasePushL(*me);
sl@0
    74
    me->ConstructL();
sl@0
    75
    CleanupStack::Pop();
sl@0
    76
	return (me);
sl@0
    77
    }
sl@0
    78
	
sl@0
    79
/*static*/ CCheckedCertStore* CCheckedCertStore::NewCheckedWritableCertStoreL(MCTTokenInterface* aTokenIF, RProperty& aProperty)
sl@0
    80
    {
sl@0
    81
    assert(aTokenIF);
sl@0
    82
	MCTWritableCertStore& tokenInterface = static_cast<MCTWritableCertStore&>(*aTokenIF);
sl@0
    83
	CCheckedCertStore* me = new (ELeave) CCheckedCertStore(tokenInterface, aProperty);
sl@0
    84
    CleanupReleasePushL(*me);
sl@0
    85
    me->ConstructL();
sl@0
    86
    CleanupStack::Pop();
sl@0
    87
	return (me);
sl@0
    88
    }
sl@0
    89
sl@0
    90
void CCheckedCertStore::ConstructL()
sl@0
    91
    {
sl@0
    92
	User::LeaveIfError(iFs.Connect());	
sl@0
    93
	CActiveScheduler::Add(this);
sl@0
    94
    }
sl@0
    95
sl@0
    96
MCTToken& CCheckedCertStore::Token()
sl@0
    97
    {
sl@0
    98
	return iCertStore.Token();
sl@0
    99
    }
sl@0
   100
sl@0
   101
//	May require checking against the keystore *after* calling the server to complete
sl@0
   102
//	the List request
sl@0
   103
void CCheckedCertStore::List(RMPointerArray<CCTCertInfo>& aCerts, const CCertAttributeFilter& aFilter,
sl@0
   104
                             TRequestStatus& aStatus)
sl@0
   105
    {
sl@0
   106
    assert(iState == EIdleState);
sl@0
   107
sl@0
   108
    // Only allow filtering on key usage for user certs
sl@0
   109
    if (aFilter.iKeyUsage != EX509UsageAll &&
sl@0
   110
        (!aFilter.iOwnerTypeIsSet || EUserCertificate != aFilter.iOwnerType))
sl@0
   111
        {
sl@0
   112
        TRequestStatus* status = &aStatus;
sl@0
   113
        User::RequestComplete(status, KErrNotSupported);
sl@0
   114
        return;
sl@0
   115
        }
sl@0
   116
sl@0
   117
    // Store caller parameters for later reference
sl@0
   118
    iCallerCerts = &aCerts;
sl@0
   119
    iCallerFilter = &aFilter;
sl@0
   120
    aStatus = KRequestPending;
sl@0
   121
    iCallerStatus = &aStatus;
sl@0
   122
sl@0
   123
    iState = EList;
sl@0
   124
    iCertStore.List(aCerts, aFilter, iStatus);
sl@0
   125
    SetActive();
sl@0
   126
    }
sl@0
   127
sl@0
   128
void CCheckedCertStore::CancelList()
sl@0
   129
    {
sl@0
   130
    if (iState == EList ||
sl@0
   131
        iState == EInitKeyStoreForList ||
sl@0
   132
        iState == EGetKeyInfosForList)
sl@0
   133
        {
sl@0
   134
        Cancel();
sl@0
   135
        }
sl@0
   136
    }
sl@0
   137
sl@0
   138
void CCheckedCertStore::GetCert(CCTCertInfo*& aCertInfo, const TCTTokenObjectHandle& aHandle, 
sl@0
   139
                                TRequestStatus& aStatus)
sl@0
   140
    {
sl@0
   141
    assert(iState == EIdleState);
sl@0
   142
    iCertStore.GetCert(aCertInfo, aHandle, aStatus);
sl@0
   143
    }
sl@0
   144
sl@0
   145
void CCheckedCertStore::CancelGetCert()
sl@0
   146
    {
sl@0
   147
    iCertStore.CancelGetCert();
sl@0
   148
    }
sl@0
   149
sl@0
   150
void CCheckedCertStore::Applications(const CCTCertInfo& aCertInfo, RArray<TUid>& aApplications,
sl@0
   151
									 TRequestStatus& aStatus)
sl@0
   152
    {
sl@0
   153
    assert(iState == EIdleState);
sl@0
   154
    iCertStore.Applications(aCertInfo, aApplications, aStatus);
sl@0
   155
    }
sl@0
   156
sl@0
   157
void CCheckedCertStore::CancelApplications()
sl@0
   158
    {
sl@0
   159
    iCertStore.CancelApplications();
sl@0
   160
    }
sl@0
   161
sl@0
   162
void CCheckedCertStore::IsApplicable(const CCTCertInfo& aCertInfo, TUid aApplication, 
sl@0
   163
                                     TBool& aIsApplicable, TRequestStatus& aStatus)
sl@0
   164
    {
sl@0
   165
    assert(iState == EIdleState);
sl@0
   166
    iCertStore.IsApplicable(aCertInfo, aApplication, aIsApplicable, aStatus);
sl@0
   167
    }
sl@0
   168
sl@0
   169
void CCheckedCertStore::CancelIsApplicable()
sl@0
   170
    {
sl@0
   171
    iCertStore.CancelIsApplicable();
sl@0
   172
    }
sl@0
   173
sl@0
   174
void CCheckedCertStore::Trusted(const CCTCertInfo& aCertInfo, TBool& aTrusted, 
sl@0
   175
                                TRequestStatus& aStatus)
sl@0
   176
    {
sl@0
   177
    assert(iState == EIdleState);
sl@0
   178
    iCertStore.Trusted(aCertInfo, aTrusted, aStatus);
sl@0
   179
    }
sl@0
   180
sl@0
   181
void CCheckedCertStore::CancelTrusted()
sl@0
   182
    {
sl@0
   183
    iCertStore.CancelTrusted();
sl@0
   184
    }
sl@0
   185
sl@0
   186
void CCheckedCertStore::Retrieve(const CCTCertInfo& aCertInfo, TDes8& aEncodedCert, 
sl@0
   187
                                 TRequestStatus& aStatus)
sl@0
   188
    {
sl@0
   189
    assert(iState == EIdleState);
sl@0
   190
    iCertStore.Retrieve(aCertInfo, aEncodedCert, aStatus);
sl@0
   191
    }
sl@0
   192
sl@0
   193
void CCheckedCertStore::CancelRetrieve()
sl@0
   194
    {
sl@0
   195
    iCertStore.CancelRetrieve();
sl@0
   196
    }
sl@0
   197
sl@0
   198
sl@0
   199
void CCheckedCertStore::Add(const TDesC& aLabel, 
sl@0
   200
							TCertificateFormat aFormat,
sl@0
   201
                            TCertificateOwnerType aCertificateOwnerType, 
sl@0
   202
                            const TKeyIdentifier* aSubjectKeyId,
sl@0
   203
                            const TKeyIdentifier* aIssuerKeyId,
sl@0
   204
                            const TDesC8& aCert, 
sl@0
   205
                            TRequestStatus& aStatus)
sl@0
   206
    {
sl@0
   207
 	// default value for aDeletable = ETrue		
sl@0
   208
	Add( aLabel, aFormat, aCertificateOwnerType, aSubjectKeyId, 
sl@0
   209
			aIssuerKeyId, aCert, ETrue, aStatus );
sl@0
   210
    }
sl@0
   211
  
sl@0
   212
// new Add(.., TBool aDeletable, ..) method from MCTWritableCertStore
sl@0
   213
void CCheckedCertStore::Add( const TDesC& aLabel, 
sl@0
   214
							 TCertificateFormat aFormat,
sl@0
   215
                             TCertificateOwnerType aCertificateOwnerType, 
sl@0
   216
                             const TKeyIdentifier* aSubjectKeyId,
sl@0
   217
                             const TKeyIdentifier* aIssuerKeyId,
sl@0
   218
                             const TDesC8& aCert, 
sl@0
   219
                             const TBool aDeletable,
sl@0
   220
                             TRequestStatus& aStatus
sl@0
   221
                             )
sl@0
   222
    {
sl@0
   223
    assert(iWritableCertStore);
sl@0
   224
    assert(iState == EIdleState);
sl@0
   225
sl@0
   226
    TRAPD(err, DoAddL(	aLabel, 
sl@0
   227
    					aFormat,
sl@0
   228
    					aCertificateOwnerType, 
sl@0
   229
    					aSubjectKeyId, 
sl@0
   230
    					aIssuerKeyId, 
sl@0
   231
    					aCert, 
sl@0
   232
    					aDeletable,
sl@0
   233
    					aStatus		) );
sl@0
   234
    
sl@0
   235
	if (err != KErrNone)
sl@0
   236
		{
sl@0
   237
    	    Complete(err);
sl@0
   238
		}
sl@0
   239
	}
sl@0
   240
sl@0
   241
 
sl@0
   242
void CCheckedCertStore::DoAddL(	const TDesC& aLabel,
sl@0
   243
								TCertificateFormat aFormat,
sl@0
   244
                               	TCertificateOwnerType aCertificateOwnerType, 
sl@0
   245
                               	const TKeyIdentifier* aSubjectKeyId,
sl@0
   246
                               	const TKeyIdentifier* aIssuerKeyId,
sl@0
   247
                               	const TDesC8& aCert, 
sl@0
   248
                               	const TBool aDeletable,
sl@0
   249
                               	TRequestStatus& aStatus)
sl@0
   250
    {
sl@0
   251
    
sl@0
   252
    //	Store caller parameters for later use
sl@0
   253
	    aStatus			= KRequestPending;
sl@0
   254
	    iCallerStatus	= &aStatus;
sl@0
   255
	    iFormat 	 	= aFormat;
sl@0
   256
	    iCertificateOwnerType = aCertificateOwnerType;
sl@0
   257
	    iSubjectKeyId	= aSubjectKeyId;
sl@0
   258
	    iIssuerKeyId	= aIssuerKeyId;
sl@0
   259
		iDeletable  	= aDeletable;
sl@0
   260
sl@0
   261
	// Store (copy)  aCert (cert data) into iCertificate[:HBufC8]
sl@0
   262
	    assert(!iCertificate);
sl@0
   263
	    iCertificate = HBufC8::NewMaxL(aCert.Size());
sl@0
   264
	    TPtr8 theCert(iCertificate->Des());
sl@0
   265
	    theCert.FillZ();
sl@0
   266
	    theCert.Copy(aCert);
sl@0
   267
sl@0
   268
	// Store (copy) aLabel (cert label) into iCertLabel[:HBufC]
sl@0
   269
	    assert(!iCertLabel);
sl@0
   270
	    iCertLabel = HBufC::NewMaxL(aLabel.Length());
sl@0
   271
	    TPtr theLabel(iCertLabel->Des());
sl@0
   272
	    theLabel.FillZ();
sl@0
   273
	    theLabel.Copy(aLabel);
sl@0
   274
sl@0
   275
    //	Checks subject key ID with certificate data, and sets up key filter
sl@0
   276
    //	which is used later to determine whether there is a key with the
sl@0
   277
    //	appropriate subject and thus, if it is OK to add the certificate	
sl@0
   278
	    ComputeAndCheckSubjectKeyIdL();
sl@0
   279
sl@0
   280
    //	Is keystore checking required? Only if a user certificate
sl@0
   281
    if (EUserCertificate==aCertificateOwnerType)
sl@0
   282
		{
sl@0
   283
        	InitialiseKeyStoreL(EInitKeyStoreForAdd);
sl@0
   284
		}
sl@0
   285
    else
sl@0
   286
		{
sl@0
   287
        iState = EAdd;
sl@0
   288
        
sl@0
   289
        // try new method first
sl@0
   290
        iWritableCertStore->Add( *iCertLabel,			// call new method
sl@0
   291
        						 iFormat,
sl@0
   292
        						 iCertificateOwnerType,
sl@0
   293
                                 iSubjectKeyId,
sl@0
   294
                                 iIssuerKeyId,
sl@0
   295
                                 *iCertificate,
sl@0
   296
                                 iDeletable,			// with deletable param
sl@0
   297
                                 iStatus );                    
sl@0
   298
        SetActive();
sl@0
   299
		}
sl@0
   300
	}
sl@0
   301
sl@0
   302
sl@0
   303
sl@0
   304
void CCheckedCertStore::CancelAdd()
sl@0
   305
    {
sl@0
   306
    if (iState == EInitKeyStoreForAdd ||
sl@0
   307
        iState == EGetKeyInfosForAdd ||
sl@0
   308
        iState == EAdd || iState == EOldAdd )
sl@0
   309
        {
sl@0
   310
        Cancel();
sl@0
   311
        }
sl@0
   312
    }
sl@0
   313
sl@0
   314
void CCheckedCertStore::ComputeAndCheckSubjectKeyIdL()
sl@0
   315
    {
sl@0
   316
	switch (iFormat)
sl@0
   317
        {
sl@0
   318
		case EX509Certificate:
sl@0
   319
            {
sl@0
   320
			TPtr8 thePtr(iCertificate->Des());
sl@0
   321
			CX509Certificate* cert = CX509Certificate::NewLC(thePtr);
sl@0
   322
sl@0
   323
			TKeyUsageX509 x509Usage = EX509UsageNone;
sl@0
   324
			const CX509CertExtension* ext = cert->Extension(KKeyUsage);
sl@0
   325
sl@0
   326
			if (!ext)
sl@0
   327
                {
sl@0
   328
				x509Usage = EX509UsageAll;
sl@0
   329
                }
sl@0
   330
			else
sl@0
   331
                {
sl@0
   332
				CX509KeyUsageExt* keyUsageExt = CX509KeyUsageExt::NewLC(ext->Data());
sl@0
   333
				
sl@0
   334
				if (keyUsageExt->IsSet(EX509DigitalSignature))
sl@0
   335
					{
sl@0
   336
					x509Usage |= EX509UsageDigitalSignature;
sl@0
   337
					}
sl@0
   338
				if (keyUsageExt->IsSet(EX509NonRepudiation))
sl@0
   339
					{
sl@0
   340
					x509Usage |= EX509UsageNonRepudiation;
sl@0
   341
					}
sl@0
   342
				if (keyUsageExt->IsSet(EX509KeyEncipherment))
sl@0
   343
					{
sl@0
   344
					x509Usage |= EX509UsageKeyEncipherment;
sl@0
   345
					}
sl@0
   346
				if (keyUsageExt->IsSet(EX509DataEncipherment))
sl@0
   347
					{
sl@0
   348
					x509Usage |= EX509UsageDataEncipherment;
sl@0
   349
					}
sl@0
   350
				if (keyUsageExt->IsSet(EX509KeyAgreement))
sl@0
   351
					{
sl@0
   352
					x509Usage |= EX509UsageKeyAgreement;
sl@0
   353
					}
sl@0
   354
				if (keyUsageExt->IsSet(EX509KeyCertSign))
sl@0
   355
					{
sl@0
   356
					x509Usage |= EX509UsageKeyCertSign;
sl@0
   357
					}
sl@0
   358
				if (keyUsageExt->IsSet(EX509CRLSign))
sl@0
   359
					{
sl@0
   360
					x509Usage |= EX509UsageCRLSign;
sl@0
   361
					}
sl@0
   362
				if (keyUsageExt->IsSet(EX509EncipherOnly))
sl@0
   363
					{
sl@0
   364
					x509Usage |= EX509UsageEncipherOnly;
sl@0
   365
					}
sl@0
   366
				if (keyUsageExt->IsSet(EX509DecipherOnly))
sl@0
   367
					{
sl@0
   368
					x509Usage |= EX509UsageDecipherOnly;
sl@0
   369
					}
sl@0
   370
sl@0
   371
				CleanupStack::PopAndDestroy(keyUsageExt);
sl@0
   372
                }
sl@0
   373
sl@0
   374
			iKeyFilter.iUsage = KeyUsageX509ToPKCS15Private(x509Usage);
sl@0
   375
			
sl@0
   376
			iComputedSubjectKeyId.Zero();
sl@0
   377
			// For non-user ceriticates (i.e. CA certificates), we use the SubjectKeyIdentifier API, as it
sl@0
   378
			// tries to get the extension from cert., and calculates a value only if it is not found. This behaviour corresponds to the RFC.
sl@0
   379
			// For user ceritificates, the key identifier is used for matching key store with cert store, so we cannot use the value in the certificate itself.
sl@0
   380
			if (iCertificateOwnerType != EUserCertificate)
sl@0
   381
				{
sl@0
   382
				iComputedSubjectKeyId = cert->SubjectKeyIdentifierL();
sl@0
   383
				}
sl@0
   384
			else
sl@0
   385
				{
sl@0
   386
				// For non-CA certs, use the recommended method of computing it from RFC3280, section 4.2.1.2
sl@0
   387
				iComputedSubjectKeyId = cert->KeyIdentifierL();									
sl@0
   388
				}
sl@0
   389
			if (!iSubjectKeyId || *iSubjectKeyId == KNullDesC8)
sl@0
   390
                {
sl@0
   391
				iSubjectKeyId = &iComputedSubjectKeyId;
sl@0
   392
                }
sl@0
   393
			else if (iSubjectKeyId->Compare(iComputedSubjectKeyId)!=0)
sl@0
   394
                {//	Different subject ids
sl@0
   395
				User::Leave(KErrArgument);
sl@0
   396
                }
sl@0
   397
			
sl@0
   398
			CleanupStack::PopAndDestroy(cert);
sl@0
   399
            }	
sl@0
   400
            break;
sl@0
   401
	
sl@0
   402
        case EWTLSCertificate:
sl@0
   403
            {
sl@0
   404
            CCertificate* cert = CWTLSCertificate::NewLC(*iCertificate);
sl@0
   405
            iComputedSubjectKeyId = cert->KeyIdentifierL();
sl@0
   406
            if (!iSubjectKeyId || *iSubjectKeyId == KNullDesC8)
sl@0
   407
                {
sl@0
   408
                iSubjectKeyId = &iComputedSubjectKeyId;
sl@0
   409
                }
sl@0
   410
            else if (iSubjectKeyId->Compare(iComputedSubjectKeyId)!=0)
sl@0
   411
                {//	Different subject ids
sl@0
   412
                User::Leave(KErrArgument);
sl@0
   413
                }
sl@0
   414
	
sl@0
   415
            CleanupStack::PopAndDestroy(cert);
sl@0
   416
            }
sl@0
   417
            break;
sl@0
   418
sl@0
   419
        case EX509CertificateUrl:
sl@0
   420
            {
sl@0
   421
            iKeyFilter.iUsage = EPKCS15UsageAll;
sl@0
   422
		
sl@0
   423
            if (!iSubjectKeyId || *iSubjectKeyId == KNullDesC8)
sl@0
   424
                {
sl@0
   425
                User::Leave(KErrArgument);
sl@0
   426
                }
sl@0
   427
            }
sl@0
   428
            break;
sl@0
   429
sl@0
   430
        default:
sl@0
   431
            User::Leave(KErrNotSupported);	
sl@0
   432
            break;
sl@0
   433
        }
sl@0
   434
sl@0
   435
	iKeyFilter.iKeyId = *iSubjectKeyId;
sl@0
   436
    }
sl@0
   437
sl@0
   438
void CCheckedCertStore::Remove(const CCTCertInfo& aCertInfo, TRequestStatus& aStatus)
sl@0
   439
    {
sl@0
   440
    assert(iWritableCertStore);
sl@0
   441
    assert(iState == EIdleState);
sl@0
   442
    aStatus = KRequestPending;
sl@0
   443
    iCallerStatus = &aStatus;
sl@0
   444
    iState = ERemove;
sl@0
   445
    iWritableCertStore->Remove(aCertInfo, iStatus);
sl@0
   446
    SetActive();
sl@0
   447
    }
sl@0
   448
sl@0
   449
void CCheckedCertStore::CancelRemove()
sl@0
   450
    {
sl@0
   451
    if (iState == ERemove)
sl@0
   452
        {
sl@0
   453
        Cancel();
sl@0
   454
        }
sl@0
   455
    }
sl@0
   456
sl@0
   457
void CCheckedCertStore::SetApplicability(const CCTCertInfo& aCertInfo, const RArray<TUid>& aApplications, TRequestStatus &aStatus)
sl@0
   458
    {
sl@0
   459
    assert(iWritableCertStore);
sl@0
   460
    assert(iState == EIdleState);
sl@0
   461
    aStatus = KRequestPending;
sl@0
   462
    iCallerStatus = &aStatus;
sl@0
   463
    iState = ESetApplicability;
sl@0
   464
    iWritableCertStore->SetApplicability(aCertInfo, aApplications, iStatus);
sl@0
   465
    SetActive();
sl@0
   466
    }
sl@0
   467
	
sl@0
   468
void CCheckedCertStore::CancelSetApplicability()
sl@0
   469
    {
sl@0
   470
    if (iState == ESetApplicability)
sl@0
   471
        {
sl@0
   472
        Cancel();
sl@0
   473
        }    
sl@0
   474
    }
sl@0
   475
sl@0
   476
void CCheckedCertStore::SetTrust(const CCTCertInfo& aCertInfo, TBool aTrusted, TRequestStatus& aStatus)
sl@0
   477
    {
sl@0
   478
    assert(iWritableCertStore);
sl@0
   479
    assert(iState == EIdleState);
sl@0
   480
    aStatus = KRequestPending;
sl@0
   481
    iCallerStatus = &aStatus;
sl@0
   482
    iState = ESetTrust;
sl@0
   483
    iWritableCertStore->SetTrust(aCertInfo, aTrusted, iStatus);
sl@0
   484
    SetActive();
sl@0
   485
    }
sl@0
   486
sl@0
   487
void CCheckedCertStore::CancelSetTrust()
sl@0
   488
    {
sl@0
   489
    if (iState == ESetTrust)
sl@0
   490
        {
sl@0
   491
        Cancel();
sl@0
   492
        }        
sl@0
   493
    }
sl@0
   494
sl@0
   495
TInt CCheckedCertStore::RunError(TInt aError)
sl@0
   496
    {
sl@0
   497
    Complete(aError);
sl@0
   498
	return KErrNone;
sl@0
   499
    }
sl@0
   500
	
sl@0
   501
void CCheckedCertStore::DoCancel()
sl@0
   502
    {
sl@0
   503
	// (see notes on cancellation in CUnifiedCertStore::DoCancel)
sl@0
   504
sl@0
   505
	switch (iState)
sl@0
   506
		{
sl@0
   507
        case EGetKeyInfosForList:
sl@0
   508
        case EAdd:
sl@0
   509
		case ERemove:
sl@0
   510
		case ESetApplicability:
sl@0
   511
		case ESetTrust:
sl@0
   512
			if (iStatus == KRequestPending)
sl@0
   513
				{
sl@0
   514
				// Attempt to cancel outstanding request and pass status back to
sl@0
   515
				// client
sl@0
   516
				CancelOutstandingRequest();
sl@0
   517
				Complete(iStatus.Int());
sl@0
   518
				}
sl@0
   519
			else
sl@0
   520
				{
sl@0
   521
				// We've already been completed - call RunL() to process results
sl@0
   522
				// and complete client
sl@0
   523
				TRAPD(err, RunL());
sl@0
   524
				if (err != KErrNone)
sl@0
   525
					{
sl@0
   526
					RunError(err);
sl@0
   527
					}
sl@0
   528
				}
sl@0
   529
			break;
sl@0
   530
			
sl@0
   531
		default:
sl@0
   532
			CancelOutstandingRequest();
sl@0
   533
			Complete(KErrCancel);
sl@0
   534
			break;
sl@0
   535
		}	
sl@0
   536
	}
sl@0
   537
sl@0
   538
void CCheckedCertStore::CancelOutstandingRequest()
sl@0
   539
	{
sl@0
   540
    switch (iState)
sl@0
   541
        {
sl@0
   542
        case EList:
sl@0
   543
            iCertStore.CancelList();
sl@0
   544
            break;
sl@0
   545
sl@0
   546
        case EInitKeyStoreForAdd:
sl@0
   547
        case EInitKeyStoreForList:
sl@0
   548
            assert(iUnifiedKeyStore);
sl@0
   549
            iUnifiedKeyStore->CancelInitialize();
sl@0
   550
            break;
sl@0
   551
sl@0
   552
        case EGetKeyInfosForAdd:
sl@0
   553
        case EGetKeyInfosForList:
sl@0
   554
            assert(iUnifiedKeyStore);
sl@0
   555
            iUnifiedKeyStore->CancelList();
sl@0
   556
            break;
sl@0
   557
sl@0
   558
        case EAdd:
sl@0
   559
        case EOldAdd:
sl@0
   560
            assert(iWritableCertStore);
sl@0
   561
            iWritableCertStore->CancelAdd();
sl@0
   562
            break;
sl@0
   563
            
sl@0
   564
        case ERemove:
sl@0
   565
		    assert(iWritableCertStore);
sl@0
   566
   			iWritableCertStore->CancelRemove();
sl@0
   567
			break;
sl@0
   568
			
sl@0
   569
        case ESetApplicability:
sl@0
   570
		    assert(iWritableCertStore);
sl@0
   571
   			iWritableCertStore->CancelSetApplicability();
sl@0
   572
			break;
sl@0
   573
			
sl@0
   574
        case ESetTrust:
sl@0
   575
		    assert(iWritableCertStore);
sl@0
   576
   			iWritableCertStore->CancelSetTrust();
sl@0
   577
			break;
sl@0
   578
sl@0
   579
sl@0
   580
        default:
sl@0
   581
            assert(EFalse);
sl@0
   582
            break;            
sl@0
   583
        }
sl@0
   584
sl@0
   585
    Complete(KErrCancel);
sl@0
   586
    }
sl@0
   587
sl@0
   588
void CCheckedCertStore::RunL()
sl@0
   589
    {
sl@0
   590
    assert(iCallerStatus);
sl@0
   591
    
sl@0
   592
	// we allow only KErrNone OR, possibly, KErrNotSupported after new Add()
sl@0
   593
	// otherwise - Leave!
sl@0
   594
	if (iStatus!=KErrNone &&
sl@0
   595
	    !(iStatus==KErrNotSupported && iState==EAdd) &&
sl@0
   596
	    !(iStatus == KErrNotFound && (iState==EList || iState==EGetKeyInfosForList || iState==EInitKeyStoreForList)))
sl@0
   597
		{
sl@0
   598
    	User::Leave(iStatus.Int());
sl@0
   599
    	}
sl@0
   600
		
sl@0
   601
    switch (iState)
sl@0
   602
        {
sl@0
   603
        case EList:
sl@0
   604
            if (iCallerFilter->iKeyUsage == EX509UsageAll)
sl@0
   605
                {
sl@0
   606
                // No key usage filter, so we're done
sl@0
   607
                Complete(KErrNone);
sl@0
   608
                }
sl@0
   609
            else
sl@0
   610
                {
sl@0
   611
                // Set up key filter according list cert parameters
sl@0
   612
                if (iCallerFilter->iSubjectKeyIdIsSet)
sl@0
   613
                    {
sl@0
   614
                    iKeyFilter.iKeyId = iCallerFilter->iSubjectKeyId;
sl@0
   615
                    }
sl@0
   616
                else
sl@0
   617
                    {
sl@0
   618
                    iKeyFilter.iKeyId = KNullDesC8;
sl@0
   619
                    }
sl@0
   620
                iKeyFilter.iUsage = KeyUsageX509ToPKCS15Private(iCallerFilter->iKeyUsage);
sl@0
   621
                InitialiseKeyStoreL(EInitKeyStoreForList);
sl@0
   622
                }
sl@0
   623
            break;
sl@0
   624
sl@0
   625
        case EInitKeyStoreForAdd:
sl@0
   626
        case EInitKeyStoreForList:
sl@0
   627
            assert(iUnifiedKeyStore);
sl@0
   628
            iState = (iState == EInitKeyStoreForAdd) ? EGetKeyInfosForAdd : EGetKeyInfosForList;
sl@0
   629
            iUnifiedKeyStore->List(iKeyInfos, iKeyFilter, iStatus);			
sl@0
   630
            SetActive();
sl@0
   631
            break;
sl@0
   632
sl@0
   633
        case EGetKeyInfosForList:
sl@0
   634
            BuildCheckedCertificateListL();	//	Not async
sl@0
   635
            Complete(KErrNone);
sl@0
   636
            break;
sl@0
   637
sl@0
   638
        case EGetKeyInfosForAdd:
sl@0
   639
            // We have a filter list of keys - there should be one with
sl@0
   640
            // the appropriate subject if we are to add it
sl@0
   641
            if (iKeyInfos.Count() == 0)
sl@0
   642
                {
sl@0
   643
                //	The private key can't be found in any key store
sl@0
   644
                Complete(KErrPrivateKeyNotFound); 
sl@0
   645
                }
sl@0
   646
            else
sl@0
   647
                {
sl@0
   648
                //	OK to go ahead and add the key
sl@0
   649
                assert(iWritableCertStore);
sl@0
   650
                iState = EAdd;
sl@0
   651
                
sl@0
   652
                // try to use new Add(.., TBool aDeletable, ..)
sl@0
   653
                // if it's not supported it will return with
sl@0
   654
                // iStatus set to KErrNotSupported
sl@0
   655
                iWritableCertStore->Add( *iCertLabel,	// call new Add() method
sl@0
   656
                						 iFormat,
sl@0
   657
                						 iCertificateOwnerType,
sl@0
   658
                                         iSubjectKeyId,
sl@0
   659
                                         iIssuerKeyId,
sl@0
   660
                                         *iCertificate,
sl@0
   661
                                         iDeletable,  	// with deletable param
sl@0
   662
                                         iStatus);
sl@0
   663
                SetActive();
sl@0
   664
                }
sl@0
   665
            break;
sl@0
   666
                
sl@0
   667
        case EAdd:
sl@0
   668
         	if (iStatus!=KErrNotSupported)
sl@0
   669
         		{
sl@0
   670
 	     		// Set published property
sl@0
   671
 		      	iPSCertstoreChangePropertyRef.Set(KUnifiedCertStorePropertyCat, // category
sl@0
   672
  												EUnifiedCertStoreFlag,        // key
sl@0
   673
  	    										1);                           // value
sl@0
   674
         		
sl@0
   675
		        // when here means MCTWritableCertStore was able to find 
sl@0
   676
		        // child's new Add(..,aDeletable,..) method
sl@0
   677
				// thus, ok and complete with whatever result it returned
sl@0
   678
			    Complete(iStatus.Int());
sl@0
   679
		        }
sl@0
   680
		    else
sl@0
   681
		       	{
sl@0
   682
				// here: call to the new Add() method above didn't work,
sl@0
   683
				// try to call old Add() method
sl@0
   684
			    iState = EOldAdd;
sl@0
   685
               	iStatus = KRequestPending;
sl@0
   686
               	iWritableCertStore->Add( *iCertLabel,	
sl@0
   687
                						 iFormat,
sl@0
   688
                						 iCertificateOwnerType,
sl@0
   689
                                         iSubjectKeyId,
sl@0
   690
                                         iIssuerKeyId,
sl@0
   691
                                         *iCertificate,
sl@0
   692
                                         iStatus);
sl@0
   693
                SetActive();                                         
sl@0
   694
               	} 
sl@0
   695
           	break;
sl@0
   696
sl@0
   697
        case EOldAdd:
sl@0
   698
        case ERemove:  
sl@0
   699
        case ESetApplicability:     
sl@0
   700
		case ESetTrust:              
sl@0
   701
      		// Set published property
sl@0
   702
 	      	iPSCertstoreChangePropertyRef.Set(KUnifiedCertStorePropertyCat, // category
sl@0
   703
											EUnifiedCertStoreFlag,        // key
sl@0
   704
 	      									1);                           // value      
sl@0
   705
            Complete(iStatus.Int());
sl@0
   706
            break;
sl@0
   707
            
sl@0
   708
        default:
sl@0
   709
            assert(EFalse);
sl@0
   710
            break;
sl@0
   711
        }
sl@0
   712
    }
sl@0
   713
	
sl@0
   714
void CCheckedCertStore::InitialiseKeyStoreL(TState aNextState)
sl@0
   715
    {
sl@0
   716
    assert(aNextState == EInitKeyStoreForAdd || aNextState == EInitKeyStoreForList);
sl@0
   717
	assert(!iUnifiedKeyStore);
sl@0
   718
    
sl@0
   719
	iUnifiedKeyStore = CUnifiedKeyStore::NewL(iFs);
sl@0
   720
    iUnifiedKeyStore->Initialize(iStatus);		
sl@0
   721
    iState = aNextState;
sl@0
   722
    SetActive();
sl@0
   723
    }
sl@0
   724
sl@0
   725
void CCheckedCertStore::BuildCheckedCertificateListL()
sl@0
   726
    {
sl@0
   727
	TInt certCount = iCallerCerts->Count();
sl@0
   728
    TInt keyCount = iKeyInfos.Count();
sl@0
   729
    
sl@0
   730
    // Iterate backwards through cert array so remove doesn't affect indicies
sl@0
   731
    for (TInt i = certCount - 1 ; i >= 0 ; --i)
sl@0
   732
        {
sl@0
   733
		CCTCertInfo* certInfo = (*iCallerCerts)[i];
sl@0
   734
sl@0
   735
        // It's problem in the certstore implementation if the list contains NULL pointers
sl@0
   736
        assert(certInfo); 
sl@0
   737
sl@0
   738
        // Check for key with corresponding id
sl@0
   739
		TBool accept = EFalse;
sl@0
   740
        for (TInt j = 0 ; j < keyCount ; ++j)
sl@0
   741
            {
sl@0
   742
            if (iKeyInfos[j]->ID()==certInfo->SubjectKeyId())
sl@0
   743
                {
sl@0
   744
                accept = ETrue;
sl@0
   745
                break;
sl@0
   746
                }
sl@0
   747
            }
sl@0
   748
sl@0
   749
        // If we don't have it, remove and release the cert info
sl@0
   750
        if (!accept)
sl@0
   751
            {
sl@0
   752
            iCallerCerts->Remove(i);
sl@0
   753
            certInfo->Release();
sl@0
   754
            }
sl@0
   755
        }
sl@0
   756
    }
sl@0
   757
sl@0
   758
void CCheckedCertStore::Complete(TInt aError)
sl@0
   759
    {
sl@0
   760
	if (iCallerStatus)
sl@0
   761
        {
sl@0
   762
		User::RequestComplete(iCallerStatus, aError);
sl@0
   763
        }
sl@0
   764
    Cleanup();
sl@0
   765
    }
sl@0
   766
sl@0
   767
void CCheckedCertStore::Cleanup()
sl@0
   768
    {
sl@0
   769
    //	Reset the state machine	
sl@0
   770
	iState = EIdleState;
sl@0
   771
	iKeyInfos.Close();
sl@0
   772
    iSubjectKeyId = NULL;
sl@0
   773
    iIssuerKeyId = NULL;
sl@0
   774
sl@0
   775
    delete iCertLabel;
sl@0
   776
    iCertLabel = NULL;
sl@0
   777
sl@0
   778
    delete iCertificate;
sl@0
   779
    iCertificate = NULL;
sl@0
   780
sl@0
   781
    delete iUnifiedKeyStore;
sl@0
   782
    iUnifiedKeyStore = 0;		
sl@0
   783
sl@0
   784
    iCallerCerts = NULL;
sl@0
   785
    iCallerFilter = NULL;
sl@0
   786
    }