summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog20
-rw-r--r--Makefile.in5
-rw-r--r--auth-bsdauth.c4
-rw-r--r--auth-chall.c5
-rw-r--r--auth-options.c14
-rw-r--r--auth-rsa.c5
-rw-r--r--auth2-none.c5
-rw-r--r--auth2-pubkey.c6
-rw-r--r--authfile.c1421
-rw-r--r--authfile.h63
-rw-r--r--cipher-3des1.c55
-rw-r--r--cipher-chachapoly.c25
-rw-r--r--cipher-chachapoly.h4
-rw-r--r--cipher.c363
-rw-r--r--cipher.h57
-rw-r--r--digest-libc.c27
-rw-r--r--digest-openssl.c36
-rw-r--r--digest.h7
-rw-r--r--dns.c4
-rw-r--r--entropy.c2
-rw-r--r--hmac.h5
-rw-r--r--hostfile.c3
-rw-r--r--key.c2803
-rw-r--r--key.h187
-rw-r--r--krl.c8
-rw-r--r--monitor.c5
-rw-r--r--openbsd-compat/openssl-compat.c141
-rw-r--r--openbsd-compat/openssl-compat.h118
-rw-r--r--packet.c38
-rw-r--r--rsa.c113
-rw-r--r--rsa.h6
-rw-r--r--ssh-add.c24
-rw-r--r--ssh-agent.c24
-rw-r--r--ssh-dss.c237
-rw-r--r--ssh-ecdsa.c232
-rw-r--r--ssh-ed25519.c183
-rw-r--r--ssh-keygen.c20
-rw-r--r--ssh-pkcs11-client.c4
-rw-r--r--ssh-pkcs11-helper.c8
-rw-r--r--ssh-pkcs11.c4
-rw-r--r--ssh-rsa.c260
-rw-r--r--sshbuf-misc.c16
-rw-r--r--sshbuf.h7
-rw-r--r--sshconnect.c4
-rw-r--r--sshconnect1.c18
-rw-r--r--sshconnect2.c8
-rw-r--r--sshd.c16
-rw-r--r--sshkey.c3843
-rw-r--r--sshkey.h222
49 files changed, 5812 insertions, 4873 deletions
diff --git a/ChangeLog b/ChangeLog
index 8f24fc6b..e821f6de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -24,6 +24,26 @@
Readers of a broken KRL caused by this bug will fail closed, so no
should-have-been-revoked key will be accepted.
+ - djm@cvs.openbsd.org 2014/06/24 01:13:21
+ [Makefile.in auth-bsdauth.c auth-chall.c auth-options.c auth-rsa.c
+ [auth2-none.c auth2-pubkey.c authfile.c authfile.h cipher-3des1.c
+ [cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h
+ [digest-libc.c digest-openssl.c digest.h dns.c entropy.c hmac.h
+ [hostfile.c key.c key.h krl.c monitor.c packet.c rsa.c rsa.h
+ [ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c
+ [ssh-keygen.c ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c
+ [ssh-rsa.c sshbuf-misc.c sshbuf.h sshconnect.c sshconnect1.c
+ [sshconnect2.c sshd.c sshkey.c sshkey.h
+ [openbsd-compat/openssl-compat.c openbsd-compat/openssl-compat.h]
+ New key API: refactor key-related functions to be more library-like,
+ existing API is offered as a set of wrappers.
+
+ with and ok markus@
+
+ Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew
+ Dempsky and Ron Bowes for a detailed review a few months ago.
+ NB. This commit also removes portable OpenSSH support for OpenSSL
+ <0.9.8e.
20140618
- (tim) [openssh/session.c] Work around to get chroot sftp working on UnixWare
diff --git a/Makefile.in b/Makefile.in
index 6bca5b51..16659c0b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
-# $Id: Makefile.in,v 1.359 2014/05/21 22:23:59 djm Exp $
+# $Id: Makefile.in,v 1.360 2014/07/02 05:28:03 djm Exp $
# uncomment if you run a non bourne compatable shell. Ie. csh
#SHELL = @SH@
@@ -68,7 +68,8 @@ LIBOPENSSH_OBJS=\
sshbuf.o \
sshbuf-getput-basic.o \
sshbuf-misc.o \
- sshbuf-getput-crypto.o
+ sshbuf-getput-crypto.o \
+ sshkey.o
LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
authfd.o authfile.o bufaux.o bufbn.o buffer.o \
diff --git a/auth-bsdauth.c b/auth-bsdauth.c
index f4209c22..37ff893e 100644
--- a/auth-bsdauth.c
+++ b/auth-bsdauth.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-bsdauth.c,v 1.12 2014/03/12 04:50:32 djm Exp $ */
+/* $OpenBSD: auth-bsdauth.c,v 1.13 2014/06/24 01:13:21 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@@ -26,6 +26,8 @@
#include "includes.h"
#include <sys/types.h>
+#include <stdarg.h>
+#include <stdio.h>
#include <stdarg.h>
diff --git a/auth-chall.c b/auth-chall.c
index 0005aa88..cb3d522d 100644
--- a/auth-chall.c
+++ b/auth-chall.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-chall.c,v 1.13 2013/05/17 00:13:13 djm Exp $ */
+/* $OpenBSD: auth-chall.c,v 1.14 2014/06/24 01:13:21 djm Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
*
@@ -26,6 +26,9 @@
#include "includes.h"
#include <sys/types.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
#include <stdarg.h>
diff --git a/auth-options.c b/auth-options.c
index fa209eaa..9a3c270e 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-options.c,v 1.62 2013/12/19 00:27:57 djm Exp $ */
+/* $OpenBSD: auth-options.c,v 1.63 2014/06/24 01:13:21 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -586,8 +586,8 @@ auth_cert_options(Key *k, struct passwd *pw)
if (key_cert_is_legacy(k)) {
/* All options are in the one field for v00 certs */
- if (parse_option_list(buffer_ptr(&k->cert->critical),
- buffer_len(&k->cert->critical), pw,
+ if (parse_option_list(buffer_ptr(k->cert->critical),
+ buffer_len(k->cert->critical), pw,
OPTIONS_CRITICAL|OPTIONS_EXTENSIONS, 1,
&cert_no_port_forwarding_flag,
&cert_no_agent_forwarding_flag,
@@ -599,14 +599,14 @@ auth_cert_options(Key *k, struct passwd *pw)
return -1;
} else {
/* Separate options and extensions for v01 certs */
- if (parse_option_list(buffer_ptr(&k->cert->critical),
- buffer_len(&k->cert->critical), pw,
+ if (parse_option_list(buffer_ptr(k->cert->critical),
+ buffer_len(k->cert->critical), pw,
OPTIONS_CRITICAL, 1, NULL, NULL, NULL, NULL, NULL,
&cert_forced_command,
&cert_source_address_done) == -1)
return -1;
- if (parse_option_list(buffer_ptr(&k->cert->extensions),
- buffer_len(&k->cert->extensions), pw,
+ if (parse_option_list(buffer_ptr(k->cert->extensions),
+ buffer_len(k->cert->extensions), pw,
OPTIONS_EXTENSIONS, 1,
&cert_no_port_forwarding_flag,
&cert_no_agent_forwarding_flag,
diff --git a/auth-rsa.c b/auth-rsa.c
index 5dad6c3d..1bddfa02 100644
--- a/auth-rsa.c
+++ b/auth-rsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth-rsa.c,v 1.86 2014/01/27 19:18:54 markus Exp $ */
+/* $OpenBSD: auth-rsa.c,v 1.87 2014/06/24 01:13:21 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -144,7 +144,8 @@ auth_rsa_challenge_dialog(Key *key)
challenge = PRIVSEP(auth_rsa_generate_challenge(key));
/* Encrypt the challenge with the public key. */
- rsa_public_encrypt(encrypted_challenge, challenge, key->rsa);
+ if (rsa_public_encrypt(encrypted_challenge, challenge, key->rsa) != 0)
+ fatal("%s: rsa_public_encrypt failed", __func__);
/* Send the encrypted challenge to the client. */
packet_start(SSH_SMSG_AUTH_RSA_CHALLENGE);
diff --git a/auth2-none.c b/auth2-none.c
index c8c6c74a..5501b9d6 100644
--- a/auth2-none.c
+++ b/auth2-none.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-none.c,v 1.16 2010/06/25 08:46:17 djm Exp $ */
+/* $OpenBSD: auth2-none.c,v 1.17 2014/06/24 01:13:21 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -30,9 +30,10 @@
#include <sys/uio.h>
#include <fcntl.h>
-#include <stdarg.h>
#include <string.h>
#include <unistd.h>
+#include <stdarg.h>
+#include <stdio.h>
#include "atomicio.h"
#include "xmalloc.h"
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 0fd27bb9..b2fd07a6 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth2-pubkey.c,v 1.39 2013/12/30 23:52:27 djm Exp $ */
+/* $OpenBSD: auth2-pubkey.c,v 1.40 2014/06/24 01:13:21 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
*
@@ -230,7 +230,7 @@ pubkey_auth_info(Authctxt *authctxt, const Key *key, const char *fmt, ...)
}
static int
-match_principals_option(const char *principal_list, struct KeyCert *cert)
+match_principals_option(const char *principal_list, struct sshkey_cert *cert)
{
char *result;
u_int i;
@@ -250,7 +250,7 @@ match_principals_option(const char *principal_list, struct KeyCert *cert)
}
static int
-match_principals_file(char *file, struct passwd *pw, struct KeyCert *cert)
+match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert)
{
FILE *f;
char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts;
diff --git a/authfile.c b/authfile.c
index 7cb90113..e93d8673 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,18 +1,5 @@
-/* $OpenBSD: authfile.c,v 1.106 2014/04/29 18:01:49 markus Exp $ */
+/* $OpenBSD: authfile.c,v 1.107 2014/06/24 01:13:21 djm Exp $ */
/*
- * Author: Tatu Ylonen <ylo@cs.hut.fi>
- * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
- * All rights reserved
- * This file contains functions for reading and writing identity files, and
- * for reading the passphrase from the user.
- *
- * As far as I am concerned, the code I have written for this software
- * can be used freely for any purpose. Any derived versions of this
- * software must be clearly marked as such, and if the derived work is
- * incompatible with the protocol description in the RFC file, it must be
- * called by a name other than "ssh" or "Secure Shell".
- *
- *
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,32 +30,15 @@
#include <sys/param.h>
#include <sys/uio.h>
-#ifdef WITH_OPENSSL
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/pem.h>
-#endif
-
-/* compatibility with old or broken OpenSSL versions */
-#include "openbsd-compat/openssl-compat.h"
-
-#include "crypto_api.h"
-
#include <errno.h>
#include <fcntl.h>
-#include <stdarg.h>
#include <stdio.h>
+#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
-#ifdef HAVE_UTIL_H
-#include <util.h>
-#endif
-
-#include "xmalloc.h"
#include "cipher.h"
-#include "buffer.h"
#include "key.h"
#include "ssh.h"
#include "log.h"
@@ -76,667 +46,92 @@
#include "rsa.h"
#include "misc.h"
#include "atomicio.h"
-#include "uuencode.h"
-
-/* openssh private key file format */
-#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n"
-#define MARK_END "-----END OPENSSH PRIVATE KEY-----\n"
-#define KDFNAME "bcrypt"
-#define AUTH_MAGIC "openssh-key-v1"
-#define SALT_LEN 16
-#define DEFAULT_CIPHERNAME "aes256-cbc"
-#define DEFAULT_ROUNDS 16
+#include "sshbuf.h"
+#include "ssherr.h"
#define MAX_KEY_FILE_SIZE (1024 * 1024)
-/* Version identification string for SSH v1 identity files. */
-static const char authfile_id_string[] =
- "SSH PRIVATE KEY FILE FORMAT 1.1\n";
-
-static int
-key_private_to_blob2(Key *prv, Buffer *blob, const char *passphrase,
- const char *comment, const char *ciphername, int rounds)
-{
- u_char *key, *cp, salt[SALT_LEN];
- size_t keylen, ivlen, blocksize, authlen;
- u_int len, check;
- int i, n;
- const Cipher *c;
- Buffer encoded, b, kdf;
- CipherContext ctx;
- const char *kdfname = KDFNAME;
-
- if (rounds <= 0)
- rounds = DEFAULT_ROUNDS;
- if (passphrase == NULL || !strlen(passphrase)) {
- ciphername = "none";
- kdfname = "none";
- } else if (ciphername == NULL)
- ciphername = DEFAULT_CIPHERNAME;
- else if (cipher_number(ciphername) != SSH_CIPHER_SSH2)
- fatal("invalid cipher");
-
- if ((c = cipher_by_name(ciphername)) == NULL)
- fatal("unknown cipher name");
- buffer_init(&kdf);
- blocksize = cipher_blocksize(c);
- keylen = cipher_keylen(c);
- ivlen = cipher_ivlen(c);
- authlen = cipher_authlen(c);
- key = xcalloc(1, keylen + ivlen);
- if (strcmp(kdfname, "none") != 0) {
- arc4random_buf(salt, SALT_LEN);
- if (bcrypt_pbkdf(passphrase, strlen(passphrase),
- salt, SALT_LEN, key, keylen + ivlen, rounds) < 0)
- fatal("bcrypt_pbkdf failed");
- buffer_put_string(&kdf, salt, SALT_LEN);
- buffer_put_int(&kdf, rounds);
- }
- cipher_init(&ctx, c, key, keylen, key + keylen , ivlen, 1);
- explicit_bzero(key, keylen + ivlen);
- free(key);
-
- buffer_init(&encoded);
- buffer_append(&encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC));
- buffer_put_cstring(&encoded, ciphername);
- buffer_put_cstring(&encoded, kdfname);
- buffer_put_string(&encoded, buffer_ptr(&kdf), buffer_len(&kdf));
- buffer_put_int(&encoded, 1); /* number of keys */
- key_to_blob(prv, &cp, &len); /* public key */
- buffer_put_string(&encoded, cp, len);
-
- explicit_bzero(cp, len);
- free(cp);
-
- buffer_free(&kdf);
-
- /* set up the buffer that will be encrypted */
- buffer_init(&b);
-
- /* Random check bytes */
- check = arc4random();
- buffer_put_int(&b, check);
- buffer_put_int(&b, check);
-
- /* append private key and comment*/
- key_private_serialize(prv, &b);
- buffer_put_cstring(&b, comment);
-
- /* padding */
- i = 0;
- while (buffer_len(&b) % blocksize)
- buffer_put_char(&b, ++i & 0xff);
-
- /* length */
- buffer_put_int(&encoded, buffer_len(&b));
-
- /* encrypt */
- cp = buffer_append_space(&encoded, buffer_len(&b) + authlen);
- if (cipher_crypt(&ctx, 0, cp, buffer_ptr(&b), buffer_len(&b), 0,
- authlen) != 0)
- fatal("%s: cipher_crypt failed", __func__);
- buffer_free(&b);
- cipher_cleanup(&ctx);
-
- /* uuencode */
- len = 2 * buffer_len(&encoded);
- cp = xmalloc(len);
- n = uuencode(buffer_ptr(&encoded), buffer_len(&encoded),
- (char *)cp, len);
- if (n < 0)
- fatal("%s: uuencode", __func__);
-
- buffer_clear(blob);
- buffer_append(blob, MARK_BEGIN, sizeof(MARK_BEGIN) - 1);
- for (i = 0; i < n; i++) {
- buffer_put_char(blob, cp[i]);
- if (i % 70 == 69)
- buffer_put_char(blob, '\n');
- }
- if (i % 70 != 69)
- buffer_put_char(blob, '\n');
- buffer_append(blob, MARK_END, sizeof(MARK_END) - 1);
- free(cp);
-
- return buffer_len(blob);
-}
-
-static Key *
-key_parse_private2(Buffer *blob, int type, const char *passphrase,
- char **commentp)
-{
- u_char *key = NULL, *cp, *salt = NULL, pad, last;
- char *comment = NULL, *ciphername = NULL, *kdfname = NULL;
- const u_char *kdfp;
- u_int keylen = 0, ivlen, blocksize, slen, klen, len, rounds, nkeys;
- u_int check1, check2, m1len, m2len;
- size_t authlen;
- const Cipher *c;
- Buffer b, encoded, copy, kdf;
- CipherContext ctx;
- Key *k = NULL;
- int dlen, ret, i;
-
- buffer_init(&b);
- buffer_init(&kdf);
- buffer_init(&encoded);
- buffer_init(&copy);
-
- /* uudecode */
- m1len = sizeof(MARK_BEGIN) - 1;
- m2len = sizeof(MARK_END) - 1;
- cp = buffer_ptr(blob);
- len = buffer_len(blob);
- if (len < m1len || memcmp(cp, MARK_BEGIN, m1len)) {
- debug("%s: missing begin marker", __func__);
- goto out;
- }
- cp += m1len;
- len -= m1len;
- while (len) {
- if (*cp != '\n' && *cp != '\r')
- buffer_put_char(&encoded, *cp);
- last = *cp;
- len--;
- cp++;
- if (last == '\n') {
- if (len >= m2len && !memcmp(cp, MARK_END, m2len)) {
- buffer_put_char(&encoded, '\0');
- break;
- }
- }
- }
- if (!len) {
- debug("%s: no end marker", __func__);
- goto out;
- }
- len = buffer_len(&encoded);
- if ((cp = buffer_append_space(&copy, len)) == NULL) {
- error("%s: buffer_append_space", __func__);
- goto out;
- }
- if ((dlen = uudecode(buffer_ptr(&encoded), cp, len)) < 0) {
- error("%s: uudecode failed", __func__);
- goto out;
- }
- if ((u_int)dlen > len) {
- error("%s: crazy uudecode length %d > %u", __func__, dlen, len);
- goto out;
- }
- buffer_consume_end(&copy, len - dlen);
- if (buffer_len(&copy) < sizeof(AUTH_MAGIC) ||
- memcmp(buffer_ptr(&copy), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {
- error("%s: bad magic", __func__);
- goto out;
- }
- buffer_consume(&copy, sizeof(AUTH_MAGIC));
-
- ciphername = buffer_get_cstring_ret(&copy, NULL);
- if (ciphername == NULL ||
- (c = cipher_by_name(ciphername)) == NULL) {
- error("%s: unknown cipher name", __func__);
- goto out;
- }
- if ((passphrase == NULL || !strlen(passphrase)) &&
- strcmp(ciphername, "none") != 0) {
- /* passphrase required */
- goto out;
- }
- kdfname = buffer_get_cstring_ret(&copy, NULL);
- if (kdfname == NULL ||
- (strcmp(kdfname, "none") != 0 && strcmp(kdfname, "bcrypt") != 0)) {
- error("%s: unknown kdf name", __func__);
- goto out;
- }
- if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) {
- error("%s: cipher %s requires kdf", __func__, ciphername);
- goto out;
- }
- /* kdf options */
- kdfp = buffer_get_string_ptr_ret(&copy, &klen);
- if (kdfp == NULL) {
- error("%s: kdf options not set", __func__);
- goto out;
- }
- if (klen > 0) {
- if ((cp = buffer_append_space(&kdf, klen)) == NULL) {
- error("%s: kdf alloc failed", __func__);
- goto out;
- }
- memcpy(cp, kdfp, klen);
- }
- /* number of keys */
- if (buffer_get_int_ret(&nkeys, &copy) < 0) {
- error("%s: key counter missing", __func__);
- goto out;
- }
- if (nkeys != 1) {
- error("%s: only one key supported", __func__);
- goto out;
- }
- /* pubkey */
- if ((cp = buffer_get_string_ret(&copy, &len)) == NULL) {
- error("%s: pubkey not found", __func__);
- goto out;
- }
- free(cp); /* XXX check pubkey against decrypted private key */
-
- /* size of encrypted key blob */
- len = buffer_get_int(&copy);
- blocksize = cipher_blocksize(c);
- authlen = cipher_authlen(c);
- if (len < blocksize) {
- error("%s: encrypted data too small", __func__);
- goto out;
- }
- if (len % blocksize) {
- error("%s: length not multiple of blocksize", __func__);
- goto out;
- }
-
- /* setup key */
- keylen = cipher_keylen(c);
- ivlen = cipher_ivlen(c);
- key = xcalloc(1, keylen + ivlen);
- if (!strcmp(kdfname, "bcrypt")) {
- if ((salt = buffer_get_string_ret(&kdf, &slen)) == NULL) {
- error("%s: salt not set", __func__);
- goto out;
- }
- if (buffer_get_int_ret(&rounds, &kdf) < 0) {
- error("%s: rounds not set", __func__);
- goto out;
- }
- if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,
- key, keylen + ivlen, rounds) < 0) {
- error("%s: bcrypt_pbkdf failed", __func__);
- goto out;
- }
- }
-
- cp = buffer_append_space(&b, len);
- cipher_init(&ctx, c, key, keylen, key + keylen, ivlen, 0);
- ret = cipher_crypt(&ctx, 0, cp, buffer_ptr(&copy), len, 0, authlen);
- cipher_cleanup(&ctx);
- buffer_consume(&copy, len);
-
- /* fail silently on decryption errors */
- if (ret != 0) {
- debug("%s: decrypt failed", __func__);
- goto out;
- }
-
- if (buffer_len(&copy) != 0) {
- error("%s: key blob has trailing data (len = %u)", __func__,
- buffer_len(&copy));
- goto out;
- }
-
- /* check bytes */
- if (buffer_get_int_ret(&check1, &b) < 0 ||
- buffer_get_int_ret(&check2, &b) < 0) {
- error("check bytes missing");
- goto out;
- }
- if (check1 != check2) {
- debug("%s: decrypt failed: 0x%08x != 0x%08x", __func__,
- check1, check2);
- goto out;
- }
-
- k = key_private_deserialize(&b);
-
- /* comment */
- comment = buffer_get_cstring_ret(&b, NULL);
-
- i = 0;
- while (buffer_len(&b)) {
- if (buffer_get_char_ret(&pad, &b) == -1 ||
- pad != (++i & 0xff)) {
- error("%s: bad padding", __func__);
- key_free(k);
- k = NULL;
- goto out;
- }
- }
-
- if (k && commentp) {
- *commentp = comment;
- comment = NULL;
- }
-
- /* XXX decode pubkey and check against private */
- out:
- free(ciphername);
- free(kdfname);
- free(salt);
- free(comment);
- if (key)
- explicit_bzero(key, keylen + ivlen);
- free(key);
- buffer_free(&encoded);
- buffer_free(&copy);
- buffer_free(&kdf);
- buffer_free(&b);
- return k;
-}
-
-#ifdef WITH_SSH1
-/*
- * Serialises the authentication (private) key to a blob, encrypting it with
- * passphrase. The identification of the blob (lowest 64 bits of n) will
- * precede the key to provide identification of the key without needing a
- * passphrase.
- */
-static int
-key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase,
- const char *comment)
-{
- Buffer buffer, encrypted;
- u_char buf[100], *cp;
- int i, cipher_num;
- CipherContext ciphercontext;
- const Cipher *cipher;
- u_int32_t rnd;
-
- /*
- * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
- * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
- */
- cipher_num = (strcmp(passphrase, "") == 0) ?
- SSH_CIPHER_NONE : SSH_AUTHFILE_CIPHER;
- if ((cipher = cipher_by_number(cipher_num)) == NULL)
- fatal("save_private_key_rsa: bad cipher");
-
- /* This buffer is used to built the secret part of the private key. */
- buffer_init(&buffer);
-
- /* Put checkbytes for checking passphrase validity. */
- rnd = arc4random();
- buf[0] = rnd & 0xff;
- buf[1] = (rnd >> 8) & 0xff;
- buf[2] = buf[0];
- buf[3] = buf[1];
- buffer_append(&buffer, buf, 4);
-
- /*
- * Store the private key (n and e will not be stored because they
- * will be stored in plain text, and storing them also in encrypted
- * format would just give known plaintext).
- */
- buffer_put_bignum(&buffer, key->rsa->d);
- buffer_put_bignum(&buffer, key->rsa->iqmp);
- buffer_put_bignum(&buffer, key->rsa->q); /* reverse from SSL p */
- buffer_put_bignum(&buffer, key->rsa->p); /* reverse from SSL q */
-
- /* Pad the part to be encrypted until its size is a multiple of 8. */
- while (buffer_len(&buffer) % 8 != 0)
- buffer_put_char(&buffer, 0);
-
- /* This buffer will be used to contain the data in the file. */
- buffer_init(&encrypted);
-
- /* First store keyfile id string. */
- for (i = 0; authfile_id_string[i]; i++)
- buffer_put_char(&encrypted, authfile_id_string[i]);
- buffer_put_char(&encrypted, 0);
-
- /* Store cipher type. */
- buffer_put_char(&encrypted, cipher_num);
- buffer_put_int(&encrypted, 0); /* For future extension */
-
- /* Store public key. This will be in plain text. */
- buffer_put_int(&encrypted, BN_num_bits(key->rsa->n));
- buffer_put_bignum(&encrypted, key->rsa->n);
- buffer_put_bignum(&encrypted, key->rsa->e);
- buffer_put_cstring(&encrypted, comment);
-
- /* Allocate space for the private part of the key in the buffer. */
- cp = buffer_append_space(&encrypted, buffer_len(&buffer));
-
- cipher_set_key_string(&ciphercontext, cipher, passphrase,
- CIPHER_ENCRYPT);
- if (cipher_crypt(&ciphercontext, 0, cp,
- buffer_ptr(&buffer), buffer_len(&buffer), 0, 0) != 0)
- fatal("%s: cipher_crypt failed", __func__);
- cipher_cleanup(&ciphercontext);
- explicit_bzero(&ciphercontext, sizeof(ciphercontext));
-
- /* Destroy temporary data. */
- explicit_bzero(buf, sizeof(buf));
- buffer_free(&buffer);
-
- buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted));
- buffer_free(&encrypted);
-
- return 1;
-}
-#endif
-
-#ifdef WITH_OPENSSL
-/* convert SSH v2 key in OpenSSL PEM format */
-static int
-key_private_pem_to_blob(Key *key, Buffer *blob, const char *_passphrase,
- const char *comment)
-{
- int suc