sl@0: /* sl@0: * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include "filecertstore.h" sl@0: #include "appuidmap.h" sl@0: #include "logger.h" sl@0: #include "stringconv.h" sl@0: #include "utils.h" sl@0: #include sl@0: sl@0: EncDecContainerItem *AppUidListEntry::Factory() sl@0: { sl@0: return new AppUidListEntry(AppUidMap::EnumEntries()); sl@0: } sl@0: sl@0: AppUidListEntry::AppUidListEntry(const EnumEntry *aEnumEntries) sl@0: : EncDecContainerItem(), iUid("Application", aEnumEntries) sl@0: { sl@0: } sl@0: sl@0: AppUidListEntry::~AppUidListEntry() sl@0: { sl@0: } sl@0: sl@0: const char *AppUidListEntry::ItemType() const sl@0: { sl@0: return 0; // n/a sl@0: } sl@0: sl@0: sl@0: void AppUidListEntry::Encode(REncodeWriteStream &aWriteStream) sl@0: { sl@0: aWriteStream << iUid; sl@0: } sl@0: sl@0: void AppUidListEntry::Decode(RDecodeReadStream &aReadStream) sl@0: { sl@0: aReadStream >> iUid; sl@0: } sl@0: sl@0: sl@0: EncDecContainerItem *CertStoreEntry::Factory() sl@0: { sl@0: return new CertStoreEntry; sl@0: } sl@0: sl@0: sl@0: static const EnumEntry enumDetailsForTBool[] = sl@0: { sl@0: { "false", 0x00}, sl@0: { "true", 0x01}, sl@0: { "EFalse", false}, sl@0: { "ETrue", true}, sl@0: { 0,0 } sl@0: }; sl@0: sl@0: sl@0: CertStoreEntry::CertStoreEntry() sl@0: : EncDecContainerItem(), sl@0: iCertInfo(false), sl@0: iCertApps("ApplicationList", AppUidListEntry::Factory), sl@0: iTrusted("Trusted", enumDetailsForTBool), sl@0: iReadDataStreamId("DataStreamId(read)", true), sl@0: iWriteDataStreamId("DataStreamId(write)", false), sl@0: iDataFileName("DataFileName"), sl@0: iCertData(), sl@0: iSwiMode(false) sl@0: { sl@0: // We only need to initialise EncDecObject members which wrap non-class types sl@0: iReadDataStreamId.Value() = 0; sl@0: iWriteDataStreamId.Value() = 0; sl@0: } sl@0: sl@0: CertStoreEntry::CertStoreEntry(bool aSwiMode) sl@0: : EncDecContainerItem(), sl@0: iCertInfo(aSwiMode), sl@0: iCertApps("ApplicationList", AppUidListEntry::Factory), sl@0: iTrusted("Trusted", enumDetailsForTBool), sl@0: iReadDataStreamId("DataStreamId(read)", true), sl@0: iWriteDataStreamId("DataStreamId(write)", false), sl@0: iDataFileName("DataFileName"), sl@0: iCertData(), sl@0: iSwiMode(aSwiMode) sl@0: { sl@0: // We only need to initialise EncDecObject members which wrap non-class types sl@0: iReadDataStreamId.Value() = 0; sl@0: iWriteDataStreamId.Value() = 0; sl@0: } sl@0: sl@0: CertStoreEntry::~CertStoreEntry() sl@0: { sl@0: } sl@0: sl@0: const TCertLabel &CertStoreEntry::Label() const sl@0: { sl@0: return iCertInfo.Label(); sl@0: } sl@0: sl@0: CertInfo &CertStoreEntry::Info() sl@0: { sl@0: return iCertInfo; sl@0: } sl@0: sl@0: const CertInfo &CertStoreEntry::Info() const sl@0: { sl@0: return iCertInfo; sl@0: } sl@0: sl@0: sl@0: sl@0: const char *CertStoreEntry::ItemType() const sl@0: { sl@0: return "Entry"; sl@0: } sl@0: sl@0: std::string CertStoreEntry::ItemName() const sl@0: { sl@0: return stringFromUtf16(Label()); sl@0: } sl@0: sl@0: sl@0: void CertStoreEntry::SetItemName(const std::string &aName) sl@0: { sl@0: TInt outputWords; sl@0: TText *outputBuf = utf16FromUtf8((const TUint8 *)aName.data(), aName.size(), outputWords); sl@0: iCertInfo.Label() = TPtrC16(outputBuf, outputWords); sl@0: delete [] outputBuf; sl@0: } sl@0: sl@0: sl@0: void CertStoreEntry::Encode(REncodeWriteStream &aWriteStream) sl@0: { sl@0: iCertInfo.Encode(aWriteStream); sl@0: aWriteStream << iCertApps; sl@0: aWriteStream << iTrusted; sl@0: if(aWriteStream.HumanReadable()) sl@0: { sl@0: // Write data to a file sl@0: sl@0: // Generate a file name sl@0: std::string certFileName = aWriteStream.CertFileName(iCertInfo.CertificateFormat(), iCertInfo.OutputCertificateId()); sl@0: iDataFileName.Value().Copy(TPtrC8((const TUint8*)certFileName.data(), certFileName.size())); sl@0: sl@0: // Write file name sl@0: aWriteStream << iDataFileName; sl@0: sl@0: std::fstream certDataFile; sl@0: OpenUtf8FStreamForWrite(certDataFile, certFileName.c_str()); sl@0: if(certDataFile.fail()) sl@0: { sl@0: dbg << Log::Indent() << "Failed to open '" << certDataFile << "' for output!" << Log::Endl(); sl@0: FatalError(); sl@0: } sl@0: if((iCertInfo.CertificateFormat() == EX509Certificate) && aWriteStream.PemOut()) sl@0: { sl@0: std::string pemCert; sl@0: Der2Pem(iCertData, pemCert); sl@0: certDataFile.write(pemCert.data(), pemCert.size()); sl@0: } sl@0: else sl@0: { sl@0: certDataFile.write(iCertData.data(), iCertData.size()); sl@0: } sl@0: sl@0: certDataFile.close(); sl@0: if(certDataFile.fail()) sl@0: { sl@0: dbg << Log::Indent() << "Failed to write cert data to '" << certDataFile << Log::Endl(); sl@0: FatalError(); sl@0: } sl@0: aWriteStream << iReadDataStreamId; sl@0: } sl@0: else sl@0: { sl@0: // Write to the store sl@0: if(iCertData.size() != iCertInfo.CertSize()) sl@0: { sl@0: dbg << Log::Indent() << "Internal error - cert data size does not match meta data" << Log::Endl(); sl@0: FatalError(); sl@0: } sl@0: sl@0: RStoreWriteStream dataStream; sl@0: TStreamId dataStreamId = dataStream.CreateLC(*aWriteStream.StoreObject()); sl@0: prog << Log::Indent() << "Created store stream " << dataStreamId << " for certificate data" << Log::Endl(); sl@0: iWriteDataStreamId.Value() = dataStreamId; sl@0: sl@0: prog << Log::Indent() << "Writing " << iCertData.size() << " bytes of binary data" << Log::Endl(); sl@0: dataStream.WriteL((const TUint8 *)iCertData.data(), iCertData.size()); sl@0: sl@0: CleanupStack::PopAndDestroy(&dataStream); sl@0: aWriteStream << iWriteDataStreamId; sl@0: } sl@0: } sl@0: sl@0: void CertStoreEntry::Decode(RDecodeReadStream &aReadStream) sl@0: { sl@0: iCertInfo.Decode(aReadStream); sl@0: aReadStream >> iCertApps; sl@0: if((!aReadStream.HumanReadable()) || sl@0: (aReadStream.PeakToken() == iTrusted.Name())) sl@0: { sl@0: aReadStream >> iTrusted; sl@0: } sl@0: else sl@0: { sl@0: iTrusted.SetValue(true); sl@0: } sl@0: aReadStream >> iReadDataStreamId; sl@0: if(aReadStream.HumanReadable()) sl@0: { sl@0: aReadStream >> iDataFileName; sl@0: // Read data from the specified file sl@0: std::string nFileName = stringFromUtf16(iDataFileName.Value()); sl@0: sl@0: std::fstream certDataFile; sl@0: OpenUtf8FStreamForRead(certDataFile, nFileName.c_str()); sl@0: if(certDataFile.fail()) sl@0: { sl@0: dbg << Log::Indent() << "Failed to open '" << nFileName << "' for input!" << Log::Endl(); sl@0: FatalError(); sl@0: } sl@0: sl@0: certDataFile.seekg(0, std::ios_base::end); sl@0: TUint32 certSize = certDataFile.tellg(); sl@0: sl@0: char *rawCertData = new char[certSize]; sl@0: sl@0: certDataFile.seekg(0, std::ios_base::beg); sl@0: certDataFile.read(rawCertData, certSize); sl@0: sl@0: certDataFile.close(); sl@0: if(certDataFile.fail()) sl@0: { sl@0: dbg << Log::Indent() << "Failed to read cert data from '" << certDataFile << Log::Endl(); sl@0: FatalError(); sl@0: } sl@0: iCertData.assign(rawCertData, certSize); sl@0: delete [] rawCertData; sl@0: sl@0: if(iCertInfo.CertificateFormat() == EX509Certificate) sl@0: { sl@0: // It might be a PEM cert sl@0: std::string derFromPem; sl@0: if(Pem2Der(iCertData, derFromPem)) sl@0: { sl@0: prog << Log::Indent() << "Converted PEM cert to DER" << Log::Endl(); sl@0: iCertData = derFromPem; sl@0: certSize = iCertData.size(); sl@0: } sl@0: } sl@0: iCertInfo.SetCertSize(certSize); sl@0: } sl@0: else sl@0: { sl@0: // Read data from the store sl@0: RStoreReadStream dataStream; sl@0: dataStream.OpenLC(*aReadStream.iStore, iReadDataStreamId.Value()); sl@0: sl@0: TUint32 certSize = iCertInfo.CertSize(); sl@0: TUint8 * certData = new TUint8[certSize]; sl@0: sl@0: prog << Log::Indent() << "Reading " << certSize << " byte certificate from store stream " << iReadDataStreamId.Value() << Log::Endl(); sl@0: sl@0: dataStream.ReadL(certData, certSize); sl@0: sl@0: iCertData.assign((const char *)certData, certSize); sl@0: sl@0: CleanupStack::PopAndDestroy(&dataStream); sl@0: } sl@0: sl@0: if(iCertInfo.CertificateFormat() == EX509Certificate) sl@0: { sl@0: TKeyIdentifier subjectKeyId; sl@0: bool isCA = ( iCertInfo.CertificateOwnerType() != EUserCertificate ); sl@0: sl@0: // nb. If processing a swicertstore we ignore any SubjectKeyId in the extension. sl@0: if(X509SubjectKeyId((iSwiMode)?(KIgnoreCertificateExtension) : (KUseCertificateExtension), sl@0: false, isCA, sl@0: iCertData, sl@0: iCertSubject, subjectKeyId)) sl@0: { sl@0: prog << Log::Indent() << "Subject = '" << iCertSubject << "'" << Log::Endl(); sl@0: sl@0: prog << Log::Indent() << "Calculated SubjectKeyId is "; sl@0: const TUint8 *p = subjectKeyId.Ptr(); sl@0: for(int i=0; i(&aRhs)); sl@0: sl@0: iCertInfo = aRhs.iCertInfo; sl@0: sl@0: iCertApps.reset(); sl@0: for(TUint32 i=0; i(&aRhs.iCertApps[i]); sl@0: *newApp = *oldApp; sl@0: iCertApps.push_back(newApp); sl@0: } sl@0: sl@0: iTrusted = aRhs.iTrusted; sl@0: iReadDataStreamId = aRhs.iReadDataStreamId; sl@0: iWriteDataStreamId = aRhs.iWriteDataStreamId; sl@0: iDataFileName = aRhs.iDataFileName; sl@0: iCertData = aRhs.iCertData; sl@0: sl@0: iCertSubject = aRhs.iCertSubject; sl@0: sl@0: iSwiMode = aRhs.iSwiMode; sl@0: sl@0: return *this; sl@0: } sl@0: sl@0: const TUint8 * CertStoreEntry::CertData() const sl@0: { sl@0: return (const TUint8 *)iCertData.data(); sl@0: } sl@0: sl@0: sl@0: const std::string &CertStoreEntry::CertSubject() const sl@0: { sl@0: return iCertSubject; sl@0: } sl@0: sl@0: sl@0: sl@0: // End of file