sl@0: /* sl@0: * Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: //RSA signature result sl@0: EXPORT_C TBool CRSASignatureResult::operator== (const CRSASignatureResult& aResult) const sl@0: { sl@0: return ((*(iDigestAlgorithm) == *(aResult.iDigestAlgorithm)) && sl@0: (*(iDigest)==*(aResult.iDigest))); sl@0: } sl@0: sl@0: EXPORT_C CRSASignatureResult::~CRSASignatureResult() sl@0: { sl@0: delete iDigestAlgorithm; sl@0: delete iDigest; sl@0: } sl@0: sl@0: //validity period sl@0: EXPORT_C CValidityPeriod::CValidityPeriod(const CValidityPeriod& aValidityPeriod) sl@0: :iStart(aValidityPeriod.iStart), iFinish(aValidityPeriod.iFinish) sl@0: { sl@0: } sl@0: sl@0: EXPORT_C CValidityPeriod::CValidityPeriod() sl@0: { sl@0: } sl@0: sl@0: EXPORT_C TBool CValidityPeriod::Valid(const TTime& aTime) const sl@0: { sl@0: return ((iStart < aTime) && (iFinish > aTime)); sl@0: } sl@0: sl@0: EXPORT_C const TTime& CValidityPeriod::Start() const sl@0: { sl@0: return iStart; sl@0: } sl@0: sl@0: EXPORT_C const TTime& CValidityPeriod::Finish() const sl@0: { sl@0: return iFinish; sl@0: } sl@0: sl@0: //******************************************************************************// sl@0: //algorithm id sl@0: EXPORT_C CAlgorithmIdentifier* CAlgorithmIdentifier::NewL(const CAlgorithmIdentifier& aAlgorithmIdentifier) sl@0: { sl@0: CAlgorithmIdentifier* self = CAlgorithmIdentifier::NewLC(aAlgorithmIdentifier); sl@0: CleanupStack::Pop();//self sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CAlgorithmIdentifier* CAlgorithmIdentifier::NewLC(const CAlgorithmIdentifier& aAlgorithmIdentifier) sl@0: { sl@0: CAlgorithmIdentifier* self = new(ELeave) CAlgorithmIdentifier; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aAlgorithmIdentifier); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CAlgorithmIdentifier* CAlgorithmIdentifier::NewL(TAlgorithmId& aAlgorithmId, const TDesC8& aEncodedParams) sl@0: { sl@0: CAlgorithmIdentifier* self = CAlgorithmIdentifier::NewLC(aAlgorithmId, aEncodedParams); sl@0: CleanupStack::Pop();//self sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CAlgorithmIdentifier* CAlgorithmIdentifier::NewLC(TAlgorithmId& aAlgorithmId, const TDesC8& aEncodedParams) sl@0: { sl@0: CAlgorithmIdentifier* self = new(ELeave) CAlgorithmIdentifier(aAlgorithmId); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aEncodedParams); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CAlgorithmIdentifier::CAlgorithmIdentifier(TAlgorithmId& aAlgorithmId) sl@0: :iAlgorithmId(aAlgorithmId) sl@0: { sl@0: } sl@0: sl@0: EXPORT_C CAlgorithmIdentifier::CAlgorithmIdentifier() sl@0: { sl@0: } sl@0: sl@0: EXPORT_C void CAlgorithmIdentifier::ConstructL(const TDesC8& aEncodedParams) sl@0: { sl@0: iEncodedParams = aEncodedParams.AllocL(); sl@0: } sl@0: sl@0: sl@0: EXPORT_C TBool CAlgorithmIdentifier::operator==(const CAlgorithmIdentifier& aAlgorithmIdentifier) const sl@0: { sl@0: return ((iAlgorithmId == aAlgorithmIdentifier.iAlgorithmId) && sl@0: (*(iEncodedParams) == *(aAlgorithmIdentifier.iEncodedParams))); sl@0: } sl@0: sl@0: EXPORT_C TAlgorithmId CAlgorithmIdentifier::Algorithm() const sl@0: { sl@0: return iAlgorithmId; sl@0: } sl@0: sl@0: EXPORT_C TPtrC8 CAlgorithmIdentifier::EncodedParams() const sl@0: { sl@0: return iEncodedParams->Des(); sl@0: } sl@0: sl@0: EXPORT_C CAlgorithmIdentifier::~CAlgorithmIdentifier() sl@0: { sl@0: delete iEncodedParams; sl@0: } sl@0: sl@0: EXPORT_C void CAlgorithmIdentifier::ConstructL(const CAlgorithmIdentifier& aAlgorithmIdentifier) sl@0: { sl@0: iAlgorithmId = aAlgorithmIdentifier.iAlgorithmId; sl@0: iEncodedParams = aAlgorithmIdentifier.iEncodedParams->AllocL(); sl@0: } sl@0: sl@0: //***********************************************************************// sl@0: //signing algorithm id sl@0: EXPORT_C CSigningAlgorithmIdentifier* CSigningAlgorithmIdentifier::NewL(const CSigningAlgorithmIdentifier& aSigningAlgorithmIdentifier) sl@0: { sl@0: CSigningAlgorithmIdentifier* self = CSigningAlgorithmIdentifier::NewLC(aSigningAlgorithmIdentifier); sl@0: CleanupStack::Pop();//self sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CSigningAlgorithmIdentifier* CSigningAlgorithmIdentifier::NewLC(const CSigningAlgorithmIdentifier& aSigningAlgorithmIdentifier) sl@0: { sl@0: CSigningAlgorithmIdentifier* self = new(ELeave) CSigningAlgorithmIdentifier; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aSigningAlgorithmIdentifier); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C TBool CSigningAlgorithmIdentifier::operator == (const CSigningAlgorithmIdentifier& aSigningAlgorithmIdentifier) const sl@0: { sl@0: return ((*(iAsymmetricAlgorithm) == *(aSigningAlgorithmIdentifier.iAsymmetricAlgorithm)) && sl@0: (*(iDigestAlgorithm) == *(aSigningAlgorithmIdentifier.iDigestAlgorithm))); sl@0: } sl@0: sl@0: void CSigningAlgorithmIdentifier::ConstructL(const CSigningAlgorithmIdentifier& aAlgorithmIdentifier) sl@0: { sl@0: iAsymmetricAlgorithm = CAlgorithmIdentifier::NewL(*(aAlgorithmIdentifier.iAsymmetricAlgorithm)); sl@0: iDigestAlgorithm = CAlgorithmIdentifier::NewL(*(aAlgorithmIdentifier.iDigestAlgorithm)); sl@0: } sl@0: sl@0: EXPORT_C const CAlgorithmIdentifier& CSigningAlgorithmIdentifier::AsymmetricAlgorithm() const sl@0: { sl@0: return *iAsymmetricAlgorithm; sl@0: } sl@0: sl@0: EXPORT_C const CAlgorithmIdentifier& CSigningAlgorithmIdentifier::DigestAlgorithm() const sl@0: { sl@0: return *iDigestAlgorithm; sl@0: } sl@0: sl@0: EXPORT_C CSigningAlgorithmIdentifier::~CSigningAlgorithmIdentifier() sl@0: { sl@0: delete iAsymmetricAlgorithm; sl@0: delete iDigestAlgorithm; sl@0: } sl@0: sl@0: //************************************************************************// sl@0: //subject public key info sl@0: EXPORT_C CSubjectPublicKeyInfo* CSubjectPublicKeyInfo::NewL(const CSubjectPublicKeyInfo& aSubjectPublicKeyInfo) sl@0: { sl@0: CSubjectPublicKeyInfo* self = CSubjectPublicKeyInfo::NewLC(aSubjectPublicKeyInfo); sl@0: CleanupStack::Pop();//self sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CSubjectPublicKeyInfo* CSubjectPublicKeyInfo::NewLC(const CSubjectPublicKeyInfo& aSubjectPublicKeyInfo) sl@0: { sl@0: CSubjectPublicKeyInfo* self = new(ELeave) CSubjectPublicKeyInfo; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aSubjectPublicKeyInfo); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C TAlgorithmId CSubjectPublicKeyInfo::AlgorithmId() const sl@0: { sl@0: return iAlgId->Algorithm(); sl@0: } sl@0: sl@0: EXPORT_C const TPtrC8 CSubjectPublicKeyInfo::EncodedParams() const sl@0: { sl@0: return iAlgId->EncodedParams(); sl@0: } sl@0: sl@0: EXPORT_C const TPtrC8 CSubjectPublicKeyInfo::KeyData() const sl@0: { sl@0: return iEncodedKeyData->Des(); sl@0: } sl@0: sl@0: EXPORT_C CSubjectPublicKeyInfo::~CSubjectPublicKeyInfo() sl@0: { sl@0: delete iAlgId; sl@0: delete iEncodedKeyData; sl@0: } sl@0: sl@0: EXPORT_C void CSubjectPublicKeyInfo::ConstructL(const CSubjectPublicKeyInfo& aSubjectPublicKeyInfo) sl@0: { sl@0: iAlgId = CAlgorithmIdentifier::NewL(*(aSubjectPublicKeyInfo.iAlgId)); sl@0: iEncodedKeyData = aSubjectPublicKeyInfo.iEncodedKeyData->AllocL(); sl@0: } sl@0: sl@0: //******************************************************************// sl@0: //signed object parameters sl@0: sl@0: //ctors sl@0: sl@0: EXPORT_C CSigningKeyParameters* CSigningKeyParameters::NewL() sl@0: { sl@0: CSigningKeyParameters* self = new(ELeave) CSigningKeyParameters; sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CSigningKeyParameters* CSigningKeyParameters::NewLC() sl@0: { sl@0: CSigningKeyParameters* self = CSigningKeyParameters::NewL(); sl@0: CleanupStack::PushL(self); sl@0: return self; sl@0: } sl@0: sl@0: //copy ctors sl@0: EXPORT_C CSigningKeyParameters* CSigningKeyParameters::NewL(const CSigningKeyParameters& aParameters) sl@0: { sl@0: CSigningKeyParameters* self = CSigningKeyParameters::NewLC(aParameters); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CSigningKeyParameters* CSigningKeyParameters::NewLC(const CSigningKeyParameters& aParameters) sl@0: { sl@0: CSigningKeyParameters* self = new(ELeave) CSigningKeyParameters; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aParameters); sl@0: return self; sl@0: } sl@0: sl@0: void CSigningKeyParameters::ConstructL(const CSigningKeyParameters& aParameters) sl@0: { sl@0: SetDSAParamsL(*(aParameters.iDSAParams)); sl@0: } sl@0: sl@0: //dtor sl@0: EXPORT_C CSigningKeyParameters::~CSigningKeyParameters() sl@0: { sl@0: delete iDSAParams; sl@0: } sl@0: sl@0: EXPORT_C void CSigningKeyParameters::SetDSAParamsL(const CDSAParameters& aParams) sl@0: { sl@0: delete iDSAParams; sl@0: iDSAParams = NULL; // In case the next fails sl@0: sl@0: // Copy the TIntegers sl@0: RInteger p = RInteger::NewL(aParams.P()); sl@0: CleanupStack::PushL(p); sl@0: sl@0: RInteger q = RInteger::NewL(aParams.Q()); sl@0: CleanupStack::PushL(q); sl@0: sl@0: RInteger g = RInteger::NewL(aParams.G()); sl@0: CleanupStack::PushL(g); sl@0: sl@0: iDSAParams = CDSAParameters::NewL(p, q, g); sl@0: CleanupStack::Pop(3, &p); sl@0: } sl@0: sl@0: const CDSAParameters* CSigningKeyParameters::DSAParams() const sl@0: { sl@0: return iDSAParams; sl@0: } sl@0: sl@0: CSigningKeyParameters::CSigningKeyParameters() sl@0: { sl@0: } sl@0: sl@0: //******************************************************************// sl@0: //signed object sl@0: EXPORT_C TBool CSignedObject::VerifySignatureL(const TDesC8& aEncodedKey) const sl@0: { sl@0: const CAlgorithmIdentifier& algId = iSigningAlgorithm->AsymmetricAlgorithm(); sl@0: const CAlgorithmIdentifier& digestId = iSigningAlgorithm->DigestAlgorithm(); sl@0: sl@0: TBool verifyResult = EFalse; sl@0: if (algId.Algorithm() == EDSA) sl@0: { sl@0: if (digestId.Algorithm() != ESHA1) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: CSHA1* sha1 = CSHA1::NewL(); sl@0: CleanupStack::PushL(sha1); sl@0: TPtrC8 signedData = SignedDataL(); sl@0: TPtrC8 hash = sha1->Final(signedData); sl@0: verifyResult=VerifySignatureL(aEncodedKey, hash); sl@0: CleanupStack::PopAndDestroy(sha1);//hash sl@0: } sl@0: else sl@0: { sl@0: TRAPD(result, verifyResult = VerifyRSASignatureL(aEncodedKey)); sl@0: if (result==KErrNoMemory) // Leave if OOM, anything else is a verify sl@0: User::Leave(result); // error => verifyResult = EFalse sl@0: sl@0: } sl@0: sl@0: return verifyResult; sl@0: } sl@0: sl@0: EXPORT_C TBool CSignedObject::VerifySignatureL(const TDesC8& aEncodedKey, const TDesC8& aHash) const sl@0: { sl@0: const CAlgorithmIdentifier& algId = iSigningAlgorithm->AsymmetricAlgorithm(); sl@0: const CAlgorithmIdentifier& digestId = iSigningAlgorithm->DigestAlgorithm(); sl@0: sl@0: TBool verifyResult = EFalse; sl@0: if (algId.Algorithm() == EDSA) sl@0: { sl@0: if (digestId.Algorithm() != ESHA1) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: CDSAPublicKey* key = NULL; sl@0: if (algId.EncodedParams().Length() != 0) sl@0: { sl@0: key = iKeyFactory->DSAPublicKeyL(algId.EncodedParams(), aEncodedKey); sl@0: } sl@0: else sl@0: { sl@0: if (iParameters != NULL) sl@0: { sl@0: const CDSAParameters* params = iParameters->DSAParams(); sl@0: if (!params) sl@0: { sl@0: User::Leave(KErrArgument);//no params sl@0: } sl@0: else sl@0: { sl@0: key = iKeyFactory->DSAPublicKeyL(*params, aEncodedKey); sl@0: } sl@0: } sl@0: } sl@0: if (key == NULL) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: CleanupStack::PushL(key); sl@0: CDSAVerifier* verifier = CDSAVerifier::NewLC(*key); sl@0: CDSASignature* sig = iKeyFactory->DSASignatureL(Signature()); sl@0: CleanupStack::PushL(sig); sl@0: verifyResult = verifier->VerifyL(aHash, *sig); sl@0: CleanupStack::PopAndDestroy(3);// key, verifier, sig sl@0: } sl@0: else sl@0: { sl@0: TRAPD(result, verifyResult = VerifyRSASignatureL(aEncodedKey, aHash)); sl@0: if (result==KErrNoMemory) // Leave if OOM, anything else is a verify sl@0: User::Leave(result); // error => verifyResult = EFalse sl@0: sl@0: } sl@0: return verifyResult; sl@0: sl@0: } sl@0: sl@0: TBool CSignedObject::VerifyRSASignatureL(const TDesC8& aEncodedKey, const TDesC8& aHash) const sl@0: { sl@0: __UHEAP_MARK; sl@0: const CAlgorithmIdentifier& algId = iSigningAlgorithm->AsymmetricAlgorithm(); sl@0: const CAlgorithmIdentifier& digestId = iSigningAlgorithm->DigestAlgorithm(); sl@0: if (algId.Algorithm() != ERSA) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: //Get the public key sl@0: CRSAPublicKey* key = iKeyFactory->RSAPublicKeyL(aEncodedKey); sl@0: CleanupStack::PushL(key); sl@0: sl@0: CRSAPKCS1v15Verifier* verifier = CRSAPKCS1v15Verifier::NewLC(*key); sl@0: sl@0: RInteger sig = RInteger::NewL(Signature()); sl@0: CleanupStack::PushL(sig); sl@0: CRSASignature* theSignature = CRSASignature::NewL(sig); sl@0: CleanupStack::Pop(&sig); sl@0: CleanupStack::PushL(theSignature); sl@0: sl@0: HBufC8* publicDecryptOutput = verifier->InverseSignLC(*theSignature); sl@0: sl@0: //Now verify it sl@0: TPtrC8 hash(aHash); sl@0: CRSASignatureResult* decoder = iKeyFactory->RSASignatureResultL(digestId, hash); sl@0: CleanupStack::PushL(decoder); sl@0: sl@0: TPtr8 outputPtr(publicDecryptOutput->Des()); sl@0: TBool verified = decoder->VerifyL(outputPtr); sl@0: CleanupStack::PopAndDestroy(5, key); // decoder, publicDecryptOutput, theSignature sl@0: // verifier, key, sl@0: __UHEAP_MARKEND; sl@0: return (verified); sl@0: } sl@0: sl@0: // x509 signature comprises of an AlgID and the signed data itself, so a simple sl@0: // verify is not possible (the data returned from public decrypt will not match sl@0: // the original data signed because of the extra algID appendage). sl@0: // sl@0: TBool CSignedObject::VerifyRSASignatureL(const TDesC8& aEncodedKey) const sl@0: { sl@0: __UHEAP_MARK; sl@0: const CAlgorithmIdentifier& algId = iSigningAlgorithm->AsymmetricAlgorithm(); sl@0: const CAlgorithmIdentifier& digestId = iSigningAlgorithm->DigestAlgorithm(); sl@0: if (algId.Algorithm() != ERSA) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: CMessageDigest* digest = NULL; sl@0: switch(digestId.Algorithm()) sl@0: { sl@0: case EMD2: sl@0: { sl@0: digest = CMD2::NewL(); sl@0: break; sl@0: } sl@0: case EMD5: sl@0: { sl@0: digest = CMD5::NewL(); sl@0: break; sl@0: } sl@0: case ESHA1: sl@0: { sl@0: digest = CSHA1::NewL(); sl@0: break; sl@0: } sl@0: case ESHA224: sl@0: { sl@0: digest = CSHA2::NewL(E224Bit); sl@0: break; sl@0: } sl@0: case ESHA256: sl@0: { sl@0: digest = CSHA2::NewL(E256Bit); sl@0: break; sl@0: } sl@0: case ESHA384: sl@0: { sl@0: digest = CSHA2::NewL(E384Bit); sl@0: break; sl@0: } sl@0: case ESHA512: sl@0: { sl@0: digest = CSHA2::NewL(E512Bit); sl@0: break; sl@0: } sl@0: sl@0: default: sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: //Hash the data sl@0: CleanupStack::PushL(digest); sl@0: TPtrC8 hash = digest->Final(SignedDataL()); sl@0: TBool verifyResult=VerifyRSASignatureL(aEncodedKey, hash); sl@0: CleanupStack::PopAndDestroy(digest); sl@0: __UHEAP_MARKEND; sl@0: return verifyResult; sl@0: } sl@0: sl@0: EXPORT_C void CSignedObject::SetParametersL(const CSigningKeyParameters& aParameters) sl@0: { sl@0: delete iParameters; sl@0: iParameters = NULL; // In case next fails sl@0: iParameters = CSigningKeyParameters::NewL(aParameters); sl@0: } sl@0: sl@0: EXPORT_C const TPtrC8 CSignedObject::Signature() const sl@0: { sl@0: return iSignature->Des(); sl@0: } sl@0: sl@0: EXPORT_C const TPtrC8 CSignedObject::Encoding() const sl@0: { sl@0: return iEncoding->Des(); sl@0: } sl@0: sl@0: EXPORT_C const CSigningAlgorithmIdentifier& CSignedObject::SigningAlgorithm() const sl@0: { sl@0: return *iSigningAlgorithm; sl@0: } sl@0: sl@0: EXPORT_C const TPtrC8 CSignedObject::Fingerprint() const sl@0: { sl@0: return iFingerprint->Des(); sl@0: } sl@0: sl@0: EXPORT_C CSignedObject::~CSignedObject() sl@0: { sl@0: delete iParameters; sl@0: delete iKeyFactory; sl@0: delete iFingerprint; sl@0: delete iEncoding; sl@0: delete iSignature; sl@0: delete iSigningAlgorithm; sl@0: } sl@0: sl@0: EXPORT_C void CSignedObject::ExternalizeL(RWriteStream& aStream) const sl@0: { sl@0: aStream.WriteInt32L(iEncoding->Length()); sl@0: aStream.WriteL(*iEncoding); sl@0: } sl@0: sl@0: sl@0: //****************************************************************************************// sl@0: //certificate base sl@0: EXPORT_C CCertificate::~CCertificate() sl@0: { sl@0: delete iSerialNumber; sl@0: delete iValidityPeriod; sl@0: delete iSubjectPublicKeyInfo; sl@0: } sl@0: sl@0: EXPORT_C const TPtrC8 CCertificate::SerialNumber() const sl@0: { sl@0: return iSerialNumber->Des(); sl@0: } sl@0: sl@0: EXPORT_C const CValidityPeriod& CCertificate::ValidityPeriod() const sl@0: { sl@0: return *iValidityPeriod; sl@0: } sl@0: sl@0: EXPORT_C const CSubjectPublicKeyInfo& CCertificate::PublicKey() const sl@0: { sl@0: return *iSubjectPublicKeyInfo; sl@0: } sl@0: sl@0: EXPORT_C TKeyIdentifier CCertificate::KeyIdentifierL() const sl@0: { sl@0: if (iSubjectPublicKeyInfo->AlgorithmId() != ERSA) sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: } sl@0: sl@0: CRSAPublicKey* rsaKey = iKeyFactory->RSAPublicKeyL(iSubjectPublicKeyInfo->KeyData()); sl@0: CleanupStack::PushL(rsaKey); sl@0: TKeyIdentifier retVal; sl@0: KeyIdentifierUtil::RSAKeyIdentifierL(*rsaKey, retVal); sl@0: CleanupStack::PopAndDestroy(rsaKey); sl@0: return retVal; sl@0: }