Asterisk - The Open Source Telephony Project GIT-master-a358458
Data Structures | Macros | Typedefs | Functions
crypto.h File Reference

Provide cryptographic signature routines. More...

#include "asterisk/optional_api.h"
#include "asterisk/logger.h"
Include dependency graph for crypto.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  aes_key
 

Macros

#define AST_CRYPTO_AES_BLOCKSIZE   128
 
#define AST_CRYPTO_RSA_KEY_BITS   1024
 
#define AST_KEY_PRIVATE   (1 << 1)
 
#define AST_KEY_PUBLIC   (1 << 0)
 

Typedefs

typedef struct aes_key ast_aes_decrypt_key
 
typedef struct aes_key ast_aes_encrypt_key
 

Functions

int ast_aes_decrypt (const unsigned char *in, unsigned char *out, const ast_aes_decrypt_key *key)
 AES decrypt data. More...
 
int ast_aes_encrypt (const unsigned char *in, unsigned char *out, const ast_aes_encrypt_key *key)
 AES encrypt data. More...
 
int ast_aes_set_decrypt_key (const unsigned char *key, ast_aes_decrypt_key *ctx)
 Set a decryption key. More...
 
int ast_aes_set_encrypt_key (const unsigned char *key, ast_aes_encrypt_key *ctx)
 Set an encryption key. More...
 
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. More...
 
int ast_check_signature_bin (struct ast_key *key, const char *msg, int msglen, const unsigned char *dsig)
 Check the authenticity of a message signature using a given public key. More...
 
int ast_crypto_loaded (void)
 
int ast_crypto_reload (void)
 
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. More...
 
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. More...
 
struct ast_keyast_key_get (const char *kname, int ktype)
 Retrieve a key. More...
 
int ast_sign (struct ast_key *key, char *msg, char *sig)
 Sign a message signature using a given private key. More...
 
int ast_sign_bin (struct ast_key *key, const char *msg, int msglen, unsigned char *dsig)
 Sign a message signature using a given private key. More...
 

Detailed Description

Provide cryptographic signature routines.

Definition in file crypto.h.

Macro Definition Documentation

◆ AST_CRYPTO_AES_BLOCKSIZE

#define AST_CRYPTO_AES_BLOCKSIZE   128

Definition at line 37 of file crypto.h.

◆ AST_CRYPTO_RSA_KEY_BITS

#define AST_CRYPTO_RSA_KEY_BITS   1024

Definition at line 36 of file crypto.h.

◆ AST_KEY_PRIVATE

#define AST_KEY_PRIVATE   (1 << 1)

Definition at line 47 of file crypto.h.

◆ AST_KEY_PUBLIC

#define AST_KEY_PUBLIC   (1 << 0)

Definition at line 46 of file crypto.h.

Typedef Documentation

◆ ast_aes_decrypt_key

typedef struct aes_key ast_aes_decrypt_key

Definition at line 44 of file crypto.h.

◆ ast_aes_encrypt_key

typedef struct aes_key ast_aes_encrypt_key

Definition at line 43 of file crypto.h.

Function Documentation

◆ ast_aes_decrypt()

int ast_aes_decrypt ( const unsigned char *  in,
unsigned char *  out,
const ast_aes_decrypt_key key 
)

AES decrypt data.

Parameters
inencrypted data
outpointer to a buffer to hold the decrypted output
keypointer to the ast_aes_decrypt_key to use for decryption
Return values
<=0 failure
otherwisenumber of bytes in output buffer

Definition at line 790 of file res_crypto.c.

791{
792 int res;
793
794 if ((res = evp_cipher_aes_decrypt(in, out, AST_CRYPTO_AES_BLOCKSIZE / 8, key)) <= 0) {
795 ast_log(LOG_ERROR, "AES decryption failed\n");
796 }
797 return res;
798}
#define ast_log
Definition: astobj2.c:42
#define AST_CRYPTO_AES_BLOCKSIZE
Definition: crypto.h:37
#define LOG_ERROR
static int evp_cipher_aes_decrypt(const unsigned char *in, unsigned char *out, unsigned inlen, const ast_aes_decrypt_key *key)
Definition: res_crypto.c:759
FILE * out
Definition: utils/frame.c:33
FILE * in
Definition: utils/frame.c:33

