We don't depend on ECDH functions from OpenSSL anymore.
This commit is contained in:
		
							parent
							
								
									aa2d4f8dd9
								
							
						
					
					
						commit
						69689f908b
					
				
					 4 changed files with 3 additions and 288 deletions
				
			
		|  | @ -35,7 +35,7 @@ AC_DEFUN([tinc_OPENSSL], | |||
|      LDFLAGS="$LDFLAGS -L$withval"] | ||||
|   ) | ||||
| 
 | ||||
|   AC_CHECK_HEADERS([openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h openssl/ecdh.h openssl/ec.h], | ||||
|   AC_CHECK_HEADERS([openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h], | ||||
|     [], | ||||
|     [AC_MSG_ERROR([OpenSSL header files not found.]); break] | ||||
|   ) | ||||
|  | @ -45,11 +45,11 @@ AC_DEFUN([tinc_OPENSSL], | |||
|     [AC_MSG_ERROR([OpenSSL libraries not found.])] | ||||
|   ) | ||||
| 
 | ||||
|   AC_CHECK_FUNCS([RAND_pseudo_bytes EVP_EncryptInit_ex ECDH_compute_key ECDSA_verify], , | ||||
|   AC_CHECK_FUNCS([RAND_status EVP_EncryptInit_ex], , | ||||
|     [AC_MSG_ERROR([Missing OpenSSL functionality, make sure you have installed the latest version.]); break], | ||||
|   ) | ||||
| 
 | ||||
|   AC_CHECK_DECLS([OpenSSL_add_all_algorithms, EVP_CTRL_GCM_GET_TAG], , | ||||
|   AC_CHECK_DECLS([OpenSSL_add_all_algorithms], , | ||||
|     [AC_MSG_ERROR([Missing OpenSSL functionality, make sure you have installed the latest version.]); break], | ||||
|     [#include <openssl/evp.h>] | ||||
|   ) | ||||
|  |  | |||
|  | @ -1,96 +0,0 @@ | |||
| /*
 | ||||
|     ecdh.c -- Diffie-Hellman key exchange handling | ||||
|     Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org> | ||||
| 
 | ||||
|     This program is free software; you can redistribute it and/or modify | ||||
|     it under the terms of the GNU General Public License as published by | ||||
|     the Free Software Foundation; either version 2 of the License, or | ||||
|     (at your option) any later version. | ||||
| 
 | ||||
|     This program is distributed in the hope that it will be useful, | ||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|     GNU General Public License for more details. | ||||
| 
 | ||||
|     You should have received a copy of the GNU General Public License along | ||||
|     with this program; if not, write to the Free Software Foundation, Inc., | ||||
|     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
| */ | ||||
| 
 | ||||
| #include "../system.h" | ||||
| 
 | ||||
| #include <openssl/err.h> | ||||
| #include <openssl/ec.h> | ||||
| #include <openssl/ecdh.h> | ||||
| #include <openssl/obj_mac.h> | ||||
| 
 | ||||
| #define __TINC_ECDH_INTERNAL__ | ||||
| typedef EC_KEY ecdh_t; | ||||
| 
 | ||||
| #include "../ecdh.h" | ||||
| #include "../logger.h" | ||||
| #include "../utils.h" | ||||
| #include "../xalloc.h" | ||||
| 
 | ||||
| ecdh_t *ecdh_generate_public(void *pubkey) { | ||||
| 	ecdh_t *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1); | ||||
| 	if(!ecdh) { | ||||
| 		logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if(!EC_KEY_generate_key(ecdh)) { | ||||
| 		EC_KEY_free(ecdh); | ||||
| 		logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	const EC_POINT *point = EC_KEY_get0_public_key(ecdh); | ||||
| 	if(!point) { | ||||
| 		EC_KEY_free(ecdh); | ||||
| 		logger(DEBUG_ALWAYS, LOG_ERR, "Getting public key failed: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	size_t result = EC_POINT_point2oct(EC_KEY_get0_group(ecdh), point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL); | ||||
| 	if(!result) { | ||||
| 		EC_KEY_free(ecdh); | ||||
| 		logger(DEBUG_ALWAYS, LOG_ERR, "Converting EC_POINT to binary failed: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	return ecdh; | ||||
| } | ||||
| 
 | ||||
| bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { | ||||
| 	EC_POINT *point = EC_POINT_new(EC_KEY_get0_group(ecdh)); | ||||
| 	if(!point) { | ||||
| 		logger(DEBUG_ALWAYS, LOG_ERR, "EC_POINT_new() failed: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 		EC_KEY_free(ecdh); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	int result = EC_POINT_oct2point(EC_KEY_get0_group(ecdh), point, pubkey, ECDH_SIZE, NULL); | ||||
| 	if(!result) { | ||||
| 		EC_POINT_free(point); | ||||
| 		EC_KEY_free(ecdh); | ||||
| 		logger(DEBUG_ALWAYS, LOG_ERR, "Converting binary to EC_POINT failed: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	result = ECDH_compute_key(shared, ECDH_SIZE, point, ecdh, NULL); | ||||
| 	EC_POINT_free(point); | ||||
| 	EC_KEY_free(ecdh); | ||||
| 
 | ||||
| 	if(!result) { | ||||
| 		logger(DEBUG_ALWAYS, LOG_ERR, "Computing Elliptic Curve Diffie-Hellman shared key failed: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| void ecdh_free(ecdh_t *ecdh) { | ||||
| 	if(ecdh) | ||||
| 		EC_KEY_free(ecdh); | ||||
| } | ||||
|  | @ -1,131 +0,0 @@ | |||
| /*
 | ||||
|     ecdsa.c -- ECDSA key handling | ||||
|     Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org> | ||||
| 
 | ||||
|     This program is free software; you can redistribute it and/or modify | ||||
|     it under the terms of the GNU General Public License as published by | ||||
|     the Free Software Foundation; either version 2 of the License, or | ||||
|     (at your option) any later version. | ||||
| 
 | ||||
|     This program is distributed in the hope that it will be useful, | ||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|     GNU General Public License for more details. | ||||
| 
 | ||||
|     You should have received a copy of the GNU General Public License along | ||||
|     with this program; if not, write to the Free Software Foundation, Inc., | ||||
|     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
| */ | ||||
| 
 | ||||
| #include "../system.h" | ||||
| 
 | ||||
| #include <openssl/pem.h> | ||||
| #include <openssl/err.h> | ||||
| 
 | ||||
| #define __TINC_ECDSA_INTERNAL__ | ||||
| typedef EC_KEY ecdsa_t; | ||||
| 
 | ||||
| #include "../logger.h" | ||||
| #include "../ecdsa.h" | ||||
| #include "../utils.h" | ||||
| #include "../xalloc.h" | ||||
| 
 | ||||
| // Get and set ECDSA keys
 | ||||
| //
 | ||||
| ecdsa_t *ecdsa_set_base64_public_key(const char *p) { | ||||
| 	ecdsa_t *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); | ||||
| 	if(!ecdsa) { | ||||
| 		logger(DEBUG_ALWAYS, LOG_DEBUG, "EC_KEY_new_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	int len = strlen(p); | ||||
| 	unsigned char pubkey[len / 4 * 3 + 3]; | ||||
| 	const unsigned char *ppubkey = pubkey; | ||||
| 	len = b64decode(p, (char *)pubkey, len); | ||||
| 
 | ||||
| 	if(!o2i_ECPublicKey(&ecdsa, &ppubkey, len)) { | ||||
| 		logger(DEBUG_ALWAYS, LOG_DEBUG, "o2i_ECPublicKey failed: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 		EC_KEY_free(ecdsa); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 
 | ||||
| 	return ecdsa; | ||||
| } | ||||
| 
 | ||||
| char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { | ||||
| 	unsigned char *pubkey = NULL; | ||||
| 	int len = i2o_ECPublicKey(ecdsa, &pubkey); | ||||
| 
 | ||||
| 	char *base64 = xmalloc(len * 4 / 3 + 5); | ||||
| 	b64encode((char *)pubkey, base64, len); | ||||
| 
 | ||||
| 	free(pubkey); | ||||
| 
 | ||||
| 	return base64; | ||||
| } | ||||
| 
 | ||||
| // Read PEM ECDSA keys
 | ||||
| 
 | ||||
| ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { | ||||
| 	ecdsa_t *ecdsa = PEM_read_EC_PUBKEY(fp, NULL, NULL, NULL); | ||||
| 
 | ||||
| 	if(!ecdsa) | ||||
| 		logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 
 | ||||
| 	return ecdsa; | ||||
| } | ||||
| 
 | ||||
| ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { | ||||
| 	ecdsa_t *ecdsa = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL); | ||||
| 
 | ||||
| 	if(!ecdsa) | ||||
| 		logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 
 | ||||
| 	return ecdsa; | ||||
| } | ||||
| 
 | ||||
| size_t ecdsa_size(ecdsa_t *ecdsa) { | ||||
| 	return ECDSA_size(ecdsa); | ||||
| } | ||||
| 
 | ||||
| // TODO: standardise output format?
 | ||||
| 
 | ||||
| bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { | ||||
| 	unsigned int siglen = ECDSA_size(ecdsa); | ||||
| 
 | ||||
| 	unsigned char hash[SHA512_DIGEST_LENGTH]; | ||||
| 	SHA512(in, len, hash); | ||||
| 
 | ||||
| 	memset(sig, 0, siglen); | ||||
| 
 | ||||
| 	if(!ECDSA_sign(0, hash, sizeof hash, sig, &siglen, ecdsa)) { | ||||
| 		logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_sign() failed: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { | ||||
| 	unsigned int siglen = ECDSA_size(ecdsa); | ||||
| 
 | ||||
| 	unsigned char hash[SHA512_DIGEST_LENGTH]; | ||||
| 	SHA512(in, len, hash); | ||||
| 
 | ||||
| 	if(!ECDSA_verify(0, hash, sizeof hash, sig, siglen, ecdsa)) { | ||||
| 		logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_verify() failed: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| bool ecdsa_active(ecdsa_t *ecdsa) { | ||||
| 	return ecdsa; | ||||
| } | ||||
| 
 | ||||
| void ecdsa_free(ecdsa_t *ecdsa) { | ||||
| 	if(ecdsa) | ||||
| 		EC_KEY_free(ecdsa); | ||||
| } | ||||
|  | @ -1,58 +0,0 @@ | |||
| /*
 | ||||
|     ecdsagen.c -- ECDSA key generation and export | ||||
|     Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org> | ||||
| 
 | ||||
|     This program is free software; you can redistribute it and/or modify | ||||
|     it under the terms of the GNU General Public License as published by | ||||
|     the Free Software Foundation; either version 2 of the License, or | ||||
|     (at your option) any later version. | ||||
| 
 | ||||
|     This program is distributed in the hope that it will be useful, | ||||
|     but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|     GNU General Public License for more details. | ||||
| 
 | ||||
|     You should have received a copy of the GNU General Public License along | ||||
|     with this program; if not, write to the Free Software Foundation, Inc., | ||||
|     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||||
| */ | ||||
| 
 | ||||
| #include "../system.h" | ||||
| 
 | ||||
| #include <openssl/pem.h> | ||||
| #include <openssl/err.h> | ||||
| #include <openssl/obj_mac.h> | ||||
| 
 | ||||
| #define __TINC_ECDSA_INTERNAL__ | ||||
| typedef EC_KEY ecdsa_t; | ||||
| 
 | ||||
| #include "../ecdsagen.h" | ||||
| #include "../utils.h" | ||||
| #include "../xalloc.h" | ||||
| 
 | ||||
| // Generate ECDSA key
 | ||||
| 
 | ||||
| ecdsa_t *ecdsa_generate(void) { | ||||
| 	ecdsa_t *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); | ||||
| 
 | ||||
| 	if(!ecdsa || !EC_KEY_generate_key(ecdsa)) { | ||||
| 		fprintf(stderr, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); | ||||
| 		ecdsa_free(ecdsa); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	EC_KEY_set_asn1_flag(ecdsa, OPENSSL_EC_NAMED_CURVE); | ||||
| 	EC_KEY_set_conv_form(ecdsa, POINT_CONVERSION_COMPRESSED); | ||||
| 
 | ||||
| 	return ecdsa; | ||||
| } | ||||
| 
 | ||||
| // Write PEM ECDSA keys
 | ||||
| 
 | ||||
| bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { | ||||
| 	return PEM_write_EC_PUBKEY(fp, ecdsa); | ||||
| } | ||||
| 
 | ||||
| bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { | ||||
| 	return PEM_write_ECPrivateKey(fp, ecdsa, NULL, NULL, 0, NULL, NULL); | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue