os/security/cryptoservices/certificateandkeymgmt/pkcs7/cmssignedobject.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) 2006-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 <cmssignedobject.h>
sl@0
    20
#include <x509cert.h>
sl@0
    21
#include <x509certext.h>
sl@0
    22
#include <asymmetrickeys.h>
sl@0
    23
#include <hash.h>
sl@0
    24
#include <asn1enc.h>
sl@0
    25
#include <asn1dec.h>
sl@0
    26
#include <pkcs7excert.h>
sl@0
    27
#include <cmssigneridentifier.h>
sl@0
    28
#include <cmscontentinfo.h>
sl@0
    29
#include <cmssignerinfo.h>
sl@0
    30
#include "cmsutils.h"
sl@0
    31
#include "pkcs7asn1.h"
sl@0
    32
sl@0
    33
const TInt KSignedDataCertificates = 0;
sl@0
    34
const TInt KSignedDataRevocationLists = 1;
sl@0
    35
sl@0
    36
const TInt KCmsMinSignedDataElements = 4;
sl@0
    37
//
sl@0
    38
// Implementation of CMS Signed object
sl@0
    39
//
sl@0
    40
EXPORT_C CCmsSignedObject* CCmsSignedObject::NewLC(TCmsContentInfoType aType, TBool aIsDetached, const TDesC8& aContentData)
sl@0
    41
	{
sl@0
    42
	CCmsSignedObject* self = new (ELeave) CCmsSignedObject();
sl@0
    43
	CleanupStack::PushL(self);
sl@0
    44
	self->ConstructL(aType, aIsDetached, aContentData);
sl@0
    45
	return self;
sl@0
    46
	}
sl@0
    47
sl@0
    48
EXPORT_C CCmsSignedObject* CCmsSignedObject::NewL(TCmsContentInfoType aType, TBool aIsDetached, const TDesC8& aContentData)
sl@0
    49
	{
sl@0
    50
	CCmsSignedObject* self = NewLC(aType, aIsDetached, aContentData);
sl@0
    51
	CleanupStack::Pop(self);
sl@0
    52
	return self;
sl@0
    53
	}
sl@0
    54
	
sl@0
    55
EXPORT_C CCmsSignedObject* CCmsSignedObject::NewLC(TCmsContentInfoType aType,
sl@0
    56
												const TDesC8& aHashValue,
sl@0
    57
												TAlgorithmId aDigestAlgorithm,
sl@0
    58
												const CDSAPrivateKey& aKey,
sl@0
    59
												const CX509Certificate& aCert,
sl@0
    60
												TBool aAddCertificate)
sl@0
    61
	{
sl@0
    62
	CCmsSignedObject* self = new (ELeave) CCmsSignedObject();
sl@0
    63
	CleanupStack::PushL(self);
sl@0
    64
	self->ConstructL(aType, aHashValue, aDigestAlgorithm, aKey, aCert, aAddCertificate);
sl@0
    65
	return self;
sl@0
    66
	}
sl@0
    67
sl@0
    68
EXPORT_C CCmsSignedObject* CCmsSignedObject::NewL(TCmsContentInfoType aType,
sl@0
    69
												const TDesC8& aHashValue,
sl@0
    70
												TAlgorithmId aDigestAlgorithm,
sl@0
    71
												const CDSAPrivateKey& aKey,
sl@0
    72
												const CX509Certificate& aCert,
sl@0
    73
												TBool aAddCertificate)
sl@0
    74
	{
sl@0
    75
	CCmsSignedObject* self = NewLC(aType, aHashValue, aDigestAlgorithm, aKey, aCert, aAddCertificate);
sl@0
    76
	CleanupStack::Pop(self);
sl@0
    77
	return self;
sl@0
    78
	}
sl@0
    79
sl@0
    80
sl@0
    81
EXPORT_C CCmsSignedObject* CCmsSignedObject::NewLC(TCmsContentInfoType aType,
sl@0
    82
												const TDesC8& aHashValue,
sl@0
    83
												TAlgorithmId aDigestAlgorithm,
sl@0
    84
												const CRSAPrivateKey& aKey,
sl@0
    85
												const CX509Certificate& aCert,
sl@0
    86
												TBool aAddCertificate)
sl@0
    87
	{
sl@0
    88
	CCmsSignedObject* self = new (ELeave) CCmsSignedObject();
sl@0
    89
	CleanupStack::PushL(self);
sl@0
    90
	self->ConstructL(aType, aHashValue, aDigestAlgorithm, aKey, aCert, aAddCertificate);
sl@0
    91
	return self;
sl@0
    92
	}
sl@0
    93
sl@0
    94
EXPORT_C CCmsSignedObject* CCmsSignedObject::NewL(TCmsContentInfoType aType,
sl@0
    95
												const TDesC8& aHashValue,
sl@0
    96
												TAlgorithmId aDigestAlgorithm,
sl@0
    97
												const CRSAPrivateKey& aKey,
sl@0
    98
												const CX509Certificate& aCert,
sl@0
    99
												TBool aAddCertificate)
sl@0
   100
	{
sl@0
   101
	CCmsSignedObject* self = NewLC(aType, aHashValue, aDigestAlgorithm, aKey, aCert, aAddCertificate);
sl@0
   102
	CleanupStack::Pop(self);
sl@0
   103
	return self;
sl@0
   104
	}
sl@0
   105
sl@0
   106
	
sl@0
   107
EXPORT_C CCmsSignedObject* CCmsSignedObject::NewL(const CCmsContentInfo& aContentInfo)
sl@0
   108
	{
sl@0
   109
	CCmsSignedObject* self = NewLC(aContentInfo);
sl@0
   110
	CleanupStack::Pop(self);
sl@0
   111
	return self;		
sl@0
   112
	}
sl@0
   113
	
sl@0
   114
EXPORT_C CCmsSignedObject* CCmsSignedObject::NewLC(const CCmsContentInfo& aContentInfo)
sl@0
   115
	{
sl@0
   116
	CCmsSignedObject* self = new (ELeave) CCmsSignedObject();
sl@0
   117
	CleanupStack::PushL(self);
sl@0
   118
	self->ConstructL(aContentInfo);
sl@0
   119
	return self;				
sl@0
   120
	}