References AST_CRYPTO_AES_BLOCKSIZE, ast_log, evp_cipher_aes_decrypt(), in, LOG_ERROR, and out.

Referenced by aes_helper(), AST_TEST_DEFINE(), decrypt_memcpy(), and memcpy_decrypt().

◆ ast_aes_encrypt()

int ast_aes_encrypt ( const unsigned char *  in,
unsigned char *  out,
const ast_aes_encrypt_key key 
)

AES encrypt data.

Parameters
indata to be encrypted
outpointer to a buffer to hold the encrypted output
keypointer to the ast_aes_encrypt_key to use for encryption
Return values
<=0 failure
otherwisenumber of bytes in output buffer

Definition at line 749 of file res_crypto.c.

750{
751 int res;
752
753 if ((res = evp_cipher_aes_encrypt(in, out, AST_CRYPTO_AES_BLOCKSIZE / 8, key)) <= 0) {
754 ast_log(LOG_ERROR, "AES encryption failed\n");
755 }
756 return res;
757}
static int evp_cipher_aes_encrypt(const unsigned char *in, unsigned char *out, unsigned inlen, const ast_aes_encrypt_key *key)
Definition: res_crypto.c:718

References AST_CRYPTO_AES_BLOCKSIZE, ast_log, evp_cipher_aes_encrypt(), in, LOG_ERROR, and out.

Referenced by aes_helper(), AST_TEST_DEFINE(), encrypt_memcpy(), and memcpy_encrypt().

◆ ast_aes_set_decrypt_key()

int ast_aes_set_decrypt_key ( const unsigned char *  key,
ast_aes_decrypt_key ctx 
)

Set a decryption key.

Parameters
keya 16 char key
ctxaddress of an aes encryption context
Return values
0success
nonzerofailure

Definition at line 709 of file res_crypto.c.

710{
711 if (key == NULL || ctx == NULL) {
712 return -1;
713 }
714 memcpy(ctx->raw, key, AST_CRYPTO_AES_BLOCKSIZE / 8);
715 return 0;
716}
#define NULL
Definition: resample.c:96
unsigned char raw[AST_CRYPTO_AES_BLOCKSIZE/8]
Definition: crypto.h:40

References AST_CRYPTO_AES_BLOCKSIZE, and NULL.

Referenced by aes_helper(), AST_TEST_DEFINE(), build_ecx_key(), build_encryption_keys(), check_key(), socket_process_helper(), and update_key().

◆ ast_aes_set_encrypt_key()

int ast_aes_set_encrypt_key ( const unsigned char *  key,
ast_aes_encrypt_key ctx 
)

Set an encryption key.

Parameters
keya 16 char key
ctxaddress of an aes encryption context
Return values
0success
nonzerofailure

Definition at line 700 of file res_crypto.c.

701{
702 if (key == NULL || ctx == NULL) {
703 return -1;
704 }
705 memcpy(ctx->raw, key, AST_CRYPTO_AES_BLOCKSIZE / 8);
706 return 0;
707}

References AST_CRYPTO_AES_BLOCKSIZE, and NULL.

Referenced by aes_helper(), AST_TEST_DEFINE(), build_ecx_key(), check_key(), and update_key().

◆ ast_check_signature()

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.

Parameters
keya public key to use to verify
msgthe message that has been signed
sigthe proposed valid signature in mime64-like encoding
Return values
0if the signature is valid.
-1otherwise.

Check the authenticity of a message signature using a given public key.

See also
ast_check_signature

Definition at line 673 of file res_crypto.c.

674{
675 unsigned char dsig[128];
676 int res;
677
678 /* Decode signature */
679 if ((res = ast_base64decode(dsig, sig, sizeof(dsig))) != sizeof(dsig)) {
680 ast_log(LOG_WARNING, "Signature improper length (expect %d, got %d)\n", (int)sizeof(dsig), (int)res);
681 return -1;
682 }
683
684 res = ast_check_signature_bin(key, msg, strlen(msg), dsig);
685
686 return res;
687}
#define LOG_WARNING
int AST_OPTIONAL_API_NAME() ast_check_signature_bin(struct ast_key *key, const char *msg, int msglen, const unsigned char *dsig)
check signature of a message
Definition: res_crypto.c:634
int ast_base64decode(unsigned char *dst, const char *src, int max)
Decode data from base64.
Definition: utils.c:296

