struct ssh2_userkey *openssh_new_read(const Filename *filename,
char *passphrase,
const char **errmsg_p);
+int openssh_auto_write(const Filename *filename, struct ssh2_userkey *key,
+ char *passphrase);
int openssh_pem_write(const Filename *filename, struct ssh2_userkey *key,
char *passphrase);
int openssh_new_write(const Filename *filename, struct ssh2_userkey *key,
int export_ssh2(const Filename *filename, int type,
struct ssh2_userkey *key, char *passphrase)
{
- if (type == SSH_KEYTYPE_OPENSSH_PEM)
- return openssh_pem_write(filename, key, passphrase);
+ if (type == SSH_KEYTYPE_OPENSSH_AUTO)
+ return openssh_auto_write(filename, key, passphrase);
if (type == SSH_KEYTYPE_OPENSSH_NEW)
return openssh_new_write(filename, key, passphrase);
if (type == SSH_KEYTYPE_SSHCOM)
retkey = NULL;
for (key_index = 0; key_index < key->nkeys; key_index++) {
- unsigned char *thiskey;
- int thiskeylen, npieces;
+ const unsigned char *thiskey;
+ int thiskeylen;
/*
* Read the key type, which will tell us how to scan over
* of strings, so we just need to know how many of them to
* skip over. (The numbers below exclude the key comment.)
*/
- if (match_ssh_id(stringlen, string, "ssh-rsa")) {
- alg = &ssh_rsa;
- npieces = 6; /* n,e,d,iqmp,q,p */
- } else if (match_ssh_id(stringlen, string, "ssh-dss")) {
- alg = &ssh_dss;
- npieces = 5; /* p,q,g,y,x */
- } else if (match_ssh_id(stringlen, string,
- "ecdsa-sha2-nistp256")) {
- alg = &ssh_ecdsa_nistp256;
- npieces = 3; /* curve name, point, private exponent */
- } else if (match_ssh_id(stringlen, string,
- "ecdsa-sha2-nistp384")) {
- alg = &ssh_ecdsa_nistp384;
- npieces = 3; /* curve name, point, private exponent */
- } else if (match_ssh_id(stringlen, string,
- "ecdsa-sha2-nistp521")) {
- alg = &ssh_ecdsa_nistp521;
- npieces = 3; /* curve name, point, private exponent */
- } else {
- errmsg = "private key did not start with type string\n";
+ {
+ /* find_pubkey_alg needs a zero-terminated copy of the
+ * algorithm name */
+ char *name_zt = dupprintf("%.*s", stringlen, (char *)string);
+ alg = find_pubkey_alg(name_zt);
+ sfree(name_zt);
+ }
+
+ if (!alg) {
+ errmsg = "private key type not recognised\n";
goto error;
}
- thiskey = (unsigned char *)priv;
+ thiskey = priv;
/*
* Skip over the pieces of key.
*/
- for (i = 0; i < npieces; i++) {
+ for (i = 0; i < alg->openssh_private_npieces; i++) {
if (!(string = get_ssh_string(&privlen, &priv, &stringlen))) {
errmsg = "ran out of data in mid-private-key";
goto error;
return ret;
}
+/* ----------------------------------------------------------------------
+ * The switch function openssh_auto_write(), which chooses one of the
+ * concrete OpenSSH output formats based on the key type.
+ */
+int openssh_auto_write(const Filename *filename, struct ssh2_userkey *key,
+ char *passphrase)
+{
+ /*
+ * The old OpenSSH format supports a fixed list of key types. We
+ * assume that anything not in that fixed list is newer, and hence
+ * will use the new format.
+ */
+ if (key->alg == &ssh_dss ||
+ key->alg == &ssh_rsa ||
+ key->alg == &ssh_ecdsa_nistp256 ||
+ key->alg == &ssh_ecdsa_nistp384 ||
+ key->alg == &ssh_ecdsa_nistp521)
+ return openssh_pem_write(filename, key, passphrase);
+ else
+ return openssh_new_write(filename, key, passphrase);
+}
+
/* ----------------------------------------------------------------------
* Code to read ssh.com private keys.
*/