sl@0
   121
sl@0
   122
CCmsSignedObject::CCmsSignedObject() : iVersion(EVersion_1)
sl@0
   123
	{
sl@0
   124
	}
sl@0
   125
sl@0
   126
EXPORT_C CCmsSignedObject::~CCmsSignedObject()
sl@0
   127
	{
sl@0
   128
	delete iContentInfo;
sl@0
   129
	iDigestAlgorithms.ResetAndDestroy();
sl@0
   130
	iCertificates.ResetAndDestroy();
sl@0
   131
	iSignerInfo.ResetAndDestroy();	
sl@0
   132
	for(TInt i = 0; i < KCmsMaxSignedDataElements; i++)
sl@0
   133
		{
sl@0
   134
		delete iDataElements.At(i);
sl@0
   135
		}		
sl@0
   136
	}
sl@0
   137
	
sl@0
   138
sl@0
   139
EXPORT_C TBool CCmsSignedObject::IsCertificateSetPresent() const
sl@0
   140
	{
sl@0
   141
	return iIsCertificateSetPresent;
sl@0
   142
	}
sl@0
   143
	
sl@0
   144
EXPORT_C TBool CCmsSignedObject::IsCertificateRevocationListsPresent() const
sl@0
   145
	{
sl@0
   146
	return iIsCertificateRevocationListsPresent;
sl@0
   147
	}
sl@0
   148
sl@0
   149
EXPORT_C TInt CCmsSignedObject::Version() const
sl@0
   150
	{
sl@0
   151
	return iVersion;	
sl@0
   152
	}
sl@0
   153
sl@0
   154
EXPORT_C const RPointerArray<CCmsCertificateChoice>& CCmsSignedObject::Certificates() const
sl@0
   155
	{
sl@0
   156
	return iCertificates;
sl@0
   157
	}
sl@0
   158
sl@0
   159
EXPORT_C const RPointerArray<CX509AlgorithmIdentifier>& CCmsSignedObject::DigestAlgorithms() const
sl@0
   160
	{
sl@0
   161
	return iDigestAlgorithms;
sl@0
   162
	}
sl@0
   163
sl@0
   164
EXPORT_C const CEncapsulatedContentInfo& CCmsSignedObject::ContentInfo() const
sl@0
   165
	{
sl@0
   166
	return *iContentInfo;
sl@0
   167
	}
sl@0
   168
		
sl@0
   169
EXPORT_C const RPointerArray<CCmsSignerInfo>& CCmsSignedObject::SignerInfo() const
sl@0
   170
	{
sl@0
   171
	return iSignerInfo;
sl@0
   172
	}
sl@0
   173
sl@0
   174
EXPORT_C void CCmsSignedObject::AddCertificateL(const CX509Certificate& aCert)
sl@0
   175
	{	
sl@0
   176
	CmsUtils::AddCertificateL(iCertificates, aCert);
sl@0
   177
	}
sl@0
   178
sl@0
   179
void CCmsSignedObject::AddDigestAlgorithmL(TAlgorithmId aDigestAlgorithm)
sl@0
   180
	{
sl@0
   181
	CmsUtils::AddAlgorithmIdentifierL(iDigestAlgorithms, aDigestAlgorithm);	
sl@0
   182
	}
sl@0
   183
sl@0
   184
EXPORT_C void CCmsSignedObject::AddCertificateL(const TDesC8& aCert, CCmsCertificateChoice::TCertificateType aType)
sl@0
   185
	{
sl@0
   186
	if (aType==CCmsCertificateChoice::ECertificateAttribute)
sl@0
   187
		{
sl@0
   188
		iVersion=EVersion_3;
sl@0
   189
		}
sl@0
   190
	CmsUtils::AddCertificateL(iCertificates, aCert, aType);
sl@0
   191
	}
sl@0
   192
sl@0
   193
void CCmsSignedObject::DecodeSignerInfoL(const TDesC8& aRawData)
sl@0
   194
	{	
sl@0
   195
	CArrayPtr<TASN1DecGeneric>* signerInfo = PKCS7ASN1::DecodeSequenceLC(aRawData);
sl@0
   196
	TInt total = signerInfo->Count();
sl@0
   197
	CCmsSignerInfo* signer(NULL);
sl@0
   198
sl@0
   199
	for(TInt item = 0; item < total; item ++)
sl@0
   200
		{
sl@0
   201
		signer = CCmsSignerInfo::NewL(signerInfo->At(item)->Encoding());
sl@0
   202
		CleanupStack::PushL(signer);
sl@0
   203
		User::LeaveIfError(iSignerInfo.Append(signer));
sl@0
   204
		CleanupStack::Pop(signer);
sl@0
   205
		}
sl@0
   206
	CleanupStack::PopAndDestroy(signerInfo);
sl@0
   207
	}
sl@0
   208
sl@0
   209
void CCmsSignedObject::DecodeEncapsulatedContentInfoL(const TDesC8& aRawData)
sl@0
   210
	{
sl@0
   211
	iContentInfo = CEncapsulatedContentInfo::NewL(aRawData);
sl@0
   212
	}
sl@0
   213
sl@0
   214
void CCmsSignedObject::ConstructL(const CCmsContentInfo& aContentInfo)
sl@0
   215
	{
sl@0
   216
	if(aContentInfo.ContentType() != EContentTypeSignedData)
sl@0
   217
		{
sl@0
   218
		User::Leave(KErrArgument);
sl@0
   219
		}
sl@0
   220
	
sl@0
   221
	TASN1DecGeneric decGen(aContentInfo.ContentData());
sl@0
   222
	decGen.InitL();
sl@0
   223
sl@0
   224
	if(decGen.Tag() == EASN1Sequence && decGen.Class()==EUniversal)
sl@0
   225
		{
sl@0
   226
		InitSignedObjectL(decGen.Encoding());
sl@0
   227
	    DecodeSignedDataL(*iEncoding);
sl@0
   228
		}
sl@0
   229
	else
sl@0
   230
		{
sl@0
   231
	    User::Leave(KErrArgument);
sl@0
   232
		}			
sl@0
   233
	}
sl@0
   234
