Add extra checks for keys and convenience encrypt/decrypt functions
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3803 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
parent
d1be79cce2
commit
574d3785ab
|
@ -85,6 +85,29 @@ extern int ast_sign(struct ast_key *key, char *msg, char *sig);
|
|||
*/
|
||||
extern int ast_sign_bin(struct ast_key *key, char *msg, int msglen, unsigned char *sig);
|
||||
|
||||
/*!
|
||||
* \param key a private key to use to encrypt
|
||||
* \param src the message to encrypt
|
||||
* \param srclen the length of the message to encrypt
|
||||
* \param dst a pointer to a buffer of at least srclen * 1.5 bytes in which the encrypted
|
||||
* answer will be stored
|
||||
*
|
||||
* Returns length of encrypted data on success or -1 on failure.
|
||||
*
|
||||
*/
|
||||
extern int ast_encrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key);
|
||||
|
||||
/*!
|
||||
* \param key a private key to use to decrypt
|
||||
* \param src the message to decrypt
|
||||
* \param srclen the length of the message to decrypt
|
||||
* \param dst a pointer to a buffer of at least srclen bytes in which the decrypted
|
||||
* answer will be stored
|
||||
*
|
||||
* Returns length of decrypted data on success or -1 on failure.
|
||||
*
|
||||
*/
|
||||
extern int ast_decrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key);
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -233,13 +233,16 @@ static struct ast_key *try_load_key (char *dir, char *fname, int ifd, int ofd, i
|
|||
key->rsa = PEM_read_RSAPrivateKey(f, NULL, pw_cb, key);
|
||||
fclose(f);
|
||||
if (key->rsa) {
|
||||
/* Key loaded okay */
|
||||
key->ktype &= ~KEY_NEEDS_PASSCODE;
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Loaded %s key '%s'\n", key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "Key '%s' loaded OK\n", key->name);
|
||||
key->delme = 0;
|
||||
if (RSA_size(key->rsa) == 128) {
|
||||
/* Key loaded okay */
|
||||
key->ktype &= ~KEY_NEEDS_PASSCODE;
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Loaded %s key '%s'\n", key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
|
||||
if (option_debug)
|
||||
ast_log(LOG_DEBUG, "Key '%s' loaded OK\n", key->name);
|
||||
key->delme = 0;
|
||||
} else
|
||||
ast_log(LOG_NOTICE, "Key '%s' is not expected size.\n", key->name);
|
||||
} else if (key->infd != -2) {
|
||||
ast_log(LOG_WARNING, "Key load %s '%s' failed\n",key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
|
||||
if (ofd > -1) {
|
||||
|
@ -303,7 +306,7 @@ int ast_sign_bin(struct ast_key *key, char *msg, int msglen, unsigned char *dsig
|
|||
int res;
|
||||
|
||||
if (key->ktype != AST_KEY_PRIVATE) {
|
||||
ast_log(LOG_WARNING, "Cannot sign with a private key\n");
|
||||
ast_log(LOG_WARNING, "Cannot sign with a public key\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -327,6 +330,58 @@ int ast_sign_bin(struct ast_key *key, char *msg, int msglen, unsigned char *dsig
|
|||
|
||||
}
|
||||
|
||||
extern int ast_decrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
|
||||
{
|
||||
int res;
|
||||
int pos = 0;
|
||||
if (key->ktype != AST_KEY_PRIVATE) {
|
||||
ast_log(LOG_WARNING, "Cannot decrypt with a public key\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (srclen % 128) {
|
||||
ast_log(LOG_NOTICE, "Tried to decrypt something not a multiple of 128 bytes\n");
|
||||
return -1;
|
||||
}
|
||||
while(srclen) {
|
||||
/* Process chunks 128 bytes at a time */
|
||||
res = RSA_private_decrypt(128, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING);
|
||||
if (res < 0)
|
||||
return -1;
|
||||
pos += res;
|
||||
src += 128;
|
||||
srclen -= 128;
|
||||
dst += res;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
extern int ast_encrypt_bin(unsigned char *dst, const unsigned char *src, int srclen, struct ast_key *key)
|
||||
{
|
||||
int res;
|
||||
int bytes;
|
||||
int pos = 0;
|
||||
if (key->ktype != AST_KEY_PUBLIC) {
|
||||
ast_log(LOG_WARNING, "Cannot encrypt with a private key\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(srclen) {
|
||||
bytes = srclen;
|
||||
if (bytes > 128 - 41)
|
||||
bytes = 128 - 41;
|
||||
/* Process chunks 128 bytes at a time */
|
||||
res = RSA_private_encrypt(bytes, src, dst, key->rsa, RSA_PKCS1_OAEP_PADDING);
|
||||
if (res != 128)
|
||||
return -1;
|
||||
src += 128 - 41;
|
||||
srclen -= 128 - 41;
|
||||
pos += res;
|
||||
dst += res;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
int ast_sign(struct ast_key *key, char *msg, char *sig)
|
||||
{
|
||||
unsigned char dsig[128];
|
||||
|
|
Loading…
Reference in New Issue