References ast_base64decode(), ast_check_signature_bin(), ast_log, and LOG_WARNING.

Referenced by authenticate_verify(), and register_verify().

◆ ast_check_signature_bin()

int ast_check_signature_bin ( struct ast_key key,
const char *  msg,
int  msglen,
const unsigned char *  dsig 
)

Check the authenticity of a message signature using a given public key.

Parameters
keya public key to use to verify
msgthe message that has been signed
msglen
dsigthe proposed valid signature in raw binary representation
Return values
0if the signature is valid.
-1otherwise.

Check the authenticity of a message signature using a given public key.

See also
ast_check_signature_bin

Definition at line 634 of file res_crypto.c.

635{
636 unsigned char digest[SHA_DIGEST_LENGTH];
637 unsigned digestlen;
638 int res;
639 EVP_MD_CTX *ctx = NULL;
640
641 if (key->ktype != AST_KEY_PUBLIC) {
642 /* Okay, so of course you really *can* but for our purposes
643 we're going to say you can't */
644 ast_log(LOG_WARNING, "Cannot check message signature with a private key\n");
645 return -1;
646 }
647
648 /* Calculate digest of message */
649 ctx = EVP_MD_CTX_create();
650 if (ctx == NULL) {
651 ast_log(LOG_ERROR, "Out of memory\n");
652 return -1;
653 }
654 EVP_DigestInit(ctx, EVP_sha1());
655 EVP_DigestUpdate(ctx, msg, msglen);
656 EVP_DigestFinal(ctx, digest, &digestlen);
657 EVP_MD_CTX_destroy(ctx);
658
659 /* Verify signature */
660 if (!(res = evp_pkey_verify(key->pkey, (const unsigned char *)digest, sizeof(digest), (unsigned char *)dsig, 128, RSA_PKCS1_PADDING))) {
661 ast_debug(1, "Key failed verification: %s\n", key->name);
662 return -1;
663 }
664
665 /* Pass */
666 return 0;
667}
#define AST_KEY_PUBLIC
Definition: crypto.h:46
#define ast_debug(level,...)
Log a DEBUG message.
static int evp_pkey_verify(EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, const unsigned char *sig, unsigned siglen, unsigned padding)
Definition: res_crypto.c:598
char name[80]
Definition: res_crypto.c:82
EVP_PKEY * pkey
Definition: res_crypto.c:88
int ktype
Definition: res_crypto.c:86

References ast_debug, AST_KEY_PUBLIC, ast_log, ast_key::digest, evp_pkey_verify(), ast_key::ktype, LOG_ERROR, LOG_WARNING, ast_key::name, NULL, and ast_key::pkey.

Referenced by ast_check_signature(), AST_TEST_DEFINE(), and check_key().

◆ ast_crypto_loaded()

int ast_crypto_loaded ( void  )

Definition at line 689 of file res_crypto.c.

690{
691 return 1;
692}

Referenced by AST_TEST_DEFINE().

◆ ast_crypto_reload()

int ast_crypto_reload ( void  )

Definition at line 694 of file res_crypto.c.

695{
696 crypto_load(-1, -1);
697 return 1;
698}
static void crypto_load(int ifd, int ofd)
refresh RSA keys from file
Definition: res_crypto.c:819

References crypto_load().

Referenced by AST_TEST_DEFINE().

◆ ast_decrypt_bin()

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.

Parameters
dsta pointer to a buffer of at least srclen bytes in which the decrypted
srcthe message to decrypt
srclenthe length of the message to decrypt
keya private key to use to decrypt answer will be stored
Return values
lengthof decrypted data on success.
-1on failure.

Decrypt a message using a given private key.

See also
ast_decrypt_bin

Definition at line 472 of file res_crypto.c.

