pkiutilities/ocsp/src/responsecertinfo.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 26 Jan 2010 15:20:08 +0200
changeset 0 164170e6151a
permissions -rw-r--r--
Revision: 201004

// 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'
				}
			}
		}
	}