123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- /*
- * Header connecting the pieces of the SSH-2 transport layer.
- */
- #ifndef PUTTY_SSH2TRANSPORT_H
- #define PUTTY_SSH2TRANSPORT_H
- #ifndef NO_GSSAPI
- #include "gssc.h"
- #include "gss.h"
- #define MIN_CTXT_LIFETIME 5 /* Avoid rekey with short lifetime (seconds) */
- #define GSS_KEX_CAPABLE (1<<0) /* Can do GSS KEX */
- #define GSS_CRED_UPDATED (1<<1) /* Cred updated since previous delegation */
- #define GSS_CTXT_EXPIRES (1<<2) /* Context expires before next timer */
- #define GSS_CTXT_MAYFAIL (1<<3) /* Context may expire during handshake */
- #endif
- #define DH_MIN_SIZE 1024
- #define DH_MAX_SIZE 8192
- struct kexinit_algorithm {
- ptrlen name;
- union {
- struct {
- const ssh_kex *kex;
- bool warn;
- } kex;
- struct {
- const ssh_keyalg *hostkey;
- unsigned hkflags;
- bool warn;
- } hk;
- struct {
- const ssh_cipheralg *cipher;
- bool warn;
- } cipher;
- struct {
- const ssh2_macalg *mac;
- bool etm;
- } mac;
- struct {
- const ssh_compression_alg *comp;
- bool delayed;
- } comp;
- } u;
- };
- struct kexinit_algorithm_list {
- struct kexinit_algorithm *algs;
- size_t nalgs, algsize;
- };
- #define HOSTKEY_ALGORITHMS(X) \
- X(HK_ED25519, ssh_ecdsa_ed25519) \
- X(HK_ED448, ssh_ecdsa_ed448) \
- X(HK_ECDSA, ssh_ecdsa_nistp256) \
- X(HK_ECDSA, ssh_ecdsa_nistp384) \
- X(HK_ECDSA, ssh_ecdsa_nistp521) \
- X(HK_DSA, ssh_dsa) \
- X(HK_RSA, ssh_rsa_sha512) \
- X(HK_RSA, ssh_rsa_sha256) \
- X(HK_RSA, ssh_rsa) \
- X(HK_ED25519, opensshcert_ssh_ecdsa_ed25519) \
- /* OpenSSH defines no certified version of Ed448 */ \
- X(HK_ECDSA, opensshcert_ssh_ecdsa_nistp256) \
- X(HK_ECDSA, opensshcert_ssh_ecdsa_nistp384) \
- X(HK_ECDSA, opensshcert_ssh_ecdsa_nistp521) \
- X(HK_DSA, opensshcert_ssh_dsa) \
- X(HK_RSA, opensshcert_ssh_rsa_sha512) \
- X(HK_RSA, opensshcert_ssh_rsa_sha256) \
- X(HK_RSA, opensshcert_ssh_rsa) \
- /* end of list */
- #define COUNT_HOSTKEY_ALGORITHM(type, alg) +1
- #define N_HOSTKEY_ALGORITHMS (0 HOSTKEY_ALGORITHMS(COUNT_HOSTKEY_ALGORITHM))
- struct ssh_signkey_with_user_pref_id {
- const ssh_keyalg *alg;
- int id;
- };
- extern const struct ssh_signkey_with_user_pref_id
- ssh2_hostkey_algs[N_HOSTKEY_ALGORITHMS];
- /*
- * Enumeration of high-level classes of reason why we might need to do
- * a repeat key exchange. A full detailed reason in human-readable
- * string form for the Event Log is also provided, but this enum type
- * is used to discriminate between classes of reason that the code
- * needs to treat differently.
- *
- * RK_NONE == 0 is the value indicating that no rekey is currently
- * needed at all. RK_INITIAL indicates that we haven't even done the
- * _first_ key exchange yet. RK_SERVER indicates that we're rekeying
- * because the server asked for it, not because we decided it
- * ourselves. RK_NORMAL is the usual case. RK_GSS_UPDATE indicates
- * that we're rekeying because we've just got new GSSAPI credentials
- * (hence there's no point in doing a preliminary check for new GSS
- * creds, because we already know the answer); RK_POST_USERAUTH
- * indicates that _if_ we're going to need a post-userauth immediate
- * rekey for any reason, this is the moment to do it.
- *
- * So RK_POST_USERAUTH only tells the transport layer to _consider_
- * rekeying, not to definitely do it. Also, that one enum value is
- * special in that the user-readable reason text is passed in to the
- * transport layer as NULL, whereas fills in the reason text after it
- * decides whether it needs a rekey at all. In the other cases,
- * rekey_reason is passed in to the at the same time as rekey_class.
- */
- typedef enum RekeyClass {
- RK_NONE = 0,
- RK_INITIAL,
- RK_SERVER,
- RK_NORMAL,
- RK_POST_USERAUTH,
- RK_GSS_UPDATE
- } RekeyClass;
- typedef struct transport_direction {
- const ssh_cipheralg *cipher;
- const ssh2_macalg *mac;
- bool etm_mode;
- const ssh_compression_alg *comp;
- bool comp_delayed;
- int mkkey_adjust;
- } transport_direction;
- struct ssh2_transport_state {
- int crState, crStateKex;
- PacketProtocolLayer *higher_layer;
- PktInQueue pq_in_higher;
- PktOutQueue pq_out_higher;
- IdempotentCallback ic_pq_out_higher;
- Conf *conf;
- char *savedhost;
- int savedport;
- const char *rekey_reason;
- enum RekeyClass rekey_class;
- unsigned long max_data_size;
- const ssh_kex *kex_alg;
- const ssh_keyalg *hostkey_alg;
- unsigned char session_id[MAX_HASH_LEN];
- int session_id_len;
- int dh_min_size, dh_max_size;
- bool dh_got_size_bounds;
- dh_ctx *dh_ctx;
- ssh_hash *exhash;
- struct DataTransferStats *stats;
- const SshServerConfig *ssc;
- char *client_greeting, *server_greeting;
- bool kex_in_progress, kexinit_delayed;
- unsigned long next_rekey, last_rekey;
- const char *deferred_rekey_reason;
- bool higher_layer_ok;
- /*
- * Fully qualified host name, which we need if doing GSSAPI.
- */
- char *fullhostname;
- /* shgss is outside the ifdef on purpose to keep APIs simple. If
- * NO_GSSAPI is not defined, then it's just an opaque structure
- * tag and the pointer will be NULL. */
- struct ssh_connection_shared_gss_state *shgss;
- #ifndef NO_GSSAPI
- int gss_status;
- time_t gss_cred_expiry; /* Re-delegate if newer */
- unsigned long gss_ctxt_lifetime; /* Re-delegate when short */
- #endif
- ssh_transient_hostkey_cache *thc;
- bool gss_kex_used;
- tree234 *host_cas;
- int nbits, pbits;
- bool warn_kex, warn_hk, warn_cscipher, warn_sccipher;
- struct {
- const char *csvuln, *scvuln;
- WeakCryptoReason wcr;
- } terrapin;
- mp_int *p, *g, *e, *f;
- strbuf *ebuf, *fbuf;
- strbuf *kex_shared_secret;
- strbuf *outgoing_kexinit, *incoming_kexinit;
- strbuf *client_kexinit, *server_kexinit; /* aliases to the above */
- int kex_init_value, kex_reply_value;
- transport_direction in, out, *cstrans, *sctrans;
- ptrlen hostkeydata, sigdata;
- strbuf *hostkeyblob; /* used in server to construct host key to
- * send to client; in client to check in rekeys */
- char *keystr;
- ssh_key *hkey; /* actual host key */
- unsigned hkflags; /* signing flags, used in server */
- RSAKey *rsa_kex_key; /* for RSA kex */
- bool rsa_kex_key_needs_freeing;
- ecdh_key *ecdh_key; /* for ECDH kex */
- unsigned char exchange_hash[MAX_HASH_LEN];
- bool can_gssapi_keyex;
- bool need_gss_transient_hostkey;
- bool warned_about_no_gss_transient_hostkey;
- bool got_session_id;
- bool can_send_ext_info, post_newkeys_ext_info;
- bool strict_kex, enabled_outgoing_crypto, enabled_incoming_crypto;
- bool seen_non_kexinit;
- SeatPromptResult spr;
- bool guessok;
- bool ignorepkt;
- struct kexinit_algorithm_list kexlists[NKEXLIST];
- #ifndef NO_GSSAPI
- Ssh_gss_buf gss_buf;
- Ssh_gss_buf gss_rcvtok, gss_sndtok;
- Ssh_gss_stat gss_stat;
- Ssh_gss_buf mic;
- bool init_token_sent;
- bool complete_rcvd;
- bool gss_delegate;
- #endif
- /* List of crypto primitives below the warning threshold that the
- * user has already clicked OK to, so that we don't keep asking
- * about them again during rekeys. This directly stores pointers
- * to the algorithm vtables, compared by pointer value (which is
- * not a determinism hazard, because we're only using it as a
- * set). */
- tree234 *weak_algorithms_consented_to;
- /*
- * List of host key algorithms for which we _don't_ have a stored
- * host key. These are indices into the main hostkey_algs[] array
- */
- int uncert_hostkeys[N_HOSTKEY_ALGORITHMS];
- int n_uncert_hostkeys;
- /*
- * Indicate that the current rekey is intended to finish with a
- * newly cross-certified host key. To double-check that we
- * certified the right one, we set this to point to the host key
- * algorithm we expect it to be.
- */
- const ssh_keyalg *cross_certifying;
- ssh_key *const *hostkeys;
- int nhostkeys;
- PacketProtocolLayer ppl;
- };
- /* Helpers shared between transport and kex */
- PktIn *ssh2_transport_pop(struct ssh2_transport_state *s);
- void ssh2_transport_dialog_callback(void *, SeatPromptResult);
- /* Provided by transport for use in kex */
- void ssh2transport_finalise_exhash(struct ssh2_transport_state *s);
- /* Provided by kex for use in transport. Must set the 'aborted' flag
- * if it throws a connection-terminating error, so that the caller
- * won't have to check that by looking inside its state parameter
- * which might already have been freed. */
- void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted);
- #endif /* PUTTY_SSH2TRANSPORT_H */
|