sl@0
   235
void CCmsSignedObject::ConstructL(TCmsContentInfoType aType, TBool aIsDetached, const TDesC8& aContentData)
sl@0
   236
	{
sl@0
   237
	if (aContentData==KNullDesC8() && !aIsDetached)
sl@0
   238
		{
sl@0
   239
		User::Leave(KErrArgument);	
sl@0
   240
		}
sl@0
   241
	iContentInfo=CEncapsulatedContentInfo::NewL(aType, !aIsDetached, aContentData);	
sl@0
   242
	//For later use to create hash if detached and hash not provided
sl@0
   243
	iContentData.Set(aContentData);			
sl@0
   244
	}
sl@0
   245
sl@0
   246
CCmsSignerIdentifier* CCmsSignedObject::BuildSignerIdentifierLC(const CX509Certificate& aCert)
sl@0
   247
	{
sl@0
   248
	CCmsSignerIdentifier* sid(NULL);
sl@0
   249
	const CX509CertExtension* certExt = aCert.Extension(KSubjectKeyId);
sl@0
   250
	if (certExt)
sl@0
   251
		{
sl@0
   252
		CX509SubjectKeyIdExt* ext=CX509SubjectKeyIdExt::NewLC(certExt->Data());
sl@0
   253
		HBufC8* subKeyId=ext->KeyId().AllocL();
sl@0
   254
		CleanupStack::PopAndDestroy(ext);
sl@0
   255
		CleanupStack::PushL(subKeyId);
sl@0
   256
		sid=CCmsSignerIdentifier::NewL(subKeyId);
sl@0
   257
		CleanupStack::Pop(subKeyId);
sl@0
   258
		CleanupStack::PushL(sid);
sl@0
   259
		iVersion=EVersion_3;
sl@0
   260
		}
sl@0
   261
	else
sl@0
   262
		{
sl@0
   263
		CX500DistinguishedName* distinguishedName=CX500DistinguishedName::NewLC(aCert.IssuerName());
sl@0
   264
		CPKCS7IssuerAndSerialNumber* issuerAndSN=CPKCS7IssuerAndSerialNumber::NewL(distinguishedName, aCert.SerialNumber());
sl@0
   265
		CleanupStack::Pop(distinguishedName);
sl@0
   266
		CleanupStack::PushL(issuerAndSN);
sl@0
   267
		sid=CCmsSignerIdentifier::NewL(issuerAndSN);
sl@0
   268
		CleanupStack::Pop(issuerAndSN);
sl@0
   269
		CleanupStack::PushL(sid);
sl@0
   270
		}
sl@0
   271
	return sid;	
sl@0
   272
	}
sl@0
   273
sl@0
   274
sl@0
   275
void CCmsSignedObject::BuildSignerInfoCertListAndAlgoritmListL(TAlgorithmId aDigestAlgorithm,
sl@0
   276
																TBool aIsHash,
sl@0
   277
																const TDesC8& aValue,
sl@0
   278
																const CDSAPrivateKey& aKey,
sl@0
   279
																const CX509Certificate& aCert,
sl@0
   280
																TBool aAddCertificate)
sl@0
   281
	{		
sl@0
   282
	//build Signer Identifier
sl@0
   283
	CCmsSignerIdentifier* sid=BuildSignerIdentifierLC(aCert);
sl@0
   284
	
sl@0
   285
	//build digest algorithm and signing algorithm
sl@0
   286
	CX509AlgorithmIdentifier* digAlg=CX509AlgorithmIdentifier::NewLC(aDigestAlgorithm, KNullDesC8());
sl@0
   287
	const CSubjectPublicKeyInfo& publicKeyInfo=aCert.PublicKey();
sl@0
   288
	CX509AlgorithmIdentifier* signingAlg=CX509AlgorithmIdentifier::NewLC(publicKeyInfo.AlgorithmId(), KNullDesC8());
sl@0
   289
sl@0
   290
	//build signer info
sl@0
   291
	CCmsSignerInfo* signerInfo=CCmsSignerInfo::NewL(aValue,
sl@0
   292
													aIsHash,
sl@0
   293
													aKey,
sl@0
   294
													sid,
sl@0
   295
													digAlg,
sl@0
   296
													signingAlg);
sl@0
   297
	CleanupStack::Pop(3, sid);
sl@0
   298
	CleanupStack::PushL(signerInfo);
sl@0
   299
	//add to the signer info list
sl@0
   300
	iSignerInfo.AppendL(signerInfo);
sl@0
   301
	CleanupStack::Pop();
sl@0
   302
	
sl@0
   303
	//Add the certificate to the list if needed
sl@0
   304
	if (aAddCertificate)
sl@0
   305
		{
sl@0
   306
		AddCertificateL(aCert);
sl@0
   307
		}
sl@0
   308
		
sl@0
   309
	//Add the digest algorithm the list if needed
sl@0
   310
	AddDigestAlgorithmL(aDigestAlgorithm);	
sl@0
   311
	}
sl@0
   312
sl@0
   313
sl@0
   314
sl@0
   315
void CCmsSignedObject::BuildSignerInfoCertListAndAlgoritmListL(TAlgorithmId aDigestAlgorithm,
sl@0
   316
																TBool aIsHash,
sl@0
   317
																const TDesC8& aValue,
sl@0
   318
																const CRSAPrivateKey& aKey,
sl@0
   319
																const CX509Certificate& aCert,
sl@0
   320
																TBool aAddCertificate)
sl@0
   321
