/*
 * Based on PuTTY's import.c for importing/exporting OpenSSH and SSH.com
 * keyfiles.
 *
 * Modifications copyright 2003 Matt Johnston
 *
 * PuTTY is copyright 1997-2003 Simon Tatham.
 * 
 * Portions copyright Robert de Bath, Joris van Rantwijk, Delian
 * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry,
 * Justin Bradford, and CORE SDI S.A.
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE
 * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "keyimport.h"
#include "bignum.h"
#include "buffer.h"
#include "dbutil.h"
#include "ecc.h"

#if DROPBEAR_ECDSA
static const unsigned char OID_SEC256R1_BLOB[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07};
static const unsigned char OID_SEC384R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x22};
static const unsigned char OID_SEC521R1_BLOB[] = {0x2b, 0x81, 0x04, 0x00, 0x23};
#endif

#define PUT_32BIT(cp, value) do { \
  (cp)[3] = (unsigned char)(value); \
  (cp)[2] = (unsigned char)((value) >> 8); \
  (cp)[1] = (unsigned char)((value) >> 16); \
  (cp)[0] = (unsigned char)((value) >> 24); } while (0)

#define GET_32BIT(cp) \
	(((unsigned long)(unsigned char)(cp)[0] << 24) | \
	((unsigned long)(unsigned char)(cp)[1] << 16) | \
	((unsigned long)(unsigned char)(cp)[2] << 8) | \
	((unsigned long)(unsigned char)(cp)[3]))

static int openssh_encrypted(const char *filename);
static sign_key *openssh_read(const char *filename, char *passphrase);
static int openssh_write(const char *filename, sign_key *key,
				  char *passphrase);

static int dropbear_write(const char*filename, sign_key * key);
static sign_key *dropbear_read(const char* filename);

static int toint(unsigned u);

#if 0
static int sshcom_encrypted(const char *filename, char **comment);
static struct ssh2_userkey *sshcom_read(const char *filename, char *passphrase);
static int sshcom_write(const char *filename, struct ssh2_userkey *key,
				 char *passphrase);
#endif

int import_encrypted(const char* filename, int filetype) {

	if (filetype == KEYFILE_OPENSSH) {
		return openssh_encrypted(filename);
#if 0
	} else if (filetype == KEYFILE_SSHCOM) {
		return sshcom_encrypted(filename, NULL);
#endif
	}
	return 0;
}

sign_key *import_read(const char *filename, char *passphrase, int filetype) {

	if (filetype == KEYFILE_OPENSSH) {
		return openssh_read(filename, passphrase);
	} else if (filetype == KEYFILE_DROPBEAR) {
		return dropbear_read(filename);
#if 0
	} else if (filetype == KEYFILE_SSHCOM) {
		return sshcom_read(filename, passphrase);
#endif
	}
	return NULL;
}

int import_write(const char *filename, sign_key *key, char *passphrase,
		int filetype) {

	if (filetype == KEYFILE_OPENSSH) {
		return openssh_write(filename, key, passphrase);
	} else if (filetype == KEYFILE_DROPBEAR) {
		return dropbear_write(filename, key);
#if 0
	} else if (filetype == KEYFILE_SSHCOM) {
		return sshcom_write(filename, key, passphrase);
#endif
	}
	return 0;
}

static sign_key *dropbear_read(const char* filename) {

	buffer * buf = NULL;
	sign_key *ret = NULL;
	enum signkey_type type;

	buf = buf_new(MAX_PRIVKEY_SIZE);
	if (buf_readfile(buf, filename) == DROPBEAR_FAILURE) {
		goto error;
	}

	buf_setpos(buf, 0);
	ret = new_sign_key();

	type = DROPBEAR_SIGNKEY_ANY;
	if (buf_get_priv_key(buf, ret, &type) == DROPBEAR_FAILURE){
		goto error;
	}
	buf_free(buf);

	ret->type = type;

	return ret;

error:
	if (buf) {
		buf_free(buf);
	}
	if (ret) {
		sign_key_free(ret);
	}
	return NULL;
}

/* returns 0 on fail, 1 on success */
static int dropbear_write(const char*filename, sign_key * key) {

	buffer * buf;
	FILE*fp;
	int len;
	int ret;

	buf = buf_new(MAX_PRIVKEY_SIZE);
	buf_put_priv_key(buf, key, key->type);

	fp = fopen(filename, "w");
	if (!fp) {
		ret = 0;
		goto out;
	}

	buf_setpos(buf, 0);
	do {
		len = fwrite(buf_getptr(buf, buf->len - buf->pos),
				1, buf->len - buf->pos, fp);
		buf_incrpos(buf, len);
	} while (len > 0 && buf->len != buf->pos);

	fclose(fp);

	if (buf->pos != buf->len) {
		ret = 0;
	} else {
		ret = 1;
	}
out:
	buf_free(buf);
	return ret;
}


/* ----------------------------------------------------------------------
 * Helper routines. (The base64 ones are defined in sshpubk.c.)
 */

#define isbase64(c) (	((c) >= 'A' && (c) <= 'Z') || \
						 ((c) >= 'a' && (c) <= 'z') || \
						 ((c) >= '0' && (c) <= '9') || \
						 (c) == '+' || (c) == '/' || (c) == '=' \
						 )

/* cpl has to be less than 100 */
static void base64_encode_fp(FILE * fp, unsigned char *data,
		int datalen, int cpl)
{
	unsigned char out[100];
	int n;
	unsigned long outlen;
	int rawcpl;
	rawcpl = cpl * 3 / 4;
	dropbear_assert((unsigned int)cpl < sizeof(out));

	while (datalen > 0) {
		n = (datalen < rawcpl ? datalen : rawcpl);
		outlen = sizeof(out);
		base64_encode(data, n, out, &outlen);
		data += n;
		datalen -= n;
		fwrite(out, 1, outlen, fp);
		fputc('\n', fp);
	}
}
/*
 * Read an ASN.1/BER identifier and length pair.
 * 
 * Flags are a combination of the #defines listed below.
 * 
 * Returns -1 if unsuccessful; otherwise returns the number of
 * bytes used out of the source data.
 */

/* ASN.1 tag classes. */
#define ASN1_CLASS_UNIVERSAL		(0 << 6)
#define ASN1_CLASS_APPLICATION	  (1 << 6)
#define ASN1_CLASS_CONTEXT_SPECIFIC (2 << 6)
#define ASN1_CLASS_PRIVATE		  (3 << 6)
#define ASN1_CLASS_MASK			 (3 << 6)

/* Primitive versus constructed bit. */
#define ASN1_CONSTRUCTED			(1 << 5)

static int ber_read_id_len(void *source, int sourcelen,
						   int *id, int *length, int *flags)
{
	unsigned char *p = (unsigned char *) source;

	if (sourcelen == 0)
		return -1;

	*flags = (*p & 0xE0);
	if ((*p & 0x1F) == 0x1F) {
		*id = 0;
		while (*p & 0x80) {
			p++, sourcelen--;
			if (sourcelen == 0)
				return -1;
			*id = (*id << 7) | (*p & 0x7F);
		}
		p++, sourcelen--;
	} else {
		*id = *p & 0x1F;
		p++, sourcelen--;
	}

	if (sourcelen == 0)
		return -1;

	if (*p & 0x80) {
		unsigned len;
		int n = *p & 0x7F;
		p++, sourcelen--;
		if (sourcelen < n)
			return -1;
		len = 0;
		while (n--)
			len = (len << 8) | (*p++);
		sourcelen -= n;
		*length = toint(len);
	} else {
		*length = *p;
		p++, sourcelen--;
	}

	if (*length < 0) {
		printf("Negative ASN.1 length\n");
		return -1;
	}

	return p - (unsigned char *) source;
}

