diff -r 000000000000 -r 95b198f216e5 omadrm/drmengine/roapstorage/src/certid.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omadrm/drmengine/roapstorage/src/certid.cpp Thu Dec 17 08:52:27 2009 +0200 @@ -0,0 +1,176 @@ +/* +* Copyright (c) 2002-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: ?Description +* +*/ + + +#include "certid.h" +#include "bigint.h" + +#include +#include +#include + +COCSPCertID* COCSPCertID::NewL(const CX509Certificate& aSubject, const CX509Certificate& aIssuer) + { + COCSPCertID* self = new (ELeave) COCSPCertID; + CleanupStack::PushL(self); + self->ConstructL(aSubject, aIssuer); + CleanupStack::Pop(self); + return self; + } + + +void COCSPCertID::ConstructL(const CX509Certificate& aSubject, const CX509Certificate& aIssuer) + { + CSHA1* sha1 = CSHA1::NewL(); + CleanupStack::PushL(sha1); + + // Hash of DER encoding of IssuerName from subject cert (including tag and length) + const TPtrC8* issuerNameDER = aSubject.DataElementEncoding(CX509Certificate::EIssuerName); + if (!issuerNameDER) + { + User::Leave(KErrArgument); + } + + iIssuerNameHash.Copy(sha1->Hash(*issuerNameDER)); + + // We'll ignore the 'number of unused bits' octet, since this is what everyone does, even + // though strictly speaking the OCSP spec says to include it. This has been discussed on + // the PKIX mailing list. + sha1->Reset(); + TPtrC8 subjectPublicKeyContents(aIssuer.PublicKey().KeyData()); + iIssuerKeyHash.Copy(sha1->Hash(subjectPublicKeyContents)); + + CleanupStack::PopAndDestroy(sha1); + + // Set serial number from subject + iSerialNumber.Set(aSubject.SerialNumber()); + } + + +COCSPCertID* COCSPCertID::NewL(const TDesC8& aBinaryData) + { + COCSPCertID* self = new (ELeave) COCSPCertID(); + CleanupStack::PushL(self); + self->ConstructL(aBinaryData); + CleanupStack::Pop(self); + return self; + } + + +void COCSPCertID::ConstructL(const TDesC8& aBinaryData) + { + // Check the tag + TASN1DecGeneric decGen(aBinaryData); + decGen.InitL(); + if (decGen.Tag() != EASN1Sequence) + { + User::Leave(KErrArgument); + } + + // Decode the sequence into 4 bits + TASN1DecSequence decSeq; + CArrayPtr* items = decSeq.DecodeDERLC(decGen, 4, 4); + + // First part - the hash algorithm - check for SHA1, no more needed + /* + CX509AlgorithmIdentifier* algID = CX509AlgorithmIdentifier::NewLC(items->At(0)->Encoding()); + if (algID->Algorithm() != ESHA1) + { + User::Leave(KErrArgument); + } + CleanupStack::PopAndDestroy(algID); + */ + + // Next parts - issuerNameHash and issuerKeyHash + TASN1DecOctetString decOS; + + HBufC8* temp = decOS.DecodeDERL(*items->At(1)); + iIssuerNameHash.Copy(*temp); + delete temp; + + temp = decOS.DecodeDERL(*items->At(2)); + iIssuerKeyHash.Copy(*temp); + delete temp; + + // Lastly, the certificate serial number - just copy a reference to the encoded data + iSerialNumber.Set(items->At(3)->GetContentDER()); + + CleanupStack::PopAndDestroy(); // items + } + + +// Construct ASN1 encoding object for the CertID data +CASN1EncBase* COCSPCertID::EncoderLC() const + { + CASN1EncSequence* certID = CASN1EncSequence::NewLC(); + + // AlgId is a sequence, containing oid and null (both specific to SHA1) + CASN1EncSequence* algEnc = CASN1EncSequence::NewLC(); + CASN1EncObjectIdentifier* algOidEnc = CASN1EncObjectIdentifier::NewLC(KSHA1); + algEnc->AddChildL(algOidEnc); + CleanupStack::Pop(); // algOidEnc, now owned by algEnc + CASN1EncNull* nullEnc = CASN1EncNull::NewLC(); + algEnc->AddChildL(nullEnc); + CleanupStack::Pop(); // nullEnc, now owned by algEnc + certID->AddChildL(algEnc); + CleanupStack::Pop(); // algEnc, now owned by certID + + // issuerNameHash + CASN1EncOctetString* name = CASN1EncOctetString::NewLC(iIssuerNameHash); + certID->AddChildL(name); + CleanupStack::Pop(); // name, now owned by certID + + // issuerKeyHash + CASN1EncOctetString* issuer = CASN1EncOctetString::NewLC(iIssuerKeyHash); + certID->AddChildL(issuer); + CleanupStack::Pop(); // issuer, now owned by certID + + // serialNumber +#ifdef SYMBIAN_CRYPTO + RInteger serialNumber = RInteger::NewL(iSerialNumber); + CleanupStack::PushL(serialNumber); +#else + CInteger& serialNumber = *CInteger::NewLC(iSerialNumber); +#endif + CASN1EncBigInt* snEnc = CASN1EncBigInt::NewLC(serialNumber); + certID->AddChildL(snEnc); + CleanupStack::Pop(); // snEnc, now owned by certID; + CleanupStack::PopAndDestroy(); // serialNumber + + return certID; + } + + +TBool COCSPCertID::operator==(const COCSPCertID& rhs) const + { + if (iIssuerNameHash == rhs.iIssuerNameHash + && iIssuerKeyHash == rhs.iIssuerKeyHash + && iSerialNumber == rhs.iSerialNumber) + { + return ETrue; + } + else + { + return EFalse; + } + } + + +TPtrC8 COCSPCertID::SerialNumber() const + { + return iSerialNumber; + }