473{
474 int res;
475 unsigned pos = 0, dstlen, blocksize;
476
477 if (key->ktype != AST_KEY_PRIVATE) {
478 ast_log(LOG_WARNING, "Cannot decrypt with a public key\n");
479 return -1;
480 }
481
482 blocksize = EVP_PKEY_size(key->pkey);
483
484 if (srclen % blocksize) {
485 ast_log(LOG_NOTICE, "Tried to decrypt something not a multiple of %u bytes\n", blocksize);
486 return -1;
487 }
488
489 while (srclen > 0) {
490 /* Process chunks 128 bytes at a time */
491 dstlen = blocksize;
492 if ((res = evp_pkey_decrypt(key->pkey, src, blocksize, dst, &dstlen, RSA_PKCS1_OAEP_PADDING)) <= 0) {
493 return -1;
494 }
495 pos += dstlen;
496 src += blocksize;
497 srclen -= blocksize;
498 dst += dstlen;
499 }
500
501 return pos;
502}
#define AST_KEY_PRIVATE
Definition: crypto.h:47
#define LOG_NOTICE
static int evp_pkey_decrypt(EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, unsigned char *out, unsigned *outlen, unsigned padding)
Definition: res_crypto.c:432

References AST_KEY_PRIVATE, ast_log, evp_pkey_decrypt(), ast_key::ktype, LOG_NOTICE, LOG_WARNING, and ast_key::pkey.

Referenced by AST_TEST_DEFINE(), and check_key().

◆ ast_encrypt_bin()

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.

Parameters
dsta pointer to a buffer of at least srclen * 1.5 bytes in which the encrypted
srcthe message to encrypt
srclenthe length of the message to encrypt
keya private key to use to encrypt answer will be stored
Return values
lengthof encrypted data on success.
-1on failure.

Encrypt a message using a given private key.

See also
ast_encrypt_bin

Definition at line 549 of file res_crypto.c.

550{
551 unsigned bytes, pos = 0, dstlen, blocksize;
552 int res;
553
554 if (key->ktype != AST_KEY_PUBLIC) {
555 ast_log(LOG_WARNING, "Cannot encrypt with a private key\n");
556 return -1;
557 }
558
559 blocksize = EVP_PKEY_size(key->pkey);
560
561 while (srclen) {
562 bytes = srclen;
563 if (bytes > blocksize - RSA_PKCS1_OAEP_PADDING_SIZE) {
564 bytes = blocksize - RSA_PKCS1_OAEP_PADDING_SIZE;
565 }
566 /* Process chunks 128-41 bytes at a time */
567 dstlen = blocksize;
568 if ((res = evp_pkey_encrypt(key->pkey, src, bytes, dst, &dstlen, RSA_PKCS1_OAEP_PADDING)) != blocksize) {
569 ast_log(LOG_NOTICE, "How odd, encrypted size is %d\n", res);
570 return -1;
571 }
572 src += bytes;
573 srclen -= bytes;
574 pos += dstlen;
575 dst += dstlen;
576 }
577 return pos;
578}
#define RSA_PKCS1_OAEP_PADDING_SIZE
Definition: res_crypto.c:78
static int evp_pkey_encrypt(EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, unsigned char *out, unsigned *outlen, unsigned padding)
Definition: res_crypto.c:504

References AST_KEY_PUBLIC, ast_log, evp_pkey_encrypt(), ast_key::ktype, LOG_NOTICE, LOG_WARNING, ast_key::pkey, and RSA_PKCS1_OAEP_PADDING_SIZE.

Referenced by AST_TEST_DEFINE(), and update_key().

◆ ast_key_get()

struct ast_key * ast_key_get ( const char *  kname,
int  ktype 
)

Retrieve a key.

Parameters
knameName of the key we are retrieving
ktypeIntger type of key (AST_KEY_PUBLIC or AST_KEY_PRIVATE)
Return values
thekey on success.
NULLon failure.

Retrieve a key.

See also
ast_key_get

Definition at line 149 of file res_crypto.c.

150{
151 struct ast_key *key;
152
154 AST_RWLIST_TRAVERSE(&keys, key, list) {
155 if (!strcmp(kname, key->name) &&
156 (ktype == key->ktype)) {
157 break;
158 }
159 }
161
162 return key;
163}
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition: linkedlists.h:78
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_key::ktype, and ast_key::name.

