--- /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 <asn1dec.h>
+#include <asn1enc.h>
+#include <x509cert.h>
+
+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<TASN1DecGeneric>* 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;
+ }