/*
 * 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"

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};

#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);

#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)
{
    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) {
			*id = (*id << 7) | (*p & 0x7F);
			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) {
		int n = *p & 0x7F;
		p++, sourcelen--;
		if (sourcelen < n)
			return -1;
		*length = 0;
		while (n--)
			*length = (*length << 8) | (*p++);
		sourcelen -= n;
	} else {
		*length = *p;
		p++, sourcelen--;
	}

	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(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;
	}

	memset(buffer, 0, sizeof(buffer));
	return ret;

	error:
	memset(buffer, 0, sizeof(buffer));
	if (ret) {
		if (ret->keyblob) {
			memset(ret->keyblob, 0, ret->keyblob_size);
			m_free(ret->keyblob);
		}
		memset(&ret, 0, sizeof(ret));
		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;
	memset(key->keyblob, 0, key->keyblob_size);
	m_free(key->keyblob);
	memset(&key, 0, sizeof(key));
	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;
	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) {
		errmsg = "ASN.1 decoding failure - wrong password?";
		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 (key->type == OSSH_DSA) {
		buf_putstring(blobbuf, "ssh-dss", 7);
		retkey->type = DROPBEAR_SIGNKEY_DSS;
	} else if (key->type == OSSH_RSA) {
		buf_putstring(blobbuf, "ssh-rsa", 7);
		retkey->type = DROPBEAR_SIGNKEY_RSA;
	}

	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 ||
			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;
			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 = (char *)p;
				modlen = len;
			} else if (i >= 2 && i <= 5) {
				buf_putstring(blobbuf, p, len);
				if (i == 2) {
					buf_putstring(blobbuf, modptr, modlen);
				}
			}
		} else if (key->type == OSSH_DSA) {
			/*
			 * OpenSSH key order is p, q, g, y, x,
			 * we want the same.
			 */
			buf_putstring(blobbuf, p, len);
		}

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

#ifdef 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 ||
			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) {
			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 ||
			key->keyblob+key->keyblob_len-p < len) {
			errmsg = "ASN.1 decoding failure";
			goto error;
		}

		if (0) {}
#ifdef 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
#ifdef 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
#ifdef 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) {
			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 ||
			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, len, seqlen, i;
	char *header = NULL, *footer = NULL;
	char zero[1];
	int ret = 0;
	FILE *fp;

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

	if (key->type == DROPBEAR_SIGNKEY_RSA || key->type == DROPBEAR_SIGNKEY_DSS)
	{
		/*
		 * 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 */

#ifdef 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;

		/* 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 */
		dropbear_assert(mp_unsigned_bin_size((*eck)->k) == curve_size);
		buf_incrwritepos(seq_buf,
			ber_write_id_len(buf_getwriteptr(seq_buf, 10), 4, curve_size, 0));
	    mp_to_unsigned_bin((*eck)->k, buf_getwriteptr(seq_buf, curve_size));
		buf_incrwritepos(seq_buf, curve_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);
		int 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(200);

		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 */
	pos += 4 + GET_32BIT(key->keyblob + pos);   /* skip key type */
	if (key->keyblob_len < pos+4)
		goto done;					 /* key is far too short */
	len = GET_32BIT(key->keyblob + pos);   /* find cipher-type length */
	if (key->keyblob_len < pos+4+len)
		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)
{
	int bits;
	int 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, 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 = GET_32BIT(ciphertext);
	if (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;
	}

	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 */
