os/security/cryptoservices/certificateandkeymgmt/tcertstore/T_unifiedcertstoreadd.cpp
First public contribution.
2 * Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
19 #include "t_unifiedcertstoreadd.h"
20 #include "t_certstoredefs.h"
22 #include "t_certstoreout.h"
23 #include <mctwritablecertstore.h>
25 CTestAction* CAddCertificate::NewL(RFs& aFs,
26 CConsoleBase& aConsole,
28 const TTestActionSpec& aTestActionSpec)
30 CAddCertificate* self = new(ELeave) CAddCertificate(aFs, aConsole, aOut);
31 CleanupStack::PushL(self);
32 self->ConstructL(aTestActionSpec);
33 CleanupStack::Pop(self);
37 CAddCertificate::~CAddCertificate()
40 delete iCertificateURL;
41 delete iCertificateContent;
42 delete iCertificateLabel;
45 void CAddCertificate::PerformAction(TRequestStatus& aStatus)
51 if (iNotificationSubscribed)
55 iNotifier = CCertStoreChangeNotifier::NewL(iNotifierFlag);
56 iNotifier->StartNotification();
58 iState = ECheckNotification;
64 MCTWritableCertStore& store = UnifiedCertStore().WritableCertStore(iStoreIndex);
66 TKeyIdentifier* issuerKeyId = &iIssuerKeyId;
67 TKeyIdentifier* subjectKeyId = &iSubjectKeyId;
69 ASSERT(iCertificateLabel);
71 // Use the Add() with Deletable param if Deletable flag present in test data
72 if (iDeletableFlagPresent)
74 store.Add(*iCertificateLabel, iCertificateFormat, iOwnerType,
75 subjectKeyId, issuerKeyId, *iCertificateContent,
78 // otherwise, use the original Add()
81 store.Add(*iCertificateLabel, iCertificateFormat, iOwnerType,
82 subjectKeyId, issuerKeyId, *iCertificateContent, aStatus);
86 case ECheckNotification:
91 TRequestStatus* status = &aStatus;
92 User::RequestComplete(status, KErrNone);
96 iNotifier->SetCompleteStatus(&aStatus);
102 if (aStatus == iExpectedResult)
111 if (aStatus != KErrNoMemory)
116 TRequestStatus* status = &aStatus;
117 User::RequestComplete(status, aStatus.Int());
127 void CAddCertificate::PerformCancel()
131 case ECheckNotification:
134 MCTWritableCertStore& store = UnifiedCertStore().WritableCertStore(iStoreIndex);
143 void CAddCertificate::AfterOOMFailure()
147 void CAddCertificate::Reset()
152 void CAddCertificate::DoReportAction()
154 iOut.writeString(_L("Adding certificate..."));
156 iOut.writeString(_L("\tLabel = "));
157 iOut.writeString(*iCertificateLabel);
159 iOut.writeString(_L("\tOwner type = "));
162 iOut.writeString(_L("\tSubjectKeyId: "));
163 iOut.writeOctetString(iSubjectKeyId);
165 iOut.writeString(_L("\tDeletable = "));
166 iDeletable ? iOut.writeString(KTrue) : iOut.writeString(KFalse);
171 void CAddCertificate::WriteFormat()
173 iOut.writeString(_L("\tFormat = "));
174 switch (iCertificateFormat)
176 case EX509Certificate:
177 iOut.writeString(_L("X.509\n"));
180 case EWTLSCertificate:
181 iOut.writeString(_L("WTLS\n"));
184 case EX509CertificateUrl:
185 iOut.writeString(_L("X.509 URL\n"));
188 case EWTLSCertificateUrl:
189 iOut.writeString(_L("WTLS URL\n"));
193 iOut.writeString(_L("Unknown format\n"));
198 void CAddCertificate::WriteOwnerType()
203 iOut.writeString(_L("CA\n"));
206 case EUserCertificate:
207 iOut.writeString(_L("User"));
210 case EPeerCertificate:
211 iOut.writeString(_L("Peer"));
215 iOut.writeString(_L("Unknown"));
220 CAddCertificate::CAddCertificate(RFs& aFs, CConsoleBase& aConsole,
222 : CSubscriberAction(aFs, aConsole, aOut), iState(EAdding),
223 iDeletable(ETrue), iDeletableFlagPresent(EFalse)
227 void CAddCertificate::ConstructL(const TTestActionSpec& aTestActionSpec)
229 CSubscriberAction::ConstructL(aTestActionSpec);
231 SetCertFormatL(Input::ParseElement(aTestActionSpec.iActionBody, KCertFormatStart));
232 SetCertOwnerTypeL(Input::ParseElement(aTestActionSpec.iActionBody, KCertOwnerTypeStart));
233 SetCertLabelL(Input::ParseElement(aTestActionSpec.iActionBody, KCertLabelStart));
234 SetKeyId(iIssuerKeyId, Input::ParseElement(aTestActionSpec.iActionBody, KIssuerKeyStart));
235 SetKeyId(iSubjectKeyId, Input::ParseElement(aTestActionSpec.iActionBody, KSubjectKeyStart));
236 SetStoreToUse(Input::ParseElement(aTestActionSpec.iActionBody, KStoreToUseStart));
238 TPtrC8 certFileOrURL = Input::ParseElement(aTestActionSpec.iActionBody, KCertFileStart);
240 SetCertificateContentL(certFileOrURL);
242 if (iCertificateFormat == EX509CertificateUrl ||
243 iCertificateFormat == EWTLSCertificateUrl)
245 iCertificateURL = certFileOrURL.AllocL();
249 ConstructCertL(certFileOrURL);
252 // check for a possible deletable flag value for the certificate
255 const TDesC8& deletableStr = Input::ParseElement(aTestActionSpec.iActionBody,
261 // set the deletable attribute if a value was found for the certificate
264 SetDeletable(deletableStr);
267 // Setting the expected result
268 HBufC* result = HBufC::NewLC(aTestActionSpec.iActionResult.Length());
269 TPtr(result->Des()).Copy(aTestActionSpec.iActionResult);
270 Input::GetExpectedResultL(Input::ParseElement(*result, KReturnStart, KReturnEnd), iExpectedResult);
271 CleanupStack::PopAndDestroy(result);
274 void CAddCertificate::SetKeyId(TKeyIdentifier& aKeyIdentifier, const TDesC8& aKeyInfo)
276 TInt size = aKeyInfo.Length();
277 for (TInt i = 0; i < size; i += 2)
279 TInt a = (aKeyInfo[i+1] >= 'a') ? (aKeyInfo[i+1] - 'a' + 10) : (aKeyInfo[i+1] - '0');
280 TInt b = (aKeyInfo[i] >= 'a') ? (aKeyInfo[i] - 'a' + 10) : (aKeyInfo[i] - '0');
281 aKeyIdentifier.Append(a + b * 16);
285 void CAddCertificate::SetCertFormatL(const TDesC8& aFormat)
287 if (aFormat == KX509)
289 iCertificateFormat = EX509Certificate;
291 else if (aFormat == KWTLS)
293 iCertificateFormat = EWTLSCertificate;
295 else if (aFormat == KX509URL)
297 iCertificateFormat = EX509CertificateUrl;
299 else if (aFormat == KWTLSURL)
301 iCertificateFormat = EWTLSCertificateUrl;
303 else if (aFormat == KUnknown)
305 iCertificateFormat = EUnknownCertificate;
309 iOut.write(_L("Unknown cert format: "));
310 iOut.writeString(aFormat);
312 User::Leave(KErrArgument);
316 void CAddCertificate::SetCertOwnerTypeL(const TDesC8& aOwnerType)
318 if (aOwnerType == KCACert)
320 iOwnerType = ECACertificate;
322 else if (aOwnerType == KUserCert)
324 iOwnerType = EUserCertificate;
326 else if (aOwnerType == KPeerCert)
328 iOwnerType = EPeerCertificate;
330 else if (aOwnerType == KUnknown)
332 // set dummy bogus owner type
333 iOwnerType = static_cast<TCertificateOwnerType>(EPeerCertificate + 1);
337 iOut.write(_L("Unknown cert owner type: "));
338 iOut.writeString(aOwnerType);
340 User::Leave(KErrArgument);
344 void CAddCertificate::SetCertLabelL(const TDesC8& aLabel)
346 delete iCertificateLabel;
347 iCertificateLabel = NULL;
348 iCertificateLabel = HBufC::NewL(aLabel.Length());
349 TPtr ptr = iCertificateLabel->Des();
353 void CAddCertificate::SetStoreToUse(const TDesC8& aStoreToUse)
355 TLex8 lex(aStoreToUse);
356 lex.Val(iStoreIndex);
359 void CAddCertificate::SetCertificateContentL(const TDesC8& aFileName)
362 fileName.Copy(aFileName);
364 User::LeaveIfError(fs.Connect());
365 CleanupClosePushL(fs);
366 __ASSERT_DEBUG(!iCertificateContent, User::Panic(_L("CAddCertificate"), 1));
367 TRAPD(err, iCertificateContent = Input::ReadFileL(fileName, fs));
370 iConsole.Printf(_L("Error reading file : "));
371 iConsole.Printf(fileName);
372 iConsole.Printf(_L("\n"));
375 CleanupStack::PopAndDestroy(); // fs
378 void CAddCertificate::SetDeletable(const TDesC8& aDeletable)
380 iDeletableFlagPresent = ETrue;
381 if (aDeletable.Compare(KTrue)==0)
391 void CAddCertificate::ConstructCertL(const TDesC8& aCert)
394 filename.Copy(aCert);
396 User::LeaveIfError(fs.Connect());
397 CleanupClosePushL(fs);
399 TRAPD(err, certBuf = Input::ReadFileL(filename, fs));
402 iConsole.Printf(_L("Error reading file : "));
403 iConsole.Printf(filename);
404 iConsole.Printf(_L("\n"));
407 CleanupStack::PushL(certBuf);
408 switch (iCertificateFormat)
410 case EX509Certificate:
411 iCertificate = CX509Certificate::NewL(*certBuf);
414 case EWTLSCertificate:
415 iCertificate = CWTLSCertificate::NewL(*certBuf);
419 // Unknown format - do nothing
422 CleanupStack::PopAndDestroy(2);
425 void CAddCertificate::DoCheckResult(TInt aError)
432 if (iExpectedResult == KErrNone )
434 iConsole.Write(_L("\tcertificate added successfully\n"));
435 iOut.writeString(_L("\tcertificate added successfully"));
439 iConsole.Write(_L("\tcertificate not added.\n"));
440 iOut.writeString(_L("\tcertificate not added."));
447 if(iExpectedResult == KErrNone )
449 iConsole.Write(_L("\tcertificate not added\n"));
450 iOut.writeString(_L("\tcertificate not added"));
454 iConsole.Write(_L("\tcertificate should not be added\n"));
455 iOut.writeString(_L("\tcertificate should not be added"));
458 iOut.writeString(_L("\t"));
459 iOut.writeError(aError);
460 if (aError == KErrBadName)
462 iOut.writeString(_L(" Check that the label is unique"));
469 //////////////////////////////////////////////////////////
470 // Key import, from keystore for adding user certificates
471 //////////////////////////////////////////////////////////
473 CTestAction* CImportKey::NewL(RFs& aFs,
474 CConsoleBase& aConsole,
476 const TTestActionSpec& aTestActionSpec)
478 CTestAction* self = CImportKey::NewLC(aFs, aConsole, aOut, aTestActionSpec);
479 CleanupStack::Pop(self);
483 CTestAction* CImportKey::NewLC(RFs& aFs,
484 CConsoleBase& aConsole,
486 const TTestActionSpec& aTestActionSpec)
488 CImportKey* self = new (ELeave) CImportKey(aFs, aConsole, aOut);
489 CleanupStack::PushL(self);
490 self->ConstructL(aTestActionSpec);
494 CImportKey::~CImportKey()
502 delete iUnifiedKeyStore;
506 CImportKey::CImportKey(RFs& aFs, CConsoleBase& aConsole, Output& aOut)
507 : CCertStoreTestAction(aFs, aConsole, aOut),
512 void CImportKey::ConstructL(const TTestActionSpec& aTestActionSpec)
514 User::LeaveIfError(iFs.Connect());
516 CCertStoreTestAction::ConstructL(aTestActionSpec);
520 SetKeyDataFileL(Input::ParseElement(aTestActionSpec.iActionBody, KImportDataFile, KImportDataFileEnd, pos, err));
521 for (;SetKeyUsage(Input::ParseElement(aTestActionSpec.iActionBody, KKeyUsageStart, KKeyUsageEnd, pos, err));)
524 SetKeyLabel(Input::ParseElement(aTestActionSpec.iActionBody, KKeyLabelStart, KKeyLabelEnd, pos, err));
525 for (;SetKeyAccessType(Input::ParseElement(aTestActionSpec.iActionBody, KKeyAccessTypeStart, KKeyAccessTypeEnd, pos, err));)
528 SetKeyPassphrase(Input::ParseElement(aTestActionSpec.iActionBody, KKeyPassphraseStart, KKeyPassphraseEnd, pos, err));
532 HBufC* result = HBufC::NewLC(aTestActionSpec.iActionResult.Length());
533 TPtr(result->Des()).Copy(aTestActionSpec.iActionResult);
534 Input::GetExpectedResultL(Input::ParseElement(*result, KReturnStart, KReturnEnd), iExpectedResult);
535 CleanupStack::PopAndDestroy(result);
538 TBool CImportKey::SetKeyUsage(const TDesC8& aKeyUsage)
541 if (aKeyUsage.Compare(KAllKeyUsages)==0)
542 iUsage = EPKCS15UsageAll;
543 else if (aKeyUsage.Compare(KAllKeyUsagesButNR)==0)
544 iUsage |= (TKeyUsagePKCS15)(EPKCS15UsageSign) |
545 (TKeyUsagePKCS15)(EPKCS15UsageSignRecover) |
546 (TKeyUsagePKCS15)(EPKCS15UsageDecrypt);
547 else if (aKeyUsage.Compare(KDSAUsage)==0)
548 iUsage |= (TKeyUsagePKCS15)(EPKCS15UsageSign) |
549 (TKeyUsagePKCS15)(EPKCS15UsageSignRecover);
550 else if (aKeyUsage.Compare(KDerive)==0)
551 iUsage |= EPKCS15UsageDerive;
552 else if (aKeyUsage.Compare(KSign)==0)
553 iUsage |= EPKCS15UsageSign;
554 else if (aKeyUsage.Compare(KSignRecover)==0)
555 iUsage |= EPKCS15UsageSignRecover;
556 else if (aKeyUsage.Compare(KDecrypt)==0)
557 iUsage |= EPKCS15UsageDecrypt;
558 else if (aKeyUsage.Compare(KNR)==0)
559 iUsage |= EPKCS15UsageNonRepudiation;
560 else if (aKeyUsage.Compare(KEncipherAndSign)==0)
561 iUsage |= (TKeyUsagePKCS15)(EPKCS15UsageSign) |
562 (TKeyUsagePKCS15)(EPKCS15UsageSignRecover) |
563 (TKeyUsagePKCS15)(EPKCS15UsageUnwrap);
569 void CImportKey::SetKeyLabel(const TDesC8& aKeyLabel)
571 iLabel = HBufC::NewMax(aKeyLabel.Size());
574 TPtr theLabel(iLabel->Des());
576 theLabel.Copy(aKeyLabel);
581 void CImportKey::SetKeyPassphrase(const TDesC8& aPassphrase)
583 // If the passphrase is empty, then use "clanger" by default.
584 _LIT8(KDefaultPassphrase, "clanger");
585 TPtrC8 phrase(KDefaultPassphrase());
586 if (aPassphrase.Length())
588 phrase.Set(aPassphrase);
596 // Write the passphrase straight to the file.
597 TDriveUnit sysDrive (fs.GetSystemDrive());
598 TBuf<24> fileName (sysDrive.Name());
599 fileName.Append(_L("\\password.txt"));
601 file.Replace(fs, fileName, EFileWrite);
607 void CImportKey::SetKeyDataFileL(const TDesC8& aDes)
609 // Now the filename itself
614 TDriveUnit sysDrive (RFs::GetSystemDrive());
615 TBuf<64> buf(sysDrive.Name());
616 buf.Append(_L("\\tcertstore\\data\\"));
617 buf.Append(fileName);
620 TInt r = file.Open(iFs, buf, EFileRead);
621 if ( (r==KErrNotFound) || (r==KErrPathNotFound) )
622 {// Not on c:, try z:
624 r = file.Open(iFs, buf, EFileRead);
627 User::LeaveIfError(r);
629 CleanupClosePushL(file);
632 User::LeaveIfError(file.Size(fileSize));
636 iKeyData = HBufC8::NewMaxL(fileSize);
637 TPtr8 data(iKeyData->Des());
639 User::LeaveIfError(file.Read(data, fileSize));
640 CleanupStack::Pop(1);
646 TBool CImportKey::SetKeyAccessType(const TDesC8& aKeyAccessType)
649 if (aKeyAccessType.Compare(KExtractable)==0)
651 iAccessType |= CCTKeyInfo::EExtractable;
653 else if (aKeyAccessType.Compare(KSensitive)==0)
655 iAccessType |= CCTKeyInfo::ESensitive;
657 else if (aKeyAccessType.Compare(KAlwaysSensitive)==0)
659 iAccessType |= CCTKeyInfo::EAlwaysSensitive;
661 else if (aKeyAccessType.Compare(KNeverExtractable)==0)
663 iAccessType |= CCTKeyInfo::ENeverExtractable;
665 else if (aKeyAccessType.Compare(KLocal)==0)
667 iAccessType |= CCTKeyInfo::ELocal;
674 void CImportKey::PerformAction(TRequestStatus& aStatus)
676 TDriveUnit sysDrive (RFs::GetSystemDrive());
681 if (iKeyInfo != NULL)
687 // Delete t_secdlg files - this will then always answer "clanger" for the passphrase
690 TBuf<24> datFile(sysDrive.Name());
691 datFile.Append(_L("\\t_secdlg_in.dat"));
692 result = iFs.Delete(datFile);
694 if (result != KErrNone && result != KErrNotFound)
696 TRequestStatus* status = &aStatus;
697 User::RequestComplete(status, result);
701 datFile.Copy(sysDrive.Name());
702 datFile.Append(_L("\\t_secdlg_out.dat"));
703 result = iFs.Delete(datFile);
705 if (result != KErrNone && result != KErrNotFound)
707 TRequestStatus* status = &aStatus;
708 User::RequestComplete(status, result);
712 TRAP(result, iUnifiedKeyStore = CUnifiedKeyStore::NewL(iFs));
713 if ( (result==KErrNone) && (iUnifiedKeyStore) )
715 iUnifiedKeyStore->Initialize(aStatus);
727 if (KErrNone==aStatus.Int())
729 // Currently uses the first store, change to check the script for a specific store
730 iUnifiedKeyStore->ImportKey(0, iKeyData->Des(), iUsage, *iLabel, iAccessType,
731 TTime(0), TTime(0), iKeyInfo, aStatus);
735 // Errors get passed to next state
736 TRequestStatus* status = &aStatus;
737 User::RequestComplete(status, aStatus.Int());
747 TRequestStatus* status = &aStatus;
748 User::RequestComplete(status, aStatus.Int());
749 if ( (aStatus == iExpectedResult) || (aStatus==KErrAlreadyExists) )
764 void CImportKey::PerformCancel()
765 {// To do when test harness cancel comes back. Currently cancel testing
766 // is performed in RunL with a set of flags and a separate active object
769 void CImportKey::Reset()
772 void CImportKey::DoReportAction()
774 _LIT(KImporting, "Importing key from keystore...");
775 iOut.writeString(KImporting);
776 TPtr theLabel(iLabel->Des());
777 iOut.writeString(theLabel);
782 void CImportKey::DoCheckResult(TInt aError)
787 if (aError == KErrNone)
789 _LIT(KSuccessful, "Key imported successfully\n");
790 iConsole.Write(KSuccessful);
791 iOut.writeString(KSuccessful);
797 if ( (aError!=iExpectedResult) && (aError!=KErrAlreadyExists) )
799 _LIT(KFailed, "!!!Key import failure!!!\n");
800 iConsole.Write(KFailed);
801 iOut.writeString(KFailed);