Referenced by AST_TEST_DEFINE(), authenticate(), authenticate_verify(), check_key(), register_verify(), and update_key().

◆ ast_sign()

int ast_sign ( struct ast_key key,
char *  msg,
char *  sig 
)

Sign a message signature using a given private key.

Parameters
keya private key to use to create the signature
msgthe message to sign
siga pointer to a buffer of at least 256 bytes in which the mime64-like encoded signature will be stored
Return values
0on success.
-1on failure.

Sign a message signature using a given private key.

See also
ast_sign

Definition at line 584 of file res_crypto.c.

585{
586 /* assumes 1024 bit RSA key size */
587 unsigned char dsig[128];
588 int siglen = sizeof(dsig), res;
589
590 if (!(res = ast_sign_bin(key, msg, strlen(msg), dsig))) {
591 /* Success -- encode (256 bytes max as documented) */
592 ast_base64encode(sig, dsig, siglen, 256);
593 }
594
595 return res;
596}
int AST_OPTIONAL_API_NAME() ast_sign_bin(struct ast_key *key, const char *msg, int msglen, unsigned char *dsig)
signs outgoing message with public key
Definition: res_crypto.c:390
int ast_base64encode(char *dst, const unsigned char *src, int srclen, int max)
Encode data in base64.
Definition: utils.c:406

References ast_base64encode(), and ast_sign_bin().

Referenced by authenticate().

◆ ast_sign_bin()

int ast_sign_bin ( struct ast_key key,
const char *  msg,
int  msglen,
unsigned char *  dsig 
)

Sign a message signature using a given private key.

Parameters
keya private key to use to create the signature
msgthe message to sign
msglen
dsiga pointer to a buffer of at least 128 bytes in which the raw encoded signature will be stored
Return values
0on success.
-1on failure.

Sign a message signature using a given private key.

See also
ast_sign_bin

Definition at line 390 of file res_crypto.c.

391{
392 unsigned char digest[SHA_DIGEST_LENGTH];
393 unsigned digestlen, siglen = 128;
394 int res;
395 EVP_MD_CTX *ctx = NULL;
396
397 if (key->ktype != AST_KEY_PRIVATE) {
398 ast_log(LOG_WARNING, "Cannot sign with a public key\n");
399 return -1;
400 }
401
402 if (siglen < EVP_PKEY_size(key->pkey)) {
403 ast_log(LOG_WARNING, "Signature buffer too small\n");
404 return -1;
405 }
406
407 /* Calculate digest of message */
408 ctx = EVP_MD_CTX_create();
409 if (ctx == NULL) {
410 ast_log(LOG_ERROR, "Out of memory\n");
411 return -1;
412 }
413 EVP_DigestInit(ctx, EVP_sha1());
414 EVP_DigestUpdate(ctx, msg, msglen);
415 EVP_DigestFinal(ctx, digest, &digestlen);
416 EVP_MD_CTX_destroy(ctx);
417
418 /* Verify signature */
419 if ((res = evp_pkey_sign(key->pkey, digest, sizeof(digest), dsig, &siglen, RSA_PKCS1_PADDING)) <= 0) {
420 ast_log(LOG_WARNING, "RSA Signature (key %s) failed %d\n", key->name, res);
421 return -1;
422 }
423
424 if (siglen != EVP_PKEY_size(key->pkey)) {
425 ast_log(LOG_WARNING, "Unexpected signature length %u, expecting %d\n", siglen, EVP_PKEY_size(key->pkey));
426 return -1;
427 }
428
429 return 0;
430}
static int evp_pkey_sign(EVP_PKEY *pkey, const unsigned char *in, unsigned inlen, unsigned char *sig, unsigned *siglen, unsigned padding)
Definition: res_crypto.c:351

References AST_KEY_PRIVATE, ast_log, ast_key::digest, evp_pkey_sign(), ast_key::ktype, LOG_ERROR, LOG_WARNING, ast_key::name, NULL, and ast_key::pkey.

Referenced by ast_sign(), AST_TEST_DEFINE(), and update_key().