os/security/securityanddataprivacytools/securitytools/certapp/encdec/filecertstore.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) 2008-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 "filecertstore.h"
sl@0
    20
#include "appuidmap.h"
sl@0
    21
#include "logger.h"
sl@0
    22
#include "stringconv.h"
sl@0
    23
#include "utils.h"
sl@0
    24
#include <iomanip>
sl@0
    25
sl@0
    26
EncDecContainerItem *AppUidListEntry::Factory()
sl@0
    27
{
sl@0
    28
	return new AppUidListEntry(AppUidMap::EnumEntries());
sl@0
    29
}
sl@0
    30
sl@0
    31
AppUidListEntry::AppUidListEntry(const EnumEntry *aEnumEntries)
sl@0
    32
	: EncDecContainerItem(), iUid("Application", aEnumEntries)
sl@0
    33
{
sl@0
    34
}
sl@0
    35
sl@0
    36
AppUidListEntry::~AppUidListEntry()
sl@0
    37
{
sl@0
    38
}
sl@0
    39
sl@0
    40
const char *AppUidListEntry::ItemType() const
sl@0
    41
{
sl@0
    42
	return 0; // n/a
sl@0
    43
}
sl@0
    44
sl@0
    45
sl@0
    46
void AppUidListEntry::Encode(REncodeWriteStream &aWriteStream)
sl@0
    47
{
sl@0
    48
	aWriteStream << iUid;
sl@0
    49
}
sl@0
    50
sl@0
    51
void AppUidListEntry::Decode(RDecodeReadStream &aReadStream)
sl@0
    52
{
sl@0
    53
	aReadStream >> iUid;
sl@0
    54
}
sl@0
    55
sl@0
    56
sl@0
    57
EncDecContainerItem *CertStoreEntry::Factory()
sl@0
    58
{
sl@0
    59
	return new CertStoreEntry;
sl@0
    60
}
sl@0
    61
sl@0
    62
sl@0
    63
static const EnumEntry enumDetailsForTBool[] =
sl@0
    64
{
sl@0
    65
    { "false", 0x00},
sl@0
    66
    { "true", 0x01},
sl@0
    67
    { "EFalse", false},
sl@0
    68
    { "ETrue", true},
sl@0
    69
	{ 0,0 }
sl@0
    70
};
sl@0
    71
sl@0
    72
sl@0
    73
CertStoreEntry::CertStoreEntry()
sl@0
    74
	: EncDecContainerItem(), 
sl@0
    75
	  iCertInfo(false),
sl@0
    76
	  iCertApps("ApplicationList", AppUidListEntry::Factory),
sl@0
    77
	  iTrusted("Trusted", enumDetailsForTBool), 
sl@0
    78
	  iReadDataStreamId("DataStreamId(read)", true),
sl@0
    79
	  iWriteDataStreamId("DataStreamId(write)", false),
sl@0
    80
	  iDataFileName("DataFileName"),
sl@0
    81
	  iCertData(),
sl@0
    82
	  iSwiMode(false)
sl@0
    83
{
sl@0
    84
	// We only need to initialise EncDecObject members which wrap non-class types
sl@0
    85
	iReadDataStreamId.Value() = 0;
sl@0
    86
	iWriteDataStreamId.Value() = 0;
sl@0
    87
}
sl@0
    88
sl@0
    89
CertStoreEntry::CertStoreEntry(bool aSwiMode)
sl@0
    90
	: EncDecContainerItem(), 
sl@0
    91
	  iCertInfo(aSwiMode),
sl@0
    92
	  iCertApps("ApplicationList", AppUidListEntry::Factory),
sl@0
    93
	  iTrusted("Trusted", enumDetailsForTBool), 
sl@0
    94
	  iReadDataStreamId("DataStreamId(read)", true),
sl@0
    95
	  iWriteDataStreamId("DataStreamId(write)", false),
sl@0
    96
	  iDataFileName("DataFileName"),
sl@0
    97
	  iCertData(),
sl@0
    98
	  iSwiMode(aSwiMode)
sl@0
    99
{
sl@0
   100
	// We only need to initialise EncDecObject members which wrap non-class types
sl@0
   101
	iReadDataStreamId.Value() = 0;
sl@0
   102
	iWriteDataStreamId.Value() = 0;
sl@0
   103
}
sl@0
   104
sl@0
   105
CertStoreEntry::~CertStoreEntry()
sl@0
   106
{
sl@0
   107
}
sl@0
   108
sl@0
   109
const TCertLabel &CertStoreEntry::Label() const
sl@0
   110
{
sl@0
   111
	return iCertInfo.Label();
sl@0
   112
}
sl@0
   113
sl@0
   114
CertInfo &CertStoreEntry::Info()
sl@0
   115
{
sl@0
   116
	return iCertInfo;
sl@0
   117
}
sl@0
   118
sl@0
   119
const CertInfo &CertStoreEntry::Info() const
sl@0
   120
{
sl@0
   121
	return iCertInfo;
sl@0
   122
}
sl@0
   123
sl@0
   124
sl@0
   125
sl@0
   126
const char *CertStoreEntry::ItemType() const
sl@0
   127
{
sl@0
   128
	return "Entry";
sl@0
   129
}
sl@0
   130
sl@0
   131
std::string CertStoreEntry::ItemName() const
sl@0
   132
{
sl@0
   133
	return stringFromUtf16(Label());
sl@0
   134
}
sl@0
   135
sl@0
   136
sl@0
   137
void CertStoreEntry::SetItemName(const std::string &aName)
sl@0
   138
{
sl@0
   139
	TInt outputWords;
sl@0
   140
	TText *outputBuf = utf16FromUtf8((const TUint8 *)aName.data(), aName.size(), outputWords);
sl@0
   141
	iCertInfo.Label() = TPtrC16(outputBuf, outputWords);
sl@0
   142
	delete [] outputBuf;
sl@0
   143
}
sl@0
   144
sl@0
   145
sl@0
   146
void CertStoreEntry::Encode(REncodeWriteStream &aWriteStream)
sl@0
   147
{
sl@0
   148
	iCertInfo.Encode(aWriteStream);
sl@0
   149
	aWriteStream << iCertApps;
sl@0
   150
	aWriteStream << iTrusted;
sl@0
   151
	if(aWriteStream.HumanReadable())
sl@0
   152
		{
sl@0
   153
		// Write data to a file
sl@0
   154
sl@0
   155
		// Generate a file name
sl@0
   156
		std::string certFileName = aWriteStream.CertFileName(iCertInfo.CertificateFormat(), iCertInfo.OutputCertificateId());
sl@0
   157
		iDataFileName.Value().Copy(TPtrC8((const TUint8*)certFileName.data(), certFileName.size()));
sl@0
   158
		
sl@0
   159
		// Write file name
sl@0
   160
		aWriteStream << iDataFileName;
sl@0
   161
		
sl@0
   162
		std::fstream certDataFile;
sl@0
   163
		OpenUtf8FStreamForWrite(certDataFile, certFileName.c_str());
sl@0
   164
		if(certDataFile.fail())
sl@0
   165
			{
sl@0
   166
			dbg << Log::Indent() << "Failed to open '" << certDataFile << "' for output!" << Log::Endl();
sl@0
   167
			FatalError();
sl@0
   168
			}
sl@0
   169
		if((iCertInfo.CertificateFormat() == EX509Certificate) && aWriteStream.PemOut())
sl@0
   170
			{
sl@0
   171
			std::string pemCert;
sl@0
   172
			Der2Pem(iCertData, pemCert);
sl@0
   173
			certDataFile.write(pemCert.data(), pemCert.size());
sl@0
   174
			}
sl@0
   175
		else
sl@0
   176
			{
sl@0
   177
			certDataFile.write(iCertData.data(), iCertData.size());
sl@0
   178
			}
sl@0
   179
		
sl@0
   180
		certDataFile.close();
sl@0
   181
		if(certDataFile.fail())
sl@0
   182
			{
sl@0
   183
			dbg << Log::Indent() << "Failed to write cert data to '" << certDataFile <<  Log::Endl();
sl@0
   184
			FatalError();
sl@0
   185
			}
sl@0
   186
		aWriteStream << iReadDataStreamId;
sl@0
   187
		}
sl@0
   188
	else
sl@0
   189
		{
sl@0
   190
		// Write to the store
sl@0
   191
		if(iCertData.size() != iCertInfo.CertSize())
sl@0
   192
			{
sl@0
   193
			dbg << Log::Indent() << "Internal error - cert data size does not match meta data" << Log::Endl();
sl@0
   194
			FatalError();
sl@0
   195
			}
sl@0
   196
sl@0
   197
		RStoreWriteStream dataStream;
sl@0
   198
		TStreamId dataStreamId = dataStream.CreateLC(*aWriteStream.StoreObject());
sl@0
   199
		prog << Log::Indent() << "Created store stream " << dataStreamId << " for certificate data" << Log::Endl();
sl@0
   200
		iWriteDataStreamId.Value() = dataStreamId;
sl@0
   201
sl@0
   202
		prog << Log::Indent() << "Writing " << iCertData.size() << " bytes of binary data" << Log::Endl();
sl@0
   203
		dataStream.WriteL((const TUint8 *)iCertData.data(), iCertData.size());
sl@0
   204
sl@0
   205
		CleanupStack::PopAndDestroy(&dataStream);
sl@0
   206
		aWriteStream << iWriteDataStreamId;
sl@0
   207
		}
sl@0
   208
}
sl@0
   209
