cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
ssh.h
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * SSHv1/SSHv2 Definitions Header File *
4 * Copyright Peter Gutmann 1998-2008 *
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 SSH1_COOKIE_SIZE 8 /* Size of SSHv1 cookie */
35 #define SSH1_HEADER_SIZE 5 /* Size of SSHv1 packet header */
36 #define SSH1_CRC_SIZE 4 /* Size of CRC value */
37 #define SSH1_MPI_LENGTH_SIZE 2 /* Size of MPI length field */
38 #define SSH1_SESSIONID_SIZE 16 /* Size of SSHv1 session ID */
39 #define SSH1_SECRET_SIZE 32 /* Size of SSHv1 shared secret */
40 #define SSH1_CHALLENGE_SIZE 32 /* Size of SSHv1 RSA auth.challenge */
41 #define SSH1_RESPONSE_SIZE 16 /* Size of SSHv1 RSA auth.response */
42 
43 #define SSH2_COOKIE_SIZE 16 /* Size of SSHv2 cookie */
44 #define SSH2_HEADER_SIZE 5 /* Size of SSHv2 packet header */
45 #define SSH2_MIN_ALGOID_SIZE 4 /* Size of shortest SSHv2 algo.name */
46 #define SSH2_MIN_PADLENGTH_SIZE 4 /* Minimum amount of padding for packets */
47 #define SSH2_PAYLOAD_HEADER_SIZE 9 /* Size of SSHv2 inner payload header */
48 #define SSH2_FIXED_KEY_SIZE 16 /* Size of SSHv2 fixed-size keys */
49 #define SSH2_DEFAULT_KEYSIZE 128 /* Size of SSHv2 default DH key */
50 
51 /* SSH packet/buffer size information. The extra packet data is for
52  additional non-payload information including the header, MAC, and up to
53  256 bytes of padding */
54 
55 #define MAX_PACKET_SIZE 262144L
56 #define EXTRA_PACKET_SIZE 512
57 #define DEFAULT_PACKET_SIZE 16384
58 #define MAX_WINDOW_SIZE ( MAX_INTLENGTH - 8192 )
59 
60 /* By default cryptlib uses DH key agreement, which is supported by all
61  servers. It's also possible to use ECDH key agreement, however due to
62  SSH's braindamaged way of choosing algorithms the peer will always go
63  for ECDH if it can handle it (see the comment in sesion/ssh2_svr.c for
64  more on this), so we disable ECDH by default. To use ECDH key agreement
65  in preference to DH, uncomment the following */
66 
67 /* #define PREFER_ECC_SUITES */
68 #if defined( PREFER_ECC_SUITES ) && defined( _MSC_VER )
69  #pragma message( " Building with ECC preferred for SSH." )
70 #endif /* PREFER_ECC_SUITES && Visual C++ */
71 #if defined( PREFER_ECC_SUITES ) && \
72  !( defined( USE_ECDH ) && defined( USE_ECDSA ) )
73  #error PREFER_ECC_SUITES can only be used with ECDH and ECDSA enabled
74 #endif /* PREFER_ECC_SUITES && !( USE_ECDH && USE_ECDSA ) */
75 
76 /* SSH protocol-specific flags that encode details of implementation bugs
77  that we need to work around */
78 
79 #define SSH_PFLAG_NONE 0x0000/* No protocol-specific flags */
80 #define SSH_PFLAG_HMACKEYSIZE 0x0001/* Peer uses short HMAC keys */
81 #define SSH_PFLAG_SIGFORMAT 0x0002/* Peer omits signature algo name */
82 #define SSH_PFLAG_NOHASHSECRET 0x0004/* Peer omits secret in key derive */
83 #define SSH_PFLAG_NOHASHLENGTH 0x0008/* Peer omits length in exchange hash */
84 #define SSH_PFLAG_RSASIGPAD 0x0010/* Peer requires zero-padded RSA sig.*/
85 #define SSH_PFLAG_WINDOWSIZE 0x0020/* Peer mishandles large window sizes */
86 #define SSH_PFLAG_TEXTDIAGS 0x0040/* Peer dumps text diagnostics on error */
87 #define SSH_PFLAG_PAMPW 0x0080/* Peer chokes on "password" as PAM submethod */
88 #define SSH_PFLAG_DUMMYUSERAUTH 0x0100/* Peer requires dummy userAuth message */
89 #define SSH_PFLAG_EMPTYUSERAUTH 0x0200/* Peer sends empty userauth-failure response */
90 #define SSH_PFLAG_ZEROLENIGNORE 0x0400/* Peer sends zero-length SSH_IGNORE */
91 #define SSH_PFLAG_ASYMMCOPR 0x0800/* Peer sends asymmetric compression algos */
92 #define SSH_PFLAG_EMPTYSVCACCEPT 0x1000/* Peer sends empty SSH_SERVICE_ACCEPT */
93 #define SSH_PFLAG_CUTEFTP 0x2000/* CuteFTP, drops conn.during handshake */
94 #define SSH_PFLAG_MAX 0x3FFF/* Maximum possible flag value */
95 
96 /* Various data sizes used for read-ahead and buffering. The minimum SSH
97  packet size is used to determine how much data we can read when reading
98  a packet header, the SSHv2 header remainder size is how much data we've
99  got left once we've extracted just the length but no other data, the
100  SSHv2 remainder size is how much data we've got left once we've
101  extracted all fixed information values, and the SSHv1 maximum header size
102  is used to determine how much space we need to reserve at the start of
103  the buffer when encoding SSHv1's variable-length data packets (SSHv2 has
104  a fixed header size so this isn't a problem any more) */
105 
106 #define MIN_PACKET_SIZE 16
107 #define SSH2_HEADER_REMAINDER_SIZE \
108  ( MIN_PACKET_SIZE - LENGTH_SIZE )
109 #define SSH1_MAX_HEADER_SIZE ( LENGTH_SIZE + 8 + ID_SIZE + LENGTH_SIZE )
110 
111 /* SSH ID information */
112 
113 #define SSH_ID "SSH-" /* Start of SSH ID */
114 #define SSH_ID_SIZE 4 /* Size of SSH ID */
115 #define SSH_VERSION_SIZE 4 /* Size of SSH version */
116 #define SSH_ID_MAX_SIZE 255 /* Max.size of SSHv2 ID string */
117 #define SSH1_ID_STRING "SSH-1.5-cryptlib"
118 #define SSH2_ID_STRING "SSH-2.0-cryptlib" /* cryptlib SSH ID strings */
119 #define SSH_ID_STRING_SIZE 16 /* Size of ID strings */
120 
121 /* SSHv1 packet types */
122 
123 #define SSH1_MSG_DISCONNECT 1 /* Disconnect session */
124 #define SSH1_SMSG_PUBLIC_KEY 2 /* Server public key */
125 #define SSH1_CMSG_SESSION_KEY 3 /* Encrypted session key */
126 #define SSH1_CMSG_USER 4 /* User name */
127 #define SSH1_CMSG_AUTH_RSA 6 /* RSA public key */
128 #define SSH1_SMSG_AUTH_RSA_CHALLENGE 7 /* RSA challenge from server */
129 #define SSH1_CMSG_AUTH_RSA_RESPONSE 8 /* RSA response from client */
130 #define SSH1_CMSG_AUTH_PASSWORD 9 /* Password */
131 #define SSH1_CMSG_REQUEST_PTY 10 /* Request a pty */
132 #define SSH1_CMSG_WINDOW_SIZE 11 /* Terminal window size change */
133 #define SSH1_CMSG_EXEC_SHELL 12 /* Request a shell */
134 #define SSH1_CMSG_EXEC_CMD 13 /* Request command execution */
135 #define SSH1_SMSG_SUCCESS 14 /* Success status message */
136 #define SSH1_SMSG_FAILURE 15 /* Failure status message */
137 #define SSH1_CMSG_STDIN_DATA 16 /* Data from client stdin */
138 #define SSH1_SMSG_STDOUT_DATA 17 /* Data from server stdout */
139 #define SSH1_SMSG_EXITSTATUS 20 /* Exit status of command run on server */
140 #define SSH1_MSG_IGNORE 32 /* No-op */
141 #define SSH1_CMSG_EXIT_CONFIRMATION 33 /* Client response to server exitstatus */
142 #define SSH1_MSG_DEBUG 36 /* Debugging/informational message */
143 #define SSH1_CMSG_MAX_PACKET_SIZE 38 /* Maximum data packet size */
144 
145 /* Further SSHv1 packet types that aren't used but which we need to
146  recognise */
147 
148 #define SSH1_CMSG_PORT_FORWARD_REQUEST 28
149 #define SSH1_CMSG_AGENT_REQUEST_FORWARDING 30
150 #define SSH1_CMSG_X11_REQUEST_FORWARDING 34
151 #define SSH1_CMSG_REQUEST_COMPRESSION 37
152 
153 /* SSHv1 cipher types */
154 
155 #define SSH1_CIPHER_NONE 0 /* No encryption */
156 #define SSH1_CIPHER_IDEA 1 /* IDEA/CFB */
157 #define SSH1_CIPHER_DES 2 /* DES/CBC */
158 #define SSH1_CIPHER_3DES 3 /* 3DES/inner-CBC (nonstandard) */
159 #define SSH1_CIPHER_TSS 4 /* Deprecated */
160 #define SSH1_CIPHER_RC4 5 /* RC4 */
161 #define SSH1_CIPHER_BLOWFISH 6 /* Blowfish */
162 #define SSH1_CIPHER_CRIPPLED 7 /* Reserved, from ssh 1.2.x source */
163 
164 /* SSHv1 authentication types */
165 
166 #define SSH1_AUTH_RHOSTS 1 /* .rhosts or /etc/hosts.equiv */
167 #define SSH1_AUTH_RSA 2 /* RSA challenge-response */
168 #define SSH1_AUTH_PASSWORD 3 /* Password */
169 #define SSH1_AUTH_RHOSTS_RSA 4 /* .rhosts with RSA challenge-response */
170 #define SSH1_AUTH_TIS 5 /* TIS authsrv */
171 #define SSH1_AUTH_KERBEROS 6 /* Kerberos */
172 #define SSH1_PASS_KERBEROS_TGT 7 /* Kerberos TGT-passing */
173 
174 /* SSHv2 packet types. There is some overlap with SSHv1, but an annoying
175  number of messages have the same name but different values. Note also
176  that the keyex (static DH keys), keyex_gex (ephemeral DH keys), and
177  keyex_ecdh (static ECDH keys) message types overlap */
178 
179 #define SSH_MSG_DISCONNECT 1 /* Disconnect session */
180 #define SSH_MSG_IGNORE 2 /* No-op */
181 #define SSH_MSG_DEBUG 4 /* No-op */
182 #define SSH_MSG_SERVICE_REQUEST 5 /* Request authentiction */
183 #define SSH_MSG_SERVICE_ACCEPT 6 /* Acknowledge request */
184 #define SSH_MSG_KEXINIT 20 /* Hello */
185 #define SSH_MSG_NEWKEYS 21 /* Change cipherspec */
186 #define SSH_MSG_KEXDH_INIT 30 /* DH, phase 1 */
187 #define SSH_MSG_KEXDH_REPLY 31 /* DH, phase 2 */
188 #define SSH_MSG_KEXDH_GEX_REQUEST_OLD 30 /* Ephem.DH key request */
189 #define SSH_MSG_KEXDH_GEX_GROUP 31 /* Ephem.DH key response */
190 #define SSH_MSG_KEXDH_GEX_INIT 32 /* Ephem.DH, phase 1 */
191 #define SSH_MSG_KEXDH_GEX_REPLY 33 /* Ephem.DH, phase 2 */
192 #define SSH_MSG_KEXDH_GEX_REQUEST_NEW 34 /* Ephem.DH key request */
193 #define SSH_MSG_KEX_ECDH_INIT 30 /* ECDH, phase 1 */
194 #define SSH_MSG_KEX_ECDH_REPLY 31 /* ECDH, phase 2 */
195 #define SSH_MSG_USERAUTH_REQUEST 50 /* Request authentication */
196 #define SSH_MSG_USERAUTH_FAILURE 51 /* Authentication failed */
197 #define SSH_MSG_USERAUTH_SUCCESS 52 /* Authentication succeeded */
198 #define SSH_MSG_USERAUTH_BANNER 53 /* No-op */
199 #define SSH_MSG_USERAUTH_INFO_REQUEST 60 /* Generic auth.svr.request */
200 #define SSH_MSG_USERAUTH_INFO_RESPONSE 61 /* Generic auth.cli.response */
201 #define SSH_MSG_GLOBAL_REQUEST 80 /* Perform a global ioctl */
202 #define SSH_MSG_GLOBAL_SUCCESS 81 /* Global request succeeded */
203 #define SSH_MSG_GLOBAL_FAILURE 82 /* Global request failed */
204 #define SSH_MSG_CHANNEL_OPEN 90 /* Open a channel over an SSH link */
205 #define SSH_MSG_CHANNEL_OPEN_CONFIRMATION 91 /* Channel open succeeded */
206 #define SSH_MSG_CHANNEL_OPEN_FAILURE 92 /* Channel open failed */
207 #define SSH_MSG_CHANNEL_WINDOW_ADJUST 93 /* No-op */
208 #define SSH_MSG_CHANNEL_DATA 94 /* Data */
209 #define SSH_MSG_CHANNEL_EXTENDED_DATA 95 /* Out-of-band data */
210 #define SSH_MSG_CHANNEL_EOF 96 /* EOF */
211 #define SSH_MSG_CHANNEL_CLOSE 97 /* Close the channel */
212 #define SSH_MSG_CHANNEL_REQUEST 98 /* Perform a channel ioctl */
213 #define SSH_MSG_CHANNEL_SUCCESS 99 /* Channel request succeeded */
214 #define SSH_MSG_CHANNEL_FAILURE 100/* Channel request failed */
215 
216 /* Special-case expected-packet-type values that are passed to
217  readHSPacketSSH() to handle situations where more than one return value is
218  valid. CMSG_USER can return failure meaning "no password" even if
219  there's no actual failure, CMSG_AUTH_PASSWORD can return SMSG_FAILURE
220  which indicates a wrong password used iff it's a response to the client
221  sending a password, and MSG_USERAUTH_REQUEST can similarly return a
222  failure or success response.
223 
224  In addition to these types there's an "any" type which is used during the
225  setup negotiation which will accept any (non-error) packet type and return
226  the type as the return code */
227 
228 #define SSH1_MSG_SPECIAL_USEROPT 500 /* Value to handle SSHv1 user name */
229 #define SSH1_MSG_SPECIAL_PWOPT 501 /* Value to handle SSHv1 password */
230 #define SSH1_MSG_SPECIAL_RSAOPT 502 /* Value to handle SSHv1 RSA challenge */
231 #define SSH1_MSG_SPECIAL_ANY 503 /* Any SSHv1 packet type */
232 
233 #define SSH_MSG_SPECIAL_FIRST 500 /* Boundary for _SPECIAL types */
234 #define SSH_MSG_SPECIAL_USERAUTH 501 /* Value to handle SSHv2 combined auth.*/
235 #define SSH_MSG_SPECIAL_USERAUTH_PAM 502 /* Value to handle SSHv2 PAM auth.*/
236 #define SSH_MSG_SPECIAL_CHANNEL 503 /* Value to handle channel open */
237 #define SSH_MSG_SPECIAL_REQUEST 504 /* Value to handle SSHv2 global/channel req.*/
238 #define SSH_MSG_SPECIAL_LAST 505 /* Last valid _SPECIAL type */
239 
240 /* SSHv2 disconnection codes */
241 
242 #define SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT 1
243 #define SSH_DISCONNECT_PROTOCOL_ERROR 2
244 #define SSH_DISCONNECT_KEY_EXCHANGE_FAILED 3
245 #define SSH_DISCONNECT_RESERVED 4
246 #define SSH_DISCONNECT_MAC_ERROR 5
247 #define SSH_DISCONNECT_COMPRESSION_ERROR 6
248 #define SSH_DISCONNECT_SERVICE_NOT_AVAILABLE 7
249 #define SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED 8
250 #define SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE 9
251 #define SSH_DISCONNECT_CONNECTION_LOST 10
252 #define SSH_DISCONNECT_BY_APPLICATION 11
253 #define SSH_DISCONNECT_TOO_MANY_CONNECTIONS 12
254 #define SSH_DISCONNECT_AUTH_CANCELLED_BY_USER 13
255 #define SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE 14
256 #define SSH_DISCONNECT_ILLEGAL_USER_NAME 15
257 
258 /* SSHv2 channel open failure codes */
259 
260 #define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1
261 #define SSH_OPEN_CONNECT_FAILED 2
262 #define SSH_OPEN_UNKNOWN_CHANNEL_TYPE 3
263 #define SSH_OPEN_RESOURCE_SHORTAGE 4
264 
265 /* SSHv2 requires the use of a number of additional (pseudo)-algorithm
266  types that don't correspond to normal cryptlib algorithms. To handle
267  these, we define pseudo-algoID values that fall within the range of
268  the normal algorithm ID types but that aren't normal algorithm IDs.
269 
270  The difference between CRYPT_PSEUDOALGO_DHE and CRYPT_PSEUDOALGO_DHE_ALT
271  is that the former uses SHA-1 and the latter uses a hastily-kludged-
272  on SHA-256 that was added shortly before the RFC was published, so
273  that the PRF uses SHA-256 but all other portions of the protocol still
274  use SHA-1.
275 
276  The ECC (pseudo-)algorithm types are even messier since they're not just
277  algorithm values but a combination of the algorithm, the key size, and
278  the hash algorithm, with CRYPT_ALGO_ECDH/CRYPT_ALGO_ECDSA being the
279  default P256 curve with SHA-256 and the others being different curve
280  types and hashes. Because the curve types are tied to the oddball SHA-2
281  hash variants (we can't just use SHA-256 for every curve), we don't
282  support P384 and P512 because we'd have to support an entirely new (and
283  64-bit-only) hash algorithm for each of the curves. Because of this the
284  values for P384/P512 are defined below, but disabled in the code */
285 
286 #define CRYPT_PSEUDOALGO_DHE ( CRYPT_ALGO_LAST_CONVENTIONAL - 9 )
287 #define CRYPT_PSEUDOALGO_DHE_ALT ( CRYPT_ALGO_LAST_CONVENTIONAL - 8 )
288 #define CRYPT_PSEUDOALGO_ECDH_P384 ( CRYPT_ALGO_LAST_CONVENTIONAL - 7 )
289 #define CRYPT_PSEUDOALGO_ECDH_P521 ( CRYPT_ALGO_LAST_CONVENTIONAL - 6 )
290 #define CRYPT_PSEUDOALGO_ECDSA_P384 ( CRYPT_ALGO_LAST_CONVENTIONAL - 5 )
291 #define CRYPT_PSEUDOALGO_ECDSA_P521 ( CRYPT_ALGO_LAST_CONVENTIONAL - 4 )
292 #define CRYPT_PSEUDOALGO_COPR ( CRYPT_ALGO_LAST_CONVENTIONAL - 3 )
293 #define CRYPT_PSEUDOALGO_PASSWORD ( CRYPT_ALGO_LAST_CONVENTIONAL - 2 )
294 #define CRYPT_PSEUDOALGO_PAM ( CRYPT_ALGO_LAST_CONVENTIONAL - 1 )
295 
296 /* The size of the encoded DH keyex value and the requested DHE key size,
297  which we have to store in encoded form so that we can hash them later in
298  the handshake */
299 
300 #define MAX_ENCODED_KEYEXSIZE ( CRYPT_MAX_PKCSIZE + 16 )
301 #define ENCODED_REQKEYSIZE ( UINT_SIZE * 3 )
302 
303 /* Check whether an algorithm ID is one of the above pseudo-algorithm
304  types */
305 
306 #define isPseudoAlgo( algorithm ) \
307  ( algorithm >= CRYPT_PSEUDOALGO_DHE && \
308  algorithm <= CRYPT_PSEUDOALGO_PAM )
309 
310 /* When working with SSH channels there are a number of SSH-internal
311  attributes that aren't exposed as cryptlib-wide attribute types. The
312  following values are used to access SSH-internal channel attributes */
313 
314 typedef enum {
315  SSH_ATTRIBUTE_NONE, /* No channel attribute */
316  SSH_ATTRIBUTE_ACTIVE, /* Channel is active */
317  SSH_ATTRIBUTE_WINDOWCOUNT, /* Data window count */
318  SSH_ATTRIBUTE_WINDOWSIZE, /* Data window size */
319  SSH_ATTRIBUTE_ALTCHANNELNO, /* Secondary channel no. */
320  SSH_ATRIBUTE_LAST /* Last channel attribute */
322 
323 /* Check whether a DH/ECDH value is valid for a given server key size. The
324  check is slightly different for the ECC version because the value is
325  a composite ECC point with two coordinates, so we have to divide the
326  length by two to get the size of a single coordinate */
327 
328 #define isValidDHsize( value, serverKeySize, extraLength ) \
329  ( ( value ) > ( ( serverKeySize ) - 8 ) + ( extraLength ) && \
330  ( value ) < ( ( serverKeySize ) + 2 ) + ( extraLength ) )
331 #define isValidECDHsize( value, serverKeySize, extraLength ) \
332  ( ( value ) / 2 > ( ( serverKeySize ) - 8 ) + ( extraLength ) && \
333  ( value ) / 2 < ( ( serverKeySize ) + 2 ) + ( extraLength ) )
334 
335 /****************************************************************************
336 * *
337 * SSH Structures *
338 * *
339 ****************************************************************************/
340 
341 /* Mapping of SSHv2 algorithm names to cryptlib algorithm IDs, in preferred
342  algorithm order. Some of the algorithms are pure algorithms while others
343  are more like cipher suites, in order to check whether they're available
344  for use we have to map the suite pseudo-value into one or more actual
345  algorithms, which are given via the checkXXXAlgo values */
346 
347 typedef struct {
348  /* Mapping from algorithm name to cryptlib algorithm ID */
349  BUFFER_FIXED( nameLen ) \
350  const char FAR_BSS *name; /* Algorithm name */
351  const int nameLen;
352  const CRYPT_ALGO_TYPE algo; /* Algorithm ID */
353 
354  /* Optional parameters needed to check for algorithm availability
355  when the algorithm actually represents a cipher suite */
356  const CRYPT_ALGO_TYPE checkCryptAlgo, checkHashAlgo;
358 
359 /* SSH handshake state information. This is passed around various
360  subfunctions that handle individual parts of the handshake */
361 
362 typedef struct SH {
363  /* SSHv1 session state information/SSHv2 exchange hash */
365  BYTE cookie[ SSH2_COOKIE_SIZE + 8 ]; /* Anti-spoofing cookie */
367  BYTE sessionID[ CRYPT_MAX_HASHSIZE + 8 ];/* Session ID/exchange hash */
369  CRYPT_ALGO_TYPE exchangeHashAlgo; /* Exchange hash algorithm */
371  /* Hash of exchanged information */
372 
373  /* Information needed to compute the session ID. SSHv1 requires the
374  host and server key modulus, SSHv2 requires the client and server
375  DH/ECDH values (along with various other things, but these are hashed
376  inline). The SSHv2 values are in MPI-encoded form so we need to
377  reserve a little extra room for the length and leading zero-padding.
378  Since the data fields are rather large and also disjoint, and since
379  SSHv1 is pretty much dead and therefore not worth going out of our
380  way to accomodate) we alias one to the other to save space */
382  BYTE clientKeyexValue[ MAX_ENCODED_KEYEXSIZE + 8 ];
384  BYTE serverKeyexValue[ MAX_ENCODED_KEYEXSIZE + 8 ];
386  #define hostModulus clientKeyexValue
387  #define serverModulus serverKeyexValue
388  #define hostModulusLength clientKeyexValueLength
389  #define serverModulusLength serverKeyexValueLength
390 
391  /* Encryption algorithm and key information */
392  CRYPT_ALGO_TYPE pubkeyAlgo; /* Host signature algo */
394  BYTE secretValue[ CRYPT_MAX_PKCSIZE + 8 ]; /* Shared secret value */
396 
397  /* Short-term server key (SSHv1) or DH/ECDH key agreement context
398  (SSHv2), and the client requested DH key size for the SSHv2 key
399  exchange. Alongside the actual key size we also store the
400  original encoded form, which has to be hashed as part of the exchange
401  hash. The long-term host key is stored as the session information
402  iKeyexCryptContext for the client and privateKey for the server.
403  Since ECDH doesn't just entail a new algorithm but an entire cipher
404  suite, we provide a flag to make checking for this easier */
405  CRYPT_ALGO_TYPE keyexAlgo; /* Keyex algo */
409  BYTE encodedReqKeySizes[ ENCODED_REQKEYSIZE + 8 ];
411  BOOLEAN isECDH; /* Use of ECC cipher suite */
412 
413  /* Tables mapping SSHv2 algorithm names to cryptlib algorithm IDs.
414  These are declared once in ssh2.c and referred to here via pointers
415  to allow them to be static const, which is necessary in some
416  environments to get them into the read-only segment */
419 
420  /* Function pointers to handshaking functions. These are set up as
421  required depending on whether the protocol being used is v1 or v2,
422  and the session is client or server */
424  int ( *beginHandshake )( INOUT SESSION_INFO *sessionInfoPtr,
425  INOUT struct SH *handshakeInfo );
427  int ( *exchangeKeys )( INOUT SESSION_INFO *sessionInfoPtr,
428  INOUT struct SH *handshakeInfo );
430  int ( *completeHandshake )( INOUT SESSION_INFO *sessionInfoPtr,
431  INOUT struct SH *handshakeInfo );
433 
434 /* Channel number and ID used to mark an unused channel */
435 
436 #define UNUSED_CHANNEL_NO CRYPT_ERROR
437 #define UNUSED_CHANNEL_ID 0
438 
439 /****************************************************************************
440 * *
441 * SSH Functions *
442 * *
443 ****************************************************************************/
444 
445 /* Unlike SSL, SSH only hashes portions of the handshake, and even then not
446  complete packets but arbitrary bits and pieces. In order to perform the
447  hashing, we have to be able to bookmark positions in a stream to allow
448  the data at that point to be hashed once it's been encoded or decoded.
449  The following macros set and complete a bookmark.
450 
451  When we create or continue a packet stream, the packet type is written
452  before we can set the bookmark. To handle this, we also provide a macro
453  that sets the bookmark for a full packet by adjusting for the packet type
454  that's already been written */
455 
456 #define streamBookmarkSet( stream, offset ) \
457  offset = stell( stream )
458 #define streamBookmarkSetFullPacket( stream, offset ) \
459  offset = stell( stream ) - ID_SIZE
460 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
461 int streamBookmarkComplete( INOUT STREAM *stream,
463  OUT_LENGTH_Z int *length,
464  IN_LENGTH const int position );
465 
466 /* Prototypes for functions in ssh2.c */
467 
468 CHECK_RETVAL \
469 int getAlgoStringInfo( OUT const ALGO_STRING_INFO **algoStringInfoPtrPtr,
470  OUT_INT_Z int *noInfoEntries );
471 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4, 6 ) ) \
472 int readAlgoString( INOUT STREAM *stream,
473  IN_ARRAY( noAlgoStringEntries ) \
474  const ALGO_STRING_INFO *algoInfo,
475  IN_RANGE( 1, 100 ) const int noAlgoStringEntries,
477  const BOOLEAN useFirstMatch,
480 int writeAlgoString( INOUT STREAM *stream,
481  IN_ALGO const CRYPT_ALGO_TYPE algo );
482 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
483 int processHelloSSH( INOUT SESSION_INFO *sessionInfoPtr,
486  const BOOLEAN isServer );
487 
488 /* Prototypes for functions in ssh2_authc.c/ssh2_auths.c */
489 
490 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
491 int processClientAuth( INOUT SESSION_INFO *sessionInfoPtr,
494 int processServerAuth( INOUT SESSION_INFO *sessionInfoPtr,
496 
497 /* Prototypes for functions in ssh2_chn.c */
498 
501 
503 int createChannel( INOUT SESSION_INFO *sessionInfoPtr );
504 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
505 int addChannel( INOUT SESSION_INFO *sessionInfoPtr,
506  IN const long channelNo,
507  IN_LENGTH_MIN( 1024 ) const int maxPacketSize,
508  IN_BUFFER( typeLen ) const void *type,
510  IN_BUFFER_OPT( arg1Len ) const void *arg1,
513 int deleteChannel( INOUT SESSION_INFO *sessionInfoPtr,
514  IN const long channelNo,
515  IN_ENUM( CHANNEL ) const CHANNEL_TYPE channelType,
518 int selectChannel( INOUT SESSION_INFO *sessionInfoPtr,
519  IN const long channelNo,
520  IN_ENUM_OPT( CHANNEL ) const CHANNEL_TYPE channelType );
521 CHECK_RETVAL_RANGE( 1, LONG_MAX ) STDC_NONNULL_ARG( ( 1 ) ) \
522 long getCurrentChannelNo( const SESSION_INFO *sessionInfoPtr,
523  IN_ENUM( CHANNEL ) const CHANNEL_TYPE channelType );
524 CHECK_RETVAL_ENUM( CHANNEL ) STDC_NONNULL_ARG( ( 1 ) ) \
525 CHANNEL_TYPE getChannelStatusByChannelNo( const SESSION_INFO *sessionInfoPtr,
526  IN const long channelNo );
527 CHECK_RETVAL_ENUM( CHANNEL ) STDC_NONNULL_ARG( ( 1 ) ) \
528 CHANNEL_TYPE getChannelStatusByAddr( const SESSION_INFO *sessionInfoPtr,
529  IN_BUFFER( addrInfoLen ) const char *addrInfo,
532 int getChannelAttribute( const SESSION_INFO *sessionInfoPtr,
534  OUT_INT_Z int *value );
536 int getChannelAttributeS( const SESSION_INFO *sessionInfoPtr,
539  void *data,
540  IN_LENGTH_SHORT_Z const int dataMaxLength,
543 int getChannelExtAttribute( const SESSION_INFO *sessionInfoPtr,
544  IN_ENUM( SSH_ATTRIBUTE ) \
545  const SSH_ATTRIBUTE_TYPE attribute,
546  OUT_INT_Z int *value );
548 int setChannelAttribute( INOUT SESSION_INFO *sessionInfoPtr,
550  IN_INT_SHORT const int value );
551 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
552 int setChannelAttributeS( INOUT SESSION_INFO *sessionInfoPtr,
554  IN_BUFFER( dataLength ) const void *data,
555  IN_RANGE( 1, CRYPT_MAX_TEXTSIZE ) const int dataLength );
556 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
557 int setChannelExtAttribute( const SESSION_INFO *sessionInfoPtr,
559  IN_INT_Z const int value );
560 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
561 int enqueueResponse( INOUT SESSION_INFO *sessionInfoPtr,
562  IN_RANGE( 1, 255 ) const int type,
563  IN_RANGE( 0, 4 ) const int noParams,
564  IN const long channelNo,
565  const int param1, const int param2, const int param3 );
566 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
567 int sendEnqueuedResponse( INOUT SESSION_INFO *sessionInfoPtr );
568 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
569 int enqueueChannelData( INOUT SESSION_INFO *sessionInfoPtr,
570  IN_RANGE( 1, 255 ) const int type,
571  IN const long channelNo,
572  const int param );
573 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
574 int appendChannelData( INOUT SESSION_INFO *sessionInfoPtr,
576 
577 /* Prototypes for functions in ssh2_msg.c */
578 
579 CHECK_RETVAL_RANGE( 10000, MAX_WINDOW_SIZE ) STDC_NONNULL_ARG( ( 1 ) ) \
580 int getWindowSize( const SESSION_INFO *sessionInfoPtr );
581 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
582 int closeChannel( INOUT SESSION_INFO *sessionInfoPtr,
584 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
585 int processChannelControlMessage( INOUT SESSION_INFO *sessionInfoPtr,
586  INOUT STREAM *stream );
587 
588 /* Prototypes for functions in ssh2_msgc.c */
589 
590 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
591 int sendChannelOpen( INOUT SESSION_INFO *sessionInfoPtr );
592 
593 /* Prototypes for functions in ssh2_msgs.c */
594 
595 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
596 int processChannelOpen( INOUT SESSION_INFO *sessionInfoPtr,
597  INOUT STREAM *stream );
598 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
599 int processChannelRequest( INOUT SESSION_INFO *sessionInfoPtr,
600  INOUT STREAM *stream,
601  IN const long prevChannelNo );
602 
603 /* Prototypes for functions in ssh2_cry.c */
604 
606 
607 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
608 int initSecurityInfo( INOUT SESSION_INFO *sessionInfoPtr,
611 int initSecurityContextsSSH( INOUT SESSION_INFO *sessionInfoPtr );
612 STDC_NONNULL_ARG( ( 1 ) ) \
613 void destroySecurityContextsSSH( INOUT SESSION_INFO *sessionInfoPtr );
614 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
615 int initDHcontextSSH( OUT_HANDLE_OPT CRYPT_CONTEXT *iCryptContext,
617  IN_BUFFER_OPT( keyDataLength ) const void *keyData,
620 #ifdef USE_ECDH
621 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
622 int initECDHcontextSSH( OUT_HANDLE_OPT CRYPT_CONTEXT *iCryptContext,
623  OUT_LENGTH_SHORT_Z int *keySize,
625 #endif /* USE_ECDH */
626 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
627 int completeKeyex( INOUT SESSION_INFO *sessionInfoPtr,
629  const BOOLEAN isServer );
631 int hashAsString( IN_HANDLE const CRYPT_CONTEXT iHashContext,
632  IN_BUFFER( dataLength ) const BYTE *data,
633  IN_LENGTH_SHORT const int dataLength );
635 int hashAsMPI( IN_HANDLE const CRYPT_CONTEXT iHashContext,
636  IN_BUFFER( dataLength ) const BYTE *data,
637  IN_LENGTH_SHORT const int dataLength );
639 int checkMacSSH( IN_HANDLE const CRYPT_CONTEXT iMacContext,
640  IN_INT const long seqNo,
641  IN_BUFFER( dataMaxLength ) const BYTE *data,
642  IN_LENGTH const int dataMaxLength,
643  IN_LENGTH_Z const int dataLength,
644  IN_RANGE( 16, CRYPT_MAX_HASHSIZE ) const int macLength );
646 int checkMacSSHIncremental( IN_HANDLE const CRYPT_CONTEXT iMacContext,
647  IN_INT const long seqNo,
648  IN_BUFFER( dataMaxLength ) const BYTE *data,
649  IN_LENGTH const int dataMaxLength,
650  IN_LENGTH_Z const int dataLength,
651  IN_LENGTH const int packetDataLength,
652  IN_ENUM( MAC ) const MAC_TYPE macType,
653  IN_RANGE( 16, CRYPT_MAX_HASHSIZE ) const int macLength );
655 int createMacSSH( IN_HANDLE const CRYPT_CONTEXT iMacContext,
656  IN_INT const long seqNo,
657  IN_BUFFER( dataMaxLength ) BYTE *data,
658  IN_LENGTH const int dataMaxLength,
659  IN_LENGTH const int dataLength );
660 
661 /* Prototypes for functions in ssh2_rd.c */
662 
663 CHECK_RETVAL_PTR \
664 const char *getSSHPacketName( IN_RANGE( 0, 255 ) const int packetType );
665 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
666 int readPacketHeaderSSH2( INOUT SESSION_INFO *sessionInfoPtr,
669  const int expectedType,
675 int readHSPacketSSH2( INOUT SESSION_INFO *sessionInfoPtr,
678  int expectedType,
679  IN_RANGE( 1, 1024 ) const int minPacketSize );
680 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
681 int getDisconnectInfo( INOUT SESSION_INFO *sessionInfoPtr,
682  INOUT STREAM *stream );
683 
684 /* Prototypes for functions in ssh2_wr.c */
685 
686 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
687 int openPacketStreamSSH( OUT STREAM *stream,
688  const SESSION_INFO *sessionInfoPtr,
691  const int packetType );
692 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
693 int openPacketStreamSSHEx( OUT STREAM *stream,
694  const SESSION_INFO *sessionInfoPtr,
695  IN_LENGTH const int bufferSize,
698  const int packetType );
699 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
700 int continuePacketStreamSSH( INOUT STREAM *stream,
703  const int packetType,
705 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
706 int wrapPacketSSH2( INOUT SESSION_INFO *sessionInfoPtr,
707  INOUT STREAM *stream,
708  IN_LENGTH_Z const int offset,
710  const BOOLEAN isWriteableStream );
711 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
712 int sendPacketSSH2( INOUT SESSION_INFO *sessionInfoPtr,
713  INOUT STREAM *stream,
714  const BOOLEAN sendOnly );
715 
716 /* Prototypes for session mapping functions */
717 
718 void initSSH1processing( INOUT SESSION_INFO *sessionInfoPtr,
720  const BOOLEAN isServer ) \
721  STDC_NONNULL_ARG( ( 1 ) );
722 STDC_NONNULL_ARG( ( 1 ) ) \
723 void initSSH2processing( INOUT SESSION_INFO *sessionInfoPtr,
725  const BOOLEAN isServer );
726 STDC_NONNULL_ARG( ( 1, 2 ) ) \
727 void initSSH2clientProcessing( STDC_UNUSED SESSION_INFO *sessionInfoPtr,
729 STDC_NONNULL_ARG( ( 1, 2 ) ) \
730 void initSSH2serverProcessing( STDC_UNUSED SESSION_INFO *sessionInfoPtr,
732 
733 #ifndef USE_SSH1
734  #define initSSH1processing initSSH2processing
735 #endif /* USE_SSH1 */
736 #endif /* _SSH_DEFINED */