/*
 * Write an ASN.1/BER identifier and length pair. Returns the
 * number of bytes consumed. Assumes dest contains enough space.
 * Will avoid writing anything if dest is NULL, but still return
 * amount of space required.
 */
static int ber_write_id_len(void *dest, int id, int length, int flags)
{
	unsigned char *d = (unsigned char *)dest;
	int len = 0;

	if (id <= 30) {
		/*
		 * Identifier is one byte.
		 */
		len++;
		if (d) *d++ = id | flags;
	} else {
		int n;
		/*
		 * Identifier is multiple bytes: the first byte is 11111
		 * plus the flags, and subsequent bytes encode the value of
		 * the identifier, 7 bits at a time, with the top bit of
		 * each byte 1 except the last one which is 0.
		 */
		len++;
		if (d) *d++ = 0x1F | flags;
		for (n = 1; (id >> (7*n)) > 0; n++)
			continue;					   /* count the bytes */
		while (n--) {
			len++;
			if (d) *d++ = (n ? 0x80 : 0) | ((id >> (7*n)) & 0x7F);
		}
	}

	if (length < 128) {
		/*
		 * Length is one byte.
		 */
		len++;
		if (d) *d++ = length;
	} else {
		int n;
		/*
		 * Length is multiple bytes. The first is 0x80 plus the
		 * number of subsequent bytes, and the subsequent bytes
		 * encode the actual length.
		 */
		for (n = 1; (length >> (8*n)) > 0; n++)
			continue;					   /* count the bytes */
		len++;
		if (d) *d++ = 0x80 | n;
		while (n--) {
			len++;
			if (d) *d++ = (length >> (8*n)) & 0xFF;
		}
	}

	return len;
}


/* Simple structure to point to an mp-int within a blob. */
struct mpint_pos { void *start; int bytes; };

/* ----------------------------------------------------------------------
 * Code to read and write OpenSSH private keys.
 */

enum { OSSH_DSA, OSSH_RSA, OSSH_EC };
struct openssh_key {
	int type;
	int encrypted;
	char iv[32];
	unsigned char *keyblob;
	unsigned int keyblob_len, keyblob_size;
};

static struct openssh_key *load_openssh_key(const char *filename)
{
	struct openssh_key *ret;
	FILE *fp = NULL;
	char buffer[256];
	char *errmsg = NULL, *p = NULL;
	int headers_done;
	unsigned long len, outlen;

	ret = (struct openssh_key*)m_malloc(sizeof(struct openssh_key));
	ret->keyblob = NULL;
	ret->keyblob_len = ret->keyblob_size = 0;
	ret->encrypted = 0;
	memset(ret->iv, 0, sizeof(ret->iv));

	if (strlen(filename) == 1 && filename[0] == '-') {
		fp = stdin;
	} else {
		fp = fopen(filename, "r");
	}
	if (!fp) {
		errmsg = "Unable to open key file";
		goto error;
	}
	if (!fgets(buffer, sizeof(buffer), fp) ||
		0 != strncmp(buffer, "-----BEGIN ", 11) ||
		0 != strcmp(buffer+strlen(buffer)-17, "PRIVATE KEY-----\n")) {
		errmsg = "File does not begin with OpenSSH key header";
		goto error;
	}
	if (!strcmp(buffer, "-----BEGIN RSA PRIVATE KEY-----\n"))
		ret->type = OSSH_RSA;
	else if (!strcmp(buffer, "-----BEGIN DSA PRIVATE KEY-----\n"))
		ret->type = OSSH_DSA;
	else if (!strcmp(buffer, "-----BEGIN EC PRIVATE KEY-----\n"))
		ret->type = OSSH_EC;
	else {
		errmsg = "Unrecognised key type";
		goto error;
	}

	headers_done = 0;
	while (1) {
		if (!fgets(buffer, sizeof(buffer), fp)) {
			errmsg = "Unexpected end of file";
			goto error;
		}
		if (0 == strncmp(buffer, "-----END ", 9) &&
			0 == strcmp(buffer+strlen(buffer)-17, "PRIVATE KEY-----\n"))
			break;					   /* done */
		if ((p = strchr(buffer, ':')) != NULL) {
			if (headers_done) {
				errmsg = "Header found in body of key data";
				goto error;
			}
			*p++ = '\0';
			while (*p && isspace((unsigned char)*p)) p++;
			if (!strcmp(buffer, "Proc-Type")) {
				if (p[0] != '4' || p[1] != ',') {
					errmsg = "Proc-Type is not 4 (only 4 is supported)";
					goto error;
				}
				p += 2;
				if (!strcmp(p, "ENCRYPTED\n"))
					ret->encrypted = 1;
			} else if (!strcmp(buffer, "DEK-Info")) {
				int i, j;

				if (strncmp(p, "DES-EDE3-CBC,", 13)) {
					errmsg = "Ciphers other than DES-EDE3-CBC not supported";
					goto error;
				}
				p += 13;
				for (i = 0; i < 8; i++) {
					if (1 != sscanf(p, "%2x", &j))
						break;
					ret->iv[i] = j;
					p += 2;
				}
				if (i < 8) {
					errmsg = "Expected 16-digit iv in DEK-Info";
					goto error;
				}
			}
		} else {
			headers_done = 1;
			len = strlen(buffer);
			outlen = len*4/3;
			if (ret->keyblob_len + outlen > ret->keyblob_size) {
				ret->keyblob_size = ret->keyblob_len + outlen + 256;
				ret->keyblob = (unsigned char*)m_realloc(ret->keyblob,
						ret->keyblob_size);
			}
			outlen = ret->keyblob_size - ret->keyblob_len;
			if (base64_decode((const unsigned char *)buffer, len,
						ret->keyblob + ret->keyblob_len, &outlen) != CRYPT_OK){
				errmsg = "Error decoding base64";
				goto error;
			}
			ret->keyblob_len += outlen;
		}
	}

	if (ret->keyblob_len == 0 || !ret->keyblob) {
		errmsg = "Key body not present";
		goto error;
	}

	if (ret->encrypted && ret->keyblob_len % 8 != 0) {
		errmsg = "Encrypted key blob is not a multiple of cipher block size";
		goto error;
	}

	m_burn(buffer, sizeof(buffer));
	return ret;

error:
	m_burn(buffer, sizeof(buffer));
	if (ret) {
		if (ret->keyblob) {
			m_burn(ret->keyblob, ret->keyblob_size);
			m_free(ret->keyblob);
		}
		m_free(ret);
	}
	if (fp) {
		fclose(fp);
	}
	if (errmsg) {
		fprintf(stderr, "Error: %s\n", errmsg);
	}
	return NULL;
}

static int openssh_encrypted(const char *filename)
{
	struct openssh_key *key = load_openssh_key(filename);
	int ret;

	if (!key)
		return 0;
	ret = key->encrypted;
	m_burn(key->keyblob, key->keyblob_size);
	m_free(key->keyblob);
	m_free(key);
	return ret;
}