sl@0
   322
	{		
sl@0
   323
	//build Signer Identifier
sl@0
   324
	CCmsSignerIdentifier* sid=BuildSignerIdentifierLC(aCert);
sl@0
   325
	
sl@0
   326
	//build digest algorithm and signing algorithm
sl@0
   327
	CX509AlgorithmIdentifier* digAlg=CX509AlgorithmIdentifier::NewLC(aDigestAlgorithm, KNullDesC8());	
sl@0
   328
	const CSubjectPublicKeyInfo& publicKeyInfo=aCert.PublicKey();
sl@0
   329
	CX509AlgorithmIdentifier* signingAlg=CX509AlgorithmIdentifier::NewLC(publicKeyInfo.AlgorithmId(), publicKeyInfo.EncodedParams());
sl@0
   330
sl@0
   331
	//build signer info
sl@0
   332
	CCmsSignerInfo* signerInfo=CCmsSignerInfo::NewL(aValue,
sl@0
   333
													aIsHash,
sl@0
   334
													aKey,
sl@0
   335
													sid,
sl@0
   336
													digAlg,
sl@0
   337
													signingAlg);
sl@0
   338
	CleanupStack::Pop(3, sid);
sl@0
   339
	CleanupStack::PushL(signerInfo);
sl@0
   340
	//add to the signer info list
sl@0
   341
	iSignerInfo.AppendL(signerInfo);
sl@0
   342
	CleanupStack::Pop();
sl@0
   343
	
sl@0
   344
	//Add the certificate to the list if needed
sl@0
   345
	if (aAddCertificate)
sl@0
   346
		{
sl@0
   347
		AddCertificateL(aCert);
sl@0
   348
		}
sl@0
   349
		
sl@0
   350
	//Add the digest algorithm the list if needed
sl@0
   351
	AddDigestAlgorithmL(aDigestAlgorithm);
sl@0
   352
	}
sl@0
   353
sl@0
   354
void CCmsSignedObject::ConstructL(TCmsContentInfoType aType,
sl@0
   355
								const TDesC8& aHashValue,
sl@0
   356
								TAlgorithmId aDigestAlgorithm,
sl@0
   357
								const CDSAPrivateKey& aKey,
sl@0
   358
								const CX509Certificate& aCert,
sl@0
   359
								TBool aAddCertificate)
sl@0
   360
	{
sl@0
   361
	//Set the CMS object version to version 3 if the encapsulatedconetent data type is not data
sl@0
   362
	if (aType != EContentTypeData)
sl@0
   363
		{
sl@0
   364
		iVersion=EVersion_3;
sl@0
   365
		}
sl@0
   366
		
sl@0
   367
	//build EncapsulatedContentInfo	
sl@0
   368
	iContentInfo=CEncapsulatedContentInfo::NewL(aType, EFalse, KNullDesC8());
sl@0
   369
	
sl@0
   370
	BuildSignerInfoCertListAndAlgoritmListL(aDigestAlgorithm,
sl@0
   371
											ETrue,
sl@0
   372
											aHashValue,
sl@0
   373
											aKey,
sl@0
   374
											aCert,
sl@0
   375
											aAddCertificate);		
sl@0
   376
		
sl@0
   377
	}
sl@0
   378
void CCmsSignedObject::ConstructL(TCmsContentInfoType aType,
sl@0
   379
								const TDesC8& aHashValue,
sl@0
   380
								TAlgorithmId aDigestAlgorithm,
sl@0
   381
								const CRSAPrivateKey& aKey,
sl@0
   382
								const CX509Certificate& aCert,
sl@0
   383
								TBool aAddCertificate)
sl@0
   384
	{
sl@0
   385
	//Set the CMS object version to version 3 if the encapsulatedconetent data type is not data
sl@0
   386
	if (aType != EContentTypeData)
sl@0
   387
		{
sl@0
   388
		iVersion=EVersion_3;
sl@0
   389
		}
sl@0
   390
sl@0
   391
	//build EncapsulatedContentInfo	
sl@0
   392
	iContentInfo=CEncapsulatedContentInfo::NewL(aType, EFalse, KNullDesC8());
sl@0
   393
sl@0
   394
	BuildSignerInfoCertListAndAlgoritmListL(aDigestAlgorithm,
sl@0
   395
											ETrue,
sl@0
   396
											aHashValue,
sl@0
   397
											aKey,
sl@0
   398
											aCert,
sl@0
   399
											aAddCertificate);		
sl@0
   400
	}
sl@0
   401
sl@0
   402
sl@0
   403
EXPORT_C void CCmsSignedObject::SignL(const TDesC8& aHashValue,
sl@0
   404
										TAlgorithmId aDigestAlgorithm,
sl@0
   405
										const CDSAPrivateKey& aKey,
sl@0
   406
										const CX509Certificate& aCert,
sl@0
   407
										TBool aAddCertificate)
sl@0
   408
										
sl@0
   409
	{
sl@0
   410
	TBool isHash=(aHashValue!=KNullDesC8())? ETrue:EFalse;
sl@0
   411
	if (isHash)
sl@0
   412
		{
sl@0
   413
		BuildSignerInfoCertListAndAlgoritmListL(aDigestAlgorithm,
sl@0
   414
												isHash,
sl@0
   415
												aHashValue,
sl@0
   416
												aKey,
sl@0
   417
												aCert,
sl@0
   418
												aAddCertificate);			
sl@0
   419
		}
sl@0
   420
	else
sl@0
   421
		{
sl@0
   422
		if (iContentData!=KNullDesC8())
sl@0
   423
			{
sl@0
   424
			BuildSignerInfoCertListAndAlgoritmListL(aDigestAlgorithm,
sl@0
   425
													isHash,
sl@0
   426
													iContentData,
sl@0
   427
													aKey,
sl@0
   428
													aCert,
sl@0
   429
													aAddCertificate);							
sl@0
   430
			}
sl@0
   431
		else
sl@0
   432
			{
sl@0
   433
			//No way to sign if no data content nor its hash.
sl@0
   434
			User::Leave(KErrArgument);	
sl@0
   435
			}
sl@0
   436
		}
sl@0
   437
	}
sl@0
   438
										
sl@0
   439
EXPORT_C void CCmsSignedObject::SignL(const TDesC8& aHashValue,
sl@0
   440
										TAlgorithmId aDigestAlgorithm,
sl@0
   441
										const CRSAPrivateKey& aKey,
sl@0
   442
										const CX509Certificate& aCert,
sl@0
   443
										TBool aAddCertificate)
