Changes since OpenSSH 6.7

=========================

This is a major release, containing a number of new features as
well as a large internal re-factoring.

Potentially-incompatible changes
--------------------------------

 * sshd(8): UseDNS now defaults to 'no'. Configurations that match
   against the client host name (via sshd_config or authorized_keys)
   may need to re-enable it or convert to matching against addresses.

New Features
------------

 * Much of OpenSSH's internal code has been re-factored to be more
   library-like. These changes are mostly not user-visible, but
   have greatly improved OpenSSH's testability and internal layout.

 * Add FingerprintHash option to ssh(1) and sshd(8), and equivalent
   command-line flags to the other tools to control algorithm used
   for key fingerprints. The default changes from MD5 to SHA256 and
   format from hex to base64.

   Fingerprints now have the hash algorithm prepended. An example of
   the new format: SHA256:mVPwvezndPv/ARoIadVY98vAC0g+P/5633yTC4d/wXE
   Please note that visual host keys will also be different.

 * ssh(1), sshd(8): Experimental host key rotation support. Add a
   protocol extension for a server to inform a client of all its
   available host keys after authentication has completed. The client
   may record the keys in known_hosts, allowing it to upgrade to better
   host key algorithms and a server to gracefully rotate its keys.

   The client side of this is controlled by a UpdateHostkeys config
   option (default off).

 * ssh(1): Add a ssh_config HostbasedKeyType option to control which
   host public key types are tried during host-based authentication.

 * ssh(1), sshd(8): fix connection-killing host key mismatch errors
   when sshd offers multiple ECDSA keys of different lengths.

 * ssh(1): when host name canonicalisation is enabled, try to
   parse host names as addresses before looking them up for
   canonicalisation. fixes bz#2074 and avoiding needless DNS
   lookups in some cases.

 * ssh-keygen(1), sshd(8): Key Revocation Lists (KRLs) no longer
   require OpenSSH to be compiled with OpenSSL support.

 * ssh(1), ssh-keysign(8): Make ed25519 keys work for host based
   authentication.

 * sshd(8): SSH protocol v.1 workaround for the Meyer, et al,
   Bleichenbacher Side Channel Attack. Fake up a bignum key before
   RSA decryption.

 * sshd(8): Remember which public keys have been used for
   authentication and refuse to accept previously-used keys.
   This allows AuthenticationMethods=publickey,publickey to require
   that users authenticate using two _different_ public keys.

 * sshd(8): add sshd_config HostbasedAcceptedKeyTypes and
   PubkeyAcceptedKeyTypes options to allow sshd to control what
   public key types will be accepted. Currently defaults to all.

 * sshd(8): Don't count partial authentication success as a failure
   against MaxAuthTries.

 * ssh(1): Add RevokedHostKeys option for the client to allow
   text-file or KRL-based revocation of host keys.

 * ssh-keygen(1), sshd(8): Permit KRLs that revoke certificates by
   serial number or key ID without scoping to a particular CA.

 * ssh(1): Add a "Match canonical" criteria that allows ssh_config
   Match blocks to trigger only in the second config pass.

 * ssh(1): Add a -G option to ssh that causes it to parse its
   configuration and dump the result to stdout, similar to "sshd -T".

 * ssh(1): Allow Match criteria to be negated. E.g. "Match !host".

 * The regression test suite has been extended to cover more OpenSSH
   features. The unit tests have been expanded and now cover key
   exchange.

Bugfixes

 * ssh-keyscan(1): ssh-keyscan has been made much more robust again
   servers that hang or violate the SSH protocol.

 * ssh(1), ssh-keygen(1): Fix regression bz#2306: Key path names were
   being lost as comment fields.

 * ssh(1): Allow ssh_config Port options set in the second config
   parse phase to be applied (they were being ignored). bz#2286

 * ssh(1): Tweak config re-parsing with host canonicalisation - make
   the second pass through the config files always run when host name
   canonicalisation is enabled (and not whenever the host name
   changes) bz#2267

 * ssh(1): Fix passing of wildcard forward bind addresses when
   connection multiplexing is in use; bz#2324;

 * ssh-keygen(1): Fix broken private key conversion from non-OpenSSH
   formats; bz#2345.

 * ssh-keygen(1): Fix KRL generation bug when multiple CAs are in
   use.

 * Various fixes to manual pages: bz#2288, bz#2316, bz#2273

Portable OpenSSH

 * Support --without-openssl at configure time

   Disables and removes dependency on OpenSSL. Many features,
   including SSH protocol 1 are not supported and the set of crypto
   options is greatly restricted. This will only work on systems
   with native arc4random or /dev/urandom.

   Considered highly experimental for now.

 * Support --without-ssh1 option at configure time

   Allows disabling support for SSH protocol 1.

 * sshd(8): Fix compilation on systems with IPv6 support in utmpx; bz#2296

 * Allow custom service name for sshd on Cygwin. Permits the use of
   multiple sshd running with different service names.

Checksums:
==========

 - SHA1 (openssh-6.8.tar.gz) = 99903c6ca76e0a2c044711017f81127e12459d37
 - SHA256 (openssh-6.8.tar.gz) = N1uzVarFbrm2CzAwuDu3sRoszmqpK+5phAChP/QNyuw=

 - SHA1 (openssh-6.8p1.tar.gz) = cdbc51e46a902b30d263b05fdc71340920e91c92
 - SHA256 (openssh-6.8p1.tar.gz) = P/ZM5z7hJEgLW/dnuYMNfTwDu8tqvnFrePAZLDfOFg4=

Please note that the PGP key used to sign releases was recently rotated.
The new key has been signed by the old key to provide continuity. It is
available from the mirror sites as RELEASE_KEY.asc.

Reporting Bugs:
===============

- Please read http://www.openssh.com/report.html
  Security bugs should be reported directly to openssh@openssh.com

OpenSSH is brought to you by Markus Friedl, Niels Provos, Theo de Raadt,
Kevin Steves, Damien Miller, Darren Tucker, Jason McIntyre, Tim Rice and
Ben Lindstrom.
This commit is contained in:
christos 2015-04-03 23:49:21 +00:00
parent 8d31b76868
commit e161120f3a
15 changed files with 1572 additions and 240 deletions

View File

@ -37,7 +37,7 @@ The available section types are:
#define KRL_SECTION_FINGERPRINT_SHA1 3
#define KRL_SECTION_SIGNATURE 4
3. Certificate serial section
2. Certificate section
These sections use type KRL_SECTION_CERTIFICATES to revoke certificates by
serial number or key ID. The consist of the CA key that issued the
@ -47,6 +47,11 @@ ignored.
string ca_key
string reserved
Where "ca_key" is the standard SSH wire serialisation of the CA's
public key. Alternately, "ca_key" may be an empty string to indicate
the certificate section applies to all CAs (this is most useful when
revoking key IDs).
Followed by one or more sections:
byte cert_section_type
@ -161,4 +166,4 @@ Implementations that retrieve KRLs over untrusted channels must verify
signatures. Signature sections are optional for KRLs distributed by
trusted means.
$OpenBSD: PROTOCOL.krl,v 1.2 2013/01/18 00:24:58 djm Exp $
$OpenBSD: PROTOCOL.krl,v 1.3 2015/01/30 01:10:33 djm Exp $

View File

