First public contribution.
2 * Copyright (c) 1997-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.
15 * -- FingerPrint Note:
16 * Developers have to be aware that if they are going to change the fingerprint for this certificate
17 * for a different hash, then there are other places that need to reflect this change
19 * void CWTLSCertificate::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
20 * EXPORT_C void CWTLSCertificate::InternalizeL(RReadStream& aStream)
21 * Also change the CX509Certificate and search for other occurences of the current
32 enum TEncAlgorithmType
37 enum TEncSigAlgorithmType
39 EEncRSAwithSHA1 = 0x02
42 const TInt KMinAlgIdLength = 2;
43 const TInt KMinExpLengthBytes = 1;
44 const TInt KMaxExpLengthBytes = 65535;
45 const TInt KMinModLengthBytes = 1;
46 const TInt KMaxModLengthBytes = 65535;
48 //WTLS RSA signature result
49 EXPORT_C CWTLSRSASignatureResult* CWTLSRSASignatureResult::NewL(const CAlgorithmIdentifier& aDigestAlgorithm, const TDesC8& aDigest)
51 CWTLSRSASignatureResult* self = CWTLSRSASignatureResult::NewLC(aDigestAlgorithm, aDigest);
56 EXPORT_C CWTLSRSASignatureResult* CWTLSRSASignatureResult::NewLC(const CAlgorithmIdentifier& aDigestAlgorithm, const TDesC8& aDigest)
58 CWTLSRSASignatureResult* self = new(ELeave) CWTLSRSASignatureResult;
59 CleanupStack::PushL(self);
60 self->ConstructL(aDigestAlgorithm, aDigest);
64 EXPORT_C TBool CWTLSRSASignatureResult::VerifyL(const TDesC8& aResult)
66 return aResult == *iDigest;
69 void CWTLSRSASignatureResult::ConstructL(const CAlgorithmIdentifier& aDigestAlgorithm, const TDesC8& aDigest)
71 iDigestAlgorithm = CAlgorithmIdentifier::NewL(aDigestAlgorithm);
72 iDigest = aDigest.AllocL();
76 CRSAPublicKey* TWTLSKeyFactory::RSAPublicKeyL(const TDesC8& aEncoding) const
78 return CWTLSRSAPublicKey::NewL(aEncoding);
81 CRSASignatureResult* TWTLSKeyFactory::RSASignatureResultL(const CAlgorithmIdentifier& aDigestAlgorithm, TDesC8& aDigest) const
83 return CWTLSRSASignatureResult::NewL(aDigestAlgorithm, aDigest);
86 CDSAPublicKey* TWTLSKeyFactory::DSAPublicKeyL(const CDSAParameters& /*aParams*/, const TDesC8& /*aEncoding*/) const
88 User::Leave(KErrNotSupported);
92 CDSAPublicKey* TWTLSKeyFactory::DSAPublicKeyL(const TDesC8& /*aParams*/, const TDesC8& /*aEncoding*/) const
94 User::Leave(KErrNotSupported);
98 CDSASignature* TWTLSKeyFactory::DSASignatureL(const TDesC8& /*aEncoding*/) const
100 User::Leave(KErrNotSupported);
105 CDSAParameters* TWTLSKeyFactory::DSAParametersL(const TDesC8& /*aParamsEncoding*/) const
107 User::Leave(KErrNotSupported);
112 EXPORT_C CWTLSValidityPeriod* CWTLSValidityPeriod::NewL(const TDesC8& aBinaryData)
115 return CWTLSValidityPeriod::NewL(aBinaryData, pos);
118 EXPORT_C CWTLSValidityPeriod* CWTLSValidityPeriod::NewLC(const TDesC8& aBinaryData)
121 return CWTLSValidityPeriod::NewLC(aBinaryData, pos);
124 EXPORT_C CWTLSValidityPeriod* CWTLSValidityPeriod::NewL(const TDesC8& aBinaryData, TInt& aPos)
126 CWTLSValidityPeriod* self = CWTLSValidityPeriod::NewLC(aBinaryData, aPos);
131 EXPORT_C CWTLSValidityPeriod* CWTLSValidityPeriod::NewLC(const TDesC8& aBinaryData, TInt& aPos)
133 CWTLSValidityPeriod* self = new(ELeave) CWTLSValidityPeriod;
134 CleanupStack::PushL(self);
135 self->ConstructL(aBinaryData, aPos);
139 CWTLSValidityPeriod::CWTLSValidityPeriod()
143 void CWTLSValidityPeriod::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
145 TWTLSDecTime timeDec;
146 iStart = timeDec.DecodeL(aBinaryData, aPos);
147 iFinish = timeDec.DecodeL(aBinaryData, aPos);
151 EXPORT_C CWTLSAlgorithmIdentifier* CWTLSAlgorithmIdentifier::NewL(const TDesC8& aBinaryData)
154 return CWTLSAlgorithmIdentifier::NewL(aBinaryData, pos);
157 EXPORT_C CWTLSAlgorithmIdentifier* CWTLSAlgorithmIdentifier::NewLC(const TDesC8& aBinaryData)
160 return CWTLSAlgorithmIdentifier::NewLC(aBinaryData, pos);
163 EXPORT_C CWTLSAlgorithmIdentifier* CWTLSAlgorithmIdentifier::NewL(const TDesC8& aBinaryData, TInt& aPos)
165 CWTLSAlgorithmIdentifier* self = CWTLSAlgorithmIdentifier::NewLC(aBinaryData, aPos);
170 EXPORT_C CWTLSAlgorithmIdentifier* CWTLSAlgorithmIdentifier::NewLC(const TDesC8& aBinaryData, TInt& aPos)
172 CWTLSAlgorithmIdentifier* self = new(ELeave) CWTLSAlgorithmIdentifier;
173 CleanupStack::PushL(self);
174 self->ConstructL(aBinaryData, aPos);
178 CWTLSAlgorithmIdentifier::CWTLSAlgorithmIdentifier()
182 void CWTLSAlgorithmIdentifier::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
184 if ((aBinaryData.Length() - aPos) < KMinAlgIdLength)
186 User::Leave(KErrArgument);
188 switch (aBinaryData[aPos])
194 if (aBinaryData[aPos] != 0)
196 User::Leave(KErrArgument);
199 iEncodedParams = HBufC8::NewL(1);
200 *iEncodedParams = KNullDesC8;
204 //we only support RSA just now...
206 User::Leave(KErrNotSupported);
211 //signing algorithm id
212 EXPORT_C CWTLSSigningAlgorithmIdentifier* CWTLSSigningAlgorithmIdentifier::NewL(const TDesC8& aBinaryData)
215 return CWTLSSigningAlgorithmIdentifier::NewL(aBinaryData, pos);
218 EXPORT_C CWTLSSigningAlgorithmIdentifier* CWTLSSigningAlgorithmIdentifier::NewLC(const TDesC8& aBinaryData)
221 return CWTLSSigningAlgorithmIdentifier::NewLC(aBinaryData, pos);
224 EXPORT_C CWTLSSigningAlgorithmIdentifier* CWTLSSigningAlgorithmIdentifier::NewL(const TDesC8& aBinaryData, TInt& aPos)
226 CWTLSSigningAlgorithmIdentifier* self = CWTLSSigningAlgorithmIdentifier::NewLC(aBinaryData, aPos);
231 EXPORT_C CWTLSSigningAlgorithmIdentifier* CWTLSSigningAlgorithmIdentifier::NewLC(const TDesC8& aBinaryData, TInt& aPos)
233 CWTLSSigningAlgorithmIdentifier* self = new(ELeave) CWTLSSigningAlgorithmIdentifier;
234 CleanupStack::PushL(self);
235 self->ConstructL(aBinaryData, aPos);
239 CWTLSSigningAlgorithmIdentifier::CWTLSSigningAlgorithmIdentifier()
243 void CWTLSSigningAlgorithmIdentifier::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
245 if ((aBinaryData.Length() - aPos) < 1)
247 User::Leave(KErrArgument);
249 switch (aBinaryData[aPos])
251 case EEncRSAwithSHA1:
253 TAlgorithmId asym = ERSA;
254 TAlgorithmId dig = ESHA1;
255 iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(asym, KNullDesC8);
256 iDigestAlgorithm = CAlgorithmIdentifier::NewL(dig, KNullDesC8);
261 //we only support RSA-SHA1 just now...
263 User::Leave(KErrNotSupported);
268 //wtls subject public key info
269 EXPORT_C CWTLSSubjectPublicKeyInfo* CWTLSSubjectPublicKeyInfo::NewL(const TDesC8& aBinaryData)
272 return CWTLSSubjectPublicKeyInfo::NewL(aBinaryData, pos);
275 EXPORT_C CWTLSSubjectPublicKeyInfo* CWTLSSubjectPublicKeyInfo::NewLC(const TDesC8& aBinaryData)
278 return CWTLSSubjectPublicKeyInfo::NewLC(aBinaryData, pos);
281 EXPORT_C CWTLSSubjectPublicKeyInfo* CWTLSSubjectPublicKeyInfo::NewL(const TDesC8& aBinaryData, TInt& aPos)
283 CWTLSSubjectPublicKeyInfo* self = CWTLSSubjectPublicKeyInfo::NewLC(aBinaryData, aPos);
288 EXPORT_C CWTLSSubjectPublicKeyInfo* CWTLSSubjectPublicKeyInfo::NewLC(const TDesC8& aBinaryData, TInt& aPos)
290 CWTLSSubjectPublicKeyInfo* self = new(ELeave) CWTLSSubjectPublicKeyInfo;
291 CleanupStack::PushL(self);
292 self->ConstructL(aBinaryData, aPos);
296 CWTLSSubjectPublicKeyInfo::CWTLSSubjectPublicKeyInfo()
300 void CWTLSSubjectPublicKeyInfo::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
302 iAlgId = CWTLSAlgorithmIdentifier::NewL(aBinaryData, aPos);
303 if (iAlgId->Algorithm() != ERSA)
305 User::Leave(KErrNotSupported);
307 TInt totalLength = aBinaryData.Length();
310 const TPtrC8 expEnc = aBinaryData.Right(totalLength - aPos);
311 TWTLSDecVector exp(expEnc, KMinExpLengthBytes, KMaxExpLengthBytes);
314 aPos += exp.EncodingLength();
316 const TPtrC8 modEnc = aBinaryData.Right(totalLength - aPos);
317 TWTLSDecVector mod(modEnc, KMinModLengthBytes, KMaxModLengthBytes);
320 aPos+= mod.EncodingLength();
321 iEncodedKeyData = (aBinaryData.Mid(tempPos, aPos - tempPos)).AllocL();
325 EXPORT_C CWTLSCertificate* CWTLSCertificate::NewL(const TDesC8& aBinaryData)
328 return CWTLSCertificate::NewL(aBinaryData, pos);
331 EXPORT_C CWTLSCertificate* CWTLSCertificate::NewLC(const TDesC8& aBinaryData)
334 return CWTLSCertificate::NewLC(aBinaryData, pos);
337 EXPORT_C CWTLSCertificate* CWTLSCertificate::NewL(const TDesC8& aBinaryData, TInt& aPos)
339 CWTLSCertificate* self = CWTLSCertificate::NewLC(aBinaryData, aPos);
344 EXPORT_C CWTLSCertificate* CWTLSCertificate::NewLC(const TDesC8& aBinaryData, TInt& aPos)
346 CWTLSCertificate* self = new(ELeave) CWTLSCertificate;
347 CleanupStack::PushL(self);
348 self->ConstructL(aBinaryData, aPos);
352 EXPORT_C CWTLSCertificate* CWTLSCertificate::NewL(RReadStream& aStream)
354 CWTLSCertificate* self = CWTLSCertificate::NewLC(aStream);
355 CleanupStack::Pop();//self
359 EXPORT_C CWTLSCertificate* CWTLSCertificate::NewLC(RReadStream& aStream)
361 CWTLSCertificate* self = new(ELeave) CWTLSCertificate;
362 CleanupStack::PushL(self);
363 self->InternalizeL(aStream);
367 EXPORT_C CWTLSCertificate* CWTLSCertificate::NewL(CCertStore& aStore, const CCertStoreEntry& aEntry)
369 CWTLSCertificate* self = CWTLSCertificate::NewLC(aStore, aEntry);
370 CleanupStack::Pop();//self
374 EXPORT_C CWTLSCertificate* CWTLSCertificate::NewLC(CCertStore& aStore, const CCertStoreEntry& aEntry)
376 CWTLSCertificate* self = new(ELeave) CWTLSCertificate;
377 CleanupStack::PushL(self);
378 aStore.LoadL(*self, aEntry);
382 EXPORT_C CWTLSCertificate* CWTLSCertificate::NewL(const CWTLSCertificate& aCert)
384 CWTLSCertificate* self = CWTLSCertificate::NewLC(aCert);
385 CleanupStack::Pop();//self
389 EXPORT_C CWTLSCertificate* CWTLSCertificate::NewLC(const CWTLSCertificate& aCert)
391 CWTLSCertificate* self = new(ELeave) CWTLSCertificate;
392 CleanupStack::PushL(self);
393 self->ConstructL(aCert);
397 EXPORT_C CWTLSCertificate::~CWTLSCertificate()
402 if (iDataElements != NULL)
404 for (TInt i = 0; i < KWTLSCertMaxDataElements; i++)
406 delete iDataElements->At(i);
408 delete iDataElements;
412 EXPORT_C TBool CWTLSCertificate::IsEqualL(const CWTLSCertificate& aCert) const
414 return (*(iFingerprint) == (*(aCert.iFingerprint)));
418 EXPORT_C const TPtrC8 CWTLSCertificate::SignedDataL() const
420 return iEncoding->Left(iEncoding->Length() - (iSignature->Length() +2));
423 EXPORT_C TInt CWTLSCertificate::Version() const
428 EXPORT_C const CWTLSName& CWTLSCertificate::IssuerName() const
433 EXPORT_C const CWTLSName& CWTLSCertificate::SubjectName() const
435 return *iSubjectName;
438 EXPORT_C HBufC* CWTLSCertificate::IssuerL() const
440 return iIssuerName->DisplayNameL();
443 EXPORT_C HBufC* CWTLSCertificate::SubjectL() const
445 return iSubjectName->DisplayNameL();
448 EXPORT_C TBool CWTLSCertificate::IsSelfSignedL() const
450 return iSubjectName->ExactMatchL(*iIssuerName);
453 EXPORT_C const TPtrC8* CWTLSCertificate::DataElementEncoding(const TUint aIndex) const
455 return iDataElements->At(aIndex);
458 EXPORT_C void CWTLSCertificate::InternalizeL(RReadStream& aStream)
460 if (iIssuerName != NULL) //just to check cert is uninitialised
462 User::Leave(KErrArgument);
464 iKeyFactory = new(ELeave) TWTLSKeyFactory;
465 TInt len = aStream.ReadInt32L();
466 iEncoding = HBufC8::NewL(aStream,len);
468 ConstructCertL(*iEncoding, pos);
470 TWTLSDecUnsignedInteger decInt;
471 TInt sigLength = decInt.DecodeShortL(*iEncoding, pos, 2);
472 iSignature = (iEncoding->Mid(pos, sigLength)).AllocL();
473 CSHA1* hash = CSHA1::NewL();
474 CleanupStack::PushL(hash);
475 iFingerprint = hash->Final(Encoding()).AllocL();
476 CleanupStack::PopAndDestroy();
478 InitEncodedDataElementsL();
481 EXPORT_C TBool CWTLSCertificate::IsTCAL() const
483 TBool isTCA = EFalse;
484 TPtrC8 nameData = SubjectName().NameData();
485 CWTLSStructuredText* sText = NULL; //inited to get rid of warning
486 TRAPD(err, sText = CWTLSStructuredText::NewL(nameData) );
487 if( err == KErrNone )
489 const TWTLSStructuredTextField* sTextField = sText->FieldByName(KWTLSTCAType);
490 if(sTextField != NULL)
492 if(sTextField->Value().Compare(KWTLSTCAValue) == 0)
502 CWTLSCertificate::CWTLSCertificate()
506 void CWTLSCertificate::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
509 ConstructCertL(aBinaryData, aPos);
510 iKeyFactory = new(ELeave) TWTLSKeyFactory;
512 TWTLSDecUnsignedInteger decInt;
513 TInt sigLength = decInt.DecodeShortL(aBinaryData, aPos, 2);
514 if ((sigLength + aPos) > aBinaryData.Length())
516 User::Leave(KErrArgument);
518 iSignature = (aBinaryData.Mid(aPos, sigLength)).AllocL();
520 iEncoding = aBinaryData.Mid(tempPos, aPos - tempPos).AllocL();
522 CSHA1* hash = CSHA1::NewL();
523 CleanupStack::PushL(hash);
524 iFingerprint = hash->Final(Encoding()).AllocL();
525 CleanupStack::PopAndDestroy();
527 InitEncodedDataElementsL();
530 void CWTLSCertificate::ConstructL(const CWTLSCertificate& aCertificate)
532 iEncoding = aCertificate.Encoding().AllocL();
533 iKeyFactory = new(ELeave) TWTLSKeyFactory;
534 iSignature = aCertificate.Signature().AllocL();
535 iFingerprint = aCertificate.Fingerprint().AllocL();
536 iSigningAlgorithm = CSigningAlgorithmIdentifier::NewL(aCertificate.SigningAlgorithm());
537 iSerialNumber = aCertificate.iSerialNumber->Des().AllocL();
538 iIssuerName = CWTLSName::NewL(*(aCertificate.iIssuerName));
539 iValidityPeriod = new(ELeave) CValidityPeriod(*(aCertificate.iValidityPeriod));
540 iSubjectName = CWTLSName::NewL(*(aCertificate.iSubjectName));
541 iSubjectPublicKeyInfo = CSubjectPublicKeyInfo::NewL(*(aCertificate.iSubjectPublicKeyInfo));
543 InitEncodedDataElementsL();
546 void CWTLSCertificate::ConstructCertL(const TDesC8& aBinaryData, TInt& aPos)
548 if ((aBinaryData.Length() - aPos) < 1)
550 User::Leave(KErrArgument);
552 iVersion = aBinaryData[aPos];
555 iSigningAlgorithm = CWTLSSigningAlgorithmIdentifier::NewL(aBinaryData, aPos);
556 iIssuerName = CWTLSName::NewL(aBinaryData, aPos);
557 iValidityPeriod = CWTLSValidityPeriod::NewL(aBinaryData, aPos);
558 iSubjectName = CWTLSName::NewL(aBinaryData, aPos);
559 iSubjectPublicKeyInfo = CWTLSSubjectPublicKeyInfo::NewL(aBinaryData, aPos);
560 iSerialNumber = HBufC8::NewL(0);
561 *iSerialNumber = KNullDesC8;
564 void CWTLSCertificate::InitEncodedDataElementsL()
566 iDataElements = new(ELeave) TFixedArray<TPtrC8*, KWTLSCertMaxDataElements>;
567 iDataElements->Reset();
568 const TPtrC8 signedData = SignedDataL();
570 TPtrC8** pElement = iDataElements->Begin();
571 *pElement++ = new(ELeave) TPtrC8(signedData.Left(++aPos));
572 *pElement++ = new(ELeave) TPtrC8(signedData.Mid(aPos, aPos));
573 aPos++; // Defect fix from Jetstream
574 TInt issuerEncodedLength = IssuerName().NameData().Length() + 1;//1 for the identifier type
575 *pElement++ = new(ELeave) TPtrC8(signedData.Mid(aPos, issuerEncodedLength));
576 aPos+=+issuerEncodedLength;
577 *pElement++ = new(ELeave) TPtrC8(signedData.Mid(aPos, 8));
579 TInt subjectEncodedLength = SubjectName().NameData().Length() + 1;//1 for the identifier type
580 *pElement++ = new(ELeave) TPtrC8(signedData.Mid(aPos, subjectEncodedLength));
581 aPos+=+subjectEncodedLength;
582 *pElement++ = new(ELeave) TPtrC8(signedData.Right(signedData.Length() - aPos));