cryptoservices/certificateandkeymgmt/wtlscert/wtlscert.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptoservices/certificateandkeymgmt/wtlscert/wtlscert.cpp	Wed Jul 08 11:25:26 2009 +0100
@@ -0,0 +1,583 @@
+/*
+* Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+* -- FingerPrint Note:
+* Developers have to be aware that if they are going to change the fingerprint for this certificate
+* for a different hash, then there are other places that need to reflect this change
+* -- Location
+* void CWTLSCertificate::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
+* EXPORT_C void CWTLSCertificate::InternalizeL(RReadStream& aStream)
+* Also change the CX509Certificate and search for other occurences of the current
+* hash.
+*
+*/
+
+
+#include <wtlscert.h>
+#include <wtlskeys.h>
+#include "wtlsdec.h"
+#include <hash.h>
+
+enum TEncAlgorithmType
+	{
+	EEncRSA = 0x02
+	};
+
+enum TEncSigAlgorithmType
+	{
+	EEncRSAwithSHA1 = 0x02
+	};
+
+const TInt KMinAlgIdLength = 2;
+const TInt KMinExpLengthBytes = 1;
+const TInt KMaxExpLengthBytes = 65535;
+const TInt KMinModLengthBytes = 1;
+const TInt KMaxModLengthBytes = 65535;
+
+//WTLS RSA signature result
+EXPORT_C CWTLSRSASignatureResult* CWTLSRSASignatureResult::NewL(const CAlgorithmIdentifier& aDigestAlgorithm, const TDesC8& aDigest)
+	{
+	CWTLSRSASignatureResult* self = CWTLSRSASignatureResult::NewLC(aDigestAlgorithm, aDigest);
+	CleanupStack::Pop();
+	return self;
+	}
+
+EXPORT_C CWTLSRSASignatureResult* CWTLSRSASignatureResult::NewLC(const CAlgorithmIdentifier& aDigestAlgorithm, const TDesC8& aDigest)
+	{
+	CWTLSRSASignatureResult* self = new(ELeave) CWTLSRSASignatureResult;
+	CleanupStack::PushL(self);
+	self->ConstructL(aDigestAlgorithm, aDigest);
+	return self;
+	}
+
+EXPORT_C TBool CWTLSRSASignatureResult::VerifyL(const TDesC8& aResult)
+	{
+	return aResult == *iDigest;
+	}
+
+void CWTLSRSASignatureResult::ConstructL(const CAlgorithmIdentifier& aDigestAlgorithm, const TDesC8& aDigest)
+	{
+	iDigestAlgorithm = CAlgorithmIdentifier::NewL(aDigestAlgorithm);
+	iDigest = aDigest.AllocL();
+	}
+
+//WTLS KeyFactory
+CRSAPublicKey* TWTLSKeyFactory::RSAPublicKeyL(const TDesC8& aEncoding) const
+	{
+	return CWTLSRSAPublicKey::NewL(aEncoding);
+	}
+
+CRSASignatureResult* TWTLSKeyFactory::RSASignatureResultL(const CAlgorithmIdentifier& aDigestAlgorithm, TDesC8& aDigest) const
+	{
+	return CWTLSRSASignatureResult::NewL(aDigestAlgorithm, aDigest);
+	}
+
+CDSAPublicKey* TWTLSKeyFactory::DSAPublicKeyL(const CDSAParameters& /*aParams*/, const TDesC8& /*aEncoding*/) const
+	{
+	User::Leave(KErrNotSupported);
+	return NULL;
+	}
+
+CDSAPublicKey* TWTLSKeyFactory::DSAPublicKeyL(const TDesC8& /*aParams*/, const TDesC8& /*aEncoding*/) const
+	{
+	User::Leave(KErrNotSupported);
+	return NULL;
+	}
+
+CDSASignature* TWTLSKeyFactory::DSASignatureL(const TDesC8& /*aEncoding*/) const
+{
+	User::Leave(KErrNotSupported);
+	return NULL;	
+}
+
+
+CDSAParameters* TWTLSKeyFactory::DSAParametersL(const TDesC8& /*aParamsEncoding*/) const
+{
+	User::Leave(KErrNotSupported);
+	return NULL;	
+}
+
+//validity period
+EXPORT_C CWTLSValidityPeriod* CWTLSValidityPeriod::NewL(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CWTLSValidityPeriod::NewL(aBinaryData, pos);
+	}
+
+EXPORT_C CWTLSValidityPeriod* CWTLSValidityPeriod::NewLC(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CWTLSValidityPeriod::NewLC(aBinaryData, pos);
+	}
+
+EXPORT_C CWTLSValidityPeriod* CWTLSValidityPeriod::NewL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CWTLSValidityPeriod* self = CWTLSValidityPeriod::NewLC(aBinaryData, aPos);
+	CleanupStack::Pop();
+	return self;
+	}
+
+EXPORT_C CWTLSValidityPeriod* CWTLSValidityPeriod::NewLC(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CWTLSValidityPeriod* self = new(ELeave) CWTLSValidityPeriod;
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData, aPos);
+	return self;
+	}
+
+CWTLSValidityPeriod::CWTLSValidityPeriod()
+	{
+	}
+
+void CWTLSValidityPeriod::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	TWTLSDecTime timeDec;
+	iStart = timeDec.DecodeL(aBinaryData, aPos);
+	iFinish = timeDec.DecodeL(aBinaryData, aPos);
+	}
+
+//algorithm id
+EXPORT_C CWTLSAlgorithmIdentifier* CWTLSAlgorithmIdentifier::NewL(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CWTLSAlgorithmIdentifier::NewL(aBinaryData, pos);
+	}
+
+EXPORT_C CWTLSAlgorithmIdentifier* CWTLSAlgorithmIdentifier::NewLC(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CWTLSAlgorithmIdentifier::NewLC(aBinaryData, pos);
+	}
+
+EXPORT_C CWTLSAlgorithmIdentifier* CWTLSAlgorithmIdentifier::NewL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CWTLSAlgorithmIdentifier* self = CWTLSAlgorithmIdentifier::NewLC(aBinaryData, aPos);
+	CleanupStack::Pop();
+	return self;
+	}
+
+EXPORT_C CWTLSAlgorithmIdentifier* CWTLSAlgorithmIdentifier::NewLC(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CWTLSAlgorithmIdentifier* self = new(ELeave) CWTLSAlgorithmIdentifier;
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData, aPos);
+	return self;
+	}
+
+CWTLSAlgorithmIdentifier::CWTLSAlgorithmIdentifier()
+	{
+	}
+
+void CWTLSAlgorithmIdentifier::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	if ((aBinaryData.Length() - aPos) < KMinAlgIdLength)
+		{
+		User::Leave(KErrArgument);
+		}
+	switch (aBinaryData[aPos])
+		{
+		case EEncRSA:
+			{
+			iAlgorithmId = ERSA;
+			aPos++;
+			if (aBinaryData[aPos] != 0)
+				{
+				User::Leave(KErrArgument);
+				}
+			aPos++;
+			iEncodedParams = HBufC8::NewL(1);
+			*iEncodedParams = KNullDesC8;
+			break;
+			}
+		default:
+			//we only support RSA just now...
+			{
+			User::Leave(KErrNotSupported);
+			}
+		}
+	}
+
+//signing algorithm id
+EXPORT_C CWTLSSigningAlgorithmIdentifier* CWTLSSigningAlgorithmIdentifier::NewL(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CWTLSSigningAlgorithmIdentifier::NewL(aBinaryData, pos);
+	}
+
+EXPORT_C CWTLSSigningAlgorithmIdentifier* CWTLSSigningAlgorithmIdentifier::NewLC(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CWTLSSigningAlgorithmIdentifier::NewLC(aBinaryData, pos);
+	}
+
+EXPORT_C CWTLSSigningAlgorithmIdentifier* CWTLSSigningAlgorithmIdentifier::NewL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CWTLSSigningAlgorithmIdentifier* self = CWTLSSigningAlgorithmIdentifier::NewLC(aBinaryData, aPos);
+	CleanupStack::Pop();
+	return self;
+	}
+
+EXPORT_C CWTLSSigningAlgorithmIdentifier* CWTLSSigningAlgorithmIdentifier::NewLC(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CWTLSSigningAlgorithmIdentifier* self = new(ELeave) CWTLSSigningAlgorithmIdentifier;
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData, aPos);
+	return self;
+	}
+
+CWTLSSigningAlgorithmIdentifier::CWTLSSigningAlgorithmIdentifier()
+	{
+	}
+
+void CWTLSSigningAlgorithmIdentifier::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	if ((aBinaryData.Length() - aPos) < 1)
+		{
+		User::Leave(KErrArgument);
+		}
+	switch (aBinaryData[aPos])
+		{
+		case EEncRSAwithSHA1:
+			{
+			TAlgorithmId asym = ERSA;
+			TAlgorithmId dig = ESHA1;
+			iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(asym, KNullDesC8);
+			iDigestAlgorithm = CAlgorithmIdentifier::NewL(dig, KNullDesC8);
+			aPos++;
+			break;
+			}
+		default:
+			//we only support RSA-SHA1 just now...
+			{
+			User::Leave(KErrNotSupported);
+			}
+		}
+	}
+
+//wtls subject public key info
+EXPORT_C CWTLSSubjectPublicKeyInfo* CWTLSSubjectPublicKeyInfo::NewL(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CWTLSSubjectPublicKeyInfo::NewL(aBinaryData, pos);
+	}
+
+EXPORT_C CWTLSSubjectPublicKeyInfo* CWTLSSubjectPublicKeyInfo::NewLC(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CWTLSSubjectPublicKeyInfo::NewLC(aBinaryData, pos);
+	}
+
+EXPORT_C CWTLSSubjectPublicKeyInfo* CWTLSSubjectPublicKeyInfo::NewL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CWTLSSubjectPublicKeyInfo* self = CWTLSSubjectPublicKeyInfo::NewLC(aBinaryData, aPos);
+	CleanupStack::Pop();
+	return self;
+	}
+
+EXPORT_C CWTLSSubjectPublicKeyInfo* CWTLSSubjectPublicKeyInfo::NewLC(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CWTLSSubjectPublicKeyInfo* self = new(ELeave) CWTLSSubjectPublicKeyInfo;
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData, aPos);
+	return self;
+	}
+
+CWTLSSubjectPublicKeyInfo::CWTLSSubjectPublicKeyInfo()
+	{
+	}
+
+void CWTLSSubjectPublicKeyInfo::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	iAlgId = CWTLSAlgorithmIdentifier::NewL(aBinaryData, aPos);
+	if (iAlgId->Algorithm() != ERSA)
+		{
+		User::Leave(KErrNotSupported);
+		}
+	TInt totalLength = aBinaryData.Length();
+	TInt tempPos = aPos;
+
+	const TPtrC8 expEnc = aBinaryData.Right(totalLength - aPos);
+	TWTLSDecVector exp(expEnc, KMinExpLengthBytes, KMaxExpLengthBytes);
+	exp.InitL();
+
+	aPos += exp.EncodingLength();
+
+	const TPtrC8 modEnc = aBinaryData.Right(totalLength - aPos);
+	TWTLSDecVector mod(modEnc, KMinModLengthBytes, KMaxModLengthBytes);
+	mod.InitL();
+
+	aPos+= mod.EncodingLength();
+	iEncodedKeyData = (aBinaryData.Mid(tempPos, aPos - tempPos)).AllocL();
+	}
+
+//wtls certificate
+EXPORT_C CWTLSCertificate* CWTLSCertificate::NewL(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CWTLSCertificate::NewL(aBinaryData, pos);
+	}
+
+EXPORT_C CWTLSCertificate* CWTLSCertificate::NewLC(const TDesC8& aBinaryData)
+	{
+	TInt pos = 0;
+	return CWTLSCertificate::NewLC(aBinaryData, pos);
+	}
+
+EXPORT_C CWTLSCertificate* CWTLSCertificate::NewL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CWTLSCertificate* self = CWTLSCertificate::NewLC(aBinaryData, aPos);
+	CleanupStack::Pop();
+	return self;
+	}
+
+EXPORT_C CWTLSCertificate* CWTLSCertificate::NewLC(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	CWTLSCertificate* self = new(ELeave) CWTLSCertificate;
+	CleanupStack::PushL(self);
+	self->ConstructL(aBinaryData, aPos);
+	return self;
+	}
+
+EXPORT_C CWTLSCertificate* CWTLSCertificate::NewL(RReadStream& aStream)
+	{
+	CWTLSCertificate* self = CWTLSCertificate::NewLC(aStream);
+	CleanupStack::Pop();//self
+	return self;
+	}
+
+EXPORT_C CWTLSCertificate* CWTLSCertificate::NewLC(RReadStream& aStream)
+	{
+	CWTLSCertificate* self = new(ELeave) CWTLSCertificate;
+	CleanupStack::PushL(self);
+	self->InternalizeL(aStream);
+	return self;
+	}
+/*
+EXPORT_C CWTLSCertificate* CWTLSCertificate::NewL(CCertStore& aStore, const CCertStoreEntry& aEntry)
+	{
+	CWTLSCertificate* self = CWTLSCertificate::NewLC(aStore, aEntry);
+	CleanupStack::Pop();//self
+	return self;
+	}
+
+EXPORT_C CWTLSCertificate* CWTLSCertificate::NewLC(CCertStore& aStore, const CCertStoreEntry& aEntry)
+	{
+	CWTLSCertificate* self = new(ELeave) CWTLSCertificate;
+	CleanupStack::PushL(self);
+	aStore.LoadL(*self, aEntry);
+	return self;
+	}
+*/
+EXPORT_C CWTLSCertificate* CWTLSCertificate::NewL(const CWTLSCertificate& aCert)
+	{
+	CWTLSCertificate* self = CWTLSCertificate::NewLC(aCert);
+	CleanupStack::Pop();//self
+	return self;
+	}
+
+EXPORT_C CWTLSCertificate* CWTLSCertificate::NewLC(const CWTLSCertificate& aCert)
+	{
+	CWTLSCertificate* self = new(ELeave) CWTLSCertificate;
+	CleanupStack::PushL(self);
+	self->ConstructL(aCert);
+	return self;
+	}
+
+EXPORT_C CWTLSCertificate::~CWTLSCertificate()
+	{
+	delete iIssuerName;
+	delete iSubjectName;
+		
+	if (iDataElements != NULL)
+		{
+		for (TInt i = 0; i < KWTLSCertMaxDataElements; i++)
+			{
+			delete iDataElements->At(i);
+			}
+		delete iDataElements;
+		}
+	}
+
+EXPORT_C TBool CWTLSCertificate::IsEqualL(const CWTLSCertificate& aCert) const
+	{
+	return	(*(iFingerprint) == (*(aCert.iFingerprint)));
+	}
+
+	//extra accessors
+EXPORT_C const TPtrC8 CWTLSCertificate::SignedDataL() const
+	{
+	return iEncoding->Left(iEncoding->Length() - (iSignature->Length() +2));
+	}
+
+EXPORT_C TInt CWTLSCertificate::Version() const
+	{
+	return iVersion;
+	}
+
+EXPORT_C const CWTLSName& CWTLSCertificate::IssuerName() const
+	{
+	return *iIssuerName;
+	}
+
+EXPORT_C const CWTLSName& CWTLSCertificate::SubjectName() const
+	{
+	return *iSubjectName;
+	}
+
+EXPORT_C HBufC* CWTLSCertificate::IssuerL() const
+	{
+	return iIssuerName->DisplayNameL();
+	}
+
+EXPORT_C HBufC* CWTLSCertificate::SubjectL() const
+	{
+	return iSubjectName->DisplayNameL();
+	}
+
+EXPORT_C TBool CWTLSCertificate::IsSelfSignedL() const
+	{
+	return iSubjectName->ExactMatchL(*iIssuerName);
+	}
+
+EXPORT_C const TPtrC8* CWTLSCertificate::DataElementEncoding(const TUint aIndex) const
+	{
+	return iDataElements->At(aIndex);
+	}
+
+EXPORT_C void CWTLSCertificate::InternalizeL(RReadStream& aStream)
+	{
+	if (iIssuerName != NULL) //just to check cert is uninitialised
+		{
+		User::Leave(KErrArgument);
+		}
+	iKeyFactory = new(ELeave) TWTLSKeyFactory;
+	TInt len = aStream.ReadInt32L();
+	iEncoding = HBufC8::NewL(aStream,len);
+	TInt pos = 0;
+	ConstructCertL(*iEncoding, pos);
+
+	TWTLSDecUnsignedInteger decInt;
+	TInt sigLength = decInt.DecodeShortL(*iEncoding, pos, 2);
+	iSignature = (iEncoding->Mid(pos, sigLength)).AllocL();
+	CSHA1* hash = CSHA1::NewL();
+	CleanupStack::PushL(hash);
+	iFingerprint = hash->Final(Encoding()).AllocL();
+	CleanupStack::PopAndDestroy();
+
+	InitEncodedDataElementsL();
+	}
+
+EXPORT_C TBool CWTLSCertificate::IsTCAL() const
+	{
+	TBool isTCA = EFalse;
+	TPtrC8 nameData = SubjectName().NameData();
+	CWTLSStructuredText* sText = NULL; //inited to get rid of warning
+	TRAPD(err, sText = CWTLSStructuredText::NewL(nameData) );
+	if( err == KErrNone )
+	    {
+		const TWTLSStructuredTextField* sTextField = sText->FieldByName(KWTLSTCAType);
+		if(sTextField != NULL)
+			{
+			if(sTextField->Value().Compare(KWTLSTCAValue) == 0)
+				{
+				isTCA = ETrue;
+				}
+			}
+		delete sText;
+		}
+	return isTCA;
+	}
+
+CWTLSCertificate::CWTLSCertificate()
+	{
+	}
+
+void CWTLSCertificate::ConstructL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	TInt tempPos = aPos;
+	ConstructCertL(aBinaryData, aPos);
+	iKeyFactory = new(ELeave) TWTLSKeyFactory;
+
+	TWTLSDecUnsignedInteger decInt;
+	TInt sigLength = decInt.DecodeShortL(aBinaryData, aPos, 2);
+	if ((sigLength + aPos) > aBinaryData.Length())
+		{
+		User::Leave(KErrArgument);
+		}
+	iSignature = (aBinaryData.Mid(aPos, sigLength)).AllocL();
+	aPos+= sigLength;
+	iEncoding = aBinaryData.Mid(tempPos, aPos - tempPos).AllocL();
+
+	CSHA1* hash = CSHA1::NewL();
+	CleanupStack::PushL(hash);
+	iFingerprint = hash->Final(Encoding()).AllocL();
+	CleanupStack::PopAndDestroy();
+	
+	InitEncodedDataElementsL();
+	}
+
+void CWTLSCertificate::ConstructL(const CWTLSCertificate& aCertificate)
+	{
+	iEncoding = aCertificate.Encoding().AllocL();
+	iKeyFactory = new(ELeave) TWTLSKeyFactory;
+	iSignature = aCertificate.Signature().AllocL();
+	iFingerprint = aCertificate.Fingerprint().AllocL();
+	iSigningAlgorithm = CSigningAlgorithmIdentifier::NewL(aCertificate.SigningAlgorithm());
+	iSerialNumber = aCertificate.iSerialNumber->Des().AllocL();
+	iIssuerName = CWTLSName::NewL(*(aCertificate.iIssuerName));
+	iValidityPeriod = new(ELeave) CValidityPeriod(*(aCertificate.iValidityPeriod));
+	iSubjectName = CWTLSName::NewL(*(aCertificate.iSubjectName));
+	iSubjectPublicKeyInfo = CSubjectPublicKeyInfo::NewL(*(aCertificate.iSubjectPublicKeyInfo));
+
+	InitEncodedDataElementsL();
+	}
+
+void CWTLSCertificate::ConstructCertL(const TDesC8& aBinaryData, TInt& aPos)
+	{
+	if ((aBinaryData.Length() - aPos) < 1)
+		{
+		User::Leave(KErrArgument);
+		}
+	iVersion = aBinaryData[aPos];
+
+	aPos++;
+	iSigningAlgorithm = CWTLSSigningAlgorithmIdentifier::NewL(aBinaryData, aPos);
+	iIssuerName = CWTLSName::NewL(aBinaryData, aPos);
+	iValidityPeriod = CWTLSValidityPeriod::NewL(aBinaryData, aPos);
+	iSubjectName = CWTLSName::NewL(aBinaryData, aPos);
+	iSubjectPublicKeyInfo = CWTLSSubjectPublicKeyInfo::NewL(aBinaryData, aPos);
+	iSerialNumber = HBufC8::NewL(0);
+	*iSerialNumber = KNullDesC8;
+	}
+
+void CWTLSCertificate::InitEncodedDataElementsL()
+	{
+	iDataElements = new(ELeave) TFixedArray<TPtrC8*, KWTLSCertMaxDataElements>;
+	iDataElements->Reset();
+	const TPtrC8 signedData = SignedDataL();
+	TInt aPos = 0;
+	TPtrC8** pElement = iDataElements->Begin();
+	*pElement++ = new(ELeave) TPtrC8(signedData.Left(++aPos));
+	*pElement++ = new(ELeave) TPtrC8(signedData.Mid(aPos, aPos));
+	aPos++;	//	Defect fix from Jetstream
+	TInt issuerEncodedLength = IssuerName().NameData().Length() + 1;//1 for the identifier type
+	*pElement++ = new(ELeave) TPtrC8(signedData.Mid(aPos, issuerEncodedLength));
+	aPos+=+issuerEncodedLength;
+	*pElement++ = new(ELeave) TPtrC8(signedData.Mid(aPos, 8));
+	aPos+=8;
+	TInt subjectEncodedLength = SubjectName().NameData().Length() + 1;//1 for the identifier type
+	*pElement++ = new(ELeave) TPtrC8(signedData.Mid(aPos, subjectEncodedLength));
+	aPos+=+subjectEncodedLength;
+	*pElement++ = new(ELeave) TPtrC8(signedData.Right(signedData.Length() - aPos));
+	}