@ -0,0 +1,210 @@
/*
* Copyright (c) 2015 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include "bitmap.h"
#define BITMAP_WTYPE u_int
#define BITMAP_MAX (1<<24)
#define BITMAP_BYTES (sizeof(BITMAP_WTYPE))
#define BITMAP_BITS (sizeof(BITMAP_WTYPE) * 8)
#define BITMAP_WMASK ((BITMAP_WTYPE)BITMAP_BITS - 1)
struct bitmap {
BITMAP_WTYPE *d;
size_t len; /* number of words allocated */
size_t top; /* index of top word allocated */
};
struct bitmap *
bitmap_new(void)
{
struct bitmap *ret;
if ((ret = calloc(1, sizeof(*ret))) == NULL)
return NULL;
if ((ret->d = calloc(1, BITMAP_BYTES)) == NULL) {
free(ret);
return NULL;
}
ret->len = 1;
ret->top = 0;
return ret;
}
void
bitmap_free(struct bitmap *b)
{
if (b != NULL && b->d != NULL) {
memset(b->d, 0, b->len);
free(b->d);
}
free(b);
}
void
bitmap_zero(struct bitmap *b)
{
memset(b->d, 0, b->len * BITMAP_BYTES);
b->top = 0;
}
int
bitmap_test_bit(struct bitmap *b, u_int n)
{
if (b->top >= b->len)
return 0; /* invalid */
if (b->len == 0 || (n / BITMAP_BITS) > b->top)
return 0;
return (b->d[n / BITMAP_BITS] >> (n & BITMAP_WMASK)) & 1;
}
static int
reserve(struct bitmap *b, u_int n)
{
BITMAP_WTYPE *tmp;
size_t nlen;
if (b->top >= b->len || n > BITMAP_MAX)
return -1; /* invalid */
nlen = (n / BITMAP_BITS) + 1;
if (b->len < nlen) {
if ((tmp = reallocarray(b->d, nlen, BITMAP_BYTES)) == NULL)
return -1;
b->d = tmp;
memset(b->d + b->len, 0, (nlen - b->len) * BITMAP_BYTES);
b->len = nlen;
}
return 0;
}
int
bitmap_set_bit(struct bitmap *b, u_int n)
{
int r;
size_t offset;
if ((r = reserve(b, n)) != 0)
return r;
offset = n / BITMAP_BITS;
if (offset > b->top)
b->top = offset;
b->d[offset] |= (BITMAP_WTYPE)1 << (n & BITMAP_WMASK);
return 0;
}
/* Resets b->top to point to the most significant bit set in b->d */
static void
retop(struct bitmap *b)
{
if (b->top >= b->len)
return;
while (b->top > 0 && b->d[b->top] == 0)
b->top--;
}
void
bitmap_clear_bit(struct bitmap *b, u_int n)
{
size_t offset;
if (b->top >= b->len || n > BITMAP_MAX)
return; /* invalid */
offset = n / BITMAP_BITS;
if (offset > b->top)
return;
b->d[offset] &= ~((BITMAP_WTYPE)1 << (n & BITMAP_WMASK));
/* The top may have changed as a result of the clear */
retop(b);
}
size_t
bitmap_nbits(struct bitmap *b)
{
size_t bits;
BITMAP_WTYPE w;
retop(b);
if (b->top >= b->len)
return 0; /* invalid */
if (b->len == 0 || (b->top == 0 && b->d[0] == 0))
return 0;
/* Find MSB set */
w = b->d[b->top];
bits = (b->top + 1) * BITMAP_BITS;
while (!(w & ((BITMAP_WTYPE)1 << (BITMAP_BITS - 1)))) {
w <<= 1;
bits--;
}
return bits;
}
size_t
bitmap_nbytes(struct bitmap *b)
{
return (bitmap_nbits(b) + 7) / 8;
}
int
bitmap_to_string(struct bitmap *b, void *p, size_t l)
{
u_char *s = (u_char *)p;
size_t i, j, k, need = bitmap_nbytes(b);
if (l < need || b->top >= b->len)
return -1;
if (l > need)
l = need;
/* Put the bytes from LSB backwards */
for (i = k = 0; i < b->top + 1; i++) {
for (j = 0; j < BITMAP_BYTES; j++) {
if (k >= l)
break;
s[need - 1 - k++] = (b->d[i] >> (j * 8)) & 0xff;
}
}
return 0;
}
int
bitmap_from_string(struct bitmap *b, const void *p, size_t l)
{
int r;
size_t i, offset, shift;
u_char *s = (u_char *)p;
if (l > BITMAP_MAX / 8)
return -1;
if ((r = reserve(b, l * 8)) != 0)
return r;
bitmap_zero(b);
if (l == 0)
return 0;
b->top = offset = ((l + (BITMAP_BYTES - 1)) / BITMAP_BYTES) - 1;
shift = ((l + (BITMAP_BYTES - 1)) % BITMAP_BYTES) * 8;
for (i = 0; i < l; i++) {
b->d[offset] |= (BITMAP_WTYPE)s[i] << shift;
if (shift == 0) {
offset--;
shift = BITMAP_BITS - 8;
} else
shift -= 8;
}
retop(b);
return 0;
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2015 Damien Miller <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _BITMAP_H
#define _BITMAP_H
#include <sys/types.h>
/* Simple bit vector routines */
struct bitmap;
/* Allocate a new bitmap. Returns NULL on allocation failure. */
struct bitmap *bitmap_new(void);
/* Free a bitmap */
void bitmap_free(struct bitmap *b);
/* Zero an existing bitmap */
void bitmap_zero(struct bitmap *b);
/* Test whether a bit is set in a bitmap. */
int bitmap_test_bit(struct bitmap *b, u_int n);
/* Set a bit in a bitmap. Returns 0 on success or -1 on error */
int bitmap_set_bit(struct bitmap *b, u_int n);
/* Clear a bit in a bitmap */
void bitmap_clear_bit(struct bitmap *b, u_int n);
/* Return the number of bits in a bitmap (i.e. the position of the MSB) */
size_t bitmap_nbits(struct bitmap *b);
/* Return the number of bytes needed to represent a bitmap */
size_t bitmap_nbytes(struct bitmap *b);
/* Convert a bitmap to a big endian byte string */
int bitmap_to_string(struct bitmap *b, void *p, size_t l);
/* Convert a big endian byte string to a bitmap */
int bitmap_from_string(struct bitmap *b, const void *p, size_t l);
#endif /* _BITMAP_H */

View File

@ -1,6 +1,6 @@
/* $OpenBSD: cipher-aesctr.c,v 1.1 2014/04/29 15:39:33 markus Exp $ */
/* $OpenBSD: cipher-aesctr.c,v 1.2 2015/01/14 10:24:42 markus Exp $ */
/*
* Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
* Copyright (c) 2003 Markus Friedl. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above

View File

@ -1,4 +1,4 @@
/* $OpenBSD: digest.h,v 1.6 2014/07/03 04:36:45 djm Exp $ */
/* $OpenBSD: digest.h,v 1.7 2014/12/21 22:27:56 djm Exp $ */
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
*
@ -33,6 +33,12 @@
struct sshbuf;
struct ssh_digest_ctx;
/* Looks up a digest algorithm by name */
int ssh_digest_alg_by_name(const char *name);
/* Returns the algorithm name for a digest identifier */
const char *ssh_digest_alg_name(int alg);
/* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */
size_t ssh_digest_bytes(int alg);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ge25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */
/* $OpenBSD: ge25519.h,v 1.4 2015/02/16 18:26:26 miod Exp $ */
/*
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
@ -28,7 +28,7 @@ typedef struct
fe25519 t;
} ge25519;
const ge25519 ge25519_base;
extern const ge25519 ge25519_base;
int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]);

View File

@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $OpenBSD: krl.h,v 1.2 2013/01/18 00:24:58 djm Exp $ */
/* $OpenBSD: krl.h,v 1.4 2015/01/13 19:06:49 djm Exp $ */
#ifndef _KRL_H
#define _KRL_H
@ -36,28 +36,30 @@
#define KRL_SECTION_CERT_SERIAL_BITMAP 0x22
#define KRL_SECTION_CERT_KEY_ID 0x23
struct sshkey;
struct sshbuf;
struct ssh_krl;
struct ssh_krl *ssh_krl_init(void);
void ssh_krl_free(struct ssh_krl *krl);
void ssh_krl_set_version(struct ssh_krl *krl, u_int64_t version);
void ssh_krl_set_sign_key(struct ssh_krl *krl, const Key *sign_key);
void ssh_krl_set_comment(struct ssh_krl *krl, const char *comment);
int ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl, const Key *ca_key,
u_int64_t serial);
int ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl, const Key *ca_key,
u_int64_t lo, u_int64_t hi);
int ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl, const Key *ca_key,
const char *key_id);
int ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const Key *key);
int ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const Key *key);
int ssh_krl_revoke_key(struct ssh_krl *krl, const Key *key);
int ssh_krl_to_blob(struct ssh_krl *krl, Buffer *buf, const Key **sign_keys,
u_int nsign_keys);
int ssh_krl_from_blob(Buffer *buf, struct ssh_krl **krlp,
const Key **sign_ca_keys, u_int nsign_ca_keys);
int ssh_krl_check_key(struct ssh_krl *krl, const Key *key);
int ssh_krl_file_contains_key(const char *path, const Key *key);
void ssh_krl_set_sign_key(struct ssh_krl *krl, const struct sshkey *sign_key);
int ssh_krl_set_comment(struct ssh_krl *krl, const char *comment);
int ssh_krl_revoke_cert_by_serial(struct ssh_krl *krl,
const struct sshkey *ca_key, u_int64_t serial);
int ssh_krl_revoke_cert_by_serial_range(struct ssh_krl *krl,
const struct sshkey *ca_key, u_int64_t lo, u_int64_t hi);
int ssh_krl_revoke_cert_by_key_id(struct ssh_krl *krl,
const struct sshkey *ca_key, const char *key_id);
int ssh_krl_revoke_key_explicit(struct ssh_krl *krl, const struct sshkey *key);
int ssh_krl_revoke_key_sha1(struct ssh_krl *krl, const struct sshkey *key);
int ssh_krl_revoke_key(struct ssh_krl *krl, const struct sshkey *key);
int ssh_krl_to_blob(struct ssh_krl *krl, struct sshbuf *buf,
const struct sshkey **sign_keys, u_int nsign_keys);
int ssh_krl_from_blob(struct sshbuf *buf, struct ssh_krl **krlp,
const struct sshkey **sign_ca_keys, size_t nsign_ca_keys);
int ssh_krl_check_key(struct ssh_krl *krl, const struct sshkey *key);
int ssh_krl_file_contains_key(const char *path, const struct sshkey *key);
#endif /* _KRL_H */

