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 2 and 3

1 2 3 4 5
1 2 3 4 5

  1. /trunk/funcs/func_aes.c: Loading...
/trunk/funcs/func_aes.c
Diff Revision 2 Diff Revision 3
1
/*
1
/*
2
 * Asterisk -- An open source telephony toolkit.
2
 * Asterisk -- An open source telephony toolkit.
3
 *
3
 *
4
 * Copyright (C) 1999-2009, Digium, Inc.
4
 * Copyright (C) 2009, Digium, Inc.
5
 *
5
 *
6
 * See http://www.asterisk.org for more information about
6
 * See http://www.asterisk.org for more information about
7
 * the Asterisk project. Please do not directly contact
7
 * the Asterisk project. Please do not directly contact
8
 * any of the maintainers of this project for assistance;
8
 * any of the maintainers of this project for assistance;
9
 * the project provides a web site, mailing lists and IRC
9
 * the project provides a web site, mailing lists and IRC
[+20] [20] 20 lines
[+20] [+] ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
30
#include "asterisk/module.h"
30
#include "asterisk/module.h"
31
#include "asterisk/pbx.h"
31
#include "asterisk/pbx.h"
32
#include "asterisk/app.h"
32
#include "asterisk/app.h"
33
#include "asterisk/aes.h"
33
#include "asterisk/aes.h"
34

    
   
34

   

    
   
35
#define AES_BLOCK_SIZE 16
35

    
   
36

   
36
static int aes_encrypt_read(struct ast_channel *chan, const char *cmd, char *data,
37
/*** DOCUMENTATION

    
   
38
	<function name="AES_ENCRYPT" language="en_US">

    
   
39
		<synopsis>

    
   
40
			Encrypt a string with AES given a 16 character key.

    
   
41
		</synopsis>

    
   
42
		<syntax>

    
   
43
			<parameter name="string" required="true">

    
   
44
				<para>Input string</para>

    
   
45
			</parameter>

    
   
46
			<parameter name="key" required="true">

    
   
47
				<para>AES Key</para>

    
   
48
			</parameter>

    
   
49
		</syntax>

    
   
50
		<description>

    
   
51
			<para>Returns an AES encrypted string encoded in base64.</para>

    
   
52
		</description>

    
   
53
	</function>

    
   
54
	<function name="AES_DECRYPT" language="en_US">

    
   
55
		<synopsis>

    
   
56
			Decrypt a string encoded in base64 with AES given a 16 character key.

    
   
57
		</synopsis>

    
   
58
		<syntax>

    
   
59
			<parameter name="string" required="true">

    
   
60
				<para>Input string.</para>

    
   
61
			</parameter>

    
   
62
			<parameter name="key" required="true">

    
   
63
				<para>AES Key</para>

    
   
64
			</parameter>

    
   
65

   

    
   
66
		</syntax>

    
   
67
		<description>

    
   
68
			<para>Returns the plain text string.</para>

    
   
69
		</description>

    
   
70
	</function>

    
   
71
 ***/

    
   
72

   

    
   
73

   

    
   
74
static int aes_helper(struct ast_channel *chan, const char *cmd, char *data,
37
	       char *buf, size_t len)
75
	       char *buf, size_t len)
