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.  

 

Diff revision 4

This is not the most recent revision of the diff. The latest diff is revision 5. See what's changed.

1 2 3 4 5
1 2 3 4 5

  1. /trunk/funcs/func_aes.c: Loading...
/trunk/funcs/func_aes.c
New File

    
   
1
/*

    
   
2
 * Asterisk -- An open source telephony toolkit.

    
   
3
 *

    
   
4
 * Copyright (C) 2009, Digium, Inc.

    
   
5
 *

    
   
6
 * See http://www.asterisk.org for more information about

    
   
7
 * the Asterisk project. Please do not directly contact

    
   
8
 * any of the maintainers of this project for assistance;

    
   
9
 * the project provides a web site, mailing lists and IRC

    
   
10
 * channels for your use.

    
   
11
 *

    
   
12
 * This program is free software, distributed under the terms of

    
   
13
 * the GNU General Public License Version 2. See the LICENSE file

    
   
14
 * at the top of the source tree.

    
   
15
 */

    
   
16

   

    
   
17
/*! \file

    
   
18
 *

    
   
19
 * \brief AES encryption/decryption dialplan functions

    
   
20
 *

    
   
21
 * \author David Vossel <dvossel@digium.com>

    
   
22
 * \ingroup functions

    
   
23
 */

    
   
24

   

    
   
25

   

    
   
26
#include "asterisk.h"

    
   
27

   

    
   
28
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")

    
   
29

   

    
   
30
#include "asterisk/module.h"

    
   
31
#include "asterisk/pbx.h"

    
   
32
#include "asterisk/app.h"

    
   
33
#include "asterisk/aes.h"

    
   
34

   

    
   
35
#define AES_BLOCK_SIZE 16

    
   
36

   

    
   
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,

    
   
75
	       char *buf, size_t len)

    
   
76
{

    
   
77
	unsigned char curblock[AES_BLOCK_SIZE] = { 0, };

    
   
78
	char *tmp;

    
   
79
	char *tmpP;

    
   
80
	int data_len, encrypt;

    
   
81
	ast_aes_encrypt_key ecx;                        /*  AES 128 Encryption context */

    
   
82
	ast_aes_decrypt_key dcx;

    
   
83

   

    
   
84
	AST_DECLARE_APP_ARGS(args,

    
   
85
		AST_APP_ARG(key);

    
   
86
		AST_APP_ARG(data);

    
   
87
	);

    
   
88

   

    
   
89
	AST_STANDARD_APP_ARGS(args, data);

    
   
90

   

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

    
   
92
		ast_log(LOG_WARNING, "Syntax: %s(<key>,<data>) - missing argument!\n", cmd);

    
   
93
		return -1;

    
   
94
	}

    
   
95

   

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

    
   
97
		ast_log(LOG_WARNING, "Syntax: %s(<key>,<data>) - <key> parameter must be exactly 16 characters!\n", cmd);

    
   
98
		return -1;

    
   
99
	}

    
   
100

   

    
   
101
	ast_aes_encrypt_key(args.key, &ecx);   /* encryption:  plaintext -> encyptedtext -> base64 */

    
   
102
	ast_aes_decrypt_key(args.key, &dcx);   /* decryption:  base64 -> encyptedtext -> plaintext */

    
   
103
	tmp = ast_calloc(1, len);                     /* requires a tmp buffer for the base64 decode */

    
   
104
	tmpP = tmp;

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

    
   
106

   

    
   
107
	if (encrypt) {                                  /* if decrypting first decode src to base64 */

    
   
108
		memcpy(tmp, args.data, strlen(args.data));  /* use same tmp buffer for encrypt as well to keep things simple */

    
   
109
		data_len = strlen(tmp);

    
   
110
	} else {

    
   
111
		ast_base64decode((unsigned char *) tmp, args.data, len);

    
   
112
		data_len = strlen(tmp);

    
   
113
	}

    
   
114

   

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

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

    
   
117
		data_len = len - 1;

    
   
118
	}

    
   
119

   

    
   
120
	while (data_len > 0) {

    
   
121
		memset(curblock, 0, AES_BLOCK_SIZE);

    
   
122
		memcpy(curblock, tmpP, (data_len < AES_BLOCK_SIZE) ? data_len : AES_BLOCK_SIZE);

    
   
123
		if (encrypt == 0) {

    
   
124
			ast_aes_encrypt(curblock, tmpP, &ecx);

    
   
125
		} else {

    
   
126
			ast_aes_decrypt(curblock, tmpP, &dcx);

    
   
127
		}

    
   
128
		tmpP += AES_BLOCK_SIZE;

    
   
129
		data_len -= AES_BLOCK_SIZE;

    
   
130
	}

    
   
131

   

    
   
132
	if (encrypt) {                            /* if encrypting encode result to base64 */

    
   
133
		ast_base64encode(buf, (unsigned char *) tmp, len, len);

    
   
134
	} else {

    
   
135
		memcpy(buf, tmp, len);

    
   
136
	}

    
   
137
	free(tmp);

    
   
138

   

    
   
139
	return 0;

    
   
140
}

    
   
141

   

    
   
142
static struct ast_custom_function aes_encrypt_function = {

    
   
143
	.name = "AES_ENCRYPT",

    
   
144
	.read = aes_helper,

    
   
145
};

    
   
146

   

    
   
147
static struct ast_custom_function aes_decrypt_function = {

    
   
148
	.name = "AES_DECRYPT",

    
   
149
	.read = aes_helper,

    
   
150
};

    
   
151

   

    
   
152

   

    
   
153
static int unload_module(void)

    
   
154
{

    
   
155
	int res = ast_custom_function_unregister(&aes_decrypt_function);

    
   
156
	return res | ast_custom_function_unregister(&aes_encrypt_function);

    
   
157
}

    
   
158

   

    
   
159
static int load_module(void)

    
   
160
{

    
   
161
	int res = ast_custom_function_register(&aes_decrypt_function);

    
   
162
	res |= ast_custom_function_register(&aes_encrypt_function);

    
   
163
	return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;

    
   
164
}

    
   
165

   

    
   
166
AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "AES dialplan functions");
  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.