pkiutilities/ocsp/src/requestencoder.cpp
changeset 0 164170e6151a
equal deleted inserted replaced
-1:000000000000 0:164170e6151a
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Implementation for OCSP request encoder object
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "requestencoder.h"
       
    19 #include "certid.h"
       
    20 #include "oids.h"
       
    21 #include "ocsp.h"
       
    22 #include "panic.h"
       
    23 #include <asn1enc.h>
       
    24 
       
    25 COCSPRequestEncoder* COCSPRequestEncoder::NewL(const COCSPRequest& aRequest)
       
    26 	{
       
    27 	COCSPRequestEncoder* self = new (ELeave) COCSPRequestEncoder();
       
    28 	CleanupStack::PushL(self);
       
    29 	self->ConstructL(aRequest);
       
    30 	CleanupStack::Pop(self);
       
    31 	return self;
       
    32 	}
       
    33 
       
    34 
       
    35 COCSPRequestEncoder::COCSPRequestEncoder()
       
    36 	{
       
    37 	}
       
    38 
       
    39 
       
    40 COCSPRequestEncoder::~COCSPRequestEncoder()
       
    41 	{
       
    42 	delete iEncoding;
       
    43 	}
       
    44 
       
    45 
       
    46 const TDesC8& COCSPRequestEncoder::Encoding() const
       
    47 	{
       
    48 	return *iEncoding;
       
    49 	}
       
    50 
       
    51 
       
    52 void COCSPRequestEncoder::ConstructL(const COCSPRequest& aRequest)
       
    53 	{
       
    54 	// Get encoder
       
    55 	CASN1EncBase* encoder = MakeOCSPRequestEncLC(aRequest);
       
    56 	
       
    57 	// Make buffer
       
    58 	TUint length = encoder->LengthDER();
       
    59 	iEncoding = HBufC8::NewMaxL(length);
       
    60 	TPtr8 buf = iEncoding->Des();
       
    61 	
       
    62 	// Write data
       
    63 	TUint position = 0;
       
    64 	encoder->WriteDERL(buf, position);
       
    65 	
       
    66 	CleanupStack::PopAndDestroy(encoder);
       
    67 	}
       
    68 
       
    69 
       
    70 // Static helper method - encapsulates a commonly-dupliciated peice of code
       
    71 void COCSPRequestEncoder::AddAndPopChildL(CASN1EncContainer& aParent, CASN1EncBase* aChild)
       
    72 	{
       
    73 	if (aChild)
       
    74 		{
       
    75 		aParent.AddChildL(aChild);
       
    76 		CleanupStack::Pop(aChild); // Now owned by aParent
       
    77 		}
       
    78 	}
       
    79 
       
    80 
       
    81 CASN1EncBase* COCSPRequestEncoder::MakeOCSPRequestEncLC(const COCSPRequest& aRequest)
       
    82 	{
       
    83 	CASN1EncSequence* ocspRequest = CASN1EncSequence::NewLC();
       
    84 
       
    85 	CASN1EncBase* tbsRequest = MakeTBSRequestEncLC(aRequest);
       
    86 	AddAndPopChildL(*ocspRequest, tbsRequest);
       
    87 
       
    88 	return ocspRequest;
       
    89 	}
       
    90 
       
    91 
       
    92 CASN1EncBase* COCSPRequestEncoder::MakeTBSRequestEncLC(const COCSPRequest& aRequest)
       
    93 	{
       
    94 	CASN1EncSequence* tbsRequest = CASN1EncSequence::NewLC();
       
    95 
       
    96 	// version - int 0, explicitly tagged as 0
       
    97 	// Excluded, since this is the default value, and we're using DER
       
    98 
       
    99 	// Skip GeneralName - we don't support that, and it is optional
       
   100 
       
   101 	// Cert requestList
       
   102 	CASN1EncBase* requestList = MakeRequestListEncLC(aRequest);
       
   103 	AddAndPopChildL(*tbsRequest, requestList);
       
   104 
       
   105 	// Global request extensions - optional, explicitly tagged [2]
       
   106 	CASN1EncBase* extensions = MakeRequestExtensionsEncLC(aRequest);
       
   107 	if (extensions)
       
   108 		{
       
   109 		CleanupStack::Pop(extensions); // Will be owned by explicit tag
       
   110 		CASN1EncExplicitTag* taggedExtensions = CASN1EncExplicitTag::NewLC(extensions, 2);
       
   111 		AddAndPopChildL(*tbsRequest, taggedExtensions);
       
   112 		}
       
   113 
       
   114 	return tbsRequest;
       
   115 	}
       
   116 
       
   117 
       
   118 CASN1EncBase* COCSPRequestEncoder::MakeRequestListEncLC(const COCSPRequest& aRequest)
       
   119 	{
       
   120 	CASN1EncSequence* requestList = CASN1EncSequence::NewLC();
       
   121 
       
   122 	// Request objects - one for each cert
       
   123 	TUint numCerts = aRequest.CertCount();
       
   124 	ASSERT(numCerts > 0);
       
   125 
       
   126 	for (TUint index = 0; index < numCerts; ++index)
       
   127 		{
       
   128 		const COCSPCertID& certId = aRequest.CertInfo(index).CertID();
       
   129 		CASN1EncBase* certEnc = MakeCertRequestEncLC(certId);
       
   130 		AddAndPopChildL(*requestList, certEnc);
       
   131 		}
       
   132 
       
   133 	return requestList;
       
   134 	}
       
   135 
       
   136 
       
   137 // Make encoder for the request object for a particular cert
       
   138 CASN1EncBase* COCSPRequestEncoder::MakeCertRequestEncLC(const COCSPCertID& aCertId)
       
   139 	{
       
   140 	CASN1EncSequence* request = CASN1EncSequence::NewLC();
       
   141 
       
   142 	// CertID
       
   143 	CASN1EncBase* certIdEnc = aCertId.EncoderLC();
       
   144 	AddAndPopChildL(*request, certIdEnc);
       
   145 
       
   146 	return request;
       
   147 	}
       
   148 
       
   149 
       
   150 CASN1EncBase* COCSPRequestEncoder::MakeRequestExtensionsEncLC(const COCSPRequest& aRequest)
       
   151 	{
       
   152 	CASN1EncSequence* extns = CASN1EncSequence::NewLC();
       
   153 
       
   154 	// Nonce extension (if present)
       
   155 	CASN1EncBase* nonceExtn = MakeNonceExtnEncLC(aRequest);
       
   156 	AddAndPopChildL(*extns, nonceExtn);
       
   157 
       
   158 	// Response type extentions
       
   159 	CASN1EncBase* responseTypeExtn = MakeResponseTypeExtnEncLC();
       
   160 	AddAndPopChildL(*extns, responseTypeExtn);
       
   161 
       
   162 	return extns;
       
   163 	}
       
   164 
       
   165 
       
   166 // Response type.  Is a sequence, with OID, default bool, and octet string
       
   167 // for contents.  In this case the octet string contains a sequence
       
   168 // of OIDs specifying the acceptable response types.
       
   169 CASN1EncBase* COCSPRequestEncoder::MakeResponseTypeExtnEncLC()
       
   170 	{
       
   171 	CASN1EncSequence* extn = CASN1EncSequence::NewLC();
       
   172 
       
   173 	// OID
       
   174 	CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KOCSPOidResponse);
       
   175 	AddAndPopChildL(*extn, oid);
       
   176 
       
   177 	// Skip Critical flag since we want default value FALSE and this is DER
       
   178 
       
   179 	// Acceptable responses - takes a bit of work, so bear with it...
       
   180 
       
   181 	// First, make sequence containing the OID for our response type
       
   182 	CASN1EncSequence* responses = CASN1EncSequence::NewLC();
       
   183 	CASN1EncObjectIdentifier* basic = CASN1EncObjectIdentifier::NewLC(KOCSPOidBasic);
       
   184 	AddAndPopChildL(*responses, basic);
       
   185 
       
   186 	// Second, encode this into a descriptor
       
   187 	TBuf8<KOCSPMaxOidEncodingLength> buf(responses->LengthDER());
       
   188 	TUint pos = 0;
       
   189 	responses->WriteDERL(buf, pos);
       
   190 	CleanupStack::PopAndDestroy(responses); // Finished with that now
       
   191 
       
   192 	// Third, make Octet string encoder from this data + add to extn
       
   193 	CASN1EncOctetString* value = CASN1EncOctetString::NewLC(buf);
       
   194 	AddAndPopChildL(*extn, value);
       
   195 
       
   196 	return extn;
       
   197 	}
       
   198 
       
   199 
       
   200 CASN1EncBase* COCSPRequestEncoder::MakeNonceExtnEncLC(const COCSPRequest& aRequest)
       
   201 	{
       
   202 	CASN1EncSequence* extn = NULL;
       
   203 
       
   204 	if (aRequest.Nonce())
       
   205 		{
       
   206 		extn = CASN1EncSequence::NewLC();
       
   207 
       
   208 		// OID
       
   209 		CASN1EncObjectIdentifier* oid = CASN1EncObjectIdentifier::NewLC(KOCSPOidNonce);
       
   210 		AddAndPopChildL(*extn, oid);
       
   211 		
       
   212 		// Skip Critical flag since we want default value FALSE and this is DER
       
   213 		
       
   214 		// Place nonce into extension
       
   215 		CASN1EncOctetString* value = CASN1EncOctetString::NewLC(*aRequest.Nonce());
       
   216 		AddAndPopChildL(*extn, value);
       
   217 		}
       
   218 		
       
   219 	return extn;
       
   220 	}