diff -r 000000000000 -r 2c201484c85f cryptoservices/certificateandkeymgmt/wtlscert/wtlscert.cpp --- /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 +#include +#include "wtlsdec.h" +#include + +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; + 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)); + }