Commit 4b4116ce authored by Alexey Alyaev's avatar Alexey Alyaev

Support for building with cygwin-2.5.2 + SSPI

parent e6e05d87
......@@ -95,10 +95,11 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \
kexdhs.o kexgexs.o kexecdhs.o kexc25519s.o \
platform-pledge.o platform-tracing.o
platform-pledge.o platform-tracing.o libcrypto-compat.o
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
sshconnect.o sshconnect1.o sshconnect2.o mux.o proxy.o
sshconnect.o sshconnect1.o sshconnect2.o mux.o proxy.o \
gss-serv-sspi.o
SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
audit.o audit-bsm.o audit-linux.o platform.o \
......@@ -108,7 +109,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
auth2-none.o auth2-passwd.o auth2-pubkey.o \
monitor.o monitor_wrap.o auth-krb5.o \
auth2-gss.o gss-serv.o gss-serv-krb5.o \
auth2-gss.o gss-serv.o gss-serv-krb5.o gss-serv-sspi.o \
loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
sftp-server.o sftp-common.o \
sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
......
# NXSSH on Cygwin 2.5.2 with SSPI module
This branch contains the code from master branch plus additional patches
applied to make it buildable with OpenSSL 1.1.* + cygwin 2.5.2
It also contains patch to enable GSS SSPI feature to support native GSS
token delegation using Windows SSPI interface.
All applied patches that make this branch different from master are located
in patches/ subdirectory.
## Building
```bash
$ WANT_AUTOCONF='2.69' autoreconf -fvi
$ ./configure --with-sspi
$ make -j$((`nproc` + 1))
```
\ No newline at end of file
......@@ -129,6 +129,10 @@ extern u_int utmp_len;
typedef pthread_t sp_pthread_t;
#else
typedef pid_t sp_pthread_t;
# define pthread_create(a, b, c, d) _ssh_compat_pthread_create(a, b, c, d)
# define pthread_exit(a) _ssh_compat_pthread_exit(a)
# define pthread_cancel(a) _ssh_compat_pthread_cancel(a)
# define pthread_join(a, b) _ssh_compat_pthread_join(a, b)
#endif
struct pam_ctxt {
......
......@@ -207,15 +207,22 @@ deserialise_identity1(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
int r, keybits;
u_int32_t bits;
char *comment = NULL;
BIGNUM *e = NULL, *n = NULL;
if ((key = sshkey_new(KEY_RSA1)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_get_u32(ids, &bits)) != 0 ||
(r = sshbuf_get_bignum1(ids, key->rsa->e)) != 0 ||
(r = sshbuf_get_bignum1(ids, key->rsa->n)) != 0 ||
(r = sshbuf_get_cstring(ids, &comment, NULL)) != 0)
if ((e = BN_new()) == NULL ||
(n = BN_new()) == NULL ||
(r = sshbuf_get_u32(ids, &bits)) != 0 ||
(r = sshbuf_get_bignum1(ids, e)) != 0 ||
(r = sshbuf_get_bignum1(ids, n)) != 0 ||
(r = sshbuf_get_cstring(ids, &comment, NULL)) != 0 ||
(RSA_set0_key(key->rsa, n, e, NULL) == 0)) {
BN_free(n);
BN_free(e);
goto out;
keybits = BN_num_bits(key->rsa->n);
}
keybits = BN_num_bits(n);
/* XXX previously we just warned here. I think we should be strict */
if (keybits < 0 || bits != (u_int)keybits) {
r = SSH_ERR_KEY_BITS_MISMATCH;
......@@ -393,15 +400,17 @@ ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
struct sshbuf *msg;
int r;
u_char type;
const BIGNUM *e, *n;
if (key->type != KEY_RSA1)
return SSH_ERR_INVALID_ARGUMENT;
if ((msg = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
RSA_get0_key(key->rsa, &n, &e, NULL);
if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 ||
(r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 ||
(r = sshbuf_put_u32(msg, BN_num_bits(n))) != 0 ||
(r = sshbuf_put_bignum1(msg, e)) != 0 ||
(r = sshbuf_put_bignum1(msg, n)) != 0 ||
(r = sshbuf_put_bignum1(msg, challenge)) != 0 ||
(r = sshbuf_put(msg, session_id, 16)) != 0 ||
(r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */
......@@ -499,15 +508,19 @@ static int
ssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment)
{
int r;
const BIGNUM *n, *e, *d, *q, *p, *iqmp;
RSA_get0_key(key, &n, &e, &d);
RSA_get0_factors(key, &p, &q);
RSA_get0_crt_params(key, NULL, NULL, &iqmp);
/* To keep within the protocol: p < q for ssh. in SSL p > q */
if ((r = sshbuf_put_u32(b, BN_num_bits(key->n))) != 0 ||
(r = sshbuf_put_bignum1(b, key->n)) != 0 ||
(r = sshbuf_put_bignum1(b, key->e)) != 0 ||
(r = sshbuf_put_bignum1(b, key->d)) != 0 ||
(r = sshbuf_put_bignum1(b, key->iqmp)) != 0 ||
(r = sshbuf_put_bignum1(b, key->q)) != 0 ||
(r = sshbuf_put_bignum1(b, key->p)) != 0 ||
if ((r = sshbuf_put_u32(b, BN_num_bits(n))) != 0 ||
(r = sshbuf_put_bignum1(b, n)) != 0 ||
(r = sshbuf_put_bignum1(b, e)) != 0 ||
(r = sshbuf_put_bignum1(b, d)) != 0 ||
(r = sshbuf_put_bignum1(b, iqmp)) != 0 ||
(r = sshbuf_put_bignum1(b, q)) != 0 ||
(r = sshbuf_put_bignum1(b, p)) != 0 ||
(r = sshbuf_put_cstring(b, comment)) != 0)
return r;
return 0;
......@@ -622,11 +635,13 @@ ssh_remove_identity(int sock, struct sshkey *key)
#ifdef WITH_SSH1
if (key->type == KEY_RSA1) {
const BIGNUM *e, *n;
RSA_get0_key(key->rsa, &n, &e, NULL);
if ((r = sshbuf_put_u8(msg,
SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 ||
(r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0)
(r = sshbuf_put_u32(msg, BN_num_bits(n))) != 0 ||
(r = sshbuf_put_bignum1(msg, e)) != 0 ||
(r = sshbuf_put_bignum1(msg, n)) != 0)
goto out;
} else
#endif
......
......@@ -44,7 +44,7 @@
*/
struct ssh1_3des_ctx
{
EVP_CIPHER_CTX k1, k2, k3;
EVP_CIPHER_CTX *k1, *k2, *k3;
};
const EVP_CIPHER * evp_ssh1_3des(void);
......@@ -65,7 +65,7 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
if (key == NULL)
return 1;
if (enc == -1)
enc = ctx->encrypt;
enc = EVP_CIPHER_CTX_encrypting(ctx);
k1 = k2 = k3 = (u_char *) key;
k2 += 8;
if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
......@@ -74,12 +74,19 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
else
k1 += 16;
}
EVP_CIPHER_CTX_init(&c->k1);
EVP_CIPHER_CTX_init(&c->k2);
EVP_CIPHER_CTX_init(&c->k3);
if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
c->k1 = EVP_CIPHER_CTX_new();
c->k2 = EVP_CIPHER_CTX_new();
c->k3 = EVP_CIPHER_CTX_new();
if (c->k1 == NULL || c->k2 == NULL || c->k3 == NULL) {
EVP_CIPHER_CTX_free(c->k1);
EVP_CIPHER_CTX_free(c->k2);
EVP_CIPHER_CTX_free(c->k3);
free(c);
return 0;
}
if (EVP_CipherInit(c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
EVP_CipherInit(c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
EVP_CipherInit(c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
explicit_bzero(c, sizeof(*c));
free(c);
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
......@@ -95,9 +102,9 @@ ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, size_t len)
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
return 0;
if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
EVP_Cipher(&c->k3, dest, dest, len) == 0)
if (EVP_Cipher(c->k1, dest, (u_char *)src, len) == 0 ||
EVP_Cipher(c->k2, dest, dest, len) == 0 ||
EVP_Cipher(c->k3, dest, dest, len) == 0)
return 0;
return 1;
}
......@@ -108,9 +115,9 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
struct ssh1_3des_ctx *c;
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
EVP_CIPHER_CTX_cleanup(&c->k1);
EVP_CIPHER_CTX_cleanup(&c->k2);
EVP_CIPHER_CTX_cleanup(&c->k3);
EVP_CIPHER_CTX_free(c->k1);
EVP_CIPHER_CTX_free(c->k2);
EVP_CIPHER_CTX_free(c->k3);
explicit_bzero(c, sizeof(*c));
free(c);
EVP_CIPHER_CTX_set_app_data(ctx, NULL);
......@@ -128,13 +135,13 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len)
if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
return SSH_ERR_INTERNAL_ERROR;
if (doset) {
memcpy(c->k1.iv, iv, 8);
memcpy(c->k2.iv, iv + 8, 8);
memcpy(c->k3.iv, iv + 16, 8);
memcpy(EVP_CIPHER_CTX_iv_noconst(c->k1), iv, 8);
memcpy(EVP_CIPHER_CTX_iv_noconst(c->k2), iv + 8, 8);
memcpy(EVP_CIPHER_CTX_iv_noconst(c->k3), iv + 16, 8);
} else {
memcpy(iv, c->k1.iv, 8);
memcpy(iv + 8, c->k2.iv, 8);
memcpy(iv + 16, c->k3.iv, 8);
memcpy(iv, EVP_CIPHER_CTX_iv(c->k1), 8);
memcpy(iv + 8, EVP_CIPHER_CTX_iv(c->k2), 8);
memcpy(iv + 16, EVP_CIPHER_CTX_iv(c->k3), 8);
}
return 0;
}
......@@ -142,17 +149,14 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len)
const EVP_CIPHER *
evp_ssh1_3des(void)
{
static EVP_CIPHER ssh1_3des;
memset(&ssh1_3des, 0, sizeof(ssh1_3des));
ssh1_3des.nid = NID_undef;
ssh1_3des.block_size = 8;
ssh1_3des.iv_len = 0;
ssh1_3des.key_len = 16;
ssh1_3des.init = ssh1_3des_init;
ssh1_3des.cleanup = ssh1_3des_cleanup;
ssh1_3des.do_cipher = ssh1_3des_cbc;
ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
return &ssh1_3des;
EVP_CIPHER *ssh1_3des;
ssh1_3des = EVP_CIPHER_meth_new(NID_undef, 8, 16);
EVP_CIPHER_meth_set_iv_length(ssh1_3des, 0);
EVP_CIPHER_meth_set_init(ssh1_3des, ssh1_3des_init);
EVP_CIPHER_meth_set_cleanup(ssh1_3des, ssh1_3des_cleanup);
EVP_CIPHER_meth_set_do_cipher(ssh1_3des, ssh1_3des_cbc);
EVP_CIPHER_meth_set_flags(ssh1_3des, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH);
return ssh1_3des;
}
#endif /* WITH_SSH1 */
......@@ -89,17 +89,28 @@ bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in,
const EVP_CIPHER *
evp_ssh1_bf(void)
{
static EVP_CIPHER ssh1_bf;
EVP_CIPHER *ssh1_bf;
memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
orig_bf = ssh1_bf.do_cipher;
ssh1_bf.nid = NID_undef;
orig_bf = EVP_CIPHER_meth_get_do_cipher(EVP_bf_cbc());
/* block_size, length, flags from openssl/crypto/engine/eng_cryptodev.c:638 */
ssh1_bf = EVP_CIPHER_meth_new(NID_undef, 8, 32);
EVP_CIPHER_meth_set_iv_length(ssh1_bf, 8);
EVP_CIPHER_meth_set_flags(ssh1_bf, EVP_CIPH_CBC_MODE);
#ifdef SSH_OLD_EVP
ssh1_bf.init = bf_ssh1_init;
EVP_CIPHER_meth_set_init(ssh1_bf, ssh1_bf_init);
#else
EVP_CIPHER_meth_set_init(ssh1_bf,
EVP_CIPHER_meth_get_init(EVP_bf_cbc()));
#endif
ssh1_bf.do_cipher = bf_ssh1_cipher;
ssh1_bf.key_len = 32;
return (&ssh1_bf);
/* copy methods and parameters from old EVP_BF_cbc()
* meth_dup does not allow to change type and key_len */
EVP_CIPHER_meth_set_cleanup(ssh1_bf,
EVP_CIPHER_meth_get_cleanup(EVP_bf_cbc()));
EVP_CIPHER_meth_set_ctrl(ssh1_bf,
EVP_CIPHER_meth_get_ctrl(EVP_bf_cbc()));
/* ASN1 params??? */
EVP_CIPHER_meth_set_do_cipher(ssh1_bf, bf_ssh1_cipher);
return ssh1_bf;
}
#endif /* defined(WITH_OPENSSL) && !defined(OPENSSL_NO_BF) */
......
......@@ -372,7 +372,7 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv,
if (EVP_CipherInit(cc->evp, type, (u_char *)key, (u_char *)iv,
(do_encrypt == CIPHER_ENCRYPT)) == 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
......@@ -390,10 +390,6 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
goto out;
}
}
if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if (cipher->discard_len > 0) {
if ((junk = malloc(cipher->discard_len)) == NULL ||
......@@ -625,7 +621,7 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
len, iv))
return SSH_ERR_LIBCRYPTO_ERROR;
} else
memcpy(iv, cc->evp->iv, len);
memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len);
break;
#endif
#ifdef WITH_SSH1
......@@ -671,7 +667,7 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
return SSH_ERR_LIBCRYPTO_ERROR;
} else
memcpy(cc->evp->iv, iv, evplen);
memcpy(EVP_CIPHER_CTX_iv_noconst(cc->evp), iv, evplen);
break;
#endif
#ifdef WITH_SSH1
......@@ -685,8 +681,8 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
}
#ifdef WITH_OPENSSL
#define EVP_X_STATE(evp) (evp)->cipher_data
#define EVP_X_STATE_LEN(evp) (evp)->cipher->ctx_size
#define EVP_X_STATE(evp) EVP_CIPHER_CTX_get_cipher_data(evp)
#define EVP_X_STATE_LEN(evp) EVP_CIPHER_impl_ctx_size(EVP_CIPHER_CTX_cipher(evp))
#endif
int
......
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -54,8 +54,8 @@ AC_SUBST([TEST_SHELL], [sh])
AC_SUBST(NXCOMPINC)
AC_SUBST(NXCOMPLIBS)
NXCOMPINC="-I$includedir/nx"
NXCOMPLIBS="-lXcomp"
NXCOMPINC="-I../nxcomp"
NXCOMPLIBS="-L../nxcomp -lXcomp -lstdc++ -lpng -ljpeg -lz"
dnl select manpage formatter
if test "x$MANDOC" != "x" ; then
......@@ -582,7 +582,7 @@ case "$host" in
*-*-cygwin*)
check_for_libcrypt_later=1
dont_check_for_resolv=1
LIBS="$LIBS /usr/lib/textmode.o /usr/lib/libminires.a"
LIBS="$LIBS /usr/lib/textmode.o"
AC_DEFINE([HAVE_CYGWIN], [1], [Define if you are on Cygwin])
AC_DEFINE([USE_PIPES], [1], [Use PIPES instead of a socketpair()])
AC_DEFINE([NO_UID_RESTORATION_TEST], [1],
......@@ -4182,11 +4182,28 @@ AC_ARG_WITH([selinux],
AC_SUBST([SSHLIBS])
AC_SUBST([SSHDLIBS])
# Check whether user wants SSPI support
SSPI_MSG="no"
AC_ARG_WITH([sspi],
[ --with-sspi Enable GSSAPI SSPI support],
[ if test "x$withval" != "xno" ; then
AC_DEFINE([SSPI], [1], [Define if you want SSPI support])
AC_DEFINE([GSSAPI], [1],
[Define this if you want GSSAPI support in the version 2 protocol])
AC_DEFINE([GSSAPI_SSPI], [1], [Define if you want GSSAPI SSPI support])
GSSLIBS="-lsecur32 -lws2_32"
SSPI_MSG="yes"
fi ]
)
# Check whether user wants Kerberos 5 support
KRB5_MSG="no"
AC_ARG_WITH([kerberos5],
[ --with-kerberos5=PATH Enable Kerberos 5 support],
[ if test "x$withval" != "xno" ; then
if test "x$SSPI_MSG" = "xyes" ; then
AC_MSG_ERROR([cannot use --with-sspi and --with-kerberos5 together, use one only])
fi
if test "x$withval" = "xyes" ; then
KRB5ROOT="/usr/local"
else
......@@ -5104,6 +5121,7 @@ echo " Manpage format: $MANTYPE"
echo " PAM support: $PAM_MSG"
echo " OSF SIA support: $SIA_MSG"
echo " KerberosV support: $KRB5_MSG"
echo " SSPI support: $SSPI_MSG"
echo " SELinux support: $SELINUX_MSG"
echo " Smartcard support: $SCARD_MSG"
echo " S/KEY support: $SKEY_MSG"
......
#pragma once
// #ifndef __attribute__
// #define __attribute__(A)
// #endif
#include "../../../log.h"
#include "../../../ssherr.h"
/* Enable the following for verbose logging */
#if (0)
#define debug4 debug2
#define debug5 debug3
#else
#define debug4(a,...)
#define debug5(a,...)
#endif
\ No newline at end of file
/*
* Author: Bryan Berns <berns@uwalumni.com>
*
* 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.
*/
#pragma once
/*
* This file provides the GSSAPI interface to support Kerberos SSPI within
* OpenSSH. This is only a partial definition of the full GSSAPI specification
* since OpenSSH only requires a subset of the overall functionality.
*
* The definitions are derived from information provided in RFC2744. In
* addition, RFC2743 provides additional information on the GSSAPI
* specification and intended operation.
*/
#include <windows.h>
#include <stdint.h>
#define SECURITY_WIN32
#include <security.h>
/*
* Common Structures & Type Definitions
*/
typedef uint32_t OM_uint32;
typedef char *gss_name_struct, *gss_name_t;
typedef struct cred_st *gss_cred_id_t;
typedef CtxtHandle *gss_ctx_id_t;
typedef OM_uint32 gss_qop_t;
typedef OM_uint32 gss_cred_usage_t;
typedef struct gss_buffer_desc_struct
{
size_t length;
void *value;
}
gss_buffer_desc, *gss_buffer_t;
typedef struct gss_OID_desc_struct
{
OM_uint32 length;
void *elements;
}
gss_OID_desc, *gss_OID;
typedef struct gss_OID_set_desc_struct
{
size_t count;
gss_OID elements;
}
gss_OID_set_desc, *gss_OID_set;
typedef struct gss_channel_bindings_struct
{
OM_uint32 initiator_addrtype;
gss_buffer_desc initiator_address;
OM_uint32 acceptor_addrtype;
gss_buffer_desc acceptor_address;
gss_buffer_desc application_data;
}
gss_channel_bindings_desc, *gss_channel_bindings_t;
/*
* Input & Return Flags
*/
/* Credential Usage Indication Options */
#define GSS_C_BOTH 0
#define GSS_C_INITIATE 1
#define GSS_C_ACCEPT 2
/* Context Flag Options */
#define GSS_C_DELEG_FLAG 1
#define GSS_C_MUTUAL_FLAG 2
#define GSS_C_REPLAY_FLAG 4
#define GSS_C_SEQUENCE_FLAG 8
#define GSS_C_CONF_FLAG 16
#define GSS_C_INTEG_FLAG 32
#define GSS_C_ANON_FLAG 64
#define GSS_C_PROT_READY_FLAG 128
#define GSS_C_TRANS_FLAG 256
#define GSS_C_DELEG_POLICY_FLAG 32768
/* Display Status Code Types */
#define GSS_C_GSS_CODE 1
#define GSS_C_MECH_CODE 2
/* Convenience Null Castless Comparison Options */
#define GSS_C_NO_NAME ((gss_name_t) 0)
#define GSS_C_NO_BUFFER ((gss_buffer_t) 0)
#define GSS_C_NO_OID ((gss_OID) 0)
#define GSS_C_NO_OID_SET ((gss_OID_set) 0)
#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0)
#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0)
#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0)
/* Convenience Initializer For Empty Buffer */
#define GSS_C_EMPTY_BUFFER {0, NULL}
/* Default Quality of Protection Code */
#define GSS_C_QOP_DEFAULT 0
/* Infinite Context / Credential Value */
#define GSS_C_INDEFINITE ((OM_uint32) 0xfffffffful)
/*
* Status & Return Code Processing
*/
#define GSS_S_COMPLETE 0
#define GSS_C_CALLING_ERROR_OFFSET 24
#define GSS_C_ROUTINE_ERROR_OFFSET 16
#define GSS_C_SUPPLEMENTARY_OFFSET 0
#define GSS_C_CALLING_ERROR_MASK ((OM_uint32) 0377ul)
#define GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul)
#define GSS_CALLING_ERROR(x) ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
#define GSS_ROUTINE_ERROR(x) ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
#define GSS_ERROR(x) ((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
#define GSS_S_BAD_MECH (((OM_uint32) 1ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_NAME (((OM_uint32) 2ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_NAMETYPE (((OM_uint32) 3ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_BINDINGS (((OM_uint32) 4ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_STATUS (((OM_uint32) 5ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_SIG (((OM_uint32) 6ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_NO_CRED (((OM_uint32) 7ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_NO_CONTEXT (((OM_uint32) 8ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_DEFECTIVE_TOKEN (((OM_uint32) 9ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_DEFECTIVE_CREDENTIAL (((OM_uint32) 10ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_CREDENTIALS_EXPIRED (((OM_uint32) 11ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_CONTEXT_EXPIRED (((OM_uint32) 12ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_FAILURE (((OM_uint32) 13ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_QOP (((OM_uint32) 14ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_UNAUTHORIZED (((OM_uint32) 15ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_UNAVAILABLE (((OM_uint32) 16ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_DUPLICATE_ELEMENT (((OM_uint32) 17ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_NAME_NOT_MN (((OM_uint32) 18ul) << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_CONTINUE_NEEDED (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
#define GSS_S_DUPLICATE_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
#define GSS_S_OLD_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
#define GSS_S_UNSEQ_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
#define GSS_S_GAP_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
/*
* Function Prototypes
*/
OM_uint32
gss_accept_sec_context(OM_uint32 * minor_status, gss_ctx_id_t * context_handle,
gss_cred_id_t acceptor_cred_handle, gss_buffer_t input_token_buffer,
gss_channel_bindings_t input_chan_bindings, gss_name_t * src_name,
gss_OID * mech_type, gss_buffer_t output_token, OM_uint32 * ret_flags,
OM_uint32 * time_rec, gss_cred_id_t * delegated_cred_handle);
OM_uint32
gss_acquire_cred(OM_uint32 *minor_status, gss_name_t desired_name,
OM_uint32 time_req, gss_OID_set desired_mechs, gss_cred_usage_t cred_usage,
gss_cred_id_t * output_cred_handle, gss_OID_set *actual_mechs,
OM_uint32 *time_rec);
OM_uint32
gss_add_oid_set_member(OM_uint32 * minor_status, gss_OID member_oid,
gss_OID_set * oid_set);
OM_uint32
gss_create_empty_oid_set(OM_uint32 * minor_status, gss_OID_set * oid_set);
OM_uint32
gss_init_sec_context(
OM_uint32 * minor_status, gss_cred_id_t claimant_cred_handle, gss_ctx_id_t * context_handle,
gss_name_t target_name, gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, gss_channel_bindings_t input_chan_bindings,
gss_buffer_t input_token, gss_OID * actual_mech_type, gss_buffer_t output_token, OM_uint32 * ret_flags,
OM_uint32 * time_rec);
OM_uint32
gss_delete_sec_context(OM_uint32 * minor_status, gss_ctx_id_t * context_handle,
gss_buffer_t output_token);
OM_uint32
gss_display_name(OM_uint32 * minor_status, gss_name_t input_name,
gss_buffer_t output_name_buffer, gss_OID * output_name_type);
OM_uint32
gss_display_status(OM_uint32 * minor_status, OM_uint32 status_value,
int status_type, gss_OID mech_type, OM_uint32 * message_context,
gss_buffer_t status_string);
OM_uint32
gss_export_name(OM_uint32 * minor_status, const gss_name_t input_name,
gss_buffer_t exported_name);
OM_uint32
gss_get_mic(OM_uint32 * minor_status, gss_ctx_id_t context_handle,
gss_qop_t qop_req, gss_buffer_t message_buffer,
gss_buffer_t message_token);
OM_uint32
gss_import_name(OM_uint32 * minor_status, gss_buffer_t input_name_buffer,
gss_OID input_name_type, gss_name_t * output_name);
OM_uint32
gss_indicate_mechs(OM_uint32 * minor_status, gss_OID_set * mech_set);
OM_uint32
gss_release_buffer(OM_uint32 * minor_status, gss_buffer_t buffer);
OM_uint32
gss_release_cred(OM_uint32 * minor_status, gss_cred_id_t * cred_handle);
OM_uint32
gss_release_name(OM_uint32 * minor_status, gss_name_t * input_name);
OM_uint32
gss_release_oid_set(OM_uint32 * minor_status, gss_OID_set * set);
OM_uint32
gss_test_oid_set_member(OM_uint32 * minor_status, gss_OID member,
gss_OID_set set, int * present);
OM_uint32
gss_verify_mic(OM_uint32 * minor_status, gss_ctx_id_t context_handle,
gss_buffer_t message_buffer, gss_buffer_t message_token,
gss_qop_t * qop_state);
extern gss_OID GSS_C_NT_HOSTBASED_SERVICE;
\ No newline at end of file
......@@ -212,14 +212,15 @@ choose_dh(int min, int wantbits, int max)
/* diffie-hellman-groupN-sha1 */
int
dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
{
int i;
int n = BN_num_bits(dh_pub);
int bits_set = 0;
BIGNUM *tmp;
const BIGNUM *p;
if (dh_pub->neg) {
if (BN_is_negative(dh_pub)) {
logit("invalid public DH value: negative");
return 0;
}
......@@ -232,7 +233,8 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
error("%s: BN_new failed", __func__);
return 0;
}
if (!BN_sub(tmp, dh->p, BN_value_one()) ||
DH_get0_pqg(dh, &p, NULL, NULL);
if (!BN_sub(tmp, p, BN_value_one()) ||
BN_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
BN_clear_free(tmp);
logit("invalid public DH value: >= p-1");
......@@ -243,14 +245,14 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
for (i = 0; i <= n; i++)
if (BN_is_bit_set(dh_pub, i))
bits_set++;
debug2("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
debug2("bits set: %d/%d", bits_set, BN_num_bits(p));
/*
* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
*/
if (bits_set < 4) {
logit("invalid public DH value (%d/%d)",
bits_set, BN_num_bits(dh->p));
bits_set, BN_num_bits(p));
return 0;
}
return 1;
......@@ -260,9 +262,11 @@ int
dh_gen_key(DH *dh, int need)
{
int pbits;
const BIGNUM *p, *pub_key;
if (need < 0 || dh->p == NULL ||
(pbits = BN_num_bits(dh->p)) <= 0 ||
DH_get0_pqg(dh, &p, NULL, NULL);
if (need < 0 || p == NULL ||
(pbits = BN_num_bits(p)) <= 0 ||
need > INT_MAX / 2 || 2 * need > pbits)
return SSH_ERR_INVALID_ARGUMENT;
if (need < 256)
......@@ -271,10 +275,11 @@ dh_gen_key(DH *dh, int need)
* Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
* so double requested need here.
*/
dh->length = MINIMUM(need * 2, pbits - 1);
if (DH_generate_key(dh) == 0 ||
!dh_pub_is_valid(dh, dh->pub_key)) {
BN_clear_free(dh->priv_key);
DH_set_length(dh, MINIMUM(need * 2, pbits - 1));
if (DH_generate_key(dh) == 0)
return SSH_ERR_LIBCRYPTO_ERROR;
DH_get0_key(dh, &pub_key, NULL);
if (!dh_pub_is_valid(dh, pub_key)) {
return SSH_ERR_LIBCRYPTO_ERROR;
}
return 0;
......@@ -284,15 +289,22 @@ DH *
dh_new_group_asc(const char *gen, const char *modulus)
{
DH *dh;
if ((dh = DH_new()) == NULL)
return NULL;
if (BN_hex2bn(&dh->p, modulus) == 0 ||
BN_hex2bn(&dh->g, gen) == 0) {
DH_free(dh);
return NULL;
}
BIGNUM *p, *g;
if ((dh = DH_new()) == NULL ||
(p = BN_new()) == NULL ||
(g = BN_new()) == NULL)
goto err;
if (BN_hex2bn(&p, modulus) == 0 ||
BN_hex2bn(&g, gen) == 0 ||
DH_set0_pqg(dh, p, NULL, g) == 0)
goto err;
return (dh);
err:
DH_free(dh);
BN_free(p);
BN_free(g);
return NULL;
}
/*
......@@ -307,8 +319,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulus)
if ((dh = DH_new()) == NULL)
return NULL;
dh->p = modulus;
dh->g = gen;
DH_set0_pqg(dh, modulus, NULL, gen);
return (dh);
}
......
......@@ -42,7 +42,7 @@ DH *dh_new_group18(void);
DH *dh_new_group_fallback(int);
int dh_gen_key(DH *, int);
int dh_pub_is_valid(DH *, BIGNUM *);
int dh_pub_is_valid(const DH *, const BIGNUM *);
u_int dh_estimate(int);
......
......@@ -43,7 +43,7 @@
struct ssh_digest_ctx {
int alg;
EVP_MD_CTX mdctx;
EVP_MD_CTX *mdctx;
};
struct ssh_digest {
......@@ -107,7 +107,7 @@ ssh_digest_bytes(int alg)
size_t
ssh_digest_blocksize(struct ssh_digest_ctx *ctx)
{
return EVP_MD_CTX_block_size(&ctx->mdctx);
return EVP_MD_CTX_block_size(ctx->mdctx);
}
struct ssh_digest_ctx *
......@@ -119,8 +119,9 @@ ssh_digest_start(int alg)
if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL))
return NULL;
ret->alg = alg;
EVP_MD_CTX_init(&ret->mdctx);
if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) {
ret->mdctx = EVP_MD_CTX_new();
if (ret->mdctx == NULL ||
EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) {
free(ret);
return NULL;
}
......@@ -133,7 +134,7 @@ ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
if (from->alg != to->alg)
return SSH_ERR_INVALID_ARGUMENT;
/* we have bcopy-style order while openssl has memcpy-style */
if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx))
if (!EVP_MD_CTX_copy_ex(to->mdctx, from->mdctx))
return SSH_ERR_LIBCRYPTO_ERROR;
return 0;
}
......@@ -141,7 +142,7 @@ ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
int
ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen)
{
if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1)
if (EVP_DigestUpdate(ctx->mdctx, m, mlen) != 1)
return SSH_ERR_LIBCRYPTO_ERROR;
return 0;
}
......@@ -162,7 +163,7 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
return SSH_ERR_INVALID_ARGUMENT;
if (dlen < digest->digest_len) /* No truncation allowed */
return SSH_ERR_INVALID_ARGUMENT;
if (EVP_DigestFinal_ex(&ctx->mdctx, d, &l) != 1)
if (EVP_DigestFinal_ex(ctx->mdctx, d, &l) != 1)
return SSH_ERR_LIBCRYPTO_ERROR;
if (l != digest->digest_len) /* sanity */
return SSH_ERR_INTERNAL_ERROR;
......@@ -173,7 +174,7 @@ void
ssh_digest_free(struct ssh_digest_ctx *ctx)
{
if (ctx != NULL) {
EVP_MD_CTX_cleanup(&ctx->mdctx);
EVP_MD_CTX_free(ctx->mdctx);
explicit_bzero(ctx, sizeof(*ctx));
free(ctx);
}
......
This diff is collapsed. Click to expand it.
......@@ -57,12 +57,12 @@ static ssh_gssapi_client gssapi_client =
ssh_gssapi_mech gssapi_null_mech =
{ NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL};
#ifdef KRB5
#if defined(KRB5) || defined (SSPI)
extern ssh_gssapi_mech gssapi_kerberos_mech;
#endif
ssh_gssapi_mech* supported_mechs[]= {
#ifdef KRB5
#if defined(KRB5) || defined (SSPI)
&gssapi_kerberos_mech,
#endif
&gssapi_null_mech,
......
......@@ -163,6 +163,7 @@
#ifdef WITH_OPENSSL
#include <openssl/opensslv.h> /* For OPENSSL_VERSION_NUMBER */
#include "libcrypto-compat.h"
#endif
#include "defines.h"
......
......@@ -56,6 +56,7 @@ kexdh_client(struct ssh *ssh)
{
struct kex *kex = ssh->kex;
int r;
const BIGNUM *pub_key;
/* generate and send 'e', client DH public key */
switch (kex->kex_type) {
......@@ -81,21 +82,27 @@ kexdh_client(struct ssh *ssh)
goto out;
}
debug("sending SSH2_MSG_KEXDH_INIT");
if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
(r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 ||
(r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||
if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
goto out;
DH_get0_key(kex->dh, &pub_key, NULL);
if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 ||
(r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
goto out;
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, kex->dh);
fprintf(stderr, "pub= ");
BN_print_fp(stderr, kex->dh->pub_key);
BN_print_fp(stderr, pub_key);
fprintf(stderr, "\n");
#endif
debug("expecting SSH2_MSG_KEXDH_REPLY");
ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_REPLY, &input_kex_dh);
r = 0;
out:
if (r != 0) {
DH_free(kex->dh);
kex->dh = NULL;
}
return r;
}
......@@ -110,6 +117,7 @@ input_kex_dh(int type, u_int32_t seq, void *ctxt)
u_char hash[SSH_DIGEST_MAX_LENGTH];
size_t klen = 0, slen, sbloblen, hashlen;
int kout, r;
const BIGNUM *pub_key;
if (kex->verify_host_key == NULL) {
r = SSH_ERR_INVALID_ARGUMENT;
......@@ -169,6 +177,7 @@ input_kex_dh(int type, u_int32_t seq, void *ctxt)
#endif
/* calc and verify H */
DH_get0_key(kex->dh, &pub_key, NULL);
hashlen = sizeof(hash);
if ((r = kex_dh_hash(
kex->hash_alg,
......@@ -177,7 +186,7 @@ input_kex_dh(int type, u_int32_t seq, void *ctxt)
sshbuf_ptr(kex->my), sshbuf_len(kex->my),
sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
server_host_key_blob, sbloblen,
kex->dh->pub_key,
pub_key,
dh_server_pub,
shared_secret,
hash, &hashlen)) != 0)
......
......@@ -87,6 +87,10 @@ kexdh_server(struct ssh *ssh)
ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init);
r = 0;
out:
if (r != 0) {
DH_free(kex->dh);
kex->dh = NULL;
}
return r;
}
......@@ -102,6 +106,7 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt)
size_t sbloblen, slen;
size_t klen = 0, hashlen;
int kout, r;
const BIGNUM *pub_key;
if (kex->load_host_public_key == NULL ||
kex->load_host_private_key == NULL) {
......@@ -164,6 +169,7 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt)
goto out;
/* calc H */
hashlen = sizeof(hash);
DH_get0_key(kex->dh, &pub_key, NULL);
if ((r = kex_dh_hash(
kex->hash_alg,
kex->client_version_string,
......@@ -172,7 +178,7 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt)
sshbuf_ptr(kex->my), sshbuf_len(kex->my),
server_host_key_blob, sbloblen,
dh_client_pub,
kex->dh->pub_key,
pub_key,
shared_secret,
hash, &hashlen)) != 0)
goto out;
......@@ -198,7 +204,7 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt)
/* send server hostkey, DH pubkey 'f' and singed H */
if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 ||
(r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
(r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */
(r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */
(r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
goto out;
......
......@@ -95,6 +95,7 @@ input_kex_dh_gex_group(int type, u_int32_t seq, void *ctxt)
struct kex *kex = ssh->kex;
BIGNUM *p = NULL, *g = NULL;
int r, bits;
const BIGNUM *pub_key;
debug("got SSH2_MSG_KEX_DH_GEX_GROUP");
......@@ -119,26 +120,30 @@ input_kex_dh_gex_group(int type, u_int32_t seq, void *ctxt)
p = g = NULL; /* belong to kex->dh now */
/* generate and send 'e', client DH public key */
if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 ||
(r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 ||
(r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 ||
if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
goto out;
DH_get0_key(kex->dh, &pub_key, NULL);
if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 ||
(r = sshpkt_put_bignum2(ssh, pub_key)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
goto out;
debug("SSH2_MSG_KEX_DH_GEX_INIT sent");
#ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, kex->dh);
fprintf(stderr, "pub= ");
BN_print_fp(stderr, kex->dh->pub_key);
BN_print_fp(stderr, pub_key);
fprintf(stderr, "\n");
#endif
ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, NULL);
ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &input_kex_dh_gex_reply);
r = 0;
out:
if (p)
BN_clear_free(p);
if (g)
BN_clear_free(g);
BN_clear_free(p);
BN_clear_free(g);
if (r != 0) {
DH_free(kex->dh);
kex->dh = NULL;
}
return r;
}
......@@ -153,6 +158,7 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt)
u_char hash[SSH_DIGEST_MAX_LENGTH];
size_t klen = 0, slen, sbloblen, hashlen;
int kout, r;
const BIGNUM *p, *g, *pub_key;
debug("got SSH2_MSG_KEX_DH_GEX_REPLY");
if (kex->verify_host_key == NULL) {
......@@ -219,6 +225,8 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt)
kex->min = kex->max = -1;
/* calc and verify H */
DH_get0_pqg(kex->dh, &p, NULL, &g);
DH_get0_key(kex->dh, &pub_key, NULL);
hashlen = sizeof(hash);
if ((r = kexgex_hash(
kex->hash_alg,
......@@ -228,8 +236,8 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt)
sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
server_host_key_blob, sbloblen,
kex->min, kex->nbits, kex->max,
kex->dh->p, kex->dh->g,
kex->dh->pub_key,
p, g,
pub_key,
dh_server_pub,
shared_secret,
hash, &hashlen)) != 0)
......
......@@ -73,6 +73,7 @@ input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt)
struct kex *kex = ssh->kex;
int r;
u_int min = 0, max = 0, nbits = 0;
const BIGNUM *p, *g;
debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
if ((r = sshpkt_get_u32(ssh, &min)) != 0 ||
......@@ -102,9 +103,10 @@ input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt)
goto out;
}
debug("SSH2_MSG_KEX_DH_GEX_GROUP sent");
DH_get0_pqg(kex->dh, &p, NULL, &g);
if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_GROUP)) != 0 ||
(r = sshpkt_put_bignum2(ssh, kex->dh->p)) != 0 ||
(r = sshpkt_put_bignum2(ssh, kex->dh->g)) != 0 ||
(r = sshpkt_put_bignum2(ssh, p)) != 0 ||
(r = sshpkt_put_bignum2(ssh, g)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
goto out;
......@@ -116,6 +118,10 @@ input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt)
ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init);
r = 0;
out:
if (r != 0) {
DH_free(kex->dh);
kex->dh = NULL;
}
return r;
}
......@@ -131,6 +137,7 @@ input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt)
size_t sbloblen, slen;
size_t klen = 0, hashlen;
int kout, r;
const BIGNUM *p, *g, *pub_key;
if (kex->load_host_public_key == NULL ||
kex->load_host_private_key == NULL) {
......@@ -193,6 +200,8 @@ input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt)
goto out;
/* calc H */
hashlen = sizeof(hash);
DH_get0_pqg(kex->dh, &p, NULL, &g);
DH_get0_key(kex->dh, &pub_key, NULL);
if ((r = kexgex_hash(
kex->hash_alg,
kex->client_version_string,
......@@ -201,9 +210,9 @@ input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt)
sshbuf_ptr(kex->my), sshbuf_len(kex->my),
server_host_key_blob, sbloblen,
kex->min, kex->nbits, kex->max,
kex->dh->p, kex->dh->g,
p, g,
dh_client_pub,
kex->dh->pub_key,
pub_key,
shared_secret,
hash, &hashlen)) != 0)
goto out;
......@@ -229,7 +238,7 @@ input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt)
/* send server hostkey, DH pubkey 'f' and singed H */
if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 ||
(r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 0 ||
(r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || /* f */
(r = sshpkt_put_bignum2(ssh, pub_key)) != 0 || /* f */
(r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
(r = sshpkt_send(ssh)) != 0)
goto out;
......
......@@ -581,9 +581,12 @@ mm_answer_moduli(int sock, Buffer *m)
return (0);
} else {
/* Send first bignum */
const BIGNUM *p, *g;
DH_get0_pqg(dh, &p, NULL, &g);
buffer_put_char(m, 1);
buffer_put_bignum2(m, dh->p);
buffer_put_bignum2(m, dh->g);
buffer_put_bignum2(m, p);
buffer_put_bignum2(m, g);
DH_free(dh);
}
......
......@@ -70,12 +70,19 @@ ssh_compatible_openssl(long headerver, long libver)
void
ssh_OpenSSL_add_all_algorithms(void)
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
OpenSSL_add_all_algorithms();
/* Enable use of crypto hardware */
ENGINE_load_builtin_engines();
#if OPENSSL_VERSION_NUMBER < 0x10001000L
ENGINE_register_all_complete();
#endif
OPENSSL_config(NULL);
#else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS |
OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL);
#endif
}
#endif
......
diff --git a/configure.ac b/configure.ac
index 7470dfc..1f0934b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,8 +54,8 @@ AC_SUBST([TEST_SHELL], [sh])
AC_SUBST(NXCOMPINC)
AC_SUBST(NXCOMPLIBS)
-NXCOMPINC="-I$includedir/nx"
-NXCOMPLIBS="-lXcomp"
+NXCOMPINC="-I../nxcomp"
+NXCOMPLIBS="-L../nxcomp -lXcomp -lstdc++ -lpng -ljpeg -lz"
dnl select manpage formatter
if test "x$MANDOC" != "x" ; then
@@ -582,7 +582,7 @@ case "$host" in
*-*-cygwin*)
check_for_libcrypt_later=1
dont_check_for_resolv=1
- LIBS="$LIBS /usr/lib/textmode.o /usr/lib/libminires.a"
+ LIBS="$LIBS /usr/lib/textmode.o"
AC_DEFINE([HAVE_CYGWIN], [1], [Define if you are on Cygwin])
AC_DEFINE([USE_PIPES], [1], [Use PIPES instead of a socketpair()])
AC_DEFINE([NO_UID_RESTORATION_TEST], [1],
......@@ -46,6 +46,7 @@ sshkey_file_tests(void)
struct sshbuf *buf, *pw;
BIGNUM *a, *b, *c;
char *cp;
const BIGNUM *n, *p, *q, *g, *pub_key, *priv_key;
TEST_START("load passphrase");
pw = load_text_file("pw");
......@@ -58,7 +59,8 @@ sshkey_file_tests(void)
sshbuf_free(buf);
ASSERT_PTR_NE(k1, NULL);
a = load_bignum("rsa1_1.param.n");
ASSERT_BIGNUM_EQ(k1->rsa->n, a);
RSA_get0_key(k1->rsa, &n, NULL, NULL);
ASSERT_BIGNUM_EQ(n, a);
BN_free(a);
TEST_DONE();
......@@ -109,9 +111,11 @@ sshkey_file_tests(void)
a = load_bignum("rsa_1.param.n");
b = load_bignum("rsa_1.param.p");
c = load_bignum("rsa_1.param.q");
ASSERT_BIGNUM_EQ(k1->rsa->n, a);
ASSERT_BIGNUM_EQ(k1->rsa->p, b);
ASSERT_BIGNUM_EQ(k1->rsa->q, c);
RSA_get0_key(k1->rsa, &n, NULL, NULL);
RSA_get0_factors(k1->rsa, &p, &q);
ASSERT_BIGNUM_EQ(n, a);
ASSERT_BIGNUM_EQ(p, b);
ASSERT_BIGNUM_EQ(q, c);
BN_free(a);
BN_free(b);
BN_free(c);
......@@ -200,9 +204,11 @@ sshkey_file_tests(void)
a = load_bignum("dsa_1.param.g");
b = load_bignum("dsa_1.param.priv");
c = load_bignum("dsa_1.param.pub");
ASSERT_BIGNUM_EQ(k1->dsa->g, a);
ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b);
ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c);
DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
DSA_get0_key(k1->dsa, &pub_key, &priv_key);
ASSERT_BIGNUM_EQ(g, a);
ASSERT_BIGNUM_EQ(priv_key, b);
ASSERT_BIGNUM_EQ(pub_key, c);
BN_free(a);
BN_free(b);
BN_free(c);
......
......@@ -197,9 +197,6 @@ sshkey_tests(void)
k1 = sshkey_new(KEY_RSA1);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->rsa, NULL);
ASSERT_PTR_NE(k1->rsa->n, NULL);
ASSERT_PTR_NE(k1->rsa->e, NULL);
ASSERT_PTR_EQ(k1->rsa->p, NULL);
sshkey_free(k1);
TEST_DONE();
......@@ -207,9 +204,6 @@ sshkey_tests(void)
k1 = sshkey_new(KEY_RSA);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->rsa, NULL);
ASSERT_PTR_NE(k1->rsa->n, NULL);
ASSERT_PTR_NE(k1->rsa->e, NULL);
ASSERT_PTR_EQ(k1->rsa->p, NULL);
sshkey_free(k1);
TEST_DONE();
......@@ -217,8 +211,6 @@ sshkey_tests(void)
k1 = sshkey_new(KEY_DSA);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->dsa, NULL);
ASSERT_PTR_NE(k1->dsa->g, NULL);
ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
sshkey_free(k1);
TEST_DONE();
......@@ -244,9 +236,6 @@ sshkey_tests(void)
k1 = sshkey_new_private(KEY_RSA);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->rsa, NULL);
ASSERT_PTR_NE(k1->rsa->n, NULL);
ASSERT_PTR_NE(k1->rsa->e, NULL);
ASSERT_PTR_NE(k1->rsa->p, NULL);
ASSERT_INT_EQ(sshkey_add_private(k1), 0);
sshkey_free(k1);
TEST_DONE();
......@@ -255,8 +244,6 @@ sshkey_tests(void)
k1 = sshkey_new_private(KEY_DSA);
ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->dsa, NULL);
ASSERT_PTR_NE(k1->dsa->g, NULL);
ASSERT_PTR_NE(k1->dsa->priv_key, NULL);
ASSERT_INT_EQ(sshkey_add_private(k1), 0);
sshkey_free(k1);
TEST_DONE();
......@@ -295,18 +282,13 @@ sshkey_tests(void)
ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0);
ASSERT_PTR_NE(kr, NULL);
ASSERT_PTR_NE(kr->rsa, NULL);
ASSERT_PTR_NE(kr->rsa->n, NULL);
ASSERT_PTR_NE(kr->rsa->e, NULL);
ASSERT_PTR_NE(kr->rsa->p, NULL);
ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 1024);
ASSERT_INT_EQ(RSA_bits(kr->rsa), 1024);
TEST_DONE();
TEST_START("generate KEY_DSA");
ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0);
ASSERT_PTR_NE(kd, NULL);
ASSERT_PTR_NE(kd->dsa, NULL);
ASSERT_PTR_NE(kd->dsa->g, NULL);
ASSERT_PTR_NE(kd->dsa->priv_key, NULL);
TEST_DONE();
#ifdef OPENSSL_HAS_ECC
......@@ -333,9 +315,6 @@ sshkey_tests(void)
ASSERT_PTR_NE(kr, k1);
ASSERT_INT_EQ(k1->type, KEY_RSA);
ASSERT_PTR_NE(k1->rsa, NULL);
ASSERT_PTR_NE(k1->rsa->n, NULL);
ASSERT_PTR_NE(k1->rsa->e, NULL);
ASSERT_PTR_EQ(k1->rsa->p, NULL);
TEST_DONE();
TEST_START("equal KEY_RSA/demoted KEY_RSA");
......@@ -349,8 +328,6 @@ sshkey_tests(void)
ASSERT_PTR_NE(kd, k1);
ASSERT_INT_EQ(k1->type, KEY_DSA);
ASSERT_PTR_NE(k1->dsa, NULL);
ASSERT_PTR_NE(k1->dsa->g, NULL);
ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
TEST_DONE();
TEST_START("equal KEY_DSA/demoted KEY_DSA");
......
......@@ -76,11 +76,14 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
{
u_char *inbuf = NULL, *outbuf = NULL;
int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR;
const BIGNUM *e, *n;
if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e))
RSA_get0_key(key, &n, &e, NULL);
if (BN_num_bits(e) < 2 || !BN_is_odd(e))
return SSH_ERR_INVALID_ARGUMENT;
olen = BN_num_bytes(key->n);
olen = BN_num_bytes(n);
if ((outbuf = malloc(olen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
......@@ -122,8 +125,11 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
{
u_char *inbuf = NULL, *outbuf = NULL;
int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR;
const BIGNUM *n;
RSA_get0_key(key, &n, NULL, NULL);
olen = BN_num_bytes(key->n);
olen = BN_num_bytes(n);
if ((outbuf = malloc(olen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
......@@ -157,31 +163,42 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
return r;
}
/* calculate p-1 and q-1 */
/* calculate d mod p-1 and d mod q-1 */
int
rsa_generate_additional_parameters(RSA *rsa)
rsa_generate_additional_parameters(RSA *rsa, BIGNUM *iqmp)
{
BIGNUM *aux = NULL;
BN_CTX *ctx = NULL;
int r;
const BIGNUM *p, *q, *d;
BIGNUM *dmp1 = NULL, *dmq1 = NULL;
RSA_get0_factors(rsa, &p, &q);
RSA_get0_key(rsa, NULL, NULL, &d);
if ((ctx = BN_CTX_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((aux = BN_new()) == NULL) {
if ((ctx = BN_CTX_new()) == NULL ||
(aux = BN_new()) == NULL ||
(dmp1 = BN_new()) == NULL ||
(dmq1 = BN_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) ||
(BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) ||
(BN_sub(aux, rsa->p, BN_value_one()) == 0) ||
(BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) {
if ((BN_sub(aux, q, BN_value_one()) == 0) ||
(BN_mod(dmq1, d, aux, ctx) == 0) ||
(BN_sub(aux, p, BN_value_one()) == 0) ||
(BN_mod(dmp1, d, aux, ctx) == 0) ||
(RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) == 0)) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
dmp1 = NULL;
dmq1 = NULL;
r = 0;
out:
BN_clear_free(aux);
BN_clear_free(dmp1);
BN_clear_free(dmq1);
BN_CTX_free(ctx);
return r;
}
......
......@@ -21,6 +21,6 @@
int rsa_public_encrypt(BIGNUM *, BIGNUM *, RSA *);
int rsa_private_decrypt(BIGNUM *, BIGNUM *, RSA *);
int rsa_generate_additional_parameters(RSA *);
int rsa_generate_additional_parameters(RSA *, BIGNUM *);
#endif /* RSA_H */
......@@ -258,12 +258,12 @@ process_request_identities(SocketEntry *e, int version)
TAILQ_FOREACH(id, &tab->idlist, next) {
if (id->key->type == KEY_RSA1) {
#ifdef WITH_SSH1
const BIGNUM *r_n, *r_e;
RSA_get0_key(id->key->rsa, &r_n, &r_e, NULL);
if ((r = sshbuf_put_u32(msg,
BN_num_bits(id->key->rsa->n))) != 0 ||
(r = sshbuf_put_bignum1(msg,
id->key->rsa->e)) != 0 ||
(r = sshbuf_put_bignum1(msg,
id->key->rsa->n)) != 0)
BN_num_bits(r_n))) != 0 ||
(r = sshbuf_put_bignum1(msg, r_e)) != 0 ||
(r = sshbuf_put_bignum1(msg, r_n)) != 0)
fatal("%s: buffer error: %s",
__func__, ssh_err(r));
#endif
......@@ -302,6 +302,7 @@ process_authentication_challenge1(SocketEntry *e)
struct sshbuf *msg;
struct ssh_digest_ctx *md;
struct sshkey *key;
BIGNUM *r_n = NULL, *r_e = NULL;
if ((msg = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
......@@ -310,11 +311,16 @@ process_authentication_challenge1(SocketEntry *e)
if ((challenge = BN_new()) == NULL)
fatal("%s: BN_new failed", __func__);
if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */
(r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
(r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 ||
(r = sshbuf_get_bignum1(e->request, challenge)))
if ((r_n = BN_new()) == NULL || (r_e = BN_new()) == NULL ||
(r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */
(r = sshbuf_get_bignum1(e->request, r_e)) != 0 ||
(r = sshbuf_get_bignum1(e->request, r_n)) != 0 ||
(r = sshbuf_get_bignum1(e->request, challenge)) ||
RSA_set0_key(key->rsa, r_n, r_e, NULL) == 0) {
BN_free(r_n);
BN_free(r_e);
fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
/* Only protocol 1.1 is supported */
if (sshbuf_len(e->request) == 0)
......@@ -450,6 +456,7 @@ process_remove_identity(SocketEntry *e, int version)
u_char *blob;
#ifdef WITH_SSH1
u_int bits;
BIGNUM *r_n = NULL, *r_e = NULL;
#endif /* WITH_SSH1 */
switch (version) {
......@@ -459,10 +466,15 @@ process_remove_identity(SocketEntry *e, int version)
error("%s: sshkey_new failed", __func__);
return;
}
if ((r = sshbuf_get_u32(e->request, &bits)) != 0 ||
(r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
(r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0)
if ((r_n = BN_new()) == NULL || (r_e = BN_new()) == NULL ||
(r = sshbuf_get_u32(e->request, &bits)) != 0 ||
(r = sshbuf_get_bignum1(e->request, r_e)) != 0 ||
(r = sshbuf_get_bignum1(e->request, r_n)) != 0 ||
RSA_set0_key(key->rsa, r_n, r_e, NULL) == 0) {
BN_free(r_n);
BN_free(r_e);
fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
if (bits != sshkey_size(key))
logit("Warning: identity keysize mismatch: "
......@@ -565,23 +577,46 @@ agent_decode_rsa1(struct sshbuf *m, struct sshkey **kp)
{
struct sshkey *k = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
BIGNUM *n = NULL, *e = NULL, *d = NULL,
*iqmp = NULL, *q = NULL, *p = NULL;
*kp = NULL;
if ((k = sshkey_new_private(KEY_RSA1)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */
(r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 ||
(r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 ||
(r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 ||
(r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 ||
if ((n = BN_new()) == NULL || (e = BN_new()) == NULL ||
(d = BN_new()) == NULL || (iqmp = BN_new()) == NULL ||
(q = BN_new()) == NULL || (p = BN_new()) == NULL ||
(r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */
(r = sshbuf_get_bignum1(m, n)) != 0 ||
(r = sshbuf_get_bignum1(m, e)) != 0 ||
(r = sshbuf_get_bignum1(m, d)) != 0 ||
(r = sshbuf_get_bignum1(m, iqmp)) != 0 ||
/* SSH1 and SSL have p and q swapped */
(r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 || /* p */
(r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */
(r = sshbuf_get_bignum1(m, q)) != 0 || /* p */
(r = sshbuf_get_bignum1(m, p)) != 0 || /* q */
RSA_set0_key(k->rsa, n, e, d) == 0) {
BN_free(n);
BN_free(e);
BN_free(d);
BN_free(p);
BN_free(q);
BN_free(iqmp);
goto out;
}
if (RSA_set0_factors(k->rsa, p, q) == 0) {
BN_free(p);
BN_free(q);
BN_free(iqmp);
goto out;
}
if (RSA_set0_crt_params(k->rsa, NULL, NULL, iqmp) == 0) {
BN_free(iqmp);
goto out;
}
/* Generate additional parameters */
if ((r = rsa_generate_additional_parameters(k->rsa)) != 0)
if ((r = rsa_generate_additional_parameters(k->rsa, NULL)) != 0)
goto out;
/* enable blinding */
if (RSA_blinding_on(k->rsa, NULL) != 1) {
......
......@@ -55,6 +55,7 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
struct sshbuf *b = NULL;
int ret = SSH_ERR_INVALID_ARGUMENT;
const BIGNUM *r, *s;
if (lenp != NULL)
*lenp = 0;
......@@ -76,15 +77,16 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
goto out;
}
rlen = BN_num_bytes(sig->r);
slen = BN_num_bytes(sig->s);
DSA_SIG_get0(sig, &r, &s);
rlen = BN_num_bytes(r);
slen = BN_num_bytes(s);
if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
ret = SSH_ERR_INTERNAL_ERROR;
goto out;
}
explicit_bzero(sigblob, SIGBLOB_LEN);
BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen);
BN_bn2bin(r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
BN_bn2bin(s, sigblob + SIGBLOB_LEN - slen);
if (compat & SSH_BUG_SIGBLOB) {
if (sigp != NULL) {
......@@ -137,6 +139,7 @@ ssh_dss_verify(const struct sshkey *key,
int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL;
char *ktype = NULL;
BIGNUM *r = NULL, *s = NULL;
if (key == NULL || key->dsa == NULL ||
sshkey_type_plain(key->type) != KEY_DSA ||
......@@ -177,16 +180,19 @@ ssh_dss_verify(const struct sshkey *key,
/* parse signature */
if ((sig = DSA_SIG_new()) == NULL ||
(sig->r = BN_new()) == NULL ||
(sig->s = BN_new()) == NULL) {
(r = BN_new()) == NULL ||
(s = BN_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) ||
(BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) {
if ((BN_bin2bn(sigblob, INTBLOB_LEN, r) == NULL) ||
(BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, s) == NULL) ||
(DSA_SIG_set0(sig, r, s) == 0)) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
r = NULL;
s = NULL;
/* sha1 the data */
if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
......@@ -207,8 +213,9 @@ ssh_dss_verify(const struct sshkey *key,
out:
explicit_bzero(digest, sizeof(digest));
if (sig != NULL)
DSA_SIG_free(sig);
BN_free(r);
BN_free(s);
DSA_SIG_free(sig);
sshbuf_free(b);
free(ktype);
if (sigblob != NULL) {
......
......@@ -54,6 +54,7 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
size_t len, dlen;
struct sshbuf *b = NULL, *bb = NULL;
int ret = SSH_ERR_INTERNAL_ERROR;
const BIGNUM *r, *s;
if (lenp != NULL)
*lenp = 0;
......@@ -80,8 +81,9 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 ||
(ret = sshbuf_put_bignum2(bb, sig->s)) != 0)
ECDSA_SIG_get0(sig, &r, &s);
if ((ret = sshbuf_put_bignum2(bb, r)) != 0 ||
(ret = sshbuf_put_bignum2(bb, s)) != 0)
goto out;
if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 ||
(ret = sshbuf_put_stringb(b, bb)) != 0)
......@@ -119,6 +121,7 @@ ssh_ecdsa_verify(const struct sshkey *key,
int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL, *sigbuf = NULL;
char *ktype = NULL;
BIGNUM *r = NULL, *s = NULL;
if (key == NULL || key->ecdsa == NULL ||
sshkey_type_plain(key->type) != KEY_ECDSA ||
......@@ -147,15 +150,23 @@ ssh_ecdsa_verify(const struct sshkey *key,
}
/* parse signature */
if ((sig = ECDSA_SIG_new()) == NULL) {
if ((sig = ECDSA_SIG_new()) == NULL ||
(r = BN_new()) == NULL ||
(s = BN_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 ||
sshbuf_get_bignum2(sigbuf, sig->s) != 0) {
if (sshbuf_get_bignum2(sigbuf, r) != 0 ||
sshbuf_get_bignum2(sigbuf, s) != 0) {
ret = SSH_ERR_INVALID_FORMAT;
goto out;
}
if (ECDSA_SIG_set0(sig, r, s) == 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
r = NULL;
s = NULL;
if (sshbuf_len(sigbuf) != 0) {
ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out;
......@@ -180,8 +191,9 @@ ssh_ecdsa_verify(const struct sshkey *key,
explicit_bzero(digest, sizeof(digest));
sshbuf_free(sigbuf);
sshbuf_free(b);
if (sig != NULL)
ECDSA_SIG_free(sig);
BN_free(r);
BN_free(s);
ECDSA_SIG_free(sig);
free(ktype);
return ret;
}
......
......@@ -28,6 +28,14 @@
#ifdef GSSAPI
#ifdef SSPI
#include "contrib/win32/win32compat/inc/gssapi.h"
#undef HAVE_GSSAPI_H
#undef HAVE_GSSAPI_GSSAPI_H
#undef HAVE_GSSAPI_GENERIC_H
#undef HAVE_GSSAPI_GSSAPI_GENERIC_H
#endif
#ifdef HAVE_GSSAPI_H
#include <gssapi.h>
#elif defined(HAVE_GSSAPI_GSSAPI_H)
......
......@@ -495,40 +495,67 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
free(type);
switch (key->type) {
case KEY_DSA:
buffer_get_bignum_bits(b, key->dsa->p);
buffer_get_bignum_bits(b, key->dsa->g);
buffer_get_bignum_bits(b, key->dsa->q);
buffer_get_bignum_bits(b, key->dsa->pub_key);
buffer_get_bignum_bits(b, key->dsa->priv_key);
case KEY_DSA: {
BIGNUM *p = NULL, *g = NULL, *q = NULL, *pub_key = NULL, *priv_key = NULL;
if ((p = BN_new()) == NULL ||
(g = BN_new()) == NULL ||
(q = BN_new()) == NULL ||
(pub_key = BN_new()) == NULL ||
(priv_key = BN_new()) == NULL)
fatal("BN_new() failed");
buffer_get_bignum_bits(b, p);
buffer_get_bignum_bits(b, g);
buffer_get_bignum_bits(b, q);
buffer_get_bignum_bits(b, pub_key);
buffer_get_bignum_bits(b, priv_key);
if (DSA_set0_pqg(key->dsa, p, q, g) == 0 ||
DSA_set0_key(key->dsa, pub_key, priv_key) == 0) {
fatal("failed to set DSA key");
}
}
break;
case KEY_RSA:
if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
(e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) ||
(e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0))
fatal("%s: buffer error: %s", __func__, ssh_err(r));
e = e1;
debug("e %lx", e);
if (e < 30) {
e <<= 8;
e += e2;
case KEY_RSA: {
BIGNUM *bn_e = NULL, *bn_d = NULL, *bn_n = NULL, *bn_iqmp = NULL, *bn_p = NULL, *bn_q = NULL;
if ((bn_e = BN_new()) == NULL ||
(bn_d = BN_new()) == NULL ||
(bn_n = BN_new()) == NULL ||
(bn_iqmp = BN_new()) == NULL ||
(bn_p = BN_new()) == NULL ||
(bn_q = BN_new()) == NULL)
fatal("BN_new() failed");
if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
(e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) ||
(e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0))
fatal("%s: buffer error: %s", __func__, ssh_err(r));
e = e1;
debug("e %lx", e);
e <<= 8;
e += e3;
debug("e %lx", e);
}
if (!BN_set_word(key->rsa->e, e)) {
sshbuf_free(b);
sshkey_free(key);
return NULL;
if (e < 30) {
e <<= 8;
e += e2;
debug("e %lx", e);
e <<= 8;
e += e3;
debug("e %lx", e);
}
if (!BN_set_word(bn_e, e)) {
sshbuf_free(b);
sshkey_free(key);
return NULL;
}
buffer_get_bignum_bits(b, bn_d);
buffer_get_bignum_bits(b, bn_n);
buffer_get_bignum_bits(b, bn_iqmp);
buffer_get_bignum_bits(b, bn_q);
buffer_get_bignum_bits(b, bn_p);
if (RSA_set0_key(key->rsa, bn_n, bn_e, bn_d) == 0 ||
RSA_set0_factors(key->rsa, bn_p, bn_q) == 0)
fatal("Failed to set RSA parameters");
if ((r = rsa_generate_additional_parameters(key->rsa, bn_iqmp)) != 0)
fatal("generate RSA parameters failed: %s", ssh_err(r));
}
buffer_get_bignum_bits(b, key->rsa->d);
buffer_get_bignum_bits(b, key->rsa->n);
buffer_get_bignum_bits(b, key->rsa->iqmp);
buffer_get_bignum_bits(b, key->rsa->q);
buffer_get_bignum_bits(b, key->rsa->p);
if ((r = rsa_generate_additional_parameters(key->rsa)) != 0)
fatal("generate RSA parameters failed: %s", ssh_err(r));
break;
}
rlen = sshbuf_len(b);
......@@ -636,7 +663,7 @@ do_convert_from_pkcs8(struct sshkey **k, int *private)
identity_file);
}
fclose(fp);
switch (EVP_PKEY_type(pubkey->type)) {
switch (EVP_PKEY_base_id(pubkey)) {
case EVP_PKEY_RSA:
if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new failed");
......@@ -660,7 +687,7 @@ do_convert_from_pkcs8(struct sshkey **k, int *private)
#endif
default:
fatal("%s: unsupported pubkey type %d", __func__,
EVP_PKEY_type(pubkey->type));
EVP_PKEY_base_id(pubkey));
}
EVP_PKEY_free(pubkey);
return;
......@@ -1702,6 +1729,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
#ifdef ENABLE_PKCS11
pkcs11_terminate();
#endif
free(ca);
exit(0);
}
......
......@@ -195,6 +195,7 @@ keygrab_ssh1(con *c)
static struct sshbuf *msg;
int r;
u_char type;
BIGNUM *n = NULL, *e = NULL;
if (rsa == NULL) {
if ((rsa = sshkey_new(KEY_RSA1)) == NULL) {
......@@ -213,16 +214,20 @@ keygrab_ssh1(con *c)
sshbuf_reset(msg);
return NULL;
}
if ((r = sshbuf_consume(msg, 8)) != 0 || /* cookie */
if ((n = BN_new()) == NULL || (e = BN_new()) == NULL ||
(r = sshbuf_consume(msg, 8)) != 0 || /* cookie */
/* server key */
(r = sshbuf_get_u32(msg, NULL)) != 0 ||
(r = sshbuf_get_bignum1(msg, NULL)) != 0 ||
(r = sshbuf_get_bignum1(msg, NULL)) != 0 ||
/* host key */
(r = sshbuf_get_u32(msg, NULL)) != 0 ||
(r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 ||
(r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) {
(r = sshbuf_get_bignum1(msg, e)) != 0 ||
(r = sshbuf_get_bignum1(msg, n)) != 0 ||
RSA_set0_key(rsa->rsa, n, e, NULL) == 0) {
buf_err:
BN_free(n);
BN_free(e);
error("%s: buffer error: %s", __func__, ssh_err(r));
sshbuf_reset(msg);
return NULL;
......
......@@ -143,12 +143,14 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
static int
wrap_key(RSA *rsa)
{
static RSA_METHOD helper_rsa;
static RSA_METHOD *helper_rsa;
memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa));
helper_rsa.name = "ssh-pkcs11-helper";
helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt;
RSA_set_method(rsa, &helper_rsa);
if (helper_rsa == NULL) {
helper_rsa = RSA_meth_dup(RSA_get_default_method());
RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper");
RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt);
}
RSA_set_method(rsa, helper_rsa);
return (0);
}
......
......@@ -67,7 +67,7 @@ struct pkcs11_key {
struct pkcs11_provider *provider;
CK_ULONG slotidx;
int (*orig_finish)(RSA *rsa);
RSA_METHOD rsa_method;
RSA_METHOD *rsa_method;
char *keyid;
int keyid_len;
};
......@@ -326,13 +326,21 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
k11->keyid = xmalloc(k11->keyid_len);
memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
}
k11->orig_finish = def->finish;
memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method));
k11->rsa_method.name = "pkcs11";
k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt;
k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt;
k11->rsa_method.finish = pkcs11_rsa_finish;
RSA_set_method(rsa, &k11->rsa_method);
k11->orig_finish = RSA_meth_get_finish(def);
if ((k11->rsa_method = RSA_meth_dup(def)) == NULL ||
RSA_meth_set1_name(k11->rsa_method, "pkcs11") == 0 ||
RSA_meth_set_priv_enc(k11->rsa_method, pkcs11_rsa_private_encrypt) == 0 ||
RSA_meth_set_priv_dec(k11->rsa_method, pkcs11_rsa_private_decrypt) == 0 ||
RSA_meth_set_finish(k11->rsa_method, pkcs11_rsa_finish) == 0) {
RSA_meth_free(k11->rsa_method);
k11->rsa_method = NULL;
pkcs11_provider_unref(k11->provider);
free(k11->keyid);
free(k11);
return (-1);
}
RSA_set_method(rsa, k11->rsa_method);
RSA_set_app_data(rsa, k11);
return (0);
}
......@@ -460,6 +468,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
CK_ULONG nfound;
CK_SESSION_HANDLE session;
CK_FUNCTION_LIST *f;
const BIGNUM *n, *e;
f = p->function_list;
session = p->slotinfo[slotidx].session;
......@@ -512,10 +521,14 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
if ((rsa = RSA_new()) == NULL) {
error("RSA_new failed");
} else {
rsa->n = BN_bin2bn(attribs[1].pValue,
BIGNUM *rsa_n, *rsa_e;
rsa_n = BN_bin2bn(attribs[1].pValue,
attribs[1].ulValueLen, NULL);
rsa->e = BN_bin2bn(attribs[2].pValue,
rsa_e = BN_bin2bn(attribs[2].pValue,
attribs[2].ulValueLen, NULL);
if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) == 0)
error("RSA_set0_key failed");
}
} else {
cp = attribs[2].pValue;
......@@ -525,17 +538,18 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
== NULL) {
error("d2i_X509 failed");
} else if ((evp = X509_get_pubkey(x509)) == NULL ||
evp->type != EVP_PKEY_RSA ||
evp->pkey.rsa == NULL) {
EVP_PKEY_id(evp) != EVP_PKEY_RSA ||
EVP_PKEY_get0_RSA(evp) == NULL) {
debug("X509_get_pubkey failed or no rsa");
} else if ((rsa = RSAPublicKey_dup(evp->pkey.rsa))
} else if ((rsa = RSAPublicKey_dup(EVP_PKEY_get0_RSA(evp)))
== NULL) {
error("RSAPublicKey_dup");
}
if (x509)
X509_free(x509);
}
if (rsa && rsa->n && rsa->e &&
RSA_get0_key(rsa, &n, &e, NULL);
if (rsa && n && e &&
pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
key = sshkey_new(KEY_UNSPEC);
key->rsa = rsa;
......
......@@ -100,7 +100,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
hash_alg = rsa_hash_alg_from_ident(alg_ident);
if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
sshkey_type_plain(key->type) != KEY_RSA ||
BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE)
RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE)
return SSH_ERR_INVALID_ARGUMENT;
slen = RSA_size(key->rsa);
if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
......@@ -172,7 +172,7 @@ ssh_rsa_verify(const struct sshkey *key,
if (key == NULL || key->rsa == NULL ||
sshkey_type_plain(key->type) != KEY_RSA ||
BN_num_bits(key->rsa->n) < SSH_RSA_MINIMUM_MODULUS_SIZE ||
RSA_bits(key->rsa) < SSH_RSA_MINIMUM_MODULUS_SIZE ||
sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT;
......
......@@ -1752,6 +1752,7 @@ ssh_login(Sensitive *sensitive, const char *orighost,
char *server_user, *local_user;
local_user = xstrdup(pw->pw_name);
free(pw);
server_user = options.user ? options.user : local_user;
/* Convert the user-supplied hostname into all lowercase. */
......
......@@ -70,6 +70,7 @@ try_agent_authentication(void)
u_char response[16];
size_t i;
BIGNUM *challenge;
const BIGNUM *n;
struct ssh_identitylist *idlist = NULL;
/* Get connection to the agent. */
......@@ -96,8 +97,9 @@ try_agent_authentication(void)
idlist->comments[i]);
/* Tell the server that we are willing to authenticate using this key. */
RSA_get0_key(idlist->keys[i]->rsa, &n, NULL, NULL);
packet_start(SSH_CMSG_AUTH_RSA);
packet_put_bignum(idlist->keys[i]->rsa->n);
packet_put_bignum((BIGNUM *)n);
packet_send();
packet_write_wait();
......@@ -220,6 +222,7 @@ static int
try_rsa_authentication(int idx)
{
BIGNUM *challenge;
const BIGNUM *n;
Key *public, *private;
char buf[300], *passphrase = NULL, *comment, *authfile;
int i, perm_ok = 1, type, quit;
......@@ -231,8 +234,9 @@ try_rsa_authentication(int idx)
debug("Trying RSA authentication with key '%.100s'", comment);
/* Tell the server that we are willing to authenticate using this key. */
RSA_get0_key(public->rsa, &n, NULL, NULL);
packet_start(SSH_CMSG_AUTH_RSA);
packet_put_bignum(public->rsa->n);
packet_put_bignum((BIGNUM *)n);
packet_send();
packet_write_wait();
......@@ -348,15 +352,17 @@ try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
{
int type;
BIGNUM *challenge;
const BIGNUM *n, *e;
debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
/* Tell the server that we are willing to authenticate using this key. */
RSA_get0_key(host_key->rsa, &n, &e, NULL);
packet_start(SSH_CMSG_AUTH_RHOSTS_RSA);
packet_put_cstring(local_user);
packet_put_int(BN_num_bits(host_key->rsa->n));
packet_put_bignum(host_key->rsa->e);
packet_put_bignum(host_key->rsa->n);
packet_put_int(BN_num_bits(n));
packet_put_bignum((BIGNUM *)e);
packet_put_bignum((BIGNUM *)n);
packet_send();
packet_write_wait();
......@@ -502,6 +508,8 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
{
int i;
BIGNUM *key;
BIGNUM *server_n = NULL, *server_e = NULL,
*host_n = NULL, *host_e = NULL;
Key *host_key, *server_key;
int bits, rbits;
int ssh_cipher_default = SSH_CIPHER_3DES;
......@@ -523,10 +531,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
if ((server_key = key_new(KEY_RSA1)) == NULL)
fatal("%s: key_new(KEY_RSA1) failed", __func__);
bits = packet_get_int();
packet_get_bignum(server_key->rsa->e);
packet_get_bignum(server_key->rsa->n);
rbits = BN_num_bits(server_key->rsa->n);
if ((server_e = BN_new()) == NULL ||
(server_n = BN_new()) == NULL)
fatal("BN_new() failed");
packet_get_bignum(server_e);
packet_get_bignum(server_n);
RSA_set0_key(server_key->rsa, server_n, server_e, NULL);
rbits = BN_num_bits(server_n);
if (bits != rbits) {
logit("Warning: Server lies about size of server public key: "
"actual size is %d bits vs. announced %d.", rbits, bits);
......@@ -536,10 +548,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
if ((host_key = key_new(KEY_RSA1)) == NULL)
fatal("%s: key_new(KEY_RSA1) failed", __func__);
bits = packet_get_int();
packet_get_bignum(host_key->rsa->e);
packet_get_bignum(host_key->rsa->n);
rbits = BN_num_bits(host_key->rsa->n);
if ((host_e = BN_new()) == NULL ||
(host_n = BN_new()) == NULL)
fatal("BN_new() failed");
packet_get_bignum(host_e);
packet_get_bignum(host_n);
RSA_set0_key(host_key->rsa, host_n, host_e, NULL);
rbits = BN_num_bits(host_n);
if (bits != rbits) {
logit("Warning: Server lies about size of server host key: "
"actual size is %d bits vs. announced %d.", rbits, bits);
......@@ -555,14 +571,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
packet_check_eom();
debug("Received server public key (%d bits) and host key (%d bits).",
BN_num_bits(server_key->rsa->n), BN_num_bits(host_key->rsa->n));
BN_num_bits(server_n), BN_num_bits(host_n));
if (verify_host_key(host, hostaddr, host_key) == -1)
fatal("Host key verification failed.");
client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN;
derive_ssh1_session_id(host_key->rsa->n, server_key->rsa->n, cookie, session_id);
derive_ssh1_session_id(host_n, server_n, cookie, session_id);
/*
* Generate an encryption key for the session. The key is a 256 bit
......@@ -597,14 +613,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
* Encrypt the integer using the public key and host key of the
* server (key with smaller modulus first).
*/
if (BN_cmp(server_key->rsa->n, host_key->rsa->n) < 0) {
if (BN_cmp(server_n, host_n) < 0) {
/* Public key has smaller modulus. */
if (BN_num_bits(host_key->rsa->n) <
BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
if (BN_num_bits(host_n) <
BN_num_bits(server_n) + SSH_KEY_BITS_RESERVED) {
fatal("respond_to_rsa_challenge: host_key %d < server_key %d + "
"SSH_KEY_BITS_RESERVED %d",
BN_num_bits(host_key->rsa->n),
BN_num_bits(server_key->rsa->n),
BN_num_bits(host_n),
BN_num_bits(server_n),
SSH_KEY_BITS_RESERVED);
}
if (rsa_public_encrypt(key, key, server_key->rsa) != 0 ||
......@@ -612,12 +628,12 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
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) <
BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
if (BN_num_bits(server_n) <
BN_num_bits(host_n) + SSH_KEY_BITS_RESERVED) {
fatal("respond_to_rsa_challenge: server_key %d < host_key %d + "
"SSH_KEY_BITS_RESERVED %d",
BN_num_bits(server_key->rsa->n),
BN_num_bits(host_key->rsa->n),
BN_num_bits(server_n),
BN_num_bits(host_n),
SSH_KEY_BITS_RESERVED);
}
if (rsa_public_encrypt(key, key, host_key->rsa) != 0 ||
......
......@@ -257,6 +257,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
packet_send();
packet_write_wait();
#endif
/* XXX free myproposal ?? */
}
/*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment