25 #define OCSP_CONTENT_TYPE_REQ "application/ocsp-request"
26 #define OCSP_CONTENT_TYPE_REQ_LEN 24
27 #define OCSP_CONTENT_TYPE_RESP "application/ocsp-response"
28 #define OCSP_CONTENT_TYPE_RESP_LEN 25
33 OCSPRESPONSE_TYPE_NONE,
34 OCSPRESPONSE_TYPE_OCSP,
35 OCSPRESPONSE_TYPE_LAST
40 enum { OCSP_RESP_SUCCESSFUL, OCSP_RESP_MALFORMEDREQUEST,
41 OCSP_RESP_INTERNALERROR, OCSP_RESP_TRYLATER, OCSP_RESP_DUMMY,
42 OCSP_RESP_SIGREQUIRED, OCSP_RESP_UNAUTHORISED };
48 OCSPRESPONSE_TYPE responseType;
65 const void *responseData,
69 assert(
isReadPtr( responseData, responseDataLength ) );
78 memcpy( sessionInfoPtr->receiveBuffer, responseData,
80 sessionInfoPtr->receiveBufEnd = responseDataLength;
81 ( void ) writePkiDatagram( sessionInfoPtr, OCSP_CONTENT_TYPE_RESP,
82 OCSP_CONTENT_TYPE_RESP_LEN );
89 IN_BUFFER( requestNonceLength )
const void *requestNonce,
95 assert(
isReadPtr( requestNonce, requestNonceLength ) );
98 REQUIRES( requestNonceLength > 0 && \
107 CRYPT_MAX_HASHSIZE );
121 if( requestNonceLength == responseMsgData.
length && \
122 !memcmp( requestNonce, responseMsgData.data, requestNonceLength ) )
138 { NULL, 0 }, { NULL, 0 }
155 sessionInfoPtr->receiveBufSize );
158 CRYPT_ICERTFORMAT_DATA );
163 "Couldn't get OCSP request data from OCSP request "
166 sessionInfoPtr->receiveBufEnd = msgData.
length;
168 sessionInfoPtr->receiveBufEnd );
171 return( writePkiDatagram( sessionInfoPtr, OCSP_CONTENT_TYPE_REQ,
172 OCSP_CONTENT_TYPE_REQ_LEN ) );
183 BYTE nonceBuffer[ CRYPT_MAX_HASHSIZE + 8 ];
190 status = readPkiDatagram( sessionInfoPtr );
194 sessionInfoPtr->receiveBufEnd );
202 sMemConnect( &stream, sessionInfoPtr->receiveBuffer,
203 sessionInfoPtr->receiveBufEnd );
204 readSequence( &stream, NULL );
208 sMemDisconnect( &stream );
211 "Invalid OCSP response status data" ) );
220 case OCSP_RESP_SUCCESSFUL:
224 case OCSP_RESP_TRYLATER:
225 errorString =
"Try again later";
229 case OCSP_RESP_SIGREQUIRED:
230 errorString =
"Signed OCSP request required";
234 case OCSP_RESP_UNAUTHORISED:
235 errorString =
"Client isn't authorised to perform query";
240 errorString =
"Unknown error";
246 sMemDisconnect( &stream );
249 "OCSP server returned status %d: %s",
250 errorCode, errorString ) );
256 readConstructed( &stream, NULL, 0 );
257 readSequence( &stream, NULL );
258 readOID( &stream, ocspOIDinfo,
260 status = readGenericHole( &stream, &length, 16,
DEFAULT_TAG );
263 sMemDisconnect( &stream );
266 "Invalid OCSP response data header" ) );
268 status = importCertFromStream( &stream, &iCertResponse,
271 sMemDisconnect( &stream );
286 status = checkNonce( iCertResponse, msgData.data, msgData.
length );
302 "OCSP response doesn't contain a nonce" : \
303 "OCSP response nonce doesn't match the one in the "
309 sessionInfoPtr->iCertResponse = iCertResponse;
324 #define RESPONSE_SIZE 5
327 0x30, 0x03, 0x0A, 0x01, 0x01
330 0x30, 0x03, 0x0A, 0x01, 0x02
348 status = readPkiDatagram( sessionInfoPtr );
352 sessionInfoPtr->receiveBufEnd );
364 sMemConnect( &stream, sessionInfoPtr->receiveBuffer,
365 sessionInfoPtr->receiveBufEnd );
366 readSequence( &stream, NULL );
367 readSequence( &stream, NULL );
368 if( peekTag( &stream ) ==
MAKE_CTAG( 0 ) )
369 readUniversal( &stream );
370 if( peekTag( &stream ) ==
MAKE_CTAG( 1 ) )
371 readUniversal( &stream );
372 readSequence( &stream, NULL );
373 status = readSequence( &stream, NULL );
374 sMemDisconnect( &stream );
381 sessionInfoPtr->receiveBuffer,
382 sessionInfoPtr->receiveBufEnd,
389 sendErrorResponse( sessionInfoPtr, respBadRequest, RESPONSE_SIZE );
402 sendErrorResponse( sessionInfoPtr, respIntError, RESPONSE_SIZE );
407 CRYPT_IATTRIBUTE_OCSPREQUEST );
412 sendErrorResponse( sessionInfoPtr, respIntError, RESPONSE_SIZE );
415 "Couldn't create OCSP response from request" ) );
417 sessionInfoPtr->iCertResponse = createInfo.
cryptHandle;
428 int responseLength, responseDataLength,
status;
439 sessionInfoPtr->cryptKeyset );
442 sendErrorResponse( sessionInfoPtr, respIntError, RESPONSE_SIZE );
445 "Couldn't check OCSP request against certificate "
451 sessionInfoPtr->privateKey );
458 sendErrorResponse( sessionInfoPtr, respIntError, RESPONSE_SIZE );
461 "Couldn't create signed OCSP response" ) );
463 responseDataLength = msgData.
length;
466 sMemOpen( &stream, sessionInfoPtr->receiveBuffer,
467 sessionInfoPtr->receiveBufSize );
469 sizeofObject( responseDataLength );
471 sizeofObject( sizeofObject( responseLength ) ) );
473 writeConstructed( &stream, sizeofObject( responseLength ), 0 );
474 writeSequence( &stream, responseLength );
476 writeOctetStringHole( &stream, responseDataLength,
DEFAULT_TAG );
479 status = exportCertToStream( &stream, sessionInfoPtr->iCertResponse,
482 sessionInfoPtr->receiveBufEnd = stell( &stream );
483 sMemDisconnect( &stream );
486 sendErrorResponse( sessionInfoPtr, respIntError, RESPONSE_SIZE );
490 sessionInfoPtr->receiveBufEnd );
493 return( writePkiDatagram( sessionInfoPtr, OCSP_CONTENT_TYPE_RESP,
494 OCSP_CONTENT_TYPE_RESP_LEN ) );
513 status = sendClientRequest( sessionInfoPtr );
515 status = readServerResponse( sessionInfoPtr );
527 status = readClientRequest( sessionInfoPtr );
529 status = sendServerResponse( sessionInfoPtr );
549 assert(
isReadPtr( data,
sizeof(
int ) ) );
560 CRYPT_ICERTFORMAT_DATA );
574 &msgData, CRYPT_IATTRIBUTE_RESPONDERURL );
583 sessionInfoPtr->iCertRequest = ocspRequest;
605 SESSION_NEEDS_PRIVKEYCERT | \
606 SESSION_NEEDS_KEYSET,
617 sessionInfoPtr->transactFunction = serverTransact;
619 sessionInfoPtr->transactFunction = clientTransact;
620 sessionInfoPtr->setAttributeFunction = setAttributeFunction;