38
{
76
{
39
	unsigned char curblock[16] = { 0, };
77
	unsigned char curblock[AES_BLOCK_SIZE] = { 0, };
40
	char *src;
78
	char *src;
41
	char *dst;
79
	char *dst;
42
	int data_len;
80
	char *result;

    
   
81
	int data_len, encrypt;
43
	ast_aes_encrypt_key ecx;                       /*  AES 128 Encryption context */
82
	ast_aes_encrypt_key ecx;                       /*  AES 128 Encryption context */

    
   
83
	ast_aes_decrypt_key dcx;
44

    
   
84

   
45
	AST_DECLARE_APP_ARGS(args,
85
	AST_DECLARE_APP_ARGS(args,
46
		AST_APP_ARG(key);
86
		AST_APP_ARG(key);
47
		AST_APP_ARG(data);
87
		AST_APP_ARG(data);
48
	);
88
	);
49

    
   
89

   
50
	AST_STANDARD_APP_ARGS(args, data);
90
	AST_STANDARD_APP_ARGS(args, data);
51

    
   
91

   
52
	if (ast_strlen_zero(args.data) || ast_strlen_zero(args.key)) {
92
	if (ast_strlen_zero(args.data) || ast_strlen_zero(args.key)) {
53
		ast_log(LOG_WARNING, "Syntax: AES_ENCRYPT(<key>,<data>) - missing argument!\n");
93
		ast_log(LOG_WARNING, "Syntax: %s(<key>,<data>) - missing argument!\n", cmd);
54
		return -1;
94
		return -1;
55
	}
95
	}
56

    
   
96

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

    
   
101

   
62
	ast_aes_encrypt_key(args.key, &ecx);
102
	ast_aes_encrypt_key(args.key, &ecx);
63

    
   
103
	ast_aes_decrypt_key(args.key, &dcx);
64
	dst = buf;
104
	result = ast_calloc(1, len);			/* separate result buffer required due to base64 decode/encode */

    
   
105
	dst = result;

    
   
106
	encrypt = strcmp("AES_ENCRYPT", cmd);            /* 0 if encrypting, -1 if decrypting */

    
   
107

   

    
   
108
	if (encrypt != 0) {				/* if decrypting first decode src to base64 */

    
   
109
		src = ast_calloc(1, len);

    
   
110
		ast_base64decode((unsigned char *) src, args.data, len);

    
   
111
		data_len = strlen(src);

    
   
112
	} else {
65
	src = args.data;
113
		src = args.data;
66
	data_len = strlen(args.data);
114
		data_len = strlen(src);

    
   
115
	}
67

    
   
116

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

    
   
121

   
73
	while (data_len > 0) {
122
	while (data_len > 0) {
74
		memset(curblock,0,sizeof(curblock));
123
		memset(curblock, 0, sizeof(curblock));
75
		if (data_len < 16) {
124
		memcpy(curblock, src, (data_len < AES_BLOCK_SIZE) ? data_len : AES_BLOCK_SIZE);
76
			memcpy(curblock,src,data_len);
125
		if (encrypt == 0) {
77
		} else {

   
78
			memcpy(curblock,src,16);

   
79
		}

   
80
		ast_aes_encrypt(curblock, dst, &ecx);
126
			ast_aes_encrypt(curblock, dst, &ecx);
81
		dst += 16;
127
		} else {
82
		src += 16;
128
			ast_aes_decrypt(curblock, dst, &dcx);
83
		data_len -= 16;

   
84
	}

   
85

    
   

   
86
	return 0;

   
87
}

   
88
static int aes_decrypt_read(struct ast_channel *chan, const char *cmd, char *data,

   
89
	char *buf, size_t len)

   
90
{

   
91
	unsigned char curblock[16] = { 0, };

   
92
	char *src;

   
93
	char *dst;

   
94
	int data_len;

   
95
	ast_aes_decrypt_key dcx;                       /*!< AES 128 Encryption context */

   
96

    
   

   
97
	AST_DECLARE_APP_ARGS(args,

   
98
			AST_APP_ARG(key);

   
99
			AST_APP_ARG(data);

   
100
	);

   
101

    
   

   
102
	AST_STANDARD_APP_ARGS(args, data);

   
103

    
   

   
104
	if (ast_strlen_zero(args.data) || ast_strlen_zero(args.key)) {

   
105
		ast_log(LOG_WARNING, "Syntax: AES_DECRYPT(<key>,<data>) - missing argument!\n");

   
106
		return -1;

   
107
	}

   
108

    
   

   
109
	if (strlen(args.key) != 16 ) {         /* key must be of 16 characters in length, 128 bits */

   
110
		ast_log(LOG_WARNING, "Syntax: AES_DECRYPT(<key>,<data>) - <key> parameter must be exactly 16 characters!\n");

   
111
		return -1;

   
112
	}
129
		}
113

    
   
130
		dst += AES_BLOCK_SIZE;
114
	ast_aes_decrypt_key(args.key, &dcx);
131
		src += AES_BLOCK_SIZE;
115

    
   
132
		data_len -= AES_BLOCK_SIZE;
116
	dst = buf;

   
117
	src = args.data;

   
118
	data_len = strlen(args.data);

   
119

    
   

   
120
	if (data_len >= len) {                       /* make sure to not go over buffer len */

   
121
		ast_log(LOG_WARNING, "Syntax: AES_DECRYPT(<keys>,<data>) - <data> exceeds buffer length.  Result may be truncated!\n");

   
122
		data_len = len - 1;

   
123
	}
133
	}
124

    
   
134

   
125
	while (data_len > 0) {
135
	if (encrypt == 0) { 				/* if encrypting encode result to base64 */
126
		memset(curblock,0,sizeof(curblock));
136
		ast_base64encode(buf, (unsigned char *) result, strlen(result), len);
127
		if (data_len < 16) {

   
128
			memcpy(curblock,src,data_len);

   
129
		} else {
137
	} else {
130
			memcpy(curblock,src,16);
138
		memcpy(buf, result, len);
131
		}

   
132
		ast_aes_decrypt(curblock, dst, &dcx);

   
133
		dst += 16;

   
134
		src += 16;

   
135
		data_len -= 16;

   
136
	}
139
	}
137

    
   
140

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

    
   
143

   
141
static struct ast_custom_function aes_encrypt_function = {
144
static struct ast_custom_function aes_encrypt_function = {
142
	.name = "AES_ENCRYPT",
145
	.name = "AES_ENCRYPT",
143
	.read = aes_encrypt_read,
146
	.read = aes_helper,
144
};
147
};
145

    
   
148

   
146
static struct ast_custom_function aes_decrypt_function = {
149
static struct ast_custom_function aes_decrypt_function = {
147
	.name = "AES_DECRYPT",
150
	.name = "AES_DECRYPT",
148
	.read = aes_decrypt_read,
151
	.read = aes_helper,
149
};
152
};
150

    
   
153

   
151

    
   
154

   
152
static int unload_module(void)
155
static int unload_module(void)
153
{
156
{
[+20] [20] 12 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.