static sign_key *openssh_read(const char *filename, char * UNUSED(passphrase))
{
	struct openssh_key *key;
	unsigned char *p;
	int ret, id, len, flags;
	int i, num_integers = 0;
	sign_key *retval = NULL;
	char *errmsg;
	unsigned char *modptr = NULL;
	int modlen = -9999;
	enum signkey_type type;

	sign_key *retkey;
	buffer * blobbuf = NULL;

	retkey = new_sign_key();

	key = load_openssh_key(filename);

	if (!key)
		return NULL;

	if (key->encrypted) {
		errmsg = "encrypted keys not supported currently";
		goto error;
#if 0
		/* matt TODO */
		/*
		 * Derive encryption key from passphrase and iv/salt:
		 * 
		 *  - let block A equal MD5(passphrase || iv)
		 *  - let block B equal MD5(A || passphrase || iv)
		 *  - block C would be MD5(B || passphrase || iv) and so on
		 *  - encryption key is the first N bytes of A || B
		 */
		struct MD5Context md5c;
		unsigned char keybuf[32];

		MD5Init(&md5c);
		MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
		MD5Update(&md5c, (unsigned char *)key->iv, 8);
		MD5Final(keybuf, &md5c);

		MD5Init(&md5c);
		MD5Update(&md5c, keybuf, 16);
		MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
		MD5Update(&md5c, (unsigned char *)key->iv, 8);
		MD5Final(keybuf+16, &md5c);

		/*
		 * Now decrypt the key blob.
		 */
		des3_decrypt_pubkey_ossh(keybuf, (unsigned char *)key->iv,
								 key->keyblob, key->keyblob_len);

		memset(&md5c, 0, sizeof(md5c));
		memset(keybuf, 0, sizeof(keybuf));
#endif 
	}

	/*
	 * Now we have a decrypted key blob, which contains an ASN.1
	 * encoded private key. We must now untangle the ASN.1.
	 *
	 * We expect the whole key blob to be formatted as a SEQUENCE
	 * (0x30 followed by a length code indicating that the rest of
	 * the blob is part of the sequence). Within that SEQUENCE we
	 * expect to see a bunch of INTEGERs. What those integers mean
	 * depends on the key type:
	 *
	 *  - For RSA, we expect the integers to be 0, n, e, d, p, q,
	 *	dmp1, dmq1, iqmp in that order. (The last three are d mod
	 *	(p-1), d mod (q-1), inverse of q mod p respectively.)
	 *
	 *  - For DSA, we expect them to be 0, p, q, g, y, x in that
	 *	order.
	 */
	
	p = key->keyblob;

	/* Expect the SEQUENCE header. Take its absence as a failure to decrypt. */
	ret = ber_read_id_len(p, key->keyblob_len, &id, &len, &flags);
	p += ret;
	if (ret < 0 || id != 16 || len < 0 ||
		key->keyblob+key->keyblob_len-p < len) {
				errmsg = "ASN.1 decoding failure";
		goto error;
	}

	/* Expect a load of INTEGERs. */
	if (key->type == OSSH_RSA)
		num_integers = 9;
	else if (key->type == OSSH_DSA)
		num_integers = 6;
	else if (key->type == OSSH_EC)
		num_integers = 1;

	/*
	 * Space to create key blob in.
	 */
	blobbuf = buf_new(3000);

#if DROPBEAR_DSS
	if (key->type == OSSH_DSA) {
		buf_putstring(blobbuf, "ssh-dss", 7);
		retkey->type = DROPBEAR_SIGNKEY_DSS;
	} 
#endif
#if DROPBEAR_RSA
	if (key->type == OSSH_RSA) {
		buf_putstring(blobbuf, "ssh-rsa", 7);
		retkey->type = DROPBEAR_SIGNKEY_RSA;
	}
#endif

	for (i = 0; i < num_integers; i++) {
		ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
							  &id, &len, &flags);
		p += ret;
		if (ret < 0 || id != 2 || len < 0 ||
			key->keyblob+key->keyblob_len-p < len) {
			errmsg = "ASN.1 decoding failure";
			goto error;
		}

		if (i == 0) {
			/* First integer is a version indicator */
			int expected = -1;
			switch (key->type) {
				case OSSH_RSA:
				case OSSH_DSA:
					expected = 0;
					break;
				case OSSH_EC:
					expected = 1;
					break;
			}
			if (len != 1 || p[0] != expected) {
				errmsg = "Version number mismatch";
				goto error;
			}
		} else if (key->type == OSSH_RSA) {
			/*
			 * OpenSSH key order is n, e, d, p, q, dmp1, dmq1, iqmp
			 * but we want e, n, d, p, q
			 */
			if (i == 1) {
				/* Save the details for after we deal with number 2. */
				modptr = p;
				modlen = len;
			} else if (i >= 2 && i <= 5) {
				buf_putstring(blobbuf, (const char*)p, len);
				if (i == 2) {
					buf_putstring(blobbuf, (const char*)modptr, modlen);
				}
			}
		} else if (key->type == OSSH_DSA) {
			/*
			 * OpenSSH key order is p, q, g, y, x,
			 * we want the same.
			 */
			buf_putstring(blobbuf, (const char*)p, len);
		}

		/* Skip past the number. */
		p += len;
	}

#if DROPBEAR_ECDSA
	if (key->type == OSSH_EC) {
		unsigned char* private_key_bytes = NULL;
		int private_key_len = 0;
		unsigned char* public_key_bytes = NULL;
		int public_key_len = 0;
		ecc_key *ecc = NULL;
		const struct dropbear_ecc_curve *curve = NULL;

		/* See SEC1 v2, Appendix C.4 */
		/* OpenSSL (so OpenSSH) seems to include the optional parts. */

		/* privateKey OCTET STRING, */
		ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
							  &id, &len, &flags);
		p += ret;
		/* id==4 for octet string */
				if (ret < 0 || id != 4 || len < 0 ||
			key->keyblob+key->keyblob_len-p < len) {
			errmsg = "ASN.1 decoding failure";
			goto error;
		}
		private_key_bytes = p;
		private_key_len = len;
		p += len;

		/* parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, */
		ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
							  &id, &len, &flags);
		p += ret;
		/* id==0 */
				if (ret < 0 || id != 0 || len < 0) {
			errmsg = "ASN.1 decoding failure";
			goto error;
		}

		ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
							  &id, &len, &flags);
		p += ret;
		/* id==6 for object */
				if (ret < 0 || id != 6 || len < 0 ||
			key->keyblob+key->keyblob_len-p < len) {
			errmsg = "ASN.1 decoding failure";
			goto error;
		}

		if (0) {}
#if DROPBEAR_ECC_256
		else if (len == sizeof(OID_SEC256R1_BLOB) 
			&& memcmp(p, OID_SEC256R1_BLOB, len) == 0) {
			retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP256;
			curve = &ecc_curve_nistp256;
		} 
#endif
#if DROPBEAR_ECC_384
		else if (len == sizeof(OID_SEC384R1_BLOB)
			&& memcmp(p, OID_SEC384R1_BLOB, len) == 0) {
			retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP384;
			curve = &ecc_curve_nistp384;
		} 
#endif
#if DROPBEAR_ECC_521
		else if (len == sizeof(OID_SEC521R1_BLOB)
			&& memcmp(p, OID_SEC521R1_BLOB, len) == 0) {
			retkey->type = DROPBEAR_SIGNKEY_ECDSA_NISTP521;
			curve = &ecc_curve_nistp521;
		} 
#endif
		else {
			errmsg = "Unknown ECC key type";
			goto error;
		}
		p += len;

		/* publicKey [1] BIT STRING OPTIONAL */
		ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
							  &id, &len, &flags);
		p += ret;
		/* id==1 */
				if (ret < 0 || id != 1 || len < 0) {
			errmsg = "ASN.1 decoding failure";
			goto error;
		}

		ret = ber_read_id_len(p, key->keyblob+key->keyblob_len-p,
							  &id, &len, &flags);
		p += ret;
		/* id==3 for bit string */
				if (ret < 0 || id != 3 || len < 0 ||
			key->keyblob+key->keyblob_len-p < len) {
			errmsg = "ASN.1 decoding failure";
			goto error;
		}
		public_key_bytes = p+1;
		public_key_len = len-1;
		p += len;

		buf_putbytes(blobbuf, public_key_bytes, public_key_len);
		ecc = buf_get_ecc_raw_pubkey(blobbuf, curve);
		if (!ecc) {
			errmsg = "Error parsing ECC key";
			goto error;
		}
		m_mp_alloc_init_multi((mp_int**)&ecc->k, NULL);
		if (mp_read_unsigned_bin(ecc->k, private_key_bytes, private_key_len)
			!= MP_OKAY) {
			errmsg = "Error parsing ECC key";
			goto error;
		}

		*signkey_key_ptr(retkey, retkey->type) = ecc;
	}
