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

Add compatibility for OpenSSL 1.1.0 pre5 and previous versions #460

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 21 additions & 1 deletion ncat/ncat_ssl.c
Expand Up @@ -118,7 +118,7 @@
* *
***************************************************************************/

/* $Id$ */
/* $Id: ncat_ssl.c 35761 2016-04-04 15:38:44Z dmiller $ */

#include "nbase.h"
#include "ncat_config.h"
Expand All @@ -132,6 +132,7 @@
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>

/* Required for windows compilation to Eliminate APPLINK errors.
See http://www.openssl.org/support/faq.html#PROG2 */
#ifdef WIN32
Expand Down Expand Up @@ -315,21 +316,40 @@ static int cert_match_dnsname(X509 *cert, const char *hostname,

/* We must copy this address into a temporary variable because ASN1_item_d2i
increments it. We don't want it to corrupt ext->value->data. */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
data = ext->value->data;
#else
ASN1_OCTET_STRING* asn1_str = X509_EXTENSION_get_data(ext);
data = asn1_str->data;
#endif
/* Here we rely on the fact that the internal representation (the "i" in
"i2d") for NID_subject_alt_name is STACK_OF(GENERAL_NAME). Converting it
to a stack of CONF_VALUE with a i2v method is not satisfactory, because a
CONF_VALUE doesn't contain the length of the value so you can't know the
presence of null bytes. */
#if (OPENSSL_VERSION_NUMBER > 0x00907000L)
if (method->it != NULL) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
gen_names = (STACK_OF(GENERAL_NAME) *) ASN1_item_d2i(NULL,
(const unsigned char **) &data,
ext->value->length, ASN1_ITEM_ptr(method->it));
#else
ASN1_OCTET_STRING* asn1_str_a = X509_EXTENSION_get_data(ext);
gen_names = (STACK_OF(GENERAL_NAME) *) ASN1_item_d2i(NULL,
(const unsigned char **) &data,
asn1_str_a->length, ASN1_ITEM_ptr(method->it));
#endif
} else {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
gen_names = (STACK_OF(GENERAL_NAME) *) method->d2i(NULL,
(const unsigned char **) &data,
ext->value->length);
#else
ASN1_OCTET_STRING* asn1_str_b = X509_EXTENSION_get_data(ext);
gen_names = (STACK_OF(GENERAL_NAME) *) method->d2i(NULL,
(const unsigned char **) &data,
asn1_str_b->length);
#endif
}
#else
gen_names = (STACK_OF(GENERAL_NAME) *) method->d2i(NULL,
Expand Down
4 changes: 4 additions & 0 deletions ncat/test/test-wildcard.c
Expand Up @@ -253,7 +253,11 @@ static int set_dNSNames(X509 *cert, const struct lstr dNSNames[])
if (gen_name == NULL)
goto stack_err;
gen_name->type = GEN_DNS;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
gen_name->d.dNSName = M_ASN1_IA5STRING_new();
#else
gen_name->d.dNSName = ASN1_IA5STRING_new();
#endif
if (gen_name->d.dNSName == NULL)
goto name_err;
if (ASN1_STRING_set(gen_name->d.dNSName, name->s, name->len) == 0)
Expand Down
125 changes: 95 additions & 30 deletions nping/Crypto.cc
Expand Up @@ -128,8 +128,8 @@

#ifdef HAVE_OPENSSL
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#endif

extern NpingOps o;
Expand Down Expand Up @@ -178,21 +178,39 @@ int Crypto::aes128_cbc_encrypt(u8 *inbuff, size_t inlen, u8 *dst_buff, u8 *key,
#ifdef HAVE_OPENSSL
if( o.doCrypto() ){
int flen=0, flen2=0;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
int result=OP_SUCCESS;
if( EVP_EncryptInit(&ctx, EVP_aes_128_cbc(), key, iv)==0 ){
nping_print(DBG_4, "EVP_EncryptInit() failed");
result=OP_FAILURE;
}else if( EVP_EncryptUpdate(&ctx, dst_buff, &flen, inbuff, (int)inlen)==0 ){
nping_print(DBG_4, "EVP_EncryptUpdate() failed");
result=OP_FAILURE;
}else if( EVP_EncryptFinal(&ctx, dst_buff+flen, &flen2)==0 ){
nping_print(DBG_4, "EVP_EncryptFinal() failed");
result=OP_FAILURE;
}
EVP_CIPHER_CTX_cleanup(&ctx);
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
int result=OP_SUCCESS;
if( EVP_EncryptInit(&ctx, EVP_aes_128_cbc(), key, iv)==0 ){
nping_print(DBG_4, "EVP_EncryptInit() failed");
result=OP_FAILURE;
}else if( EVP_EncryptUpdate(&ctx, dst_buff, &flen, inbuff, (int)inlen)==0 ){
nping_print(DBG_4, "EVP_EncryptUpdate() failed");
result=OP_FAILURE;
}else if( EVP_EncryptFinal(&ctx, dst_buff+flen, &flen2)==0 ){
nping_print(DBG_4, "EVP_EncryptFinal() failed");
result=OP_FAILURE;
}
EVP_CIPHER_CTX_cleanup(&ctx);
#else
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_reset(ctx);
EVP_CIPHER_CTX_set_padding(ctx, 0);
int result=OP_SUCCESS;
if( EVP_EncryptInit(ctx, EVP_aes_128_cbc(), key, iv)==0 ){
nping_print(DBG_4, "EVP_EncryptInit() failed");
result=OP_FAILURE;
}else if( EVP_EncryptUpdate(ctx, dst_buff, &flen, inbuff, (int)inlen)==0 ){
nping_print(DBG_4, "EVP_EncryptUpdate() failed");
result=OP_FAILURE;
}else if( EVP_EncryptFinal(ctx, dst_buff+flen, &flen2)==0 ){
nping_print(DBG_4, "EVP_EncryptFinal() failed");
result=OP_FAILURE;
}
EVP_CIPHER_CTX_cleanup(ctx);
#endif
return result;
}
#endif
Expand All @@ -213,19 +231,35 @@ int Crypto::aes128_cbc_decrypt(u8 *inbuff, size_t inlen, u8 *dst_buff, u8 *key,
#ifdef HAVE_OPENSSL
if( o.doCrypto() ){
int flen1=0, flen2=0;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
int result=OP_SUCCESS;
if( EVP_DecryptInit(&ctx, EVP_aes_128_cbc(), key, iv)==0 ){
nping_print(DBG_4, "EVP_DecryptInit() failed");
result=OP_FAILURE;
}else if( EVP_DecryptUpdate(&ctx, dst_buff, &flen1, inbuff, (int)inlen)==0 ){
nping_print(DBG_4, "EVP_DecryptUpdate() failed");
result=OP_FAILURE;
}else if( EVP_DecryptFinal(&ctx, dst_buff+flen1, &flen2)==0 ){
nping_print(DBG_4, "OpenSSL bug: it says EVP_DecryptFinal() failed when it didn't (%s).",
ERR_error_string(ERR_peek_last_error(), NULL));
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
EVP_CIPHER_CTX_set_padding(&ctx, 0);
int result=OP_SUCCESS;
if( EVP_DecryptInit(&ctx, EVP_aes_128_cbc(), key, iv)==0 ){
nping_print(DBG_4, "EVP_DecryptInit() failed");
result=OP_FAILURE;
}else if( EVP_DecryptUpdate(&ctx, dst_buff, &flen1, inbuff, (int)inlen)==0 ){
nping_print(DBG_4, "EVP_DecryptUpdate() failed");
result=OP_FAILURE;
}else if( EVP_DecryptFinal(&ctx, dst_buff+flen1, &flen2)==0 ){
nping_print(DBG_4, "OpenSSL bug: it says EVP_DecryptFinal() failed when it didn't (%s).",
ERR_error_string(ERR_peek_last_error(), NULL));
#else
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_reset(ctx);
EVP_CIPHER_CTX_set_padding(ctx, 0);
int result=OP_SUCCESS;
if( EVP_DecryptInit(ctx, EVP_aes_128_cbc(), key, iv)==0 ){
nping_print(DBG_4, "EVP_DecryptInit() failed");
result=OP_FAILURE;
}else if( EVP_DecryptUpdate(ctx, dst_buff, &flen1, inbuff, (int)inlen)==0 ){
nping_print(DBG_4, "EVP_DecryptUpdate() failed");
result=OP_FAILURE;
}else if( EVP_DecryptFinal(ctx, dst_buff+flen1, &flen2)==0 ){
nping_print(DBG_4, "OpenSSL bug: it says EVP_DecryptFinal() failed when it didn't (%s).",
ERR_error_string(ERR_peek_last_error(), NULL));
#endif
/* We do not return OP_FAILURE in this case because the
* EVP_DecryptFinal() function seems to be buggy and fails when it shouldn't.
* We are passing a buffer whose length is multiple of the AES block
Expand All @@ -252,7 +286,11 @@ int Crypto::aes128_cbc_decrypt(u8 *inbuff, size_t inlen, u8 *dst_buff, u8 *key,
//ERR_free_strings();
//ERR_pop_to_mark();
}
EVP_CIPHER_CTX_cleanup(&ctx);
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_CIPHER_CTX_cleanup(&ctx);
#else
EVP_CIPHER_CTX_reset(ctx);
#endif
return result;
}
#endif
Expand Down Expand Up @@ -289,6 +327,7 @@ u8 *Crypto::deriveKey(const u8 *from, size_t fromlen, size_t *final_len){
static u8 hash[MAX(SHA256_HASH_LEN, EVP_MAX_MD_SIZE)];
static u8 next[MAX(SHA256_HASH_LEN, EVP_MAX_MD_SIZE)];
unsigned int lastlen;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);

Expand All @@ -310,7 +349,33 @@ u8 *Crypto::deriveKey(const u8 *from, size_t fromlen, size_t *final_len){
}
if(final_len!=NULL)
*final_len=SHA256_HASH_LEN;

EVP_MD_CTX_cleanup(&ctx);
#else
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
EVP_MD_CTX_init(ctx);

if( EVP_MD_size(EVP_sha256()) != SHA256_HASH_LEN )
nping_fatal(QT_2, "OpenSSL is broken. SHA256 len is %d\n", EVP_MD_size(EVP_sha256()) );

/* Compute the SHA256 hash of the supplied buffer */
EVP_DigestInit(ctx, EVP_sha256());
EVP_DigestUpdate(ctx, from, fromlen);
EVP_DigestFinal(ctx, hash, &lastlen);

/* Now compute the 1000th hash of that hash */
for(int i=0; i<TIMES_KEY_DERIVATION; i++){
EVP_MD_CTX_init(ctx);
EVP_DigestInit(ctx, EVP_sha256());
EVP_DigestUpdate(ctx, hash, SHA256_HASH_LEN);
EVP_DigestFinal(ctx, next, &lastlen);
memcpy(hash, next, SHA256_HASH_LEN);
}
if(final_len!=NULL)
*final_len=SHA256_HASH_LEN;

EVP_MD_CTX_free(ctx);
#endif
return hash;
}
#endif
Expand Down
19 changes: 18 additions & 1 deletion nping/configure
Expand Up @@ -2216,6 +2216,23 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu



















# Check whether --with-localdirs was given.
if test "${with_localdirs+set}" = set; then :
withval=$with_localdirs; case "$with_localdirs" in
Expand Down Expand Up @@ -5058,7 +5075,7 @@ if test "$use_openssl" = "yes"; then

OPENSSL_LIBS="-lssl -lcrypto"
LIBS_TMP="$LIBS"
LIBS="$LIBS $OPENSSL_LIBS"
LIBS="$OPENSSL_LIBS $LIBS"
# Check whether the installed OpenSSL supports SHA-256 (ver 0.9.8 or later).
ac_fn_c_check_func "$LINENO" "EVP_sha256" "ac_cv_func_EVP_sha256"
if test "x$ac_cv_func_EVP_sha256" = xyes; then :
Expand Down
2 changes: 1 addition & 1 deletion nping/configure.ac
Expand Up @@ -175,7 +175,7 @@ if test "$use_openssl" = "yes"; then
AC_DEFINE(HAVE_OPENSSL)
OPENSSL_LIBS="-lssl -lcrypto"
LIBS_TMP="$LIBS"
LIBS="$LIBS $OPENSSL_LIBS"
LIBS="$OPENSSL_LIBS $LIBS @LIBS@"
# Check whether the installed OpenSSL supports SHA-256 (ver 0.9.8 or later).
AC_CHECK_FUNC(EVP_sha256,, AC_MSG_ERROR([Your version of OpenSSL does not support SHA-256. Please install OpenSSL 0.9.8 or later.]))
LIBS="$LIBS_TMP"
Expand Down