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:
Mark Spencer 2004-09-18 03:59:51 +00:00
parent d1be79cce2
commit 574d3785ab
2 changed files with 86 additions and 8 deletions

View File

@ -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

View File

@ -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];