sl@0
   444
	{
sl@0
   445
	TBool isHash=(aHashValue!=KNullDesC8())? ETrue:EFalse;
sl@0
   446
	if (isHash)
sl@0
   447
		{
sl@0
   448
		BuildSignerInfoCertListAndAlgoritmListL(aDigestAlgorithm,
sl@0
   449
												isHash,
sl@0
   450
												aHashValue,
sl@0
   451
												aKey,
sl@0
   452
												aCert,
sl@0
   453
												aAddCertificate);			
sl@0
   454
		}
sl@0
   455
	else
sl@0
   456
		{
sl@0
   457
		if (iContentData!=KNullDesC8())
sl@0
   458
			{
sl@0
   459
			BuildSignerInfoCertListAndAlgoritmListL(aDigestAlgorithm,
sl@0
   460
													isHash,
sl@0
   461
													iContentData,
sl@0
   462
													aKey,
sl@0
   463
													aCert,
sl@0
   464
													aAddCertificate);
sl@0
   465
			}
sl@0
   466
		else
sl@0
   467
			{
sl@0
   468
			//No way to sign if no data content nor its hash.
sl@0
   469
			User::Leave(KErrArgument);	
sl@0
   470
			}
sl@0
   471
		}
sl@0
   472
	}
sl@0
   473
sl@0
   474
sl@0
   475
EXPORT_C CASN1EncSequence* CCmsSignedObject::EncodeASN1DERLC() const
sl@0
   476
	{
sl@0
   477
	// the root sequence contains the signed object
sl@0
   478
	CASN1EncSequence* root = CASN1EncSequence::NewLC();
sl@0
   479
	
sl@0
   480
	// Encode version
sl@0
   481
	CASN1EncInt* version=CASN1EncInt::NewLC(iVersion);	
sl@0
   482
	root->AddAndPopChildL(version);
sl@0
   483
sl@0
   484
	// Encode Algorithm
sl@0
   485
	CASN1EncBase* algorithm=EncodeAlgorithmsLC();
sl@0
   486
	root->AddAndPopChildL(algorithm);			
sl@0
   487
sl@0
   488
			
sl@0
   489
	// Encode EncapsulatedContentInfo	
sl@0
   490
	CASN1EncSequence* contentInfo=iContentInfo->EncodeASN1DERLC();
sl@0
   491
	root->AddAndPopChildL(contentInfo);
sl@0
   492
	
sl@0
   493
	// Encode option fields certificates SET
sl@0
   494
	CASN1EncBase* cert=EncodeCertificatesLC();
sl@0
   495
	if (cert)
sl@0
   496
		{
sl@0
   497
		root->AddAndPopChildL(cert);			
sl@0
   498
		}
sl@0
   499
		
sl@0
   500
	// Encode signerinfo
sl@0
   501
	CASN1EncBase* signerInfo=EncodeSignerInfoLC();
sl@0
   502
	root->AddAndPopChildL(signerInfo);			
sl@0
   503
	
sl@0
   504
	return root;
sl@0
   505
	}
sl@0
   506
sl@0
   507
sl@0
   508
CASN1EncBase* CCmsSignedObject::EncodeCertificatesLC() const
sl@0
   509
	{
sl@0
   510
	return CmsUtils::EncodeCertificatesLC(iCertificates);
sl@0
   511
	}
sl@0
   512
sl@0
   513
CASN1EncBase* CCmsSignedObject::EncodeAlgorithmsLC() const
sl@0
   514
	{
sl@0
   515
	return CmsUtils::EncodeDigestAlgorithmsLC(iDigestAlgorithms);
sl@0
   516
	}
sl@0
   517
sl@0
   518
CASN1EncBase* CCmsSignedObject::EncodeSignerInfoLC() const
sl@0
   519
	{
sl@0
   520
	CASN1EncSet* signerInfoSet = CASN1EncSet::NewLC();
sl@0
   521
	TInt count=iSignerInfo.Count();
sl@0
   522
	
sl@0
   523
	for (TInt i=0;i<count;i++)
sl@0
   524
		{
sl@0
   525
		CASN1EncSequence* signerInfo=iSignerInfo[i]->EncodeASN1DERLC();
sl@0
   526
		signerInfoSet->AddAndPopChildL(signerInfo);	
sl@0
   527
		}
sl@0
   528
	return signerInfoSet;	
sl@0
   529
	}
sl@0
   530
	
sl@0
   531
