38 #include "asterisk/paths.h"
39 #include <openssl/ssl.h>
40 #include <openssl/err.h>
41 #include <openssl/aes.h>
51 #define AST_API_MODULE
67 #define KEY_NEEDS_PASSCODE (1 << 16)
99 static
int pw_cb(
char *buf,
int size,
int rwflag,
void *userdata)
101 struct ast_key *key = (
struct ast_key *)userdata;
112 snprintf(prompt,
sizeof(prompt),
">>>> passcode for %s key '%s': ",
114 if (write(key->
outfd, prompt, strlen(prompt)) < 0) {
120 memset(buf, 0, size);
121 res = read(key->
infd, buf, size);
126 if (buf[strlen(buf) -1] ==
'\n') {
127 buf[strlen(buf) - 1] =
'\0';
142 if (!strcmp(kname, key->
name) &&
164 int ktype = 0, found = 0;
165 char *c = NULL, ffname[256];
170 static int notice = 0;
173 if ((c = strstr(fname,
".pub")) && !strcmp(c,
".pub")) {
175 }
else if ((c = strstr(fname,
".key")) && !strcmp(c,
".key")) {
182 snprintf(ffname,
sizeof(ffname),
"%s/%s", dir, fname);
185 if (!(f = fopen(ffname,
"r"))) {
194 if (!fgets(buf,
sizeof(buf), f)) {
198 MD5Update(&md5, (
unsigned char *) buf, strlen(buf));
205 if (!strcasecmp(key->
fn, ffname)) {
213 if (!memcmp(digest, key->
digest, 16) &&
242 memcpy(key->
digest, digest, 16);
250 key->
rsa = PEM_read_RSA_PUBKEY(f, NULL,
pw_cb, key);
252 key->
rsa = PEM_read_RSAPrivateKey(f, NULL,
pw_cb, key);
256 if (RSA_size(key->
rsa) == 128) {
265 }
else if (key->
infd != -2) {
268 ERR_print_errors_fp(stderr);
270 ERR_print_errors_fp(stderr);
277 ast_log(
LOG_NOTICE,
"Add the '-i' flag to the asterisk command line if you want to automatically initialize passcodes at launch.\n");
302 unsigned int siglen = 128;
311 SHA1((
unsigned char *)msg, msglen, digest);
314 if (!(res = RSA_sign(NID_sha1, digest,
sizeof(digest), dsig, &siglen, key->rsa))) {
320 ast_log(
LOG_WARNING,
"Unexpected signature length %d, expecting %d\n", (
int)siglen, (
int)128);
347 if ((res = RSA_private_decrypt(128, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING)) < 0) {
365 int res, bytes, pos = 0;
374 if (bytes > 128 - 41) {
378 if ((res = RSA_public_encrypt(bytes, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING)) != 128) {
396 unsigned char dsig[128];
397 int siglen =
sizeof(dsig), res;
399 if (!(res =
ast_sign_bin(key, msg, strlen(msg), dsig))) {
424 SHA1((
unsigned char *)msg, msglen, digest);
427 if (!(res = RSA_verify(NID_sha1, digest,
sizeof(digest), (
unsigned char *)dsig, 128, key->rsa))) {
428 ast_debug(1,
"Key failed verification: %s\n", key->name);
442 unsigned char dsig[128];
447 ast_log(
LOG_WARNING,
"Signature improper length (expect %d, got %d)\n", (
int)
sizeof(dsig), (
int)res);
463 return AES_set_encrypt_key(key, 128, ctx);
468 return AES_set_decrypt_key(key, 128, ctx);
473 return AES_encrypt(in, out, ctx);
478 return AES_decrypt(in, out, ctx);
503 while ((ent = readdir(dir))) {
512 ast_log(
LOG_NOTICE,
"Please run the command 'keys init' to enter the passcodes for the keys\n");
534 for (x = 0; x < 16; x++) {
535 sum += sprintf(sum,
"%02x", (
unsigned)*(md5++));
548 #define FORMAT "%-18s %-8s %-16s %-33s\n"
551 char sum[16 * 2 + 1];
559 " Displays information about RSA keys known by Asterisk\n";
566 ast_cli(a->
fd,
FORMAT,
"------------------",
"--------",
"----------------",
"--------------------------------");
578 ast_cli(a->
fd,
"\n%d known RSA keys.\n", count_keys);
596 char *kn, tmp[256] =
"";
603 " Initializes private keys (by reading in pass code from\n"
int ast_decrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
Decrypt a message using a given private key.
const char * ast_config_AST_KEY_DIR
static int load_module(void)
#define AST_CLI_DEFINE(fn, txt,...)
Asterisk locking-related definitions:
Asterisk main include file. File version handling, generic pbx functions.
int ast_check_signature_bin(struct ast_key *key, const char *msg, int msglen, const unsigned char *sig)
Check the authenticity of a message signature using a given public key.
int ast_crypto_loaded(void)
#define AST_RWLIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a read/write list of specified type, statically initialized...
int ast_aes_set_encrypt_key(const unsigned char *key, ast_aes_encrypt_key *ctx)
Set an encryption key.
static struct ast_key * try_load_key(const char *dir, const char *fname, int ifd, int ofd, int *not2)
load RSA key from file
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
descriptor for a cli entry.
int ast_hide_password(int fd)
Provide cryptographic signature routines.
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
void MD5Final(unsigned char digest[16], struct MD5Context *context)
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
I/O Management (derived from Cheops-NG)
void ast_cli(int fd, const char *fmt,...)
static char * handle_cli_keys_init(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
initialize all RSA keys
#define ast_opt_init_keys
#define ast_verb(level,...)
void MD5Init(struct MD5Context *context)
void ast_aes_decrypt(const unsigned char *in, unsigned char *out, const ast_aes_decrypt_key *ctx)
AES decrypt data.
static struct ast_cli_entry cli_crypto[]
static int unload_module(void)
int ast_restore_tty(int fd, int oldstatus)
Restores TTY mode. Call with result from previous ast_hide_password.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
AES_KEY ast_aes_encrypt_key
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
void ast_aes_encrypt(const unsigned char *in, unsigned char *out, const ast_aes_encrypt_key *ctx)
AES encrypt data.
#define ast_debug(level,...)
Log a DEBUG message.
int ast_encrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
Encrypt a message using a given private key.
int ast_sign_bin(struct ast_key *key, const char *msg, int msglen, unsigned char *sig)
Sign a message signature using a given private key.
#define AST_RWLIST_TRAVERSE
#define AST_RWLIST_REMOVE_CURRENT
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len)
static int md5(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
int ast_aes_set_decrypt_key(const unsigned char *key, ast_aes_decrypt_key *ctx)
Set a decryption key.
#define KEY_NEEDS_PASSCODE
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
static void md52sum(char *sum, unsigned char *md5)
int ast_sign(struct ast_key *key, char *msg, char *sig)
Sign a message signature using a given private key.
AES_KEY ast_aes_decrypt_key
static void crypto_load(int ifd, int ofd)
refresh RSA keys from file
static char * handle_cli_keys_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
show the list of RSA keys
#define AST_RWLIST_INSERT_TAIL
Standard Command Line Interface.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
int ast_check_signature(struct ast_key *key, const char *msg, const char *sig)
Check the authenticity of a message signature using a given public key.
#define AST_OPTIONAL_API_NAME(name)
static struct ast_str * prompt
static int pw_cb(char *buf, int size, int rwflag, void *userdata)
setting of priv key
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
#define AST_RWLIST_TRAVERSE_SAFE_END
struct ast_key * ast_key_get(const char *key, int type)
Retrieve a key.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
static int crypto_init(void)
initialise the res_crypto module