@@ -1,4 +1,4 @@
/* $OpenBSD: sshbuf-misc.c,v 1.1 2014/04/30 05:29:56 djm Exp $ */
/* $OpenBSD: sshbuf-misc.c,v 1.2 2014/06/24 01:13:21 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@@ -33,12 +33,11 @@
#include "sshbuf.h"

void
sshbuf_dump(struct sshbuf *buf, FILE *f)
sshbuf_dump_data(const void *s, size_t len, FILE *f)
{
const u_char *p = sshbuf_ptr(buf);
size_t i, j, len = sshbuf_len(buf);
size_t i, j;
const u_char *p = (const u_char *)s;

fprintf(f, "buffer %p len = %zu\n", buf, len);
for (i = 0; i < len; i += 16) {
fprintf(f, "%.4zd: ", i);
for (j = i; j < i + 16; j++) {
@@ -60,6 +59,13 @@ sshbuf_dump(struct sshbuf *buf, FILE *f)
}
}

void
sshbuf_dump(struct sshbuf *buf, FILE *f)
{
fprintf(f, "buffer %p len = %zu\n", buf, sshbuf_len(buf));
sshbuf_dump_data(sshbuf_ptr(buf), sshbuf_len(buf), f);
}

char *
sshbuf_dtob16(struct sshbuf *buf)
{
@@ -1,4 +1,4 @@
/* $OpenBSD: sshbuf.h,v 1.2 2014/06/10 21:46:11 dtucker Exp $ */
/* $OpenBSD: sshbuf.h,v 1.3 2014/06/24 01:13:21 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@@ -216,9 +216,12 @@ int sshbuf_put_ec(struct sshbuf *buf, const EC_POINT *v, const EC_GROUP *g);
int sshbuf_put_eckey(struct sshbuf *buf, const EC_KEY *v);
#endif

/* Dump the contents of the buffer to stderr in a human-readable format */
/* Dump the contents of the buffer in a human-readable format */
void sshbuf_dump(struct sshbuf *buf, FILE *f);

/* Dump specified memory in a human-readable format */
void sshbuf_dump_data(const void *s, size_t len, FILE *f);

/* Return the hexadecimal representation of the contents of the buffer */
char *sshbuf_dtob16(struct sshbuf *buf);

@@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.c,v 1.248 2014/04/29 18:01:49 markus Exp $ */
/* $OpenBSD: sshconnect.c,v 1.249 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
@@ -709,7 +709,7 @@ check_host_cert(const char *host, const Key *host_key)
error("%s", reason);
return 0;
}
if (buffer_len(&host_key->cert->critical) != 0) {
if (buffer_len(host_key->cert->critical) != 0) {
error("Certificate for %s contains unsupported "
"critical options(s)", host);
return 0;
@@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect1.c,v 1.74 2014/02/02 03:44:32 djm Exp $ */
/* $OpenBSD: sshconnect1.c,v 1.75 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
@@ -166,7 +166,7 @@ respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)

/* Decrypt the challenge using the private key. */
/* XXX think about Bleichenbacher, too */
if (rsa_private_decrypt(challenge, challenge, prv) <= 0)
if (rsa_private_decrypt(challenge, challenge, prv) != 0)
packet_disconnect(
"respond_to_rsa_challenge: rsa_private_decrypt failed");

@@ -253,7 +253,7 @@ try_rsa_authentication(int idx)
* load the private key. Try first with empty passphrase; if it
* fails, ask for a passphrase.
*/
if (public->flags & KEY_FLAG_EXT)
if (public->flags & SSHKEY_FLAG_EXT)
private = public;
else
private = key_load_private_type(KEY_RSA1, authfile, "", NULL,
@@ -302,7 +302,7 @@ try_rsa_authentication(int idx)
respond_to_rsa_challenge(challenge, private->rsa);

/* Destroy the private key unless it in external hardware. */
if (!(private->flags & KEY_FLAG_EXT))
if (!(private->flags & SSHKEY_FLAG_EXT))
key_free(private);

/* We no longer need the challenge. */
@@ -592,8 +592,9 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
BN_num_bits(server_key->rsa->n),
SSH_KEY_BITS_RESERVED);
}
rsa_public_encrypt(key, key, server_key->rsa);
rsa_public_encrypt(key, key, host_key->rsa);
if (rsa_public_encrypt(key, key, server_key->rsa) != 0 ||
rsa_public_encrypt(key, key, host_key->rsa) != 0)
fatal("%s: rsa_public_encrypt failed", __func__);
} else {
/* Host key has smaller modulus (or they are equal). */
if (BN_num_bits(server_key->rsa->n) <
@@ -604,8 +605,9 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
BN_num_bits(host_key->rsa->n),
SSH_KEY_BITS_RESERVED);
}
rsa_public_encrypt(key, key, host_key->rsa);
rsa_public_encrypt(key, key, server_key->rsa);
if (rsa_public_encrypt(key, key, host_key->rsa) != 0 ||
rsa_public_encrypt(key, key, server_key->rsa) != 0)
fatal("%s: rsa_public_encrypt failed", __func__);
}

/* Destroy the public keys since we no longer need them. */
@@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect2.c,v 1.208 2014/06/05 22:17:50 djm Exp $ */
/* $OpenBSD: sshconnect2.c,v 1.209 2014/06/24 01:13:21 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -970,7 +970,7 @@ identity_sign(Identity *id, u_char **sigp, u_int *lenp,
* we have already loaded the private key or
* the private key is stored in external hardware
*/
if (id->isprivate || (id->key->flags & KEY_FLAG_EXT))
if (id->isprivate || (id->key->flags & SSHKEY_FLAG_EXT))
return (key_sign(id->key, sigp, lenp, data, datalen));
/* load the private key from the file */
if ((prv = load_identity_file(id->filename, id->userprovided)) == NULL)
@@ -1178,12 +1178,12 @@ pubkey_prepare(Authctxt *authctxt)
}
/* Prefer PKCS11 keys that are explicitly listed */
TAILQ_FOREACH_SAFE(id, &files, next, tmp) {
if (id->key == NULL || (id->key->flags & KEY_FLAG_EXT) == 0)
if (id->key == NULL || (id->key->flags & SSHKEY_FLAG_EXT) == 0)
continue;
found = 0;
TAILQ_FOREACH(id2, &files, next) {
if (id2->key == NULL ||
(id2->key->flags & KEY_FLAG_EXT) == 0)
(id2->key->flags & SSHKEY_FLAG_EXT) == 0)
continue;
if (key_equal(id->key, id2->key)) {
TAILQ_REMOVE(&files, id, next);
16 sshd.c
@@ -1,4 +1,4 @@
/* $OpenBSD: sshd.c,v 1.426 2014/04/29 18:01:49 markus Exp $ */
/* $OpenBSD: sshd.c,v 1.427 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
@@ -1031,8 +1031,10 @@ recv_rexec_state(int fd, Buffer *conf)
buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp);
buffer_get_bignum(&m, sensitive_data.server_key->rsa->p);
buffer_get_bignum(&m, sensitive_data.server_key->rsa->q);
rsa_generate_additional_parameters(
sensitive_data.server_key->rsa);
if (rsa_generate_additional_parameters(
sensitive_data.server_key->rsa) != 0)
fatal("%s: rsa_generate_additional_parameters "
"error", __func__);
#else
fatal("ssh1 not supported");
#endif
@@ -2215,10 +2217,10 @@ ssh1_session_key(BIGNUM *session_key_int)
SSH_KEY_BITS_RESERVED);
}
if (rsa_private_decrypt(session_key_int, session_key_int,
sensitive_data.server_key->rsa) <= 0)
sensitive_data.server_key->rsa) != 0)
rsafail++;
if (rsa_private_decrypt(session_key_int, session_key_int,
sensitive_data.ssh1_host_key->rsa) <= 0)
sensitive_data.ssh1_host_key->rsa) != 0)
rsafail++;
} else {
/* Host key has bigger modulus (or they are equal). */
@@ -2233,10 +2235,10 @@ ssh1_session_key(BIGNUM *session_key_int)
SSH_KEY_BITS_RESERVED);
}
if (rsa_private_decrypt(session_key_int, session_key_int,
sensitive_data.ssh1_host_key->rsa) < 0)
sensitive_data.ssh1_host_key->rsa) != 0)
rsafail++;
if (rsa_private_decrypt(session_key_int, session_key_int,
sensitive_data.server_key->rsa) < 0)
sensitive_data.server_key->rsa) != 0)
rsafail++;
}
return (rsafail);
3,843 sshkey.c

