]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - ssh.h
Unix Pageant: move handling of --exec arguments.
[PuTTY.git] / ssh.h
diff --git a/ssh.h b/ssh.h
index 89f772d661e34bfa1395874ff4418d4b97e91d7a..256478cbace54465dab14640448effb15dc0d6d7 100644 (file)
--- a/ssh.h
+++ b/ssh.h
@@ -99,9 +99,73 @@ struct dss_key {
     Bignum p, q, g, y, x;
 };
 
-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);
+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);
+
+/* Weierstrass form curve */
+struct ec_wcurve
+{
+    Bignum a, b, n;
+    struct ec_point G;
+};
+
+/* Montgomery form curve */
+struct ec_mcurve
+{
+    Bignum a, b;
+    struct ec_point G;
+};
+
+/* Edwards form curve */
+struct ec_ecurve
+{
+    Bignum l, d;
+    struct ec_point B;
+};
+
+struct ec_curve {
+    enum { EC_WEIERSTRASS, EC_MONTGOMERY, EC_EDWARDS } type;
+    unsigned int fieldBits;
+    Bignum p;
+    union {
+        struct ec_wcurve w;
+        struct ec_mcurve m;
+        struct ec_ecurve e;
+    };
+};
+
+extern unsigned char nistp256_oid[];
+extern unsigned char nistp384_oid[];
+extern unsigned char nistp521_oid[];
+extern unsigned char curve25519_oid[];
+extern int nistp256_oid_len;
+extern int nistp384_oid_len;
+extern int nistp521_oid_len;
+extern int curve25519_oid_len;
+struct ec_curve *ec_p256(void);
+struct ec_curve *ec_p384(void);
+struct ec_curve *ec_p521(void);
+struct ec_curve *ec_ed25519(void);
+struct ec_curve *ec_curve25519(void);
+
+struct ec_key {
+    struct ec_point publicKey;
+    Bignum privateKey;
+};
+
+struct ec_point *ec_public(const Bignum privateKey, const struct ec_curve *curve);
+
+int makekey(const unsigned char *data, int len, struct RSAKey *result,
+           const unsigned char **keystr, int order);
+int makeprivate(const unsigned char *data, int len, struct RSAKey *result);
 int rsaencrypt(unsigned char *data, int length, struct RSAKey *key);
 Bignum rsadecrypt(Bignum input, struct RSAKey *key);
 void rsasign(unsigned char *data, int length, struct RSAKey *key);
@@ -141,6 +205,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(const char *name);
+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;
@@ -198,10 +276,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);
@@ -245,7 +328,7 @@ struct ssh_mac {
     void (*bytes) (void *, unsigned char const *, int);
     void (*genresult) (void *, unsigned char *);
     int (*verresult) (void *, unsigned char const *);
-    char *name;
+    char *name, *etm_name;
     int len;
     char *text_name;
 };
@@ -260,7 +343,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;
@@ -273,20 +356,29 @@ struct ssh_kexes {
 };
 
 struct ssh_signkey {
-    void *(*newkey) (char *data, int len);
+    void *(*newkey) (const char *data, int len);
     void (*freekey) (void *key);
     char *(*fmtkey) (void *key);
     unsigned char *(*public_blob) (void *key, int *len);
     unsigned char *(*private_blob) (void *key, int *len);
-    void *(*createkey) (unsigned char *pub_blob, int pub_len,
-                       unsigned char *priv_blob, int priv_len);
-    void *(*openssh_createkey) (unsigned char **blob, int *len);
+    void *(*createkey) (const unsigned char *pub_blob, int pub_len,
+                       const unsigned char *priv_blob, int priv_len);
+    void *(*openssh_createkey) (const unsigned char **blob, int *len);
     int (*openssh_fmtkey) (void *key, unsigned char *blob, int len);
-    int (*pubkey_bits) (void *blob, int len);
+    /* OpenSSH private key blobs, as created by openssh_fmtkey and
+     * consumed by openssh_createkey, always (at least so far...) take
+     * the form of a number of SSH-2 strings / mpints concatenated
+     * end-to-end. Because the new-style OpenSSH private key format
+     * stores those blobs without a containing string wrapper, we need
+     * to know how many strings each one consists of, so that we can
+     * skip over the right number to find the next key in the file.
+     * openssh_private_npieces gives that information. */
+    int openssh_private_npieces;
+    int (*pubkey_bits) (const void *blob, int len);
     char *(*fingerprint) (void *key);
-    int (*verifysig) (void *key, char *sig, int siglen,
-                     char *data, int datalen);
-    unsigned char *(*sign) (void *key, char *data, int datalen,
+    int (*verifysig) (void *key, const char *sig, int siglen,
+                     const char *data, int datalen);
+    unsigned char *(*sign) (void *key, const char *data, int datalen,
                            int *siglen);
     char *name;
     char *keytype;                    /* for host key cache */
@@ -316,7 +408,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;
@@ -328,12 +420,19 @@ 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_ed25519;
+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;
@@ -455,7 +554,7 @@ int x11_authcmp(void *av, void *bv); /* for putting X11FakeAuth in a tree234 */
  * authorisation protocol to use at the remote end. The local auth
  * details are looked up by calling platform_get_x11_auth.
  */
-extern struct X11Display *x11_setup_display(char *display, Conf *);
+extern struct X11Display *x11_setup_display(const char *display, Conf *);
 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);
@@ -502,9 +601,12 @@ 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_from_bytes_le(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);
@@ -525,6 +627,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);
 