#endif /* DROPBEAR_ECDSA */

	/*
	 * Now put together the actual key. Simplest way to do this is
	 * to assemble our own key blobs and feed them to the createkey
	 * functions; this is a bit faffy but it does mean we get all
	 * the sanity checks for free.
	 */
	if (key->type == OSSH_RSA || key->type == OSSH_DSA) {
		buf_setpos(blobbuf, 0);
		type = DROPBEAR_SIGNKEY_ANY;
		if (buf_get_priv_key(blobbuf, retkey, &type)
				!= DROPBEAR_SUCCESS) {
			errmsg = "unable to create key structure";
			sign_key_free(retkey);
			retkey = NULL;
			goto error;
		}
	}

	errmsg = NULL;					 /* no error */
	retval = retkey;

	error:
	if (blobbuf) {
		buf_burn(blobbuf);
		buf_free(blobbuf);
	}
	m_burn(key->keyblob, key->keyblob_size);
	m_free(key->keyblob);
	m_burn(key, sizeof(*key));
	m_free(key);
	if (errmsg) {
		fprintf(stderr, "Error: %s\n", errmsg);
	}
	return retval;
}

static int openssh_write(const char *filename, sign_key *key,
				  char *passphrase)
{
	buffer * keyblob = NULL;
	buffer * extrablob = NULL; /* used for calculated values to write */
	unsigned char *outblob = NULL;
	int outlen = -9999;
	struct mpint_pos numbers[9];
	int nnumbers = -1, pos = 0, len = 0, seqlen, i;
	char *header = NULL, *footer = NULL;
	char zero[1];
	int ret = 0;
	FILE *fp;

#if DROPBEAR_RSA
	mp_int dmp1, dmq1, iqmp, tmpval; /* for rsa */
#endif

	if (
#if DROPBEAR_RSA
			key->type == DROPBEAR_SIGNKEY_RSA ||
#endif
#if DROPBEAR_DSS
			key->type == DROPBEAR_SIGNKEY_DSS ||
#endif
			0)
	{
		/*
		 * Fetch the key blobs.
		 */
		keyblob = buf_new(3000);
		buf_put_priv_key(keyblob, key, key->type);

		buf_setpos(keyblob, 0);
		/* skip the "ssh-rsa" or "ssh-dss" header */
		buf_incrpos(keyblob, buf_getint(keyblob));

		/*
		 * Find the sequence of integers to be encoded into the OpenSSH
		 * key blob, and also decide on the header line.
		 */
		numbers[0].start = zero; numbers[0].bytes = 1; zero[0] = '\0';

	#ifdef DROPBEAR_RSA
		if (key->type == DROPBEAR_SIGNKEY_RSA) {

			if (key->rsakey->p == NULL || key->rsakey->q == NULL) {
				fprintf(stderr, "Pre-0.33 Dropbear keys cannot be converted to OpenSSH keys.\n");
				goto error;
			}

			/* e */
			numbers[2].bytes = buf_getint(keyblob);
			numbers[2].start = buf_getptr(keyblob, numbers[2].bytes);
			buf_incrpos(keyblob, numbers[2].bytes);
			
			/* n */
			numbers[1].bytes = buf_getint(keyblob);
			numbers[1].start = buf_getptr(keyblob, numbers[1].bytes);
			buf_incrpos(keyblob, numbers[1].bytes);
			
			/* d */
			numbers[3].bytes = buf_getint(keyblob);
			numbers[3].start = buf_getptr(keyblob, numbers[3].bytes);
			buf_incrpos(keyblob, numbers[3].bytes);
			
			/* p */
			numbers[4].bytes = buf_getint(keyblob);
			numbers[4].start = buf_getptr(keyblob, numbers[4].bytes);
			buf_incrpos(keyblob, numbers[4].bytes);
			
			/* q */
			numbers[5].bytes = buf_getint(keyblob);
			numbers[5].start = buf_getptr(keyblob, numbers[5].bytes);
			buf_incrpos(keyblob, numbers[5].bytes);

			/* now calculate some extra parameters: */
			m_mp_init(&tmpval);
			m_mp_init(&dmp1);
			m_mp_init(&dmq1);
			m_mp_init(&iqmp);

			/* dmp1 = d mod (p-1) */
			if (mp_sub_d(key->rsakey->p, 1, &tmpval) != MP_OKAY) {
				fprintf(stderr, "Bignum error for p-1\n");
				goto error;
			}
			if (mp_mod(key->rsakey->d, &tmpval, &dmp1) != MP_OKAY) {
				fprintf(stderr, "Bignum error for dmp1\n");
				goto error;
			}

			/* dmq1 = d mod (q-1) */
			if (mp_sub_d(key->rsakey->q, 1, &tmpval) != MP_OKAY) {
				fprintf(stderr, "Bignum error for q-1\n");
				goto error;
			}
			if (mp_mod(key->rsakey->d, &tmpval, &dmq1) != MP_OKAY) {
				fprintf(stderr, "Bignum error for dmq1\n");
				goto error;
			}

			/* iqmp = (q^-1) mod p */
			if (mp_invmod(key->rsakey->q, key->rsakey->p, &iqmp) != MP_OKAY) {
				fprintf(stderr, "Bignum error for iqmp\n");
				goto error;
			}

			extrablob = buf_new(2000);
			buf_putmpint(extrablob, &dmp1);
			buf_putmpint(extrablob, &dmq1);
			buf_putmpint(extrablob, &iqmp);
			buf_setpos(extrablob, 0);
			mp_clear(&dmp1);
			mp_clear(&dmq1);
			mp_clear(&iqmp);
			mp_clear(&tmpval);
			
			/* dmp1 */
			numbers[6].bytes = buf_getint(extrablob);
			numbers[6].start = buf_getptr(extrablob, numbers[6].bytes);
			buf_incrpos(extrablob, numbers[6].bytes);
			
			/* dmq1 */
			numbers[7].bytes = buf_getint(extrablob);
			numbers[7].start = buf_getptr(extrablob, numbers[7].bytes);
			buf_incrpos(extrablob, numbers[7].bytes);
			
			/* iqmp */
			numbers[8].bytes = buf_getint(extrablob);
			numbers[8].start = buf_getptr(extrablob, numbers[8].bytes);
			buf_incrpos(extrablob, numbers[8].bytes);

			nnumbers = 9;
			header = "-----BEGIN RSA PRIVATE KEY-----\n";
			footer = "-----END RSA PRIVATE KEY-----\n";
		}
	#endif /* DROPBEAR_RSA */

	#ifdef DROPBEAR_DSS
		if (key->type == DROPBEAR_SIGNKEY_DSS) {

			/* p */
			numbers[1].bytes = buf_getint(keyblob);
			numbers[1].start = buf_getptr(keyblob, numbers[1].bytes);
			buf_incrpos(keyblob, numbers[1].bytes);

			/* q */
			numbers[2].bytes = buf_getint(keyblob);
			numbers[2].start = buf_getptr(keyblob, numbers[2].bytes);
			buf_incrpos(keyblob, numbers[2].bytes);

			/* g */
			numbers[3].bytes = buf_getint(keyblob);
			numbers[3].start = buf_getptr(keyblob, numbers[3].bytes);
			buf_incrpos(keyblob, numbers[3].bytes);

			/* y */
			numbers[4].bytes = buf_getint(keyblob);
			numbers[4].start = buf_getptr(keyblob, numbers[4].bytes);
			buf_incrpos(keyblob, numbers[4].bytes);

			/* x */
			numbers[5].bytes = buf_getint(keyblob);
			numbers[5].start = buf_getptr(keyblob, numbers[5].bytes);
			buf_incrpos(keyblob, numbers[5].bytes);

			nnumbers = 6;
			header = "-----BEGIN DSA PRIVATE KEY-----\n";
			footer = "-----END DSA PRIVATE KEY-----\n";
		}
	#endif /* DROPBEAR_DSS */

		/*
		 * Now count up the total size of the ASN.1 encoded integers,
		 * so as to determine the length of the containing SEQUENCE.
		 */
		len = 0;
		for (i = 0; i < nnumbers; i++) {
			len += ber_write_id_len(NULL, 2, numbers[i].bytes, 0);
			len += numbers[i].bytes;
		}
		seqlen = len;
		/* Now add on the SEQUENCE header. */
		len += ber_write_id_len(NULL, 16, seqlen, ASN1_CONSTRUCTED);
		/* Round up to the cipher block size, ensuring we have at least one
		 * byte of padding (see below). */
		outlen = len;
		if (passphrase)
			outlen = (outlen+8) &~ 7;

		/*
		 * Now we know how big outblob needs to be. Allocate it.
		 */
		outblob = (unsigned char*)m_malloc(outlen);

		/*
		 * And write the data into it.
		 */
		pos = 0;
		pos += ber_write_id_len(outblob+pos, 16, seqlen, ASN1_CONSTRUCTED);
		for (i = 0; i < nnumbers; i++) {
			pos += ber_write_id_len(outblob+pos, 2, numbers[i].bytes, 0);
			memcpy(outblob+pos, numbers[i].start, numbers[i].bytes);
			pos += numbers[i].bytes;
		}
	} /* end RSA and DSS handling */

#if DROPBEAR_ECDSA
	if (key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP256
		|| key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP384
		|| key->type == DROPBEAR_SIGNKEY_ECDSA_NISTP521) {

		/*  SEC1 V2 appendix c.4
		ECPrivateKey ::= SEQUENCE {
			version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
			privateKey OCTET STRING,
			parameters [0] ECDomainParameters {{ SECGCurveNames }} OPTIONAL, 
			publicKey [1] BIT STRING OPTIONAL
		}
		*/
		buffer *seq_buf = buf_new(400);
		ecc_key **eck = (ecc_key**)signkey_key_ptr(key, key->type);
		const long curve_size = (*eck)->dp->size;
		int curve_oid_len = 0;
		const void* curve_oid = NULL;
		unsigned long pubkey_size = 2*curve_size+1;
		int k_size;
		int err = 0;

		/* version. less than 10 bytes */
		buf_incrwritepos(seq_buf,
			ber_write_id_len(buf_getwriteptr(seq_buf, 10), 2, 1, 0));
		buf_putbyte(seq_buf, 1);

		/* privateKey */
		k_size = mp_unsigned_bin_size((*eck)->k);
		dropbear_assert(k_size <= curve_size);
		buf_incrwritepos(seq_buf,
			ber_write_id_len(buf_getwriteptr(seq_buf, 10), 4, k_size, 0));
		mp_to_unsigned_bin((*eck)->k, buf_getwriteptr(seq_buf, k_size));
		buf_incrwritepos(seq_buf, k_size);

		/* SECGCurveNames */
		switch (key->type)
		{
			case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
				curve_oid_len = sizeof(OID_SEC256R1_BLOB);
				curve_oid = OID_SEC256R1_BLOB;
				break;
			case DROPBEAR_SIGNKEY_ECDSA_NISTP384:
				curve_oid_len = sizeof(OID_SEC384R1_BLOB);
				curve_oid = OID_SEC384R1_BLOB;
				break;
			case DROPBEAR_SIGNKEY_ECDSA_NISTP521:
				curve_oid_len = sizeof(OID_SEC521R1_BLOB);
				curve_oid = OID_SEC521R1_BLOB;
				break;
			default:
				dropbear_exit("Internal error");
		}

		buf_incrwritepos(seq_buf,
			ber_write_id_len(buf_getwriteptr(seq_buf, 10), 0, 2+curve_oid_len, 0xa0));
		/* object == 6 */
		buf_incrwritepos(seq_buf,
			ber_write_id_len(buf_getwriteptr(seq_buf, 10), 6, curve_oid_len, 0));
		buf_putbytes(seq_buf, curve_oid, curve_oid_len);

		buf_incrwritepos(seq_buf,
			ber_write_id_len(buf_getwriteptr(seq_buf, 10), 1, 2+1+pubkey_size, 0xa0));
		buf_incrwritepos(seq_buf,
			ber_write_id_len(buf_getwriteptr(seq_buf, 10), 3, 1+pubkey_size, 0));
		buf_putbyte(seq_buf, 0);
		err = ecc_ansi_x963_export(*eck, buf_getwriteptr(seq_buf, pubkey_size), &pubkey_size);
		if (err != CRYPT_OK) {
			dropbear_exit("ECC error");
		}
		buf_incrwritepos(seq_buf, pubkey_size);

		buf_setpos(seq_buf, 0);
			
		outblob = (unsigned char*)m_malloc(1000);

		pos = 0;
		pos += ber_write_id_len(outblob+pos, 16, seq_buf->len, ASN1_CONSTRUCTED);
		memcpy(&outblob[pos], seq_buf->data, seq_buf->len);
		pos += seq_buf->len;
		len = pos;
		outlen = len;

		buf_burn(seq_buf);
		buf_free(seq_buf);
		seq_buf = NULL;

		header = "-----BEGIN EC PRIVATE KEY-----\n";
		footer = "-----END EC PRIVATE KEY-----\n";
	}
#endif

	/*
	 * Padding on OpenSSH keys is deterministic. The number of
	 * padding bytes is always more than zero, and always at most
	 * the cipher block length. The value of each padding byte is
	 * equal to the number of padding bytes. So a plaintext that's
	 * an exact multiple of the block size will be padded with 08
	 * 08 08 08 08 08 08 08 (assuming a 64-bit block cipher); a
	 * plaintext one byte less than a multiple of the block size
	 * will be padded with just 01.
	 * 
	 * This enables the OpenSSL key decryption function to strip
	 * off the padding algorithmically and return the unpadded
	 * plaintext to the next layer: it looks at the final byte, and
	 * then expects to find that many bytes at the end of the data
	 * with the same value. Those are all removed and the rest is
	 * returned.
	 */
	dropbear_assert(pos == len);
	while (pos < outlen) {
		outblob[pos++] = outlen - len;
	}

	/*
	 * Encrypt the key.
	 */
	if (passphrase) {
		fprintf(stderr, "Encrypted keys aren't supported currently\n");
		goto error;
	}

	/*
	 * And save it. We'll use Unix line endings just in case it's
	 * subsequently transferred in binary mode.
	 */
	if (strlen(filename) == 1 && filename[0] == '-') {
		fp = stdout;
	} else {
		fp = fopen(filename, "wb");	  /* ensure Unix line endings */
	}
	if (!fp) {
		fprintf(stderr, "Failed opening output file\n");
		goto error;
	}
	fputs(header, fp);
	base64_encode_fp(fp, outblob, outlen, 64);
	fputs(footer, fp);
	fclose(fp);
	ret = 1;

	error:
	if (outblob) {
		memset(outblob, 0, outlen);
		m_free(outblob);
	}
	if (keyblob) {
		buf_burn(keyblob);
		buf_free(keyblob);
	}
	if (extrablob) {
		buf_burn(extrablob);
		buf_free(extrablob);
	}
	return ret;
}

