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} \ ...@@ -95,10 +95,11 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \
kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \ kexdhc.o kexgexc.o kexecdhc.o kexc25519c.o \
kexdhs.o kexgexs.o kexecdhs.o kexc25519s.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 \ 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 \ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \
audit.o audit-bsm.o audit-linux.o platform.o \ audit.o audit-bsm.o audit-linux.o platform.o \
...@@ -108,7 +109,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.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 \ auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \
auth2-none.o auth2-passwd.o auth2-pubkey.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o \
monitor.o monitor_wrap.o auth-krb5.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 \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
sftp-server.o sftp-common.o \ sftp-server.o sftp-common.o \
sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.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; ...@@ -129,6 +129,10 @@ extern u_int utmp_len;
typedef pthread_t sp_pthread_t; typedef pthread_t sp_pthread_t;
#else #else
typedef pid_t sp_pthread_t; 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 #endif
struct pam_ctxt { struct pam_ctxt {
......
...@@ -207,15 +207,22 @@ deserialise_identity1(struct sshbuf *ids, struct sshkey **keyp, char **commentp) ...@@ -207,15 +207,22 @@ deserialise_identity1(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
int r, keybits; int r, keybits;
u_int32_t bits; u_int32_t bits;
char *comment = NULL; char *comment = NULL;
BIGNUM *e = NULL, *n = NULL;
if ((key = sshkey_new(KEY_RSA1)) == NULL) if ((key = sshkey_new(KEY_RSA1)) == NULL)
return SSH_ERR_ALLOC_FAIL; return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_get_u32(ids, &bits)) != 0 || if ((e = BN_new()) == NULL ||
(r = sshbuf_get_bignum1(ids, key->rsa->e)) != 0 || (n = BN_new()) == NULL ||
(r = sshbuf_get_bignum1(ids, key->rsa->n)) != 0 || (r = sshbuf_get_u32(ids, &bits)) != 0 ||
(r = sshbuf_get_cstring(ids, &comment, NULL)) != 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; 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 */ /* XXX previously we just warned here. I think we should be strict */
if (keybits < 0 || bits != (u_int)keybits) { if (keybits < 0 || bits != (u_int)keybits) {
r = SSH_ERR_KEY_BITS_MISMATCH; r = SSH_ERR_KEY_BITS_MISMATCH;
...@@ -393,15 +400,17 @@ ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge, ...@@ -393,15 +400,17 @@ ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
struct sshbuf *msg; struct sshbuf *msg;
int r; int r;
u_char type; u_char type;
const BIGNUM *e, *n;
if (key->type != KEY_RSA1) if (key->type != KEY_RSA1)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
if ((msg = sshbuf_new()) == NULL) if ((msg = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL; return SSH_ERR_ALLOC_FAIL;
RSA_get0_key(key->rsa, &n, &e, NULL);
if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 || 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_u32(msg, BN_num_bits(n))) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 || (r = sshbuf_put_bignum1(msg, e)) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 || (r = sshbuf_put_bignum1(msg, n)) != 0 ||
(r = sshbuf_put_bignum1(msg, challenge)) != 0 || (r = sshbuf_put_bignum1(msg, challenge)) != 0 ||
(r = sshbuf_put(msg, session_id, 16)) != 0 || (r = sshbuf_put(msg, session_id, 16)) != 0 ||
(r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */ (r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */
...@@ -499,15 +508,19 @@ static int ...@@ -499,15 +508,19 @@ static int
ssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment) ssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment)
{ {
int r; 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 */ /* 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 || if ((r = sshbuf_put_u32(b, BN_num_bits(n))) != 0 ||
(r = sshbuf_put_bignum1(b, key->n)) != 0 || (r = sshbuf_put_bignum1(b, n)) != 0 ||
(r = sshbuf_put_bignum1(b, key->e)) != 0 || (r = sshbuf_put_bignum1(b, e)) != 0 ||
(r = sshbuf_put_bignum1(b, key->d)) != 0 || (r = sshbuf_put_bignum1(b, d)) != 0 ||
(r = sshbuf_put_bignum1(b, key->iqmp)) != 0 || (r = sshbuf_put_bignum1(b, iqmp)) != 0 ||
(r = sshbuf_put_bignum1(b, key->q)) != 0 || (r = sshbuf_put_bignum1(b, q)) != 0 ||
(r = sshbuf_put_bignum1(b, key->p)) != 0 || (r = sshbuf_put_bignum1(b, p)) != 0 ||
(r = sshbuf_put_cstring(b, comment)) != 0) (r = sshbuf_put_cstring(b, comment)) != 0)
return r; return r;
return 0; return 0;
...@@ -622,11 +635,13 @@ ssh_remove_identity(int sock, struct sshkey *key) ...@@ -622,11 +635,13 @@ ssh_remove_identity(int sock, struct sshkey *key)
#ifdef WITH_SSH1 #ifdef WITH_SSH1
if (key->type == KEY_RSA1) { if (key->type == KEY_RSA1) {
const BIGNUM *e, *n;
RSA_get0_key(key->rsa, &n, &e, NULL);
if ((r = sshbuf_put_u8(msg, if ((r = sshbuf_put_u8(msg,
SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 || SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 ||
(r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 || (r = sshbuf_put_u32(msg, BN_num_bits(n))) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 || (r = sshbuf_put_bignum1(msg, e)) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0) (r = sshbuf_put_bignum1(msg, n)) != 0)
goto out; goto out;
} else } else
#endif #endif
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
*/ */
struct ssh1_3des_ctx struct ssh1_3des_ctx
{ {
EVP_CIPHER_CTX k1, k2, k3; EVP_CIPHER_CTX *k1, *k2, *k3;
}; };
const EVP_CIPHER * evp_ssh1_3des(void); 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, ...@@ -65,7 +65,7 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
if (key == NULL) if (key == NULL)
return 1; return 1;
if (enc == -1) if (enc == -1)
enc = ctx->encrypt; enc = EVP_CIPHER_CTX_encrypting(ctx);
k1 = k2 = k3 = (u_char *) key; k1 = k2 = k3 = (u_char *) key;
k2 += 8; k2 += 8;
if (EVP_CIPHER_CTX_key_length(ctx) >= 16+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, ...@@ -74,12 +74,19 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
else else
k1 += 16; k1 += 16;
} }
EVP_CIPHER_CTX_init(&c->k1); c->k1 = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(&c->k2); c->k2 = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(&c->k3); c->k3 = EVP_CIPHER_CTX_new();
if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || if (c->k1 == NULL || c->k2 == NULL || c->k3 == NULL) {
EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || EVP_CIPHER_CTX_free(c->k1);
EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { 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)); explicit_bzero(c, sizeof(*c));
free(c); free(c);
EVP_CIPHER_CTX_set_app_data(ctx, NULL); 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) ...@@ -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) if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
return 0; return 0;
if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 || if (EVP_Cipher(c->k1, dest, (u_char *)src, len) == 0 ||
EVP_Cipher(&c->k2, dest, dest, len) == 0 || EVP_Cipher(c->k2, dest, dest, len) == 0 ||
EVP_Cipher(&c->k3, dest, dest, len) == 0) EVP_Cipher(c->k3, dest, dest, len) == 0)
return 0; return 0;
return 1; return 1;
} }
...@@ -108,9 +115,9 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) ...@@ -108,9 +115,9 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
struct ssh1_3des_ctx *c; struct ssh1_3des_ctx *c;
if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
EVP_CIPHER_CTX_cleanup(&c->k1); EVP_CIPHER_CTX_free(c->k1);
EVP_CIPHER_CTX_cleanup(&c->k2); EVP_CIPHER_CTX_free(c->k2);
EVP_CIPHER_CTX_cleanup(&c->k3); EVP_CIPHER_CTX_free(c->k3);
explicit_bzero(c, sizeof(*c)); explicit_bzero(c, sizeof(*c));
free(c); free(c);
EVP_CIPHER_CTX_set_app_data(ctx, NULL); 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) ...@@ -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) if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
return SSH_ERR_INTERNAL_ERROR; return SSH_ERR_INTERNAL_ERROR;
if (doset) { if (doset) {
memcpy(c->k1.iv, iv, 8); memcpy(EVP_CIPHER_CTX_iv_noconst(c->k1), iv, 8);
memcpy(c->k2.iv, iv + 8, 8); memcpy(EVP_CIPHER_CTX_iv_noconst(c->k2), iv + 8, 8);
memcpy(c->k3.iv, iv + 16, 8); memcpy(EVP_CIPHER_CTX_iv_noconst(c->k3), iv + 16, 8);
} else { } else {
memcpy(iv, c->k1.iv, 8); memcpy(iv, EVP_CIPHER_CTX_iv(c->k1), 8);
memcpy(iv + 8, c->k2.iv, 8); memcpy(iv + 8, EVP_CIPHER_CTX_iv(c->k2), 8);
memcpy(iv + 16, c->k3.iv, 8); memcpy(iv + 16, EVP_CIPHER_CTX_iv(c->k3), 8);
} }
return 0; return 0;
} }
...@@ -142,17 +149,14 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len) ...@@ -142,17 +149,14 @@ ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len)
const EVP_CIPHER * const EVP_CIPHER *
evp_ssh1_3des(void) evp_ssh1_3des(void)
{ {
static EVP_CIPHER ssh1_3des; EVP_CIPHER *ssh1_3des;
memset(&ssh1_3des, 0, sizeof(ssh1_3des)); ssh1_3des = EVP_CIPHER_meth_new(NID_undef, 8, 16);
ssh1_3des.nid = NID_undef; EVP_CIPHER_meth_set_iv_length(ssh1_3des, 0);
ssh1_3des.block_size = 8; EVP_CIPHER_meth_set_init(ssh1_3des, ssh1_3des_init);
ssh1_3des.iv_len = 0; EVP_CIPHER_meth_set_cleanup(ssh1_3des, ssh1_3des_cleanup);
ssh1_3des.key_len = 16; EVP_CIPHER_meth_set_do_cipher(ssh1_3des, ssh1_3des_cbc);
ssh1_3des.init = ssh1_3des_init; EVP_CIPHER_meth_set_flags(ssh1_3des, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH);
ssh1_3des.cleanup = ssh1_3des_cleanup; return ssh1_3des;
ssh1_3des.do_cipher = ssh1_3des_cbc;
ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
return &ssh1_3des;
} }
#endif /* WITH_SSH1 */ #endif /* WITH_SSH1 */
...@@ -89,17 +89,28 @@ bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, ...@@ -89,17 +89,28 @@ bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in,
const EVP_CIPHER * const EVP_CIPHER *
evp_ssh1_bf(void) evp_ssh1_bf(void)
{ {
static EVP_CIPHER ssh1_bf; EVP_CIPHER *ssh1_bf;
memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER)); orig_bf = EVP_CIPHER_meth_get_do_cipher(EVP_bf_cbc());
orig_bf = ssh1_bf.do_cipher; /* block_size, length, flags from openssl/crypto/engine/eng_cryptodev.c:638 */
ssh1_bf.nid = NID_undef; 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 #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 #endif
ssh1_bf.do_cipher = bf_ssh1_cipher; /* copy methods and parameters from old EVP_BF_cbc()
ssh1_bf.key_len = 32; * meth_dup does not allow to change type and key_len */
return (&ssh1_bf); 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) */ #endif /* defined(WITH_OPENSSL) && !defined(OPENSSL_NO_BF) */
......
...@@ -372,7 +372,7 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, ...@@ -372,7 +372,7 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
ret = SSH_ERR_ALLOC_FAIL; ret = SSH_ERR_ALLOC_FAIL;
goto out; 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) { (do_encrypt == CIPHER_ENCRYPT)) == 0) {
ret = SSH_ERR_LIBCRYPTO_ERROR; ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
...@@ -390,10 +390,6 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, ...@@ -390,10 +390,6 @@ cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher,
goto out; 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 (cipher->discard_len > 0) {
if ((junk = malloc(cipher->discard_len)) == NULL || if ((junk = malloc(cipher->discard_len)) == NULL ||
...@@ -625,7 +621,7 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len) ...@@ -625,7 +621,7 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
len, iv)) len, iv))
return SSH_ERR_LIBCRYPTO_ERROR; return SSH_ERR_LIBCRYPTO_ERROR;
} else } else
memcpy(iv, cc->evp->iv, len); memcpy(iv, EVP_CIPHER_CTX_iv(cc->evp), len);
break; break;
#endif #endif
#ifdef WITH_SSH1 #ifdef WITH_SSH1
...@@ -671,7 +667,7 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv) ...@@ -671,7 +667,7 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv))
return SSH_ERR_LIBCRYPTO_ERROR; return SSH_ERR_LIBCRYPTO_ERROR;
} else } else
memcpy(cc->evp->iv, iv, evplen); memcpy(EVP_CIPHER_CTX_iv_noconst(cc->evp), iv, evplen);
break; break;
#endif #endif
#ifdef WITH_SSH1 #ifdef WITH_SSH1
...@@ -685,8 +681,8 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv) ...@@ -685,8 +681,8 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
} }
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
#define EVP_X_STATE(evp) (evp)->cipher_data #define EVP_X_STATE(evp) EVP_CIPHER_CTX_get_cipher_data(evp)
#define EVP_X_STATE_LEN(evp) (evp)->cipher->ctx_size #define EVP_X_STATE_LEN(evp) EVP_CIPHER_impl_ctx_size(EVP_CIPHER_CTX_cipher(evp))
#endif #endif
int 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]) ...@@ -54,8 +54,8 @@ AC_SUBST([TEST_SHELL], [sh])
AC_SUBST(NXCOMPINC) AC_SUBST(NXCOMPINC)
AC_SUBST(NXCOMPLIBS) AC_SUBST(NXCOMPLIBS)
NXCOMPINC="-I$includedir/nx" NXCOMPINC="-I../nxcomp"
NXCOMPLIBS="-lXcomp" NXCOMPLIBS="-L../nxcomp -lXcomp -lstdc++ -lpng -ljpeg -lz"
dnl select manpage formatter dnl select manpage formatter
if test "x$MANDOC" != "x" ; then if test "x$MANDOC" != "x" ; then
...@@ -582,7 +582,7 @@ case "$host" in ...@@ -582,7 +582,7 @@ case "$host" in
*-*-cygwin*) *-*-cygwin*)
check_for_libcrypt_later=1 check_for_libcrypt_later=1
dont_check_for_resolv=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([HAVE_CYGWIN], [1], [Define if you are on Cygwin])
AC_DEFINE([USE_PIPES], [1], [Use PIPES instead of a socketpair()]) AC_DEFINE([USE_PIPES], [1], [Use PIPES instead of a socketpair()])
AC_DEFINE([NO_UID_RESTORATION_TEST], [1], AC_DEFINE([NO_UID_RESTORATION_TEST], [1],
...@@ -4182,11 +4182,28 @@ AC_ARG_WITH([selinux], ...@@ -4182,11 +4182,28 @@ AC_ARG_WITH([selinux],
AC_SUBST([SSHLIBS]) AC_SUBST([SSHLIBS])
AC_SUBST([SSHDLIBS]) 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 # Check whether user wants Kerberos 5 support
KRB5_MSG="no" KRB5_MSG="no"
AC_ARG_WITH([kerberos5], AC_ARG_WITH([kerberos5],
[ --with-kerberos5=PATH Enable Kerberos 5 support], [ --with-kerberos5=PATH Enable Kerberos 5 support],
[ if test "x$withval" != "xno" ; then [ 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 if test "x$withval" = "xyes" ; then
KRB5ROOT="/usr/local" KRB5ROOT="/usr/local"
else else
...@@ -5104,6 +5121,7 @@ echo " Manpage format: $MANTYPE" ...@@ -5104,6 +5121,7 @@ echo " Manpage format: $MANTYPE"
echo " PAM support: $PAM_MSG" echo " PAM support: $PAM_MSG"
echo " OSF SIA support: $SIA_MSG" echo " OSF SIA support: $SIA_MSG"
echo " KerberosV support: $KRB5_MSG" echo " KerberosV support: $KRB5_MSG"
echo " SSPI support: $SSPI_MSG"
echo " SELinux support: $SELINUX_MSG" echo " SELinux support: $SELINUX_MSG"
echo " Smartcard support: $SCARD_MSG" echo " Smartcard support: $SCARD_MSG"
echo " S/KEY support: $SKEY_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) ...@@ -212,14 +212,15 @@ choose_dh(int min, int wantbits, int max)
/* diffie-hellman-groupN-sha1 */ /* diffie-hellman-groupN-sha1 */
int int
dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
{ {
int i; int i;
int n = BN_num_bits(dh_pub); int n = BN_num_bits(dh_pub);
int bits_set = 0; int bits_set = 0;
BIGNUM *tmp; BIGNUM *tmp;
const BIGNUM *p;
if (dh_pub->neg) { if (BN_is_negative(dh_pub)) {
logit("invalid public DH value: negative"); logit("invalid public DH value: negative");
return 0; return 0;
} }
...@@ -232,7 +233,8 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) ...@@ -232,7 +233,8 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
error("%s: BN_new failed", __func__); error("%s: BN_new failed", __func__);
return 0; 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_cmp(dh_pub, tmp) != -1) { /* pub_exp > p-2 */
BN_clear_free(tmp); BN_clear_free(tmp);
logit("invalid public DH value: >= p-1"); logit("invalid public DH value: >= p-1");
...@@ -243,14 +245,14 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub) ...@@ -243,14 +245,14 @@ dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
for (i = 0; i <= n; i++) for (i = 0; i <= n; i++)
if (BN_is_bit_set(dh_pub, i)) if (BN_is_bit_set(dh_pub, i))
bits_set++; 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 g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
*/ */
if (bits_set < 4) { if (bits_set < 4) {
logit("invalid public DH value (%d/%d)", logit("invalid public DH value (%d/%d)",
bits_set, BN_num_bits(dh->p)); bits_set, BN_num_bits(p));
return 0; return 0;
} }
return 1; return 1;
...@@ -260,9 +262,11 @@ int ...@@ -260,9 +262,11 @@ int
dh_gen_key(DH *dh, int need) dh_gen_key(DH *dh, int need)
{ {
int pbits; int pbits;
const BIGNUM *p, *pub_key;
if (need < 0 || dh->p == NULL || DH_get0_pqg(dh, &p, NULL, NULL);
(pbits = BN_num_bits(dh->p)) <= 0 || if (need < 0 || p == NULL ||
(pbits = BN_num_bits(p)) <= 0 ||
need > INT_MAX / 2 || 2 * need > pbits) need > INT_MAX / 2 || 2 * need > pbits)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
if (need < 256) if (need < 256)
...@@ -271,10 +275,11 @@ dh_gen_key(DH *dh, int need) ...@@ -271,10 +275,11 @@ dh_gen_key(DH *dh, int need)
* Pollard Rho, Big step/Little Step attacks are O(sqrt(n)), * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
* so double requested need here. * so double requested need here.
*/ */
dh->length = MINIMUM(need * 2, pbits - 1); DH_set_length(dh, MINIMUM(need * 2, pbits - 1));
if (DH_generate_key(dh) == 0 || if (DH_generate_key(dh) == 0)
!dh_pub_is_valid(dh, dh->pub_key)) { return SSH_ERR_LIBCRYPTO_ERROR;
BN_clear_free(dh->priv_key); DH_get0_key(dh, &pub_key, NULL);
if (!dh_pub_is_valid(dh, pub_key)) {
return SSH_ERR_LIBCRYPTO_ERROR; return SSH_ERR_LIBCRYPTO_ERROR;
} }
return 0; return 0;
...@@ -284,15 +289,22 @@ DH * ...@@ -284,15 +289,22 @@ DH *
dh_new_group_asc(const char *gen, const char *modulus) dh_new_group_asc(const char *gen, const char *modulus)
{ {
DH *dh; DH *dh;
BIGNUM *p, *g;
if ((dh = DH_new()) == NULL)
return NULL; if ((dh = DH_new()) == NULL ||
if (BN_hex2bn(&dh->p, modulus) == 0 || (p = BN_new()) == NULL ||
BN_hex2bn(&dh->g, gen) == 0) { (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); DH_free(dh);
BN_free(p);
BN_free(g);
return NULL; return NULL;
}
return (dh);
} }
/* /*
...@@ -307,8 +319,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulus) ...@@ -307,8 +319,7 @@ dh_new_group(BIGNUM *gen, BIGNUM *modulus)
if ((dh = DH_new()) == NULL) if ((dh = DH_new()) == NULL)
return NULL; return NULL;
dh->p = modulus; DH_set0_pqg(dh, modulus, NULL, gen);
dh->g = gen;
return (dh); return (dh);
} }
......
...@@ -42,7 +42,7 @@ DH *dh_new_group18(void); ...@@ -42,7 +42,7 @@ DH *dh_new_group18(void);
DH *dh_new_group_fallback(int); DH *dh_new_group_fallback(int);
int dh_gen_key(DH *, 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); u_int dh_estimate(int);
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
struct ssh_digest_ctx { struct ssh_digest_ctx {
int alg; int alg;
EVP_MD_CTX mdctx; EVP_MD_CTX *mdctx;
}; };
struct ssh_digest { struct ssh_digest {
...@@ -107,7 +107,7 @@ ssh_digest_bytes(int alg) ...@@ -107,7 +107,7 @@ ssh_digest_bytes(int alg)
size_t size_t
ssh_digest_blocksize(struct ssh_digest_ctx *ctx) 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 * struct ssh_digest_ctx *
...@@ -119,8 +119,9 @@ ssh_digest_start(int alg) ...@@ -119,8 +119,9 @@ ssh_digest_start(int alg)
if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL)) if (digest == NULL || ((ret = calloc(1, sizeof(*ret))) == NULL))
return NULL; return NULL;
ret->alg = alg; ret->alg = alg;
EVP_MD_CTX_init(&ret->mdctx); ret->mdctx = EVP_MD_CTX_new();
if (EVP_DigestInit_ex(&ret->mdctx, digest->mdfunc(), NULL) != 1) { if (ret->mdctx == NULL ||
EVP_DigestInit_ex(ret->mdctx, digest->mdfunc(), NULL) != 1) {
free(ret); free(ret);
return NULL; return NULL;
} }
...@@ -133,7 +134,7 @@ ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to) ...@@ -133,7 +134,7 @@ ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
if (from->alg != to->alg) if (from->alg != to->alg)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
/* we have bcopy-style order while openssl has memcpy-style */ /* 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 SSH_ERR_LIBCRYPTO_ERROR;
return 0; return 0;
} }
...@@ -141,7 +142,7 @@ ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to) ...@@ -141,7 +142,7 @@ ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to)
int int
ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) 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 SSH_ERR_LIBCRYPTO_ERROR;
return 0; return 0;
} }
...@@ -162,7 +163,7 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) ...@@ -162,7 +163,7 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
if (dlen < digest->digest_len) /* No truncation allowed */ if (dlen < digest->digest_len) /* No truncation allowed */
return SSH_ERR_INVALID_ARGUMENT; 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; return SSH_ERR_LIBCRYPTO_ERROR;
if (l != digest->digest_len) /* sanity */ if (l != digest->digest_len) /* sanity */
return SSH_ERR_INTERNAL_ERROR; return SSH_ERR_INTERNAL_ERROR;
...@@ -173,7 +174,7 @@ void ...@@ -173,7 +174,7 @@ void
ssh_digest_free(struct ssh_digest_ctx *ctx) ssh_digest_free(struct ssh_digest_ctx *ctx)
{ {
if (ctx != NULL) { if (ctx != NULL) {
EVP_MD_CTX_cleanup(&ctx->mdctx); EVP_MD_CTX_free(ctx->mdctx);
explicit_bzero(ctx, sizeof(*ctx)); explicit_bzero(ctx, sizeof(*ctx));
free(ctx); free(ctx);
} }
......
This diff is collapsed. Click to expand it.
...@@ -57,12 +57,12 @@ static ssh_gssapi_client gssapi_client = ...@@ -57,12 +57,12 @@ static ssh_gssapi_client gssapi_client =
ssh_gssapi_mech gssapi_null_mech = ssh_gssapi_mech gssapi_null_mech =
{ NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL}; { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL};
#ifdef KRB5 #if defined(KRB5) || defined (SSPI)
extern ssh_gssapi_mech gssapi_kerberos_mech; extern ssh_gssapi_mech gssapi_kerberos_mech;
#endif #endif
ssh_gssapi_mech* supported_mechs[]= { ssh_gssapi_mech* supported_mechs[]= {
#ifdef KRB5 #if defined(KRB5) || defined (SSPI)
&gssapi_kerberos_mech, &gssapi_kerberos_mech,
#endif #endif
&gssapi_null_mech, &gssapi_null_mech,
......
...@@ -163,6 +163,7 @@ ...@@ -163,6 +163,7 @@
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
#include <openssl/opensslv.h> /* For OPENSSL_VERSION_NUMBER */ #include <openssl/opensslv.h> /* For OPENSSL_VERSION_NUMBER */
#include "libcrypto-compat.h"
#endif #endif
#include "defines.h" #include "defines.h"
......
...@@ -56,6 +56,7 @@ kexdh_client(struct ssh *ssh) ...@@ -56,6 +56,7 @@ kexdh_client(struct ssh *ssh)
{ {
struct kex *kex = ssh->kex; struct kex *kex = ssh->kex;
int r; int r;
const BIGNUM *pub_key;
/* generate and send 'e', client DH public key */ /* generate and send 'e', client DH public key */
switch (kex->kex_type) { switch (kex->kex_type) {
...@@ -81,21 +82,27 @@ kexdh_client(struct ssh *ssh) ...@@ -81,21 +82,27 @@ kexdh_client(struct ssh *ssh)
goto out; goto out;
} }
debug("sending SSH2_MSG_KEXDH_INIT"); debug("sending SSH2_MSG_KEXDH_INIT");
if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
(r = sshpkt_start(ssh, SSH2_MSG_KEXDH_INIT)) != 0 || goto out;
(r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || 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) (r = sshpkt_send(ssh)) != 0)
goto out; goto out;
#ifdef DEBUG_KEXDH #ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, kex->dh); DHparams_print_fp(stderr, kex->dh);
fprintf(stderr, "pub= "); fprintf(stderr, "pub= ");
BN_print_fp(stderr, kex->dh->pub_key); BN_print_fp(stderr, pub_key);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
#endif #endif
debug("expecting SSH2_MSG_KEXDH_REPLY"); debug("expecting SSH2_MSG_KEXDH_REPLY");
ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_REPLY, &input_kex_dh); ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_REPLY, &input_kex_dh);
r = 0; r = 0;
out: out:
if (r != 0) {
DH_free(kex->dh);
kex->dh = NULL;
}
return r; return r;
} }
...@@ -110,6 +117,7 @@ input_kex_dh(int type, u_int32_t seq, void *ctxt) ...@@ -110,6 +117,7 @@ input_kex_dh(int type, u_int32_t seq, void *ctxt)
u_char hash[SSH_DIGEST_MAX_LENGTH]; u_char hash[SSH_DIGEST_MAX_LENGTH];
size_t klen = 0, slen, sbloblen, hashlen; size_t klen = 0, slen, sbloblen, hashlen;
int kout, r; int kout, r;
const BIGNUM *pub_key;
if (kex->verify_host_key == NULL) { if (kex->verify_host_key == NULL) {
r = SSH_ERR_INVALID_ARGUMENT; r = SSH_ERR_INVALID_ARGUMENT;
...@@ -169,6 +177,7 @@ input_kex_dh(int type, u_int32_t seq, void *ctxt) ...@@ -169,6 +177,7 @@ input_kex_dh(int type, u_int32_t seq, void *ctxt)
#endif #endif
/* calc and verify H */ /* calc and verify H */
DH_get0_key(kex->dh, &pub_key, NULL);
hashlen = sizeof(hash); hashlen = sizeof(hash);
if ((r = kex_dh_hash( if ((r = kex_dh_hash(
kex->hash_alg, kex->hash_alg,
...@@ -177,7 +186,7 @@ input_kex_dh(int type, u_int32_t seq, void *ctxt) ...@@ -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->my), sshbuf_len(kex->my),
sshbuf_ptr(kex->peer), sshbuf_len(kex->peer), sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
server_host_key_blob, sbloblen, server_host_key_blob, sbloblen,
kex->dh->pub_key, pub_key,
dh_server_pub, dh_server_pub,
shared_secret, shared_secret,
hash, &hashlen)) != 0) hash, &hashlen)) != 0)
......
...@@ -87,6 +87,10 @@ kexdh_server(struct ssh *ssh) ...@@ -87,6 +87,10 @@ kexdh_server(struct ssh *ssh)
ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init); ssh_dispatch_set(ssh, SSH2_MSG_KEXDH_INIT, &input_kex_dh_init);
r = 0; r = 0;
out: out:
if (r != 0) {
DH_free(kex->dh);
kex->dh = NULL;
}
return r; return r;
} }
...@@ -102,6 +106,7 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt) ...@@ -102,6 +106,7 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt)
size_t sbloblen, slen; size_t sbloblen, slen;
size_t klen = 0, hashlen; size_t klen = 0, hashlen;
int kout, r; int kout, r;
const BIGNUM *pub_key;
if (kex->load_host_public_key == NULL || if (kex->load_host_public_key == NULL ||
kex->load_host_private_key == NULL) { kex->load_host_private_key == NULL) {
...@@ -164,6 +169,7 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt) ...@@ -164,6 +169,7 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt)
goto out; goto out;
/* calc H */ /* calc H */
hashlen = sizeof(hash); hashlen = sizeof(hash);
DH_get0_key(kex->dh, &pub_key, NULL);
if ((r = kex_dh_hash( if ((r = kex_dh_hash(
kex->hash_alg, kex->hash_alg,
kex->client_version_string, kex->client_version_string,
...@@ -172,7 +178,7 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt) ...@@ -172,7 +178,7 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt)
sshbuf_ptr(kex->my), sshbuf_len(kex->my), sshbuf_ptr(kex->my), sshbuf_len(kex->my),
server_host_key_blob, sbloblen, server_host_key_blob, sbloblen,
dh_client_pub, dh_client_pub,
kex->dh->pub_key, pub_key,
shared_secret, shared_secret,
hash, &hashlen)) != 0) hash, &hashlen)) != 0)
goto out; goto out;
...@@ -198,7 +204,7 @@ input_kex_dh_init(int type, u_int32_t seq, void *ctxt) ...@@ -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 */ /* send server hostkey, DH pubkey 'f' and singed H */
if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 || if ((r = sshpkt_start(ssh, SSH2_MSG_KEXDH_REPLY)) != 0 ||
(r = sshpkt_put_string(ssh, server_host_key_blob, sbloblen)) != 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_put_string(ssh, signature, slen)) != 0 ||
(r = sshpkt_send(ssh)) != 0) (r = sshpkt_send(ssh)) != 0)
goto out; goto out;
......
...@@ -95,6 +95,7 @@ input_kex_dh_gex_group(int type, u_int32_t seq, void *ctxt) ...@@ -95,6 +95,7 @@ input_kex_dh_gex_group(int type, u_int32_t seq, void *ctxt)
struct kex *kex = ssh->kex; struct kex *kex = ssh->kex;
BIGNUM *p = NULL, *g = NULL; BIGNUM *p = NULL, *g = NULL;
int r, bits; int r, bits;
const BIGNUM *pub_key;
debug("got SSH2_MSG_KEX_DH_GEX_GROUP"); 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) ...@@ -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 */ p = g = NULL; /* belong to kex->dh now */
/* generate and send 'e', client DH public key */ /* generate and send 'e', client DH public key */
if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0 || if ((r = dh_gen_key(kex->dh, kex->we_need * 8)) != 0)
(r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_INIT)) != 0 || goto out;
(r = sshpkt_put_bignum2(ssh, kex->dh->pub_key)) != 0 || 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) (r = sshpkt_send(ssh)) != 0)
goto out; goto out;
debug("SSH2_MSG_KEX_DH_GEX_INIT sent"); debug("SSH2_MSG_KEX_DH_GEX_INIT sent");
#ifdef DEBUG_KEXDH #ifdef DEBUG_KEXDH
DHparams_print_fp(stderr, kex->dh); DHparams_print_fp(stderr, kex->dh);
fprintf(stderr, "pub= "); fprintf(stderr, "pub= ");
BN_print_fp(stderr, kex->dh->pub_key); BN_print_fp(stderr, pub_key);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
#endif #endif
ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_GROUP, NULL); 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); ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_REPLY, &input_kex_dh_gex_reply);
r = 0; r = 0;
out: out:
if (p)
BN_clear_free(p); BN_clear_free(p);
if (g)
BN_clear_free(g); BN_clear_free(g);
if (r != 0) {
DH_free(kex->dh);
kex->dh = NULL;
}
return r; return r;
} }
...@@ -153,6 +158,7 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt) ...@@ -153,6 +158,7 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt)
u_char hash[SSH_DIGEST_MAX_LENGTH]; u_char hash[SSH_DIGEST_MAX_LENGTH];
size_t klen = 0, slen, sbloblen, hashlen; size_t klen = 0, slen, sbloblen, hashlen;
int kout, r; int kout, r;
const BIGNUM *p, *g, *pub_key;
debug("got SSH2_MSG_KEX_DH_GEX_REPLY"); debug("got SSH2_MSG_KEX_DH_GEX_REPLY");
if (kex->verify_host_key == NULL) { if (kex->verify_host_key == NULL) {
...@@ -219,6 +225,8 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt) ...@@ -219,6 +225,8 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt)
kex->min = kex->max = -1; kex->min = kex->max = -1;
/* calc and verify H */ /* calc and verify H */
DH_get0_pqg(kex->dh, &p, NULL, &g);
DH_get0_key(kex->dh, &pub_key, NULL);
hashlen = sizeof(hash); hashlen = sizeof(hash);
if ((r = kexgex_hash( if ((r = kexgex_hash(
kex->hash_alg, kex->hash_alg,
...@@ -228,8 +236,8 @@ input_kex_dh_gex_reply(int type, u_int32_t seq, void *ctxt) ...@@ -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), sshbuf_ptr(kex->peer), sshbuf_len(kex->peer),
server_host_key_blob, sbloblen, server_host_key_blob, sbloblen,
kex->min, kex->nbits, kex->max, kex->min, kex->nbits, kex->max,
kex->dh->p, kex->dh->g, p, g,
kex->dh->pub_key, pub_key,
dh_server_pub, dh_server_pub,
shared_secret, shared_secret,
hash, &hashlen)) != 0) hash, &hashlen)) != 0)
......
...@@ -73,6 +73,7 @@ input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt) ...@@ -73,6 +73,7 @@ input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt)
struct kex *kex = ssh->kex; struct kex *kex = ssh->kex;
int r; int r;
u_int min = 0, max = 0, nbits = 0; u_int min = 0, max = 0, nbits = 0;
const BIGNUM *p, *g;
debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); debug("SSH2_MSG_KEX_DH_GEX_REQUEST received");
if ((r = sshpkt_get_u32(ssh, &min)) != 0 || 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) ...@@ -102,9 +103,10 @@ input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt)
goto out; goto out;
} }
debug("SSH2_MSG_KEX_DH_GEX_GROUP sent"); 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 || 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, p)) != 0 ||
(r = sshpkt_put_bignum2(ssh, kex->dh->g)) != 0 || (r = sshpkt_put_bignum2(ssh, g)) != 0 ||
(r = sshpkt_send(ssh)) != 0) (r = sshpkt_send(ssh)) != 0)
goto out; goto out;
...@@ -116,6 +118,10 @@ input_kex_dh_gex_request(int type, u_int32_t seq, void *ctxt) ...@@ -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); ssh_dispatch_set(ssh, SSH2_MSG_KEX_DH_GEX_INIT, &input_kex_dh_gex_init);
r = 0; r = 0;
out: out:
if (r != 0) {
DH_free(kex->dh);
kex->dh = NULL;
}
return r; return r;
} }
...@@ -131,6 +137,7 @@ input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt) ...@@ -131,6 +137,7 @@ input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt)
size_t sbloblen, slen; size_t sbloblen, slen;
size_t klen = 0, hashlen; size_t klen = 0, hashlen;
int kout, r; int kout, r;
const BIGNUM *p, *g, *pub_key;
if (kex->load_host_public_key == NULL || if (kex->load_host_public_key == NULL ||
kex->load_host_private_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) ...@@ -193,6 +200,8 @@ input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt)
goto out; goto out;
/* calc H */ /* calc H */
hashlen = sizeof(hash); hashlen = sizeof(hash);
DH_get0_pqg(kex->dh, &p, NULL, &g);
DH_get0_key(kex->dh, &pub_key, NULL);
if ((r = kexgex_hash( if ((r = kexgex_hash(
kex->hash_alg, kex->hash_alg,
kex->client_version_string, kex->client_version_string,
...@@ -201,9 +210,9 @@ input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt) ...@@ -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), sshbuf_ptr(kex->my), sshbuf_len(kex->my),
server_host_key_blob, sbloblen, server_host_key_blob, sbloblen,
kex->min, kex->nbits, kex->max, kex->min, kex->nbits, kex->max,
kex->dh->p, kex->dh->g, p, g,
dh_client_pub, dh_client_pub,
kex->dh->pub_key, pub_key,
shared_secret, shared_secret,
hash, &hashlen)) != 0) hash, &hashlen)) != 0)
goto out; goto out;
...@@ -229,7 +238,7 @@ input_kex_dh_gex_init(int type, u_int32_t seq, void *ctxt) ...@@ -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 */ /* send server hostkey, DH pubkey 'f' and singed H */
if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_DH_GEX_REPLY)) != 0 || 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_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_put_string(ssh, signature, slen)) != 0 ||
(r = sshpkt_send(ssh)) != 0) (r = sshpkt_send(ssh)) != 0)
goto out; goto out;
......
...@@ -581,9 +581,12 @@ mm_answer_moduli(int sock, Buffer *m) ...@@ -581,9 +581,12 @@ mm_answer_moduli(int sock, Buffer *m)
return (0); return (0);
} else { } else {
/* Send first bignum */ /* Send first bignum */
const BIGNUM *p, *g;
DH_get0_pqg(dh, &p, NULL, &g);
buffer_put_char(m, 1); buffer_put_char(m, 1);
buffer_put_bignum2(m, dh->p); buffer_put_bignum2(m, p);
buffer_put_bignum2(m, dh->g); buffer_put_bignum2(m, g);
DH_free(dh); DH_free(dh);
} }
......
...@@ -70,12 +70,19 @@ ssh_compatible_openssl(long headerver, long libver) ...@@ -70,12 +70,19 @@ ssh_compatible_openssl(long headerver, long libver)
void void
ssh_OpenSSL_add_all_algorithms(void) ssh_OpenSSL_add_all_algorithms(void)
{ {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
OpenSSL_add_all_algorithms(); OpenSSL_add_all_algorithms();
/* Enable use of crypto hardware */ /* Enable use of crypto hardware */
ENGINE_load_builtin_engines(); ENGINE_load_builtin_engines();
#if OPENSSL_VERSION_NUMBER < 0x10001000L
ENGINE_register_all_complete(); ENGINE_register_all_complete();
#endif
OPENSSL_config(NULL); OPENSSL_config(NULL);
#else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS |
OPENSSL_INIT_ADD_ALL_DIGESTS | OPENSSL_INIT_LOAD_CONFIG, NULL);
#endif
} }
#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) ...@@ -46,6 +46,7 @@ sshkey_file_tests(void)
struct sshbuf *buf, *pw; struct sshbuf *buf, *pw;
BIGNUM *a, *b, *c; BIGNUM *a, *b, *c;
char *cp; char *cp;
const BIGNUM *n, *p, *q, *g, *pub_key, *priv_key;
TEST_START("load passphrase"); TEST_START("load passphrase");
pw = load_text_file("pw"); pw = load_text_file("pw");
...@@ -58,7 +59,8 @@ sshkey_file_tests(void) ...@@ -58,7 +59,8 @@ sshkey_file_tests(void)
sshbuf_free(buf); sshbuf_free(buf);
ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1, NULL);
a = load_bignum("rsa1_1.param.n"); 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); BN_free(a);
TEST_DONE(); TEST_DONE();
...@@ -109,9 +111,11 @@ sshkey_file_tests(void) ...@@ -109,9 +111,11 @@ sshkey_file_tests(void)
a = load_bignum("rsa_1.param.n"); a = load_bignum("rsa_1.param.n");
b = load_bignum("rsa_1.param.p"); b = load_bignum("rsa_1.param.p");
c = load_bignum("rsa_1.param.q"); c = load_bignum("rsa_1.param.q");
ASSERT_BIGNUM_EQ(k1->rsa->n, a); RSA_get0_key(k1->rsa, &n, NULL, NULL);
ASSERT_BIGNUM_EQ(k1->rsa->p, b); RSA_get0_factors(k1->rsa, &p, &q);
ASSERT_BIGNUM_EQ(k1->rsa->q, c); ASSERT_BIGNUM_EQ(n, a);
ASSERT_BIGNUM_EQ(p, b);
ASSERT_BIGNUM_EQ(q, c);
BN_free(a); BN_free(a);
BN_free(b); BN_free(b);
BN_free(c); BN_free(c);
...@@ -200,9 +204,11 @@ sshkey_file_tests(void) ...@@ -200,9 +204,11 @@ sshkey_file_tests(void)
a = load_bignum("dsa_1.param.g"); a = load_bignum("dsa_1.param.g");
b = load_bignum("dsa_1.param.priv"); b = load_bignum("dsa_1.param.priv");
c = load_bignum("dsa_1.param.pub"); c = load_bignum("dsa_1.param.pub");
ASSERT_BIGNUM_EQ(k1->dsa->g, a); DSA_get0_pqg(k1->dsa, NULL, NULL, &g);
ASSERT_BIGNUM_EQ(k1->dsa->priv_key, b); DSA_get0_key(k1->dsa, &pub_key, &priv_key);
ASSERT_BIGNUM_EQ(k1->dsa->pub_key, c); ASSERT_BIGNUM_EQ(g, a);
ASSERT_BIGNUM_EQ(priv_key, b);
ASSERT_BIGNUM_EQ(pub_key, c);
BN_free(a); BN_free(a);
BN_free(b); BN_free(b);
BN_free(c); BN_free(c);
......
...@@ -197,9 +197,6 @@ sshkey_tests(void) ...@@ -197,9 +197,6 @@ sshkey_tests(void)
k1 = sshkey_new(KEY_RSA1); k1 = sshkey_new(KEY_RSA1);
ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->rsa, 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); sshkey_free(k1);
TEST_DONE(); TEST_DONE();
...@@ -207,9 +204,6 @@ sshkey_tests(void) ...@@ -207,9 +204,6 @@ sshkey_tests(void)
k1 = sshkey_new(KEY_RSA); k1 = sshkey_new(KEY_RSA);
ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->rsa, 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); sshkey_free(k1);
TEST_DONE(); TEST_DONE();
...@@ -217,8 +211,6 @@ sshkey_tests(void) ...@@ -217,8 +211,6 @@ sshkey_tests(void)
k1 = sshkey_new(KEY_DSA); k1 = sshkey_new(KEY_DSA);
ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->dsa, 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); sshkey_free(k1);
TEST_DONE(); TEST_DONE();
...@@ -244,9 +236,6 @@ sshkey_tests(void) ...@@ -244,9 +236,6 @@ sshkey_tests(void)
k1 = sshkey_new_private(KEY_RSA); k1 = sshkey_new_private(KEY_RSA);
ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->rsa, 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); ASSERT_INT_EQ(sshkey_add_private(k1), 0);
sshkey_free(k1); sshkey_free(k1);
TEST_DONE(); TEST_DONE();
...@@ -255,8 +244,6 @@ sshkey_tests(void) ...@@ -255,8 +244,6 @@ sshkey_tests(void)
k1 = sshkey_new_private(KEY_DSA); k1 = sshkey_new_private(KEY_DSA);
ASSERT_PTR_NE(k1, NULL); ASSERT_PTR_NE(k1, NULL);
ASSERT_PTR_NE(k1->dsa, 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); ASSERT_INT_EQ(sshkey_add_private(k1), 0);
sshkey_free(k1); sshkey_free(k1);
TEST_DONE(); TEST_DONE();
...@@ -295,18 +282,13 @@ sshkey_tests(void) ...@@ -295,18 +282,13 @@ sshkey_tests(void)
ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0); ASSERT_INT_EQ(sshkey_generate(KEY_RSA, 1024, &kr), 0);
ASSERT_PTR_NE(kr, NULL); ASSERT_PTR_NE(kr, NULL);
ASSERT_PTR_NE(kr->rsa, NULL); ASSERT_PTR_NE(kr->rsa, NULL);
ASSERT_PTR_NE(kr->rsa->n, NULL); ASSERT_INT_EQ(RSA_bits(kr->rsa), 1024);
ASSERT_PTR_NE(kr->rsa->e, NULL);
ASSERT_PTR_NE(kr->rsa->p, NULL);
ASSERT_INT_EQ(BN_num_bits(kr->rsa->n), 1024);
TEST_DONE(); TEST_DONE();
TEST_START("generate KEY_DSA"); TEST_START("generate KEY_DSA");
ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0); ASSERT_INT_EQ(sshkey_generate(KEY_DSA, 1024, &kd), 0);
ASSERT_PTR_NE(kd, NULL); ASSERT_PTR_NE(kd, NULL);
ASSERT_PTR_NE(kd->dsa, NULL); ASSERT_PTR_NE(kd->dsa, NULL);
ASSERT_PTR_NE(kd->dsa->g, NULL);
ASSERT_PTR_NE(kd->dsa->priv_key, NULL);
TEST_DONE(); TEST_DONE();
#ifdef OPENSSL_HAS_ECC #ifdef OPENSSL_HAS_ECC
...@@ -333,9 +315,6 @@ sshkey_tests(void) ...@@ -333,9 +315,6 @@ sshkey_tests(void)
ASSERT_PTR_NE(kr, k1); ASSERT_PTR_NE(kr, k1);
ASSERT_INT_EQ(k1->type, KEY_RSA); ASSERT_INT_EQ(k1->type, KEY_RSA);
ASSERT_PTR_NE(k1->rsa, 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);
TEST_DONE(); TEST_DONE();
TEST_START("equal KEY_RSA/demoted KEY_RSA"); TEST_START("equal KEY_RSA/demoted KEY_RSA");
...@@ -349,8 +328,6 @@ sshkey_tests(void) ...@@ -349,8 +328,6 @@ sshkey_tests(void)
ASSERT_PTR_NE(kd, k1); ASSERT_PTR_NE(kd, k1);
ASSERT_INT_EQ(k1->type, KEY_DSA); ASSERT_INT_EQ(k1->type, KEY_DSA);
ASSERT_PTR_NE(k1->dsa, NULL); ASSERT_PTR_NE(k1->dsa, NULL);
ASSERT_PTR_NE(k1->dsa->g, NULL);
ASSERT_PTR_EQ(k1->dsa->priv_key, NULL);
TEST_DONE(); TEST_DONE();
TEST_START("equal KEY_DSA/demoted KEY_DSA"); TEST_START("equal KEY_DSA/demoted KEY_DSA");
......
...@@ -76,11 +76,14 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key) ...@@ -76,11 +76,14 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
{ {
u_char *inbuf = NULL, *outbuf = NULL; u_char *inbuf = NULL, *outbuf = NULL;
int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR; 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; return SSH_ERR_INVALID_ARGUMENT;
olen = BN_num_bytes(key->n); olen = BN_num_bytes(n);
if ((outbuf = malloc(olen)) == NULL) { if ((outbuf = malloc(olen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL; r = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
...@@ -122,8 +125,11 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) ...@@ -122,8 +125,11 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
{ {
u_char *inbuf = NULL, *outbuf = NULL; u_char *inbuf = NULL, *outbuf = NULL;
int len, ilen, olen, r = SSH_ERR_INTERNAL_ERROR; 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) { if ((outbuf = malloc(olen)) == NULL) {
r = SSH_ERR_ALLOC_FAIL; r = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
...@@ -157,31 +163,42 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key) ...@@ -157,31 +163,42 @@ rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
return r; return r;
} }
/* calculate p-1 and q-1 */ /* calculate d mod p-1 and d mod q-1 */
int int
rsa_generate_additional_parameters(RSA *rsa) rsa_generate_additional_parameters(RSA *rsa, BIGNUM *iqmp)
{ {
BIGNUM *aux = NULL; BIGNUM *aux = NULL;
BN_CTX *ctx = NULL; BN_CTX *ctx = NULL;
int r; 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) if ((ctx = BN_CTX_new()) == NULL ||
return SSH_ERR_ALLOC_FAIL; (aux = BN_new()) == NULL ||
if ((aux = BN_new()) == NULL) { (dmp1 = BN_new()) == NULL ||
(dmq1 = BN_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL; r = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
} }
if ((BN_sub(aux, rsa->q, BN_value_one()) == 0) || if ((BN_sub(aux, q, BN_value_one()) == 0) ||
(BN_mod(rsa->dmq1, rsa->d, aux, ctx) == 0) || (BN_mod(dmq1, d, aux, ctx) == 0) ||
(BN_sub(aux, rsa->p, BN_value_one()) == 0) || (BN_sub(aux, p, BN_value_one()) == 0) ||
(BN_mod(rsa->dmp1, rsa->d, aux, ctx) == 0)) { (BN_mod(dmp1, d, aux, ctx) == 0) ||
(RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp) == 0)) {
r = SSH_ERR_LIBCRYPTO_ERROR; r = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
dmp1 = NULL;
dmq1 = NULL;
r = 0; r = 0;
out: out:
BN_clear_free(aux); BN_clear_free(aux);
BN_clear_free(dmp1);
BN_clear_free(dmq1);
BN_CTX_free(ctx); BN_CTX_free(ctx);
return r; return r;
} }
......
...@@ -21,6 +21,6 @@ ...@@ -21,6 +21,6 @@
int rsa_public_encrypt(BIGNUM *, BIGNUM *, RSA *); int rsa_public_encrypt(BIGNUM *, BIGNUM *, RSA *);
int rsa_private_decrypt(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 */ #endif /* RSA_H */
...@@ -258,12 +258,12 @@ process_request_identities(SocketEntry *e, int version) ...@@ -258,12 +258,12 @@ process_request_identities(SocketEntry *e, int version)
TAILQ_FOREACH(id, &tab->idlist, next) { TAILQ_FOREACH(id, &tab->idlist, next) {
if (id->key->type == KEY_RSA1) { if (id->key->type == KEY_RSA1) {
#ifdef WITH_SSH1 #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, if ((r = sshbuf_put_u32(msg,
BN_num_bits(id->key->rsa->n))) != 0 || BN_num_bits(r_n))) != 0 ||
(r = sshbuf_put_bignum1(msg, (r = sshbuf_put_bignum1(msg, r_e)) != 0 ||
id->key->rsa->e)) != 0 || (r = sshbuf_put_bignum1(msg, r_n)) != 0)
(r = sshbuf_put_bignum1(msg,
id->key->rsa->n)) != 0)
fatal("%s: buffer error: %s", fatal("%s: buffer error: %s",
__func__, ssh_err(r)); __func__, ssh_err(r));
#endif #endif
...@@ -302,6 +302,7 @@ process_authentication_challenge1(SocketEntry *e) ...@@ -302,6 +302,7 @@ process_authentication_challenge1(SocketEntry *e)
struct sshbuf *msg; struct sshbuf *msg;
struct ssh_digest_ctx *md; struct ssh_digest_ctx *md;
struct sshkey *key; struct sshkey *key;
BIGNUM *r_n = NULL, *r_e = NULL;
if ((msg = sshbuf_new()) == NULL) if ((msg = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__); fatal("%s: sshbuf_new failed", __func__);
...@@ -310,11 +311,16 @@ process_authentication_challenge1(SocketEntry *e) ...@@ -310,11 +311,16 @@ process_authentication_challenge1(SocketEntry *e)
if ((challenge = BN_new()) == NULL) if ((challenge = BN_new()) == NULL)
fatal("%s: BN_new failed", __func__); fatal("%s: BN_new failed", __func__);
if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */ if ((r_n = BN_new()) == NULL || (r_e = BN_new()) == NULL ||
(r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || (r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */
(r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 || (r = sshbuf_get_bignum1(e->request, r_e)) != 0 ||
(r = sshbuf_get_bignum1(e->request, challenge))) (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)); fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
/* Only protocol 1.1 is supported */ /* Only protocol 1.1 is supported */
if (sshbuf_len(e->request) == 0) if (sshbuf_len(e->request) == 0)
...@@ -450,6 +456,7 @@ process_remove_identity(SocketEntry *e, int version) ...@@ -450,6 +456,7 @@ process_remove_identity(SocketEntry *e, int version)
u_char *blob; u_char *blob;
#ifdef WITH_SSH1 #ifdef WITH_SSH1
u_int bits; u_int bits;
BIGNUM *r_n = NULL, *r_e = NULL;
#endif /* WITH_SSH1 */ #endif /* WITH_SSH1 */
switch (version) { switch (version) {
...@@ -459,10 +466,15 @@ process_remove_identity(SocketEntry *e, int version) ...@@ -459,10 +466,15 @@ process_remove_identity(SocketEntry *e, int version)
error("%s: sshkey_new failed", __func__); error("%s: sshkey_new failed", __func__);
return; return;
} }
if ((r = sshbuf_get_u32(e->request, &bits)) != 0 || if ((r_n = BN_new()) == NULL || (r_e = BN_new()) == NULL ||
(r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 || (r = sshbuf_get_u32(e->request, &bits)) != 0 ||
(r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 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)); fatal("%s: buffer error: %s", __func__, ssh_err(r));
}
if (bits != sshkey_size(key)) if (bits != sshkey_size(key))
logit("Warning: identity keysize mismatch: " logit("Warning: identity keysize mismatch: "
...@@ -565,23 +577,46 @@ agent_decode_rsa1(struct sshbuf *m, struct sshkey **kp) ...@@ -565,23 +577,46 @@ agent_decode_rsa1(struct sshbuf *m, struct sshkey **kp)
{ {
struct sshkey *k = NULL; struct sshkey *k = NULL;
int r = SSH_ERR_INTERNAL_ERROR; int r = SSH_ERR_INTERNAL_ERROR;
BIGNUM *n = NULL, *e = NULL, *d = NULL,
*iqmp = NULL, *q = NULL, *p = NULL;
*kp = NULL; *kp = NULL;
if ((k = sshkey_new_private(KEY_RSA1)) == NULL) if ((k = sshkey_new_private(KEY_RSA1)) == NULL)
return SSH_ERR_ALLOC_FAIL; return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */ if ((n = BN_new()) == NULL || (e = BN_new()) == NULL ||
(r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 || (d = BN_new()) == NULL || (iqmp = BN_new()) == NULL ||
(r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 || (q = BN_new()) == NULL || (p = BN_new()) == NULL ||
(r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 || (r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */
(r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 || (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 */ /* SSH1 and SSL have p and q swapped */
(r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 || /* p */ (r = sshbuf_get_bignum1(m, q)) != 0 || /* p */
(r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */ (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; goto out;
}
if (RSA_set0_crt_params(k->rsa, NULL, NULL, iqmp) == 0) {
BN_free(iqmp);
goto out;
}
/* Generate additional parameters */ /* Generate additional parameters */
if ((r = rsa_generate_additional_parameters(k->rsa)) != 0) if ((r = rsa_generate_additional_parameters(k->rsa, NULL)) != 0)
goto out; goto out;
/* enable blinding */ /* enable blinding */
if (RSA_blinding_on(k->rsa, NULL) != 1) { 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, ...@@ -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); size_t rlen, slen, len, dlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
struct sshbuf *b = NULL; struct sshbuf *b = NULL;
int ret = SSH_ERR_INVALID_ARGUMENT; int ret = SSH_ERR_INVALID_ARGUMENT;
const BIGNUM *r, *s;
if (lenp != NULL) if (lenp != NULL)
*lenp = 0; *lenp = 0;
...@@ -76,15 +77,16 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, ...@@ -76,15 +77,16 @@ ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
goto out; goto out;
} }
rlen = BN_num_bytes(sig->r); DSA_SIG_get0(sig, &r, &s);
slen = BN_num_bytes(sig->s); rlen = BN_num_bytes(r);
slen = BN_num_bytes(s);
if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) { if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
ret = SSH_ERR_INTERNAL_ERROR; ret = SSH_ERR_INTERNAL_ERROR;
goto out; goto out;
} }
explicit_bzero(sigblob, SIGBLOB_LEN); explicit_bzero(sigblob, SIGBLOB_LEN);
BN_bn2bin(sig->r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen); BN_bn2bin(r, sigblob + SIGBLOB_LEN - INTBLOB_LEN - rlen);
BN_bn2bin(sig->s, sigblob + SIGBLOB_LEN - slen); BN_bn2bin(s, sigblob + SIGBLOB_LEN - slen);
if (compat & SSH_BUG_SIGBLOB) { if (compat & SSH_BUG_SIGBLOB) {
if (sigp != NULL) { if (sigp != NULL) {
...@@ -137,6 +139,7 @@ ssh_dss_verify(const struct sshkey *key, ...@@ -137,6 +139,7 @@ ssh_dss_verify(const struct sshkey *key,
int ret = SSH_ERR_INTERNAL_ERROR; int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL; struct sshbuf *b = NULL;
char *ktype = NULL; char *ktype = NULL;
BIGNUM *r = NULL, *s = NULL;
if (key == NULL || key->dsa == NULL || if (key == NULL || key->dsa == NULL ||
sshkey_type_plain(key->type) != KEY_DSA || sshkey_type_plain(key->type) != KEY_DSA ||
...@@ -177,16 +180,19 @@ ssh_dss_verify(const struct sshkey *key, ...@@ -177,16 +180,19 @@ ssh_dss_verify(const struct sshkey *key,
/* parse signature */ /* parse signature */
if ((sig = DSA_SIG_new()) == NULL || if ((sig = DSA_SIG_new()) == NULL ||
(sig->r = BN_new()) == NULL || (r = BN_new()) == NULL ||
(sig->s = BN_new()) == NULL) { (s = BN_new()) == NULL) {
ret = SSH_ERR_ALLOC_FAIL; ret = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
} }
if ((BN_bin2bn(sigblob, INTBLOB_LEN, sig->r) == NULL) || if ((BN_bin2bn(sigblob, INTBLOB_LEN, r) == NULL) ||
(BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s) == NULL)) { (BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, s) == NULL) ||
(DSA_SIG_set0(sig, r, s) == 0)) {
ret = SSH_ERR_LIBCRYPTO_ERROR; ret = SSH_ERR_LIBCRYPTO_ERROR;
goto out; goto out;
} }
r = NULL;
s = NULL;
/* sha1 the data */ /* sha1 the data */
if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen, if ((ret = ssh_digest_memory(SSH_DIGEST_SHA1, data, datalen,
...@@ -207,7 +213,8 @@ ssh_dss_verify(const struct sshkey *key, ...@@ -207,7 +213,8 @@ ssh_dss_verify(const struct sshkey *key,
out: out:
explicit_bzero(digest, sizeof(digest)); explicit_bzero(digest, sizeof(digest));
if (sig != NULL) BN_free(r);
BN_free(s);
DSA_SIG_free(sig); DSA_SIG_free(sig);
sshbuf_free(b); sshbuf_free(b);
free(ktype); free(ktype);
......
...@@ -54,6 +54,7 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, ...@@ -54,6 +54,7 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
size_t len, dlen; size_t len, dlen;
struct sshbuf *b = NULL, *bb = NULL; struct sshbuf *b = NULL, *bb = NULL;
int ret = SSH_ERR_INTERNAL_ERROR; int ret = SSH_ERR_INTERNAL_ERROR;
const BIGNUM *r, *s;
if (lenp != NULL) if (lenp != NULL)
*lenp = 0; *lenp = 0;
...@@ -80,8 +81,9 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, ...@@ -80,8 +81,9 @@ ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
ret = SSH_ERR_ALLOC_FAIL; ret = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
} }
if ((ret = sshbuf_put_bignum2(bb, sig->r)) != 0 || ECDSA_SIG_get0(sig, &r, &s);
(ret = sshbuf_put_bignum2(bb, sig->s)) != 0) if ((ret = sshbuf_put_bignum2(bb, r)) != 0 ||
(ret = sshbuf_put_bignum2(bb, s)) != 0)
goto out; goto out;
if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 || if ((ret = sshbuf_put_cstring(b, sshkey_ssh_name_plain(key))) != 0 ||
(ret = sshbuf_put_stringb(b, bb)) != 0) (ret = sshbuf_put_stringb(b, bb)) != 0)
...@@ -119,6 +121,7 @@ ssh_ecdsa_verify(const struct sshkey *key, ...@@ -119,6 +121,7 @@ ssh_ecdsa_verify(const struct sshkey *key,
int ret = SSH_ERR_INTERNAL_ERROR; int ret = SSH_ERR_INTERNAL_ERROR;
struct sshbuf *b = NULL, *sigbuf = NULL; struct sshbuf *b = NULL, *sigbuf = NULL;
char *ktype = NULL; char *ktype = NULL;
BIGNUM *r = NULL, *s = NULL;
if (key == NULL || key->ecdsa == NULL || if (key == NULL || key->ecdsa == NULL ||
sshkey_type_plain(key->type) != KEY_ECDSA || sshkey_type_plain(key->type) != KEY_ECDSA ||
...@@ -147,15 +150,23 @@ ssh_ecdsa_verify(const struct sshkey *key, ...@@ -147,15 +150,23 @@ ssh_ecdsa_verify(const struct sshkey *key,
} }
/* parse signature */ /* 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; ret = SSH_ERR_ALLOC_FAIL;
goto out; goto out;
} }
if (sshbuf_get_bignum2(sigbuf, sig->r) != 0 || if (sshbuf_get_bignum2(sigbuf, r) != 0 ||
sshbuf_get_bignum2(sigbuf, sig->s) != 0) { sshbuf_get_bignum2(sigbuf, s) != 0) {
ret = SSH_ERR_INVALID_FORMAT; ret = SSH_ERR_INVALID_FORMAT;
goto out; 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) { if (sshbuf_len(sigbuf) != 0) {
ret = SSH_ERR_UNEXPECTED_TRAILING_DATA; ret = SSH_ERR_UNEXPECTED_TRAILING_DATA;
goto out; goto out;
...@@ -180,7 +191,8 @@ ssh_ecdsa_verify(const struct sshkey *key, ...@@ -180,7 +191,8 @@ ssh_ecdsa_verify(const struct sshkey *key,
explicit_bzero(digest, sizeof(digest)); explicit_bzero(digest, sizeof(digest));
sshbuf_free(sigbuf); sshbuf_free(sigbuf);
sshbuf_free(b); sshbuf_free(b);
if (sig != NULL) BN_free(r);
BN_free(s);
ECDSA_SIG_free(sig); ECDSA_SIG_free(sig);
free(ktype); free(ktype);
return ret; return ret;
......
...@@ -28,6 +28,14 @@ ...@@ -28,6 +28,14 @@
#ifdef GSSAPI #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 #ifdef HAVE_GSSAPI_H
#include <gssapi.h> #include <gssapi.h>
#elif defined(HAVE_GSSAPI_GSSAPI_H) #elif defined(HAVE_GSSAPI_GSSAPI_H)
......
...@@ -495,14 +495,37 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) ...@@ -495,14 +495,37 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
free(type); free(type);
switch (key->type) { switch (key->type) {
case KEY_DSA: case KEY_DSA: {
buffer_get_bignum_bits(b, key->dsa->p); BIGNUM *p = NULL, *g = NULL, *q = NULL, *pub_key = NULL, *priv_key = NULL;
buffer_get_bignum_bits(b, key->dsa->g);
buffer_get_bignum_bits(b, key->dsa->q); if ((p = BN_new()) == NULL ||
buffer_get_bignum_bits(b, key->dsa->pub_key); (g = BN_new()) == NULL ||
buffer_get_bignum_bits(b, key->dsa->priv_key); (q = BN_new()) == NULL ||
break; (pub_key = BN_new()) == NULL ||
case KEY_RSA: (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: {
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 || if ((r = sshbuf_get_u8(b, &e1)) != 0 ||
(e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) || (e1 < 30 && (r = sshbuf_get_u8(b, &e2)) != 0) ||
(e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0)) (e1 < 30 && (r = sshbuf_get_u8(b, &e3)) != 0))
...@@ -517,18 +540,22 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen) ...@@ -517,18 +540,22 @@ do_convert_private_ssh2_from_blob(u_char *blob, u_int blen)
e += e3; e += e3;
debug("e %lx", e); debug("e %lx", e);
} }
if (!BN_set_word(key->rsa->e, e)) { if (!BN_set_word(bn_e, e)) {
sshbuf_free(b); sshbuf_free(b);
sshkey_free(key); sshkey_free(key);
return NULL; return NULL;
} }
buffer_get_bignum_bits(b, key->rsa->d); buffer_get_bignum_bits(b, bn_d);
buffer_get_bignum_bits(b, key->rsa->n); buffer_get_bignum_bits(b, bn_n);
buffer_get_bignum_bits(b, key->rsa->iqmp); buffer_get_bignum_bits(b, bn_iqmp);
buffer_get_bignum_bits(b, key->rsa->q); buffer_get_bignum_bits(b, bn_q);
buffer_get_bignum_bits(b, key->rsa->p); buffer_get_bignum_bits(b, bn_p);
if ((r = rsa_generate_additional_parameters(key->rsa)) != 0) 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)); fatal("generate RSA parameters failed: %s", ssh_err(r));
}
break; break;
} }
rlen = sshbuf_len(b); rlen = sshbuf_len(b);
...@@ -636,7 +663,7 @@ do_convert_from_pkcs8(struct sshkey **k, int *private) ...@@ -636,7 +663,7 @@ do_convert_from_pkcs8(struct sshkey **k, int *private)
identity_file); identity_file);
} }
fclose(fp); fclose(fp);
switch (EVP_PKEY_type(pubkey->type)) { switch (EVP_PKEY_base_id(pubkey)) {
case EVP_PKEY_RSA: case EVP_PKEY_RSA:
if ((*k = sshkey_new(KEY_UNSPEC)) == NULL) if ((*k = sshkey_new(KEY_UNSPEC)) == NULL)
fatal("sshkey_new failed"); fatal("sshkey_new failed");
...@@ -660,7 +687,7 @@ do_convert_from_pkcs8(struct sshkey **k, int *private) ...@@ -660,7 +687,7 @@ do_convert_from_pkcs8(struct sshkey **k, int *private)
#endif #endif
default: default:
fatal("%s: unsupported pubkey type %d", __func__, fatal("%s: unsupported pubkey type %d", __func__,
EVP_PKEY_type(pubkey->type)); EVP_PKEY_base_id(pubkey));
} }
EVP_PKEY_free(pubkey); EVP_PKEY_free(pubkey);
return; return;
...@@ -1702,6 +1729,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv) ...@@ -1702,6 +1729,7 @@ do_ca_sign(struct passwd *pw, int argc, char **argv)
#ifdef ENABLE_PKCS11 #ifdef ENABLE_PKCS11
pkcs11_terminate(); pkcs11_terminate();
#endif #endif
free(ca);
exit(0); exit(0);
} }
......
...@@ -195,6 +195,7 @@ keygrab_ssh1(con *c) ...@@ -195,6 +195,7 @@ keygrab_ssh1(con *c)
static struct sshbuf *msg; static struct sshbuf *msg;
int r; int r;
u_char type; u_char type;
BIGNUM *n = NULL, *e = NULL;
if (rsa == NULL) { if (rsa == NULL) {
if ((rsa = sshkey_new(KEY_RSA1)) == NULL) { if ((rsa = sshkey_new(KEY_RSA1)) == NULL) {
...@@ -213,16 +214,20 @@ keygrab_ssh1(con *c) ...@@ -213,16 +214,20 @@ keygrab_ssh1(con *c)
sshbuf_reset(msg); sshbuf_reset(msg);
return NULL; 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 */ /* server key */
(r = sshbuf_get_u32(msg, NULL)) != 0 || (r = sshbuf_get_u32(msg, NULL)) != 0 ||
(r = sshbuf_get_bignum1(msg, NULL)) != 0 || (r = sshbuf_get_bignum1(msg, NULL)) != 0 ||
(r = sshbuf_get_bignum1(msg, NULL)) != 0 || (r = sshbuf_get_bignum1(msg, NULL)) != 0 ||
/* host key */ /* host key */
(r = sshbuf_get_u32(msg, NULL)) != 0 || (r = sshbuf_get_u32(msg, NULL)) != 0 ||
(r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 || (r = sshbuf_get_bignum1(msg, e)) != 0 ||
(r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) { (r = sshbuf_get_bignum1(msg, n)) != 0 ||
RSA_set0_key(rsa->rsa, n, e, NULL) == 0) {
buf_err: buf_err:
BN_free(n);
BN_free(e);
error("%s: buffer error: %s", __func__, ssh_err(r)); error("%s: buffer error: %s", __func__, ssh_err(r));
sshbuf_reset(msg); sshbuf_reset(msg);
return NULL; return NULL;
......
...@@ -143,12 +143,14 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa, ...@@ -143,12 +143,14 @@ pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
static int static int
wrap_key(RSA *rsa) wrap_key(RSA *rsa)
{ {
static RSA_METHOD helper_rsa; static RSA_METHOD *helper_rsa;
memcpy(&helper_rsa, RSA_get_default_method(), sizeof(helper_rsa)); if (helper_rsa == NULL) {
helper_rsa.name = "ssh-pkcs11-helper"; helper_rsa = RSA_meth_dup(RSA_get_default_method());
helper_rsa.rsa_priv_enc = pkcs11_rsa_private_encrypt; RSA_meth_set1_name(helper_rsa, "ssh-pkcs11-helper");
RSA_set_method(rsa, &helper_rsa); RSA_meth_set_priv_enc(helper_rsa, pkcs11_rsa_private_encrypt);
}
RSA_set_method(rsa, helper_rsa);
return (0); return (0);
} }
......
...@@ -67,7 +67,7 @@ struct pkcs11_key { ...@@ -67,7 +67,7 @@ struct pkcs11_key {
struct pkcs11_provider *provider; struct pkcs11_provider *provider;
CK_ULONG slotidx; CK_ULONG slotidx;
int (*orig_finish)(RSA *rsa); int (*orig_finish)(RSA *rsa);
RSA_METHOD rsa_method; RSA_METHOD *rsa_method;
char *keyid; char *keyid;
int keyid_len; int keyid_len;
}; };
...@@ -326,13 +326,21 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx, ...@@ -326,13 +326,21 @@ pkcs11_rsa_wrap(struct pkcs11_provider *provider, CK_ULONG slotidx,
k11->keyid = xmalloc(k11->keyid_len); k11->keyid = xmalloc(k11->keyid_len);
memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len); memcpy(k11->keyid, keyid_attrib->pValue, k11->keyid_len);
} }
k11->orig_finish = def->finish; k11->orig_finish = RSA_meth_get_finish(def);
memcpy(&k11->rsa_method, def, sizeof(k11->rsa_method)); if ((k11->rsa_method = RSA_meth_dup(def)) == NULL ||
k11->rsa_method.name = "pkcs11"; RSA_meth_set1_name(k11->rsa_method, "pkcs11") == 0 ||
k11->rsa_method.rsa_priv_enc = pkcs11_rsa_private_encrypt; RSA_meth_set_priv_enc(k11->rsa_method, pkcs11_rsa_private_encrypt) == 0 ||
k11->rsa_method.rsa_priv_dec = pkcs11_rsa_private_decrypt; RSA_meth_set_priv_dec(k11->rsa_method, pkcs11_rsa_private_decrypt) == 0 ||
k11->rsa_method.finish = pkcs11_rsa_finish; RSA_meth_set_finish(k11->rsa_method, pkcs11_rsa_finish) == 0) {
RSA_set_method(rsa, &k11->rsa_method); 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); RSA_set_app_data(rsa, k11);
return (0); return (0);
} }
...@@ -460,6 +468,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, ...@@ -460,6 +468,7 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
CK_ULONG nfound; CK_ULONG nfound;
CK_SESSION_HANDLE session; CK_SESSION_HANDLE session;
CK_FUNCTION_LIST *f; CK_FUNCTION_LIST *f;
const BIGNUM *n, *e;
f = p->function_list; f = p->function_list;
session = p->slotinfo[slotidx].session; session = p->slotinfo[slotidx].session;
...@@ -512,10 +521,14 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, ...@@ -512,10 +521,14 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
if ((rsa = RSA_new()) == NULL) { if ((rsa = RSA_new()) == NULL) {
error("RSA_new failed"); error("RSA_new failed");
} else { } else {
rsa->n = BN_bin2bn(attribs[1].pValue, BIGNUM *rsa_n, *rsa_e;
rsa_n = BN_bin2bn(attribs[1].pValue,
attribs[1].ulValueLen, NULL); attribs[1].ulValueLen, NULL);
rsa->e = BN_bin2bn(attribs[2].pValue, rsa_e = BN_bin2bn(attribs[2].pValue,
attribs[2].ulValueLen, NULL); attribs[2].ulValueLen, NULL);
if (RSA_set0_key(rsa, rsa_n, rsa_e, NULL) == 0)
error("RSA_set0_key failed");
} }
} else { } else {
cp = attribs[2].pValue; cp = attribs[2].pValue;
...@@ -525,17 +538,18 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx, ...@@ -525,17 +538,18 @@ pkcs11_fetch_keys_filter(struct pkcs11_provider *p, CK_ULONG slotidx,
== NULL) { == NULL) {
error("d2i_X509 failed"); error("d2i_X509 failed");
} else if ((evp = X509_get_pubkey(x509)) == NULL || } else if ((evp = X509_get_pubkey(x509)) == NULL ||
evp->type != EVP_PKEY_RSA || EVP_PKEY_id(evp) != EVP_PKEY_RSA ||
evp->pkey.rsa == NULL) { EVP_PKEY_get0_RSA(evp) == NULL) {
debug("X509_get_pubkey failed or no rsa"); 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) { == NULL) {
error("RSAPublicKey_dup"); error("RSAPublicKey_dup");
} }
if (x509) if (x509)
X509_free(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) { pkcs11_rsa_wrap(p, slotidx, &attribs[0], rsa) == 0) {
key = sshkey_new(KEY_UNSPEC); key = sshkey_new(KEY_UNSPEC);
key->rsa = rsa; key->rsa = rsa;
......
...@@ -100,7 +100,7 @@ ssh_rsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp, ...@@ -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); hash_alg = rsa_hash_alg_from_ident(alg_ident);
if (key == NULL || key->rsa == NULL || hash_alg == -1 || if (key == NULL || key->rsa == NULL || hash_alg == -1 ||
sshkey_type_plain(key->type) != KEY_RSA || 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; return SSH_ERR_INVALID_ARGUMENT;
slen = RSA_size(key->rsa); slen = RSA_size(key->rsa);
if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM) if (slen <= 0 || slen > SSHBUF_MAX_BIGNUM)
...@@ -172,7 +172,7 @@ ssh_rsa_verify(const struct sshkey *key, ...@@ -172,7 +172,7 @@ ssh_rsa_verify(const struct sshkey *key,
if (key == NULL || key->rsa == NULL || if (key == NULL || key->rsa == NULL ||
sshkey_type_plain(key->type) != KEY_RSA || 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) sig == NULL || siglen == 0)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
......
...@@ -1752,6 +1752,7 @@ ssh_login(Sensitive *sensitive, const char *orighost, ...@@ -1752,6 +1752,7 @@ ssh_login(Sensitive *sensitive, const char *orighost,
char *server_user, *local_user; char *server_user, *local_user;
local_user = xstrdup(pw->pw_name); local_user = xstrdup(pw->pw_name);
free(pw);
server_user = options.user ? options.user : local_user; server_user = options.user ? options.user : local_user;
/* Convert the user-supplied hostname into all lowercase. */ /* Convert the user-supplied hostname into all lowercase. */
......
...@@ -70,6 +70,7 @@ try_agent_authentication(void) ...@@ -70,6 +70,7 @@ try_agent_authentication(void)
u_char response[16]; u_char response[16];
size_t i; size_t i;
BIGNUM *challenge; BIGNUM *challenge;
const BIGNUM *n;
struct ssh_identitylist *idlist = NULL; struct ssh_identitylist *idlist = NULL;
/* Get connection to the agent. */ /* Get connection to the agent. */
...@@ -96,8 +97,9 @@ try_agent_authentication(void) ...@@ -96,8 +97,9 @@ try_agent_authentication(void)
idlist->comments[i]); idlist->comments[i]);
/* Tell the server that we are willing to authenticate using this key. */ /* 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_start(SSH_CMSG_AUTH_RSA);
packet_put_bignum(idlist->keys[i]->rsa->n); packet_put_bignum((BIGNUM *)n);
packet_send(); packet_send();
packet_write_wait(); packet_write_wait();
...@@ -220,6 +222,7 @@ static int ...@@ -220,6 +222,7 @@ static int
try_rsa_authentication(int idx) try_rsa_authentication(int idx)
{ {
BIGNUM *challenge; BIGNUM *challenge;
const BIGNUM *n;
Key *public, *private; Key *public, *private;
char buf[300], *passphrase = NULL, *comment, *authfile; char buf[300], *passphrase = NULL, *comment, *authfile;
int i, perm_ok = 1, type, quit; int i, perm_ok = 1, type, quit;
...@@ -231,8 +234,9 @@ try_rsa_authentication(int idx) ...@@ -231,8 +234,9 @@ try_rsa_authentication(int idx)
debug("Trying RSA authentication with key '%.100s'", comment); debug("Trying RSA authentication with key '%.100s'", comment);
/* Tell the server that we are willing to authenticate using this key. */ /* 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_start(SSH_CMSG_AUTH_RSA);
packet_put_bignum(public->rsa->n); packet_put_bignum((BIGNUM *)n);
packet_send(); packet_send();
packet_write_wait(); packet_write_wait();
...@@ -348,15 +352,17 @@ try_rhosts_rsa_authentication(const char *local_user, Key * host_key) ...@@ -348,15 +352,17 @@ try_rhosts_rsa_authentication(const char *local_user, Key * host_key)
{ {
int type; int type;
BIGNUM *challenge; BIGNUM *challenge;
const BIGNUM *n, *e;
debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication."); debug("Trying rhosts or /etc/hosts.equiv with RSA host authentication.");
/* Tell the server that we are willing to authenticate using this key. */ /* 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_start(SSH_CMSG_AUTH_RHOSTS_RSA);
packet_put_cstring(local_user); packet_put_cstring(local_user);
packet_put_int(BN_num_bits(host_key->rsa->n)); packet_put_int(BN_num_bits(n));
packet_put_bignum(host_key->rsa->e); packet_put_bignum((BIGNUM *)e);
packet_put_bignum(host_key->rsa->n); packet_put_bignum((BIGNUM *)n);
packet_send(); packet_send();
packet_write_wait(); packet_write_wait();
...@@ -502,6 +508,8 @@ ssh_kex(char *host, struct sockaddr *hostaddr) ...@@ -502,6 +508,8 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
{ {
int i; int i;
BIGNUM *key; BIGNUM *key;
BIGNUM *server_n = NULL, *server_e = NULL,
*host_n = NULL, *host_e = NULL;
Key *host_key, *server_key; Key *host_key, *server_key;
int bits, rbits; int bits, rbits;
int ssh_cipher_default = SSH_CIPHER_3DES; int ssh_cipher_default = SSH_CIPHER_3DES;
...@@ -523,10 +531,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr) ...@@ -523,10 +531,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
if ((server_key = key_new(KEY_RSA1)) == NULL) if ((server_key = key_new(KEY_RSA1)) == NULL)
fatal("%s: key_new(KEY_RSA1) failed", __func__); fatal("%s: key_new(KEY_RSA1) failed", __func__);
bits = packet_get_int(); bits = packet_get_int();
packet_get_bignum(server_key->rsa->e); if ((server_e = BN_new()) == NULL ||
packet_get_bignum(server_key->rsa->n); (server_n = BN_new()) == NULL)
fatal("BN_new() failed");
rbits = BN_num_bits(server_key->rsa->n); 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) { if (bits != rbits) {
logit("Warning: Server lies about size of server public key: " logit("Warning: Server lies about size of server public key: "
"actual size is %d bits vs. announced %d.", rbits, bits); "actual size is %d bits vs. announced %d.", rbits, bits);
...@@ -536,10 +548,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr) ...@@ -536,10 +548,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
if ((host_key = key_new(KEY_RSA1)) == NULL) if ((host_key = key_new(KEY_RSA1)) == NULL)
fatal("%s: key_new(KEY_RSA1) failed", __func__); fatal("%s: key_new(KEY_RSA1) failed", __func__);
bits = packet_get_int(); bits = packet_get_int();
packet_get_bignum(host_key->rsa->e); if ((host_e = BN_new()) == NULL ||
packet_get_bignum(host_key->rsa->n); (host_n = BN_new()) == NULL)
fatal("BN_new() failed");
rbits = BN_num_bits(host_key->rsa->n); 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) { if (bits != rbits) {
logit("Warning: Server lies about size of server host key: " logit("Warning: Server lies about size of server host key: "
"actual size is %d bits vs. announced %d.", rbits, bits); "actual size is %d bits vs. announced %d.", rbits, bits);
...@@ -555,14 +571,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr) ...@@ -555,14 +571,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
packet_check_eom(); packet_check_eom();
debug("Received server public key (%d bits) and host key (%d bits).", 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) if (verify_host_key(host, hostaddr, host_key) == -1)
fatal("Host key verification failed."); fatal("Host key verification failed.");
client_flags = SSH_PROTOFLAG_SCREEN_NUMBER | SSH_PROTOFLAG_HOST_IN_FWD_OPEN; 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 * Generate an encryption key for the session. The key is a 256 bit
...@@ -597,14 +613,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr) ...@@ -597,14 +613,14 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
* Encrypt the integer using the public key and host key of the * Encrypt the integer using the public key and host key of the
* server (key with smaller modulus first). * 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. */ /* Public key has smaller modulus. */
if (BN_num_bits(host_key->rsa->n) < if (BN_num_bits(host_n) <
BN_num_bits(server_key->rsa->n) + SSH_KEY_BITS_RESERVED) { BN_num_bits(server_n) + SSH_KEY_BITS_RESERVED) {
fatal("respond_to_rsa_challenge: host_key %d < server_key %d + " fatal("respond_to_rsa_challenge: host_key %d < server_key %d + "
"SSH_KEY_BITS_RESERVED %d", "SSH_KEY_BITS_RESERVED %d",
BN_num_bits(host_key->rsa->n), BN_num_bits(host_n),
BN_num_bits(server_key->rsa->n), BN_num_bits(server_n),
SSH_KEY_BITS_RESERVED); SSH_KEY_BITS_RESERVED);
} }
if (rsa_public_encrypt(key, key, server_key->rsa) != 0 || if (rsa_public_encrypt(key, key, server_key->rsa) != 0 ||
...@@ -612,12 +628,12 @@ ssh_kex(char *host, struct sockaddr *hostaddr) ...@@ -612,12 +628,12 @@ ssh_kex(char *host, struct sockaddr *hostaddr)
fatal("%s: rsa_public_encrypt failed", __func__); fatal("%s: rsa_public_encrypt failed", __func__);
} else { } else {
/* Host key has smaller modulus (or they are equal). */ /* Host key has smaller modulus (or they are equal). */
if (BN_num_bits(server_key->rsa->n) < if (BN_num_bits(server_n) <
BN_num_bits(host_key->rsa->n) + SSH_KEY_BITS_RESERVED) { BN_num_bits(host_n) + SSH_KEY_BITS_RESERVED) {
fatal("respond_to_rsa_challenge: server_key %d < host_key %d + " fatal("respond_to_rsa_challenge: server_key %d < host_key %d + "
"SSH_KEY_BITS_RESERVED %d", "SSH_KEY_BITS_RESERVED %d",
BN_num_bits(server_key->rsa->n), BN_num_bits(server_n),
BN_num_bits(host_key->rsa->n), BN_num_bits(host_n),
SSH_KEY_BITS_RESERVED); SSH_KEY_BITS_RESERVED);
} }
if (rsa_public_encrypt(key, key, host_key->rsa) != 0 || if (rsa_public_encrypt(key, key, host_key->rsa) != 0 ||
......
...@@ -257,6 +257,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port) ...@@ -257,6 +257,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr, u_short port)
packet_send(); packet_send();
packet_write_wait(); packet_write_wait();
#endif #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