Large diffs are not rendered by default.

222 sshkey.h
@@ -0,0 +1,222 @@
/* $OpenBSD: sshkey.h,v 1.1 2014/06/24 01:16:58 djm Exp $ */

/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SSHKEY_H
#define SSHKEY_H

#include <sys/types.h>

#ifdef WITH_OPENSSL
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/ec.h>
#else /* OPENSSL */
#define RSA void
#define DSA void
#define EC_KEY void
#define EC_GROUP void
#define EC_POINT void
#endif /* WITH_OPENSSL */

#define SSH_RSA_MINIMUM_MODULUS_SIZE 768
#define SSH_KEY_MAX_SIGN_DATA_SIZE (1 << 20)

struct sshbuf;

/* Key types */
enum sshkey_types {
KEY_RSA1,
KEY_RSA,
KEY_DSA,
KEY_ECDSA,
KEY_ED25519,
KEY_RSA_CERT,
KEY_DSA_CERT,
KEY_ECDSA_CERT,
KEY_ED25519_CERT,
KEY_RSA_CERT_V00,
KEY_DSA_CERT_V00,
KEY_UNSPEC
};

/* Fingerprint hash algorithms */
enum sshkey_fp_type {
SSH_FP_SHA1,
SSH_FP_MD5,
SSH_FP_SHA256
};

/* Fingerprint representation formats */
enum sshkey_fp_rep {
SSH_FP_HEX,
SSH_FP_BUBBLEBABBLE,
SSH_FP_RANDOMART
};

/* key is stored in external hardware */
#define SSHKEY_FLAG_EXT 0x0001

#define SSHKEY_CERT_MAX_PRINCIPALS 256
/* XXX opaquify? */
struct sshkey_cert {
struct sshbuf *certblob; /* Kept around for use on wire */
u_int type; /* SSH2_CERT_TYPE_USER or SSH2_CERT_TYPE_HOST */
u_int64_t serial;
char *key_id;
u_int nprincipals;
char **principals;
u_int64_t valid_after, valid_before;
struct sshbuf *critical;
struct sshbuf *extensions;
struct sshkey *signature_key;
};

/* XXX opaquify? */
struct sshkey {
int type;
int flags;
RSA *rsa;
DSA *dsa;
int ecdsa_nid; /* NID of curve */
EC_KEY *ecdsa;
u_char *ed25519_sk;
u_char *ed25519_pk;
struct sshkey_cert *cert;
};

#define ED25519_SK_SZ crypto_sign_ed25519_SECRETKEYBYTES
#define ED25519_PK_SZ crypto_sign_ed25519_PUBLICKEYBYTES

struct sshkey *sshkey_new(int);
int sshkey_add_private(struct sshkey *);
struct sshkey *sshkey_new_private(int);
void sshkey_free(struct sshkey *);
int sshkey_demote(const struct sshkey *, struct sshkey **);
int sshkey_equal_public(const struct sshkey *,
const struct sshkey *);
int sshkey_equal(const struct sshkey *, const struct sshkey *);
char *sshkey_fingerprint(const struct sshkey *,
enum sshkey_fp_type, enum sshkey_fp_rep);
int sshkey_fingerprint_raw(const struct sshkey *k,
enum sshkey_fp_type dgst_type, u_char **retp, size_t *lenp);
const char *sshkey_type(const struct sshkey *);
const char *sshkey_cert_type(const struct sshkey *);
int sshkey_write(const struct sshkey *, FILE *);
int sshkey_read(struct sshkey *, char **);
u_int sshkey_size(const struct sshkey *);