#if 0
/* XXX TODO ssh.com stuff isn't going yet */

/* ----------------------------------------------------------------------
 * Code to read ssh.com private keys.
 */

/*
 * The format of the base64 blob is largely ssh2-packet-formatted,
 * except that mpints are a bit different: they're more like the
 * old ssh1 mpint. You have a 32-bit bit count N, followed by
 * (N+7)/8 bytes of data.
 * 
 * So. The blob contains:
 * 
 *  - uint32 0x3f6ff9eb	   (magic number)
 *  - uint32 size			 (total blob size)
 *  - string key-type		 (see below)
 *  - string cipher-type	  (tells you if key is encrypted)
 *  - string encrypted-blob
 * 
 * (The first size field includes the size field itself and the
 * magic number before it. All other size fields are ordinary ssh2
 * strings, so the size field indicates how much data is to
 * _follow_.)
 * 
 * The encrypted blob, once decrypted, contains a single string
 * which in turn contains the payload. (This allows padding to be
 * added after that string while still making it clear where the
 * real payload ends. Also it probably makes for a reasonable
 * decryption check.)
 * 
 * The payload blob, for an RSA key, contains:
 *  - mpint e
 *  - mpint d
 *  - mpint n  (yes, the public and private stuff is intermixed)
 *  - mpint u  (presumably inverse of p mod q)
 *  - mpint p  (p is the smaller prime)
 *  - mpint q  (q is the larger)
 * 
 * For a DSA key, the payload blob contains:
 *  - uint32 0
 *  - mpint p
 *  - mpint g
 *  - mpint q
 *  - mpint y
 *  - mpint x
 * 
 * Alternatively, if the parameters are `predefined', that
 * (0,p,g,q) sequence can be replaced by a uint32 1 and a string
 * containing some predefined parameter specification. *shudder*,
 * but I doubt we'll encounter this in real life.
 * 
 * The key type strings are ghastly. The RSA key I looked at had a
 * type string of
 * 
 *   `if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}'
 * 
 * and the DSA key wasn't much better:
 * 
 *   `dl-modp{sign{dsa-nist-sha1},dh{plain}}'
 * 
 * It isn't clear that these will always be the same. I think it
 * might be wise just to look at the `if-modn{sign{rsa' and
 * `dl-modp{sign{dsa' prefixes.
 * 
 * Finally, the encryption. The cipher-type string appears to be
 * either `none' or `3des-cbc'. Looks as if this is SSH2-style
 * 3des-cbc (i.e. outer cbc rather than inner). The key is created
 * from the passphrase by means of yet another hashing faff:
 * 
 *  - first 16 bytes are MD5(passphrase)
 *  - next 16 bytes are MD5(passphrase || first 16 bytes)
 *  - if there were more, they'd be MD5(passphrase || first 32),
 *	and so on.
 */