sl@0
   210
void CertStoreEntry::Decode(RDecodeReadStream &aReadStream)
sl@0
   211
{
sl@0
   212
	iCertInfo.Decode(aReadStream);
sl@0
   213
	aReadStream >> iCertApps;
sl@0
   214
	if((!aReadStream.HumanReadable()) ||
sl@0
   215
	   (aReadStream.PeakToken() == iTrusted.Name()))
sl@0
   216
		{
sl@0
   217
		aReadStream >> iTrusted;
sl@0
   218
		}
sl@0
   219
	else
sl@0
   220
		{
sl@0
   221
		iTrusted.SetValue(true);
sl@0
   222
		}
sl@0
   223
	aReadStream >> iReadDataStreamId;
sl@0
   224
	if(aReadStream.HumanReadable())
sl@0
   225
		{
sl@0
   226
		aReadStream >> iDataFileName;
sl@0
   227
		// Read data from the specified file
sl@0
   228
		std::string nFileName = stringFromUtf16(iDataFileName.Value());
sl@0
   229
		
sl@0
   230
		std::fstream certDataFile;
sl@0
   231
		OpenUtf8FStreamForRead(certDataFile, nFileName.c_str());
sl@0
   232
		if(certDataFile.fail())
sl@0
   233
			{
sl@0
   234
			dbg << Log::Indent() << "Failed to open '" << nFileName << "' for input!" << Log::Endl();
sl@0
   235
			FatalError();
sl@0
   236
			}
sl@0
   237
		
sl@0
   238
		certDataFile.seekg(0, std::ios_base::end);
sl@0
   239
		TUint32 certSize = certDataFile.tellg();
sl@0
   240
		
sl@0
   241
		char *rawCertData = new char[certSize];
sl@0
   242
		
sl@0
   243
		certDataFile.seekg(0, std::ios_base::beg);
sl@0
   244
		certDataFile.read(rawCertData, certSize);
sl@0
   245
		
sl@0
   246
		certDataFile.close();
sl@0
   247
		if(certDataFile.fail())
sl@0
   248
			{
sl@0
   249
			dbg << Log::Indent() << "Failed to read cert data from '" << certDataFile << Log::Endl();
sl@0
   250
			FatalError();
sl@0
   251
			}
sl@0
   252
		iCertData.assign(rawCertData, certSize);
sl@0
   253
		delete [] rawCertData;
sl@0
   254
		
sl@0
   255
		if(iCertInfo.CertificateFormat() == EX509Certificate)
sl@0
   256
			{
sl@0
   257
			// It might be a PEM cert
sl@0
   258
			std::string derFromPem;
sl@0
   259
			if(Pem2Der(iCertData, derFromPem))
sl@0
   260
				{
sl@0
   261
				prog << Log::Indent() << "Converted PEM cert to DER" << Log::Endl();
sl@0
   262
				iCertData = derFromPem;
sl@0
   263
				certSize = iCertData.size();
sl@0
   264
				}
sl@0
   265
			}
sl@0
   266
		iCertInfo.SetCertSize(certSize);
sl@0
   267
		}
sl@0
   268
	else 
sl@0
   269
		{
sl@0
   270
		// Read data from the store
sl@0
   271
		RStoreReadStream dataStream;
sl@0
   272
		dataStream.OpenLC(*aReadStream.iStore, iReadDataStreamId.Value());
sl@0
   273
sl@0
   274
		TUint32 certSize = iCertInfo.CertSize();
sl@0
   275
		TUint8 * certData = new TUint8[certSize];
sl@0
   276
sl@0
   277
		prog << Log::Indent() << "Reading " << certSize << " byte certificate from store stream " << iReadDataStreamId.Value() << Log::Endl();
sl@0
   278
		
sl@0
   279
		dataStream.ReadL(certData, certSize);
sl@0
   280
sl@0
   281
		iCertData.assign((const char *)certData, certSize);
sl@0
   282
		
sl@0
   283
		CleanupStack::PopAndDestroy(&dataStream);
sl@0
   284
		}
sl@0
   285
sl@0
   286
	if(iCertInfo.CertificateFormat() == EX509Certificate)
sl@0
   287
		{
sl@0
   288
		TKeyIdentifier subjectKeyId;
sl@0
   289
		bool isCA = ( iCertInfo.CertificateOwnerType() != EUserCertificate );
sl@0
   290
sl@0
   291
		// nb. If processing a swicertstore we ignore any SubjectKeyId in the extension.
sl@0
   292
		if(X509SubjectKeyId((iSwiMode)?(KIgnoreCertificateExtension) : (KUseCertificateExtension), 
sl@0
   293
							false, isCA,
sl@0
   294
							iCertData,
sl@0
   295
							iCertSubject, subjectKeyId))
sl@0
   296
			{
sl@0
   297
			prog << Log::Indent() << "Subject = '" << iCertSubject << "'" << Log::Endl();
sl@0
   298
sl@0
   299
			prog << Log::Indent() << "Calculated SubjectKeyId is ";
sl@0
   300
			const TUint8 *p = subjectKeyId.Ptr();
sl@0
   301
			for(int i=0; i<subjectKeyId.Length(); ++i)
sl@0
   302
				{
sl@0
   303
				if(i) prog << ":";
sl@0
   304
				prog.Stream() << std::setfill('0') << std::setw(2) << int(p[i]);
sl@0
   305
				}
sl@0
   306
			prog.Stream() << std::setw(0);
sl@0
   307
			prog << Log::Endl();
sl@0
   308
			
sl@0
   309
			if(aReadStream.HumanReadable() && iCertInfo.SubjectKeyId().iAutoKey)
sl@0
   310
				{
sl@0
   311
				// Reading config file and auto set so copy generated
sl@0
   312
				// SubjectKeyId to value.
sl@0
   313
				prog << Log::Indent() << "Field set to auto so using calculated SubjectKeyId" << Log::Endl();;
sl@0
   314
				iCertInfo.SubjectKeyId().iHash = subjectKeyId;
sl@0
   315
				}
sl@0
   316
			else
sl@0
   317
				{
sl@0
   318
				// If the read value matches the calculated value then
sl@0
   319
				// set iAutoKey so we dump it as auto (with the value
sl@0
   320
				// as a comment).
sl@0
   321
				if(iCertInfo.SubjectKeyId().iHash == subjectKeyId)
sl@0
   322
					{
sl@0
   323
					prog << Log::Indent() << "Calculated SubjectKeyId matches value read from input so setting to auto" << Log::Endl();;
sl@0
   324
					iCertInfo.SubjectKeyId().iAutoKey = true;
sl@0
   325
					}
sl@0
   326
				else
sl@0
   327
					{
sl@0
   328
					prog << Log::Indent() << "Calculated SubjectKeyId does NOT match value read from input so setting to value read" << Log::Endl();;
sl@0
   329
					}
sl@0
   330
				
sl@0
   331
				}
sl@0
   332
			}
sl@0
   333
		}
sl@0
   334
}
sl@0
   335
	
