1 /**************************************************************************** 2 * * 3 * Secure Session Routines Header File * 4 * Copyright Peter Gutmann 1998-2013 * 5 * * 6 ****************************************************************************/ 7 8 #ifndef _SES_DEFINED 9 10 #define _SES_DEFINED 11 12 #ifndef _STREAM_DEFINED 13 #if defined( INC_ALL ) 14 #include "stream.h" 15 #else 16 #include "io/stream.h" 17 #endif /* Compiler-specific includes */ 18 #endif /* _STREAM_DEFINED */ 19 20 /**************************************************************************** 21 * * 22 * Session Types and Constants * 23 * * 24 ****************************************************************************/ 25 26 /* Session information flags. These are: 27 28 SESSION_ISOPEN: The session is active. 29 30 SESSION_PARTIALOPEN: The session is partially active pending 31 confirmation of credentials such as a username and password 32 or certificate. This means that the session remains in the 33 handshake state, with the handshake being completed once the 34 credentials have been confirmed. 35 36 SESSION_SENDCLOSED: The remote system has closed its receive channel, 37 which means that no more data can be sent to it. This does not 38 however mean that no more data can be received on our receive 39 channel. 40 41 SESSION_ISCLOSINGDOWN: The session is in the shutdown stage, if further 42 requests from the remote system arrive they should be NACK'd or 43 ignored. 44 45 SESSION_NOREPORTERROR: Don't update the extended error information if 46 an error occurs, since this has already been set. This is 47 typically used when performing shutdown actions in response to 48 a protocol error, when a network error such as the other side 49 closing the connection would overwrite the details of the 50 error that caused the shutdown to be performed. 51 52 SESSION_ISSERVER: The session is a server session. 53 54 SESSION_ISSECURE_READ: The read/write channel is in the secure state, 55 SESSION_ISSECURE_WRITE: for secure data transport sessions. In other 56 words the session has passed the initial handshake stage and all 57 data is now being encrypted/MACd/whatever. 58 59 SESSION_ISCRYPTLIB: The peer is also running cryptlib, which means that 60 we can apply cryptlib-specific optimistions and security 61 enhancements. 62 63 SESSION_ISHTTPTRANSPORT: The session is using HTTP transport, for 64 request/response sessions */ 65 66 #define SESSION_NONE 0x0000 /* No session flags */ 67 #define SESSION_ISOPEN 0x0001 /* Session is active */ 68 #define SESSION_PARTIALOPEN 0x0002 /* Session is partially active */ 69 #define SESSION_SENDCLOSED 0x0004 /* Send channel is closed */ 70 #define SESSION_ISCLOSINGDOWN 0x0008 /* Session is in process of shutdown */ 71 #define SESSION_NOREPORTERROR 0x0010 /* Don't report network-level errors */ 72 #define SESSION_ISSERVER 0x0020 /* Session is server session */ 73 #define SESSION_ISSECURE_READ 0x0040 /* Session read ch.in secure state */ 74 #define SESSION_ISSECURE_WRITE 0x0080 /* Session write ch.in secure state */ 75 #define SESSION_ISCRYPTLIB 0x0100 /* Peer is running cryptlib */ 76 #define SESSION_ISHTTPTRANSPORT 0x0200 /* Session using HTTP transport */ 77 78 /* Needed-information flags used by protocol-specific handlers to indicate 79 that the caller must set the given attributes in the session information 80 before the session can be activated. This allows it to be checked at the 81 general cryptses.c level rather than at the per-protocol level. 82 83 Some session types have private keys optional but if present they must 84 meet certain requirements, this is indicated by omitting the presence- 85 check SESSION_NEEDS_PRIVATEKEY but specifying one or more of the 86 SESSION_NEEDS_PRIVKEYxxx options */ 87 88 #define SESSION_NEEDS_USERID 0x0001 /* Must have userID */ 89 #define SESSION_NEEDS_PASSWORD 0x0002 /* Must have password */ 90 #define SESSION_NEEDS_PRIVATEKEY 0x0004 /* Must have private key */ 91 #define SESSION_NEEDS_PRIVKEYCRYPT 0x0008 /* Priv.key must have certificate */ 92 #define SESSION_NEEDS_PRIVKEYSIGN 0x0010 /* Priv.key must have sig.capabil.*/ 93 #define SESSION_NEEDS_PRIVKEYCERT 0x0020 /* Priv.key must have crypt capabil.*/ 94 #define SESSION_NEEDS_PRIVKEYCACERT 0x0040 /* Priv key must have CA certificate */ 95 #define SESSION_NEEDS_KEYORPASSWORD ( 0x0080 | SESSION_NEEDS_PASSWORD | \ 96 SESSION_NEEDS_PRIVATEKEY ) 97 /* Password can be used in place of 98 private, this is a modifier on top 99 of privKey/password */ 100 #define SESSION_NEEDS_REQUEST 0x0100 /* Must have request obj.*/ 101 #define SESSION_NEEDS_KEYSET 0x0200 /* Must have certificate keyset */ 102 #define SESSION_NEEDS_CERTSTORE 0x0400 /* Keyset must be certificate store */ 103 104 /* The minimum- and maximum-length fixed headers that we should see in 105 header-read code */ 106 107 #define FIXED_HEADER_MIN 5 /* SSL header */ 108 #define FIXED_HEADER_MAX 21 /* TLS 1.1+ header with explicit 109 AES IV */ 110 111 /* When reading packets for a secure session protocol, we need to 112 communicate read state information which is more complex than the usual 113 length or error code. The following values modify the standard return 114 value (either a positive or zero byte count or a negative error value) 115 with additional context-specific information */ 116 117 typedef enum { 118 READINFO_NONE, /* No special handling */ 119 READINFO_HEADERPAYLOAD, /* Header read got some payload data */ 120 READINFO_NOOP, /* Packet was no-op, try again */ 121 READINFO_PARTIAL, /* Partial packet, try again */ 122 READINFO_FATAL, /* Treat errors as fatal */ 123 READINFO_LAST /* Last possible read information */ 124 } READSTATE_INFO; 125 126 /* The control mechanism for authorisation in interactive sessions. 127 Normally when the server gets a user-authorisation request it'll return a 128 CRYPT_ENVELOPE_RESOURCE to tell the caller that they need to decide what 129 to do with the request. If they set it to AUTHRESPONSE_SUCCESS, we allow 130 the client authorisation, if they set it to AUTHRESPONSE_FAILURE we 131 disallow it and the client gets another go at authorising themselves. 132 The default setting of AUTHRESPONSE_NONE means that we ask the user for 133 instructions */ 134 135 typedef enum { 136 AUTHRESPONSE_NONE, /* No authorisation response */ 137 AUTHRESPONSE_SUCCESS, /* Allow authorisation */ 138 AUTHRESPONSE_FAILURE, /* Disallow authorisation */ 139 AUTHRESPONSE_LAST /* Last possible authorisation response */ 140 } AUTHRESPONSE_TYPE; 141 142 /**************************************************************************** 143 * * 144 * Session Structures * 145 * * 146 ****************************************************************************/ 147 148 /* Protocol-specific information for each session */ 149 150 typedef struct { 151 /* Information required for all sessions: Whether this is a secure 152 session or request/response protocol, protocol-specific flags, the 153 default port for the protocol, flags for attributes required before 154 the session can be activated, the default protocol version and lowest 155 and highest allowed versions, and the transport-protocol client and 156 server content-types */ 157 const BOOLEAN isReqResp; /* Whether session is req/resp session */ 158 const int flags; /* Protocol flags */ 159 const int port; /* Default port */ 160 const int clientReqAttrFlags, serverReqAttrFlags; /* Required attributes */ 161 const int version, minVersion, maxVersion;/* Protocol version/subtype */ 162 163 /* Session type-specific information: The send and receive buffer size, 164 the alternative transport protocol for request/response sessions if 165 HTTP isn't being used, the minimum allowed size for the server's 166 private key */ 167 const int bufSize; /* Send/receive buffer sizes */ 168 const int sendBufStartOfs; /* Payload data start */ 169 const int maxPacketSize; /* Maximum packet (payload data) size */ 170 } PROTOCOL_INFO; 171 172 /* A value to initialise the session type-specific buffer size values to 173 default settings for request/response protocols */ 174 175 #define BUFFER_SIZE_DEFAULT 0, 0, 0 176 177 /* Attribute flags. These are: 178 179 FLAG_COMPOSITE: Composite attribute containing sub-attribute data in the 180 { value, valueLength } buffer. The attribute cursor can be 181 moved within the attribute using the internal virtual cursor. 182 183 FLAG_CURSORMOVED: The attribute (group) cursor has moved, so the virtual 184 cursor within the attribute needs to be reset the next time that 185 it's referenced. This is used with composite attributes, whose 186 internal structure is opaque to the general session code. 187 188 FLAG_ENCODEDVALUE: The attribute value is stored in cryptlib 189 XXXXX-XXXXX-... style encoding and needs to be converted to 190 binary form before use. 191 192 FLAG_EPHEMERAL: The attribute is only valid for the current session 193 activation and is cleared between session re-activations. 194 195 FLAG_MULTIVALUED: Multiple instances of the attribute are permitted. 196 This complements ATTR_FLAG_OVERWRITE in that instead of 197 overwriting the single existing instance, another instance is 198 created */ 199 200 #define ATTR_FLAG_NONE 0x00 /* No attribute flag */ 201 #define ATTR_FLAG_ENCODEDVALUE 0x01 /* Value uses XXX-XXX encoding */ 202 #define ATTR_FLAG_MULTIVALUED 0x02 /* Multiple instances permitted */ 203 #define ATTR_FLAG_COMPOSITE 0x04 /* Composite attribute */ 204 #define ATTR_FLAG_CURSORMOVED 0x08 /* Attribute virtual cursor reset */ 205 #define ATTR_FLAG_EPHEMERAL 0x10 /* Only valid for current sess.act.*/ 206 #define ATTR_FLAG_MAX 0x1F /* Maximum possible flag value */ 207 208 /* The helper function used to access session subtype-specific internal 209 attributes within an attribute list entry */ 210 211 struct AL; /* Forward declaration for attribute-list access function */ 212 213 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \ 214 int ( *ATTRACCESS_FUNCTION )( INOUT struct AL *attributeListPtr, 215 IN_ENUM_OPT( ATTR ) \ 216 const ATTR_TYPE attrGetType, 217 OUT_INT_Z int *value ); 218 219 /* An attribute list used to store session-related attributes such as 220 user names, passwords, and public keys. Since some of these can be 221 composite attributes (with information stored in the { value, 222 valueLength } buffer), we implement a virtual cursor that points to the 223 currently-selected sub-attribute within the composite attribute */ 224 225 typedef struct AL { 226 /* Identification and other information for this attribute */ 227 CRYPT_ATTRIBUTE_TYPE groupID, attributeID; 228 /* Attribute group and type */ 229 FNPTR_DECLARE( ATTRACCESS_FUNCTION, accessFunction ); 230 /* Internal attribute access fn.*/ 231 int flags; /* Attribute data flags */ 232 233 /* The data payload for this attribute. If it's numeric data such as 234 a small integer or context, we store it in the intValue member. If 235 it's a string or composite attribute data, we store it in the 236 variable-length buffer */ 237 long intValue; /* Integer value for simple types */ 238 BUFFER_OPT_FIXED( valueLength ) \ 239 void *value; /* Attribute value */ 240 int valueLength; /* Attribute value length */ 241 242 /* The previous and next list element in the linked list of elements */ 243 struct AL *prev, *next; /* Prev, next item in the list */ 244 245 /* Variable-length storage for the attribute data */ 246 DECLARE_VARSTRUCT_VARS; 247 } ATTRIBUTE_LIST; 248 249 /* Deferred response information. When we get a request, we may be in the 250 middle of assembling or sending a data packet, so the response has to be 251 deferred until after the data packet has been completed and sent. The 252 following structure is used to hold the response data until the send 253 channel is clear */ 254 255 #define SSH_MAX_RESPONSESIZE 16 /* 2 * channelNo + 2 * param */ 256 257 typedef struct { 258 int type; /* Response type */ 259 BUFFER( SSH_MAX_RESPONSESIZE, dataLen ) \ 260 BYTE data[ SSH_MAX_RESPONSESIZE + 8 ]; /* Encoded response data */ 261 int dataLen; 262 } SSH_RESPONSE_INFO; 263 264 /* The internal fields in a session that hold data for the various session 265 types */ 266 267 typedef struct { 268 /* Session state information */ 269 int sessionCacheID; /* Session cache ID for this session */ 270 int minVersion; /* Minimum acceptable protocol version */ 271 int ivSize; /* Explicit IV size for TLS 1.1+ */ 272 273 /* The incoming and outgoing packet sequence number, for detecting 274 insertion/deletion attacks */ 275 long readSeqNo, writeSeqNo; 276 277 /* The SSL MAC read/write secrets are required because SSL 3.0 uses a 278 proto-HMAC that isn't handled by cryptlib. We leave the data in 279 normal memory because it's only usable for an active attack, which 280 means that recovering it from swap afterwards isn't a problem */ 281 BUFFER_FIXED( CRYPT_MAX_HASHSIZE ) \ 282 BYTE macReadSecret[ CRYPT_MAX_HASHSIZE + 8 ]; 283 BUFFER_FIXED( CRYPT_MAX_HASHSIZE ) \ 284 BYTE macWriteSecret[ CRYPT_MAX_HASHSIZE + 8 ]; 285 286 /* TLS 1.2+ with GCM modes breaks the IV down into two parts, an 287 explicit portion that's sent with every packet and an implicit 288 portion that's derived from the master secret. To save space 289 we store this in the data block for the SSL 3.0 MAC read/write 290 secrets */ 291 #define gcmReadSalt macReadSecret 292 #define gcmWriteSalt macWriteSecret 293 int gcmSaltSize; 294 295 /* When TLS 1.1+ explicit IVs are used the IV is stripped on read so 296 that the remaining packet data can be copied into the read buffer for 297 in-place processing, however when used with encrypt-then-MAC we need 298 to store the read IV in order that it can be MAC'd once the packet is 299 processed */ 300 BYTE iv[ CRYPT_MAX_IVSIZE + 8 ]; 301 302 /* When performing manual certificate checking the handshake is 303 interrupted halfway through, so we have to store the handshake state 304 in order to allow it to be continued later. The following pointer 305 points to this state data, a buffer of size SSL_HANDSHAKE_INFO */ 306 void *savedHandshakeInfo; /* Saved handshake state */ 307 308 /* The session scoreboard, used for the SSL session cache */ 309 void *scoreboardInfoPtr; /* Session scoreboard */ 310 311 /* A buffer for the SSL packet header, which is read out-of-band */ 312 BUFFER_FIXED( 8 + CRYPT_MAX_IVSIZE ) \ 313 BYTE headerBuffer[ 8 + CRYPT_MAX_IVSIZE + 8 ]; 314 } SSL_INFO; 315 316 typedef struct { 317 /* The packet type and padding length, which are extracted from the 318 packet header during header processing */ 319 int packetType, padLength; 320 321 /* The incoming and outgoing packet sequence number, for detecting 322 insertion/deletion attacks */ 323 long readSeqNo, writeSeqNo; 324 325 /* Per-channel state information */ 326 int currReadChannel, currWriteChannel; /* Current active R/W channels */ 327 int nextChannelNo; /* Next SSH channel no.to use */ 328 int channelIndex; /* Current cryptlib unique channel ID */ 329 330 /* Deferred response data, used to enqueue responses when unwritten data 331 remains in the send buffer */ 332 SSH_RESPONSE_INFO response; 333 334 /* Whether an SSH user authentication packet has been read ready for the 335 server to act on */ 336 BOOLEAN authRead; 337 338 /* A buffer for the SSH packet header, which we receive in encrypted 339 form so that it needs to be decrypted, parts discarded, and the 340 remainder copied into the main buffer as payload data (ugh) */ 341 BUFFER_FIXED( CRYPT_MAX_IVSIZE ) \ 342 BYTE headerBuffer[ CRYPT_MAX_IVSIZE + 8 ]; 343 344 /* To keep track of the partially-processed data we need to augment the 345 standard pendingPacket indicators with an additional value that 346 tracks how much of the pending packet has already been processed as 347 part of the header read */ 348 int partialPacketDataLength; /* Length of data already processed */ 349 350 /* The SSH spec allows authentication to be performed in lots of little 351 bits and pieces, which give an attacker lots of leeway to fiddle with 352 the credentials being submitted on different passes of the 353 authentication to try and confuse the server. To avoid this problem 354 we require that the userID and authentication method remain constant 355 over different iterations of authentication, which unfortunately 356 means recording a pile of server-side authentication state */ 357 BUFFER_FIXED( KEYID_SIZE ) \ 358 BYTE authUserNameHash[ KEYID_SIZE + 8 ]; /* Hashed userID */ 359 int authType; /* Authentication method */ 360 } SSH_INFO; 361 362 typedef struct { 363 /* The message imprint (hash) algorithm and hash value */ 364 CRYPT_ALGO_TYPE imprintAlgo; 365 BUFFER( CRYPT_MAX_HASHSIZE, imprintSize ) \ 366 BYTE imprint[ CRYPT_MAX_HASHSIZE ]; 367 int imprintSize; 368 } TSP_INFO; 369 370 typedef struct { 371 /* CMP request subtype, user information and protocol flags */ 372 int requestType; /* CMP request subtype */ 373 CRYPT_CERTIFICATE userInfo; /* PKI user information */ 374 int flags; /* Protocol flags */ 375 376 /* The saved MAC context from a previous transaction (if any). This is 377 saved across transactions in case the same user information is used 378 for subsequent transactions, see the comment in cmp.h for details */ 379 CRYPT_CONTEXT savedMacContext; /* MAC context from prev.trans */ 380 } CMP_INFO; 381 382 typedef struct { 383 /* SCEP request type and protocol flags */ 384 int requestType; /* SCEP request subtype */ 385 int flags; /* Protocol flags */ 386 } SCEP_INFO; 387 388 /* Defines to make access to the union fields less messy */ 389 390 #define sessionSSH sessionInfo.sshInfo 391 #define sessionSSL sessionInfo.sslInfo 392 #define sessionTSP sessionInfo.tspInfo 393 #define sessionCMP sessionInfo.cmpInfo 394 #define sessionSCEP sessionInfo.scepInfo 395 396 /* The structure that stores the information on a session */ 397 398 struct SI; 399 400 typedef STDC_NONNULL_ARG( ( 1 ) ) \ 401 void ( *SES_SHUTDOWN_FUNCTION )( INOUT struct SI *sessionInfoPtr ); 402 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 403 int ( *SES_CONNECT_FUNCTION )( INOUT struct SI *sessionInfoPtr ); 404 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 405 int ( *SES_GETATTRIBUTE_FUNCTION )( INOUT struct SI *sessionInfoPtr, 406 OUT void *data, 407 IN_ATTRIBUTE \ 408 const CRYPT_ATTRIBUTE_TYPE type ); 409 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 410 int ( *SES_SETATTRIBUTE_FUNCTION )( INOUT struct SI *sessionInfoPtr, 411 IN const void *data, 412 IN_ATTRIBUTE \ 413 const CRYPT_ATTRIBUTE_TYPE type ); 414 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 415 int ( *SES_CHECKATTRIBUTE_FUNCTION )( INOUT struct SI *sessionInfoPtr, 416 IN const void *data, 417 IN_ATTRIBUTE \ 418 const CRYPT_ATTRIBUTE_TYPE type ); 419 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 420 int ( *SES_TRANSACT_FUNCTION )( INOUT struct SI *sessionInfoPtr ); 421 typedef CHECK_RETVAL_LENGTH STDC_NONNULL_ARG( ( 1, 2 ) ) \ 422 int ( *SES_READHEADER_FUNCTION )( INOUT struct SI *sessionInfoPtr, 423 OUT_ENUM_OPT( READINFO ) \ 424 READSTATE_INFO *readInfo ); 425 typedef CHECK_RETVAL_LENGTH STDC_NONNULL_ARG( ( 1, 2 ) ) \ 426 int ( *SES_PROCESSBODY_FUNCTION )( INOUT struct SI *sessionInfoPtr, 427 OUT_ENUM_OPT( READINFO ) \ 428 READSTATE_INFO *readInfo ); 429 typedef CHECK_RETVAL_LENGTH STDC_NONNULL_ARG( ( 1 ) ) \ 430 int ( *SES_PREPAREPACKET_FUNCTION )( INOUT struct SI *sessionInfoPtr ); 431 432 typedef struct SI { 433 /* Control and status information */ 434 CRYPT_SESSION_TYPE type; /* Session type */ 435 const PROTOCOL_INFO *protocolInfo; /* Session subtype information */ 436 int version; /* Protocol version/subtype */ 437 CRYPT_ALGO_TYPE cryptAlgo; /* Negotiated encryption algo */ 438 CRYPT_ALGO_TYPE integrityAlgo; /* Negotiated integrity prot.algo */ 439 int flags, protocolFlags; /* Session information, protocol-specific flags */ 440 AUTHRESPONSE_TYPE authResponse; /* Response to user-auth request */ 441 442 /* Session type-specific information */ 443 union { 444 SSL_INFO *sslInfo; 445 SSH_INFO *sshInfo; 446 TSP_INFO *tspInfo; 447 CMP_INFO *cmpInfo; 448 SCEP_INFO *scepInfo; 449 } sessionInfo; 450 451 /* When we add generic attributes to the session, we occasionally need to 452 perform protocol-specific checking of the attributes being added. The 453 following values are used to tell the generic cryptses.c code which 454 checks need to be performed */ 455 int clientReqAttrFlags, serverReqAttrFlags; /* Required attributes */ 456 457 /* The overall session status. If we run into a nonrecoverable error 458 (which for the encrypted session types means just about anything, 459 once we lose sync we're toast) we remember the status here so that 460 any further attempts to work with the session will return this 461 status. Since an error on one side of the channel (e.g. bad data on 462 read) doesn't necessarily affect the operation of the other side, we 463 keep track of the two sides independantly, and only set the error 464 state for both sides for network-related errors. 465 466 In many cases there'll still be data in the internal buffer that the 467 user can read/write without triggering an error response so before we 468 set the error state we set the pending error state and only move the 469 pending state into the current state once all data still present in 470 the buffer has been read */ 471 int readErrorState, writeErrorState;/* Current error state */ 472 int pendingReadErrorState, pendingWriteErrorState; 473 /* Error state when buffer emptied */ 474 475 /* Data buffer information. In protocols that consist of single 476 messages sent back and forth only the receive buffer is used for 477 sending and receiving data, this buffer is somewhat more flexible 478 since it's associated with extra variables for handling the current 479 position in the buffer (bufPos) vs.the total amount of data present 480 (bufEnd) */ 481 BUFFER( sendBufSize, sendBufPos ) \ 482 BYTE *sendBuffer; 483 BUFFER_OPT( receiveBufSize, receiveBufEnd ) \ 484 BYTE *receiveBuffer; /* Data buffer */ 485 int sendBufSize, receiveBufSize; /* Total buffer size */ 486 int sendBufPos, receiveBufPos; /* Current position in buffer */ 487 int sendBufStartOfs, receiveBufStartOfs; /* Space for header in buffer */ 488 int receiveBufEnd; /* Total data in buffer */ 489 int maxPacketSize; /* Maximum packet (payload data) size */ 490 491 /* When reading encrypted data packets we typically end up with a partial 492 packet in the read buffer that we can't process until the remainder 493 arrives, the following variables holds the eventual length of the 494 pending data packet and the amount of data remaining to be read */ 495 int pendingPacketLength; /* Lending of pending data packet */ 496 int pendingPacketRemaining; /* Bytes remaining to be read */ 497 498 /* Unlike payload data, the packet header can't be read in sections but 499 must be read completely since all of the header information needs to 500 be processed at once. The following value is usually zero, if it's 501 nonzero it records how much of the header remains to be read */ 502 int partialHeaderRemaining; /* Header bytes still to read */ 503 504 /* When sending data we can also end up with partially-processed packets 505 in the send buffer, but for sending we prevent further packets from 506 being added until the current one is flushed. To handle this all we 507 need is a simple high-water-mark indicator that indicates the start 508 position of any yet-to-be-written data */ 509 BOOLEAN partialWrite; /* Unwritten data remains in buffer */ 510 int sendBufPartialBufPos; /* Progress point of partial write */ 511 512 /* The session generally has various ephemeral contexts associated with 513 it, some short-term (e.g.public-key contexts used to establish the 514 session) and some long-term (e.g.encryption contexts used to perform 515 bulk data encryption). These contexts are ephemeral ones that are 516 created as part of the session, long-term ones (e.g.signature keys 517 used for authentication) are held elsewhere */ 518 CRYPT_CONTEXT iKeyexCryptContext; /* Key exchange encryption */ 519 CRYPT_CONTEXT iKeyexAuthContext; /* Key exchange authentication */ 520 CRYPT_CONTEXT iCryptInContext, iCryptOutContext; 521 /* In/outgoing data encryption */ 522 CRYPT_CONTEXT iAuthInContext, iAuthOutContext; 523 /* In/outgoing auth/integrity */ 524 CRYPT_CERTIFICATE iCertRequest, iCertResponse; 525 /* Certificate request/response */ 526 int cryptBlocksize, authBlocksize; /* Block size of crypt, auth.algos */ 527 528 /* The private key, which is required to authenticate the client or 529 server in some protocols */ 530 CRYPT_CONTEXT privateKey; /* Authentication private key */ 531 532 /* Certificate store for certificate management protocols like OCSP and 533 CMP and private-key keyset for PnP PKI protocols */ 534 CRYPT_KEYSET cryptKeyset; /* Certificate store */ 535 CRYPT_HANDLE privKeyset; /* Private-key keyset/device */ 536 537 /* Session-related attributes, a current-position cursor in the 538 attribute list */ 539 ATTRIBUTE_LIST *attributeList, *attributeListCurrent; 540 541 /* Network connection information. The reason why the client and server 542 information require separate storage is that (on the server) we may 543 be binding to a specific interface (requiring a server name) and we 544 need to record where the remote system's connection is coming from 545 (requiring a client name) */ 546 CRYPT_SESSION transportSession; /* Transport mechanism */ 547 int networkSocket; /* User-supplied network socket */ 548 int readTimeout, writeTimeout, connectTimeout; 549 /* Connect and data xfer.timeouts */ 550 STREAM stream; /* Network I/O stream */ 551 552 /* Low-level error information */ 553 ERROR_INFO errorInfo; 554 555 /* Pointers to session access methods. Stateful sessions use the read/ 556 write functions, stateless ones use the transact function */ 557 FNPTR_DECLARE( SES_SHUTDOWN_FUNCTION, shutdownFunction ); 558 FNPTR_DECLARE( SES_CONNECT_FUNCTION, connectFunction ); 559 FNPTR_DECLARE( SES_GETATTRIBUTE_FUNCTION, getAttributeFunction ); 560 FNPTR_DECLARE( SES_SETATTRIBUTE_FUNCTION, setAttributeFunction ); 561 FNPTR_DECLARE( SES_CHECKATTRIBUTE_FUNCTION, checkAttributeFunction ); 562 FNPTR_DECLARE( SES_TRANSACT_FUNCTION, transactFunction ); 563 FNPTR_DECLARE( SES_READHEADER_FUNCTION, readHeaderFunction ); 564 FNPTR_DECLARE( SES_PROCESSBODY_FUNCTION, processBodyFunction ); 565 FNPTR_DECLARE( SES_PREPAREPACKET_FUNCTION, preparePacketFunction ); 566 567 /* Error information */ 568 CRYPT_ATTRIBUTE_TYPE errorLocus;/* Error locus */ 569 CRYPT_ERRTYPE_TYPE errorType; /* Error type */ 570 571 /* The object's handle and the handle of the user who owns this object. 572 The former is used when sending messages to the object when only the 573 xxx_INFO is available, the latter is used to avoid having to fetch the 574 same information from the system object table */ 575 CRYPT_HANDLE objectHandle; 576 CRYPT_USER ownerHandle; 577 578 /* Variable-length storage for the type-specific data */ 579 DECLARE_VARSTRUCT_VARS; 580 } SESSION_INFO; 581 582 /**************************************************************************** 583 * * 584 * Session Functions * 585 * * 586 ****************************************************************************/ 587 588 /* Macros to make handling of error reporting on shutdown a bit more 589 obvious */ 590 591 #define disableErrorReporting( sessionInfoPtr ) \ 592 ( sessionInfoPtr )->flags |= SESSION_NOREPORTERROR 593 #define enableErrorReporting( sessionInfoPtr ) \ 594 ( sessionInfoPtr )->flags &= ~SESSION_NOREPORTERROR 595 596 /* The SESSION_ISSERVER flag is checked so often that we define a macro to 597 handle it */ 598 599 #define isServer( sessionInfoPtr ) \ 600 ( sessionInfoPtr->flags & SESSION_ISSERVER ) 601 602 /* Session attribute handling functions */ 603 604 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 605 int getSessionAttribute( INOUT SESSION_INFO *sessionInfoPtr, 606 OUT_INT_Z int *valuePtr, 607 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute ); 608 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 609 int getSessionAttributeS( INOUT SESSION_INFO *sessionInfoPtr, 610 INOUT MESSAGE_DATA *msgData, 611 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute ); 612 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 613 int setSessionAttribute( INOUT SESSION_INFO *sessionInfoPtr, 614 IN const int value, 615 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute ); 616 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 617 int setSessionAttributeS( INOUT SESSION_INFO *sessionInfoPtr, 618 IN_BUFFER( dataLength ) const void *data, 619 IN_LENGTH const int dataLength, 620 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute ); 621 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 622 int deleteSessionAttribute( INOUT SESSION_INFO *sessionInfoPtr, 623 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute ); 624 625 /* Session-specific attribute management functions */ 626 627 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 628 int addSessionInfo( INOUT_PTR ATTRIBUTE_LIST **listHeadPtr, 629 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attributeID, 630 IN_INT_Z const int value ); 631 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \ 632 int addSessionInfoS( INOUT_PTR ATTRIBUTE_LIST **listHeadPtr, 633 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attributeID, 634 IN_BUFFER( dataLength ) const void *data, 635 IN_LENGTH_SHORT const int dataLength ); 636 637 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \ 638 int addSessionInfoEx( INOUT_PTR ATTRIBUTE_LIST **listHeadPtr, 639 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attributeID, 640 IN_BUFFER( dataLength ) const void *data, 641 IN_LENGTH_SHORT const int dataLength, 642 IN_FLAGS_Z( ATTR ) const int flags ); 643 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \ 644 int addSessionInfoComposite( INOUT_PTR ATTRIBUTE_LIST **listHeadPtr, 645 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attributeID, 646 const ATTRACCESS_FUNCTION accessFunction, 647 IN_BUFFER( dataLength ) const void *data, 648 IN_LENGTH_SHORT const int dataLength, 649 IN_FLAGS( ATTR ) const int flags ); 650 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \ 651 int updateSessionInfo( INOUT_PTR ATTRIBUTE_LIST **listHeadPtr, 652 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attributeID, 653 IN_BUFFER( dataLength ) const void *data, 654 IN_LENGTH_SHORT const int dataLength, 655 IN_LENGTH_SHORT const int dataMaxLength, 656 IN_FLAGS_Z( ATTR ) const int flags ); 657 CHECK_RETVAL STDC_NONNULL_ARG( ( 4 ) ) \ 658 int getSessionAttributeCursor( IN_OPT ATTRIBUTE_LIST *attributeListHead, 659 IN_OPT ATTRIBUTE_LIST *attributeListCursor, 660 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE sessionInfoType, 661 OUT_ATTRIBUTE_Z CRYPT_ATTRIBUTE_TYPE *valuePtr ); 662 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \ 663 int setSessionAttributeCursor( IN_OPT const ATTRIBUTE_LIST *attributeListHead, 664 INOUT_PTR ATTRIBUTE_LIST **attributeListCursorPtr, 665 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE sessionInfoType, 666 IN_RANGE( CRYPT_CURSOR_LAST, \ 667 CRYPT_CURSOR_FIRST ) /* Values are -ve */ 668 const int position ); 669 CHECK_RETVAL_PTR \ 670 const ATTRIBUTE_LIST *findSessionInfo( IN_OPT const ATTRIBUTE_LIST *attributeListPtr, 671 IN_ATTRIBUTE \ 672 const CRYPT_ATTRIBUTE_TYPE attributeID ); 673 CHECK_RETVAL_PTR STDC_NONNULL_ARG( ( 3 ) ) \ 674 const ATTRIBUTE_LIST *findSessionInfoEx( IN_OPT const ATTRIBUTE_LIST *attributeListPtr, 675 IN_ATTRIBUTE \ 676 const CRYPT_ATTRIBUTE_TYPE attributeID, 677 IN_BUFFER( valueLength ) const void *value, 678 IN_LENGTH_SHORT const int valueLength ); 679 STDC_NONNULL_ARG( ( 1 ) ) \ 680 void lockEphemeralAttributes( INOUT ATTRIBUTE_LIST *attributeListHead ); 681 STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \ 682 int deleteSessionInfo( INOUT ATTRIBUTE_LIST **attributeListHead, 683 INOUT ATTRIBUTE_LIST **attributeListCurrent, 684 INOUT ATTRIBUTE_LIST *attributeListPtr ); 685 STDC_NONNULL_ARG( ( 1, 2 ) ) \ 686 void deleteSessionInfoAll( INOUT ATTRIBUTE_LIST **attributeListHead, 687 INOUT ATTRIBUTE_LIST **attributeListCurrent ); 688 CHECK_RETVAL_ENUM( CRYPT_ATTRIBUTE ) \ 689 CRYPT_ATTRIBUTE_TYPE checkMissingInfo( IN_OPT const ATTRIBUTE_LIST *attributeListHead, 690 const BOOLEAN isServer ); 691 692 /* Prototypes for functions in sess_rw.c */ 693 694 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 695 int readFixedHeaderAtomic( INOUT SESSION_INFO *sessionInfoPtr, 696 OUT_BUFFER_FIXED( headerLength ) void *headerBuffer, 697 IN_LENGTH_SHORT_MIN( FIXED_HEADER_MIN ) \ 698 const int headerLength ); 699 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 700 int readFixedHeader( INOUT SESSION_INFO *sessionInfoPtr, 701 OUT_BUFFER_FIXED( headerLength ) void *headerBuffer, 702 IN_LENGTH_SHORT_MIN( FIXED_HEADER_MIN ) \ 703 const int headerLength ); 704 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \ 705 int getSessionData( INOUT SESSION_INFO *sessionInfoPtr, 706 OUT_BUFFER( dataMaxLength, *bytesCopied ) void *data, 707 IN_DATALENGTH const int dataMaxLength, 708 OUT_DATALENGTH_Z int *bytesCopied ); 709 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \ 710 int putSessionData( INOUT SESSION_INFO *sessionInfoPtr, 711 IN_BUFFER_OPT( dataLength ) const void *data, 712 IN_DATALENGTH_Z const int dataLength, 713 OUT_DATALENGTH_Z int *bytesCopied ); 714 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 715 int readPkiDatagram( INOUT SESSION_INFO *sessionInfoPtr ); 716 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 717 int writePkiDatagram( INOUT SESSION_INFO *sessionInfoPtr, 718 IN_BUFFER( contentTypeLen ) const char *contentType, 719 IN_LENGTH_TEXT const int contentTypeLen ); 720 721 /* Prototypes for functions in session.c */ 722 723 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 724 int initSessionIO( INOUT SESSION_INFO *sessionInfoPtr ); 725 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 726 int initSessionNetConnectInfo( const SESSION_INFO *sessionInfoPtr, 727 OUT NET_CONNECT_INFO *connectInfo ); 728 CHECK_RETVAL_BOOL STDC_NONNULL_ARG( ( 1 ) ) \ 729 BOOLEAN checkAttributesConsistent( INOUT SESSION_INFO *sessionInfoPtr, 730 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute ); 731 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \ 732 int checkServerCertValid( const CRYPT_CERTIFICATE iServerKey, 733 INOUT ERROR_INFO *errorInfo ); 734 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 735 int activateSession( INOUT SESSION_INFO *sessionInfoPtr ); 736 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 737 int sendCloseNotification( INOUT SESSION_INFO *sessionInfoPtr, 738 IN_BUFFER_OPT( length ) const void *data, 739 IN_LENGTH_SHORT_Z const int length ); 740 741 /* Prototypes for session mapping functions */ 742 743 #ifdef USE_CERTSTORE 744 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 745 int setAccessMethodCertstore( INOUT SESSION_INFO *sessionInfoPtr ); 746 #else 747 #define setAccessMethodCertstore( x ) CRYPT_ARGERROR_NUM1 748 #endif /* USE_CERTSTORE */ 749 #ifdef USE_CMP 750 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 751 int setAccessMethodCMP( INOUT SESSION_INFO *sessionInfoPtr ); 752 #else 753 #define setAccessMethodCMP( x ) CRYPT_ARGERROR_NUM1 754 #endif /* USE_CMP */ 755 #ifdef USE_RTCS 756 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 757 int setAccessMethodRTCS( INOUT SESSION_INFO *sessionInfoPtr ); 758 #else 759 #define setAccessMethodRTCS( x ) CRYPT_ARGERROR_NUM1 760 #endif /* USE_RTCS */ 761 #ifdef USE_OCSP 762 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 763 int setAccessMethodOCSP( INOUT SESSION_INFO *sessionInfoPtr ); 764 #else 765 #define setAccessMethodOCSP( x ) CRYPT_ARGERROR_NUM1 766 #endif /* USE_OCSP */ 767 #ifdef USE_SCEP 768 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 769 int setAccessMethodSCEP( INOUT SESSION_INFO *sessionInfoPtr ); 770 #else 771 #define setAccessMethodSCEP( x ) CRYPT_ARGERROR_NUM1 772 #endif /* USE_SCEP */ 773 #if defined( USE_SSH ) || defined( USE_SSH1 ) 774 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 775 int setAccessMethodSSH( INOUT SESSION_INFO *sessionInfoPtr ); 776 #else 777 #define setAccessMethodSSH( x ) CRYPT_ARGERROR_NUM1 778 #endif /* USE_SSH || USE_SSH1 */ 779 #ifdef USE_SSL 780 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 781 int setAccessMethodSSL( INOUT SESSION_INFO *sessionInfoPtr ); 782 #else 783 #define setAccessMethodSSL( x ) CRYPT_ARGERROR_NUM1 784 #endif /* USE_SSL */ 785 #ifdef USE_TSP 786 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 787 int setAccessMethodTSP( INOUT SESSION_INFO *sessionInfoPtr ); 788 #else 789 #define setAccessMethodTSP( x ) CRYPT_ARGERROR_NUM1 790 #endif /* USE_TCP */ 791 #endif /* _SES_DEFINED */ 792