#define SSHCOM_MAGIC_NUMBER 0x3f6ff9eb

struct sshcom_key {
	char comment[256];				 /* allowing any length is overkill */
	unsigned char *keyblob;
	int keyblob_len, keyblob_size;
};

static struct sshcom_key *load_sshcom_key(const char *filename)
{
	struct sshcom_key *ret;
	FILE *fp;
	char buffer[256];
	int len;
	char *errmsg, *p;
	int headers_done;
	char base64_bit[4];
	int base64_chars = 0;

	ret = snew(struct sshcom_key);
	ret->comment[0] = '\0';
	ret->keyblob = NULL;
	ret->keyblob_len = ret->keyblob_size = 0;

	fp = fopen(filename, "r");
	if (!fp) {
		errmsg = "Unable to open key file";
		goto error;
	}
	if (!fgets(buffer, sizeof(buffer), fp) ||
		0 != strcmp(buffer, "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n")) {
		errmsg = "File does not begin with ssh.com key header";
		goto error;
	}

	headers_done = 0;
	while (1) {
		if (!fgets(buffer, sizeof(buffer), fp)) {
			errmsg = "Unexpected end of file";
			goto error;
		}
		if (!strcmp(buffer, "---- END SSH2 ENCRYPTED PRIVATE KEY ----\n"))
			break;					 /* done */
		if ((p = strchr(buffer, ':')) != NULL) {
			if (headers_done) {
				errmsg = "Header found in body of key data";
				goto error;
			}
			*p++ = '\0';
			while (*p && isspace((unsigned char)*p)) p++;
			/*
			 * Header lines can end in a trailing backslash for
			 * continuation.
			 */
			while ((len = strlen(p)) > (int)(sizeof(buffer) - (p-buffer) -1) ||
				   p[len-1] != '\n' || p[len-2] == '\\') {
				if (len > (int)((p-buffer) + sizeof(buffer)-2)) {
					errmsg = "Header line too long to deal with";
					goto error;
				}
				if (!fgets(p+len-2, sizeof(buffer)-(p-buffer)-(len-2), fp)) {
					errmsg = "Unexpected end of file";
					goto error;
				}
			}
			p[strcspn(p, "\n")] = '\0';
			if (!strcmp(buffer, "Comment")) {
				/* Strip quotes in comment if present. */
				if (p[0] == '"' && p[strlen(p)-1] == '"') {
					p++;
					p[strlen(p)-1] = '\0';
				}
				strncpy(ret->comment, p, sizeof(ret->comment));
				ret->comment[sizeof(ret->comment)-1] = '\0';
			}
		} else {
			headers_done = 1;

			p = buffer;
			while (isbase64(*p)) {
				base64_bit[base64_chars++] = *p;
				if (base64_chars == 4) {
					unsigned char out[3];

					base64_chars = 0;

					len = base64_decode_atom(base64_bit, out);

					if (len <= 0) {
						errmsg = "Invalid base64 encoding";
						goto error;
					}

					if (ret->keyblob_len + len > ret->keyblob_size) {
						ret->keyblob_size = ret->keyblob_len + len + 256;
						ret->keyblob = sresize(ret->keyblob, ret->keyblob_size,
											   unsigned char);
					}

					memcpy(ret->keyblob + ret->keyblob_len, out, len);
					ret->keyblob_len += len;
				}

				p++;
			}
		}
	}

	if (ret->keyblob_len == 0 || !ret->keyblob) {
		errmsg = "Key body not present";
		goto error;
	}

	return ret;

	error:
	if (ret) {
		if (ret->keyblob) {
			memset(ret->keyblob, 0, ret->keyblob_size);
			m_free(ret->keyblob);
		}
		memset(ret, 0, sizeof(*ret));
		m_free(ret);
	}
	return NULL;
}

int sshcom_encrypted(const char *filename, char **comment)
{
	struct sshcom_key *key = load_sshcom_key(filename);
	int pos, len, answer;

	*comment = NULL;
	if (!key)
		return 0;

	/*
	 * Check magic number.
	 */
	if (GET_32BIT(key->keyblob) != 0x3f6ff9eb)
		return 0;					  /* key is invalid */

	/*
	 * Find the cipher-type string.
	 */
	answer = 0;
	pos = 8;
	if (key->keyblob_len < pos+4)
		goto done;					 /* key is far too short */
	len = toint(GET_32BIT(key->keyblob + pos));
	if (len < 0 || len > key->keyblob_len - pos - 4)
		goto done;					 /* key is far too short */
	pos += 4 + len;                    /* skip key type */
	len = toint(GET_32BIT(key->keyblob + pos)); /* find cipher-type length */
	if (len < 0 || len > key->keyblob_len - pos - 4)
		goto done;					 /* cipher type string is incomplete */
	if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4))
		answer = 1;

	done:
	*comment = dupstr(key->comment);
	memset(key->keyblob, 0, key->keyblob_size);
	m_free(key->keyblob);
	memset(key, 0, sizeof(*key));
	m_free(key);
	return answer;
}

