1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/cryptoservices/certificateandkeymgmt/pkcs7/cmssignedobject.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,897 @@
1.4 +/*
1.5 +* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.6 +* All rights reserved.
1.7 +* This component and the accompanying materials are made available
1.8 +* under the terms of the License "Eclipse Public License v1.0"
1.9 +* which accompanies this distribution, and is available
1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.11 +*
1.12 +* Initial Contributors:
1.13 +* Nokia Corporation - initial contribution.
1.14 +*
1.15 +* Contributors:
1.16 +*
1.17 +* Description:
1.18 +*
1.19 +*/
1.20 +
1.21 +
1.22 +#include <cmssignedobject.h>
1.23 +#include <x509cert.h>
1.24 +#include <x509certext.h>
1.25 +#include <asymmetrickeys.h>
1.26 +#include <hash.h>
1.27 +#include <asn1enc.h>
1.28 +#include <asn1dec.h>
1.29 +#include <pkcs7excert.h>
1.30 +#include <cmssigneridentifier.h>
1.31 +#include <cmscontentinfo.h>
1.32 +#include <cmssignerinfo.h>
1.33 +#include "cmsutils.h"
1.34 +#include "pkcs7asn1.h"
1.35 +
1.36 +const TInt KSignedDataCertificates = 0;
1.37 +const TInt KSignedDataRevocationLists = 1;
1.38 +
1.39 +const TInt KCmsMinSignedDataElements = 4;
1.40 +//
1.41 +// Implementation of CMS Signed object
1.42 +//
1.43 +EXPORT_C CCmsSignedObject* CCmsSignedObject::NewLC(TCmsContentInfoType aType, TBool aIsDetached, const TDesC8& aContentData)
1.44 + {
1.45 + CCmsSignedObject* self = new (ELeave) CCmsSignedObject();
1.46 + CleanupStack::PushL(self);
1.47 + self->ConstructL(aType, aIsDetached, aContentData);
1.48 + return self;
1.49 + }
1.50 +
1.51 +EXPORT_C CCmsSignedObject* CCmsSignedObject::NewL(TCmsContentInfoType aType, TBool aIsDetached, const TDesC8& aContentData)
1.52 + {
1.53 + CCmsSignedObject* self = NewLC(aType, aIsDetached, aContentData);
1.54 + CleanupStack::Pop(self);
1.55 + return self;
1.56 + }
1.57 +
1.58 +EXPORT_C CCmsSignedObject* CCmsSignedObject::NewLC(TCmsContentInfoType aType,
1.59 + const TDesC8& aHashValue,
1.60 + TAlgorithmId aDigestAlgorithm,
1.61 + const CDSAPrivateKey& aKey,
1.62 + const CX509Certificate& aCert,
1.63 + TBool aAddCertificate)
1.64 + {
1.65 + CCmsSignedObject* self = new (ELeave) CCmsSignedObject();
1.66 + CleanupStack::PushL(self);
1.67 + self->ConstructL(aType, aHashValue, aDigestAlgorithm, aKey, aCert, aAddCertificate);
1.68 + return self;
1.69 + }
1.70 +
1.71 +EXPORT_C CCmsSignedObject* CCmsSignedObject::NewL(TCmsContentInfoType aType,
1.72 + const TDesC8& aHashValue,
1.73 + TAlgorithmId aDigestAlgorithm,
1.74 + const CDSAPrivateKey& aKey,
1.75 + const CX509Certificate& aCert,
1.76 + TBool aAddCertificate)
1.77 + {
1.78 + CCmsSignedObject* self = NewLC(aType, aHashValue, aDigestAlgorithm, aKey, aCert, aAddCertificate);
1.79 + CleanupStack::Pop(self);
1.80 + return self;
1.81 + }
1.82 +
1.83 +
1.84 +EXPORT_C CCmsSignedObject* CCmsSignedObject::NewLC(TCmsContentInfoType aType,
1.85 + const TDesC8& aHashValue,
1.86 + TAlgorithmId aDigestAlgorithm,
1.87 + const CRSAPrivateKey& aKey,
1.88 + const CX509Certificate& aCert,
1.89 + TBool aAddCertificate)
1.90 + {
1.91 + CCmsSignedObject* self = new (ELeave) CCmsSignedObject();
1.92 + CleanupStack::PushL(self);
1.93 + self->ConstructL(aType, aHashValue, aDigestAlgorithm, aKey, aCert, aAddCertificate);
1.94 + return self;
1.95 + }
1.96 +
1.97 +EXPORT_C CCmsSignedObject* CCmsSignedObject::NewL(TCmsContentInfoType aType,
1.98 + const TDesC8& aHashValue,
1.99 + TAlgorithmId aDigestAlgorithm,
1.100 + const CRSAPrivateKey& aKey,
1.101 + const CX509Certificate& aCert,
1.102 + TBool aAddCertificate)
1.103 + {
1.104 + CCmsSignedObject* self = NewLC(aType, aHashValue, aDigestAlgorithm, aKey, aCert, aAddCertificate);
1.105 + CleanupStack::Pop(self);
1.106 + return self;
1.107 + }
1.108 +
1.109 +
1.110 +EXPORT_C CCmsSignedObject* CCmsSignedObject::NewL(const CCmsContentInfo& aContentInfo)
1.111 + {
1.112 + CCmsSignedObject* self = NewLC(aContentInfo);
1.113 + CleanupStack::Pop(self);
1.114 + return self;
1.115 + }
1.116 +
1.117 +EXPORT_C CCmsSignedObject* CCmsSignedObject::NewLC(const CCmsContentInfo& aContentInfo)
1.118 + {
1.119 + CCmsSignedObject* self = new (ELeave) CCmsSignedObject();
1.120 + CleanupStack::PushL(self);
1.121 + self->ConstructL(aContentInfo);
1.122 + return self;
1.123 + }
1.124 +
1.125 +CCmsSignedObject::CCmsSignedObject() : iVersion(EVersion_1)
1.126 + {
1.127 + }
1.128 +
1.129 +EXPORT_C CCmsSignedObject::~CCmsSignedObject()
1.130 + {
1.131 + delete iContentInfo;
1.132 + iDigestAlgorithms.ResetAndDestroy();
1.133 + iCertificates.ResetAndDestroy();
1.134 + iSignerInfo.ResetAndDestroy();
1.135 + for(TInt i = 0; i < KCmsMaxSignedDataElements; i++)
1.136 + {
1.137 + delete iDataElements.At(i);
1.138 + }
1.139 + }
1.140 +
1.141 +
1.142 +EXPORT_C TBool CCmsSignedObject::IsCertificateSetPresent() const
1.143 + {
1.144 + return iIsCertificateSetPresent;
1.145 + }
1.146 +
1.147 +EXPORT_C TBool CCmsSignedObject::IsCertificateRevocationListsPresent() const
1.148 + {
1.149 + return iIsCertificateRevocationListsPresent;
1.150 + }
1.151 +
1.152 +EXPORT_C TInt CCmsSignedObject::Version() const
1.153 + {
1.154 + return iVersion;
1.155 + }
1.156 +
1.157 +EXPORT_C const RPointerArray<CCmsCertificateChoice>& CCmsSignedObject::Certificates() const
1.158 + {
1.159 + return iCertificates;
1.160 + }
1.161 +
1.162 +EXPORT_C const RPointerArray<CX509AlgorithmIdentifier>& CCmsSignedObject::DigestAlgorithms() const
1.163 + {
1.164 + return iDigestAlgorithms;
1.165 + }
1.166 +
1.167 +EXPORT_C const CEncapsulatedContentInfo& CCmsSignedObject::ContentInfo() const
1.168 + {
1.169 + return *iContentInfo;
1.170 + }
1.171 +
1.172 +EXPORT_C const RPointerArray<CCmsSignerInfo>& CCmsSignedObject::SignerInfo() const
1.173 + {
1.174 + return iSignerInfo;
1.175 + }
1.176 +
1.177 +EXPORT_C void CCmsSignedObject::AddCertificateL(const CX509Certificate& aCert)
1.178 + {
1.179 + CmsUtils::AddCertificateL(iCertificates, aCert);
1.180 + }
1.181 +
1.182 +void CCmsSignedObject::AddDigestAlgorithmL(TAlgorithmId aDigestAlgorithm)
1.183 + {
1.184 + CmsUtils::AddAlgorithmIdentifierL(iDigestAlgorithms, aDigestAlgorithm);
1.185 + }
1.186 +
1.187 +EXPORT_C void CCmsSignedObject::AddCertificateL(const TDesC8& aCert, CCmsCertificateChoice::TCertificateType aType)
1.188 + {
1.189 + if (aType==CCmsCertificateChoice::ECertificateAttribute)
1.190 + {
1.191 + iVersion=EVersion_3;
1.192 + }
1.193 + CmsUtils::AddCertificateL(iCertificates, aCert, aType);
1.194 + }
1.195 +
1.196 +void CCmsSignedObject::DecodeSignerInfoL(const TDesC8& aRawData)
1.197 + {
1.198 + CArrayPtr<TASN1DecGeneric>* signerInfo = PKCS7ASN1::DecodeSequenceLC(aRawData);
1.199 + TInt total = signerInfo->Count();
1.200 + CCmsSignerInfo* signer(NULL);
1.201 +
1.202 + for(TInt item = 0; item < total; item ++)
1.203 + {
1.204 + signer = CCmsSignerInfo::NewL(signerInfo->At(item)->Encoding());
1.205 + CleanupStack::PushL(signer);
1.206 + User::LeaveIfError(iSignerInfo.Append(signer));
1.207 + CleanupStack::Pop(signer);
1.208 + }
1.209 + CleanupStack::PopAndDestroy(signerInfo);
1.210 + }
1.211 +
1.212 +void CCmsSignedObject::DecodeEncapsulatedContentInfoL(const TDesC8& aRawData)
1.213 + {
1.214 + iContentInfo = CEncapsulatedContentInfo::NewL(aRawData);
1.215 + }
1.216 +
1.217 +void CCmsSignedObject::ConstructL(const CCmsContentInfo& aContentInfo)
1.218 + {
1.219 + if(aContentInfo.ContentType() != EContentTypeSignedData)
1.220 + {
1.221 + User::Leave(KErrArgument);
1.222 + }
1.223 +
1.224 + TASN1DecGeneric decGen(aContentInfo.ContentData());
1.225 + decGen.InitL();
1.226 +
1.227 + if(decGen.Tag() == EASN1Sequence && decGen.Class()==EUniversal)
1.228 + {
1.229 + InitSignedObjectL(decGen.Encoding());
1.230 + DecodeSignedDataL(*iEncoding);
1.231 + }
1.232 + else
1.233 + {
1.234 + User::Leave(KErrArgument);
1.235 + }
1.236 + }
1.237 +
1.238 +void CCmsSignedObject::ConstructL(TCmsContentInfoType aType, TBool aIsDetached, const TDesC8& aContentData)
1.239 + {
1.240 + if (aContentData==KNullDesC8() && !aIsDetached)
1.241 + {
1.242 + User::Leave(KErrArgument);
1.243 + }
1.244 + iContentInfo=CEncapsulatedContentInfo::NewL(aType, !aIsDetached, aContentData);
1.245 + //For later use to create hash if detached and hash not provided
1.246 + iContentData.Set(aContentData);
1.247 + }
1.248 +
1.249 +CCmsSignerIdentifier* CCmsSignedObject::BuildSignerIdentifierLC(const CX509Certificate& aCert)
1.250 + {
1.251 + CCmsSignerIdentifier* sid(NULL);
1.252 + const CX509CertExtension* certExt = aCert.Extension(KSubjectKeyId);
1.253 + if (certExt)
1.254 + {
1.255 + CX509SubjectKeyIdExt* ext=CX509SubjectKeyIdExt::NewLC(certExt->Data());
1.256 + HBufC8* subKeyId=ext->KeyId().AllocL();
1.257 + CleanupStack::PopAndDestroy(ext);
1.258 + CleanupStack::PushL(subKeyId);
1.259 + sid=CCmsSignerIdentifier::NewL(subKeyId);
1.260 + CleanupStack::Pop(subKeyId);
1.261 + CleanupStack::PushL(sid);
1.262 + iVersion=EVersion_3;
1.263 + }
1.264 + else
1.265 + {
1.266 + CX500DistinguishedName* distinguishedName=CX500DistinguishedName::NewLC(aCert.IssuerName());
1.267 + CPKCS7IssuerAndSerialNumber* issuerAndSN=CPKCS7IssuerAndSerialNumber::NewL(distinguishedName, aCert.SerialNumber());
1.268 + CleanupStack::Pop(distinguishedName);
1.269 + CleanupStack::PushL(issuerAndSN);
1.270 + sid=CCmsSignerIdentifier::NewL(issuerAndSN);
1.271 + CleanupStack::Pop(issuerAndSN);
1.272 + CleanupStack::PushL(sid);
1.273 + }
1.274 + return sid;
1.275 + }
1.276 +
1.277 +
1.278 +void CCmsSignedObject::BuildSignerInfoCertListAndAlgoritmListL(TAlgorithmId aDigestAlgorithm,
1.279 + TBool aIsHash,
1.280 + const TDesC8& aValue,
1.281 + const CDSAPrivateKey& aKey,
1.282 + const CX509Certificate& aCert,
1.283 + TBool aAddCertificate)
1.284 + {
1.285 + //build Signer Identifier
1.286 + CCmsSignerIdentifier* sid=BuildSignerIdentifierLC(aCert);
1.287 +
1.288 + //build digest algorithm and signing algorithm
1.289 + CX509AlgorithmIdentifier* digAlg=CX509AlgorithmIdentifier::NewLC(aDigestAlgorithm, KNullDesC8());
1.290 + const CSubjectPublicKeyInfo& publicKeyInfo=aCert.PublicKey();
1.291 + CX509AlgorithmIdentifier* signingAlg=CX509AlgorithmIdentifier::NewLC(publicKeyInfo.AlgorithmId(), KNullDesC8());
1.292 +
1.293 + //build signer info
1.294 + CCmsSignerInfo* signerInfo=CCmsSignerInfo::NewL(aValue,
1.295 + aIsHash,
1.296 + aKey,
1.297 + sid,
1.298 + digAlg,
1.299 + signingAlg);
1.300 + CleanupStack::Pop(3, sid);
1.301 + CleanupStack::PushL(signerInfo);
1.302 + //add to the signer info list
1.303 + iSignerInfo.AppendL(signerInfo);
1.304 + CleanupStack::Pop();
1.305 +
1.306 + //Add the certificate to the list if needed
1.307 + if (aAddCertificate)
1.308 + {
1.309 + AddCertificateL(aCert);
1.310 + }
1.311 +
1.312 + //Add the digest algorithm the list if needed
1.313 + AddDigestAlgorithmL(aDigestAlgorithm);
1.314 + }
1.315 +
1.316 +
1.317 +
1.318 +void CCmsSignedObject::BuildSignerInfoCertListAndAlgoritmListL(TAlgorithmId aDigestAlgorithm,
1.319 + TBool aIsHash,
1.320 + const TDesC8& aValue,
1.321 + const CRSAPrivateKey& aKey,
1.322 + const CX509Certificate& aCert,
1.323 + TBool aAddCertificate)
1.324 +
1.325 + {
1.326 + //build Signer Identifier
1.327 + CCmsSignerIdentifier* sid=BuildSignerIdentifierLC(aCert);
1.328 +
1.329 + //build digest algorithm and signing algorithm
1.330 + CX509AlgorithmIdentifier* digAlg=CX509AlgorithmIdentifier::NewLC(aDigestAlgorithm, KNullDesC8());
1.331 + const CSubjectPublicKeyInfo& publicKeyInfo=aCert.PublicKey();
1.332 + CX509AlgorithmIdentifier* signingAlg=CX509AlgorithmIdentifier::NewLC(publicKeyInfo.AlgorithmId(), publicKeyInfo.EncodedParams());
1.333 +
1.334 + //build signer info
1.335 + CCmsSignerInfo* signerInfo=CCmsSignerInfo::NewL(aValue,
1.336 + aIsHash,
1.337 + aKey,
1.338 + sid,
1.339 + digAlg,
1.340 + signingAlg);
1.341 + CleanupStack::Pop(3, sid);
1.342 + CleanupStack::PushL(signerInfo);
1.343 + //add to the signer info list
1.344 + iSignerInfo.AppendL(signerInfo);
1.345 + CleanupStack::Pop();
1.346 +
1.347 + //Add the certificate to the list if needed
1.348 + if (aAddCertificate)
1.349 + {
1.350 + AddCertificateL(aCert);
1.351 + }
1.352 +
1.353 + //Add the digest algorithm the list if needed
1.354 + AddDigestAlgorithmL(aDigestAlgorithm);
1.355 + }
1.356 +
1.357 +void CCmsSignedObject::ConstructL(TCmsContentInfoType aType,
1.358 + const TDesC8& aHashValue,
1.359 + TAlgorithmId aDigestAlgorithm,
1.360 + const CDSAPrivateKey& aKey,
1.361 + const CX509Certificate& aCert,
1.362 + TBool aAddCertificate)
1.363 + {
1.364 + //Set the CMS object version to version 3 if the encapsulatedconetent data type is not data
1.365 + if (aType != EContentTypeData)
1.366 + {
1.367 + iVersion=EVersion_3;
1.368 + }
1.369 +
1.370 + //build EncapsulatedContentInfo
1.371 + iContentInfo=CEncapsulatedContentInfo::NewL(aType, EFalse, KNullDesC8());
1.372 +
1.373 + BuildSignerInfoCertListAndAlgoritmListL(aDigestAlgorithm,
1.374 + ETrue,
1.375 + aHashValue,
1.376 + aKey,
1.377 + aCert,
1.378 + aAddCertificate);
1.379 +
1.380 + }
1.381 +void CCmsSignedObject::ConstructL(TCmsContentInfoType aType,
1.382 + const TDesC8& aHashValue,
1.383 + TAlgorithmId aDigestAlgorithm,
1.384 + const CRSAPrivateKey& aKey,
1.385 + const CX509Certificate& aCert,
1.386 + TBool aAddCertificate)
1.387 + {
1.388 + //Set the CMS object version to version 3 if the encapsulatedconetent data type is not data
1.389 + if (aType != EContentTypeData)
1.390 + {
1.391 + iVersion=EVersion_3;
1.392 + }
1.393 +
1.394 + //build EncapsulatedContentInfo
1.395 + iContentInfo=CEncapsulatedContentInfo::NewL(aType, EFalse, KNullDesC8());
1.396 +
1.397 + BuildSignerInfoCertListAndAlgoritmListL(aDigestAlgorithm,
1.398 + ETrue,
1.399 + aHashValue,
1.400 + aKey,
1.401 + aCert,
1.402 + aAddCertificate);
1.403 + }
1.404 +
1.405 +
1.406 +EXPORT_C void CCmsSignedObject::SignL(const TDesC8& aHashValue,
1.407 + TAlgorithmId aDigestAlgorithm,
1.408 + const CDSAPrivateKey& aKey,
1.409 + const CX509Certificate& aCert,
1.410 + TBool aAddCertificate)
1.411 +
1.412 + {
1.413 + TBool isHash=(aHashValue!=KNullDesC8())? ETrue:EFalse;
1.414 + if (isHash)
1.415 + {
1.416 + BuildSignerInfoCertListAndAlgoritmListL(aDigestAlgorithm,
1.417 + isHash,
1.418 + aHashValue,
1.419 + aKey,
1.420 + aCert,
1.421 + aAddCertificate);
1.422 + }
1.423 + else
1.424 + {
1.425 + if (iContentData!=KNullDesC8())
1.426 + {
1.427 + BuildSignerInfoCertListAndAlgoritmListL(aDigestAlgorithm,
1.428 + isHash,
1.429 + iContentData,
1.430 + aKey,
1.431 + aCert,
1.432 + aAddCertificate);
1.433 + }
1.434 + else
1.435 + {
1.436 + //No way to sign if no data content nor its hash.
1.437 + User::Leave(KErrArgument);
1.438 + }
1.439 + }
1.440 + }
1.441 +
1.442 +EXPORT_C void CCmsSignedObject::SignL(const TDesC8& aHashValue,
1.443 + TAlgorithmId aDigestAlgorithm,
1.444 + const CRSAPrivateKey& aKey,
1.445 + const CX509Certificate& aCert,
1.446 + TBool aAddCertificate)
1.447 + {
1.448 + TBool isHash=(aHashValue!=KNullDesC8())? ETrue:EFalse;
1.449 + if (isHash)
1.450 + {
1.451 + BuildSignerInfoCertListAndAlgoritmListL(aDigestAlgorithm,
1.452 + isHash,
1.453 + aHashValue,
1.454 + aKey,
1.455 + aCert,
1.456 + aAddCertificate);
1.457 + }
1.458 + else
1.459 + {
1.460 + if (iContentData!=KNullDesC8())
1.461 + {
1.462 + BuildSignerInfoCertListAndAlgoritmListL(aDigestAlgorithm,
1.463 + isHash,
1.464 + iContentData,
1.465 + aKey,
1.466 + aCert,
1.467 + aAddCertificate);
1.468 + }
1.469 + else
1.470 + {
1.471 + //No way to sign if no data content nor its hash.
1.472 + User::Leave(KErrArgument);
1.473 + }
1.474 + }
1.475 + }
1.476 +
1.477 +
1.478 +EXPORT_C CASN1EncSequence* CCmsSignedObject::EncodeASN1DERLC() const
1.479 + {
1.480 + // the root sequence contains the signed object
1.481 + CASN1EncSequence* root = CASN1EncSequence::NewLC();
1.482 +
1.483 + // Encode version
1.484 + CASN1EncInt* version=CASN1EncInt::NewLC(iVersion);
1.485 + root->AddAndPopChildL(version);
1.486 +
1.487 + // Encode Algorithm
1.488 + CASN1EncBase* algorithm=EncodeAlgorithmsLC();
1.489 + root->AddAndPopChildL(algorithm);
1.490 +
1.491 +
1.492 + // Encode EncapsulatedContentInfo
1.493 + CASN1EncSequence* contentInfo=iContentInfo->EncodeASN1DERLC();
1.494 + root->AddAndPopChildL(contentInfo);
1.495 +
1.496 + // Encode option fields certificates SET
1.497 + CASN1EncBase* cert=EncodeCertificatesLC();
1.498 + if (cert)
1.499 + {
1.500 + root->AddAndPopChildL(cert);
1.501 + }
1.502 +
1.503 + // Encode signerinfo
1.504 + CASN1EncBase* signerInfo=EncodeSignerInfoLC();
1.505 + root->AddAndPopChildL(signerInfo);
1.506 +
1.507 + return root;
1.508 + }
1.509 +
1.510 +
1.511 +CASN1EncBase* CCmsSignedObject::EncodeCertificatesLC() const
1.512 + {
1.513 + return CmsUtils::EncodeCertificatesLC(iCertificates);
1.514 + }
1.515 +
1.516 +CASN1EncBase* CCmsSignedObject::EncodeAlgorithmsLC() const
1.517 + {
1.518 + return CmsUtils::EncodeDigestAlgorithmsLC(iDigestAlgorithms);
1.519 + }
1.520 +
1.521 +CASN1EncBase* CCmsSignedObject::EncodeSignerInfoLC() const
1.522 + {
1.523 + CASN1EncSet* signerInfoSet = CASN1EncSet::NewLC();
1.524 + TInt count=iSignerInfo.Count();
1.525 +
1.526 + for (TInt i=0;i<count;i++)
1.527 + {
1.528 + CASN1EncSequence* signerInfo=iSignerInfo[i]->EncodeASN1DERLC();
1.529 + signerInfoSet->AddAndPopChildL(signerInfo);
1.530 + }
1.531 + return signerInfoSet;
1.532 + }
1.533 +
1.534 +EXPORT_C TBool CCmsSignedObject::ValidateSignerLC(const CCmsSignerInfo& aSignerInfo, HBufC8*& aCertChainEncoding)
1.535 + {
1.536 + TInt certCount = iCertificates.Count();
1.537 + TInt endEntityPos = -1;
1.538 + TInt endEncodingSize = 0;
1.539 + TPtrC8 endEntityEncoding;
1.540 + TInt cert;
1.541 + TBool valid = EFalse;
1.542 +
1.543 + const CCmsSignerIdentifier& signerId = aSignerInfo.SignerIdentifier();
1.544 +
1.545 + // looks for end entity certificate
1.546 + for(cert = 0; cert < certCount; cert++)
1.547 + {
1.548 + if (iCertificates[cert]->CertificateType()==CCmsCertificateChoice::ECertificateX509)
1.549 + {
1.550 + const CX509Certificate& certificate = iCertificates[cert]->Certificate();
1.551 +
1.552 + endEncodingSize+= certificate.Encoding().Length();
1.553 +
1.554 + if(endEntityPos == -1)
1.555 + {
1.556 + if (signerId.SignerIdentifierType()==CCmsSignerIdentifier::EIssuerAndSerialNumber)
1.557 + {
1.558 + if (certificate.IssuerName().ExactMatchL(signerId.IssuerAndSerialNumber()->IssuerName()))
1.559 + {
1.560 + RInteger sn1=RInteger::NewL(certificate.SerialNumber());
1.561 + CleanupClosePushL(sn1);
1.562 + RInteger sn2=RInteger::NewL(signerId.IssuerAndSerialNumber()->SerialNumber());
1.563 + CleanupClosePushL(sn2);
1.564 + if (sn1==sn2)
1.565 + {
1.566 + endEntityPos = cert;
1.567 + endEntityEncoding.Set(certificate.Encoding());
1.568 + valid = ValidateSignatureL(aSignerInfo, certificate);
1.569 + }
1.570 + CleanupStack::PopAndDestroy(2, &sn1);//sn2, sn1
1.571 + }
1.572 + }
1.573 + else
1.574 + {
1.575 + const CX509CertExtension* certExt = certificate.Extension(KSubjectKeyId);
1.576 + if (certExt)
1.577 + {
1.578 + CX509SubjectKeyIdExt* ext=CX509SubjectKeyIdExt::NewLC(certExt->Data());
1.579 + if (signerId.SubjectKeyIdentifier().Compare(ext->KeyId())==0)
1.580 + {
1.581 + endEntityPos = cert;
1.582 + endEntityEncoding.Set(certificate.Encoding());
1.583 + valid = ValidateSignatureL(aSignerInfo, certificate);
1.584 + }
1.585 + CleanupStack::PopAndDestroy(ext);
1.586 + }
1.587 + }
1.588 + }
1.589 + }
1.590 + }
1.591 +
1.592 + // checks if end entity was found
1.593 + if(endEntityPos != -1)
1.594 + {
1.595 + // builds the cert chain encoding by putting the end entity first then all remaining
1.596 + // certs
1.597 + aCertChainEncoding = HBufC8::NewLC(endEncodingSize);
1.598 + TPtr8 encodingPtr(aCertChainEncoding->Des());
1.599 + encodingPtr.Copy(endEntityEncoding);
1.600 + for(cert = 0; cert < certCount; cert++)
1.601 + {
1.602 + if (iCertificates[cert]->CertificateType()==CCmsCertificateChoice::ECertificateX509)
1.603 + {
1.604 + const CX509Certificate& certificate = iCertificates[cert]->Certificate();
1.605 + if(cert != endEntityPos)
1.606 + {
1.607 + encodingPtr.Append(certificate.Encoding());
1.608 + }
1.609 + }
1.610 + }
1.611 + }
1.612 + else
1.613 + {
1.614 + User::Leave(KErrNotFound);
1.615 + }
1.616 + return valid;
1.617 + }
1.618 +
1.619 +
1.620 +EXPORT_C TBool CCmsSignedObject::ValidateSignerLC(const CCmsSignerInfo& aSignerInfo, const RPointerArray<CX509Certificate>& aCertificates, HBufC8*& aCertChainEncoding)
1.621 + {
1.622 + TInt certCount = aCertificates.Count();
1.623 + TInt endEntityPos = -1;
1.624 + TInt endEncodingSize = 0;
1.625 + TPtrC8 endEntityEncoding;
1.626 + TInt cert;
1.627 + TBool valid = EFalse;
1.628 + const CCmsSignerIdentifier& signerId = aSignerInfo.SignerIdentifier();
1.629 +
1.630 + // looks for end entity certificate
1.631 + for(cert = 0; cert < certCount; cert++)
1.632 + {
1.633 + const CX509Certificate& certificate = *aCertificates[cert];
1.634 + endEncodingSize+= certificate.Encoding().Length();
1.635 + if(endEntityPos == -1)
1.636 + {
1.637 + if (signerId.SignerIdentifierType()==CCmsSignerIdentifier::EIssuerAndSerialNumber)
1.638 + {
1.639 + if (certificate.IssuerName().ExactMatchL(signerId.IssuerAndSerialNumber()->IssuerName()))
1.640 + {
1.641 + RInteger sn1=RInteger::NewL(certificate.SerialNumber());
1.642 + CleanupClosePushL(sn1);
1.643 + RInteger sn2=RInteger::NewL(signerId.IssuerAndSerialNumber()->SerialNumber());
1.644 + CleanupClosePushL(sn2);
1.645 + if (sn1==sn2)
1.646 + {
1.647 + endEntityPos = cert;
1.648 + endEntityEncoding.Set(certificate.Encoding());
1.649 + valid = ValidateSignatureL(aSignerInfo, certificate);
1.650 + }
1.651 + CleanupStack::PopAndDestroy(2, &sn1);//sn2, sn1
1.652 + }
1.653 + }
1.654 + else
1.655 + {
1.656 + const CX509CertExtension* certExt = certificate.Extension(KSubjectKeyId);
1.657 + if (certExt)
1.658 + {
1.659 + CX509SubjectKeyIdExt* ext=CX509SubjectKeyIdExt::NewLC(certExt->Data());
1.660 + if (signerId.SubjectKeyIdentifier().Compare(ext->KeyId())==0)
1.661 + {
1.662 + endEntityPos = cert;
1.663 + endEntityEncoding.Set(certificate.Encoding());
1.664 + valid = ValidateSignatureL(aSignerInfo, certificate);
1.665 + }
1.666 + CleanupStack::PopAndDestroy(ext);
1.667 + }
1.668 + }
1.669 + }
1.670 + }
1.671 +
1.672 + // checks if end entity was found
1.673 + if(endEntityPos != -1)
1.674 + {
1.675 + // builds the cert chain encoding by putting the end entity first then all remaining
1.676 + // certs
1.677 + aCertChainEncoding = HBufC8::NewLC(endEncodingSize);
1.678 + TPtr8 encodingPtr(aCertChainEncoding->Des());
1.679 + encodingPtr.Copy(endEntityEncoding);
1.680 + for(cert = 0; cert < certCount; cert++)
1.681 + {
1.682 + const CX509Certificate& certificate = *aCertificates[cert];
1.683 +
1.684 + if(cert != endEntityPos)
1.685 + {
1.686 + encodingPtr.Append(certificate.Encoding());
1.687 + }
1.688 + }
1.689 + }
1.690 + else
1.691 + {
1.692 + User::Leave(KErrNotFound);
1.693 + }
1.694 +
1.695 + return valid;
1.696 + }
1.697 +
1.698 +
1.699 +EXPORT_C TBool CCmsSignedObject::ValidateSignerLC(const CCmsSignerInfo& aSignerInfo, HBufC8*& aCertChainEncoding, TBool aIsHash, const TDesC8& aContentDataOrHash)
1.700 + {
1.701 + if (aIsHash)
1.702 + {
1.703 + SetHash(aContentDataOrHash);
1.704 + }
1.705 + else
1.706 + {
1.707 + SetContentData(aContentDataOrHash);
1.708 + }
1.709 + return ValidateSignerLC(aSignerInfo, aCertChainEncoding);
1.710 + }
1.711 +
1.712 +EXPORT_C TBool CCmsSignedObject::ValidateSignerLC(const CCmsSignerInfo& aSignerInfo, const RPointerArray<CX509Certificate>& aCertificates, HBufC8*& aCertChainEncoding, TBool aIsHash, const TDesC8& aContentDataOrHash)
1.713 + {
1.714 + if (aIsHash)
1.715 + {
1.716 + SetHash(aContentDataOrHash);
1.717 + }
1.718 + else
1.719 + {
1.720 + SetContentData(aContentDataOrHash);
1.721 + }
1.722 + return ValidateSignerLC(aSignerInfo, aCertificates, aCertChainEncoding);
1.723 + }
1.724 +
1.725 +TBool CCmsSignedObject::ValidateSignatureL(const CCmsSignerInfo& aSignerInfo, const CX509Certificate& aEndEntityCert)
1.726 + {
1.727 + delete iSigningAlgorithm;
1.728 + iSigningAlgorithm = NULL;
1.729 + iSigningAlgorithm = CX509SigningAlgorithmIdentifier::NewL(aSignerInfo.SignatureAlgorithm(), aSignerInfo.DigestAlgorithm());
1.730 +
1.731 + delete iSignature;
1.732 + iSignature = NULL;
1.733 + iSignature = aSignerInfo.SignatureValue().AllocL();
1.734 +
1.735 + if (aSignerInfo.SignatureAlgorithm().Algorithm()==EDSA)
1.736 + {
1.737 + delete iParameters;
1.738 + iParameters = NULL;
1.739 + CDSAParameters* theDSAParams = iKeyFactory->DSAParametersL(aEndEntityCert.PublicKey().EncodedParams());
1.740 + CleanupStack::PushL(theDSAParams);
1.741 + CSigningKeyParameters* params = CSigningKeyParameters::NewLC();
1.742 + params->SetDSAParamsL(*theDSAParams);
1.743 + SetParametersL(*params);
1.744 + CleanupStack::PopAndDestroy(2, theDSAParams);
1.745 + }
1.746 +
1.747 + if (iContentInfo->IsContentDataPresent() || iContentData != KNullDesC8)
1.748 + {
1.749 + return VerifySignatureL(aEndEntityCert.PublicKey().KeyData());
1.750 + }
1.751 + else if (iHash!=KNullDesC8)
1.752 + {
1.753 + return VerifySignatureL(aEndEntityCert.PublicKey().KeyData(), iHash);
1.754 + }
1.755 + else
1.756 + {
1.757 + User::Leave(KErrArgument);
1.758 + return EFalse;
1.759 + }
1.760 +
1.761 + }
1.762 +
1.763 +void CCmsSignedObject::InitSignedObjectL(const TDesC8& aRawData)
1.764 + {
1.765 + // Populate CSignedObject data members
1.766 + iKeyFactory = new (ELeave) TX509KeyFactory;
1.767 + iEncoding = aRawData.AllocL();
1.768 +
1.769 + CSHA1* hash = CSHA1::NewL();
1.770 + CleanupStack::PushL(hash);
1.771 + iFingerprint = hash->Hash(Encoding()).AllocL();
1.772 + CleanupStack::PopAndDestroy(hash);
1.773 + }
1.774 +
1.775 +void CCmsSignedObject::DecodeSignedDataL(const TDesC8& aRawData)
1.776 + {
1.777 + CArrayPtr<TASN1DecGeneric>* signedData = PKCS7ASN1::DecodeSequenceLC(aRawData, KCmsMinSignedDataElements, KCmsMaxSignedDataElements);
1.778 + TInt totalItems = signedData->Count();
1.779 + TASN1DecInteger decInt;
1.780 +
1.781 + // decodes version
1.782 + iDataElements.At(EVersionNumber) = new(ELeave) TPtrC8(signedData->At(0)->GetContentDER());
1.783 + iVersion = decInt.DecodeDERShortL(*signedData->At(0));
1.784 + if (iVersion>4 || iVersion<0)
1.785 + {
1.786 + User::Leave(KErrArgument);
1.787 + }
1.788 + // decodes algorithms
1.789 + iDataElements.At(EDigestAlgorithms) = new(ELeave) TPtrC8(signedData->At(1)->GetContentDER());
1.790 + DecodeDigestAlgorithmsL(signedData->At(1)->Encoding());
1.791 + // decodes contentinfo
1.792 + iDataElements.At(EEncapsulatedContentInfo) = new(ELeave) TPtrC8(signedData->At(2)->GetContentDER());
1.793 + DecodeEncapsulatedContentInfoL(signedData->At(2)->Encoding());
1.794 +
1.795 + // Checks for optional fields
1.796 + TInt pos = 3; // Skip first non-optional fields
1.797 + do
1.798 + {
1.799 + const TASN1DecGeneric& currentItem = *signedData->At(pos);
1.800 + switch(currentItem.Tag())
1.801 + {
1.802 + case KSignedDataCertificates:
1.803 + {
1.804 + if (currentItem.Class()!=EContextSpecific)
1.805 + {
1.806 + User::Leave(KErrArgument);
1.807 + }
1.808 + iIsCertificateSetPresent=ETrue;
1.809 + iDataElements.At(ECertificates) = new(ELeave) TPtrC8(currentItem.GetContentDER());
1.810 + DecodeCertificatesL(currentItem.Encoding());
1.811 + break;
1.812 + }
1.813 + case KSignedDataRevocationLists:
1.814 + {
1.815 + if (currentItem.Class()!=EContextSpecific)
1.816 + {
1.817 + User::Leave(KErrArgument);
1.818 + }
1.819 + iIsCertificateRevocationListsPresent=ETrue;
1.820 + iDataElements.At(ERevocationLists) = new(ELeave) TPtrC8(currentItem.GetContentDER());
1.821 + DecodeRevocationListsL(currentItem.Encoding());
1.822 + break;
1.823 + }
1.824 + default:
1.825 + {
1.826 + //Optional field with wrong tag and class
1.827 + if (pos<totalItems-1)
1.828 + {
1.829 + User::Leave(KErrArgument);
1.830 + }
1.831 + // else Non-optional field
1.832 + }
1.833 + }
1.834 + pos++;
1.835 + }
1.836 + while(pos < totalItems);
1.837 +
1.838 + iDataElements.At(ESignedInfo) = new(ELeave) TPtrC8(signedData->At(totalItems-1)->GetContentDER());
1.839 + DecodeSignerInfoL(signedData->At(totalItems-1)->Encoding());
1.840 +
1.841 + CleanupStack::PopAndDestroy(signedData);
1.842 + }
1.843 +
1.844 +void CCmsSignedObject::DecodeDigestAlgorithmsL(const TDesC8& aRawData)
1.845 + {
1.846 + CmsUtils::DecodeDigestAlgorithmsL(iDigestAlgorithms, aRawData);
1.847 + }
1.848 +
1.849 +void CCmsSignedObject::DecodeCertificatesL(const TDesC8& aRawData)
1.850 + {
1.851 + CmsUtils::DecodeCertificatesL(iCertificates, aRawData);
1.852 + }
1.853 +
1.854 +void CCmsSignedObject::DecodeRevocationListsL(const TDesC8& /*aRawData*/)
1.855 + {
1.856 + }
1.857 +
1.858 +EXPORT_C const TPtrC8 CCmsSignedObject::SignedDataL() const
1.859 + {
1.860 + if (iContentInfo->IsContentDataPresent())
1.861 + {
1.862 + return iContentInfo->ContentData();
1.863 + }
1.864 + else
1.865 + {
1.866 + if (iContentData!=KNullDesC8)
1.867 + {
1.868 + return iContentData;
1.869 + }
1.870 + else
1.871 + {
1.872 + User::Leave(KErrArgument);
1.873 + }
1.874 + }
1.875 + return KNullDesC8();
1.876 + }
1.877 +
1.878 +EXPORT_C void CCmsSignedObject::InternalizeL(RReadStream& /*aStream*/)
1.879 + {
1.880 + User::Leave(KErrNotSupported);
1.881 + }
1.882 +
1.883 +EXPORT_C const TPtrC8* CCmsSignedObject::DataElementEncoding(const TUint aIndex) const
1.884 + {
1.885 + return iDataElements.At(aIndex);
1.886 + }
1.887 +
1.888 +void CCmsSignedObject::SetContentData(const TDesC8& aContentData)
1.889 + {
1.890 + iContentData.Set(aContentData);
1.891 + }
1.892 +
1.893 +void CCmsSignedObject::SetHash(const TDesC8& aHash)
1.894 + {
1.895 + iHash.Set(aHash);
1.896 + }
1.897 +
1.898 +
1.899 +
1.900 +