First public contribution.
2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
20 #include <asymmetric.h>
24 #include <pkcs7excert.h>
26 #include "pkcs7asn1.h"
29 TInt CmsUtils::DecodeContentTypeL(const TASN1DecGeneric* aASN1DecGeneric)
32 if(aASN1DecGeneric->Tag()==EASN1ObjectIdentifier || aASN1DecGeneric->Class() == EUniversal)
34 TASN1DecObjectIdentifier oidDec;
35 HBufC* oidVal = oidDec.DecodeDERL(*aASN1DecGeneric);
36 CleanupStack::PushL(oidVal);
38 // Checks if it is data OID.
39 if(*oidVal == KCmsDataOID)
41 // The Content Type is indicated by an Integer.
42 // Here if Content Type is equal to Data then,it is represented by 1
43 type = EContentTypeData;
45 else if(*oidVal == KCmsSignedDataOID)
47 // The Content Type is indicated by an Integer.
48 // Here if Content Type is equal to SignedData then,it is represented by 2
49 type = EContentTypeSignedData;
51 else if(*oidVal == KCmsEnvelopedDataOID)
53 // The Content Type is indicated by an Integer.
54 // Here if Content Type is equal to EnvelopedData then,it is represented by 3.
55 type = EContentTypeEnvelopedData;
57 else if(*oidVal == KCmsDigestedDataOID)
59 // The Content Type is indicated by an Integer.
60 // Here if Content Type is equal to DigestedData then,it is represented by 5.
61 type = EContentTypeDigestedData;
63 else if(*oidVal == KCmsEncryptedDataOID)
65 // The Content Type is indicated by an Integer.
66 // Here if Content Type is equal to EncryptedData then,it is represented by 6
67 type = EContentTypeEncryptedData;
69 else if(*oidVal == KCmsAuthenticatedDataOID)
71 // The Content Type is indicated by an Integer.
72 // Here if Content Type is equal to EncryptedData then,it is represented by 7
73 type = EContentTypeAuthenticatedData;
78 User::Leave(KErrArgument);
80 CleanupStack::PopAndDestroy(oidVal);
84 User::Leave(KErrArgument);
89 CASN1EncObjectIdentifier* CmsUtils::EncodeContentTypeLC(TInt aContentType)
94 case EContentTypeData:
95 oidBuf.Set(KCmsDataOID());
98 case EContentTypeSignedData:
99 oidBuf.Set(KCmsSignedDataOID());
102 case EContentTypeEnvelopedData:
103 oidBuf.Set(KCmsEnvelopedDataOID());
106 case EContentTypeDigestedData:
107 oidBuf.Set(KCmsDigestedDataOID());
110 case EContentTypeEncryptedData:
111 oidBuf.Set(KCmsEncryptedDataOID());
115 User::Leave(KErrArgument);
118 CASN1EncObjectIdentifier* oid=CASN1EncObjectIdentifier::NewLC(oidBuf);
122 void CmsUtils::AddCertificateL(RPointerArray<CCmsCertificateChoice>& aCertList, const TDesC8& aCert, CCmsCertificateChoice::TCertificateType aType)
125 TInt count=aCertList.Count();
126 for (TInt i=0;i<count;i++)
128 if (aCertList[i]->CertificateType()==CCmsCertificateChoice::ECertificateAttribute
129 && aCert.Compare(*aCertList[i]->AttributeCertificate())==0)
138 CCmsCertificateChoice* cert=CCmsCertificateChoice::NewL(aType, aCert);
139 CleanupStack::PushL(cert);
140 aCertList.AppendL(cert);
141 CleanupStack::Pop(cert);
145 void CmsUtils::AddCertificateL(RPointerArray<CCmsCertificateChoice>& aCertList, const CX509Certificate& aCert)
149 TInt count=aCertList.Count();
150 for (TInt i=0;i<count;i++)
152 if (aCertList[i]->CertificateType()==CCmsCertificateChoice::ECertificateX509
153 && aCert.IsEqualL(aCertList[i]->Certificate()))
162 CCmsCertificateChoice* cert=CCmsCertificateChoice::NewL(aCert);
163 CleanupStack::PushL(cert);
164 aCertList.AppendL(cert);
165 CleanupStack::Pop(cert);
170 void CmsUtils::AddAlgorithmIdentifierL(RPointerArray<CX509AlgorithmIdentifier>& aAlgorithmIdList, TAlgorithmId aDigestAlgorithm)
173 TInt count=aAlgorithmIdList.Count();
174 for (TInt i=0;i<count;i++)
176 if (aAlgorithmIdList[i]->Algorithm()==aDigestAlgorithm)
184 CX509AlgorithmIdentifier* digAlg=CX509AlgorithmIdentifier::NewLC(aDigestAlgorithm, KNullDesC8());
185 aAlgorithmIdList.AppendL(digAlg);
186 CleanupStack::Pop(digAlg);
190 void CmsUtils::DecodeDigestAlgorithmsL(RPointerArray<CX509AlgorithmIdentifier>& aDigestAlgorithms, const TDesC8& aRawData)
192 CArrayPtr<TASN1DecGeneric>* algsData = PKCS7ASN1::DecodeSequenceLC(aRawData);
193 TInt count = algsData->Count();
194 CX509AlgorithmIdentifier* alIdent;
196 for(TInt item = 0; item < count; item++)
198 alIdent = CX509AlgorithmIdentifier::NewLC(algsData->At(item)->Encoding());
199 aDigestAlgorithms.AppendL(alIdent);
200 CleanupStack::Pop(alIdent);
202 CleanupStack::PopAndDestroy(algsData);
205 void CmsUtils::DecodeCertificatesL(RPointerArray<CCmsCertificateChoice>& aCertificates, const TDesC8& aRawData)
207 TASN1DecGeneric decGen(aRawData);
209 TASN1DecSequence decSeq;
210 // have to do manual decoding of sequence because field is optional
211 CArrayPtr<TASN1DecGeneric>* items = NULL;
212 items = decSeq.DecodeDERLC(decGen);
213 TInt count = items->Count();
215 CCmsCertificateChoice* certificate;
217 for(TInt item = 0; item < count; item++)
219 certificate = CCmsCertificateChoice::NewL(items->At(item)->Encoding());
220 CleanupStack::PushL(certificate);
221 aCertificates.AppendL(certificate);
222 CleanupStack::Pop(certificate);
225 CleanupStack::PopAndDestroy(items);
228 CASN1EncBase* CmsUtils::EncodeCertificatesLC(const RPointerArray<CCmsCertificateChoice>& aCertificates)
230 CASN1EncSet* certSet(NULL);
231 TInt count=aCertificates.Count();
234 certSet = CASN1EncSet::NewLC();
235 for (TInt i=0;i<count;i++)
237 CASN1EncEncoding* cert=aCertificates[i]->EncodeASN1DERLC();
238 certSet->AddAndPopChildL(cert);
246 CASN1EncBase* CmsUtils::EncodeDigestAlgorithmsLC(const RPointerArray<CX509AlgorithmIdentifier>& aDigestAlgorithms)
248 CASN1EncSet* algorithmSet = CASN1EncSet::NewLC();
249 TInt count=aDigestAlgorithms.Count();
251 for (TInt i=0;i<count;i++)
253 CASN1EncSequence* tmp=aDigestAlgorithms[i]->EncodeASN1DERLC();
254 algorithmSet->AddAndPopChildL(tmp);
260 void CmsUtils::DecodeOctetStringL(const TDesC8& aRawData, HBufC8*& aBuf)
262 TASN1DecGeneric decGen(aRawData);
265 if(decGen.Tag()==EASN1OctetString && decGen.Class()==EUniversal)
267 TASN1DecOctetString decOct;
268 aBuf = decOct.DecodeDERL(decGen);
272 User::Leave(KErrArgument);
277 CMessageDigest* CmsUtils::CreateHashLC(TAlgorithmId aAlgorithm)
279 CMessageDigest* hash(NULL);
295 User::Leave(KErrNotSupported);
297 CleanupStack::PushL(hash);
302 HBufC8* CmsUtils::CreateSignatureL(const TDesC8& aDataToBeSigned, TBool aIsHash, TAlgorithmId aAlgorithm, const CDSAPrivateKey& aKey)
304 HBufC8* signature(NULL);
310 CMessageDigest* hash=CreateHashLC(aAlgorithm);
311 hashValue.Set(hash->Hash(aDataToBeSigned));
312 signature=CreateSignatureL(hashValue, aKey);
313 CleanupStack::PopAndDestroy(); // hash
317 signature=CreateSignatureL(aDataToBeSigned, aKey);
323 HBufC8* CmsUtils::CreateSignatureL(const TDesC8& aDataToBeSigned, TBool aIsHash, TAlgorithmId aAlgorithm, const CRSAPrivateKey& aKey)
325 HBufC8* signature(NULL);
330 CMessageDigest* hash=CreateHashLC(aAlgorithm);
331 hashValue.Set(hash->Hash(aDataToBeSigned));
335 hashValue.Set(aDataToBeSigned);
338 //Build the digestInfo Sequence
339 CASN1EncSequence* digestInfoSeq = CASN1EncSequence::NewLC();
341 //Encode the Algorithm
342 CX509AlgorithmIdentifier* digAlg=CX509AlgorithmIdentifier::NewLC(aAlgorithm, KNullDesC8());
343 CASN1EncSequence* sigAlg=digAlg->EncodeASN1DERLC();
344 digestInfoSeq->AddAndPopChildL(sigAlg);
345 CleanupStack::PopAndDestroy(digAlg);
347 //Encode the digest itself
348 CASN1EncOctetString* sigEnc=CASN1EncOctetString::NewLC(hashValue);
349 digestInfoSeq->AddAndPopChildL(sigEnc);
352 HBufC8* digestInfo=CreateDEREncodingLC(*digestInfoSeq);
353 signature=CreateSignatureL(digestInfo->Des(), aKey);
355 CleanupStack::PopAndDestroy(2, digestInfoSeq); //digestInfo, digestInfoSeq
358 CleanupStack::PopAndDestroy(); // hash
363 HBufC8* CmsUtils::CreateSignatureL(const TDesC8& aHash, const CDSAPrivateKey& aKey)
365 //Create Signer and sign the hash
366 CDSASigner* signer=CDSASigner::NewLC(aKey);
367 const CDSASignature* sig=signer->SignL(aHash);
368 CDSASignature* signonc=const_cast<CDSASignature*>(sig);
370 CleanupStack::PushL(signonc);
373 CASN1EncSequence* sigSeq = CASN1EncSequence::NewLC();
374 CASN1EncBigInt* r = CASN1EncBigInt::NewLC(static_cast<const RInteger&>(sig->R()));
375 sigSeq->AddAndPopChildL(r);
376 CASN1EncBigInt* s = CASN1EncBigInt::NewLC(static_cast<const RInteger&>(sig->S()));
377 sigSeq->AddAndPopChildL(s);
380 TUint len=sigSeq->LengthDER();
381 HBufC8* buf=HBufC8::NewMaxLC(len);
382 TPtr8 des=buf->Des();
384 sigSeq->WriteDERL(des, pos);
387 CleanupStack::Pop(buf); //buf
388 CleanupStack::PopAndDestroy(3, signer); //sigSeq, signonc, signer
392 HBufC8* CmsUtils::CreateSignatureL(const TDesC8& aHash, const CRSAPrivateKey& aKey)
394 //Create Signer and sign the hash
395 CRSAPKCS1v15Signer* signer=CRSAPKCS1v15Signer::NewLC(aKey);
396 const CRSASignature* sig=signer->SignL(aHash);
397 CRSASignature* signonc=const_cast<CRSASignature*>(sig);
399 CleanupStack::PushL(signonc);
401 HBufC8* sigData = sig->S().BufferWithNoTruncationLC();
404 CleanupStack::Pop(sigData);
405 CleanupStack::PopAndDestroy(2, signer);//signonc signer
409 HBufC8* CmsUtils::CreateDEREncodingLC(const CASN1EncBase& aEncoding)
411 TUint len = aEncoding.LengthDER();
412 HBufC8* buf = HBufC8::NewMaxLC(len);
414 TPtr8 bufptr(buf->Des());
415 aEncoding.WriteDERL(bufptr, pos);