]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - ssh.h
Elliptic-curve cryptography support.
[PuTTY.git] / ssh.h
diff --git a/ssh.h b/ssh.h
index 8e2a908d4c550716e707bb627e5201cb10b6fd1f..3bb8593b6ecdf15ea951ccc61dc31bc8d97a1d8a 100644 (file)
--- a/ssh.h
+++ b/ssh.h
@@ -8,12 +8,53 @@
 #include "misc.h"
 
 struct ssh_channel;
+typedef struct ssh_tag *Ssh;
 
 extern int sshfwd_write(struct ssh_channel *c, char *, int);
 extern void sshfwd_write_eof(struct ssh_channel *c);
 extern void sshfwd_unclean_close(struct ssh_channel *c, const char *err);
 extern void sshfwd_unthrottle(struct ssh_channel *c, int bufsize);
 Conf *sshfwd_get_conf(struct ssh_channel *c);
+void sshfwd_x11_sharing_handover(struct ssh_channel *c,
+                                 void *share_cs, void *share_chan,
+                                 const char *peer_addr, int peer_port,
+                                 int endian, int protomajor, int protominor,
+                                 const void *initial_data, int initial_len);
+void sshfwd_x11_is_local(struct ssh_channel *c);
+
+extern Socket ssh_connection_sharing_init(const char *host, int port,
+                                          Conf *conf, Ssh ssh, void **state);
+void share_got_pkt_from_server(void *ctx, int type,
+                               unsigned char *pkt, int pktlen);
+void share_activate(void *state, const char *server_verstring);
+void sharestate_free(void *state);
+int share_ndownstreams(void *state);
+
+void ssh_connshare_log(Ssh ssh, int event, const char *logtext,
+                       const char *ds_err, const char *us_err);
+unsigned ssh_alloc_sharing_channel(Ssh ssh, void *sharing_ctx);
+void ssh_delete_sharing_channel(Ssh ssh, unsigned localid);
+int ssh_alloc_sharing_rportfwd(Ssh ssh, const char *shost, int sport,
+                               void *share_ctx);
+void ssh_sharing_queue_global_request(Ssh ssh, void *share_ctx);
+struct X11FakeAuth *ssh_sharing_add_x11_display(Ssh ssh, int authtype,
+                                                void *share_cs,
+                                                void *share_chan);
+void ssh_sharing_remove_x11_display(Ssh ssh, struct X11FakeAuth *auth);
+void ssh_send_packet_from_downstream(Ssh ssh, unsigned id, int type,
+                                     const void *pkt, int pktlen,
+                                     const char *additional_log_text);
+void ssh_sharing_downstream_connected(Ssh ssh, unsigned id);
+void ssh_sharing_downstream_disconnected(Ssh ssh, unsigned id);
+void ssh_sharing_logf(Ssh ssh, unsigned id, const char *logfmt, ...);
+int ssh_agent_forwarding_permitted(Ssh ssh);
+void share_setup_x11_channel(void *csv, void *chanv,
+                             unsigned upstream_id, unsigned server_id,
+                             unsigned server_currwin, unsigned server_maxpkt,
+                             unsigned client_adjusted_window,
+                             const char *peer_addr, int peer_port, int endian,
+                             int protomajor, int protominor,
+                             const void *initial_data, int initial_len);
 
 /*
  * Useful thing.
@@ -58,6 +99,38 @@ struct dss_key {
     Bignum p, q, g, y, x;
 };
 
+struct ec_curve;
+
+struct ec_point {
+    const struct ec_curve *curve;
+    Bignum x, y;
+    Bignum z;  // Jacobian denominator
+    unsigned char infinity;
+};
+
+void ec_point_free(struct ec_point *point);
+
+struct ec_curve {
+    unsigned int fieldBits;
+    Bignum p, a, b, n;
+    struct ec_point G;
+};
+
+extern unsigned char nistp256_oid[];
+extern unsigned char nistp384_oid[];
+extern unsigned char nistp521_oid[];
+extern int nistp256_oid_len;
+extern int nistp384_oid_len;
+extern int nistp521_oid_len;
+struct ec_curve *ec_p256(void);
+struct ec_curve *ec_p384(void);
+struct ec_curve *ec_p521(void);
+
+struct ec_key {
+    struct ec_point publicKey;
+    Bignum privateKey;
+};
+
 int makekey(unsigned char *data, int len, struct RSAKey *result,
            unsigned char **keystr, int order);
 int makeprivate(unsigned char *data, int len, struct RSAKey *result);
@@ -100,6 +173,20 @@ void ssh_rsakex_encrypt(const struct ssh_hash *h, unsigned char *in, int inlen,
                         unsigned char *out, int outlen,
                         void *key);
 
+/*
+ * SSH2 ECDH key exchange functions
+ */
+void *ssh_ecdhkex_newkey(struct ec_curve *curve);
+void ssh_ecdhkex_freekey(void *key);
+char *ssh_ecdhkex_getpublic(void *key, int *len);
+Bignum ssh_ecdhkex_getkey(void *key, char *remoteKey, int remoteKeyLen);
+
+/*
+ * Helper function for k generation in DSA, reused in ECDSA
+ */
+Bignum *dss_gen_k(const char *id_string, Bignum modulus, Bignum private_key,
+                  unsigned char *digest, int digest_len);
+
 typedef struct {
     uint32 h[4];
 } MD5_Core_State;
@@ -157,10 +244,15 @@ typedef struct {
     int blkused;
     uint32 len[4];
 } SHA512_State;
+#define SHA384_State SHA512_State
 void SHA512_Init(SHA512_State * s);
 void SHA512_Bytes(SHA512_State * s, const void *p, int len);
 void SHA512_Final(SHA512_State * s, unsigned char *output);
 void SHA512_Simple(const void *p, int len, unsigned char *output);
+void SHA384_Init(SHA384_State * s);
+#define SHA384_Bytes(s, p, len) SHA512_Bytes(s, p, len)
+void SHA384_Final(SHA384_State * s, unsigned char *output);
+void SHA384_Simple(const void *p, int len, unsigned char *output);
 
 struct ssh_cipher {
     void *(*make_context)(void);
@@ -219,7 +311,7 @@ struct ssh_hash {
 
 struct ssh_kex {
     char *name, *groupname;
-    enum { KEXTYPE_DH, KEXTYPE_RSA } main_type;
+    enum { KEXTYPE_DH, KEXTYPE_RSA, KEXTYPE_ECDH } main_type;
     /* For DH */
     const unsigned char *pdata, *gdata; /* NULL means group exchange */
     int plen, glen;
@@ -275,7 +367,7 @@ struct ssh2_userkey {
 };
 
 /* The maximum length of any hash algorithm used in kex. (bytes) */
-#define SSH2_KEX_MAX_HASH_LEN (32) /* SHA-256 */
+#define SSH2_KEX_MAX_HASH_LEN (64) /* SHA-512 */
 
 extern const struct ssh_cipher ssh_3des;
 extern const struct ssh_cipher ssh_des;
@@ -287,12 +379,18 @@ extern const struct ssh2_ciphers ssh2_blowfish;
 extern const struct ssh2_ciphers ssh2_arcfour;
 extern const struct ssh_hash ssh_sha1;
 extern const struct ssh_hash ssh_sha256;
+extern const struct ssh_hash ssh_sha384;
+extern const struct ssh_hash ssh_sha512;
 extern const struct ssh_kexes ssh_diffiehellman_group1;
 extern const struct ssh_kexes ssh_diffiehellman_group14;
 extern const struct ssh_kexes ssh_diffiehellman_gex;
 extern const struct ssh_kexes ssh_rsa_kex;
+extern const struct ssh_kexes ssh_ecdh_kex;
 extern const struct ssh_signkey ssh_dss;
 extern const struct ssh_signkey ssh_rsa;
+extern const struct ssh_signkey ssh_ecdsa_nistp256;
+extern const struct ssh_signkey ssh_ecdsa_nistp384;
+extern const struct ssh_signkey ssh_ecdsa_nistp521;
 extern const struct ssh_mac ssh_hmac_md5;
 extern const struct ssh_mac ssh_hmac_sha1;
 extern const struct ssh_mac ssh_hmac_sha1_buggy;
@@ -400,7 +498,12 @@ struct X11FakeAuth {
      * What to do with an X connection matching this auth data.
      */
     struct X11Display *disp;
+    void *share_cs, *share_chan;
 };
+void *x11_make_greeting(int endian, int protomajor, int protominor,
+                        int auth_proto, const void *auth_data, int auth_len,
+                        const char *peer_ip, int peer_port,
+                        int *outlen);
 int x11_authcmp(void *av, void *bv); /* for putting X11FakeAuth in a tree234 */
 /*
  * x11_setup_display() parses the display variable and fills in an
@@ -414,8 +517,7 @@ void x11_free_display(struct X11Display *disp);
 struct X11FakeAuth *x11_invent_fake_auth(tree234 *t, int authtype);
 void x11_free_fake_auth(struct X11FakeAuth *auth);
 struct X11Connection;                  /* opaque outside x11fwd.c */
-extern char *x11_init(struct X11Connection **, tree234 *authtree,
-                      void *, const char *, int);
+struct X11Connection *x11_init(tree234 *authtree, void *, const char *, int);
 extern void x11_close(struct X11Connection *);
 extern int x11_send(struct X11Connection *, char *, int);
 extern void x11_send_eof(struct X11Connection *s);
@@ -447,6 +549,8 @@ char *platform_get_x_display(void);
  */
 void x11_get_auth_from_authfile(struct X11Display *display,
                                const char *authfilename);
+int x11_identify_auth_proto(const char *proto);
+void *x11_dehexify(const char *hex, int *outlen);
 
 Bignum copybn(Bignum b);
 Bignum bn_power_2(int n);
@@ -455,9 +559,11 @@ Bignum bignum_from_long(unsigned long n);
 void freebn(Bignum b);
 Bignum modpow(Bignum base, Bignum exp, Bignum mod);
 Bignum modmul(Bignum a, Bignum b, Bignum mod);
+Bignum modsub(const Bignum a, const Bignum b, const Bignum n);
 void decbn(Bignum n);
 extern Bignum Zero, One;
 Bignum bignum_from_bytes(const unsigned char *data, int nbytes);
+Bignum bignum_random_in_range(const Bignum lower, const Bignum upper);
 int ssh1_read_bignum(const unsigned char *data, int len, Bignum * result);
 int bignum_bitcount(Bignum bn);
 int ssh1_bignum_length(Bignum bn);
@@ -478,6 +584,7 @@ Bignum bigmod(Bignum a, Bignum b);
 Bignum modinv(Bignum number, Bignum modulus);
 Bignum bignum_bitmask(Bignum number);
 Bignum bignum_rshift(Bignum number, int shift);
+Bignum bignum_lshift(Bignum number, int shift);
 int bignum_cmp(Bignum a, Bignum b);
 char *bignum_decimal(Bignum x);
 
@@ -570,6 +677,8 @@ int rsa_generate(struct RSAKey *key, int bits, progfn_t pfn,
                 void *pfnparam);
 int dsa_generate(struct dss_key *key, int bits, progfn_t pfn,
                 void *pfnparam);
+int ec_generate(struct ec_key *key, int bits, progfn_t pfn,
+                void *pfnparam);
 Bignum primegen(int bits, int modulus, int residue, Bignum factor,
                int phase, progfn_t pfn, void *pfnparam, unsigned firstbits);
 void invent_firstbits(unsigned *one, unsigned *two);
@@ -587,6 +696,22 @@ int zlib_compress_block(void *, unsigned char *block, int len,
 int zlib_decompress_block(void *, unsigned char *block, int len,
                          unsigned char **outblock, int *outlen);
 
+/*
+ * Connection-sharing API provided by platforms. This function must
+ * either:
+ *  - return SHARE_NONE and do nothing
+ *  - return SHARE_DOWNSTREAM and set *sock to a Socket connected to
+ *    downplug
+ *  - return SHARE_UPSTREAM and set *sock to a Socket connected to
+ *    upplug.
+ */
+enum { SHARE_NONE, SHARE_DOWNSTREAM, SHARE_UPSTREAM };
+int platform_ssh_share(const char *name, Conf *conf,
+                       Plug downplug, Plug upplug, Socket *sock,
+                       char **logtext, char **ds_err, char **us_err,
+                       int can_upstream, int can_downstream);
+void platform_ssh_share_cleanup(const char *name);
+
 /*
  * SSH-1 message type codes.
  */
@@ -663,6 +788,10 @@ int zlib_decompress_block(void *, unsigned char *block, int len,
 #define SSH2_MSG_KEXRSA_PUBKEY                    30    /* 0x1e */
 #define SSH2_MSG_KEXRSA_SECRET                    31    /* 0x1f */
 #define SSH2_MSG_KEXRSA_DONE                      32    /* 0x20 */
+#define SSH2_MSG_KEX_ECDH_INIT                    30    /* 0x1e */
+#define SSH2_MSG_KEX_ECDH_REPLY                   31    /* 0x1f */
+#define SSH2_MSG_KEX_ECMQV_INIT                   30    /* 0x1e */
+#define SSH2_MSG_KEX_ECMQV_REPLY                  31    /* 0x1f */
 #define SSH2_MSG_USERAUTH_REQUEST                 50   /* 0x32 */
 #define SSH2_MSG_USERAUTH_FAILURE                 51   /* 0x33 */
 #define SSH2_MSG_USERAUTH_SUCCESS                 52   /* 0x34 */