sl@0
   336
CertStoreEntry& CertStoreEntry::operator= (const CertStoreEntry& aRhs)
sl@0
   337
{
sl@0
   338
	if(this == &aRhs) return *this; // handle self assignment
sl@0
   339
sl@0
   340
	EncDecContainerItem::operator=(*static_cast<const EncDecContainerItem *>(&aRhs));
sl@0
   341
sl@0
   342
	iCertInfo = aRhs.iCertInfo;
sl@0
   343
sl@0
   344
	iCertApps.reset();
sl@0
   345
	for(TUint32 i=0; i<aRhs.iCertApps.size(); ++i)
sl@0
   346
		{
sl@0
   347
		AppUidListEntry *newApp = new AppUidListEntry(AppUidMap::EnumEntries());
sl@0
   348
		const AppUidListEntry *oldApp = static_cast<const AppUidListEntry *>(&aRhs.iCertApps[i]);
sl@0
   349
		*newApp = *oldApp;
sl@0
   350
		iCertApps.push_back(newApp);
sl@0
   351
		}
sl@0
   352
sl@0
   353
	iTrusted = aRhs.iTrusted;
sl@0
   354
	iReadDataStreamId = aRhs.iReadDataStreamId;
sl@0
   355
	iWriteDataStreamId = aRhs.iWriteDataStreamId;
sl@0
   356
	iDataFileName = aRhs.iDataFileName;
sl@0
   357
	iCertData = aRhs.iCertData;
sl@0
   358
sl@0
   359
	iCertSubject = aRhs.iCertSubject;
sl@0
   360
sl@0
   361
	iSwiMode = aRhs.iSwiMode;
sl@0
   362
		
sl@0
   363
	return *this;
sl@0
   364
}
sl@0
   365
sl@0
   366
const TUint8 * CertStoreEntry::CertData() const
sl@0
   367
{
sl@0
   368
	return (const TUint8 *)iCertData.data();
sl@0
   369
}
sl@0
   370
sl@0
   371
sl@0
   372
const std::string &CertStoreEntry::CertSubject() const
sl@0
   373
{
sl@0
   374
	return iCertSubject;
sl@0
   375
}
sl@0
   376
sl@0
   377
sl@0
   378
sl@0
   379
// End of file