Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to openssl-1-1-1 #16

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ tcpkill
tcpnice
urlsnarf
webmitm
webspy
82 changes: 61 additions & 21 deletions ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ static u_int crc32_tab[] = {
static u_char pkt[4 + 8 + SSH_MAX_PKTLEN];

static void
put_bn(BIGNUM *bn, u_char **pp)
put_bn(const BIGNUM *bn, u_char **pp)
{
short i;

Expand Down Expand Up @@ -122,7 +122,7 @@ get_bn(BIGNUM *bn, u_char **pp, int *lenp)
}

static u_char *
ssh_session_id(u_char *cookie, BIGNUM *hostkey_n, BIGNUM *servkey_n)
ssh_session_id(u_char *cookie, const BIGNUM *hostkey_n, const BIGNUM *servkey_n)
{
static u_char sessid[16];
u_int i, j;
Expand Down Expand Up @@ -233,7 +233,12 @@ SSH_set_fd(SSH *ssh, int fd)
int
SSH_accept(SSH *ssh)
{
const BIGNUM *host_bn_n;
const BIGNUM *host_bn_e;
const BIGNUM *serv_bn_n;
const BIGNUM *serv_bn_e;
BIGNUM *enckey;

u_char *p, cipher, cookie[8], msg[1024];
u_int32_t num;
int i;
Expand All @@ -244,14 +249,19 @@ SSH_accept(SSH *ssh)
/* Send public key. */
p = msg;
*p++ = SSH_SMSG_PUBLIC_KEY; /* type */
memcpy(p, cookie, 8); p += 8; /* cookie */
memcpy(p, cookie, 8); p += 8; /* cookie */
num = 768; PUTLONG(num, p); /* servkey bits */
put_bn(ssh->ctx->servkey->e, &p); /* servkey exponent */
put_bn(ssh->ctx->servkey->n, &p); /* servkey modulus */

RSA_get0_key(ssh->ctx->servkey, &serv_bn_n, &serv_bn_e, NULL);
put_bn(serv_bn_e, &p); /* servkey exponent */
put_bn(serv_bn_n, &p); /* servkey modulus */
num = 1024; PUTLONG(num, p); /* hostkey bits */
put_bn(ssh->ctx->hostkey->e, &p); /* hostkey exponent */
put_bn(ssh->ctx->hostkey->n, &p); /* hostkey modulus */

RSA_get0_key(ssh->ctx->hostkey, &host_bn_n, &host_bn_e, NULL);
put_bn(host_bn_e, &p); /* hostkey exponent */
put_bn(host_bn_n, &p); /* hostkey modulus */
num = 0; PUTLONG(num, p); /* protocol flags */

num = ssh->ctx->encmask; PUTLONG(num, p); /* ciphers */
num = ssh->ctx->authmask; PUTLONG(num, p); /* authmask */

Expand Down Expand Up @@ -301,7 +311,7 @@ SSH_accept(SSH *ssh)
SKIP(p, i, 4);

/* Decrypt session key. */
if (BN_cmp(ssh->ctx->servkey->n, ssh->ctx->hostkey->n) > 0) {
if (BN_cmp(serv_bn_n, host_bn_n) > 0) {
rsa_private_decrypt(enckey, enckey, ssh->ctx->servkey);
rsa_private_decrypt(enckey, enckey, ssh->ctx->hostkey);
}
Expand All @@ -321,8 +331,7 @@ SSH_accept(SSH *ssh)
BN_clear_free(enckey);

/* Derive real session key using session id. */
if ((p = ssh_session_id(cookie, ssh->ctx->hostkey->n,
ssh->ctx->servkey->n)) == NULL) {
if ((p = ssh_session_id(cookie, host_bn_n, serv_bn_n)) == NULL) {
warn("ssh_session_id");
return (-1);
}
Expand Down Expand Up @@ -356,6 +365,14 @@ SSH_accept(SSH *ssh)
int
SSH_connect(SSH *ssh)
{
BN_CTX *serv_bn_ctx;
BIGNUM *serv_bn_e;
BIGNUM *serv_bn_n;

BN_CTX *host_bn_ctx;
BIGNUM *host_bn_e;
BIGNUM *host_bn_n;

BIGNUM *bn;
u_char *p, cipher, cookie[8], msg[1024];
u_int32_t num;
Expand All @@ -382,21 +399,45 @@ SSH_connect(SSH *ssh)

/* Get servkey. */
ssh->ctx->servkey = RSA_new();
ssh->ctx->servkey->n = BN_new();
ssh->ctx->servkey->e = BN_new();

serv_bn_ctx = BN_CTX_new();
if (serv_bn_ctx == NULL)
{
return (-1);
}

BN_CTX_start (serv_bn_ctx);
serv_bn_e = BN_CTX_get(serv_bn_ctx);
serv_bn_n = BN_CTX_get(serv_bn_ctx);
RSA_set0_key(ssh->ctx->servkey, serv_bn_n, serv_bn_n, NULL);

SKIP(p, i, 4);
get_bn(ssh->ctx->servkey->e, &p, &i);
get_bn(ssh->ctx->servkey->n, &p, &i);
get_bn(serv_bn_e, &p, &i);
get_bn(serv_bn_n, &p, &i);

BN_CTX_end (serv_bn_ctx);

/* Get hostkey. */
ssh->ctx->hostkey = RSA_new();
ssh->ctx->hostkey->n = BN_new();
ssh->ctx->hostkey->e = BN_new();

host_bn_ctx = BN_CTX_new();
if (host_bn_ctx == NULL)
{
return (-1);
}

BN_CTX_start (host_bn_ctx);
host_bn_e = BN_CTX_get(host_bn_ctx);
host_bn_n = BN_CTX_get(host_bn_ctx);
RSA_set0_key(ssh->ctx->hostkey, host_bn_n, host_bn_n, NULL);

BN_CTX_end (host_bn_ctx);

SKIP(p, i, 4);
get_bn(ssh->ctx->hostkey->e, &p, &i);
get_bn(ssh->ctx->hostkey->n, &p, &i);
get_bn(host_bn_e, &p, &i);
get_bn(host_bn_n, &p, &i);

BN_CTX_end (host_bn_ctx);

/* Get cipher, auth masks. */
SKIP(p, i, 4);
Expand All @@ -408,8 +449,7 @@ SSH_connect(SSH *ssh)
RAND_bytes(ssh->sesskey, sizeof(ssh->sesskey));

/* Obfuscate with session id. */
if ((p = ssh_session_id(cookie, ssh->ctx->hostkey->n,
ssh->ctx->servkey->n)) == NULL) {
if ((p = ssh_session_id(cookie, host_bn_n, serv_bn_n)) == NULL) {
warn("ssh_session_id");
return (-1);
}
Expand All @@ -425,7 +465,7 @@ SSH_connect(SSH *ssh)
else BN_add_word(bn, ssh->sesskey[i]);
}
/* Encrypt session key. */
if (BN_cmp(ssh->ctx->servkey->n, ssh->ctx->hostkey->n) < 0) {
if (BN_cmp(serv_bn_n, host_bn_n) < 0) {
rsa_public_encrypt(bn, bn, ssh->ctx->servkey);
rsa_public_encrypt(bn, bn, ssh->ctx->hostkey);
}
Expand Down
38 changes: 23 additions & 15 deletions sshcrypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <stdio.h>
#include <stdlib.h>

#include <string.h>

#include "sshcrypto.h"

struct blowfish_state {
Expand All @@ -29,20 +31,23 @@ struct blowfish_state {
};

struct des3_state {
des_key_schedule k1, k2, k3;
des_cblock iv1, iv2, iv3;
DES_key_schedule k1, k2, k3;
DES_cblock iv1, iv2, iv3;
};

void
rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
{
BIGNUM *bn_e, *bn_n;
u_char *inbuf, *outbuf;
int len, ilen, olen;

if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e))
RSA_get0_key(key, &bn_n, &bn_e, NULL);

if (BN_num_bits(bn_e) < 2 || !BN_is_odd(bn_e))
errx(1, "rsa_public_encrypt() exponent too small or not odd");

olen = BN_num_bytes(key->n);
olen = BN_num_bytes(bn_n);
outbuf = malloc(olen);

ilen = BN_num_bytes(in);
Expand All @@ -68,10 +73,13 @@ rsa_public_encrypt(BIGNUM *out, BIGNUM *in, RSA *key)
void
rsa_private_decrypt(BIGNUM *out, BIGNUM *in, RSA *key)
{
BIGNUM *bn_n, *bn_e;
u_char *inbuf, *outbuf;
int len, ilen, olen;

RSA_get0_key(key, &bn_n, &bn_e, NULL);

olen = BN_num_bytes(key->n);
olen = BN_num_bytes(bn_n);
outbuf = malloc(olen);

ilen = BN_num_bytes(in);
Expand Down Expand Up @@ -155,13 +163,13 @@ des3_init(u_char *sesskey, int len)
if ((state = malloc(sizeof(*state))) == NULL)
err(1, "malloc");

des_set_key((void *)sesskey, state->k1);
des_set_key((void *)(sesskey + 8), state->k2);
DES_set_key((void *)sesskey, &state->k1);
DES_set_key((void *)(sesskey + 8), &state->k2);

if (len <= 16)
des_set_key((void *)sesskey, state->k3);
DES_set_key((void *)sesskey, &state->k3);
else
des_set_key((void *)(sesskey + 16), state->k3);
DES_set_key((void *)(sesskey + 16), &state->k3);

memset(state->iv1, 0, 8);
memset(state->iv2, 0, 8);
Expand All @@ -177,9 +185,9 @@ des3_encrypt(u_char *src, u_char *dst, int len, void *state)
estate = (struct des3_state *)state;
memcpy(estate->iv1, estate->iv2, 8);

des_ncbc_encrypt(src, dst, len, estate->k1, &estate->iv1, DES_ENCRYPT);
des_ncbc_encrypt(dst, dst, len, estate->k2, &estate->iv2, DES_DECRYPT);
des_ncbc_encrypt(dst, dst, len, estate->k3, &estate->iv3, DES_ENCRYPT);
DES_ncbc_encrypt(src, dst, len, &estate->k1, &estate->iv1, DES_ENCRYPT);
DES_ncbc_encrypt(dst, dst, len, &estate->k2, &estate->iv2, DES_DECRYPT);
DES_ncbc_encrypt(dst, dst, len, &estate->k3, &estate->iv3, DES_ENCRYPT);
}

void
Expand All @@ -190,7 +198,7 @@ des3_decrypt(u_char *src, u_char *dst, int len, void *state)
dstate = (struct des3_state *)state;
memcpy(dstate->iv1, dstate->iv2, 8);

des_ncbc_encrypt(src, dst, len, dstate->k3, &dstate->iv3, DES_DECRYPT);
des_ncbc_encrypt(dst, dst, len, dstate->k2, &dstate->iv2, DES_ENCRYPT);
des_ncbc_encrypt(dst, dst, len, dstate->k1, &dstate->iv1, DES_DECRYPT);
DES_ncbc_encrypt(src, dst, len, &dstate->k3, &dstate->iv3, DES_DECRYPT);
DES_ncbc_encrypt(dst, dst, len, &dstate->k2, &dstate->iv2, DES_ENCRYPT);
DES_ncbc_encrypt(dst, dst, len, &dstate->k1, &dstate->iv1, DES_DECRYPT);
}