GUACAMOLE-205: Update to 1.1 version of OpenSSL API.

This commit is contained in:
Michael Jumper 2017-02-27 10:40:18 -08:00
parent c8fca94899
commit dbfb782dd5
6 changed files with 106 additions and 19 deletions

View File

@ -236,6 +236,31 @@ then
--------------------------------------------])
else
AC_DEFINE([ENABLE_SSL],, [Whether SSL-related support is enabled])
# OpenSSL 1.1 accessor function for DSA signature values
AC_CHECK_DECL([DSA_SIG_get0],
[AC_DEFINE([HAVE_DSA_SIG_GET0],,
[Whether libssl provides DSA_SIG_get0()])],,
[#include <openssl/dsa.h>])
# OpenSSL 1.1 accessor function for DSA public key parameters
AC_CHECK_DECL([DSA_get0_pqg],
[AC_DEFINE([HAVE_DSA_GET0_PQG],,
[Whether libssl provides DSA_get0_pqg()])],,
[#include <openssl/dsa.h>])
# OpenSSL 1.1 accessor function for DSA public/private key values
AC_CHECK_DECL([DSA_get0_key],
[AC_DEFINE([HAVE_DSA_GET0_KEY],,
[Whether libssl provides DSA_get0_key()])],,
[#include <openssl/dsa.h>])
# OpenSSL 1.1 accessor function for RSA public/private key values
AC_CHECK_DECL([RSA_get0_key],
[AC_DEFINE([HAVE_RSA_GET0_KEY],,
[Whether libssl provides RSA_get0_key()])],,
[#include <openssl/rsa.h>])
fi
fi

View File

@ -54,7 +54,7 @@ void guac_common_ssh_buffer_write_data(char** buffer, const char* data,
*buffer += length;
}
void guac_common_ssh_buffer_write_bignum(char** buffer, BIGNUM* value) {
void guac_common_ssh_buffer_write_bignum(char** buffer, const BIGNUM* value) {
unsigned char* bn_buffer;
int length;

View File

@ -76,7 +76,7 @@ void guac_common_ssh_buffer_write_string(char** buffer, const char* string,
* @param value
* The value to write.
*/
void guac_common_ssh_buffer_write_bignum(char** buffer, BIGNUM* value);
void guac_common_ssh_buffer_write_bignum(char** buffer, const BIGNUM* value);
/**
* Writes the given data the given buffer, advancing the buffer pointer by the

View File

@ -53,6 +53,9 @@ guac_common_ssh_key* guac_common_ssh_key_alloc(char* data, int length,
RSA* rsa_key;
const BIGNUM* key_e;
const BIGNUM* key_n;
/* Read key */
rsa_key = PEM_read_bio_RSAPrivateKey(key_bio, NULL, NULL, passphrase);
if (rsa_key == NULL)
@ -69,10 +72,18 @@ guac_common_ssh_key* guac_common_ssh_key_alloc(char* data, int length,
public_key = malloc(4096);
pos = public_key;
/* Derive public key */
/* Retrieve public key */
#ifdef HAVE_RSA_GET0_KEY
RSA_get0_key(rsa_key, &key_n, &key_e, NULL);
#else
key_n = rsa_key->n;
key_e = rsa_key->e;
#endif
/* Send public key formatted for SSH */
guac_common_ssh_buffer_write_string(&pos, "ssh-rsa", sizeof("ssh-rsa")-1);
guac_common_ssh_buffer_write_bignum(&pos, rsa_key->e);
guac_common_ssh_buffer_write_bignum(&pos, rsa_key->n);
guac_common_ssh_buffer_write_bignum(&pos, key_e);
guac_common_ssh_buffer_write_bignum(&pos, key_n);
/* Save public key to structure */
key->public_key = public_key;
@ -87,6 +98,11 @@ guac_common_ssh_key* guac_common_ssh_key_alloc(char* data, int length,
DSA* dsa_key;
const BIGNUM* key_p;
const BIGNUM* key_q;
const BIGNUM* key_g;
const BIGNUM* pub_key;
/* Read key */
dsa_key = PEM_read_bio_DSAPrivateKey(key_bio, NULL, NULL, passphrase);
if (dsa_key == NULL)
@ -103,12 +119,28 @@ guac_common_ssh_key* guac_common_ssh_key_alloc(char* data, int length,
public_key = malloc(4096);
pos = public_key;
/* Derive public key */
/* Retrieve public key parameters */
#ifdef HAVE_DSA_GET0_PQG
DSA_get0_pqg(dsa_key, &key_p, &key_q, &key_g);
#else
key_p = dsa_key->p;
key_q = dsa_key->q;
key_g = dsa_key->g;
#endif
/* Retrieve public key */
#ifdef HAVE_DSA_GET0_KEY
DSA_get0_key(dsa_key, &pub_key, NULL);
#else
pub_key = dsa_key->pub_key;
#endif
/* Send public key formatted for SSH */
guac_common_ssh_buffer_write_string(&pos, "ssh-dss", sizeof("ssh-dss")-1);
guac_common_ssh_buffer_write_bignum(&pos, dsa_key->p);
guac_common_ssh_buffer_write_bignum(&pos, dsa_key->q);
guac_common_ssh_buffer_write_bignum(&pos, dsa_key->g);
guac_common_ssh_buffer_write_bignum(&pos, dsa_key->pub_key);
guac_common_ssh_buffer_write_bignum(&pos, key_p);
guac_common_ssh_buffer_write_bignum(&pos, key_q);
guac_common_ssh_buffer_write_bignum(&pos, key_g);
guac_common_ssh_buffer_write_bignum(&pos, pub_key);
/* Save public key to structure */
key->public_key = public_key;
@ -156,7 +188,6 @@ int guac_common_ssh_key_sign(guac_common_ssh_key* key, const char* data,
int length, unsigned char* sig) {
const EVP_MD* md;
EVP_MD_CTX md_ctx;
unsigned char digest[EVP_MAX_MD_SIZE];
unsigned int dlen, len;
@ -165,10 +196,18 @@ int guac_common_ssh_key_sign(guac_common_ssh_key* key, const char* data,
if ((md = EVP_get_digestbynid(NID_sha1)) == NULL)
return -1;
/* Allocate digest context */
EVP_MD_CTX* md_ctx = EVP_MD_CTX_create();
if (md_ctx == NULL)
return -1;
/* Digest data */
EVP_DigestInit(&md_ctx, md);
EVP_DigestUpdate(&md_ctx, data, length);
EVP_DigestFinal(&md_ctx, digest, &dlen);
EVP_DigestInit(md_ctx, md);
EVP_DigestUpdate(md_ctx, data, length);
EVP_DigestFinal(md_ctx, digest, &dlen);
/* Digest context no longer needed */
EVP_MD_CTX_destroy(md_ctx);
/* Sign with key */
switch (key->type) {
@ -183,9 +222,20 @@ int guac_common_ssh_key_sign(guac_common_ssh_key* key, const char* data,
DSA_SIG* dsa_sig = DSA_do_sign(digest, dlen, key->dsa);
if (dsa_sig != NULL) {
const BIGNUM* sig_r;
const BIGNUM* sig_s;
/* Retrieve DSA signature values */
#ifdef HAVE_DSA_SIG_GET0
DSA_SIG_get0(dsa_sig, &sig_r, &sig_s);
#else
sig_r = dsa_sig->r;
sig_s = dsa_sig->s;
#endif
/* Compute size of each half of signature */
int rlen = BN_num_bytes(dsa_sig->r);
int slen = BN_num_bytes(dsa_sig->s);
int rlen = BN_num_bytes(sig_r);
int slen = BN_num_bytes(sig_s);
/* Ensure each number is within the required size */
if (rlen > DSA_SIG_NUMBER_SIZE || slen > DSA_SIG_NUMBER_SIZE)
@ -195,11 +245,11 @@ int guac_common_ssh_key_sign(guac_common_ssh_key* key, const char* data,
memset(sig, 0, DSA_SIG_SIZE);
/* Add R at the end of the first block of the signature */
BN_bn2bin(dsa_sig->r, sig + DSA_SIG_SIZE
BN_bn2bin(sig_r, sig + DSA_SIG_SIZE
- DSA_SIG_NUMBER_SIZE - rlen);
/* Add S at the end of the second block of the signature */
BN_bn2bin(dsa_sig->s, sig + DSA_SIG_SIZE - slen);
BN_bn2bin(sig_s, sig + DSA_SIG_SIZE - slen);
/* Done */
DSA_SIG_free(dsa_sig);

View File

@ -45,6 +45,7 @@
GCRY_THREAD_OPTION_PTHREAD_IMPL;
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L
/**
* Array of mutexes, used by OpenSSL.
*/
@ -133,6 +134,7 @@ static void guac_common_ssh_openssl_free_locks(int count) {
free(guac_common_ssh_openssl_locks);
}
#endif
int guac_common_ssh_init(guac_client* client) {
@ -145,10 +147,12 @@ int guac_common_ssh_init(guac_client* client) {
}
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L
/* Init threadsafety in OpenSSL */
guac_common_ssh_openssl_init_locks(CRYPTO_num_locks());
CRYPTO_set_id_callback(guac_common_ssh_openssl_id_callback);
CRYPTO_set_locking_callback(guac_common_ssh_openssl_locking_callback);
#endif
/* Init OpenSSL */
SSL_library_init();
@ -163,7 +167,9 @@ int guac_common_ssh_init(guac_client* client) {
}
void guac_common_ssh_uninit() {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
guac_common_ssh_openssl_free_locks(CRYPTO_num_locks());
#endif
}
/**

View File

@ -153,6 +153,7 @@ static int daemonize() {
}
#ifdef ENABLE_SSL
#if OPENSSL_VERSION_NUMBER < 0x10100000L
/**
* Array of mutexes, used by OpenSSL.
*/
@ -242,6 +243,7 @@ static void guacd_openssl_free_locks(int count) {
}
#endif
#endif
int main(int argc, char* argv[]) {
@ -359,10 +361,12 @@ int main(int argc, char* argv[]) {
guacd_log(GUAC_LOG_INFO, "Communication will require SSL/TLS.");
#if OPENSSL_VERSION_NUMBER < 0x10100000L
/* Init threadsafety in OpenSSL */
guacd_openssl_init_locks(CRYPTO_num_locks());
CRYPTO_set_id_callback(guacd_openssl_id_callback);
CRYPTO_set_locking_callback(guacd_openssl_locking_callback);
#endif
/* Init SSL */
SSL_library_init();
@ -490,7 +494,9 @@ int main(int argc, char* argv[]) {
#ifdef ENABLE_SSL
if (ssl_context != NULL) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
guacd_openssl_free_locks(CRYPTO_num_locks());
#endif
SSL_CTX_free(ssl_context);
}
#endif