View File

@ -0,0 +1,315 @@
/* Written by Markus Friedl. Placed in the public domain. */
#include "ssherr.h"
#include "packet.h"
#include "log.h"
struct ssh *active_state, *backup_state;
/* Map old to new API */
void
ssh_packet_start(struct ssh *ssh, u_char type)
{
int r;
if ((r = sshpkt_start(ssh, type)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
void
ssh_packet_put_char(struct ssh *ssh, int value)
{
u_char ch = value;
int r;
if ((r = sshpkt_put_u8(ssh, ch)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
void
ssh_packet_put_int(struct ssh *ssh, u_int value)
{
int r;
if ((r = sshpkt_put_u32(ssh, value)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
void
ssh_packet_put_int64(struct ssh *ssh, u_int64_t value)
{
int r;
if ((r = sshpkt_put_u64(ssh, value)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
void
ssh_packet_put_string(struct ssh *ssh, const void *buf, u_int len)
{
int r;
if ((r = sshpkt_put_string(ssh, buf, len)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
void
ssh_packet_put_cstring(struct ssh *ssh, const char *str)
{
int r;
if ((r = sshpkt_put_cstring(ssh, str)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
void
ssh_packet_put_raw(struct ssh *ssh, const void *buf, u_int len)
{
int r;
if ((r = sshpkt_put(ssh, buf, len)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
#ifdef WITH_OPENSSL
void
ssh_packet_put_bignum(struct ssh *ssh, BIGNUM * value)
{
int r;
if ((r = sshpkt_put_bignum1(ssh, value)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
void
ssh_packet_put_bignum2(struct ssh *ssh, BIGNUM * value)
{
int r;
if ((r = sshpkt_put_bignum2(ssh, value)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
void
ssh_packet_put_ecpoint(struct ssh *ssh, const EC_GROUP *curve,
const EC_POINT *point)
{
int r;
if ((r = sshpkt_put_ec(ssh, point, curve)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
#endif /* WITH_OPENSSL */
void
ssh_packet_send(struct ssh *ssh)
{
int r;
if ((r = sshpkt_send(ssh)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
u_int
ssh_packet_get_char(struct ssh *ssh)
{
u_char ch;
int r;
if ((r = sshpkt_get_u8(ssh, &ch)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
return ch;
}
u_int
ssh_packet_get_int(struct ssh *ssh)
{
u_int val;
int r;
if ((r = sshpkt_get_u32(ssh, &val)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
return val;
}
u_int64_t
ssh_packet_get_int64(struct ssh *ssh)
{
u_int64_t val;
int r;
if ((r = sshpkt_get_u64(ssh, &val)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
return val;
}
#ifdef WITH_OPENSSL
void
ssh_packet_get_bignum(struct ssh *ssh, BIGNUM * value)
{
int r;
if ((r = sshpkt_get_bignum1(ssh, value)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
void
ssh_packet_get_bignum2(struct ssh *ssh, BIGNUM * value)
{
int r;
if ((r = sshpkt_get_bignum2(ssh, value)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
void
ssh_packet_get_ecpoint(struct ssh *ssh, const EC_GROUP *curve, EC_POINT *point)
{
int r;
if ((r = sshpkt_get_ec(ssh, point, curve)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
#endif /* WITH_OPENSSL */
void *
ssh_packet_get_string(struct ssh *ssh, u_int *length_ptr)
{
int r;
size_t len;
u_char *val;
if ((r = sshpkt_get_string(ssh, &val, &len)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
if (length_ptr != NULL)
*length_ptr = (u_int)len;
return val;
}
const void *
ssh_packet_get_string_ptr(struct ssh *ssh, u_int *length_ptr)
{
int r;
size_t len;
const u_char *val;
if ((r = sshpkt_get_string_direct(ssh, &val, &len)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
if (length_ptr != NULL)
*length_ptr = (u_int)len;
return val;
}
char *
ssh_packet_get_cstring(struct ssh *ssh, u_int *length_ptr)
{
int r;
size_t len;
char *val;
if ((r = sshpkt_get_cstring(ssh, &val, &len)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
if (length_ptr != NULL)
*length_ptr = (u_int)len;
return val;
}
/* Old API, that had to be reimplemented */
void
packet_set_connection(int fd_in, int fd_out)
{
active_state = ssh_packet_set_connection(active_state, fd_in, fd_out);
if (active_state == NULL)
fatal("%s: ssh_packet_set_connection failed", __func__);
}
void
packet_backup_state(void)
{
ssh_packet_backup_state(active_state, backup_state);
}
void
packet_restore_state(void)
{
ssh_packet_restore_state(active_state, backup_state);
}
u_int
packet_get_char(void)
{
return (ssh_packet_get_char(active_state));
}
u_int
packet_get_int(void)
{
return (ssh_packet_get_int(active_state));
}
int
packet_read_seqnr(u_int32_t *seqnr)
{
u_char type;
int r;
if ((r = ssh_packet_read_seqnr(active_state, &type, seqnr)) != 0)
sshpkt_fatal(active_state, __func__, r);
return type;
}
int
packet_read_poll_seqnr(u_int32_t *seqnr)
{
u_char type;
int r;
if ((r = ssh_packet_read_poll_seqnr(active_state, &type, seqnr)))
sshpkt_fatal(active_state, __func__, r);
return type;
}
void
packet_close(void)
{
ssh_packet_close(active_state);
active_state = NULL;
}
void
packet_process_incoming(const char *buf, u_int len)
{
int r;
if ((r = ssh_packet_process_incoming(active_state, buf, len)) != 0)
sshpkt_fatal(active_state, __func__, r);
}
void
packet_write_wait(void)
{
int r;
if ((r = ssh_packet_write_wait(active_state)) != 0)
sshpkt_fatal(active_state, __func__, r);
}
void
packet_write_poll(void)
{
int r;
if ((r = ssh_packet_write_poll(active_state)) != 0)
sshpkt_fatal(active_state, __func__, r);
}
void
packet_read_expect(int expected_type)
{
int r;
if ((r = ssh_packet_read_expect(active_state, expected_type)) != 0)
sshpkt_fatal(active_state, __func__, r);
}

View File

@ -0,0 +1,167 @@
#ifndef _OPACKET_H
/* Written by Markus Friedl. Placed in the public domain. */
/* Map old to new API */
void ssh_packet_start(struct ssh *, u_char);
void ssh_packet_put_char(struct ssh *, int ch);
void ssh_packet_put_int(struct ssh *, u_int value);
void ssh_packet_put_int64(struct ssh *, u_int64_t value);
void ssh_packet_put_bignum(struct ssh *, BIGNUM * value);
void ssh_packet_put_bignum2(struct ssh *, BIGNUM * value);
void ssh_packet_put_ecpoint(struct ssh *, const EC_GROUP *, const EC_POINT *);
void ssh_packet_put_string(struct ssh *, const void *buf, u_int len);
void ssh_packet_put_cstring(struct ssh *, const char *str);
void ssh_packet_put_raw(struct ssh *, const void *buf, u_int len);
void ssh_packet_send(struct ssh *);
u_int ssh_packet_get_char(struct ssh *);
u_int ssh_packet_get_int(struct ssh *);
u_int64_t ssh_packet_get_int64(struct ssh *);
void ssh_packet_get_bignum(struct ssh *, BIGNUM * value);
void ssh_packet_get_bignum2(struct ssh *, BIGNUM * value);
void ssh_packet_get_ecpoint(struct ssh *, const EC_GROUP *, EC_POINT *);
void *ssh_packet_get_string(struct ssh *, u_int *length_ptr);
char *ssh_packet_get_cstring(struct ssh *, u_int *length_ptr);
/* don't allow remaining bytes after the end of the message */
#define ssh_packet_check_eom(ssh) \
do { \
int _len = ssh_packet_remaining(ssh); \
if (_len > 0) { \
logit("Packet integrity error (%d bytes remaining) at %s:%d", \
_len ,__FILE__, __LINE__); \
ssh_packet_disconnect(ssh, \
"Packet integrity error."); \
} \
} while (0)
/* old API */
void packet_close(void);
u_int packet_get_char(void);
u_int packet_get_int(void);
void packet_backup_state(void);
void packet_restore_state(void);
void packet_set_connection(int, int);
int packet_read_seqnr(u_int32_t *);
int packet_read_poll_seqnr(u_int32_t *);
void packet_process_incoming(const char *buf, u_int len);
void packet_write_wait(void);
void packet_write_poll(void);
void packet_read_expect(int expected_type);
#define packet_set_timeout(timeout, count) \
ssh_packet_set_timeout(active_state, (timeout), (count))
#define packet_connection_is_on_socket() \
ssh_packet_connection_is_on_socket(active_state)
#define packet_set_nonblocking() \
ssh_packet_set_nonblocking(active_state)
#define packet_get_connection_in() \
ssh_packet_get_connection_in(active_state)
#define packet_get_connection_out() \
ssh_packet_get_connection_out(active_state)
#define packet_set_protocol_flags(protocol_flags) \
ssh_packet_set_protocol_flags(active_state, (protocol_flags))
#define packet_get_protocol_flags() \
ssh_packet_get_protocol_flags(active_state)
#define packet_start_compression(level) \
ssh_packet_start_compression(active_state, (level))
#define packet_set_encryption_key(key, keylen, number) \
ssh_packet_set_encryption_key(active_state, (key), (keylen), (number))
#define packet_start(type) \
ssh_packet_start(active_state, (type))
#define packet_put_char(value) \
ssh_packet_put_char(active_state, (value))
#define packet_put_int(value) \
ssh_packet_put_int(active_state, (value))
#define packet_put_int64(value) \
ssh_packet_put_int64(active_state, (value))
#define packet_put_string( buf, len) \
ssh_packet_put_string(active_state, (buf), (len))
#define packet_put_cstring(str) \
ssh_packet_put_cstring(active_state, (str))
#define packet_put_raw(buf, len) \
ssh_packet_put_raw(active_state, (buf), (len))
#define packet_put_bignum(value) \
ssh_packet_put_bignum(active_state, (value))
#define packet_put_bignum2(value) \
ssh_packet_put_bignum2(active_state, (value))
#define packet_send() \
ssh_packet_send(active_state)
#define packet_read() \
ssh_packet_read(active_state)
#define packet_get_int64() \
ssh_packet_get_int64(active_state)
#define packet_get_bignum(value) \
ssh_packet_get_bignum(active_state, (value))
#define packet_get_bignum2(value) \
ssh_packet_get_bignum2(active_state, (value))
#define packet_remaining() \
ssh_packet_remaining(active_state)
#define packet_get_string(length_ptr) \
ssh_packet_get_string(active_state, (length_ptr))
#define packet_get_string_ptr(length_ptr) \
ssh_packet_get_string_ptr(active_state, (length_ptr))
#define packet_get_cstring(length_ptr) \
ssh_packet_get_cstring(active_state, (length_ptr))
#define packet_send_debug(fmt, args...) \
ssh_packet_send_debug(active_state, (fmt), ##args)
#define packet_disconnect(fmt, args...) \
ssh_packet_disconnect(active_state, (fmt), ##args)
#define packet_have_data_to_write() \
ssh_packet_have_data_to_write(active_state)
#define packet_not_very_much_data_to_write() \
ssh_packet_not_very_much_data_to_write(active_state)
#define packet_set_interactive(interactive, qos_interactive, qos_bulk) \
ssh_packet_set_interactive(active_state, (interactive), (qos_interactive), (qos_bulk))
#define packet_is_interactive() \
ssh_packet_is_interactive(active_state)
#define packet_set_maxsize(s) \
ssh_packet_set_maxsize(active_state, (s))
#define packet_inc_alive_timeouts() \
ssh_packet_inc_alive_timeouts(active_state)
#define packet_set_alive_timeouts(ka) \
ssh_packet_set_alive_timeouts(active_state, (ka))
#define packet_get_maxsize() \
ssh_packet_get_maxsize(active_state)
#define packet_add_padding(pad) \
sshpkt_add_padding(active_state, (pad))
#define packet_send_ignore(nbytes) \
ssh_packet_send_ignore(active_state, (nbytes))
#define packet_need_rekeying() \
ssh_packet_need_rekeying(active_state)
#define packet_set_server() \
ssh_packet_set_server(active_state)
#define packet_set_authenticated() \
ssh_packet_set_authenticated(active_state)
#define packet_get_input() \
ssh_packet_get_input(active_state)
#define packet_get_output() \
ssh_packet_get_output(active_state)
#define packet_set_compress_hooks(ctx, allocfunc, freefunc) \
ssh_packet_set_compress_hooks(active_state, ctx, \
allocfunc, freefunc);
#define packet_check_eom() \
ssh_packet_check_eom(active_state)
#define set_newkeys(mode) \
ssh_set_newkeys(active_state, (mode))
#define packet_get_state(m) \
ssh_packet_get_state(active_state, m)
#define packet_set_state(m) \
ssh_packet_set_state(active_state, m)
#if 0
#define get_remote_ipaddr() \
ssh_remote_ipaddr(active_state)
#endif
#define packet_get_raw(lenp) \
sshpkt_ptr(active_state, lenp)
#define packet_get_ecpoint(c,p) \
ssh_packet_get_ecpoint(active_state, c, p)
#define packet_put_ecpoint(c,p) \
ssh_packet_put_ecpoint(active_state, c, p)
#define packet_get_rekey_timeout() \
ssh_packet_get_rekey_timeout(active_state)
#define packet_set_rekey_limits(x,y) \
ssh_packet_set_rekey_limits(active_state, x, y)
#define packet_get_bytes(x,y) \
ssh_packet_get_bytes(active_state, x, y)
#endif /* _OPACKET_H */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: rijndael.c,v 1.18 2014/04/29 15:42:07 markus Exp $ */
/* $OpenBSD: rijndael.c,v 1.19 2014/11/18 22:38:48 mikeb Exp $ */
/**
* rijndael-alg-fst.c
@ -37,13 +37,12 @@ Te0[x] = S [x].[02, 01, 01, 03];
Te1[x] = S [x].[03, 02, 01, 01];
Te2[x] = S [x].[01, 03, 02, 01];
Te3[x] = S [x].[01, 01, 03, 02];
Te4[x] = S [x].[01, 01, 01, 01];
Td0[x] = Si[x].[0e, 09, 0d, 0b];
Td1[x] = Si[x].[0b, 0e, 09, 0d];
Td2[x] = Si[x].[0d, 0b, 0e, 09];
Td3[x] = Si[x].[09, 0d, 0b, 0e];
Td4[x] = Si[x].[01, 01, 01, 01];
Td4[x] = Si[x].[01];
*/
static const u32 Te0[256] = {
@ -310,72 +309,6 @@ static const u32 Te3[256] = {
0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
};
static const u32 Te4[256] = {
0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
};
static const u32 Td0[256] = {
0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
@ -640,72 +573,42 @@ static const u32 Td3[256] = {
0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
};
static const u32 Td4[256] = {
0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
#if 0
static const u8 Td4[256] = {
0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U,
0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU,
0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U,
0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU,
0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU,
0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU,
0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U,
0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U,
0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U,
0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U,
0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU,
0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U,
0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU,
0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U,
0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U,
0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU,
0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU,
0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U,
0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U,
0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU,
0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U,
0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU,
0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U,
0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U,
0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U,
0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU,
0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU,
0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU,
0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U,
0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U,
0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U,
0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
};
#endif
static const u32 rcon[] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000,
@ -734,10 +637,10 @@ rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits)
for (;;) {
temp = rk[3];
rk[4] = rk[0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te0[(temp ) & 0xff] & 0x0000ff00) ^
(Te1[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
@ -754,10 +657,10 @@ rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits)
for (;;) {
temp = rk[ 5];
rk[ 6] = rk[ 0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te0[(temp ) & 0xff] & 0x0000ff00) ^
(Te1[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7];
@ -776,10 +679,10 @@ rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits)
for (;;) {
temp = rk[ 7];
rk[ 8] = rk[ 0] ^
(Te4[(temp >> 16) & 0xff] & 0xff000000) ^
(Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
(Te0[(temp ) & 0xff] & 0x0000ff00) ^
(Te1[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9];
@ -789,10 +692,10 @@ rijndaelKeySetupEnc(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits)
}
temp = rk[11];
rk[12] = rk[ 4] ^
(Te4[(temp >> 24) ] & 0xff000000) ^
(Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(temp ) & 0xff] & 0x000000ff);
(Te2[(temp >> 24) ] & 0xff000000) ^
(Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^
(Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^
(Te1[(temp ) & 0xff] & 0x000000ff);
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
@ -828,25 +731,25 @@ rijndaelKeySetupDec(u32 rk[/*4*(Nr + 1)*/], const u8 cipherKey[], int keyBits)
for (i = 1; i < Nr; i++) {
rk += 4;
rk[0] =
Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[0] ) & 0xff] & 0xff];
Td0[Te1[(rk[0] >> 24) ] & 0xff] ^
Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^
Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^
Td3[Te1[(rk[0] ) & 0xff] & 0xff];
rk[1] =
Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[1] ) & 0xff] & 0xff];
Td0[Te1[(rk[1] >> 24) ] & 0xff] ^
Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^
Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^
Td3[Te1[(rk[1] ) & 0xff] & 0xff];
rk[2] =
Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[2] ) & 0xff] & 0xff];
Td0[Te1[(rk[2] >> 24) ] & 0xff] ^
Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^
Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^
Td3[Te1[(rk[2] ) & 0xff] & 0xff];
rk[3] =
Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[3] ) & 0xff] & 0xff];
Td0[Te1[(rk[3] >> 24) ] & 0xff] ^
Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^
Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^
Td3[Te1[(rk[3] ) & 0xff] & 0xff];
}
return Nr;
}
@ -1007,31 +910,31 @@ rijndaelEncrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 pt[16],
* map cipher state to byte array block:
*/
s0 =
(Te4[(t0 >> 24) ] & 0xff000000) ^
(Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t3 ) & 0xff] & 0x000000ff) ^
(Te2[(t0 >> 24) ] & 0xff000000) ^
(Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Te1[(t3 ) & 0xff] & 0x000000ff) ^
rk[0];
PUTU32(ct , s0);
s1 =
(Te4[(t1 >> 24) ] & 0xff000000) ^
(Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t0 ) & 0xff] & 0x000000ff) ^
(Te2[(t1 >> 24) ] & 0xff000000) ^
(Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Te1[(t0 ) & 0xff] & 0x000000ff) ^
rk[1];
PUTU32(ct + 4, s1);
s2 =
(Te4[(t2 >> 24) ] & 0xff000000) ^
(Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t1 ) & 0xff] & 0x000000ff) ^
(Te2[(t2 >> 24) ] & 0xff000000) ^
(Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Te1[(t1 ) & 0xff] & 0x000000ff) ^
rk[2];
PUTU32(ct + 8, s2);
s3 =
(Te4[(t3 >> 24) ] & 0xff000000) ^
(Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t2 ) & 0xff] & 0x000000ff) ^
(Te2[(t3 >> 24) ] & 0xff000000) ^
(Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Te1[(t2 ) & 0xff] & 0x000000ff) ^
rk[3];
PUTU32(ct + 12, s3);
}
@ -1192,31 +1095,31 @@ rijndaelDecrypt(const u32 rk[/*4*(Nr + 1)*/], int Nr, const u8 ct[16],
* map cipher state to byte array block:
*/
s0 =
(Td4[(t0 >> 24) ] & 0xff000000) ^
(Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t1 ) & 0xff] & 0x000000ff) ^
(Td4[(t0 >> 24) ] << 24) ^
(Td4[(t3 >> 16) & 0xff] << 16) ^
(Td4[(t2 >> 8) & 0xff] << 8) ^
(Td4[(t1 ) & 0xff]) ^
rk[0];
PUTU32(pt , s0);
s1 =
(Td4[(t1 >> 24) ] & 0xff000000) ^
(Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t2 ) & 0xff] & 0x000000ff) ^
(Td4[(t1 >> 24) ] << 24) ^
(Td4[(t0 >> 16) & 0xff] << 16) ^
(Td4[(t3 >> 8) & 0xff] << 8) ^
(Td4[(t2 ) & 0xff]) ^
rk[1];
PUTU32(pt + 4, s1);
s2 =
(Td4[(t2 >> 24) ] & 0xff000000) ^
(Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t3 ) & 0xff] & 0x000000ff) ^
(Td4[(t2 >> 24) ] << 24) ^
(Td4[(t1 >> 16) & 0xff] << 16) ^
(Td4[(t0 >> 8) & 0xff] << 8) ^
(Td4[(t3 ) & 0xff]) ^
rk[2];
PUTU32(pt + 8, s2);
s3 =
(Td4[(t3 >> 24) ] & 0xff000000) ^
(Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t0 ) & 0xff] & 0x000000ff) ^
(Td4[(t3 >> 24) ] << 24) ^
(Td4[(t2 >> 16) & 0xff] << 16) ^
(Td4[(t1 >> 8) & 0xff] << 8) ^
(Td4[(t0 ) & 0xff]) ^
rk[3];
PUTU32(pt + 12, s3);
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sandbox-systrace.c,v 1.13 2014/07/17 00:10:56 djm Exp $ */
/* $OpenBSD: sandbox-systrace.c,v 1.14 2015/01/20 23:14:00 deraadt Exp $ */
/*
* Copyright (c) 2011 Damien Miller <djm@mindrot.org>
*
@ -16,7 +16,6 @@
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <sys/socket.h>
@ -33,6 +32,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include "atomicio.h"
#include "log.h"

View File

@ -0,0 +1,529 @@
/* $OpenBSD: ssh_api.c,v 1.4 2015/02/16 22:13:32 djm Exp $ */
/*
* Copyright (c) 2012 Markus Friedl. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "ssh1.h" /* For SSH_MSG_NONE */
#include "ssh_api.h"
#include "compat.h"
#include "log.h"
#include "authfile.h"
#include "sshkey.h"
#include "misc.h"
#include "ssh1.h"
#include "ssh2.h"
#include "version.h"
#include "myproposal.h"
#include "ssherr.h"
#include "sshbuf.h"
#include <string.h>
int _ssh_exchange_banner(struct ssh *);
int _ssh_send_banner(struct ssh *, char **);
int _ssh_read_banner(struct ssh *, char **);
int _ssh_order_hostkeyalgs(struct ssh *);
int _ssh_verify_host_key(struct sshkey *, struct ssh *);
struct sshkey *_ssh_host_public_key(int, int, struct ssh *);
struct sshkey *_ssh_host_private_key(int, int, struct ssh *);
int _ssh_host_key_sign(struct sshkey *, struct sshkey *, u_char **,
size_t *, const u_char *, size_t, u_int);
/*
* stubs for the server side implementation of kex.
* disable privsep so our stubs will never be called.
*/
int use_privsep = 0;
int mm_sshkey_sign(struct sshkey *, u_char **, u_int *,
u_char *, u_int, u_int);
DH *mm_choose_dh(int, int, int);
/* Define these two variables here so that they are part of the library */
u_char *session_id2 = NULL;
u_int session_id2_len = 0;
int
mm_sshkey_sign(struct sshkey *key, u_char **sigp, u_int *lenp,
u_char *data, u_int datalen, u_int compat)
{
return (-1);
}
DH *
mm_choose_dh(int min, int nbits, int max)
{
return (NULL);
}
/* API */
int
ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params)
{
char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
struct ssh *ssh;
char **proposal;
static int called;
int r;
if (!called) {
OpenSSL_add_all_algorithms();
called = 1;
}
if ((ssh = ssh_packet_set_connection(NULL, -1, -1)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if (is_server)
ssh_packet_set_server(ssh);
/* Initialize key exchange */
proposal = kex_params ? kex_params->proposal : myproposal;
if ((r = kex_new(ssh, proposal, &ssh->kex)) != 0) {
ssh_free(ssh);
return r;
}
ssh->kex->server = is_server;
if (is_server) {
#ifdef WITH_OPENSSL
ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
#endif /* WITH_OPENSSL */
ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_server;
ssh->kex->load_host_public_key=&_ssh_host_public_key;
ssh->kex->load_host_private_key=&_ssh_host_private_key;
ssh->kex->sign=&_ssh_host_key_sign;
} else {
#ifdef WITH_OPENSSL
ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_client;
#endif /* WITH_OPENSSL */
ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_client;
ssh->kex->verify_host_key =&_ssh_verify_host_key;
}
*sshp = ssh;
return 0;
}
void
ssh_free(struct ssh *ssh)
{
struct key_entry *k;
ssh_packet_close(ssh);
/*
* we've only created the public keys variants in case we
* are a acting as a server.
*/
while ((k = TAILQ_FIRST(&ssh->public_keys)) != NULL) {
TAILQ_REMOVE(&ssh->public_keys, k, next);
if (ssh->kex && ssh->kex->server)
sshkey_free(k->key);
free(k);
}
while ((k = TAILQ_FIRST(&ssh->private_keys)) != NULL) {
TAILQ_REMOVE(&ssh->private_keys, k, next);
free(k);
}
if (ssh->kex)
kex_free(ssh->kex);
free(ssh);
}
void
ssh_set_app_data(struct ssh *ssh, void *app_data)
{
ssh->app_data = app_data;
}
void *
ssh_get_app_data(struct ssh *ssh)
{
return ssh->app_data;
}
/* Returns < 0 on error, 0 otherwise */
int
ssh_add_hostkey(struct ssh *ssh, struct sshkey *key)
{
struct sshkey *pubkey = NULL;
struct key_entry *k = NULL, *k_prv = NULL;
int r;
if (ssh->kex->server) {
if ((r = sshkey_from_private(key, &pubkey)) != 0)
return r;
if ((k = malloc(sizeof(*k))) == NULL ||
(k_prv = malloc(sizeof(*k_prv))) == NULL) {
free(k);
sshkey_free(pubkey);
return SSH_ERR_ALLOC_FAIL;
}
k_prv->key = key;
TAILQ_INSERT_TAIL(&ssh->private_keys, k_prv, next);
/* add the public key, too */
k->key = pubkey;
TAILQ_INSERT_TAIL(&ssh->public_keys, k, next);
r = 0;
} else {
if ((k = malloc(sizeof(*k))) == NULL)
return SSH_ERR_ALLOC_FAIL;
k->key = key;
TAILQ_INSERT_TAIL(&ssh->public_keys, k, next);
r = 0;
}
return r;
}
int
ssh_set_verify_host_key_callback(struct ssh *ssh,
int (*cb)(struct sshkey *, struct ssh *))
{
if (cb == NULL || ssh->kex == NULL)
return SSH_ERR_INVALID_ARGUMENT;
ssh->kex->verify_host_key = cb;
return 0;
}
int
ssh_input_append(struct ssh *ssh, const u_char *data, size_t len)
{
return sshbuf_put(ssh_packet_get_input(ssh), data, len);
}
int
ssh_packet_next(struct ssh *ssh, u_char *typep)
{
int r;
u_int32_t seqnr;
u_char type;
/*
* Try to read a packet. Return SSH_MSG_NONE if no packet or not
* enough data.
*/
*typep = SSH_MSG_NONE;
if (ssh->kex->client_version_string == NULL ||
ssh->kex->server_version_string == NULL)
return _ssh_exchange_banner(ssh);
/*
* If we enough data and a dispatch function then
* call the function and get the next packet.
* Otherwise return the packet type to the caller so it
* can decide how to go on.
*
* We will only call the dispatch function for:
* 20-29 Algorithm negotiation
* 30-49 Key exchange method specific (numbers can be reused for
* different authentication methods)
*/
for (;;) {
if ((r = ssh_packet_read_poll2(ssh, &type, &seqnr)) != 0)
return r;
if (type > 0 && type < DISPATCH_MAX &&
type >= SSH2_MSG_KEXINIT && type <= SSH2_MSG_TRANSPORT_MAX &&
ssh->dispatch[type] != NULL) {
if ((r = (*ssh->dispatch[type])(type, seqnr, ssh)) != 0)
return r;
} else {
*typep = type;
return 0;
}
}
}
const u_char *
ssh_packet_payload(struct ssh *ssh, size_t *lenp)
{
return sshpkt_ptr(ssh, lenp);
}
int
ssh_packet_put(struct ssh *ssh, int type, const u_char *data, size_t len)
{
int r;
if ((r = sshpkt_start(ssh, type)) != 0 ||
(r = sshpkt_put(ssh, data, len)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
return r;
return 0;
}
const u_char *
ssh_output_ptr(struct ssh *ssh, size_t *len)
{
struct sshbuf *output = ssh_packet_get_output(ssh);
*len = sshbuf_len(output);
return sshbuf_ptr(output);
}
int
ssh_output_consume(struct ssh *ssh, size_t len)
{
return sshbuf_consume(ssh_packet_get_output(ssh), len);
}
int
ssh_output_space(struct ssh *ssh, size_t len)
{
return (0 == sshbuf_check_reserve(ssh_packet_get_output(ssh), len));
}
int
ssh_input_space(struct ssh *ssh, size_t len)
{
return (0 == sshbuf_check_reserve(ssh_packet_get_input(ssh), len));
}
/* Read other side's version identification. */
int
_ssh_read_banner(struct ssh *ssh, char **bannerp)
{
struct sshbuf *input;
const char *s;
char buf[256], remote_version[256]; /* must be same size! */
const char *mismatch = "Protocol mismatch.\r\n";
int r, remote_major, remote_minor;
size_t i, n, j, len;
*bannerp = NULL;
input = ssh_packet_get_input(ssh);
len = sshbuf_len(input);
s = (const char *)sshbuf_ptr(input);
for (j = n = 0;;) {
for (i = 0; i < sizeof(buf) - 1; i++) {
if (j >= len)
return (0);
buf[i] = s[j++];
if (buf[i] == '\r') {
buf[i] = '\n';
buf[i + 1] = 0;
continue; /**XXX wait for \n */
}
if (buf[i] == '\n') {
buf[i + 1] = 0;
break;
}
}
buf[sizeof(buf) - 1] = 0;
if (strncmp(buf, "SSH-", 4) == 0)
break;
debug("ssh_exchange_identification: %s", buf);
if (ssh->kex->server || ++n > 65536) {
if ((r = sshbuf_put(ssh_packet_get_output(ssh),
mismatch, strlen(mismatch))) != 0)
return r;
return SSH_ERR_NO_PROTOCOL_VERSION;
}
}
if ((r = sshbuf_consume(input, j)) != 0)
return r;
/*
* Check that the versions match. In future this might accept
* several versions and set appropriate flags to handle them.
*/
if (sscanf(buf, "SSH-%d.%d-%[^\n]\n",
&remote_major, &remote_minor, remote_version) != 3)
return SSH_ERR_INVALID_FORMAT;
debug("Remote protocol version %d.%d, remote software version %.100s",
remote_major, remote_minor, remote_version);
ssh->compat = compat_datafellows(remote_version);
if (remote_major == 1 && remote_minor == 99) {
remote_major = 2;
remote_minor = 0;
}
if (remote_major != 2)
return SSH_ERR_PROTOCOL_MISMATCH;
enable_compat20();
chop(buf);
debug("Remote version string %.100s", buf);
if ((*bannerp = strdup(buf)) == NULL)
return SSH_ERR_ALLOC_FAIL;
return 0;
}
/* Send our own protocol version identification. */
int
_ssh_send_banner(struct ssh *ssh, char **bannerp)
{
char buf[256];
int r;
snprintf(buf, sizeof buf, "SSH-2.0-%.100s\r\n", SSH_VERSION);
if ((r = sshbuf_put(ssh_packet_get_output(ssh), buf, strlen(buf))) != 0)
return r;
chop(buf);
debug("Local version string %.100s", buf);
if ((*bannerp = strdup(buf)) == NULL)
return SSH_ERR_ALLOC_FAIL;
return 0;
}
int
_ssh_exchange_banner(struct ssh *ssh)
{
struct kex *kex = ssh->kex;
int r;
/*
* if _ssh_read_banner() cannot parse a full version string
* it will return NULL and we end up calling it again.
*/
r = 0;
if (kex->server) {
if (kex->server_version_string == NULL)
r = _ssh_send_banner(ssh, &kex->server_version_string);
if (r == 0 &&
kex->server_version_string != NULL &&
kex->client_version_string == NULL)
r = _ssh_read_banner(ssh, &kex->client_version_string);
} else {
if (kex->server_version_string == NULL)
r = _ssh_read_banner(ssh, &kex->server_version_string);
if (r == 0 &&
kex->server_version_string != NULL &&
kex->client_version_string == NULL)
r = _ssh_send_banner(ssh, &kex->client_version_string);
}
if (r != 0)
return r;
/* start initial kex as soon as we have exchanged the banners */
if (kex->server_version_string != NULL &&
kex->client_version_string != NULL) {
if ((r = _ssh_order_hostkeyalgs(ssh)) != 0 ||
(r = kex_send_kexinit(ssh)) != 0)
return r;
}
return 0;
}
struct sshkey *
_ssh_host_public_key(int type, int nid, struct ssh *ssh)
{
struct key_entry *k;
debug3("%s: need %d", __func__, type);
TAILQ_FOREACH(k, &ssh->public_keys, next) {
debug3("%s: check %s", __func__, sshkey_type(k->key));
if (k->key->type == type &&
(type != KEY_ECDSA || k->key->ecdsa_nid == nid))
return (k->key);
}
return (NULL);
}
struct sshkey *
_ssh_host_private_key(int type, int nid, struct ssh *ssh)
{
struct key_entry *k;
debug3("%s: need %d", __func__, type);
TAILQ_FOREACH(k, &ssh->private_keys, next) {
debug3("%s: check %s", __func__, sshkey_type(k->key));
if (k->key->type == type &&
(type != KEY_ECDSA || k->key->ecdsa_nid == nid))
return (k->key);
}
return (NULL);
}
int
_ssh_verify_host_key(struct sshkey *hostkey, struct ssh *ssh)
{
struct key_entry *k;
debug3("%s: need %s", __func__, sshkey_type(hostkey));
TAILQ_FOREACH(k, &ssh->public_keys, next) {
debug3("%s: check %s", __func__, sshkey_type(k->key));
if (sshkey_equal_public(hostkey, k->key))
return (0); /* ok */
}
return (-1); /* failed */
}
/* offer hostkey algorithms in kexinit depending on registered keys */
int
_ssh_order_hostkeyalgs(struct ssh *ssh)
{
struct key_entry *k;
char *orig, *avail, *oavail = NULL, *alg, *replace = NULL;
char **proposal;
size_t maxlen;
int ktype, r;
/* XXX we de-serialize ssh->kex->my, modify it, and change it */
if ((r = kex_buf2prop(ssh->kex->my, NULL, &proposal)) != 0)
return r;
orig = proposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
if ((oavail = avail = strdup(orig)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
maxlen = strlen(avail) + 1;
if ((replace = calloc(1, maxlen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
*replace = '\0';
while ((alg = strsep(&avail, ",")) && *alg != '\0') {
if ((ktype = sshkey_type_from_name(alg)) == KEY_UNSPEC)
continue;
TAILQ_FOREACH(k, &ssh->public_keys, next) {
if (k->key->type == ktype ||
(sshkey_is_cert(k->key) && k->key->type ==
sshkey_type_plain(ktype))) {
if (*replace != '\0')
strlcat(replace, ",", maxlen);
strlcat(replace, alg, maxlen);
break;
}
}
}
if (*replace != '\0') {
debug2("%s: orig/%d %s", __func__, ssh->kex->server, orig);
debug2("%s: replace/%d %s", __func__, ssh->kex->server, replace);
free(orig);
proposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = replace;
replace = NULL; /* owned by proposal */
r = kex_prop2buf(ssh->kex->my, proposal);
}
out:
free(oavail);
free(replace);
kex_prop_free(proposal);
return r;
}
int
_ssh_host_key_sign(struct sshkey *privkey, struct sshkey *pubkey,
u_char **signature, size_t *slen,
const u_char *data, size_t dlen, u_int compat)
{
return sshkey_sign(privkey, signature, slen, data, dlen, compat);
}

View File

@ -0,0 +1,136 @@
/* $OpenBSD: ssh_api.h,v 1.1 2015/01/19 20:30:23 markus Exp $ */
/*
* Copyright (c) 2012 Markus Friedl. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef API_H
#define API_H
#include <sys/queue.h>
#include <sys/types.h>
#include <signal.h>
#include "cipher.h"
#include "sshkey.h"
#include "kex.h"
#include "ssh.h"
#include "ssh2.h"
#include "packet.h"
struct kex_params {
char *proposal[PROPOSAL_MAX];
};
/* public SSH API functions */
/*
* ssh_init() create a ssh connection object with given (optional)
* key exchange parameters.
*/
int ssh_init(struct ssh **, int is_server, struct kex_params *kex_params);
/*
* release ssh connection state.
*/
void ssh_free(struct ssh *);
/*
* attach application specific data to the connection state
*/
void ssh_set_app_data(struct ssh *, void *);
void *ssh_get_app_data(struct ssh *);
/*
* ssh_add_hostkey() registers a private/public hostkey for an ssh
* connection.
* ssh_add_hostkey() needs to be called before a key exchange is
* initiated with ssh_packet_next().
* private hostkeys are required if we need to act as a server.
* public hostkeys are used to verify the servers hostkey.
*/
int ssh_add_hostkey(struct ssh *ssh, struct sshkey *key);
/*
* ssh_set_verify_host_key_callback() registers a callback function
* which should be called instead of the default verification. The
* function given must return 0 if the hostkey is ok, -1 if the
* verification has failed.
*/
int ssh_set_verify_host_key_callback(struct ssh *ssh,
int (*cb)(struct sshkey *, struct ssh *));
/*
* ssh_packet_next() advances to the next input packet and returns
* the packet type in typep.
* ssh_packet_next() works by processing an input byte-stream,
* decrypting the received data and hiding the key-exchange from
* the caller.
* ssh_packet_next() sets typep if there is no new packet available.
* in this case the caller must fill the input byte-stream by passing
* the data received over network to ssh_input_append().
* additinally, the caller needs to send the resulting output
* byte-stream back over the network. otherwise the key exchange
* would not proceed. the output byte-stream is accessed through
* ssh_output_ptr().
*/
int ssh_packet_next(struct ssh *ssh, u_char *typep);
/*
* ssh_packet_payload() returns a pointer to the raw payload data of
* the current input packet and the length of this payload.
* the payload is accessible until ssh_packet_next() is called again.
*/
const u_char *ssh_packet_payload(struct ssh *ssh, size_t *lenp);
/*
* ssh_packet_put() creates an encrypted packet with the given type
* and payload.
* the encrypted packet is appended to the output byte-stream.
*/
int ssh_packet_put(struct ssh *ssh, int type, const u_char *data,
size_t len);
/*
* ssh_input_space() checks if 'len' bytes can be appended to the
* input byte-stream.
*/
int ssh_input_space(struct ssh *ssh, size_t len);
/*
* ssh_input_append() appends data to the input byte-stream.
*/
int ssh_input_append(struct ssh *ssh, const u_char *data, size_t len);
/*
* ssh_output_space() checks if 'len' bytes can be appended to the
* output byte-stream. XXX
*/
int ssh_output_space(struct ssh *ssh, size_t len);
/*
* ssh_output_ptr() retrieves both a pointer and the length of the
* current output byte-stream. the bytes need to be sent over the
* network. the number of bytes that have been successfully sent can
* be removed from the output byte-stream with ssh_output_consume().
*/
const u_char *ssh_output_ptr(struct ssh *ssh, size_t *len);
/*
* ssh_output_consume() removes the given number of bytes from
* the output byte-stream.
*/
int ssh_output_consume(struct ssh *ssh, size_t len);
#endif

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssherr.h,v 1.1 2014/04/30 05:29:56 djm Exp $ */
/* $OpenBSD: ssherr.h,v 1.3 2015/01/30 01:13:33 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
@ -73,6 +73,10 @@
#define SSH_ERR_BUFFER_READ_ONLY -49
#define SSH_ERR_KRL_BAD_MAGIC -50
#define SSH_ERR_KEY_REVOKED -51
#define SSH_ERR_CONN_CLOSED -52
#define SSH_ERR_CONN_TIMEOUT -53
#define SSH_ERR_CONN_CORRUPT -54
#define SSH_ERR_PROTOCOL_ERROR -55
/* Translate a numeric error code to a human-readable error string */
const char *ssh_err(int n);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshkey.h,v 1.1 2014/06/24 01:16:58 djm Exp $ */
/* $OpenBSD: sshkey.h,v 1.5 2015/01/26 02:59:11 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
@ -61,16 +61,14 @@ enum sshkey_types {
KEY_UNSPEC
};
/* Fingerprint hash algorithms */
enum sshkey_fp_type {
SSH_FP_SHA1,
SSH_FP_MD5,
SSH_FP_SHA256
};
/* Default fingerprint hash */
#define SSH_FP_HASH_DEFAULT SSH_DIGEST_SHA256
/* Fingerprint representation formats */
enum sshkey_fp_rep {
SSH_FP_DEFAULT = 0,
SSH_FP_HEX,
SSH_FP_BASE64,
SSH_FP_BUBBLEBABBLE,
SSH_FP_RANDOMART
};
@ -118,9 +116,9 @@ 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, enum sshkey_fp_rep);
int sshkey_fingerprint_raw(const struct sshkey *k,
enum sshkey_fp_type dgst_type, u_char **retp, size_t *lenp);
int, 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 *);
@ -152,14 +150,17 @@ 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 *);
int sshkey_names_valid2(const char *, int);
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_fromb(struct sshbuf *, struct sshkey **);
int sshkey_froms(struct sshbuf *, struct sshkey **);
int sshkey_to_blob(const struct sshkey *, u_char **, size_t *);
int sshkey_plain_to_blob_buf(const struct sshkey *, struct sshbuf *);
int sshkey_putb(const struct sshkey *, struct sshbuf *);
int sshkey_puts(const struct sshkey *, struct sshbuf *);
int sshkey_plain_to_blob(const struct sshkey *, u_char **, size_t *);
int sshkey_putb_plain(const struct sshkey *, struct sshbuf *);
int sshkey_sign(const struct sshkey *, u_char **, size_t *,
const u_char *, size_t, u_int);
@ -180,8 +181,6 @@ int sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
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);