diff -r 000000000000 -r 164170e6151a cms/src/CCMSX509Certificate.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cms/src/CCMSX509Certificate.cpp Tue Jan 26 15:20:08 2010 +0200 @@ -0,0 +1,624 @@ +/* +* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: X.509 Certificate type +* +*/ + + +// INCLUDE FILES +#include "CCMSX509Certificate.h" +#include "CCMSX509AlgorithmIdentifier.h" +#include "CCMSX509Validity.h" +#include "CCMSX509SubjectPublicKeyInfo.h" +#include +#include + +// CONSTANTS +const TInt KVersion2 = 1; +const TInt KVersion3 = 2; +const TTagType KVersionTag = 0; +const TTagType KIssuerUniqueIdentifierTag = 1; +const TTagType KSubjectUniqueIdentifierTag = 2; +const TInt KToBeSignedItemsMin = 6; +const TInt KToBeSignedItemsMax = 10; +const TInt KDefaultGranularity = 1; + +// ============================ MEMBER FUNCTIONS =============================== + +// Destructor +CCMSX509Certificate::CCertificateData::~CCertificateData() + { + delete iSerialNumber; + delete iSignature; + delete iIssuer; + delete iValidity; + delete iSubject; + delete iSubjectPublicKeyInfo; + delete iIssuerUniqueIdentifier; + delete iSubjectUniqueIdentifier; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::CCMSX509Certificate +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +EXPORT_C CCMSX509Certificate::CCMSX509Certificate( ) + { + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CCMSX509Certificate::ConstructL( + const TDesC8& aSerialNumber, + const CCMSX509AlgorithmIdentifier& aSignature, + const CX500DistinguishedName& aIssuer, + const CCMSX509Validity& aValidity, + const CX500DistinguishedName& aSubject, + const CCMSX509SubjectPublicKeyInfo& aSubjectPublicKeyInfo, + const CCMSX509AlgorithmIdentifier& aAlgorithmIdentifier, + const TDesC8& aEncrypted ) + { + BaseConstructL( aAlgorithmIdentifier, aEncrypted ); + iData = new( ELeave ) CCertificateData; + SetSerialNumberL( aSerialNumber ); + SetSignatureL( aSignature ); + SetIssuerL( aIssuer ); + SetValidityL( aValidity ); + SetSubjectL( aSubject ); + SetSubjectPublicKeyInfoL( aSubjectPublicKeyInfo ); + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CCMSX509Certificate::ConstructL( + const CX509Certificate& aCertificate ) + { + SetDataL( aCertificate ); + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +EXPORT_C void CCMSX509Certificate::ConstructL( ) + { + // creating empty/default values + CArrayPtrFlat< CX520AttributeTypeAndValue >* elements = new( ELeave ) + CArrayPtrFlat< CX520AttributeTypeAndValue >( KDefaultGranularity ); + CleanupStack::PushL( elements ); + + iData = new( ELeave ) CCertificateData; + iData->iSerialNumber = KNullDesC8().AllocL(); + iData->iSignature = CCMSX509AlgorithmIdentifier::NewL(); + iData->iIssuer = CX500DistinguishedName::NewL( *elements ); + iData->iValidity = CCMSX509Validity::NewL(); + iData->iSubject = CX500DistinguishedName::NewL( *elements ); + iData->iSubjectPublicKeyInfo = CCMSX509SubjectPublicKeyInfo::NewL(); + + CleanupStack::PopAndDestroy( elements ); + + iAlgorithmIdentifier = CCMSX509AlgorithmIdentifier::NewL(); + iEncrypted = KNullDesC8().AllocL(); + + } + + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CCMSX509Certificate* +CCMSX509Certificate::NewL() + { + // creating with empty values + CCMSX509Certificate* self = + new( ELeave ) CCMSX509Certificate(); + CleanupStack::PushL( self ); + self->ConstructL( ); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CCMSX509Certificate* +CCMSX509Certificate::NewL( + const TDesC8& aSerialNumber, + const CCMSX509AlgorithmIdentifier& aSignature, + const CX500DistinguishedName& aIssuer, + const CCMSX509Validity& aValidity, + const CX500DistinguishedName& aSubject, + const CCMSX509SubjectPublicKeyInfo& aSubjectPublicKeyInfo, + const CCMSX509AlgorithmIdentifier& aAlgorithmIdentifier, + const TDesC8& aEncrypted ) + { + CCMSX509Certificate* self = + new( ELeave ) CCMSX509Certificate(); + CleanupStack::PushL( self ); + self->ConstructL( aSerialNumber, aSignature, aIssuer, aValidity, aSubject, + aSubjectPublicKeyInfo, aAlgorithmIdentifier, aEncrypted ); + CleanupStack::Pop(); + + return self; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CCMSX509Certificate* +CCMSX509Certificate::NewL( + const CX509Certificate& aCertificate ) + { + CCMSX509Certificate* self = + new( ELeave ) CCMSX509Certificate(); + CleanupStack::PushL( self ); + self->ConstructL( aCertificate ); + CleanupStack::Pop(); + + return self; + } + +// Destructor +CCMSX509Certificate::~CCMSX509Certificate() + { + delete iData; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::DecodeL +// Decrypts raw data to this instance +// ----------------------------------------------------------------------------- +void CCMSX509Certificate::DecodeL( const TDesC8& aRawData ) + { + CCMSX509AlgorithmIdentifier* algId = NULL; + HBufC8* encrypted = NULL; + TASN1DecGeneric dataDecoder = + DecodeSignatureL( aRawData, algId, encrypted ); + + CleanupStack::PushL( algId ); + CleanupStack::PushL( encrypted ); + + CArrayPtr< TASN1DecGeneric >* itemList = DecodeSequenceLC( + dataDecoder.Encoding(), KToBeSignedItemsMin, KToBeSignedItemsMax ); + + CCertificateData* data = new( ELeave ) CCertificateData(); + CleanupStack::PushL( data ); + + TInt sequenceCounter = 0; + + // decode version + TASN1DecGeneric* taggedVersion = itemList->At( sequenceCounter ); + if( ( taggedVersion->Tag() == KVersionTag ) && + ( taggedVersion->Class() == EContextSpecific ) ) + { + TASN1DecGeneric version( taggedVersion->GetContentDER() ); + version.InitL(); + TASN1DecInteger intDecoder; + data->iVersion = + intDecoder.DecodeDERShortL( version ); + sequenceCounter++; + } + + // decode serialNumber + data->iSerialNumber = + itemList->At( sequenceCounter++ )->GetContentDER().AllocL(); + + // decode signature + data->iSignature = CCMSX509AlgorithmIdentifier::NewL(); + data->iSignature->DecodeL( itemList->At( sequenceCounter++)->Encoding() ); + + // decode issuer + data->iIssuer = CX500DistinguishedName::NewL( + itemList->At( sequenceCounter++ )->Encoding() ); + + // decode validity + data->iValidity = CCMSX509Validity::NewL(); + data->iValidity->DecodeL( itemList->At( sequenceCounter++ )->Encoding() ); + + // decode subject + data->iSubject = CX500DistinguishedName::NewL( + itemList->At( sequenceCounter++ )->Encoding() ); + + // decode subjectPublicKeyInfo + data->iSubjectPublicKeyInfo = CCMSX509SubjectPublicKeyInfo::NewL(); + data->iSubjectPublicKeyInfo->DecodeL( + itemList->At( sequenceCounter++ )->Encoding() ); + + // decode issuerUniqueIdentifier, if it exists + TInt itemCount = itemList->Count(); + TASN1DecBitString bsDecoder; + if( sequenceCounter < itemCount ) + { + TASN1DecGeneric* taggedIssuerUniqueIdentifier = + itemList->At( sequenceCounter ); + if( taggedIssuerUniqueIdentifier->Tag() == KIssuerUniqueIdentifierTag ) + { + data->iIssuerUniqueIdentifier = + bsDecoder.ExtractOctetStringL( *taggedIssuerUniqueIdentifier ); + sequenceCounter++; + } + } + + // decode subjectUniqueIdentifier, if it exists + if( sequenceCounter < itemCount ) + { + TASN1DecGeneric* taggedSubjectUniqueIdentifier = + itemList->At( sequenceCounter ); + if( taggedSubjectUniqueIdentifier->Tag() == KSubjectUniqueIdentifierTag ) + { + data->iSubjectUniqueIdentifier = + bsDecoder.ExtractOctetStringL( *taggedSubjectUniqueIdentifier ); + sequenceCounter++; + } + } + + // extensions are ignored + + // all done, change state + delete iAlgorithmIdentifier; + iAlgorithmIdentifier = algId; + delete iEncrypted; + iEncrypted = encrypted; + delete iData; + iData = data; + CleanupStack::Pop( data ); + CleanupStack::PopAndDestroy( itemList ); + CleanupStack::Pop( encrypted ); + CleanupStack::Pop( algId ); + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::EncoderLC +// Returns ASN1 encoder for this instance +// ----------------------------------------------------------------------------- + +CASN1EncBase* CCMSX509Certificate::EncoderLC() const + { + + // encode ToBeSigned part + CASN1EncBase* toBeSigned = ToBeSignedEncoderLC(); + + // sign + CASN1EncSequence* root = SignAndPopLC( toBeSigned ); + + return root; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::Version() +// Getter for Version +// ----------------------------------------------------------------------------- +EXPORT_C TInt CCMSX509Certificate::Version() const + { + return iData->iVersion; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::SerialNumber() +// Getter for SerialNumber +// ----------------------------------------------------------------------------- +EXPORT_C const TDesC8& CCMSX509Certificate::SerialNumber() const + { + return *( iData->iSerialNumber ); + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::Signature() +// Getter for signature +// ----------------------------------------------------------------------------- +EXPORT_C const CCMSX509AlgorithmIdentifier& CCMSX509Certificate::Signature() const + { + return *( iData->iSignature ); + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::Issuer() +// Getter for issuer +// ----------------------------------------------------------------------------- +EXPORT_C const CX500DistinguishedName& CCMSX509Certificate::Issuer() const + { + return *( iData->iIssuer ); + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::Validity() +// Getter for Validity +// ----------------------------------------------------------------------------- +EXPORT_C const CCMSX509Validity& CCMSX509Certificate::Validity() const + { + return *( iData->iValidity ); + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::Subject() +// Getter for subject +// ----------------------------------------------------------------------------- +EXPORT_C const CX500DistinguishedName& CCMSX509Certificate::Subject() const + { + return *( iData->iSubject ); + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::SubjectPublicKeyInfo() +// Getter for subjectPublicKeyInfo +// ----------------------------------------------------------------------------- +EXPORT_C const CCMSX509SubjectPublicKeyInfo& +CCMSX509Certificate::SubjectPublicKeyInfo() const + { + return *( iData->iSubjectPublicKeyInfo ); + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::IssuerUniqueIdentifier() +// Getter for issuerUniqueIdentifier +// ----------------------------------------------------------------------------- +EXPORT_C const TDesC8* CCMSX509Certificate::IssuerUniqueIdentifier() const + { + return iData->iIssuerUniqueIdentifier; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::SubjectUniqueIdentifier() +// Getter for subjectUniqueIdentifier +// ----------------------------------------------------------------------------- +EXPORT_C const TDesC8* CCMSX509Certificate::SubjectUniqueIdentifier() const + { + return iData->iSubjectUniqueIdentifier; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::SetVersion() +// Setter for version +// ----------------------------------------------------------------------------- +EXPORT_C void CCMSX509Certificate::SetVersion( const TInt aVersion ) + { + iData->iVersion = aVersion; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::SetSerialNumberL() +// Setter for serialNumber +// ----------------------------------------------------------------------------- +EXPORT_C void CCMSX509Certificate::SetSerialNumberL( const TDesC8& aSerialNumber ) + { + HBufC8* serialNumber = aSerialNumber.AllocLC(); + delete iData->iSerialNumber; + iData->iSerialNumber = serialNumber; + CleanupStack::Pop( serialNumber ); + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::SetSignatureL() +// Setter for signature +// ----------------------------------------------------------------------------- +EXPORT_C void CCMSX509Certificate::SetSignatureL( + const CCMSX509AlgorithmIdentifier& aSignature ) + { + CCMSX509AlgorithmIdentifier* signature = + CCMSX509AlgorithmIdentifier::NewL( aSignature.AlgorithmIdentifier() ); + CleanupStack::PushL( signature ); + const CAlgorithmIdentifier* digestIdentifier = + aSignature.DigestAlgorithm(); + if( digestIdentifier ) + { + signature->SetDigestAlgorithmL( digestIdentifier ); + } + CleanupStack::Pop( signature ); + delete iData->iSignature; + iData->iSignature = signature; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::SetIssuerL() +// Setter for issuer +// ----------------------------------------------------------------------------- +EXPORT_C void CCMSX509Certificate::SetIssuerL( + const CX500DistinguishedName& aIssuer ) + { + CX500DistinguishedName* issuer = CX500DistinguishedName::NewL( aIssuer ); + delete iData->iIssuer; + iData->iIssuer = issuer; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::SetValidityL() +// Setter for validity +// ----------------------------------------------------------------------------- +EXPORT_C void CCMSX509Certificate::SetValidityL( + const CCMSX509Validity& aValidity ) + { + CCMSX509Validity* validity = + CCMSX509Validity::NewL( aValidity.NotBefore(), aValidity.NotAfter() ); + delete iData->iValidity; + iData->iValidity = validity; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::SetSubjectL() +// Setter for subject +// ----------------------------------------------------------------------------- +EXPORT_C void CCMSX509Certificate::SetSubjectL( + const CX500DistinguishedName& aSubject ) + { + CX500DistinguishedName* subject = CX500DistinguishedName::NewL( aSubject ); + delete iData->iSubject; + iData->iSubject = subject; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::SetSubjectPublicKeyInfoL() +// Setter for subjectPublicKeyInfo +// ----------------------------------------------------------------------------- +EXPORT_C void CCMSX509Certificate::SetSubjectPublicKeyInfoL( + const CCMSX509SubjectPublicKeyInfo& aSubjectPublicKeyInfo ) + { + CCMSX509SubjectPublicKeyInfo* spkInfo = CCMSX509SubjectPublicKeyInfo::NewL( + aSubjectPublicKeyInfo.Algorithm(), + aSubjectPublicKeyInfo.SubjectPublicKey() ); + delete iData->iSubjectPublicKeyInfo; + iData->iSubjectPublicKeyInfo = spkInfo; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::SetIssuerUniqueIdentifierL() +// Setter for issuerUniqueIdentifier, make sure version is v2 or v3 +// ----------------------------------------------------------------------------- +EXPORT_C void CCMSX509Certificate::SetIssuerUniqueIdentifierL( + const TDesC8& aIssuerUniqueIdentifier ) + { + HBufC8* issuerUniqueIdentifier = aIssuerUniqueIdentifier.AllocL(); + delete iData->iIssuerUniqueIdentifier; + iData->iIssuerUniqueIdentifier = issuerUniqueIdentifier; + if( ( iData->iVersion > KVersion3 ) || ( iData->iVersion < KVersion2 ) ) + { + iData->iVersion = KVersion2; + } + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::SetSubjectUniqueIdentifierL() +// Setter for subjectUniqueIdentifier, make sure version is v2 or v3 +// ----------------------------------------------------------------------------- +EXPORT_C void CCMSX509Certificate::SetSubjectUniqueIdentifierL( + const TDesC8& aSubjectUniqueIdentifier ) + { + HBufC8* subjectUniqueIdentifier = aSubjectUniqueIdentifier.AllocL(); + delete iData->iSubjectUniqueIdentifier; + iData->iSubjectUniqueIdentifier = subjectUniqueIdentifier; + if( ( iData->iVersion > KVersion3 ) || ( iData->iVersion < KVersion2 ) ) + { + iData->iVersion = KVersion2; + } + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::ToBeSignedEncoderLC +// Returns ASN1 encoder for the the ToBeSigned part +// ----------------------------------------------------------------------------- + +CASN1EncBase* CCMSX509Certificate::ToBeSignedEncoderLC() const + { + CASN1EncSequence* root = CASN1EncSequence::NewLC(); + + // encode version + CASN1EncInt* version = CASN1EncInt::NewL( iData->iVersion ); + CASN1EncExplicitTag* taggedVersion = + CASN1EncExplicitTag::NewLC( version, KVersionTag ); + root->AddAndPopChildL( taggedVersion ); + + // encode serialNumber + CASN1EncOctetString* serialNumber = + CASN1EncOctetString::NewLC( *( iData->iSerialNumber ) ); + serialNumber->SetTag( EASN1Integer, EUniversal ); + root->AddAndPopChildL( serialNumber ); + + // encode signature + CASN1EncBase* signature = iData->iSignature->EncoderLC(); + root->AddAndPopChildL( signature ); + + // encode issuer + CASN1EncSequence* issuer = iData->iIssuer->EncodeASN1LC(); + root->AddAndPopChildL( issuer ); + + // encode validity + CASN1EncBase* validity = iData->iValidity->EncoderLC(); + root->AddAndPopChildL( validity ); + + // encode subject + CASN1EncSequence* subject = iData->iSubject->EncodeASN1LC(); + root->AddAndPopChildL( subject ); + + // encode subjectPublicKeyInfo + CASN1EncBase* spkInfo = iData->iSubjectPublicKeyInfo->EncoderLC(); + root->AddAndPopChildL( spkInfo ); + + if( iData->iIssuerUniqueIdentifier ) + { + CASN1EncBitString* iuIdentifier = + CASN1EncBitString::NewLC( *iData->iIssuerUniqueIdentifier ); + iuIdentifier->SetTag( KIssuerUniqueIdentifierTag ); + root->AddAndPopChildL( iuIdentifier ); + } + if( iData->iSubjectUniqueIdentifier ) + { + CASN1EncBitString* suIdentifier = + CASN1EncBitString::NewLC( *iData->iSubjectUniqueIdentifier ); + suIdentifier->SetTag( KSubjectUniqueIdentifierTag ); + root->AddAndPopChildL( suIdentifier ); + } + + return root; + } + +// ----------------------------------------------------------------------------- +// CCMSX509Certificate::SetDataL +// Copies the data from the CX509Certificate object +// ----------------------------------------------------------------------------- +void CCMSX509Certificate::SetDataL( const CX509Certificate& aCertificate ) + { + const CSigningAlgorithmIdentifier& signingAlgorithm = + aCertificate.SigningAlgorithm(); + CCMSX509AlgorithmIdentifier* algId = + CCMSX509AlgorithmIdentifier::NewL( signingAlgorithm.AsymmetricAlgorithm(), + signingAlgorithm.DigestAlgorithm() ); + CleanupStack::PushL( algId ); + + HBufC8* encrypted = aCertificate.Signature().AllocLC(); + + CCertificateData* data = new( ELeave ) CCertificateData(); + CleanupStack::PushL( data ); + + data->iVersion = aCertificate.Version(); + + data->iSerialNumber = aCertificate.SerialNumber().AllocL(); + + data->iSignature = CCMSX509AlgorithmIdentifier::NewL( + signingAlgorithm.AsymmetricAlgorithm(), + signingAlgorithm.DigestAlgorithm() ); + + data->iIssuer = CX500DistinguishedName::NewL( aCertificate.IssuerName() ); + + data->iValidity = CCMSX509Validity::NewL( aCertificate.ValidityPeriod() ); + + data->iSubject = CX500DistinguishedName::NewL( aCertificate.SubjectName() ); + + data->iSubjectPublicKeyInfo = CCMSX509SubjectPublicKeyInfo::NewL( + aCertificate.PublicKey() ); + + // all done, change state + delete iData; + iData = data; + delete iAlgorithmIdentifier; + iAlgorithmIdentifier = algId; + delete iEncrypted; + iEncrypted = encrypted; + CleanupStack::Pop( 3 ); // data, encrypted, algId + } + +// End of File