summaryrefslogtreecommitdiffstats
path: root/src/crypto.c
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-07-07 11:42:57 -0400
committerSimo Sorce <simo@redhat.com>2014-07-09 05:14:36 -0400
commitf9cd5e4ba41b112804f824f460108cfb743526e0 (patch)
treeefd2bcf51da456f9097fbdc8fa2465f05b2f5422 /src/crypto.c
parent285432d9f918c45a1746d0f569eee727aaa9673b (diff)
downloadmod_auth_gssapi-sessions.tar.gz
mod_auth_gssapi-sessions.tar.xz
mod_auth_gssapi-sessions.zip
Add permanent session keys supportsessions
Keys (encryption+MAC) can now be stored in apache configuration. The key must be a base64 encoded blob of original length of 32 bytes (16 bytes for encryption and 16 for the MAC key) The format is: key:<base64 blob>
Diffstat (limited to 'src/crypto.c')
-rw-r--r--src/crypto.c65
1 files changed, 41 insertions, 24 deletions
diff --git a/src/crypto.c b/src/crypto.c
index 9be58e5..584bf16 100644
--- a/src/crypto.c
+++ b/src/crypto.c
@@ -13,56 +13,73 @@ struct seal_key {
unsigned char *hkey;
};
-apr_status_t SEAL_KEY_CREATE(struct seal_key **skey)
+apr_status_t SEAL_KEY_CREATE(apr_pool_t *p, struct seal_key **skey,
+ struct databuf *keys)
{
struct seal_key *n;
+ int keylen;
int ret;
- n = calloc(1, sizeof(*n));
+ n = apr_pcalloc(p, sizeof(*n));
if (!n) return ENOMEM;
n->cipher = EVP_aes_128_cbc();
if (!n->cipher) {
- free(n);
- return EFAULT;
+ ret = EFAULT;
+ goto done;
}
+ keylen = n->cipher->key_len;
+
n->md = EVP_sha256();
if (!n->md) {
- free(n);
- return EFAULT;
+ ret = EFAULT;
+ goto done;
}
- n->ekey = malloc(n->cipher->key_len);
+ n->ekey = apr_palloc(p, keylen);
if (!n->ekey) {
- free(n);
- return ENOMEM;
+ ret = ENOMEM;
+ goto done;
}
- n->hkey = malloc(n->cipher->key_len);
+ n->hkey = apr_palloc(p, keylen);
if (!n->hkey) {
- free(n);
- return ENOMEM;
+ ret = ENOMEM;
+ goto done;
}
- ret = RAND_bytes(n->ekey, n->cipher->key_len);
- if (ret == 0) {
- free(n->ekey);
- free(n->hkey);
- free(n);
- return EFAULT;
+ if (keys) {
+ if (keys->length != (keylen * 2)) {
+ ret = EINVAL;
+ goto done;
+ }
+ memcpy(n->ekey, keys->value, keylen);
+ memcpy(n->hkey, keys->value + keylen, keylen);
+ } else {
+ ret = RAND_bytes(n->ekey, keylen);
+ if (ret == 0) {
+ ret = EFAULT;
+ goto done;
+ }
+
+ ret = RAND_bytes(n->hkey, keylen);
+ if (ret == 0) {
+ ret = EFAULT;
+ goto done;
+ }
}
- ret = RAND_bytes(n->hkey, n->cipher->key_len);
- if (ret == 0) {
+ ret = 0;
+done:
+ if (ret) {
free(n->ekey);
free(n->hkey);
free(n);
- return EFAULT;
+ } else {
+ *skey = n;
}
-
- *skey = n;
- return 0;
+ return ret;
}
apr_status_t SEAL_BUFFER(apr_pool_t *p, struct seal_key *skey,