EXPORT_C TBool CCmsSignedObject::ValidateSignerLC(const CCmsSignerInfo& aSignerInfo, HBufC8*& aCertChainEncoding)
sl@0
   532
	{
sl@0
   533
	TInt certCount = iCertificates.Count();
sl@0
   534
	TInt endEntityPos = -1;
sl@0
   535
	TInt endEncodingSize = 0;
sl@0
   536
	TPtrC8 endEntityEncoding;
sl@0
   537
	TInt cert;
sl@0
   538
	TBool valid = EFalse;
sl@0
   539
sl@0
   540
	const CCmsSignerIdentifier& signerId = aSignerInfo.SignerIdentifier();
sl@0
   541
	
sl@0
   542
	// looks for end entity certificate
sl@0
   543
	for(cert = 0; cert < certCount; cert++)
sl@0
   544
		{
sl@0
   545
		if (iCertificates[cert]->CertificateType()==CCmsCertificateChoice::ECertificateX509)
sl@0
   546
			{
sl@0
   547
			const CX509Certificate& certificate = iCertificates[cert]->Certificate();
sl@0
   548
sl@0
   549
			endEncodingSize+= certificate.Encoding().Length();
sl@0
   550
			
sl@0
   551
			if(endEntityPos == -1)
sl@0
   552
				{
sl@0
   553
				if (signerId.SignerIdentifierType()==CCmsSignerIdentifier::EIssuerAndSerialNumber)
sl@0
   554
					{
sl@0
   555
					if (certificate.IssuerName().ExactMatchL(signerId.IssuerAndSerialNumber()->IssuerName()))
sl@0
   556
						{
sl@0
   557
						RInteger sn1=RInteger::NewL(certificate.SerialNumber());
sl@0
   558
						CleanupClosePushL(sn1);
sl@0
   559
						RInteger sn2=RInteger::NewL(signerId.IssuerAndSerialNumber()->SerialNumber());
sl@0
   560
						CleanupClosePushL(sn2);
sl@0
   561
						if (sn1==sn2)
sl@0
   562
							{
sl@0
   563
							endEntityPos = cert;
sl@0
   564
							endEntityEncoding.Set(certificate.Encoding());
sl@0
   565
							valid = ValidateSignatureL(aSignerInfo, certificate);					
sl@0
   566
							}
sl@0
   567
						CleanupStack::PopAndDestroy(2, &sn1);//sn2, sn1
sl@0
   568
						}
sl@0
   569
					}
sl@0
   570
				else
sl@0
   571
					{
sl@0
   572
					const CX509CertExtension* certExt = certificate.Extension(KSubjectKeyId);
sl@0
   573
					if (certExt)
sl@0
   574
						{
sl@0
   575
						CX509SubjectKeyIdExt* ext=CX509SubjectKeyIdExt::NewLC(certExt->Data());
sl@0
   576
						if (signerId.SubjectKeyIdentifier().Compare(ext->KeyId())==0)
sl@0
   577
							{
sl@0
   578
							endEntityPos = cert;
sl@0
   579
							endEntityEncoding.Set(certificate.Encoding());
sl@0
   580
							valid = ValidateSignatureL(aSignerInfo, certificate);						
sl@0
   581
							}
sl@0
   582
						CleanupStack::PopAndDestroy(ext);					
sl@0
   583
						}
sl@0
   584
					}											
sl@0
   585
				}
sl@0
   586
			}
sl@0
   587
		}
sl@0
   588
sl@0
   589
	// checks if end entity was found
sl@0
   590
	if(endEntityPos != -1)
sl@0
   591
		{
sl@0
   592
		// builds the cert chain encoding by putting the end entity first then all remaining
sl@0
   593
		// certs
sl@0
   594
  		aCertChainEncoding = HBufC8::NewLC(endEncodingSize);
sl@0
   595
  		TPtr8 encodingPtr(aCertChainEncoding->Des());
sl@0
   596
		encodingPtr.Copy(endEntityEncoding);
sl@0
   597
		for(cert = 0; cert < certCount; cert++)
sl@0
   598
			{
sl@0
   599
			if (iCertificates[cert]->CertificateType()==CCmsCertificateChoice::ECertificateX509)
sl@0
   600
				{
sl@0
   601
				const CX509Certificate& certificate = iCertificates[cert]->Certificate();
sl@0
   602
				if(cert != endEntityPos)
sl@0
   603
					{
sl@0
   604
					encodingPtr.Append(certificate.Encoding());
sl@0
   605
					}					
sl@0
   606
				}
sl@0
   607
			}
sl@0
   608
		}
sl@0
   609
	else
sl@0
   610
		{
sl@0
   611
		User::Leave(KErrNotFound);
sl@0
   612
		}
sl@0
   613
	return valid;
sl@0
   614
	}
sl@0
   615
sl@0
   616
sl@0
   617
EXPORT_C TBool CCmsSignedObject::ValidateSignerLC(const CCmsSignerInfo& aSignerInfo, const RPointerArray<CX509Certificate>& aCertificates, HBufC8*& aCertChainEncoding)
sl@0
   618
	{
sl@0
   619
	TInt certCount = aCertificates.Count();
sl@0
   620
	TInt endEntityPos = -1;
sl@0
   621
	TInt endEncodingSize = 0;
sl@0
   622
	TPtrC8 endEntityEncoding;
sl@0
   623
	TInt cert;
sl@0
   624
	TBool valid = EFalse;
sl@0
   625
	const CCmsSignerIdentifier& signerId = aSignerInfo.SignerIdentifier();
sl@0
   626
	
sl@0
   627
	// looks for end entity certificate
sl@0
   628
	for(cert = 0; cert < certCount; cert++)
sl@0
   629
		{
sl@0
   630
		const CX509Certificate& certificate = *aCertificates[cert];
sl@0
   631
		endEncodingSize+= certificate.Encoding().Length();
sl@0
   632
		if(endEntityPos == -1)
sl@0
   633
			{
sl@0
   634
			if (signerId.SignerIdentifierType()==CCmsSignerIdentifier::EIssuerAndSerialNumber)
sl@0
   635
				{
sl@0
   636
				if (certificate.IssuerName().ExactMatchL(signerId.IssuerAndSerialNumber()->IssuerName()))
sl@0
   637
					{					
sl@0
   638
					RInteger sn1=RInteger::NewL(certificate.SerialNumber());
sl@0
   639
					CleanupClosePushL(sn1);
sl@0
   640
					RInteger sn2=RInteger::NewL(signerId.IssuerAndSerialNumber()->SerialNumber());
sl@0
   641
					CleanupClosePushL(sn2);
sl@0
   642
					if (sn1==sn2)
sl@0
   643
						{
sl@0
   644
						endEntityPos = cert;
sl@0
   645
						endEntityEncoding.Set(certificate.Encoding());
sl@0
   646
						valid = ValidateSignatureL(aSignerInfo, certificate);					
sl@0
   647
						}
sl@0
   648
					CleanupStack::PopAndDestroy(2, &sn1);//sn2, sn1
sl@0
   649
					}
sl@0
   650
				}
sl@0
   651
			else
sl@0
   652
				{
sl@0
   653
				const CX509CertExtension* certExt = certificate.Extension(KSubjectKeyId);
sl@0
   654
				if (certExt)
sl@0
   655
					{
sl@0
   656
					CX509SubjectKeyIdExt* ext=CX509SubjectKeyIdExt::NewLC(certExt->Data());
sl@0
   657
					if (signerId.SubjectKeyIdentifier().Compare(ext->KeyId())==0)
sl@0
   658
						{
sl@0
   659
						endEntityPos = cert;
sl@0
   660
						endEntityEncoding.Set(certificate.Encoding());
sl@0
   661
						valid = ValidateSignatureL(aSignerInfo, certificate);						
sl@0
   662
						}
sl@0
   663
					CleanupStack::PopAndDestroy(ext);
sl@0
   664
					}
sl@0
   665
				}				
sl@0
   666
			}		
sl@0
   667
		}
sl@0
   668
sl@0
   669
	// checks if end entity was found
sl@0
   670
	if(endEntityPos != -1)
sl@0
   671
		{
sl@0
   672
		// builds the cert chain encoding by putting the end entity first then all remaining
sl@0
   673
		// certs
sl@0
   674
  		aCertChainEncoding = HBufC8::NewLC(endEncodingSize);
sl@0
   675
  		TPtr8 encodingPtr(aCertChainEncoding->Des());
sl@0
   676
		encodingPtr.Copy(endEntityEncoding);
sl@0
   677
		for(cert = 0; cert < certCount; cert++)
sl@0
   678
			{
sl@0
   679
			const CX509Certificate& certificate = *aCertificates[cert];
sl@0
   680
	
sl@0
   681
			if(cert != endEntityPos)
sl@0
   682
				{
sl@0
   683
				encodingPtr.Append(certificate.Encoding());
sl@0
   684
				}
sl@0
   685
			}
sl@0
   686
		}
sl@0
   687
	else
sl@0
   688
		{
sl@0
   689
		User::Leave(KErrNotFound);
sl@0
   690
		}
sl@0
   691
		
sl@0
   692
	return valid;
sl@0
   693
	}
