First public contribution.
2 * Copyright (c) 1998-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>
23 #include <keyidentifierutil.h>
26 //RSA signature result
27 EXPORT_C TBool CRSASignatureResult::operator== (const CRSASignatureResult& aResult) const
29 return ((*(iDigestAlgorithm) == *(aResult.iDigestAlgorithm)) &&
30 (*(iDigest)==*(aResult.iDigest)));
33 EXPORT_C CRSASignatureResult::~CRSASignatureResult()
35 delete iDigestAlgorithm;
40 EXPORT_C CValidityPeriod::CValidityPeriod(const CValidityPeriod& aValidityPeriod)
41 :iStart(aValidityPeriod.iStart), iFinish(aValidityPeriod.iFinish)
45 EXPORT_C CValidityPeriod::CValidityPeriod()
49 EXPORT_C TBool CValidityPeriod::Valid(const TTime& aTime) const
51 return ((iStart < aTime) && (iFinish > aTime));
54 EXPORT_C const TTime& CValidityPeriod::Start() const
59 EXPORT_C const TTime& CValidityPeriod::Finish() const
64 //******************************************************************************//
66 EXPORT_C CAlgorithmIdentifier* CAlgorithmIdentifier::NewL(const CAlgorithmIdentifier& aAlgorithmIdentifier)
68 CAlgorithmIdentifier* self = CAlgorithmIdentifier::NewLC(aAlgorithmIdentifier);
69 CleanupStack::Pop();//self
73 EXPORT_C CAlgorithmIdentifier* CAlgorithmIdentifier::NewLC(const CAlgorithmIdentifier& aAlgorithmIdentifier)
75 CAlgorithmIdentifier* self = new(ELeave) CAlgorithmIdentifier;
76 CleanupStack::PushL(self);
77 self->ConstructL(aAlgorithmIdentifier);
81 EXPORT_C CAlgorithmIdentifier* CAlgorithmIdentifier::NewL(TAlgorithmId& aAlgorithmId, const TDesC8& aEncodedParams)
83 CAlgorithmIdentifier* self = CAlgorithmIdentifier::NewLC(aAlgorithmId, aEncodedParams);
84 CleanupStack::Pop();//self
88 EXPORT_C CAlgorithmIdentifier* CAlgorithmIdentifier::NewLC(TAlgorithmId& aAlgorithmId, const TDesC8& aEncodedParams)
90 CAlgorithmIdentifier* self = new(ELeave) CAlgorithmIdentifier(aAlgorithmId);
91 CleanupStack::PushL(self);
92 self->ConstructL(aEncodedParams);
96 EXPORT_C CAlgorithmIdentifier::CAlgorithmIdentifier(TAlgorithmId& aAlgorithmId)
97 :iAlgorithmId(aAlgorithmId)
101 EXPORT_C CAlgorithmIdentifier::CAlgorithmIdentifier()
105 EXPORT_C void CAlgorithmIdentifier::ConstructL(const TDesC8& aEncodedParams)
107 iEncodedParams = aEncodedParams.AllocL();
111 EXPORT_C TBool CAlgorithmIdentifier::operator==(const CAlgorithmIdentifier& aAlgorithmIdentifier) const
113 return ((iAlgorithmId == aAlgorithmIdentifier.iAlgorithmId) &&
114 (*(iEncodedParams) == *(aAlgorithmIdentifier.iEncodedParams)));
117 EXPORT_C TAlgorithmId CAlgorithmIdentifier::Algorithm() const
122 EXPORT_C TPtrC8 CAlgorithmIdentifier::EncodedParams() const
124 return iEncodedParams->Des();
127 EXPORT_C CAlgorithmIdentifier::~CAlgorithmIdentifier()
129 delete iEncodedParams;
132 EXPORT_C void CAlgorithmIdentifier::ConstructL(const CAlgorithmIdentifier& aAlgorithmIdentifier)
134 iAlgorithmId = aAlgorithmIdentifier.iAlgorithmId;
135 iEncodedParams = aAlgorithmIdentifier.iEncodedParams->AllocL();
138 //***********************************************************************//
139 //signing algorithm id
140 EXPORT_C CSigningAlgorithmIdentifier* CSigningAlgorithmIdentifier::NewL(const CSigningAlgorithmIdentifier& aSigningAlgorithmIdentifier)
142 CSigningAlgorithmIdentifier* self = CSigningAlgorithmIdentifier::NewLC(aSigningAlgorithmIdentifier);
143 CleanupStack::Pop();//self
147 EXPORT_C CSigningAlgorithmIdentifier* CSigningAlgorithmIdentifier::NewLC(const CSigningAlgorithmIdentifier& aSigningAlgorithmIdentifier)
149 CSigningAlgorithmIdentifier* self = new(ELeave) CSigningAlgorithmIdentifier;
150 CleanupStack::PushL(self);
151 self->ConstructL(aSigningAlgorithmIdentifier);
155 EXPORT_C TBool CSigningAlgorithmIdentifier::operator == (const CSigningAlgorithmIdentifier& aSigningAlgorithmIdentifier) const
157 return ((*(iAsymmetricAlgorithm) == *(aSigningAlgorithmIdentifier.iAsymmetricAlgorithm)) &&
158 (*(iDigestAlgorithm) == *(aSigningAlgorithmIdentifier.iDigestAlgorithm)));
161 void CSigningAlgorithmIdentifier::ConstructL(const CSigningAlgorithmIdentifier& aAlgorithmIdentifier)
163 iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(*(aAlgorithmIdentifier.iAsymmetricAlgorithm));
164 iDigestAlgorithm = CAlgorithmIdentifier::NewL(*(aAlgorithmIdentifier.iDigestAlgorithm));
167 EXPORT_C const CAlgorithmIdentifier& CSigningAlgorithmIdentifier::AsymmetricAlgorithm() const
169 return *iAsymmetricAlgorithm;
172 EXPORT_C const CAlgorithmIdentifier& CSigningAlgorithmIdentifier::DigestAlgorithm() const
174 return *iDigestAlgorithm;
177 EXPORT_C CSigningAlgorithmIdentifier::~CSigningAlgorithmIdentifier()
179 delete iAsymmetricAlgorithm;
180 delete iDigestAlgorithm;
183 //************************************************************************//
184 //subject public key info
185 EXPORT_C CSubjectPublicKeyInfo* CSubjectPublicKeyInfo::NewL(const CSubjectPublicKeyInfo& aSubjectPublicKeyInfo)
187 CSubjectPublicKeyInfo* self = CSubjectPublicKeyInfo::NewLC(aSubjectPublicKeyInfo);
188 CleanupStack::Pop();//self
192 EXPORT_C CSubjectPublicKeyInfo* CSubjectPublicKeyInfo::NewLC(const CSubjectPublicKeyInfo& aSubjectPublicKeyInfo)
194 CSubjectPublicKeyInfo* self = new(ELeave) CSubjectPublicKeyInfo;
195 CleanupStack::PushL(self);
196 self->ConstructL(aSubjectPublicKeyInfo);
200 EXPORT_C TAlgorithmId CSubjectPublicKeyInfo::AlgorithmId() const
202 return iAlgId->Algorithm();
205 EXPORT_C const TPtrC8 CSubjectPublicKeyInfo::EncodedParams() const
207 return iAlgId->EncodedParams();
210 EXPORT_C const TPtrC8 CSubjectPublicKeyInfo::KeyData() const
212 return iEncodedKeyData->Des();
215 EXPORT_C CSubjectPublicKeyInfo::~CSubjectPublicKeyInfo()
218 delete iEncodedKeyData;
221 EXPORT_C void CSubjectPublicKeyInfo::ConstructL(const CSubjectPublicKeyInfo& aSubjectPublicKeyInfo)
223 iAlgId = CAlgorithmIdentifier::NewL(*(aSubjectPublicKeyInfo.iAlgId));
224 iEncodedKeyData = aSubjectPublicKeyInfo.iEncodedKeyData->AllocL();
227 //******************************************************************//
228 //signed object parameters
232 EXPORT_C CSigningKeyParameters* CSigningKeyParameters::NewL()
234 CSigningKeyParameters* self = new(ELeave) CSigningKeyParameters;
238 EXPORT_C CSigningKeyParameters* CSigningKeyParameters::NewLC()
240 CSigningKeyParameters* self = CSigningKeyParameters::NewL();
241 CleanupStack::PushL(self);
246 EXPORT_C CSigningKeyParameters* CSigningKeyParameters::NewL(const CSigningKeyParameters& aParameters)
248 CSigningKeyParameters* self = CSigningKeyParameters::NewLC(aParameters);
253 EXPORT_C CSigningKeyParameters* CSigningKeyParameters::NewLC(const CSigningKeyParameters& aParameters)
255 CSigningKeyParameters* self = new(ELeave) CSigningKeyParameters;
256 CleanupStack::PushL(self);
257 self->ConstructL(aParameters);
261 void CSigningKeyParameters::ConstructL(const CSigningKeyParameters& aParameters)
263 SetDSAParamsL(*(aParameters.iDSAParams));
267 EXPORT_C CSigningKeyParameters::~CSigningKeyParameters()
272 EXPORT_C void CSigningKeyParameters::SetDSAParamsL(const CDSAParameters& aParams)
275 iDSAParams = NULL; // In case the next fails
277 // Copy the TIntegers
278 RInteger p = RInteger::NewL(aParams.P());
279 CleanupStack::PushL(p);
281 RInteger q = RInteger::NewL(aParams.Q());
282 CleanupStack::PushL(q);
284 RInteger g = RInteger::NewL(aParams.G());
285 CleanupStack::PushL(g);
287 iDSAParams = CDSAParameters::NewL(p, q, g);
288 CleanupStack::Pop(3, &p);
291 const CDSAParameters* CSigningKeyParameters::DSAParams() const
296 CSigningKeyParameters::CSigningKeyParameters()
300 //******************************************************************//
302 EXPORT_C TBool CSignedObject::VerifySignatureL(const TDesC8& aEncodedKey) const
304 const CAlgorithmIdentifier& algId = iSigningAlgorithm->AsymmetricAlgorithm();
305 const CAlgorithmIdentifier& digestId = iSigningAlgorithm->DigestAlgorithm();
307 TBool verifyResult = EFalse;
308 if (algId.Algorithm() == EDSA)
310 if (digestId.Algorithm() != ESHA1)
312 User::Leave(KErrArgument);
315 CSHA1* sha1 = CSHA1::NewL();
316 CleanupStack::PushL(sha1);
317 TPtrC8 signedData = SignedDataL();
318 TPtrC8 hash = sha1->Final(signedData);
319 verifyResult=VerifySignatureL(aEncodedKey, hash);
320 CleanupStack::PopAndDestroy(sha1);//hash
324 TRAPD(result, verifyResult = VerifyRSASignatureL(aEncodedKey));
325 if (result==KErrNoMemory) // Leave if OOM, anything else is a verify
326 User::Leave(result); // error => verifyResult = EFalse
333 EXPORT_C TBool CSignedObject::VerifySignatureL(const TDesC8& aEncodedKey, const TDesC8& aHash) const
335 const CAlgorithmIdentifier& algId = iSigningAlgorithm->AsymmetricAlgorithm();
336 const CAlgorithmIdentifier& digestId = iSigningAlgorithm->DigestAlgorithm();
338 TBool verifyResult = EFalse;
339 if (algId.Algorithm() == EDSA)
341 if (digestId.Algorithm() != ESHA1)
343 User::Leave(KErrArgument);
346 CDSAPublicKey* key = NULL;
347 if (algId.EncodedParams().Length() != 0)
349 key = iKeyFactory->DSAPublicKeyL(algId.EncodedParams(), aEncodedKey);
353 if (iParameters != NULL)
355 const CDSAParameters* params = iParameters->DSAParams();
358 User::Leave(KErrArgument);//no params
362 key = iKeyFactory->DSAPublicKeyL(*params, aEncodedKey);
368 User::Leave(KErrArgument);
370 CleanupStack::PushL(key);
371 CDSAVerifier* verifier = CDSAVerifier::NewLC(*key);
372 CDSASignature* sig = iKeyFactory->DSASignatureL(Signature());
373 CleanupStack::PushL(sig);
374 verifyResult = verifier->VerifyL(aHash, *sig);
375 CleanupStack::PopAndDestroy(3);// key, verifier, sig
379 TRAPD(result, verifyResult = VerifyRSASignatureL(aEncodedKey, aHash));
380 if (result==KErrNoMemory) // Leave if OOM, anything else is a verify
381 User::Leave(result); // error => verifyResult = EFalse
388 TBool CSignedObject::VerifyRSASignatureL(const TDesC8& aEncodedKey, const TDesC8& aHash) const
391 const CAlgorithmIdentifier& algId = iSigningAlgorithm->AsymmetricAlgorithm();
392 const CAlgorithmIdentifier& digestId = iSigningAlgorithm->DigestAlgorithm();
393 if (algId.Algorithm() != ERSA)
395 User::Leave(KErrArgument);
399 CRSAPublicKey* key = iKeyFactory->RSAPublicKeyL(aEncodedKey);
400 CleanupStack::PushL(key);
402 CRSAPKCS1v15Verifier* verifier = CRSAPKCS1v15Verifier::NewLC(*key);
404 RInteger sig = RInteger::NewL(Signature());
405 CleanupStack::PushL(sig);
406 CRSASignature* theSignature = CRSASignature::NewL(sig);
407 CleanupStack::Pop(&sig);
408 CleanupStack::PushL(theSignature);
410 HBufC8* publicDecryptOutput = verifier->InverseSignLC(*theSignature);
414 CRSASignatureResult* decoder = iKeyFactory->RSASignatureResultL(digestId, hash);
415 CleanupStack::PushL(decoder);
417 TPtr8 outputPtr(publicDecryptOutput->Des());
418 TBool verified = decoder->VerifyL(outputPtr);
419 CleanupStack::PopAndDestroy(5, key); // decoder, publicDecryptOutput, theSignature
425 // x509 signature comprises of an AlgID and the signed data itself, so a simple
426 // verify is not possible (the data returned from public decrypt will not match
427 // the original data signed because of the extra algID appendage).
429 TBool CSignedObject::VerifyRSASignatureL(const TDesC8& aEncodedKey) const
432 const CAlgorithmIdentifier& algId = iSigningAlgorithm->AsymmetricAlgorithm();
433 const CAlgorithmIdentifier& digestId = iSigningAlgorithm->DigestAlgorithm();
434 if (algId.Algorithm() != ERSA)
436 User::Leave(KErrArgument);
438 CMessageDigest* digest = NULL;
439 switch(digestId.Algorithm())
443 digest = CMD2::NewL();
448 digest = CMD5::NewL();
453 digest = CSHA1::NewL();
458 digest = CSHA2::NewL(E224Bit);
463 digest = CSHA2::NewL(E256Bit);
468 digest = CSHA2::NewL(E384Bit);
473 digest = CSHA2::NewL(E512Bit);
478 User::Leave(KErrArgument);
482 CleanupStack::PushL(digest);
483 TPtrC8 hash = digest->Final(SignedDataL());
484 TBool verifyResult=VerifyRSASignatureL(aEncodedKey, hash);
485 CleanupStack::PopAndDestroy(digest);
490 EXPORT_C void CSignedObject::SetParametersL(const CSigningKeyParameters& aParameters)
493 iParameters = NULL; // In case next fails
494 iParameters = CSigningKeyParameters::NewL(aParameters);
497 EXPORT_C const TPtrC8 CSignedObject::Signature() const
499 return iSignature->Des();
502 EXPORT_C const TPtrC8 CSignedObject::Encoding() const
504 return iEncoding->Des();
507 EXPORT_C const CSigningAlgorithmIdentifier& CSignedObject::SigningAlgorithm() const
509 return *iSigningAlgorithm;
512 EXPORT_C const TPtrC8 CSignedObject::Fingerprint() const
514 return iFingerprint->Des();
517 EXPORT_C CSignedObject::~CSignedObject()
524 delete iSigningAlgorithm;
527 EXPORT_C void CSignedObject::ExternalizeL(RWriteStream& aStream) const
529 aStream.WriteInt32L(iEncoding->Length());
530 aStream.WriteL(*iEncoding);
534 //****************************************************************************************//
536 EXPORT_C CCertificate::~CCertificate()
538 delete iSerialNumber;
539 delete iValidityPeriod;
540 delete iSubjectPublicKeyInfo;
543 EXPORT_C const TPtrC8 CCertificate::SerialNumber() const
545 return iSerialNumber->Des();
548 EXPORT_C const CValidityPeriod& CCertificate::ValidityPeriod() const
550 return *iValidityPeriod;
553 EXPORT_C const CSubjectPublicKeyInfo& CCertificate::PublicKey() const
555 return *iSubjectPublicKeyInfo;
558 EXPORT_C TKeyIdentifier CCertificate::KeyIdentifierL() const
560 if (iSubjectPublicKeyInfo->AlgorithmId() != ERSA)
562 User::Leave(KErrNotSupported);
565 CRSAPublicKey* rsaKey = iKeyFactory->RSAPublicKeyL(iSubjectPublicKeyInfo->KeyData());
566 CleanupStack::PushL(rsaKey);
567 TKeyIdentifier retVal;
568 KeyIdentifierUtil::RSAKeyIdentifierL(*rsaKey, retVal);
569 CleanupStack::PopAndDestroy(rsaKey);