Browse Source

crypto: aes encrypt/decrypt based on event_route[crypto:netio]

Daniel-Constantin Mierla 5 years ago
parent
commit
6f7b04d62e

+ 48 - 0
src/modules/crypto/crypto_aes.c

@@ -19,6 +19,54 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../../core/dprint.h"
+
+#include "crypto_aes.h"
+
+static char _crypto_salt[CRYPTO_SALT_BSIZE];
+static int _crypto_salt_set = 0;
+
+/**
+ *
+ */
+int crypto_set_salt(char *psalt)
+{
+	int i;
+	char k;
+
+	memset(_crypto_salt, 0, CRYPTO_SALT_BSIZE*sizeof(char));
+	if(psalt!=NULL) {
+		if(strlen(psalt)<8) {
+			LM_ERR("salt parameter must be at least 8 characters\n");
+			return -1;
+		}
+		k = 97;
+		for(i=0; i<strlen(psalt); i++) {
+			if(i>=CRYPTO_SALT_BSIZE) break;
+			_crypto_salt[i] = (psalt[i]*7 + k + k*(i+1))%0xff;
+			k = _crypto_salt[i];
+		}
+		_crypto_salt_set = 1;
+	}
+	return 0;
+}
+
+/**
+ *
+ */
+char *crypto_get_salt(void)
+{
+	if(_crypto_salt_set == 0) {
+		return NULL;
+	}
+	return _crypto_salt;
+}
+
 /**
  * Create an 256 bit key and IV using the supplied key_data and salt.
  * Fills in the encryption and decryption ctx objects and returns 0 on success

+ 6 - 0
src/modules/crypto/crypto_aes.h

@@ -24,6 +24,12 @@
 
 #include <openssl/evp.h>
 
+#define AES_BLOCK_SIZE 256
+#define CRYPTO_SALT_BSIZE 16
+
+int crypto_set_salt(char *psalt);
+char *crypto_get_salt(void);
+
 int crypto_aes_init(unsigned char *key_data, int key_data_len,
 		unsigned char *salt, EVP_CIPHER_CTX *e_ctx, EVP_CIPHER_CTX *d_ctx);
 

+ 102 - 4
src/modules/crypto/crypto_evcb.c

@@ -33,6 +33,7 @@
 #include "../../core/events.h"
 #include "../../core/onsend.h"
 
+#include "crypto_aes.h"
 
 #define CRYPTO_NIO_OUT (1<<0)
 #define CRYPTO_NIO_ENCRYPT (1<<1)
@@ -111,6 +112,10 @@ int crypto_exec_evroute(crypto_env_t *evenv, int rt, str *kevcb, str *rtname)
 	}
 	fmsg = &tmsg;
 
+	if(evenv->evp->rcv != NULL) {
+		fmsg->rcv = *evenv->evp->rcv;
+	}
+
 	if(evenv->mflags & CRYPTO_NIO_OUT) {
 		onsnd_info.to = &evenv->evp->dst->to;
 		onsnd_info.send_sock = evenv->evp->dst->send_sock;
@@ -152,6 +157,9 @@ int crypto_nio_received(sr_event_param_t *evp)
 {
 	int ret;
 	crypto_env_t evenv;
+	EVP_CIPHER_CTX *de=NULL;
+	str dtext;
+	str *obuf;
 
 	memset(&evenv, 0, sizeof(crypto_env_t));
 
@@ -162,10 +170,51 @@ int crypto_nio_received(sr_event_param_t *evp)
 
 	LM_DBG("sent event callback - ret:%d - flags:%d\n", ret, evenv.mflags);
 
-	if(evenv.mflags & CRYPTO_NIO_DECRYPT) {
-		LM_DBG("decrypting\n");
+	if(!(evenv.mflags & CRYPTO_NIO_DECRYPT)) {
+		goto done;
+	}
+	LM_DBG("decrypting\n");
+
+	de = EVP_CIPHER_CTX_new();
+	if(de==NULL) {
+		LM_ERR("cannot get new cipher context\n");
+		return -1;
+	}
+
+	/* gen key and iv. init the cipher ctx object */
+	if (crypto_aes_init((unsigned char *)_crypto_netio_key.s, _crypto_netio_key.len,
+				(unsigned char*)crypto_get_salt(), NULL, de)) {
+		EVP_CIPHER_CTX_free(de);
+		LM_ERR("couldn't initialize AES cipher\n");
+		return -1;
+	}
+
+	obuf = (str*)evp->data;
+	dtext.len = obuf->len;
+	dtext.s = (char *)crypto_aes_decrypt(de, (unsigned char *)obuf->s,
+			&dtext.len);
+	if(dtext.s==NULL) {
+		EVP_CIPHER_CTX_free(de);
+		LM_ERR("AES decryption failed\n");
+		return -1;
+	}
+
+	if(dtext.len>=BUF_SIZE) {
+		LM_ERR("new buffer overflow (%d)\n", dtext.len);
+		free(dtext.s);
+		EVP_CIPHER_CTX_free(de);
+		return -1;
 	}
 
+	obuf->len = dtext.len;
+	memcpy(obuf->s, dtext.s, obuf->len);
+	obuf->s[obuf->len] = '\0';
+
+	EVP_CIPHER_CTX_cleanup(de);
+	EVP_CIPHER_CTX_free(de);
+	free(dtext.s);
+
+done:
     return 0;
 }
 
