diff options
author | Simo Sorce <simo@redhat.com> | 2014-07-07 11:42:57 -0400 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2014-07-09 05:14:36 -0400 |
commit | f9cd5e4ba41b112804f824f460108cfb743526e0 (patch) | |
tree | efd2bcf51da456f9097fbdc8fa2465f05b2f5422 /src/crypto.c | |
parent | 285432d9f918c45a1746d0f569eee727aaa9673b (diff) | |
download | mod_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.c | 65 |
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, |