1 /**************************************************************************** 2 * * 3 * SSH Definitions Header File * 4 * Copyright Peter Gutmann 1998-2013 * 5 * * 6 ****************************************************************************/ 7 8 #ifndef _SSH_DEFINED 9 10 #define _SSH_DEFINED 11 12 #if defined( USE_SSH_EXTENDED ) && defined( _MSC_VER ) 13 #pragma message( " Building with extended SSH facilities enabled." ) 14 #endif /* USE_SSH_EXTENDED with VC++ */ 15 16 /**************************************************************************** 17 * * 18 * SSH Constants * 19 * * 20 ****************************************************************************/ 21 22 /* Default SSH port */ 23 24 #define SSH_PORT 22 25 26 /* Various SSH constants */ 27 28 #define ID_SIZE 1 /* ID byte */ 29 #define LENGTH_SIZE 4 /* Size of packet length field */ 30 #define UINT_SIZE 4 /* Size of integer value */ 31 #define PADLENGTH_SIZE 1 /* Size of padding length field */ 32 #define BOOLEAN_SIZE 1 /* Size of boolean value */ 33 34 #define SSH2_COOKIE_SIZE 16 /* Size of SSHv2 cookie */ 35 #define SSH2_HEADER_SIZE 5 /* Size of SSHv2 packet header */ 36 #define SSH2_MIN_ALGOID_SIZE 4 /* Size of shortest SSHv2 algo.name */ 37 #define SSH2_MIN_PADLENGTH_SIZE 4 /* Minimum amount of padding for packets */ 38 #define SSH2_PAYLOAD_HEADER_SIZE 9 /* Size of SSHv2 inner payload header */ 39 #define SSH2_FIXED_KEY_SIZE 16 /* Size of SSHv2 fixed-size keys */ 40 #ifdef USE_DH1024 41 #define SSH2_DEFAULT_KEYSIZE 128 /* Size of SSHv2 default DH key */ 42 #else 43 #define SSH2_DEFAULT_KEYSIZE 192 /* Size of SSHv2 default DH key */ 44 #endif /* USE_DH1024 */ 45 46 /* SSH packet/buffer size information. The extra packet data is for 47 additional non-payload information including the header, MAC, and up to 48 256 bytes of padding */ 49 50 #define MAX_PACKET_SIZE 262144L 51 #define EXTRA_PACKET_SIZE 512 52 #define DEFAULT_PACKET_SIZE 16384 53 #define MAX_WINDOW_SIZE ( MAX_INTLENGTH - 8192 ) 54 55 /* By default cryptlib uses DH key agreement, which is supported by all 56 servers. It's also possible to use ECDH key agreement, however due to 57 SSH's braindamaged way of choosing algorithms the peer will always go 58 for ECDH if it can handle it (see the comment in sesion/ssh2_svr.c for 59 more on this), so we disable ECDH by default. To use ECDH key agreement 60 in preference to DH, uncomment the following */ 61 62 /* #define PREFER_ECC */ 63 #if defined( PREFER_ECC ) && defined( _MSC_VER ) 64 #pragma message( " Building with ECC preferred for SSH." ) 65 #endif /* PREFER_ECC && Visual C++ */ 66 #if defined( PREFER_ECC ) && \ 67 !( defined( USE_ECDH ) && defined( USE_ECDSA ) ) 68 #error PREFER_ECC can only be used with ECDH and ECDSA enabled 69 #endif /* PREFER_ECC && !( USE_ECDH && USE_ECDSA ) */ 70 71 /* SSH protocol-specific flags that encode details of implementation bugs 72 that we need to work around */ 73 74 #define SSH_PFLAG_NONE 0x0000/* No protocol-specific flags */ 75 #define SSH_PFLAG_HMACKEYSIZE 0x0001/* Peer uses short HMAC keys */ 76 #define SSH_PFLAG_SIGFORMAT 0x0002/* Peer omits signature algo name */ 77 #define SSH_PFLAG_NOHASHSECRET 0x0004/* Peer omits secret in key derive */ 78 #define SSH_PFLAG_NOHASHLENGTH 0x0008/* Peer omits length in exchange hash */ 79 #define SSH_PFLAG_RSASIGPAD 0x0010/* Peer requires zero-padded RSA sig.*/ 80 #define SSH_PFLAG_WINDOWSIZE 0x0020/* Peer mishandles large window sizes */ 81 #define SSH_PFLAG_TEXTDIAGS 0x0040/* Peer dumps text diagnostics on error */ 82 #define SSH_PFLAG_PAMPW 0x0080/* Peer chokes on "password" as PAM submethod */ 83 #define SSH_PFLAG_DUMMYUSERAUTH 0x0100/* Peer requires dummy userAuth message */ 84 #define SSH_PFLAG_EMPTYUSERAUTH 0x0200/* Peer sends empty userauth-failure response */ 85 #define SSH_PFLAG_ZEROLENIGNORE 0x0400/* Peer sends zero-length SSH_IGNORE */ 86 #define SSH_PFLAG_ASYMMCOPR 0x0800/* Peer sends asymmetric compression algos */ 87 #define SSH_PFLAG_EMPTYSVCACCEPT 0x1000/* Peer sends empty SSH_SERVICE_ACCEPT */ 88 #define SSH_PFLAG_CUTEFTP 0x2000/* CuteFTP, drops conn.during handshake */ 89 #define SSH_PFLAG_MAX 0x3FFF/* Maximum possible flag value */ 90 91 /* Various data sizes used for read-ahead and buffering. The minimum SSH 92 packet size is used to determine how much data we can read when reading 93 a packet header, the SSH header remainder size is how much data we've 94 got left once we've extracted just the length but no other data */ 95 96 #define MIN_PACKET_SIZE 16 97 #define SSH_HEADER_REMAINDER_SIZE ( MIN_PACKET_SIZE - LENGTH_SIZE ) 98 99 /* SSH ID information */ 100 101 #define SSH_ID "SSH-" /* Start of SSH ID */ 102 #define SSH_ID_SIZE 4 /* Size of SSH ID */ 103 #define SSH_VERSION_SIZE 4 /* Size of SSH version */ 104 #define SSH_ID_MAX_SIZE 255 /* Max.size of SSH ID string */ 105 #define SSH_ID_STRING "SSH-2.0-cryptlib" /* cryptlib SSH ID strings */ 106 #define SSH_ID_STRING_SIZE 16 /* Size of ID strings */ 107 108 /* SSH packet types. Note that the keyex (static DH keys), keyex_gex 109 (ephemeral DH keys), and keyex_ecdh (static ECDH keys) message types 110 overlap */ 111 112 #define SSH_MSG_DISCONNECT 1 /* Disconnect session */ 113 #define SSH_MSG_IGNORE 2 /* No-op */ 114 #define SSH_MSG_DEBUG 4 /* No-op */ 115 #define SSH_MSG_SERVICE_REQUEST 5 /* Request authentiction */ 116 #define SSH_MSG_SERVICE_ACCEPT 6 /* Acknowledge request */ 117 #define SSH_MSG_KEXINIT 20 /* Hello */ 118 #define SSH_MSG_NEWKEYS 21 /* Change cipherspec */ 119 #define SSH_MSG_KEXDH_INIT 30 /* DH, phase 1 */ 120 #define SSH_MSG_KEXDH_REPLY 31 /* DH, phase 2 */ 121 #define SSH_MSG_KEXDH_GEX_REQUEST_OLD 30 /* Ephem.DH key request */ 122 #define SSH_MSG_KEXDH_GEX_GROUP 31 /* Ephem.DH key response */ 123 #define SSH_MSG_KEXDH_GEX_INIT 32 /* Ephem.DH, phase 1 */ 124 #define SSH_MSG_KEXDH_GEX_REPLY 33 /* Ephem.DH, phase 2 */ 125 #define SSH_MSG_KEXDH_GEX_REQUEST_NEW 34 /* Ephem.DH key request */ 126 #define SSH_MSG_KEX_ECDH_INIT 30 /* ECDH, phase 1 */ 127 #define SSH_MSG_KEX_ECDH_REPLY 31 /* ECDH, phase 2 */ 128 #define SSH_MSG_USERAUTH_REQUEST 50 /* Request authentication */ 129 #define SSH_MSG_USERAUTH_FAILURE 51 /* Authentication failed */ 130 #define SSH_MSG_USERAUTH_SUCCESS 52 /* Authentication succeeded */ 131 #define SSH_MSG_USERAUTH_BANNER 53 /* No-op */ 132 #define SSH_MSG_USERAUTH_INFO_REQUEST 60 /* Generic auth.svr.request */ 133 #define SSH_MSG_USERAUTH_INFO_RESPONSE 61 /* Generic auth.cli.response */ 134 #define SSH_MSG_GLOBAL_REQUEST 80 /* Perform a global ioctl */ 135 #define SSH_MSG_GLOBAL_SUCCESS 81 /* Global request succeeded */ 136 #define SSH_MSG_GLOBAL_FAILURE 82 /* Global request failed */ 137 #define SSH_MSG_CHANNEL_OPEN 90 /* Open a channel over an SSH link */ 138 #define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91 /* Channel open succeeded */ 139 #define SSH_MSG_CHANNEL_OPEN_FAILURE 92 /* Channel open failed */ 140 #define SSH_MSG_CHANNEL_WINDOW_ADJUST 93 /* No-op */ 141 #define SSH_MSG_CHANNEL_DATA 94 /* Data */ 142 #define SSH_MSG_CHANNEL_EXTENDED_DATA 95 /* Out-of-band data */ 143 #define SSH_MSG_CHANNEL_EOF 96 /* EOF */ 144 #define SSH_MSG_CHANNEL_CLOSE 97 /* Close the channel */ 145 #define SSH_MSG_CHANNEL_REQUEST 98 /* Perform a channel ioctl */ 146 #define SSH_MSG_CHANNEL_SUCCESS 99 /* Channel request succeeded */ 147 #define SSH_MSG_CHANNEL_FAILURE 100/* Channel request failed */ 148 149 /* Special-case expected-packet-type values that are passed to 150 readHSPacketSSH() to handle situations where more than one return value is 151 valid. CMSG_USER can return failure meaning "no password" even if 152 there's no actual failure, CMSG_AUTH_PASSWORD can return SMSG_FAILURE 153 which indicates a wrong password used iff it's a response to the client 154 sending a password, and MSG_USERAUTH_REQUEST can similarly return a 155 failure or success response. 156 157 In addition to these types there's an "any" type which is used during the 158 setup negotiation which will accept any (non-error) packet type and return 159 the type as the return code */ 160 161 #define SSH_MSG_SPECIAL_FIRST 500 /* Boundary for _SPECIAL types */ 162 #define SSH_MSG_SPECIAL_USERAUTH 501 /* Value to handle SSH combined auth.*/ 163 #define SSH_MSG_SPECIAL_USERAUTH_PAM 502 /* Value to handle SSH PAM auth.*/ 164 #define SSH_MSG_SPECIAL_CHANNEL 503 /* Value to handle channel open */ 165 #define SSH_MSG_SPECIAL_REQUEST 504 /* Value to handle SSH global/channel req.*/ 166 #define SSH_MSG_SPECIAL_LAST 505 /* Last valid _SPECIAL type */ 167 168 /* SSH disconnection codes */ 169 170 enum { SSH_DISCONNECT_NONE, SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT, 171 SSH_DISCONNECT_PROTOCOL_ERROR, SSH_DISCONNECT_KEY_EXCHANGE_FAILED, 172 SSH_DISCONNECT_RESERVED, SSH_DISCONNECT_MAC_ERROR, 173 SSH_DISCONNECT_COMPRESSION_ERROR, SSH_DISCONNECT_SERVICE_NOT_AVAILABLE, 174 SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED, 175 SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE, SSH_DISCONNECT_CONNECTION_LOST, 176 SSH_DISCONNECT_BY_APPLICATION, SSH_DISCONNECT_TOO_MANY_CONNECTIONS, 177 SSH_DISCONNECT_AUTH_CANCELLED_BY_USER, 178 SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE, 179 SSH_DISCONNECT_ILLEGAL_USER_NAME, SSH_DISCONNECT_LAST }; 180 181 /* SSH channel open failure codes */ 182 183 #define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1 184 #define SSH_OPEN_CONNECT_FAILED 2 185 #define SSH_OPEN_UNKNOWN_CHANNEL_TYPE 3 186 #define SSH_OPEN_RESOURCE_SHORTAGE 4 187 188 /* SSH requires the use of a number of additional (pseudo)-algorithm 189 types that don't correspond to normal cryptlib algorithms. To handle 190 these, we define pseudo-algoID values that fall within the range of 191 the normal algorithm ID types but that aren't normal algorithm IDs */ 192 193 #define CRYPT_PSEUDOALGO_PASSWORD ( CRYPT_ALGO_LAST_CONVENTIONAL - 2 ) 194 #define CRYPT_PSEUDOALGO_PAM ( CRYPT_ALGO_LAST_CONVENTIONAL - 1 ) 195 #define CRYPT_PSEUDOALGO_LAST ( CRYPT_ALGO_LAST_CONVENTIONAL ) 196 197 #define MK_ALGO( value ) ( CRYPT_ALGO_TYPE ) ( CRYPT_##value ) 198 199 /* The size of the encoded DH keyex value and the requested DHE key size, 200 which we have to store in encoded form so that we can hash them later in 201 the handshake */ 202 203 #define MAX_ENCODED_KEYEXSIZE ( CRYPT_MAX_PKCSIZE + 16 ) 204 #define ENCODED_REQKEYSIZE ( UINT_SIZE * 3 ) 205 206 /* Check whether an algorithm ID is one of the above pseudo-algorithm 207 types */ 208 209 #define isPseudoAlgo( algorithm ) \ 210 ( algorithm >= CRYPT_PSEUDOALGO_PASSWORD && \ 211 algorithm <= CRYPT_PSEUDOALGO_PAM ) 212 213 /* SSH algorithms are grouped into classes such as keyex algorithms or MAC 214 algorithms, the following type identifies the different algorithm 215 classes */ 216 217 typedef enum { 218 SSH_ALGOCLASS_NONE, /* No algorithm class */ 219 SSH_ALGOCLASS_KEYEX, /* Keyex algorithms */ 220 SSH_ALGOCLASS_KEYEX_NOECC,/* Keyex algorithms limited to non-ECC algos */ 221 SSH_ALGOCLASS_ENCR, /* Encryption algorithms */ 222 SSH_ALGOCLASS_MAC, /* MAC algorithms */ 223 SSH_ALGOCLASS_COPR, /* Compression algorithms */ 224 SSH_ALGOCLASS_LAST /* Last possible algorithm class */ 225 } SSH_ALGOCLASS_TYPE; 226 227 /* Values for working with SSH channels. Channels have a 32-bit ID 228 (although no sane implementation uses very large values), to deal with 229 range checking for these we limit them to LONG_MAX in 32-bit systems. 230 231 SSH channels have a number of SSH-internal attributes that aren't exposed 232 as cryptlib-wide attribute types. The following values are used to 233 access SSH-internal channel attributes */ 234 235 #ifdef SYSTEM_64BIT 236 #define CHANNEL_MAX 0x0FFFFFFFFUL 237 #else 238 #define CHANNEL_MAX LONG_MAX 239 #endif /* 32- vs 64-bit systems */ 240 241 typedef enum { 242 SSH_ATTRIBUTE_NONE, /* No channel attribute */ 243 SSH_ATTRIBUTE_ACTIVE, /* Channel is active */ 244 SSH_ATTRIBUTE_WINDOWCOUNT, /* Data window count */ 245 SSH_ATTRIBUTE_WINDOWSIZE, /* Data window size */ 246 SSH_ATTRIBUTE_ALTCHANNELNO, /* Secondary channel no. */ 247 SSH_ATTRIBUTE_LAST /* Last channel attribute */ 248 } SSH_ATTRIBUTE_TYPE; 249 250 /* Check whether a DH/ECDH value is valid for a given server key size. The 251 check is slightly different for the ECC version because the value is 252 a composite ECC point with two coordinates, so we have to divide the 253 length by two to get the size of a single coordinate */ 254 255 #define isValidDHsize( value, serverKeySize, extraLength ) \ 256 ( ( value ) > ( ( serverKeySize ) - 8 ) + ( extraLength ) && \ 257 ( value ) < ( ( serverKeySize ) + 2 ) + ( extraLength ) ) 258 #define isValidECDHsize( value, serverKeySize, extraLength ) \ 259 ( ( value ) / 2 > ( ( serverKeySize ) - 8 ) + ( extraLength ) && \ 260 ( value ) / 2 < ( ( serverKeySize ) + 2 ) + ( extraLength ) ) 261 262 /* The following macro can be used to enable dumping of PDUs to disk. As a 263 safeguard, this only works in the Win32 debug version to prevent it from 264 being accidentally enabled in any release version */ 265 266 #if defined( __WIN32__ ) && !defined( NDEBUG ) 267 #define DEBUG_DUMP_SSH( buffer, length, isRead ) \ 268 debugDumpSSH( sessionInfoPtr, buffer, length, isRead ) 269 270 STDC_NONNULL_ARG( ( 1, 2 ) ) \ 271 void debugDumpSSH( const SESSION_INFO *sessionInfoPtr, 272 IN_BUFFER( length ) const void *buffer, 273 IN_LENGTH_SHORT const int length, 274 const BOOLEAN isRead ); 275 #else 276 #define DEBUG_DUMP_SSH( buffer, length, isRead ) 277 #endif /* Win32 debug */ 278 279 /**************************************************************************** 280 * * 281 * SSH Structures * 282 * * 283 ****************************************************************************/ 284 285 /* Mapping of SSH algorithm names to cryptlib algorithm IDs, in preferred 286 algorithm order. Some of the algorithms are pure algorithms while others 287 are more like cipher suites, in order to check whether they're available 288 for use we have to map the suite pseudo-value into one or more actual 289 algorithms, which are given via the checkXXXAlgo values */ 290 291 typedef struct { 292 /* Mapping from algorithm name to cryptlib algorithm ID. The 293 "encryption" algorithm may not be a real cryptlib algorithm type but 294 an SSH-specific pseudo-algorithm in the CRYPT_PSEUDOALGO_xxx 295 range, for example CRYPT_PSEUDOALGO_PASSWORD */ 296 BUFFER_FIXED( nameLen ) \ 297 const char FAR_BSS *name; /* Algorithm name */ 298 const int nameLen; 299 const CRYPT_ALGO_TYPE algo; /* Algorithm ID */ 300 301 /* Optional parameters needed when the algorithm actually represents a 302 cipher suite */ 303 const CRYPT_ALGO_TYPE subAlgo; 304 } ALGO_STRING_INFO; 305 306 /* SSH handshake state information. This is passed around various 307 subfunctions that handle individual parts of the handshake */ 308 309 #ifdef SH 310 /* VxWorks defines 'SH' (for SuperH CPUs), so we have to undefine it to 311 allow the following struct to be declared. The VxWorks include file 312 order is such that it comes after osspec.h is included, so we can't 313 cover up the problem in that */ 314 #undef SH 315 #endif /* SH */ 316 317 struct SH; 318 319 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 320 int ( *SSH_HANDSHAKE_FUNCTION )( INOUT SESSION_INFO *sessionInfoPtr, 321 INOUT struct SH *handshakeInfo ); 322 323 typedef struct SH { 324 /* SSH exchange hash */ 325 BUFFER_FIXED( SSH2_COOKIE_SIZE ) \ 326 BYTE cookie[ SSH2_COOKIE_SIZE + 8 ]; /* Anti-spoofing cookie */ 327 BUFFER_FIXED( CRYPT_MAX_HASHSIZE ) \ 328 BYTE sessionID[ CRYPT_MAX_HASHSIZE + 8 ];/* Session ID/exchange hash */ 329 int sessionIDlength; 330 CRYPT_ALGO_TYPE exchangeHashAlgo; /* Exchange hash algorithm */ 331 CRYPT_CONTEXT iExchangeHashContext, iExchangeHashAltContext; 332 /* Hash of exchanged information */ 333 334 /* Information needed to compute the session ID. SSH requires the 335 client and server DH/ECDH values (along with various other things, 336 but these are hashed inline). The SSH values are in MPI-encoded 337 form so we need to reserve a little extra room for the length and 338 leading zero-padding */ 339 BUFFER( MAX_ENCODED_KEYEXSIZE, clientKeyexValueLength ) \ 340 BYTE clientKeyexValue[ MAX_ENCODED_KEYEXSIZE + 8 ]; 341 BUFFER( MAX_ENCODED_KEYEXSIZE, serverKeyexValueLength ) \ 342 BYTE serverKeyexValue[ MAX_ENCODED_KEYEXSIZE + 8 ]; 343 int clientKeyexValueLength, serverKeyexValueLength; 344 345 /* Encryption algorithm and key information */ 346 CRYPT_ALGO_TYPE pubkeyAlgo; /* Host signature algo */ 347 CRYPT_ALGO_TYPE hashAlgo; /* Host signature hash algo */ 348 BUFFER( CRYPT_MAX_PKCSIZE, secretValueLength ) \ 349 BYTE secretValue[ CRYPT_MAX_PKCSIZE + 8 ]; /* Shared secret value */ 350 int secretValueLength; 351 352 /* DH/ECDH key agreement context and the client requested DH key size 353 for the key exchange. Alongside the actual key size we also store 354 the original encoded form, which has to be hashed as part of the 355 exchange hash. The long-term host key is stored as the session 356 information iKeyexCryptContext for the client and privateKey for the 357 server. Since ECDH doesn't just entail a new algorithm but an 358 entire cipher suite, we provide a flag to make checking for this 359 easier */ 360 CRYPT_ALGO_TYPE keyexAlgo; /* Keyex algo */ 361 CRYPT_CONTEXT iServerCryptContext; 362 int serverKeySize, requestedServerKeySize; 363 BUFFER( ENCODED_REQKEYSIZE, encodedReqKeySizesLength ) \ 364 BYTE encodedReqKeySizes[ ENCODED_REQKEYSIZE + 8 ]; 365 int encodedReqKeySizesLength; 366 BOOLEAN isECDH; /* Use of ECC cipher suite */ 367 368 /* Table mapping SSH algorithm names to cryptlib algorithm IDs. This 369 serves two purposes, firstly by declaring it once in ssh2.c and 370 referring to it via pointers we can make the data static const, which 371 is necessary in some environments to get them into the read-only 372 segment, and secondly for the server where we advertise algorithm X 373 to the client it allows us to switch to a restricted table that only 374 allows algorithm X in return from the client */ 375 const ALGO_STRING_INFO FAR_BSS *algoStringPubkeyTbl; 376 int algoStringPubkeyTblNoEntries; 377 378 /* Function pointers to handshaking functions. These are set up as 379 required depending on whether the session is client or server */ 380 FNPTR_DECLARE( SSH_HANDSHAKE_FUNCTION, beginHandshake ); 381 FNPTR_DECLARE( SSH_HANDSHAKE_FUNCTION, exchangeKeys ); 382 FNPTR_DECLARE( SSH_HANDSHAKE_FUNCTION, completeHandshake ); 383 } SSH_HANDSHAKE_INFO; 384 385 /* Channel number and ID used to mark an unused channel */ 386 387 #define UNUSED_CHANNEL_NO CRYPT_ERROR 388 #define UNUSED_CHANNEL_ID 0 389 390 /**************************************************************************** 391 * * 392 * SSH Functions * 393 * * 394 ****************************************************************************/ 395 396 /* Unlike SSL, SSH only hashes portions of the handshake, and even then not 397 complete packets but arbitrary bits and pieces. In order to perform the 398 hashing, we have to be able to bookmark positions in a stream to allow 399 the data at that point to be hashed once it's been encoded or decoded. 400 The following macros set and complete a bookmark. 401 402 When we create or continue a packet stream, the packet type is written 403 before we can set the bookmark. To handle this, we also provide a macro 404 that sets the bookmark for a full packet by adjusting for the packet type 405 that's already been written */ 406 407 #define streamBookmarkSet( stream, offset ) \ 408 offset = stell( stream ) 409 #define streamBookmarkSetFullPacket( stream, offset ) \ 410 offset = stell( stream ) - ID_SIZE 411 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \ 412 int streamBookmarkComplete( INOUT STREAM *stream, 413 OUT_OPT_PTR void **dataPtrPtr, 414 OUT_DATALENGTH_Z int *length, 415 IN_DATALENGTH const int position ); 416 417 /* Prototypes for functions in ssh2.c */ 418 419 STDC_NONNULL_ARG( ( 1 ) ) \ 420 void initHandshakeCrypt( INOUT SSH_HANDSHAKE_INFO *handshakeInfo ); 421 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \ 422 int hashHandshakeStrings( INOUT SSH_HANDSHAKE_INFO *handshakeInfo, 423 IN_BUFFER( clientStringLength ) \ 424 const void *clientString, 425 IN_LENGTH_SHORT const int clientStringLength, 426 IN_BUFFER( serverStringLength ) \ 427 const void *serverString, 428 IN_LENGTH_SHORT const int serverStringLength ); 429 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4, 6 ) ) \ 430 int readAlgoString( INOUT STREAM *stream, 431 IN_ARRAY( noAlgoStringEntries ) \ 432 const ALGO_STRING_INFO *algoInfo, 433 IN_RANGE( 1, 100 ) const int noAlgoStringEntries, 434 OUT_ALGO_Z CRYPT_ALGO_TYPE *algo, 435 const BOOLEAN useFirstMatch, 436 INOUT ERROR_INFO *errorInfo ); 437 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 438 int writeAlgoString( INOUT STREAM *stream, 439 IN_ALGO const CRYPT_ALGO_TYPE algo ); 440 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 441 int writeAlgoStringEx( INOUT STREAM *stream, 442 IN_ALGO const CRYPT_ALGO_TYPE algo, 443 IN_ALGO_OPT const CRYPT_ALGO_TYPE subAlgo ); 444 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 445 int writeAlgoList( INOUT STREAM *stream, 446 IN_ARRAY( noAlgoStringInfoEntries ) \ 447 const ALGO_STRING_INFO *algoStringInfoTbl, 448 IN_RANGE( 1, 10 ) const int noAlgoStringInfoEntries ); 449 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 450 int writeAlgoClassList( INOUT STREAM *stream, 451 IN_ENUM( SSH_ALGOCLASS ) \ 452 const SSH_ALGOCLASS_TYPE algoClass ); 453 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \ 454 int processHelloSSH( INOUT SESSION_INFO *sessionInfoPtr, 455 INOUT SSH_HANDSHAKE_INFO *handshakeInfo, 456 OUT_LENGTH_SHORT_Z int *keyexLength, 457 const BOOLEAN isServer ); 458 459 /* Prototypes for functions in ssh2_authc.c/ssh2_auths.c */ 460 461 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 462 int processClientAuth( INOUT SESSION_INFO *sessionInfoPtr, 463 INOUT SSH_HANDSHAKE_INFO *handshakeInfo ); 464 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 465 int processServerAuth( INOUT SESSION_INFO *sessionInfoPtr, 466 const BOOLEAN userInfoPresent ); 467 468 /* Prototypes for functions in ssh2_chn.c */ 469 470 typedef enum { CHANNEL_NONE, CHANNEL_READ, CHANNEL_WRITE, 471 CHANNEL_BOTH, CHANNEL_LAST } CHANNEL_TYPE; 472 473 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 474 int createChannel( INOUT SESSION_INFO *sessionInfoPtr ); 475 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \ 476 int addChannel( INOUT SESSION_INFO *sessionInfoPtr, 477 IN const long channelNo, 478 IN_LENGTH_MIN( 1024 ) const int maxPacketSize, 479 IN_BUFFER( typeLen ) const void *type, 480 IN_LENGTH_SHORT const int typeLen, 481 IN_BUFFER_OPT( arg1Len ) const void *arg1, 482 IN_LENGTH_SHORT_Z const int arg1Len ); 483 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 484 int deleteChannel( INOUT SESSION_INFO *sessionInfoPtr, 485 IN const long channelNo, 486 IN_ENUM( CHANNEL ) const CHANNEL_TYPE channelType, 487 const BOOLEAN deleteLastChannel ); 488 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 489 int selectChannel( INOUT SESSION_INFO *sessionInfoPtr, 490 IN const long channelNo, 491 IN_ENUM_OPT( CHANNEL ) const CHANNEL_TYPE channelType ); 492 CHECK_RETVAL_RANGE_NOERROR( UNUSED_CHANNEL_NO, CHANNEL_MAX ) STDC_NONNULL_ARG( ( 1 ) ) \ 493 long getCurrentChannelNo( const SESSION_INFO *sessionInfoPtr, 494 IN_ENUM( CHANNEL ) const CHANNEL_TYPE channelType ); 495 CHECK_RETVAL_ENUM( CHANNEL ) STDC_NONNULL_ARG( ( 1 ) ) \ 496 CHANNEL_TYPE getChannelStatusByChannelNo( const SESSION_INFO *sessionInfoPtr, 497 IN const long channelNo ); 498 CHECK_RETVAL_ENUM( CHANNEL ) STDC_NONNULL_ARG( ( 1 ) ) \ 499 CHANNEL_TYPE getChannelStatusByAddr( const SESSION_INFO *sessionInfoPtr, 500 IN_BUFFER( addrInfoLen ) const char *addrInfo, 501 IN_LENGTH_SHORT const int addrInfoLen ); 502 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 503 int getChannelAttribute( const SESSION_INFO *sessionInfoPtr, 504 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute, 505 OUT_INT_Z int *value ); 506 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 507 int getChannelAttributeS( const SESSION_INFO *sessionInfoPtr, 508 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute, 509 OUT_BUFFER_OPT( dataMaxLength, *dataLength ) \ 510 void *data, 511 IN_LENGTH_SHORT_Z const int dataMaxLength, 512 OUT_LENGTH_BOUNDED_Z( dataMaxLength ) \ 513 int *dataLength ); 514 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 515 int getChannelExtAttribute( const SESSION_INFO *sessionInfoPtr, 516 IN_ENUM( SSH_ATTRIBUTE ) \ 517 const SSH_ATTRIBUTE_TYPE attribute, 518 OUT_INT_Z int *value ); 519 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 520 int setChannelAttribute( INOUT SESSION_INFO *sessionInfoPtr, 521 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute, 522 IN_INT_SHORT const int value ); 523 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \ 524 int setChannelAttributeS( INOUT SESSION_INFO *sessionInfoPtr, 525 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute, 526 IN_BUFFER( dataLength ) const void *data, 527 IN_LENGTH_TEXT const int dataLength ); 528 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 529 int setChannelExtAttribute( const SESSION_INFO *sessionInfoPtr, 530 IN_ATTRIBUTE const SSH_ATTRIBUTE_TYPE attribute, 531 IN_INT_Z const int value ); 532 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 533 int enqueueResponse( INOUT SESSION_INFO *sessionInfoPtr, 534 IN_RANGE( 1, 255 ) const int type, 535 IN_RANGE( 0, 4 ) const int noParams, 536 IN const long channelNo, 537 const int param1, const int param2, const int param3 ); 538 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 539 int sendEnqueuedResponse( INOUT SESSION_INFO *sessionInfoPtr ); 540 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 541 int enqueueChannelData( INOUT SESSION_INFO *sessionInfoPtr, 542 IN_RANGE( 1, 255 ) const int type, 543 IN const long channelNo, 544 const int param ); 545 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 546 int appendChannelData( INOUT SESSION_INFO *sessionInfoPtr, 547 IN_LENGTH_SHORT_Z const int offset ); 548 549 /* Prototypes for functions in ssh2_msg.c */ 550 551 CHECK_RETVAL_RANGE_NOERROR( 10000, MAX_WINDOW_SIZE ) STDC_NONNULL_ARG( ( 1 ) ) \ 552 int getWindowSize( const SESSION_INFO *sessionInfoPtr ); 553 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 554 int closeChannel( INOUT SESSION_INFO *sessionInfoPtr, 555 const BOOLEAN closeAllChannels ); 556 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 557 int processChannelControlMessage( INOUT SESSION_INFO *sessionInfoPtr, 558 INOUT STREAM *stream ); 559 560 /* Prototypes for functions in ssh2_msgc.c */ 561 562 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 563 int sendChannelOpen( INOUT SESSION_INFO *sessionInfoPtr ); 564 565 /* Prototypes for functions in ssh2_msgs.c */ 566 567 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 568 int processChannelOpen( INOUT SESSION_INFO *sessionInfoPtr, 569 INOUT STREAM *stream ); 570 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 571 int processChannelRequest( INOUT SESSION_INFO *sessionInfoPtr, 572 INOUT STREAM *stream, 573 IN const long prevChannelNo ); 574 575 /* Prototypes for functions in ssh2_cry.c */ 576 577 typedef enum { MAC_NONE, MAC_START, MAC_END, MAC_LAST } MAC_TYPE; 578 579 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 580 int initSecurityInfo( INOUT SESSION_INFO *sessionInfoPtr, 581 INOUT SSH_HANDSHAKE_INFO *handshakeInfo ); 582 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 583 int initSecurityContextsSSH( INOUT SESSION_INFO *sessionInfoPtr ); 584 STDC_NONNULL_ARG( ( 1 ) ) \ 585 void destroySecurityContextsSSH( INOUT SESSION_INFO *sessionInfoPtr ); 586 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 587 int initDHcontextSSH( OUT_HANDLE_OPT CRYPT_CONTEXT *iCryptContext, 588 OUT_LENGTH_SHORT_Z int *keySize, 589 IN_BUFFER_OPT( keyDataLength ) const void *keyData, 590 IN_LENGTH_SHORT_Z const int keyDataLength, 591 IN_LENGTH_SHORT_OPT const int requestedKeySize ); 592 #ifdef USE_ECDH 593 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 594 int initECDHcontextSSH( OUT_HANDLE_OPT CRYPT_CONTEXT *iCryptContext, 595 OUT_LENGTH_SHORT_Z int *keySize, 596 IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo ); 597 #endif /* USE_ECDH */ 598 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 599 int completeKeyex( INOUT SESSION_INFO *sessionInfoPtr, 600 INOUT SSH_HANDSHAKE_INFO *handshakeInfo, 601 const BOOLEAN isServer ); 602 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \ 603 int hashAsString( IN_HANDLE const CRYPT_CONTEXT iHashContext, 604 IN_BUFFER( dataLength ) const BYTE *data, 605 IN_LENGTH_SHORT const int dataLength ); 606 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \ 607 int hashAsMPI( IN_HANDLE const CRYPT_CONTEXT iHashContext, 608 IN_BUFFER( dataLength ) const BYTE *data, 609 IN_LENGTH_SHORT const int dataLength ); 610 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 611 int checkMacSSH( IN_HANDLE const CRYPT_CONTEXT iMacContext, 612 IN_INT const long seqNo, 613 IN_BUFFER( dataMaxLength ) const BYTE *data, 614 IN_DATALENGTH const int dataMaxLength, 615 IN_DATALENGTH_Z const int dataLength, 616 IN_RANGE( 16, CRYPT_MAX_HASHSIZE ) const int macLength ); 617 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 618 int checkMacSSHIncremental( IN_HANDLE const CRYPT_CONTEXT iMacContext, 619 IN_INT_Z const long seqNo, 620 IN_BUFFER( dataMaxLength ) const BYTE *data, 621 IN_DATALENGTH const int dataMaxLength, 622 IN_DATALENGTH_Z const int dataLength, 623 IN_DATALENGTH_Z const int packetDataLength, 624 IN_ENUM( MAC ) const MAC_TYPE macType, 625 IN_RANGE( 16, CRYPT_MAX_HASHSIZE ) const int macLength ); 626 CHECK_RETVAL STDC_NONNULL_ARG( ( 3 ) ) \ 627 int createMacSSH( IN_HANDLE const CRYPT_CONTEXT iMacContext, 628 IN_INT const long seqNo, 629 IN_BUFFER( dataMaxLength ) BYTE *data, 630 IN_DATALENGTH const int dataMaxLength, 631 IN_DATALENGTH const int dataLength ); 632 633 /* Prototypes for functions in ssh2_rd.c */ 634 635 CHECK_RETVAL_PTR_NONNULL \ 636 const char *getSSHPacketName( IN_RANGE( 0, 255 ) const int packetType ); 637 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \ 638 int readPacketHeaderSSH2( INOUT SESSION_INFO *sessionInfoPtr, 639 IN_RANGE( SSH_MSG_DISCONNECT, \ 640 SSH_MSG_SPECIAL_REQUEST ) \ 641 const int expectedType, 642 OUT_LENGTH_Z long *packetLength, 643 OUT_DATALENGTH_Z int *packetExtraLength, 644 INOUT SSH_INFO *sshInfo, 645 INOUT_OPT READSTATE_INFO *readInfo ); 646 CHECK_RETVAL_LENGTH_SHORT STDC_NONNULL_ARG( ( 1 ) ) \ 647 int readHSPacketSSH2( INOUT SESSION_INFO *sessionInfoPtr, 648 IN_RANGE( SSH_MSG_DISCONNECT, \ 649 SSH_MSG_SPECIAL_REQUEST ) \ 650 int expectedType, 651 IN_RANGE( 1, 1024 ) const int minPacketSize ); 652 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 653 int getDisconnectInfo( INOUT SESSION_INFO *sessionInfoPtr, 654 INOUT STREAM *stream ); 655 656 /* Prototypes for functions in ssh2_wr.c */ 657 658 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 659 int openPacketStreamSSH( OUT STREAM *stream, 660 const SESSION_INFO *sessionInfoPtr, 661 IN_RANGE( SSH_MSG_DISCONNECT, \ 662 SSH_MSG_CHANNEL_FAILURE ) 663 const int packetType ); 664 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 665 int openPacketStreamSSHEx( OUT STREAM *stream, 666 const SESSION_INFO *sessionInfoPtr, 667 IN_DATALENGTH const int bufferSize, 668 IN_RANGE( SSH_MSG_DISCONNECT, \ 669 SSH_MSG_CHANNEL_FAILURE ) 670 const int packetType ); 671 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \ 672 int continuePacketStreamSSH( INOUT STREAM *stream, 673 IN_RANGE( SSH_MSG_DISCONNECT, \ 674 SSH_MSG_CHANNEL_FAILURE ) \ 675 const int packetType, 676 OUT_DATALENGTH_Z int *packetOffset ); 677 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 678 int wrapPacketSSH2( INOUT SESSION_INFO *sessionInfoPtr, 679 INOUT STREAM *stream, 680 IN_DATALENGTH_Z const int offset, 681 const BOOLEAN useQuantisedPadding, 682 const BOOLEAN isWriteableStream ); 683 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 684 int sendPacketSSH2( INOUT SESSION_INFO *sessionInfoPtr, 685 INOUT STREAM *stream, 686 const BOOLEAN sendOnly ); 687 688 /* Prototypes for session mapping functions */ 689 690 STDC_NONNULL_ARG( ( 1 ) ) \ 691 void initSSH2processing( INOUT SESSION_INFO *sessionInfoPtr ); 692 STDC_NONNULL_ARG( ( 1 ) ) \ 693 void initSSH2clientProcessing( INOUT SSH_HANDSHAKE_INFO *handshakeInfo ); 694 STDC_NONNULL_ARG( ( 1 ) ) \ 695 void initSSH2serverProcessing( INOUT SSH_HANDSHAKE_INFO *handshakeInfo ); 696 #endif /* _SSH_DEFINED */ 697