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);
|
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)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#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);
|
key->rsa = PEM_read_RSAPrivateKey(f, NULL, pw_cb, key);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
if (key->rsa) {
|
if (key->rsa) {
|
||||||
/* Key loaded okay */
|
if (RSA_size(key->rsa) == 128) {
|
||||||
key->ktype &= ~KEY_NEEDS_PASSCODE;
|
/* Key loaded okay */
|
||||||
if (option_verbose > 2)
|
key->ktype &= ~KEY_NEEDS_PASSCODE;
|
||||||
ast_verbose(VERBOSE_PREFIX_3 "Loaded %s key '%s'\n", key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
|
if (option_verbose > 2)
|
||||||
if (option_debug)
|
ast_verbose(VERBOSE_PREFIX_3 "Loaded %s key '%s'\n", key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
|
||||||
ast_log(LOG_DEBUG, "Key '%s' loaded OK\n", key->name);
|
if (option_debug)
|
||||||
key->delme = 0;
|
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) {
|
} else if (key->infd != -2) {
|
||||||
ast_log(LOG_WARNING, "Key load %s '%s' failed\n",key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
|
ast_log(LOG_WARNING, "Key load %s '%s' failed\n",key->ktype == AST_KEY_PUBLIC ? "PUBLIC" : "PRIVATE", key->name);
|
||||||
if (ofd > -1) {
|
if (ofd > -1) {
|
||||||
|
@ -303,7 +306,7 @@ int ast_sign_bin(struct ast_key *key, char *msg, int msglen, unsigned char *dsig
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (key->ktype != AST_KEY_PRIVATE) {
|
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;
|
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)
|
int ast_sign(struct ast_key *key, char *msg, char *sig)
|
||||||
{
|
{
|
||||||
unsigned char dsig[128];
|
unsigned char dsig[128];
|
||||||
|
|
Loading…
Reference in New Issue