pkiutilities/ocsp/src/responsecertinfo.cpp
changeset 0 164170e6151a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkiutilities/ocsp/src/responsecertinfo.cpp	Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,167 @@
+// Copyright (c) 2001-2009 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:
+// Implement response cert info object methods
+// 
+//
+
+#include "certid.h"
+#include <ocsp.h>
+
+#include <asn1dec.h>
+#include "ocsprequestandresponse.h"
+
+const TUint KNextUpdateTag = 0;
+const TUint KSingleExtensionsTag = 1;
+
+const TUint KGoodTag = 0;
+const TUint KRevokedTag = 1;
+const TUint KUnknownTag = 2;
+
+COCSPResponseCertInfo* COCSPResponseCertInfo::NewLC(CArrayPtr<TASN1DecGeneric>& aItems)
+	{
+	COCSPResponseCertInfo* self = new (ELeave) COCSPResponseCertInfo;
+	CleanupStack::PushL(self);
+	self->ConstructL(aItems);
+	return self;
+	}
+
+
+COCSPResponseCertInfo::~COCSPResponseCertInfo()
+	{
+	delete iNextUpdate;
+	delete iRevocationTime;
+	delete iCertID;
+	}
+
+
+EXPORT_C OCSP::TResult COCSPResponseCertInfo::Status() const
+	{
+	return iStatus;
+	}
+
+
+EXPORT_C TTime COCSPResponseCertInfo::ThisUpdate() const
+	{
+	return iThisUpdate;
+	}
+
+
+EXPORT_C const TTime* COCSPResponseCertInfo::NextUpdate() const
+	{
+	return iNextUpdate;
+	}
+
+
+EXPORT_C const TTime* COCSPResponseCertInfo::RevocationTime() const
+	{
+	return iRevocationTime;
+	}
+
+
+COCSPCertID& COCSPResponseCertInfo::CertID() const
+	{
+	return *iCertID;
+	}
+
+
+void COCSPResponseCertInfo::ConstructL(CArrayPtr<TASN1DecGeneric>& aItems)
+	{
+	// The CertID
+	iCertID = COCSPCertID::NewL(aItems.At(0)->Encoding());
+	
+	// The cert status - implicitly tagged
+	TASN1DecGeneric& statusDec = *aItems.At(1);
+	switch(statusDec.Tag())
+		{
+		case KGoodTag:
+			iStatus = OCSP::EGood;
+			break;
+		case KRevokedTag:
+			{
+			iStatus = OCSP::ERevoked;
+
+			// Get revocation time
+			TASN1DecSequence seqDec;
+			CArrayPtr<TASN1DecGeneric>* revokedInfo = seqDec.DecodeDERLC(statusDec, 1, 2);
+			TASN1DecGeneric& revocationTimeDec = *revokedInfo->At(0);
+			if (revocationTimeDec.Tag() != EASN1GeneralizedTime)
+				{
+				User::Leave(OCSP::EMalformedResponse);
+				}
+
+			TASN1DecGeneralizedTime decGT;
+			iRevocationTime = new (ELeave) TTime(decGT.DecodeDERL(revocationTimeDec));
+
+			CleanupStack::PopAndDestroy(revokedInfo);
+			break;
+			}
+		case KUnknownTag:
+			iStatus = OCSP::EUnknown;
+			break;
+		default:
+			User::Leave(OCSP::EMalformedResponse);
+		}
+		
+	// Carry on with thisUpdate
+	TASN1DecGeneralizedTime decGT;
+	iThisUpdate = decGT.DecodeDERL(*aItems.At(2));
+
+	// Optional bits...
+	TInt numItems = aItems.Count();
+	if (numItems > 3)
+		{
+		TInt nextItem = 3;
+
+		// Maybe nextUpdate is there too
+		TASN1DecGeneric& item4 = *aItems.At(3);
+		if (item4.Tag() == KNextUpdateTag)
+			{
+			++nextItem;
+			TASN1DecGeneralizedTime decGT;
+			TInt pos = 0;
+			iNextUpdate = new (ELeave) TTime (decGT.DecodeDERL(item4.GetContentDER(), pos));
+			}
+
+		// Check for extensions - we don't support any, but we need to leave if there are any marked 'critical'
+		if (nextItem < numItems)
+			{
+			TASN1DecGeneric& extnList = *aItems.At(nextItem);
+			if (extnList.Tag() == KSingleExtensionsTag)
+				{
+				// OK, we've got extensions, with an explicit tag.  Loop through them...
+				TASN1DecSequence decSeq;
+				TInt pos = 0;
+				CArrayPtr<TASN1DecGeneric>* extns = decSeq.DecodeDERLC(extnList.GetContentDER(), pos);
+				TInt numExts = extns->Count();
+				for (TInt extIndex = 0; extIndex < numExts; ++extIndex)
+					{
+					TASN1DecGeneric& ext = *extns->At(extIndex);
+					CArrayPtr<TASN1DecGeneric>* terms = decSeq.DecodeDERLC(ext);
+
+					// Check critical flag (may be absent - default value false
+					if (terms->Count() == 3)
+						{
+						TASN1DecBoolean boolDec;
+						if (boolDec.DecodeDERL(*terms->At(1)))
+							{
+							User::Leave(OCSP::EUnknownCriticalExtension);
+							}
+						}
+					CleanupStack::PopAndDestroy(); // Clean up 'terms'
+					}
+				CleanupStack::PopAndDestroy(); // Clean up 'extns'
+				}
+			}
+		}
+	}