sl@0
   694
sl@0
   695
sl@0
   696
EXPORT_C TBool CCmsSignedObject::ValidateSignerLC(const CCmsSignerInfo& aSignerInfo, HBufC8*& aCertChainEncoding, TBool aIsHash, const TDesC8& aContentDataOrHash)
sl@0
   697
	{
sl@0
   698
	if (aIsHash)
sl@0
   699
		{
sl@0
   700
		SetHash(aContentDataOrHash);	
sl@0
   701
		}
sl@0
   702
	else
sl@0
   703
		{
sl@0
   704
		SetContentData(aContentDataOrHash);
sl@0
   705
		}
sl@0
   706
	return ValidateSignerLC(aSignerInfo, aCertChainEncoding);
sl@0
   707
	}
sl@0
   708
sl@0
   709
EXPORT_C TBool CCmsSignedObject::ValidateSignerLC(const CCmsSignerInfo& aSignerInfo, const RPointerArray<CX509Certificate>& aCertificates, HBufC8*& aCertChainEncoding, TBool aIsHash, const TDesC8& aContentDataOrHash)
sl@0
   710
	{
sl@0
   711
	if (aIsHash)
sl@0
   712
		{
sl@0
   713
		SetHash(aContentDataOrHash);	
sl@0
   714
		}
sl@0
   715
	else
sl@0
   716
		{
sl@0
   717
		SetContentData(aContentDataOrHash);
sl@0
   718
		}
sl@0
   719
	return ValidateSignerLC(aSignerInfo, aCertificates, aCertChainEncoding);	
sl@0
   720
	}
sl@0
   721
sl@0
   722
TBool CCmsSignedObject::ValidateSignatureL(const CCmsSignerInfo& aSignerInfo, const CX509Certificate& aEndEntityCert)
sl@0
   723
	{
sl@0
   724
	delete iSigningAlgorithm;
sl@0
   725
	iSigningAlgorithm = NULL;			
sl@0
   726
	iSigningAlgorithm = CX509SigningAlgorithmIdentifier::NewL(aSignerInfo.SignatureAlgorithm(), aSignerInfo.DigestAlgorithm());
sl@0
   727
	
sl@0
   728
	delete iSignature;
sl@0
   729
	iSignature = NULL;
sl@0
   730
	iSignature = aSignerInfo.SignatureValue().AllocL();
sl@0
   731
	
sl@0
   732
	if (aSignerInfo.SignatureAlgorithm().Algorithm()==EDSA)
sl@0
   733
		{
sl@0
   734
		delete iParameters;
sl@0
   735
		iParameters = NULL;
sl@0
   736
		CDSAParameters* theDSAParams = iKeyFactory->DSAParametersL(aEndEntityCert.PublicKey().EncodedParams());
sl@0
   737
		CleanupStack::PushL(theDSAParams);
sl@0
   738
		CSigningKeyParameters* params = CSigningKeyParameters::NewLC();
sl@0
   739
		params->SetDSAParamsL(*theDSAParams);
sl@0
   740
		SetParametersL(*params);
sl@0
   741
		CleanupStack::PopAndDestroy(2, theDSAParams);
sl@0
   742
		}
sl@0
   743
	
sl@0
   744
	if (iContentInfo->IsContentDataPresent() || iContentData != KNullDesC8)
sl@0
   745
		{
sl@0
   746
		return VerifySignatureL(aEndEntityCert.PublicKey().KeyData());			
sl@0
   747
		}
sl@0
   748
	else if (iHash!=KNullDesC8)
sl@0
   749
			{
sl@0
   750
			return VerifySignatureL(aEndEntityCert.PublicKey().KeyData(), iHash);	
sl@0
   751
			}
sl@0
   752
		 else
sl@0
   753
			 {
sl@0
   754
			 User::Leave(KErrArgument);
sl@0
   755
			 return EFalse;
sl@0
   756
			 }			
sl@0
   757
	
sl@0
   758
	}
sl@0
   759
sl@0
   760
void CCmsSignedObject::InitSignedObjectL(const TDesC8& aRawData)
sl@0
   761
	{	
sl@0
   762
	// Populate CSignedObject data members
sl@0
   763
	iKeyFactory = new (ELeave) TX509KeyFactory;
sl@0
   764
	iEncoding = aRawData.AllocL();
sl@0
   765
sl@0
   766
	CSHA1* hash = CSHA1::NewL();
sl@0
   767
	CleanupStack::PushL(hash);
sl@0
   768
	iFingerprint = hash->Hash(Encoding()).AllocL();
sl@0
   769
	CleanupStack::PopAndDestroy(hash);	
sl@0
   770
	}
sl@0
   771
sl@0
   772
