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