@@ -176,6 +225,10 @@ int crypto_nio_sent(sr_event_param_t *evp)
 {
 	int ret;
 	crypto_env_t evenv;
+	EVP_CIPHER_CTX *en = NULL;
+	str etext;
+	str nbuf;
+	str *obuf;
 
 	memset(&evenv, 0, sizeof(crypto_env_t));
 
@@ -187,10 +240,55 @@ int crypto_nio_sent(sr_event_param_t *evp)
 
 	LM_DBG("sent event callback - ret:%d - flags:%d\n", ret, evenv.mflags);
 
-	if(evenv.mflags & CRYPTO_NIO_ENCRYPT) {
-		LM_DBG("encrypting\n");
+	if(!(evenv.mflags & CRYPTO_NIO_ENCRYPT)) {
+		goto done;
 	}
 
+	LM_DBG("encrypting\n");
+	en = EVP_CIPHER_CTX_new();
+	if(en==NULL) {
+		LM_ERR("cannot get new cipher context\n");
+		return -1;
+	}
+
+	/* gen key and iv. init the cipher ctx object */
+	if (crypto_aes_init((unsigned char *)_crypto_netio_key.s, _crypto_netio_key.len,
+				(unsigned char*)crypto_get_salt(), en, NULL)) {
+		EVP_CIPHER_CTX_free(en);
+		LM_ERR("couldn't initialize AES cipher\n");
+		return -1;
+	}
+
+	obuf = (str*)evp->data;
+
+	etext.len = obuf->len;
+	etext.s = (char *)crypto_aes_encrypt(en, (unsigned char *)obuf->s, &etext.len);
+	if(etext.s==NULL) {
+		EVP_CIPHER_CTX_free(en);
+		LM_ERR("AES encryption failed\n");
+		return -1;
+	}
+
+	nbuf.s = (char*)pkg_malloc(etext.len + 1);
+	if(nbuf.s==NULL) {
+		EVP_CIPHER_CTX_free(en);
+		PKG_MEM_ERROR;
+		free(etext.s);
+		return -1;
+	}
+	pkg_free(obuf->s);
+	nbuf.len = etext.len;
+	memcpy(nbuf.s, etext.s, nbuf.len);
+	nbuf.s[nbuf.len] = '\0';
+
+	EVP_CIPHER_CTX_cleanup(en);
+	EVP_CIPHER_CTX_free(en);
+	free(etext.s);
+
+	obuf->s = nbuf.s;
+	obuf->len = nbuf.len;
+
+done:
 	return 0;
 }
 

+ 9 - 22
src/modules/crypto/crypto_mod.c

@@ -38,10 +38,6 @@
 #include "crypto_evcb.h"
 #include "api.h"
 
-
-
-#define AES_BLOCK_SIZE 256
-
 MODULE_VERSION
 
 int crypto_aes_init(unsigned char *key_data, int key_data_len,
@@ -65,8 +61,6 @@ static int w_crypto_nio_out(sip_msg_t* msg, char* p1, char* p2);
 static int w_crypto_nio_encrypt(sip_msg_t* msg, char* p1, char* p2);
 static int w_crypto_nio_decrypt(sip_msg_t* msg, char* p1, char* p2);
 
-#define CRYPTO_SALT_BSIZE	16
-static char _crypto_salt[CRYPTO_SALT_BSIZE];
 static char *_crypto_salt_param = "k8hTm4aZ";
 
 static int _crypto_register_callid = 0;
@@ -121,23 +115,15 @@ struct module_exports exports = {
  */
 static int mod_init(void)
 {
-	int i;
-	char k;
-	memset(_crypto_salt, 0, CRYPTO_SALT_BSIZE*sizeof(char));
+
 	if(_crypto_salt_param==NULL || _crypto_salt_param[0]==0) {
 		_crypto_salt_param = NULL;
-	} else {
-		if(strlen(_crypto_salt_param)<8) {
-			LM_ERR("salt parameter must be at least 8 characters\n");
-			return -1;
-		}
-		k = 97;
-		for(i=0; i<strlen(_crypto_salt_param); i++) {
-			if(i>=CRYPTO_SALT_BSIZE) break;
-			_crypto_salt[i] = (_crypto_salt_param[i]*7 + k + k*(i+1))%0xff;
-			k = _crypto_salt[i];
-		}
 	}
+
+	if(crypto_set_salt(_crypto_salt_param) < 0) {
+		return -1;
+	}
+
 	if(_crypto_register_callid!=0) {
 		if(crypto_init_callid()<0) {
 			LM_ERR("failed to init callid callback\n");
@@ -149,6 +135,7 @@ static int mod_init(void)
 		}
 		LM_DBG("registered crypto callid callback\n");
 	}
+
 	if(_crypto_register_evcb!=0) {
 		crypto_evcb_enable();
 	}
@@ -195,7 +182,7 @@ static int ki_crypto_aes_encrypt_helper(sip_msg_t* msg, str *ins, str *keys,
 
 	/* gen key and iv. init the cipher ctx object */
 	if (crypto_aes_init((unsigned char *)keys->s, keys->len,
-				(unsigned char*)((_crypto_salt_param)?_crypto_salt:0), en, NULL)) {
+				(unsigned char*)crypto_get_salt(), en, NULL)) {
 		EVP_CIPHER_CTX_free(en);
 		LM_ERR("couldn't initialize AES cipher\n");
 		return -1;
@@ -314,7 +301,7 @@ static int ki_crypto_aes_decrypt_helper(sip_msg_t* msg, str *ins, str *keys,
 
 	/* gen key and iv. init the cipher ctx object */
 	if (crypto_aes_init((unsigned char *)keys->s, keys->len,
-				(unsigned char*)((_crypto_salt_param)?_crypto_salt:0), NULL, de)) {
+				(unsigned char*)crypto_get_salt(), NULL, de)) {
 		EVP_CIPHER_CTX_free(de);
 		LM_ERR("couldn't initialize AES cipher\n");
 		return -1;