static int sshcom_read_mpint(void *data, int len, struct mpint_pos *ret)
{
	unsigned bits, bytes;
	unsigned char *d = (unsigned char *) data;

	if (len < 4)
		goto error;
	bits = GET_32BIT(d);

	bytes = (bits + 7) / 8;
	if (len < 4+bytes)
		goto error;

	ret->start = d + 4;
	ret->bytes = bytes;
	return bytes+4;

	error:
	ret->start = NULL;
	ret->bytes = -1;
	return len;						/* ensure further calls fail as well */
}

static int sshcom_put_mpint(void *target, void *data, int len)
{
	unsigned char *d = (unsigned char *)target;
	unsigned char *i = (unsigned char *)data;
	int bits = len * 8 - 1;

	while (bits > 0) {
		if (*i & (1 << (bits & 7)))
			break;
		if (!(bits-- & 7))
			i++, len--;
	}

	PUT_32BIT(d, bits+1);
	memcpy(d+4, i, len);
	return len+4;
}

sign_key *sshcom_read(const char *filename, char *passphrase)
{
	struct sshcom_key *key = load_sshcom_key(filename);
	char *errmsg;
	int pos, len;
	const char prefix_rsa[] = "if-modn{sign{rsa";
	const char prefix_dsa[] = "dl-modp{sign{dsa";
	enum { RSA, DSA } type;
	int encrypted;
	char *ciphertext;
	int cipherlen;
	struct ssh2_userkey *ret = NULL, *retkey;
	const struct ssh_signkey *alg;
	unsigned char *blob = NULL;
	int blobsize = 0, publen, privlen;

	if (!key)
		return NULL;

	/*
	 * Check magic number.
	 */
	if (GET_32BIT(key->keyblob) != SSHCOM_MAGIC_NUMBER) {
		errmsg = "Key does not begin with magic number";
		goto error;
	}

	/*
	 * Determine the key type.
	 */
	pos = 8;
	if (key->keyblob_len < pos+4 ||
		(len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
		errmsg = "Key blob does not contain a key type string";
		goto error;
	}
	if (len > sizeof(prefix_rsa) - 1 &&
		!memcmp(key->keyblob+pos+4, prefix_rsa, sizeof(prefix_rsa) - 1)) {
		type = RSA;
	} else if (len > sizeof(prefix_dsa) - 1 &&
		!memcmp(key->keyblob+pos+4, prefix_dsa, sizeof(prefix_dsa) - 1)) {
		type = DSA;
	} else {
		errmsg = "Key is of unknown type";
		goto error;
	}
	pos += 4+len;

	/*
	 * Determine the cipher type.
	 */
	if (key->keyblob_len < pos+4 ||
		(len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
		errmsg = "Key blob does not contain a cipher type string";
		goto error;
	}
	if (len == 4 && !memcmp(key->keyblob+pos+4, "none", 4))
		encrypted = 0;
	else if (len == 8 && !memcmp(key->keyblob+pos+4, "3des-cbc", 8))
		encrypted = 1;
	else {
		errmsg = "Key encryption is of unknown type";
		goto error;
	}
	pos += 4+len;

	/*
	 * Get hold of the encrypted part of the key.
	 */
	if (key->keyblob_len < pos+4 ||
		(len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
		errmsg = "Key blob does not contain actual key data";
		goto error;
	}
	ciphertext = (char *)key->keyblob + pos + 4;
	cipherlen = len;
	if (cipherlen == 0) {
		errmsg = "Length of key data is zero";
		goto error;
	}

	/*
	 * Decrypt it if necessary.
	 */
	if (encrypted) {
		/*
		 * Derive encryption key from passphrase and iv/salt:
		 * 
		 *  - let block A equal MD5(passphrase)
		 *  - let block B equal MD5(passphrase || A)
		 *  - block C would be MD5(passphrase || A || B) and so on
		 *  - encryption key is the first N bytes of A || B
		 */
		struct MD5Context md5c;
		unsigned char keybuf[32], iv[8];

		if (cipherlen % 8 != 0) {
			errmsg = "Encrypted part of key is not a multiple of cipher block"
				" size";
			goto error;
		}

		MD5Init(&md5c);
		MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
		MD5Final(keybuf, &md5c);

		MD5Init(&md5c);
		MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
		MD5Update(&md5c, keybuf, 16);
		MD5Final(keybuf+16, &md5c);

		/*
		 * Now decrypt the key blob.
		 */
		memset(iv, 0, sizeof(iv));
		des3_decrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
								 cipherlen);

		memset(&md5c, 0, sizeof(md5c));
		memset(keybuf, 0, sizeof(keybuf));

		/*
		 * Hereafter we return WRONG_PASSPHRASE for any parsing
		 * error. (But only if we've just tried to decrypt it!
		 * Returning WRONG_PASSPHRASE for an unencrypted key is
		 * automatic doom.)
		 */
		if (encrypted)
			ret = SSH2_WRONG_PASSPHRASE;
	}

	/*
	 * Strip away the containing string to get to the real meat.
	 */
	len = toint(GET_32BIT(ciphertext));
	if (len < 0 || len > cipherlen-4) {
		errmsg = "containing string was ill-formed";
		goto error;
	}
	ciphertext += 4;
	cipherlen = len;

	/*
	 * Now we break down into RSA versus DSA. In either case we'll
	 * construct public and private blobs in our own format, and
	 * end up feeding them to alg->createkey().
	 */
	blobsize = cipherlen + 256;
	blob = snewn(blobsize, unsigned char);
	privlen = 0;
	if (type == RSA) {
		struct mpint_pos n, e, d, u, p, q;
		int pos = 0;
		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &e);
		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &d);
		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &n);
		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &u);
		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);
		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);
		if (!q.start) {
			errmsg = "key data did not contain six integers";
			goto error;
		}

		alg = &ssh_rsa;
		pos = 0;
		pos += put_string(blob+pos, "ssh-rsa", 7);
		pos += put_mp(blob+pos, e.start, e.bytes);
		pos += put_mp(blob+pos, n.start, n.bytes);
		publen = pos;
		pos += put_string(blob+pos, d.start, d.bytes);
		pos += put_mp(blob+pos, q.start, q.bytes);
		pos += put_mp(blob+pos, p.start, p.bytes);
		pos += put_mp(blob+pos, u.start, u.bytes);
		privlen = pos - publen;
	} else if (type == DSA) {
		struct mpint_pos p, q, g, x, y;
		int pos = 4;
		if (GET_32BIT(ciphertext) != 0) {
			errmsg = "predefined DSA parameters not supported";
			goto error;
		}
		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);
		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &g);
		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);
		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &y);
		pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &x);
		if (!x.start) {
			errmsg = "key data did not contain five integers";
			goto error;
		}

		alg = &ssh_dss;
		pos = 0;
		pos += put_string(blob+pos, "ssh-dss", 7);
		pos += put_mp(blob+pos, p.start, p.bytes);
		pos += put_mp(blob+pos, q.start, q.bytes);
		pos += put_mp(blob+pos, g.start, g.bytes);
		pos += put_mp(blob+pos, y.start, y.bytes);
		publen = pos;
		pos += put_mp(blob+pos, x.start, x.bytes);
		privlen = pos - publen;
	} else
		return NULL;

	dropbear_assert(privlen > 0);			   /* should have bombed by now if not */

	retkey = snew(struct ssh2_userkey);
	retkey->alg = alg;
	retkey->data = alg->createkey(blob, publen, blob+publen, privlen);
	if (!retkey->data) {
		m_free(retkey);
		errmsg = "unable to create key data structure";
		goto error;
	}
	retkey->comment = dupstr(key->comment);

	errmsg = NULL; /* no error */
	ret = retkey;

	error:
	if (blob) {
		memset(blob, 0, blobsize);
		m_free(blob);
	}
	memset(key->keyblob, 0, key->keyblob_size);
	m_free(key->keyblob);
	memset(key, 0, sizeof(*key));
	m_free(key);
	return ret;
}