void CCmsSignedObject::DecodeSignedDataL(const TDesC8& aRawData)
sl@0
   773
	{		
sl@0
   774
	CArrayPtr<TASN1DecGeneric>* signedData = PKCS7ASN1::DecodeSequenceLC(aRawData, KCmsMinSignedDataElements, KCmsMaxSignedDataElements);
sl@0
   775
	TInt totalItems = signedData->Count();
sl@0
   776
	TASN1DecInteger decInt;
sl@0
   777
sl@0
   778
	// decodes version
sl@0
   779
	iDataElements.At(EVersionNumber) = new(ELeave) TPtrC8(signedData->At(0)->GetContentDER());
sl@0
   780
	iVersion = decInt.DecodeDERShortL(*signedData->At(0));
sl@0
   781
	if (iVersion>4 || iVersion<0)
sl@0
   782
		{
sl@0
   783
		User::Leave(KErrArgument);
sl@0
   784
		}
sl@0
   785
	// decodes algorithms
sl@0
   786
	iDataElements.At(EDigestAlgorithms) = new(ELeave) TPtrC8(signedData->At(1)->GetContentDER());
sl@0
   787
	DecodeDigestAlgorithmsL(signedData->At(1)->Encoding());
sl@0
   788
	// decodes contentinfo
sl@0
   789
	iDataElements.At(EEncapsulatedContentInfo) = new(ELeave) TPtrC8(signedData->At(2)->GetContentDER());
sl@0
   790
	DecodeEncapsulatedContentInfoL(signedData->At(2)->Encoding());
sl@0
   791
sl@0
   792
	// Checks for optional fields
sl@0
   793
	TInt pos = 3;	// Skip first non-optional fields
sl@0
   794
	do
sl@0
   795
		{
sl@0
   796
		const TASN1DecGeneric& currentItem = *signedData->At(pos);
sl@0
   797
		switch(currentItem.Tag())
sl@0
   798
			{
sl@0
   799
			case KSignedDataCertificates:
sl@0
   800
				{
sl@0
   801
				if (currentItem.Class()!=EContextSpecific)
sl@0
   802
					{
sl@0
   803
					User::Leave(KErrArgument);	
sl@0
   804
					}				
sl@0
   805
				iIsCertificateSetPresent=ETrue;
sl@0
   806
				iDataElements.At(ECertificates) = new(ELeave) TPtrC8(currentItem.GetContentDER());
sl@0
   807
				DecodeCertificatesL(currentItem.Encoding());
sl@0
   808
				break;
sl@0
   809
				}
sl@0
   810
			case KSignedDataRevocationLists:
sl@0
   811
				{
sl@0
   812
				if (currentItem.Class()!=EContextSpecific)
sl@0
   813
					{
sl@0
   814
					User::Leave(KErrArgument);	
sl@0
   815
					}				
sl@0
   816
				iIsCertificateRevocationListsPresent=ETrue;
sl@0
   817
				iDataElements.At(ERevocationLists) = new(ELeave) TPtrC8(currentItem.GetContentDER());
sl@0
   818
				DecodeRevocationListsL(currentItem.Encoding());
sl@0
   819
				break;
sl@0
   820
				}
sl@0
   821
			default:	
sl@0
   822
				{
sl@0
   823
				//Optional field with wrong tag and class
sl@0
   824
				if (pos<totalItems-1)
sl@0
   825
					{
sl@0
   826
					User::Leave(KErrArgument);
sl@0
   827
					}
sl@0
   828
				// else Non-optional field	
sl@0
   829
				}
sl@0
   830
			}
sl@0
   831
		pos++;
sl@0
   832
		}
sl@0
   833
	while(pos < totalItems);
sl@0
   834
sl@0
   835
	iDataElements.At(ESignedInfo) = new(ELeave) TPtrC8(signedData->At(totalItems-1)->GetContentDER());
sl@0
   836
	DecodeSignerInfoL(signedData->At(totalItems-1)->Encoding());
sl@0
   837
sl@0
   838
	CleanupStack::PopAndDestroy(signedData);
sl@0
   839
	}
sl@0
   840
sl@0
   841
void CCmsSignedObject::DecodeDigestAlgorithmsL(const TDesC8& aRawData)
sl@0
   842
	{	
sl@0
   843
	CmsUtils::DecodeDigestAlgorithmsL(iDigestAlgorithms, aRawData);
sl@0
   844
	}
sl@0
   845
sl@0
   846
void CCmsSignedObject::DecodeCertificatesL(const TDesC8& aRawData)
sl@0
   847
	{
sl@0
   848
	CmsUtils::DecodeCertificatesL(iCertificates, aRawData);	
sl@0
   849
	}
sl@0
   850
sl@0
   851
void CCmsSignedObject::DecodeRevocationListsL(const TDesC8& /*aRawData*/)
sl@0
   852
	{	
sl@0
   853
	}
sl@0
   854
	
sl@0
   855
EXPORT_C const TPtrC8 CCmsSignedObject::SignedDataL() const
sl@0
   856
	{
sl@0
   857
	if (iContentInfo->IsContentDataPresent())
sl@0
   858
		{
sl@0
   859
		return iContentInfo->ContentData();	
sl@0
   860
		}
sl@0
   861
	else
sl@0
   862
		{
sl@0
   863
		if (iContentData!=KNullDesC8)
sl@0
   864
			{
sl@0
   865
			return iContentData;	
sl@0
   866
			}
sl@0
   867
		else
sl@0
   868
			{
sl@0
   869
			User::Leave(KErrArgument);
sl@0
   870
			}
sl@0
   871
		}
sl@0
   872
	return KNullDesC8();
sl@0
   873
	}
sl@0
   874
sl@0
   875
EXPORT_C void CCmsSignedObject::InternalizeL(RReadStream& /*aStream*/) 
sl@0
   876
	{
sl@0
   877
	User::Leave(KErrNotSupported);
sl@0
   878
	}
sl@0
   879
sl@0
   880
EXPORT_C const TPtrC8* CCmsSignedObject::DataElementEncoding(const TUint aIndex) const
sl@0
   881
	{
sl@0
   882
	return iDataElements.At(aIndex);
sl@0
   883
	}
sl@0
   884
sl@0
   885
void CCmsSignedObject::SetContentData(const TDesC8& aContentData)
sl@0
   886
	{
sl@0
   887
	iContentData.Set(aContentData);	
sl@0
   888
	}
sl@0
   889
sl@0
   890
void CCmsSignedObject::SetHash(const TDesC8& aHash)
sl@0
   891
	{
sl@0
   892
	iHash.Set(aHash);
sl@0
   893
	}
sl@0
   894
sl@0
   895
sl@0
   896
	
sl@0
   897