aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-09-18 03:59:51 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-09-18 03:59:51 +0000
commit4fcbfbedea878e22848d235acda3e08a67e5b047 (patch)
tree2312ff86b75e85d7a846b8661d5e20ebacc5c0aa
parent904af1c1a97d99e4351ccbed0457da52f0dc7041 (diff)
Add extra checks for keys and convenience encrypt/decrypt functions
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@3803 f38db490-d61c-443f-a65b-d21fe96a405b
-rwxr-xr-xinclude/asterisk/crypto.h23
-rwxr-xr-xres/res_crypto.c71
2 files changed, 86 insertions, 8 deletions
diff --git a/include/asterisk/crypto.h b/include/asterisk/crypto.h
index 227957a9b..dff70e6b0 100755
--- a/include/asterisk/crypto.h
+++ b/include/asterisk/crypto.h
@@ -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
diff --git a/res/res_crypto.c b/res/res_crypto.c
index 9da1c48b1..6152d42b0 100755
--- a/res/res_crypto.c
+++ b/res/res_crypto.c
@@ -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];