int sshcom_write(const char *filename, sign_key *key,
				 char *passphrase)
{
	unsigned char *pubblob, *privblob;
	int publen, privlen;
	unsigned char *outblob;
	int outlen;
	struct mpint_pos numbers[6];
	int nnumbers, initial_zero, pos, lenpos, i;
	char *type;
	char *ciphertext;
	int cipherlen;
	int ret = 0;
	FILE *fp;

	/*
	 * Fetch the key blobs.
	 */
	pubblob = key->alg->public_blob(key->data, &publen);
	privblob = key->alg->private_blob(key->data, &privlen);
	outblob = NULL;

	/*
	 * Find the sequence of integers to be encoded into the OpenSSH
	 * key blob, and also decide on the header line.
	 */
	if (key->alg == &ssh_rsa) {
		int pos;
		struct mpint_pos n, e, d, p, q, iqmp;

		pos = 4 + GET_32BIT(pubblob);
		pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e);
		pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n);
		pos = 0;
		pos += ssh2_read_mpint(privblob+pos, privlen-pos, &d);
		pos += ssh2_read_mpint(privblob+pos, privlen-pos, &p);
		pos += ssh2_read_mpint(privblob+pos, privlen-pos, &q);
		pos += ssh2_read_mpint(privblob+pos, privlen-pos, &iqmp);

		dropbear_assert(e.start && iqmp.start); /* can't go wrong */

		numbers[0] = e;
		numbers[1] = d;
		numbers[2] = n;
		numbers[3] = iqmp;
		numbers[4] = q;
		numbers[5] = p;

		nnumbers = 6;
		initial_zero = 0;
		type = "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}";
	} else if (key->alg == &ssh_dss) {
		int pos;
		struct mpint_pos p, q, g, y, x;

		pos = 4 + GET_32BIT(pubblob);
		pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p);
		pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q);
		pos += ssh2_read_mpint(pubblob+pos, publen-pos, &g);
		pos += ssh2_read_mpint(pubblob+pos, publen-pos, &y);
		pos = 0;
		pos += ssh2_read_mpint(privblob+pos, privlen-pos, &x);

		dropbear_assert(y.start && x.start); /* can't go wrong */

		numbers[0] = p;
		numbers[1] = g;
		numbers[2] = q;
		numbers[3] = y;
		numbers[4] = x;

		nnumbers = 5;
		initial_zero = 1;
		type = "dl-modp{sign{dsa-nist-sha1},dh{plain}}";
	} else {
		dropbear_assert(0);					 /* zoinks! */
	}

	/*
	 * Total size of key blob will be somewhere under 512 plus
	 * combined length of integers. We'll calculate the more
	 * precise size as we construct the blob.
	 */
	outlen = 512;
	for (i = 0; i < nnumbers; i++)
		outlen += 4 + numbers[i].bytes;
	outblob = snewn(outlen, unsigned char);

	/*
	 * Create the unencrypted key blob.
	 */
	pos = 0;
	PUT_32BIT(outblob+pos, SSHCOM_MAGIC_NUMBER); pos += 4;
	pos += 4;							   /* length field, fill in later */
	pos += put_string(outblob+pos, type, strlen(type));
	{
		char *ciphertype = passphrase ? "3des-cbc" : "none";
		pos += put_string(outblob+pos, ciphertype, strlen(ciphertype));
	}
	lenpos = pos;					   /* remember this position */
	pos += 4;							   /* encrypted-blob size */
	pos += 4;							   /* encrypted-payload size */
	if (initial_zero) {
		PUT_32BIT(outblob+pos, 0);
		pos += 4;
	}
	for (i = 0; i < nnumbers; i++)
		pos += sshcom_put_mpint(outblob+pos,
								numbers[i].start, numbers[i].bytes);
	/* Now wrap up the encrypted payload. */
	PUT_32BIT(outblob+lenpos+4, pos - (lenpos+8));
	/* Pad encrypted blob to a multiple of cipher block size. */
	if (passphrase) {
		int padding = -(pos - (lenpos+4)) & 7;
		while (padding--)
			outblob[pos++] = random_byte();
	}
	ciphertext = (char *)outblob+lenpos+4;
	cipherlen = pos - (lenpos+4);
	dropbear_assert(!passphrase || cipherlen % 8 == 0);
	/* Wrap up the encrypted blob string. */
	PUT_32BIT(outblob+lenpos, cipherlen);
	/* And finally fill in the total length field. */
	PUT_32BIT(outblob+4, pos);

	dropbear_assert(pos < outlen);

	/*
	 * Encrypt the key.
	 */
	if (passphrase) {
		/*
		 * Derive encryption key from passphrase and iv/salt:
		 * 
		 *  - let block A equal MD5(passphrase)
		 *  - let block B equal MD5(passphrase || A)
		 *  - block C would be MD5(passphrase || A || B) and so on
		 *  - encryption key is the first N bytes of A || B
		 */
		struct MD5Context md5c;
		unsigned char keybuf[32], iv[8];

		MD5Init(&md5c);
		MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
		MD5Final(keybuf, &md5c);

		MD5Init(&md5c);
		MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
		MD5Update(&md5c, keybuf, 16);
		MD5Final(keybuf+16, &md5c);

		/*
		 * Now decrypt the key blob.
		 */
		memset(iv, 0, sizeof(iv));
		des3_encrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
								 cipherlen);

		memset(&md5c, 0, sizeof(md5c));
		memset(keybuf, 0, sizeof(keybuf));
	}

	/*
	 * And save it. We'll use Unix line endings just in case it's
	 * subsequently transferred in binary mode.
	 */
	fp = fopen(filename, "wb");	  /* ensure Unix line endings */
	if (!fp)
		goto error;
	fputs("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);
	fprintf(fp, "Comment: \"");
	/*
	 * Comment header is broken with backslash-newline if it goes
	 * over 70 chars. Although it's surrounded by quotes, it
	 * _doesn't_ escape backslashes or quotes within the string.
	 * Don't ask me, I didn't design it.
	 */
	{
		int slen = 60;					   /* starts at 60 due to "Comment: " */
		char *c = key->comment;
		while ((int)strlen(c) > slen) {
			fprintf(fp, "%.*s\\\n", slen, c);
			c += slen;
			slen = 70;					   /* allow 70 chars on subsequent lines */
		}
		fprintf(fp, "%s\"\n", c);
	}
	base64_encode_fp(fp, outblob, pos, 70);
	fputs("---- END SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);
	fclose(fp);
	ret = 1;

	error:
	if (outblob) {
		memset(outblob, 0, outlen);
		m_free(outblob);
	}
	if (privblob) {
		memset(privblob, 0, privlen);
		m_free(privblob);
	}
	if (pubblob) {
		memset(pubblob, 0, publen);
		m_free(pubblob);
	}
	return ret;
}
#endif /* ssh.com stuff disabled */

/* From PuTTY misc.c */
static int toint(unsigned u)
{
	/*
	 * Convert an unsigned to an int, without running into the
	 * undefined behaviour which happens by the strict C standard if
	 * the value overflows. You'd hope that sensible compilers would
	 * do the sensible thing in response to a cast, but actually I
	 * don't trust modern compilers not to do silly things like
	 * assuming that _obviously_ you wouldn't have caused an overflow
	 * and so they can elide an 'if (i < 0)' test immediately after
	 * the cast.
	 *
	 * Sensible compilers ought of course to optimise this entire
	 * function into 'just return the input value'!
	 */
	if (u <= (unsigned)INT_MAX)
		return (int)u;
	else if (u >= (unsigned)INT_MIN)   /* wrap in cast _to_ unsigned is OK */
		return INT_MIN + (int)(u - (unsigned)INT_MIN);
	else
		return INT_MIN; /* fallback; should never occur on binary machines */
}
