1 /****************************************************************************
2 * *
3 * cryptlib RTCS Session Management *
4 * Copyright Peter Gutmann 1999-2008 *
5 * *
6 ****************************************************************************/
7
8 #if defined( INC_ALL )
9 #include "crypt.h"
10 #include "asn1.h"
11 #include "asn1_ext.h"
12 #include "session.h"
13 #else
14 #include "crypt.h"
15 #include "enc_dec/asn1.h"
16 #include "enc_dec/asn1_ext.h"
17 #include "session/session.h"
18 #endif /* Compiler-specific includes */
19
20 #ifdef USE_RTCS
21
22 /* RTCS HTTP content types */
23
24 #define RTCS_CONTENT_TYPE_REQ "application/rtcs-request"
25 #define RTCS_CONTENT_TYPE_REQ_LEN 24
26 #define RTCS_CONTENT_TYPE_RESP "application/rtcs-response"
27 #define RTCS_CONTENT_TYPE_RESP_LEN 25
28
29 /* The action to take to process an RTCS request/response */
30
31 typedef enum {
32 ACTION_NONE, /* No processing */
33 ACTION_UNWRAP, /* Unwrap raw data */
34 ACTION_CRYPT, /* Decrypt data */
35 ACTION_SIGN, /* Sig.check data */
36 ACTION_LAST /* Last valid action type */
37 } ACTION_TYPE;
38
39 /* RTCS protocol state information. This is passed around various
40 subfunctions that handle individual parts of the protocol */
41
42 typedef struct {
43 /* State variable information. The nonce is copied from the request to
44 the response to prevent replay attacks */
45 BYTE nonce[ CRYPT_MAX_HASHSIZE + 8 ];
46 int nonceSize;
47 } RTCS_PROTOCOL_INFO;
48
49 /****************************************************************************
50 * *
51 * Utility Functions *
52 * *
53 ****************************************************************************/
54
55 /* Check for a valid-looking RTCS request/response header */
56
57 static const CMS_CONTENT_INFO FAR_BSS oidInfoSignedData = { 0, 3 };
58 static const CMS_CONTENT_INFO FAR_BSS oidInfoEnvelopedData = { 0, 3 };
59
60 static const OID_INFO FAR_BSS envelopeOIDinfo[] = {
61 { OID_CRYPTLIB_RTCSREQ, ACTION_UNWRAP },
62 { OID_CRYPTLIB_RTCSRESP, ACTION_UNWRAP },
63 { OID_CRYPTLIB_RTCSRESP_EXT, ACTION_UNWRAP },
64 { OID_CMS_SIGNEDDATA, ACTION_SIGN, &oidInfoSignedData },
65 { OID_CMS_ENVELOPEDDATA, ACTION_CRYPT, &oidInfoEnvelopedData },
66 { NULL, 0 }, { NULL, 0 }
67 };
68
69 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
checkRtcsHeader(IN_BUFFER (rtcsDataLength)const void * rtcsData,IN_LENGTH_SHORT const int rtcsDataLength,OUT_ENUM_OPT (ACTION)ACTION_TYPE * actionType)70 static int checkRtcsHeader( IN_BUFFER( rtcsDataLength ) const void *rtcsData,
71 IN_LENGTH_SHORT const int rtcsDataLength,
72 OUT_ENUM_OPT( ACTION ) ACTION_TYPE *actionType )
73 {
74 STREAM stream;
75 int status;
76
77 assert( isReadPtr( rtcsData, rtcsDataLength ) );
78 assert( isWritePtr( actionType, sizeof( ACTION_TYPE ) ) );
79
80 REQUIRES( rtcsDataLength > 0 && rtcsDataLength < MAX_INTLENGTH_SHORT );
81
82 /* Clear return value */
83 *actionType = ACTION_NONE;
84
85 /* We've got a valid response, check the CMS encapsulation */
86 sMemConnect( &stream, rtcsData, rtcsDataLength );
87 status = readCMSheader( &stream, envelopeOIDinfo,
88 FAILSAFE_ARRAYSIZE( envelopeOIDinfo, OID_INFO ),
89 NULL, READCMS_FLAG_NONE );
90 sMemDisconnect( &stream );
91 if( cryptStatusError( status ) )
92 return( status );
93 *actionType = status;
94 return( CRYPT_OK );
95 }
96
97 /****************************************************************************
98 * *
99 * Client-side Functions *
100 * *
101 ****************************************************************************/
102
103 /* Send a request to an RTCS server */
104
105 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
sendClientRequest(INOUT SESSION_INFO * sessionInfoPtr)106 static int sendClientRequest( INOUT SESSION_INFO *sessionInfoPtr )
107 {
108 MESSAGE_DATA msgData;
109 ERROR_INFO errorInfo;
110 int status;
111
112 assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
113
114 /* Get the encoded request data and wrap it up for sending */
115 setMessageData( &msgData, sessionInfoPtr->receiveBuffer,
116 sessionInfoPtr->receiveBufSize );
117 status = krnlSendMessage( sessionInfoPtr->iCertRequest,
118 IMESSAGE_CRT_EXPORT, &msgData,
119 CRYPT_ICERTFORMAT_DATA );
120 if( cryptStatusError( status ) )
121 {
122 retExt( status,
123 ( status, SESSION_ERRINFO,
124 "Couldn't get RTCS request data from RTCS request "
125 "object" ) );
126 }
127 status = envelopeWrap( sessionInfoPtr->receiveBuffer, msgData.length,
128 sessionInfoPtr->receiveBuffer,
129 sessionInfoPtr->receiveBufSize,
130 &sessionInfoPtr->receiveBufEnd,
131 CRYPT_FORMAT_CMS, CRYPT_CONTENT_RTCSREQUEST,
132 CRYPT_UNUSED, &errorInfo );
133 if( cryptStatusError( status ) )
134 {
135 retExtErr( status,
136 ( status, SESSION_ERRINFO, &errorInfo,
137 "Couldn't CMS-envelope RTCS request data: " ) );
138 }
139 DEBUG_DUMP_FILE( "rtcs_req", sessionInfoPtr->receiveBuffer,
140 sessionInfoPtr->receiveBufEnd );
141
142 /* Send the request to the responder */
143 return( writePkiDatagram( sessionInfoPtr, RTCS_CONTENT_TYPE_REQ,
144 RTCS_CONTENT_TYPE_REQ_LEN ) );
145 }
146
147 /* Read the response from the RTCS server */
148
149 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
readServerResponse(INOUT SESSION_INFO * sessionInfoPtr)150 static int readServerResponse( INOUT SESSION_INFO *sessionInfoPtr )
151 {
152 CRYPT_CERTIFICATE iCmsAttributes;
153 MESSAGE_CREATEOBJECT_INFO createInfo;
154 MESSAGE_DATA msgData;
155 ERROR_INFO errorInfo;
156 ACTION_TYPE actionType;
157 BYTE nonceBuffer[ CRYPT_MAX_HASHSIZE + 8 ];
158 int dataLength, sigResult, status;
159
160 assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
161
162 /* Read the response from the responder */
163 status = readPkiDatagram( sessionInfoPtr );
164 if( cryptStatusError( status ) )
165 return( status );
166 DEBUG_DUMP_FILE( "rtcs_resp", sessionInfoPtr->receiveBuffer,
167 sessionInfoPtr->receiveBufEnd );
168 status = checkRtcsHeader( sessionInfoPtr->receiveBuffer,
169 sessionInfoPtr->receiveBufEnd, &actionType );
170 if( cryptStatusError( status ) )
171 {
172 retExt( status,
173 ( status, SESSION_ERRINFO,
174 "Invalid RTCS response header" ) );
175 }
176 if( actionType != ACTION_SIGN )
177 {
178 retExt( CRYPT_ERROR_BADDATA,
179 ( CRYPT_ERROR_BADDATA, SESSION_ERRINFO,
180 "Unexpected RTCS encapsulation type %d", actionType ) );
181 }
182
183 /* Sig.check the data using the responder's key */
184 status = envelopeSigCheck( sessionInfoPtr->receiveBuffer,
185 sessionInfoPtr->receiveBufEnd,
186 sessionInfoPtr->receiveBuffer,
187 sessionInfoPtr->receiveBufSize, &dataLength,
188 CRYPT_UNUSED, &sigResult, NULL,
189 &iCmsAttributes, &errorInfo );
190 if( cryptStatusError( status ) )
191 {
192 retExtErr( status,
193 ( status, SESSION_ERRINFO, &errorInfo,
194 "Invalid CMS-enveloped RTCS response data: " ) );
195 }
196
197 /* Make sure that the nonce in the response matches the one in the
198 request */
199 setMessageData( &msgData, nonceBuffer, CRYPT_MAX_HASHSIZE );
200 status = krnlSendMessage( iCmsAttributes, IMESSAGE_GETATTRIBUTE_S,
201 &msgData, CRYPT_CERTINFO_CMS_NONCE );
202 krnlSendNotifier( iCmsAttributes, IMESSAGE_DECREFCOUNT );
203 if( cryptStatusOK( status ) )
204 {
205 MESSAGE_DATA responseMsgData;
206 BYTE responseNonceBuffer[ CRYPT_MAX_HASHSIZE + 8 ];
207
208 setMessageData( &responseMsgData, responseNonceBuffer,
209 CRYPT_MAX_HASHSIZE );
210 status = krnlSendMessage( sessionInfoPtr->iCertRequest,
211 IMESSAGE_GETATTRIBUTE_S, &responseMsgData,
212 CRYPT_CERTINFO_CMS_NONCE );
213 if( cryptStatusOK( status ) && \
214 ( msgData.length < 4 || \
215 msgData.length != responseMsgData.length || \
216 memcmp( msgData.data, responseMsgData.data, msgData.length ) ) )
217 status = CRYPT_ERROR_SIGNATURE;
218 }
219 krnlSendNotifier( sessionInfoPtr->iCertRequest, IMESSAGE_DECREFCOUNT );
220 sessionInfoPtr->iCertRequest = CRYPT_ERROR;
221 if( cryptStatusError( status ) )
222 {
223 /* The response doesn't contain a nonce or it doesn't match what
224 we sent, we can't trust it. The best error that we can return
225 here is a signature error to indicate that the integrity check
226 failed */
227 retExt( status,
228 ( status, SESSION_ERRINFO,
229 ( status != CRYPT_ERROR_SIGNATURE ) ? \
230 "RTCS response doesn't contain a nonce" : \
231 "RTCS response nonce doesn't match the one in the "
232 "request" ) );
233 }
234
235 /* Everything is OK, import the response */
236 setMessageCreateObjectIndirectInfo( &createInfo,
237 sessionInfoPtr->receiveBuffer, dataLength,
238 CRYPT_CERTTYPE_RTCS_RESPONSE );
239 status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
240 IMESSAGE_DEV_CREATEOBJECT_INDIRECT,
241 &createInfo, OBJECT_TYPE_CERTIFICATE );
242 if( cryptStatusError( status ) )
243 {
244 retExt( status,
245 ( status, SESSION_ERRINFO,
246 "Invalid RTCS response contents" ) );
247 }
248 sessionInfoPtr->iCertResponse = createInfo.cryptHandle;
249
250 return( CRYPT_OK );
251 }
252
253 /****************************************************************************
254 * *
255 * Server-side Functions *
256 * *
257 ****************************************************************************/
258
259 /* Read a request from an RTCS client */
260
261 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
readClientRequest(INOUT SESSION_INFO * sessionInfoPtr,INOUT RTCS_PROTOCOL_INFO * protocolInfo)262 static int readClientRequest( INOUT SESSION_INFO *sessionInfoPtr,
263 INOUT RTCS_PROTOCOL_INFO *protocolInfo )
264 {
265 MESSAGE_CREATEOBJECT_INFO createInfo;
266 MESSAGE_DATA msgData;
267 ERROR_INFO errorInfo;
268 ACTION_TYPE actionType;
269 int dataLength, status;
270
271 assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
272 assert( isWritePtr( protocolInfo, sizeof( RTCS_PROTOCOL_INFO ) ) );
273
274 /* Read the request data from the client. We don't write an error
275 response at this initial stage to prevent scanning/DOS attacks
276 (vir sapit qui pauca loquitur) */
277 status = readPkiDatagram( sessionInfoPtr );
278 if( cryptStatusError( status ) )
279 return( status );
280 DEBUG_DUMP_FILE( "rtcs_sreq", sessionInfoPtr->receiveBuffer,
281 sessionInfoPtr->receiveBufEnd );
282 status = checkRtcsHeader( sessionInfoPtr->receiveBuffer,
283 sessionInfoPtr->receiveBufEnd, &actionType );
284 if( cryptStatusError( status ) )
285 {
286 retExt( status,
287 ( status, SESSION_ERRINFO, "Invalid RTCS request header" ) );
288 }
289 if( actionType != ACTION_UNWRAP )
290 {
291 retExt( CRYPT_ERROR_BADDATA,
292 ( CRYPT_ERROR_BADDATA, SESSION_ERRINFO,
293 "Unexpected RTCS encapsulation type %d", actionType ) );
294 }
295 status = envelopeUnwrap( sessionInfoPtr->receiveBuffer,
296 sessionInfoPtr->receiveBufEnd,
297 sessionInfoPtr->receiveBuffer,
298 sessionInfoPtr->receiveBufSize, &dataLength,
299 CRYPT_UNUSED, &errorInfo );
300 if( cryptStatusError( status ) )
301 {
302 retExtErr( status,
303 ( status, SESSION_ERRINFO, &errorInfo,
304 "Invalid CMS-enveloped RTCS request data: " ) );
305 }
306
307 /* Create an RTCS response. We always create this since an empty
308 response is sent to indicate an error condition */
309 setMessageCreateObjectInfo( &createInfo, CRYPT_CERTTYPE_RTCS_RESPONSE );
310 status = krnlSendMessage( SYSTEM_OBJECT_HANDLE, IMESSAGE_DEV_CREATEOBJECT,
311 &createInfo, OBJECT_TYPE_CERTIFICATE );
312 if( cryptStatusError( status ) )
313 return( status );
314 sessionInfoPtr->iCertResponse = createInfo.cryptHandle;
315
316 /* Import the request as a cryptlib object and read the nonce from it */
317 setMessageCreateObjectIndirectInfo( &createInfo,
318 sessionInfoPtr->receiveBuffer, dataLength,
319 CRYPT_CERTTYPE_RTCS_REQUEST );
320 status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
321 IMESSAGE_DEV_CREATEOBJECT_INDIRECT,
322 &createInfo, OBJECT_TYPE_CERTIFICATE );
323 if( cryptStatusOK( status ) )
324 {
325 setMessageData( &msgData, protocolInfo->nonce, CRYPT_MAX_HASHSIZE );
326 status = krnlSendMessage( createInfo.cryptHandle,
327 IMESSAGE_GETATTRIBUTE_S, &msgData,
328 CRYPT_CERTINFO_CMS_NONCE );
329 if( cryptStatusOK( status ) )
330 protocolInfo->nonceSize = msgData.length;
331 else
332 {
333 /* We couldn't read the nonce, delete the request object prior
334 to exiting */
335 krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
336 }
337 }
338 if( cryptStatusError( status ) )
339 {
340 retExt( status,
341 ( status, SESSION_ERRINFO,
342 "Invalid RTCS request contents" ) );
343 }
344
345 /* Create an RTCS response and add the request information to it */
346 status = krnlSendMessage( sessionInfoPtr->iCertResponse,
347 IMESSAGE_SETATTRIBUTE,
348 &createInfo.cryptHandle,
349 CRYPT_IATTRIBUTE_RTCSREQUEST );
350 krnlSendNotifier( createInfo.cryptHandle, IMESSAGE_DECREFCOUNT );
351 if( cryptStatusError( status ) )
352 {
353 retExt( status,
354 ( status, SESSION_ERRINFO,
355 "Couldn't create RTCS response from request" ) );
356 }
357 return( CRYPT_OK );
358 }
359
360 /* Return a response to an RTCS client */
361
362 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
sendServerResponse(INOUT SESSION_INFO * sessionInfoPtr,INOUT RTCS_PROTOCOL_INFO * protocolInfo)363 static int sendServerResponse( INOUT SESSION_INFO *sessionInfoPtr,
364 INOUT RTCS_PROTOCOL_INFO *protocolInfo )
365 {
366 CRYPT_CERTIFICATE iCmsAttributes = CRYPT_UNUSED;
367 MESSAGE_DATA msgData;
368 ERROR_INFO errorInfo;
369 int status;
370
371 assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
372 assert( isWritePtr( protocolInfo, sizeof( RTCS_PROTOCOL_INFO ) ) );
373
374 /* Check the entries from the request against the certificate store and
375 sign the resulting status information ("Love, ken"). Note that
376 CRYPT_ERROR_INVALID is a valid return status for the sigcheck call
377 since it indicates that one (or more) of the certificates are
378 invalid */
379 status = krnlSendMessage( sessionInfoPtr->iCertResponse,
380 IMESSAGE_CRT_SIGCHECK, NULL,
381 sessionInfoPtr->cryptKeyset );
382 if( cryptStatusError( status ) && status != CRYPT_ERROR_INVALID )
383 {
384 retExt( status,
385 ( status, SESSION_ERRINFO,
386 "Couldn't check RTCS request against certificate "
387 "store" ) );
388 }
389
390 /* If there's a nonce present, create CMS attributes to contain it */
391 if( protocolInfo->nonceSize > 0 )
392 {
393 MESSAGE_CREATEOBJECT_INFO createInfo;
394
395 setMessageCreateObjectInfo( &createInfo,
396 CRYPT_CERTTYPE_CMS_ATTRIBUTES );
397 status = krnlSendMessage( SYSTEM_OBJECT_HANDLE,
398 IMESSAGE_DEV_CREATEOBJECT,
399 &createInfo, OBJECT_TYPE_CERTIFICATE );
400 if( cryptStatusError( status ) )
401 return( status );
402 iCmsAttributes = createInfo.cryptHandle;
403 setMessageData( &msgData, protocolInfo->nonce,
404 protocolInfo->nonceSize );
405 status = krnlSendMessage( iCmsAttributes, IMESSAGE_SETATTRIBUTE_S,
406 &msgData, CRYPT_CERTINFO_CMS_NONCE );
407 if( cryptStatusError( status ) )
408 {
409 krnlSendNotifier( iCmsAttributes, IMESSAGE_DECREFCOUNT );
410 return( status );
411 }
412 }
413
414 /* Extract the response data */
415 setMessageData( &msgData, sessionInfoPtr->receiveBuffer,
416 sessionInfoPtr->receiveBufSize );
417 status = krnlSendMessage( sessionInfoPtr->iCertResponse,
418 IMESSAGE_CRT_EXPORT, &msgData,
419 CRYPT_ICERTFORMAT_DATA );
420 if( cryptStatusError( status ) )
421 {
422 if( iCmsAttributes != CRYPT_UNUSED )
423 krnlSendNotifier( iCmsAttributes, IMESSAGE_DECREFCOUNT );
424 retExt( status,
425 ( status, SESSION_ERRINFO,
426 "Couldn't encode RTCS response" ) );
427 }
428
429 /* Sign the response data using the responder's key and send it to the
430 client */
431 status = envelopeSign( sessionInfoPtr->receiveBuffer, msgData.length,
432 sessionInfoPtr->receiveBuffer,
433 sessionInfoPtr->receiveBufSize,
434 &sessionInfoPtr->receiveBufEnd,
435 CRYPT_CONTENT_RTCSRESPONSE,
436 sessionInfoPtr->privateKey, iCmsAttributes,
437 &errorInfo );
438 if( iCmsAttributes != CRYPT_UNUSED )
439 krnlSendNotifier( iCmsAttributes, IMESSAGE_DECREFCOUNT );
440 if( cryptStatusError( status ) )
441 {
442 retExtErr( status,
443 ( status, SESSION_ERRINFO, &errorInfo,
444 "Couldn't CMS-envelope RTCS response: " ) );
445 }
446 DEBUG_DUMP_FILE( "rtcs_sresp", sessionInfoPtr->receiveBuffer,
447 sessionInfoPtr->receiveBufEnd );
448 return( writePkiDatagram( sessionInfoPtr, RTCS_CONTENT_TYPE_RESP,
449 RTCS_CONTENT_TYPE_RESP_LEN ) );
450 }
451
452 /****************************************************************************
453 * *
454 * Init/Shutdown Functions *
455 * *
456 ****************************************************************************/
457
458 /* Exchange data with an RTCS client/server */
459
460 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
clientTransact(INOUT SESSION_INFO * sessionInfoPtr)461 static int clientTransact( INOUT SESSION_INFO *sessionInfoPtr )
462 {
463 int status;
464
465 assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
466
467 /* Get certificate status information from the server */
468 status = sendClientRequest( sessionInfoPtr );
469 if( cryptStatusOK( status ) )
470 status = readServerResponse( sessionInfoPtr );
471 return( status );
472 }
473
474 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
serverTransact(INOUT SESSION_INFO * sessionInfoPtr)475 static int serverTransact( INOUT SESSION_INFO *sessionInfoPtr )
476 {
477 RTCS_PROTOCOL_INFO protocolInfo;
478 int status;
479
480 assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
481
482 /* Send certificate status information to the client */
483 memset( &protocolInfo, 0, sizeof( RTCS_PROTOCOL_INFO ) );
484 status = readClientRequest( sessionInfoPtr, &protocolInfo );
485 if( cryptStatusOK( status ) )
486 status = sendServerResponse( sessionInfoPtr, &protocolInfo );
487 return( status );
488 }
489
490 /****************************************************************************
491 * *
492 * Control Information Management Functions *
493 * *
494 ****************************************************************************/
495
496 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
setAttributeFunction(INOUT SESSION_INFO * sessionInfoPtr,IN const void * data,IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE type)497 static int setAttributeFunction( INOUT SESSION_INFO *sessionInfoPtr,
498 IN const void *data,
499 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE type )
500 {
501 const CRYPT_CERTIFICATE rtcsRequest = *( ( CRYPT_CERTIFICATE * ) data );
502 MESSAGE_DATA msgData = { NULL, 0 };
503 int status;
504
505 assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
506 assert( isReadPtr( data, sizeof( int ) ) );
507
508 REQUIRES( type == CRYPT_SESSINFO_REQUEST );
509
510 /* Make sure that everything is set up ready to go. Since RTCS requests
511 aren't signed like normal certificate objects we can't just check the
512 immutable attribute but have to perform a dummy export for which the
513 certificate export code will return an error status if there's a
514 problem with the request. If not, it pseudo-signs the request (if it
515 hasn't already done so) and prepares it for use */
516 status = krnlSendMessage( rtcsRequest, IMESSAGE_CRT_EXPORT, &msgData,
517 CRYPT_ICERTFORMAT_DATA );
518 if( cryptStatusError( status ) )
519 return( CRYPT_ARGERROR_NUM1 );
520
521 /* If we haven't already got a server name explicitly set, try and get
522 it from the request. This is an opportunistic action so we ignore
523 any potential error, the caller can still set the value explicitly */
524 if( findSessionInfo( sessionInfoPtr->attributeList,
525 CRYPT_SESSINFO_SERVER_NAME ) == NULL )
526 {
527 char buffer[ MAX_URL_SIZE + 8 ];
528
529 setMessageData( &msgData, buffer, MAX_URL_SIZE );
530 status = krnlSendMessage( rtcsRequest, IMESSAGE_GETATTRIBUTE_S,
531 &msgData, CRYPT_IATTRIBUTE_RESPONDERURL );
532 if( cryptStatusOK( status ) )
533 ( void ) krnlSendMessage( sessionInfoPtr->objectHandle,
534 IMESSAGE_SETATTRIBUTE_S, &msgData,
535 CRYPT_SESSINFO_SERVER_NAME );
536 }
537
538 /* Add the request and increment its usage count */
539 krnlSendNotifier( rtcsRequest, IMESSAGE_INCREFCOUNT );
540 sessionInfoPtr->iCertRequest = rtcsRequest;
541
542 return( CRYPT_OK );
543 }
544
545 /****************************************************************************
546 * *
547 * Session Access Routines *
548 * *
549 ****************************************************************************/
550
551 /* Open/close an RTCS session */
552
553 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
setAccessMethodRTCS(INOUT SESSION_INFO * sessionInfoPtr)554 int setAccessMethodRTCS( INOUT SESSION_INFO *sessionInfoPtr )
555 {
556 static const PROTOCOL_INFO protocolInfo = {
557 /* General session information */
558 TRUE, /* Request-response protocol */
559 SESSION_ISHTTPTRANSPORT, /* Flags */
560 80, /* HTTP port */
561 SESSION_NEEDS_REQUEST, /* Client flags */
562 SESSION_NEEDS_PRIVATEKEY | /* Server flags */
563 SESSION_NEEDS_PRIVKEYSIGN | \
564 SESSION_NEEDS_PRIVKEYCERT | \
565 SESSION_NEEDS_KEYSET,
566 1, 1, 1 /* Version 1 */
567
568 /* Protocol-specific information */
569 };
570
571 assert( isWritePtr( sessionInfoPtr, sizeof( SESSION_INFO ) ) );
572
573 /* Set the access method pointers */
574 sessionInfoPtr->protocolInfo = &protocolInfo;
575 if( isServer( sessionInfoPtr ) )
576 {
577 FNPTR_SET( sessionInfoPtr->transactFunction, serverTransact );
578 }
579 else
580 {
581 FNPTR_SET( sessionInfoPtr->transactFunction, clientTransact );
582 }
583 FNPTR_SET( sessionInfoPtr->setAttributeFunction, setAttributeFunction );
584
585 return( CRYPT_OK );
586 }
587 #endif /* USE_RTCS */
588