int sshkey_generate(int type, u_int bits, struct sshkey **keyp);
int sshkey_from_private(const struct sshkey *, struct sshkey **);
int sshkey_type_from_name(const char *);
int sshkey_is_cert(const struct sshkey *);
int sshkey_type_is_cert(int);
int sshkey_type_plain(int);
int sshkey_to_certified(struct sshkey *, int);
int sshkey_drop_cert(struct sshkey *);
int sshkey_certify(struct sshkey *, struct sshkey *);
int sshkey_cert_copy(const struct sshkey *, struct sshkey *);
int sshkey_cert_check_authority(const struct sshkey *, int, int,
const char *, const char **);
int sshkey_cert_is_legacy(const struct sshkey *);

int sshkey_ecdsa_nid_from_name(const char *);
int sshkey_curve_name_to_nid(const char *);
const char * sshkey_curve_nid_to_name(int);
u_int sshkey_curve_nid_to_bits(int);
int sshkey_ecdsa_bits_to_nid(int);
int sshkey_ecdsa_key_to_nid(EC_KEY *);
int sshkey_ec_nid_to_hash_alg(int nid);
int sshkey_ec_validate_public(const EC_GROUP *, const EC_POINT *);
int sshkey_ec_validate_private(const EC_KEY *);
const char *sshkey_ssh_name(const struct sshkey *);
const char *sshkey_ssh_name_plain(const struct sshkey *);
int sshkey_names_valid2(const char *);
char *key_alg_list(int, int);

int sshkey_from_blob(const u_char *, size_t, struct sshkey **);
int sshkey_to_blob_buf(const struct sshkey *, struct sshbuf *);
int sshkey_to_blob(const struct sshkey *, u_char **, size_t *);
int sshkey_plain_to_blob_buf(const struct sshkey *, struct sshbuf *);
int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);

int sshkey_sign(const struct sshkey *, u_char **, size_t *,
const u_char *, size_t, u_int);
int sshkey_verify(const struct sshkey *, const u_char *, size_t,
const u_char *, size_t, u_int);

/* for debug */
void sshkey_dump_ec_point(const EC_GROUP *, const EC_POINT *);
void sshkey_dump_ec_key(const EC_KEY *);

/* private key parsing and serialisation */
int sshkey_private_serialize(const struct sshkey *key, struct sshbuf *buf);
int sshkey_private_deserialize(struct sshbuf *buf, struct sshkey **keyp);

/* private key file format parsing and serialisation */
int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
const char *passphrase, const char *comment,
int force_new_format, const char *new_format_cipher, int new_format_rounds);
int sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob,
struct sshkey **keyp, char **commentp);
int sshkey_parse_private_pem_fileblob(struct sshbuf *blob, int type,
const char *passphrase, struct sshkey **keyp, char **commentp);
int sshkey_parse_private_fileblob(struct sshbuf *buffer,
const char *passphrase, const char *filename, struct sshkey **keyp,
char **commentp);
int sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
const char *passphrase, struct sshkey **keyp, char **commentp);

#ifdef SSHKEY_INTERNAL
int ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat);
int ssh_rsa_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
const u_char *data, size_t datalen, u_int compat);
int ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat);
int ssh_dss_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
const u_char *data, size_t datalen, u_int compat);
int ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat);
int ssh_ecdsa_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
const u_char *data, size_t datalen, u_int compat);
int ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
const u_char *data, size_t datalen, u_int compat);
int ssh_ed25519_verify(const struct sshkey *key,
const u_char *signature, size_t signaturelen,
const u_char *data, size_t datalen, u_int compat);
#endif

#ifndef WITH_OPENSSL
#undef RSA
#undef DSA
#undef EC_KEY
#undef EC_GROUP
#undef EC_POINT
#endif /* WITH_OPENSSL */

#endif /* SSHKEY_H */