diff -r 000000000000 -r 2c201484c85f cryptoservices/certificateandkeymgmt/crypto/Signed.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cryptoservices/certificateandkeymgmt/crypto/Signed.cpp Wed Jul 08 11:25:26 2009 +0100 @@ -0,0 +1,604 @@ +/* +* Copyright (c) 1998-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: +* +*/ + + +#include +#include +#include +#include +#include +#include + +//RSA signature result +EXPORT_C TBool CRSASignatureResult::operator== (const CRSASignatureResult& aResult) const + { + return ((*(iDigestAlgorithm) == *(aResult.iDigestAlgorithm)) && + (*(iDigest)==*(aResult.iDigest))); + } + +EXPORT_C CRSASignatureResult::~CRSASignatureResult() + { + delete iDigestAlgorithm; + delete iDigest; + } + +//validity period +EXPORT_C CValidityPeriod::CValidityPeriod(const CValidityPeriod& aValidityPeriod) + :iStart(aValidityPeriod.iStart), iFinish(aValidityPeriod.iFinish) + { + } + +EXPORT_C CValidityPeriod::CValidityPeriod() + { + } + +EXPORT_C TBool CValidityPeriod::Valid(const TTime& aTime) const + { + return ((iStart < aTime) && (iFinish > aTime)); + } + +EXPORT_C const TTime& CValidityPeriod::Start() const + { + return iStart; + } + +EXPORT_C const TTime& CValidityPeriod::Finish() const + { + return iFinish; + } + +//******************************************************************************// +//algorithm id +EXPORT_C CAlgorithmIdentifier* CAlgorithmIdentifier::NewL(const CAlgorithmIdentifier& aAlgorithmIdentifier) + { + CAlgorithmIdentifier* self = CAlgorithmIdentifier::NewLC(aAlgorithmIdentifier); + CleanupStack::Pop();//self + return self; + } + +EXPORT_C CAlgorithmIdentifier* CAlgorithmIdentifier::NewLC(const CAlgorithmIdentifier& aAlgorithmIdentifier) + { + CAlgorithmIdentifier* self = new(ELeave) CAlgorithmIdentifier; + CleanupStack::PushL(self); + self->ConstructL(aAlgorithmIdentifier); + return self; + } + +EXPORT_C CAlgorithmIdentifier* CAlgorithmIdentifier::NewL(TAlgorithmId& aAlgorithmId, const TDesC8& aEncodedParams) + { + CAlgorithmIdentifier* self = CAlgorithmIdentifier::NewLC(aAlgorithmId, aEncodedParams); + CleanupStack::Pop();//self + return self; + } + +EXPORT_C CAlgorithmIdentifier* CAlgorithmIdentifier::NewLC(TAlgorithmId& aAlgorithmId, const TDesC8& aEncodedParams) + { + CAlgorithmIdentifier* self = new(ELeave) CAlgorithmIdentifier(aAlgorithmId); + CleanupStack::PushL(self); + self->ConstructL(aEncodedParams); + return self; + } + +EXPORT_C CAlgorithmIdentifier::CAlgorithmIdentifier(TAlgorithmId& aAlgorithmId) + :iAlgorithmId(aAlgorithmId) + { + } + +EXPORT_C CAlgorithmIdentifier::CAlgorithmIdentifier() + { + } + +EXPORT_C void CAlgorithmIdentifier::ConstructL(const TDesC8& aEncodedParams) + { + iEncodedParams = aEncodedParams.AllocL(); + } + + +EXPORT_C TBool CAlgorithmIdentifier::operator==(const CAlgorithmIdentifier& aAlgorithmIdentifier) const + { + return ((iAlgorithmId == aAlgorithmIdentifier.iAlgorithmId) && + (*(iEncodedParams) == *(aAlgorithmIdentifier.iEncodedParams))); + } + +EXPORT_C TAlgorithmId CAlgorithmIdentifier::Algorithm() const + { + return iAlgorithmId; + } + +EXPORT_C TPtrC8 CAlgorithmIdentifier::EncodedParams() const + { + return iEncodedParams->Des(); + } + +EXPORT_C CAlgorithmIdentifier::~CAlgorithmIdentifier() + { + delete iEncodedParams; + } + +EXPORT_C void CAlgorithmIdentifier::ConstructL(const CAlgorithmIdentifier& aAlgorithmIdentifier) + { + iAlgorithmId = aAlgorithmIdentifier.iAlgorithmId; + iEncodedParams = aAlgorithmIdentifier.iEncodedParams->AllocL(); + } + +//***********************************************************************// +//signing algorithm id +EXPORT_C CSigningAlgorithmIdentifier* CSigningAlgorithmIdentifier::NewL(const CSigningAlgorithmIdentifier& aSigningAlgorithmIdentifier) + { + CSigningAlgorithmIdentifier* self = CSigningAlgorithmIdentifier::NewLC(aSigningAlgorithmIdentifier); + CleanupStack::Pop();//self + return self; + } + +EXPORT_C CSigningAlgorithmIdentifier* CSigningAlgorithmIdentifier::NewLC(const CSigningAlgorithmIdentifier& aSigningAlgorithmIdentifier) + { + CSigningAlgorithmIdentifier* self = new(ELeave) CSigningAlgorithmIdentifier; + CleanupStack::PushL(self); + self->ConstructL(aSigningAlgorithmIdentifier); + return self; + } + +EXPORT_C TBool CSigningAlgorithmIdentifier::operator == (const CSigningAlgorithmIdentifier& aSigningAlgorithmIdentifier) const + { + return ((*(iAsymmetricAlgorithm) == *(aSigningAlgorithmIdentifier.iAsymmetricAlgorithm)) && + (*(iDigestAlgorithm) == *(aSigningAlgorithmIdentifier.iDigestAlgorithm))); + } + +void CSigningAlgorithmIdentifier::ConstructL(const CSigningAlgorithmIdentifier& aAlgorithmIdentifier) + { + iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(*(aAlgorithmIdentifier.iAsymmetricAlgorithm)); + iDigestAlgorithm = CAlgorithmIdentifier::NewL(*(aAlgorithmIdentifier.iDigestAlgorithm)); + } + +EXPORT_C const CAlgorithmIdentifier& CSigningAlgorithmIdentifier::AsymmetricAlgorithm() const + { + return *iAsymmetricAlgorithm; + } + +EXPORT_C const CAlgorithmIdentifier& CSigningAlgorithmIdentifier::DigestAlgorithm() const + { + return *iDigestAlgorithm; + } + +EXPORT_C CSigningAlgorithmIdentifier::~CSigningAlgorithmIdentifier() + { + delete iAsymmetricAlgorithm; + delete iDigestAlgorithm; + } + +//************************************************************************// +//subject public key info +EXPORT_C CSubjectPublicKeyInfo* CSubjectPublicKeyInfo::NewL(const CSubjectPublicKeyInfo& aSubjectPublicKeyInfo) + { + CSubjectPublicKeyInfo* self = CSubjectPublicKeyInfo::NewLC(aSubjectPublicKeyInfo); + CleanupStack::Pop();//self + return self; + } + +EXPORT_C CSubjectPublicKeyInfo* CSubjectPublicKeyInfo::NewLC(const CSubjectPublicKeyInfo& aSubjectPublicKeyInfo) + { + CSubjectPublicKeyInfo* self = new(ELeave) CSubjectPublicKeyInfo; + CleanupStack::PushL(self); + self->ConstructL(aSubjectPublicKeyInfo); + return self; + } + +EXPORT_C TAlgorithmId CSubjectPublicKeyInfo::AlgorithmId() const + { + return iAlgId->Algorithm(); + } + +EXPORT_C const TPtrC8 CSubjectPublicKeyInfo::EncodedParams() const + { + return iAlgId->EncodedParams(); + } + +EXPORT_C const TPtrC8 CSubjectPublicKeyInfo::KeyData() const + { + return iEncodedKeyData->Des(); + } + +EXPORT_C CSubjectPublicKeyInfo::~CSubjectPublicKeyInfo() + { + delete iAlgId; + delete iEncodedKeyData; + } + +EXPORT_C void CSubjectPublicKeyInfo::ConstructL(const CSubjectPublicKeyInfo& aSubjectPublicKeyInfo) + { + iAlgId = CAlgorithmIdentifier::NewL(*(aSubjectPublicKeyInfo.iAlgId)); + iEncodedKeyData = aSubjectPublicKeyInfo.iEncodedKeyData->AllocL(); + } + +//******************************************************************// +//signed object parameters + + //ctors + +EXPORT_C CSigningKeyParameters* CSigningKeyParameters::NewL() + { + CSigningKeyParameters* self = new(ELeave) CSigningKeyParameters; + return self; + } + +EXPORT_C CSigningKeyParameters* CSigningKeyParameters::NewLC() + { + CSigningKeyParameters* self = CSigningKeyParameters::NewL(); + CleanupStack::PushL(self); + return self; + } + + //copy ctors +EXPORT_C CSigningKeyParameters* CSigningKeyParameters::NewL(const CSigningKeyParameters& aParameters) + { + CSigningKeyParameters* self = CSigningKeyParameters::NewLC(aParameters); + CleanupStack::Pop(); + return self; + } + +EXPORT_C CSigningKeyParameters* CSigningKeyParameters::NewLC(const CSigningKeyParameters& aParameters) + { + CSigningKeyParameters* self = new(ELeave) CSigningKeyParameters; + CleanupStack::PushL(self); + self->ConstructL(aParameters); + return self; + } + +void CSigningKeyParameters::ConstructL(const CSigningKeyParameters& aParameters) + { + SetDSAParamsL(*(aParameters.iDSAParams)); + } + + //dtor +EXPORT_C CSigningKeyParameters::~CSigningKeyParameters() + { + delete iDSAParams; + } + +EXPORT_C void CSigningKeyParameters::SetDSAParamsL(const CDSAParameters& aParams) + { + delete iDSAParams; + iDSAParams = NULL; // In case the next fails + +// Copy the TIntegers + RInteger p = RInteger::NewL(aParams.P()); + CleanupStack::PushL(p); + + RInteger q = RInteger::NewL(aParams.Q()); + CleanupStack::PushL(q); + + RInteger g = RInteger::NewL(aParams.G()); + CleanupStack::PushL(g); + + iDSAParams = CDSAParameters::NewL(p, q, g); + CleanupStack::Pop(3, &p); + } + +const CDSAParameters* CSigningKeyParameters::DSAParams() const + { + return iDSAParams; + } + +CSigningKeyParameters::CSigningKeyParameters() + { + } + +//******************************************************************// +//signed object +EXPORT_C TBool CSignedObject::VerifySignatureL(const TDesC8& aEncodedKey) const + { + const CAlgorithmIdentifier& algId = iSigningAlgorithm->AsymmetricAlgorithm(); + const CAlgorithmIdentifier& digestId = iSigningAlgorithm->DigestAlgorithm(); + + TBool verifyResult = EFalse; + if (algId.Algorithm() == EDSA) + { + if (digestId.Algorithm() != ESHA1) + { + User::Leave(KErrArgument); + } + + CSHA1* sha1 = CSHA1::NewL(); + CleanupStack::PushL(sha1); + TPtrC8 signedData = SignedDataL(); + TPtrC8 hash = sha1->Final(signedData); + verifyResult=VerifySignatureL(aEncodedKey, hash); + CleanupStack::PopAndDestroy(sha1);//hash + } + else + { + TRAPD(result, verifyResult = VerifyRSASignatureL(aEncodedKey)); + if (result==KErrNoMemory) // Leave if OOM, anything else is a verify + User::Leave(result); // error => verifyResult = EFalse + + } + + return verifyResult; + } + +EXPORT_C TBool CSignedObject::VerifySignatureL(const TDesC8& aEncodedKey, const TDesC8& aHash) const + { + const CAlgorithmIdentifier& algId = iSigningAlgorithm->AsymmetricAlgorithm(); + const CAlgorithmIdentifier& digestId = iSigningAlgorithm->DigestAlgorithm(); + + TBool verifyResult = EFalse; + if (algId.Algorithm() == EDSA) + { + if (digestId.Algorithm() != ESHA1) + { + User::Leave(KErrArgument); + } + + CDSAPublicKey* key = NULL; + if (algId.EncodedParams().Length() != 0) + { + key = iKeyFactory->DSAPublicKeyL(algId.EncodedParams(), aEncodedKey); + } + else + { + if (iParameters != NULL) + { + const CDSAParameters* params = iParameters->DSAParams(); + if (!params) + { + User::Leave(KErrArgument);//no params + } + else + { + key = iKeyFactory->DSAPublicKeyL(*params, aEncodedKey); + } + } + } + if (key == NULL) + { + User::Leave(KErrArgument); + } + CleanupStack::PushL(key); + CDSAVerifier* verifier = CDSAVerifier::NewLC(*key); + CDSASignature* sig = iKeyFactory->DSASignatureL(Signature()); + CleanupStack::PushL(sig); + verifyResult = verifier->VerifyL(aHash, *sig); + CleanupStack::PopAndDestroy(3);// key, verifier, sig + } + else + { + TRAPD(result, verifyResult = VerifyRSASignatureL(aEncodedKey, aHash)); + if (result==KErrNoMemory) // Leave if OOM, anything else is a verify + User::Leave(result); // error => verifyResult = EFalse + + } + return verifyResult; + + } + +TBool CSignedObject::VerifyRSASignatureL(const TDesC8& aEncodedKey, const TDesC8& aHash) const + { + __UHEAP_MARK; + const CAlgorithmIdentifier& algId = iSigningAlgorithm->AsymmetricAlgorithm(); + const CAlgorithmIdentifier& digestId = iSigningAlgorithm->DigestAlgorithm(); + if (algId.Algorithm() != ERSA) + { + User::Leave(KErrArgument); + } + + //Get the public key + CRSAPublicKey* key = iKeyFactory->RSAPublicKeyL(aEncodedKey); + CleanupStack::PushL(key); + + CRSAPKCS1v15Verifier* verifier = CRSAPKCS1v15Verifier::NewLC(*key); + + RInteger sig = RInteger::NewL(Signature()); + CleanupStack::PushL(sig); + CRSASignature* theSignature = CRSASignature::NewL(sig); + CleanupStack::Pop(&sig); + CleanupStack::PushL(theSignature); + + HBufC8* publicDecryptOutput = verifier->InverseSignLC(*theSignature); + + //Now verify it + TPtrC8 hash(aHash); + CRSASignatureResult* decoder = iKeyFactory->RSASignatureResultL(digestId, hash); + CleanupStack::PushL(decoder); + + TPtr8 outputPtr(publicDecryptOutput->Des()); + TBool verified = decoder->VerifyL(outputPtr); + CleanupStack::PopAndDestroy(5, key); // decoder, publicDecryptOutput, theSignature + // verifier, key, + __UHEAP_MARKEND; + return (verified); + } + +// x509 signature comprises of an AlgID and the signed data itself, so a simple +// verify is not possible (the data returned from public decrypt will not match +// the original data signed because of the extra algID appendage). +// +TBool CSignedObject::VerifyRSASignatureL(const TDesC8& aEncodedKey) const + { + __UHEAP_MARK; + const CAlgorithmIdentifier& algId = iSigningAlgorithm->AsymmetricAlgorithm(); + const CAlgorithmIdentifier& digestId = iSigningAlgorithm->DigestAlgorithm(); + if (algId.Algorithm() != ERSA) + { + User::Leave(KErrArgument); + } + CMessageDigest* digest = NULL; + switch(digestId.Algorithm()) + { + case EMD2: + { + digest = CMD2::NewL(); + break; + } + case EMD5: + { + digest = CMD5::NewL(); + break; + } + case ESHA1: + { + digest = CSHA1::NewL(); + break; + } + default: + User::Leave(KErrArgument); + } + + //Hash the data + CleanupStack::PushL(digest); + TPtrC8 hash = digest->Final(SignedDataL()); + TBool verifyResult=VerifyRSASignatureL(aEncodedKey, hash); + CleanupStack::PopAndDestroy(digest); + __UHEAP_MARKEND; + return verifyResult; + } + +EXPORT_C void CSignedObject::SetParametersL(const CSigningKeyParameters& aParameters) + { + delete iParameters; + iParameters = NULL; // In case next fails + iParameters = CSigningKeyParameters::NewL(aParameters); + } + +EXPORT_C const TPtrC8 CSignedObject::Signature() const + { + return iSignature->Des(); + } + +EXPORT_C const TPtrC8 CSignedObject::Encoding() const + { + return iEncoding->Des(); + } + +EXPORT_C const CSigningAlgorithmIdentifier& CSignedObject::SigningAlgorithm() const + { + return *iSigningAlgorithm; + } + +EXPORT_C const TPtrC8 CSignedObject::Fingerprint() const + { + return iFingerprint->Des(); + } + +EXPORT_C CSignedObject::~CSignedObject() + { + delete iParameters; + delete iKeyFactory; + delete iFingerprint; + delete iEncoding; + delete iSignature; + delete iSigningAlgorithm; + } + +EXPORT_C void CSignedObject::ExternalizeL(RWriteStream& aStream) const + { + aStream.WriteInt32L(iEncoding->Length()); + aStream.WriteL(*iEncoding); + } +/* +EXPORT_C void CSignedObject::ConstructL(RReadStream& aStream, TSignedObjectParser* aParser, TKeyFactory* aFactory) + { + if (iParser != NULL) + { + delete iParser; + iParser = NULL; + } + iParser = aParser; + if (iKeyFactory != NULL) + { + delete iKeyFactory; + iKeyFactory = NULL; + } + iKeyFactory = aFactory; + if (iEncoding != NULL) + { + User::Leave(KErrGeneral); + } + TInt len = aStream.ReadInt32L(); + iEncoding = HBufC8::NewL(aStream,len); + DoConstructL(); + } + +EXPORT_C void CSignedObject::ConstructL(const TPtrC8& aBinaryData, TSignedObjectParser* aParser, TKeyFactory* aFactory) + { + iParser = aParser; + iKeyFactory = aFactory; + //take a copy of the whole thing + iEncoding = aBinaryData.AllocL(); + DoConstructL(); + } + +EXPORT_C void CSignedObject::ConstructL(const CSignedObject& aSignedObject, TSignedObjectParser* aParser, TKeyFactory* aFactory) + { + iParser = aParser; + iKeyFactory = aFactory; + iEncoding = aSignedObject.iEncoding->AllocL(); + iFingerprint = aSignedObject.iFingerprint->AllocL(); + iSignature = aSignedObject.iSignature->AllocL(); + iSigningAlgorithm = CSigningAlgorithmIdentifier::NewL(*(aSignedObject.iSigningAlgorithm)); + } + +void CSignedObject::DoConstructL() + { + //generate your fingerprint + CMD5* hash = CMD5::NewL(); + CleanupStack::PushL(hash); + iFingerprint = hash->Hash(Encoding()).AllocL(); + CleanupStack::PopAndDestroy(); + //ask the parser for the signature + iSignature = iParser->SignatureL(Encoding()); + //ask the parser for the algorithm ID + iSigningAlgorithm = iParser->AlgorithmIdL(Encoding()); + } +*/ +//****************************************************************************************// +//certificate base +EXPORT_C CCertificate::~CCertificate() + { + delete iSerialNumber; + delete iValidityPeriod; + delete iSubjectPublicKeyInfo; + } + +EXPORT_C const TPtrC8 CCertificate::SerialNumber() const + { + return iSerialNumber->Des(); + } + +EXPORT_C const CValidityPeriod& CCertificate::ValidityPeriod() const + { + return *iValidityPeriod; + } + +EXPORT_C const CSubjectPublicKeyInfo& CCertificate::PublicKey() const + { + return *iSubjectPublicKeyInfo; + } + +EXPORT_C TKeyIdentifier CCertificate::KeyIdentifierL() const + { + if (iSubjectPublicKeyInfo->AlgorithmId() != ERSA) + { + User::Leave(KErrNotSupported); + } + + CRSAPublicKey* rsaKey = iKeyFactory->RSAPublicKeyL(iSubjectPublicKeyInfo->KeyData()); + CleanupStack::PushL(rsaKey); + TKeyIdentifier retVal; + KeyIdentifierUtil::RSAKeyIdentifierL(*rsaKey, retVal); + CleanupStack::PopAndDestroy(rsaKey); + return retVal; + }