Review Board 1.7.16


added AES_ENCRYPT and AES_DECRYPT dialplan functions

Review Request #128 - Created Jan. 22, 2009 and submitted

David Vossel
trunk
0014301
Reviewers
asterisk-dev
mmichelson, russell
Asterisk
Allows data to be encrypted and decrypted using AES in the dialplan.  

 

Changes between revision 3 and 4

1 2 3 4 5
1 2 3 4 5

  1. /trunk/funcs/func_aes.c: Loading...
/trunk/funcs/func_aes.c
Diff Revision 3 Diff Revision 4
[20] 72 lines
[+20] [+] ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
73

    
   
73

   
74
static int aes_helper(struct ast_channel *chan, const char *cmd, char *data,
74
static int aes_helper(struct ast_channel *chan, const char *cmd, char *data,
75
	       char *buf, size_t len)
75
	       char *buf, size_t len)
76
{
76
{
77
	unsigned char curblock[AES_BLOCK_SIZE] = { 0, };
77
	unsigned char curblock[AES_BLOCK_SIZE] = { 0, };
78
	char *src;
78
	char *tmp;
79
	char *dst;
79
	char *tmpP;
80
	char *result;

   
81
	int data_len, encrypt;
80
	int data_len, encrypt;
82
	ast_aes_encrypt_key ecx;                       /*  AES 128 Encryption context */
81
	ast_aes_encrypt_key ecx;                        /*  AES 128 Encryption context */
83
	ast_aes_decrypt_key dcx;
82
	ast_aes_decrypt_key dcx;
84

    
   
83

   
85
	AST_DECLARE_APP_ARGS(args,
84
	AST_DECLARE_APP_ARGS(args,
86
		AST_APP_ARG(key);
85
		AST_APP_ARG(key);
87
		AST_APP_ARG(data);
86
		AST_APP_ARG(data);
[+20] [20] 4 lines
[+20] static int aes_helper(struct ast_channel *chan, const char *cmd, char *data,
92
	if (ast_strlen_zero(args.data) || ast_strlen_zero(args.key)) {
91
	if (ast_strlen_zero(args.data) || ast_strlen_zero(args.key)) {
93
		ast_log(LOG_WARNING, "Syntax: %s(<key>,<data>) - missing argument!\n", cmd);
92
		ast_log(LOG_WARNING, "Syntax: %s(<key>,<data>) - missing argument!\n", cmd);
94
		return -1;
93
		return -1;
95
	}
94
	}
96

    
   
95

   
97
	if (strlen(args.key) != AES_BLOCK_SIZE) {         /* key must be of 16 characters in length, 128 bits */
96
	if (strlen(args.key) != AES_BLOCK_SIZE) {        /* key must be of 16 characters in length, 128 bits */
98
		ast_log(LOG_WARNING, "Syntax: %s(<key>,<data>) - <key> parameter must be exactly 16 characters!\n", cmd);
97
		ast_log(LOG_WARNING, "Syntax: %s(<key>,<data>) - <key> parameter must be exactly 16 characters!\n", cmd);
99
		return -1;
98
		return -1;
100
	}
99
	}
101

    
   
100

   
102
	ast_aes_encrypt_key(args.key, &ecx);
101
	ast_aes_encrypt_key(args.key, &ecx);   /* encryption:  plaintext -> encyptedtext -> base64 */
103
	ast_aes_decrypt_key(args.key, &dcx);
102
	ast_aes_decrypt_key(args.key, &dcx);   /* decryption:  base64 -> encyptedtext -> plaintext */
104
	result = ast_calloc(1, len);			/* separate result buffer required due to base64 decode/encode */
103
	tmp = ast_calloc(1, len);                     /* requires a tmp buffer for the base64 decode */
105
	dst = result;
104
	tmpP = tmp;
106
	encrypt = strcmp("AES_ENCRYPT", cmd);            /* 0 if encrypting, -1 if decrypting */
105
	encrypt = strcmp("AES_DECRYPT", cmd);           /* -1 if encrypting, 0 if decrypting */
107

    
   
106

   
108
	if (encrypt != 0) {				/* if decrypting first decode src to base64 */
107
	if (encrypt) {                                  /* if decrypting first decode src to base64 */
109
		src = ast_calloc(1, len);
108
		memcpy(tmp, args.data, strlen(args.data));  /* use same tmp buffer for encrypt as well to keep things simple */
110
		ast_base64decode((unsigned char *) src, args.data, len);
109
		data_len = strlen(tmp);
111
		data_len = strlen(src);

   
112
	} else {
110
	} else {
113
		src = args.data;
111
		ast_base64decode((unsigned char *) tmp, args.data, len);
114
		data_len = strlen(src);
112
		data_len = strlen(tmp);
115
	}
113
	}
116

    
   
114

   
117
	if (data_len >= len) {                           /* make sure to not go over buffer len */
115
	if (data_len >= len) {                        /* make sure to not go over buffer len */
118
		ast_log(LOG_WARNING, "Syntax: %s(<keys>,<data>) - <data> exceeds buffer length.  Result may be truncated!\n", cmd);
116
		ast_log(LOG_WARNING, "Syntax: %s(<keys>,<data>) - <data> exceeds buffer length.  Result may be truncated!\n", cmd);
119
		data_len = len - 1;
117
		data_len = len - 1;
120
	}
118
	}
121

    
   
119

   
122
	while (data_len > 0) {
120
	while (data_len > 0) {
123
		memset(curblock, 0, sizeof(curblock));
121
		memset(curblock, 0, AES_BLOCK_SIZE);
124
		memcpy(curblock, src, (data_len < AES_BLOCK_SIZE) ? data_len : AES_BLOCK_SIZE);
122
		memcpy(curblock, tmpP, (data_len < AES_BLOCK_SIZE) ? data_len : AES_BLOCK_SIZE);
125
		if (encrypt == 0) {
123
		if (encrypt == 0) {
126
			ast_aes_encrypt(curblock, dst, &ecx);
124
			ast_aes_encrypt(curblock, tmpP, &ecx);
127
		} else {
125
		} else {
128
			ast_aes_decrypt(curblock, dst, &dcx);
126
			ast_aes_decrypt(curblock, tmpP, &dcx);
129
		}
127
		}
130
		dst += AES_BLOCK_SIZE;
128
		tmpP += AES_BLOCK_SIZE;
131
		src += AES_BLOCK_SIZE;

   
132
		data_len -= AES_BLOCK_SIZE;
129
		data_len -= AES_BLOCK_SIZE;
133
	}
130
	}
134

    
   
131

   
135
	if (encrypt == 0) { 				/* if encrypting encode result to base64 */
132
	if (encrypt) {                            /* if encrypting encode result to base64 */
136
		ast_base64encode(buf, (unsigned char *) result, strlen(result), len);
133
		ast_base64encode(buf, (unsigned char *) tmp, len, len);
137
	} else {
134
	} else {
138
		memcpy(buf, result, len);
135
		memcpy(buf, tmp, len);
139
	}
136
	}

    
   
137
	free(tmp);
140

    
   
138

   
141
	return 0;
139
	return 0;
142
}
140
}
143

    
   
141

   
144
static struct ast_custom_function aes_encrypt_function = {
142
static struct ast_custom_function aes_encrypt_function = {
[+20] [20] 24 lines
  1. /trunk/funcs/func_aes.c: Loading...

https://reviewboard.asterisk.org/ runs on a server provided by Digium, Inc. and uses bandwidth donated to the open source Asterisk community by API Digital Communications in Huntsville, AL USA.
Please report problems with this site to asteriskteam@digium.com.