@@ -536,10 +639,11 @@ void *dh_setup_group(const struct ssh_kex *kex);
 void *dh_setup_gex(Bignum pval, Bignum gval);
 void dh_cleanup(void *);
 Bignum dh_create_e(void *, int nbits);
+const char *dh_validate_f(void *handle, Bignum f);
 Bignum dh_find_K(void *, Bignum f);
 
 int loadrsakey(const Filename *filename, struct RSAKey *key,
-              char *passphrase, const char **errorstr);
+              const char *passphrase, const char **errorstr);
 int rsakey_encrypted(const Filename *filename, char **comment);
 int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen,
                   char **commentptr, const char **errorstr);
@@ -557,19 +661,51 @@ extern struct ssh2_userkey ssh2_wrong_passphrase;
 
 int ssh2_userkey_encrypted(const Filename *filename, char **comment);
 struct ssh2_userkey *ssh2_load_userkey(const Filename *filename,
-                                      char *passphrase, const char **errorstr);
+                                      const char *passphrase,
+                                       const char **errorstr);
 unsigned char *ssh2_userkey_loadpub(const Filename *filename, char **algorithm,
                                    int *pub_blob_len, char **commentptr,
                                    const char **errorstr);
 int ssh2_save_userkey(const Filename *filename, struct ssh2_userkey *key,
                      char *passphrase);
 const struct ssh_signkey *find_pubkey_alg(const char *name);
+const struct ssh_signkey *find_pubkey_alg_len(int namelen, const char *name);
 
 enum {
     SSH_KEYTYPE_UNOPENABLE,
     SSH_KEYTYPE_UNKNOWN,
     SSH_KEYTYPE_SSH1, SSH_KEYTYPE_SSH2,
-    SSH_KEYTYPE_OPENSSH, SSH_KEYTYPE_SSHCOM
+    /*
+     * The OpenSSH key types deserve a little explanation. OpenSSH has
+     * two physical formats for private key storage: an old PEM-based
+     * one largely dictated by their use of OpenSSL and full of ASN.1,
+     * and a new one using the same private key formats used over the
+     * wire for talking to ssh-agent. The old format can only support
+     * a subset of the key types, because it needs redesign for each
+     * key type, and after a while they decided to move to the new
+     * format so as not to have to do that.
+     *
+     * On input, key files are identified as either
+     * SSH_KEYTYPE_OPENSSH_PEM or SSH_KEYTYPE_OPENSSH_NEW, describing
+     * accurately which actual format the keys are stored in.
+     *
+     * On output, however, we default to following OpenSSH's own
+     * policy of writing out PEM-style keys for maximum backwards
+     * compatibility if the key type supports it, and otherwise
+     * switching to the new format. So the formats you can select for
+     * output are SSH_KEYTYPE_OPENSSH_NEW (forcing the new format for
+     * any key type), and SSH_KEYTYPE_OPENSSH_AUTO to use the oldest
+     * format supported by whatever key type you're writing out.
+     *
+     * So we have three type codes, but only two of them usable in any
+     * given circumstance. An input key file will never be identified
+     * as AUTO, only PEM or NEW; key export UIs should not be able to
+     * select PEM, only AUTO or NEW.
+     */
+    SSH_KEYTYPE_OPENSSH_AUTO,
+    SSH_KEYTYPE_OPENSSH_PEM,
+    SSH_KEYTYPE_OPENSSH_NEW,
+    SSH_KEYTYPE_SSHCOM
 };
 int key_type(const Filename *filename);
 char *key_type_to_str(int type);
@@ -602,6 +738,10 @@ void des_encrypt_xdmauth(const unsigned char *key,
 void des_decrypt_xdmauth(const unsigned char *key,
                          unsigned char *blk, int len);
 
+void openssh_bcrypt(const char *passphrase,
+                    const unsigned char *salt, int saltbytes,
+                    int rounds, unsigned char *out, int outbytes);
+
 /*
  * For progress updates in the key generation utility.
  */
@@ -617,6 +757,10 @@ 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);
+int ec_edgenerate(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);
@@ -719,13 +863,18 @@ void platform_ssh_share_cleanup(const char *name);
 #define SSH2_MSG_NEWKEYS                          21   /* 0x15 */
 #define SSH2_MSG_KEXDH_INIT                       30   /* 0x1e */
 #define SSH2_MSG_KEXDH_REPLY                      31   /* 0x1f */
-#define SSH2_MSG_KEX_DH_GEX_REQUEST               30   /* 0x1e */
+#define SSH2_MSG_KEX_DH_GEX_REQUEST_OLD           30   /* 0x1e */
+#define SSH2_MSG_KEX_DH_GEX_REQUEST               34   /* 0x22 */
 #define SSH2_MSG_KEX_DH_GEX_GROUP                 31   /* 0x1f */
 #define SSH2_MSG_KEX_DH_GEX_INIT                  32   /* 0x20 */
 #define SSH2_MSG_KEX_DH_GEX_REPLY                 33   /* 0x21 */
 #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 */