summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2016-07-01 10:30:42 -0400
committerSimo Sorce <simo@redhat.com>2016-07-06 16:16:22 -0400
commit86aaf37e4ca95145512c56e3643bcbcb0e534b57 (patch)
treeccc92f2597f15894848be2c5c850345b82eb5c7f /src
parent7156420b179143f969cf5edf898385327f4d5e84 (diff)
downloadmod_auth_gssapi-86aaf37e4ca95145512c56e3643bcbcb0e534b57.tar.gz
mod_auth_gssapi-86aaf37e4ca95145512c56e3643bcbcb0e534b57.tar.xz
mod_auth_gssapi-86aaf37e4ca95145512c56e3643bcbcb0e534b57.zip
Add compatibility with OpenSSL 1.1.0
In their continued wisdom OpenSSL developers keep breaking APIs left and right with very poor documentation and forward/backward source compatibility. Signed-off-by: Simo Sorce <simo@redhat.com> Closes #96 Closes #97
Diffstat (limited to 'src')
-rw-r--r--src/crypto.c107
1 files changed, 76 insertions, 31 deletions
diff --git a/src/crypto.c b/src/crypto.c
index 7f9097f..e1257db 100644
--- a/src/crypto.c
+++ b/src/crypto.c
@@ -6,6 +6,48 @@
#include <stdbool.h>
#include "crypto.h"
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+HMAC_CTX *HMAC_CTX_new(void)
+{
+ HMAC_CTX *ctx;
+
+ ctx = OPENSSL_malloc(sizeof(HMAC_CTX));
+ if (!ctx) return NULL;
+
+ HMAC_CTX_init(ctx);
+
+ return ctx;
+}
+
+void HMAC_CTX_free(HMAC_CTX *ctx)
+{
+ if (ctx == NULL) return;
+
+ HMAC_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+}
+
+EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void)
+{
+ EVP_CIPHER_CTX *ctx;
+
+ ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX));
+ if (!ctx) return NULL;
+
+ EVP_CIPHER_CTX_init(ctx);
+
+ return ctx;
+}
+
+void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
+{
+ if (ctx == NULL) return;
+
+ EVP_CIPHER_CTX_cleanup(ctx);
+ OPENSSL_free(ctx);
+}
+#endif
+
struct seal_key {
const EVP_CIPHER *cipher;
const EVP_MD *md;
@@ -29,7 +71,7 @@ apr_status_t SEAL_KEY_CREATE(apr_pool_t *p, struct seal_key **skey,
goto done;
}
- keylen = n->cipher->key_len;
+ keylen = EVP_CIPHER_key_length(n->cipher);
n->md = EVP_sha256();
if (!n->md) {
@@ -81,24 +123,25 @@ done:
apr_status_t HMAC_BUFFER(struct seal_key *skey, struct databuf *buffer,
struct databuf *result)
{
- HMAC_CTX hmac_ctx = { 0 };
+ HMAC_CTX *hmac_ctx;
unsigned int len;
- int ret;
+ int ret = 0;
/* now MAC the buffer */
- HMAC_CTX_init(&hmac_ctx);
+ hmac_ctx = HMAC_CTX_new();
+ if (!hmac_ctx) goto done;
- ret = HMAC_Init_ex(&hmac_ctx, skey->hkey,
- skey->cipher->key_len, skey->md, NULL);
+ ret = HMAC_Init_ex(hmac_ctx, skey->hkey,
+ EVP_CIPHER_key_length(skey->cipher), skey->md, NULL);
if (ret == 0) goto done;
- ret = HMAC_Update(&hmac_ctx, buffer->value, buffer->length);
+ ret = HMAC_Update(hmac_ctx, buffer->value, buffer->length);
if (ret == 0) goto done;
- ret = HMAC_Final(&hmac_ctx, result->value, &len);
+ ret = HMAC_Final(hmac_ctx, result->value, &len);
done:
- HMAC_CTX_cleanup(&hmac_ctx);
+ HMAC_CTX_free(hmac_ctx);
if (ret == 0) return EFAULT;
result->length = len;
@@ -108,15 +151,15 @@ done:
apr_status_t SEAL_BUFFER(apr_pool_t *p, struct seal_key *skey,
struct databuf *plain, struct databuf *cipher)
{
- int blksz = skey->cipher->block_size;
+ int blksz = EVP_CIPHER_block_size(skey->cipher);
apr_status_t err = EFAULT;
- EVP_CIPHER_CTX ctx = { 0 };
+ EVP_CIPHER_CTX *ctx;
uint8_t rbuf[blksz];
struct databuf hmacbuf;
int outlen, totlen;
int ret;
- EVP_CIPHER_CTX_init(&ctx);
+ ctx = EVP_CIPHER_CTX_new();
/* confounder to avoid exposing random numbers directly to clients
* as IVs */
@@ -126,30 +169,30 @@ apr_status_t SEAL_BUFFER(apr_pool_t *p, struct seal_key *skey,
if (cipher->length == 0) {
/* add space for confounder and padding and MAC */
cipher->length = (plain->length / blksz + 2) * blksz;
- cipher->value = apr_palloc(p, cipher->length + skey->md->md_size);
+ cipher->value = apr_palloc(p, cipher->length + EVP_MD_size(skey->md));
if (!cipher->value) {
err = ENOMEM;
goto done;
}
}
- ret = EVP_EncryptInit_ex(&ctx, skey->cipher, NULL, skey->ekey, NULL);
+ ret = EVP_EncryptInit_ex(ctx, skey->cipher, NULL, skey->ekey, NULL);
if (ret == 0) goto done;
totlen = 0;
outlen = cipher->length;
- ret = EVP_EncryptUpdate(&ctx, cipher->value, &outlen, rbuf, sizeof(rbuf));
+ ret = EVP_EncryptUpdate(ctx, cipher->value, &outlen, rbuf, sizeof(rbuf));
if (ret == 0) goto done;
totlen += outlen;
outlen = cipher->length - totlen;
- ret = EVP_EncryptUpdate(&ctx, &cipher->value[totlen], &outlen,
+ ret = EVP_EncryptUpdate(ctx, &cipher->value[totlen], &outlen,
plain->value, plain->length);
if (ret == 0) goto done;
totlen += outlen;
outlen = cipher->length - totlen;
- ret = EVP_EncryptFinal_ex(&ctx, &cipher->value[totlen], &outlen);
+ ret = EVP_EncryptFinal_ex(ctx, &cipher->value[totlen], &outlen);
if (ret == 0) goto done;
totlen += outlen;
@@ -163,7 +206,7 @@ apr_status_t SEAL_BUFFER(apr_pool_t *p, struct seal_key *skey,
err = 0;
done:
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
return err;
}
@@ -171,28 +214,30 @@ apr_status_t UNSEAL_BUFFER(apr_pool_t *p, struct seal_key *skey,
struct databuf *cipher, struct databuf *plain)
{
apr_status_t err = EFAULT;
- EVP_CIPHER_CTX ctx = { 0 };
- unsigned char mac[skey->md->md_size];
+ EVP_CIPHER_CTX *ctx = NULL;
+ int blksz = EVP_CIPHER_block_size(skey->cipher);
+ int md_size = EVP_MD_size(skey->md);
+ unsigned char mac[md_size];
struct databuf hmacbuf;
int outlen, totlen;
volatile bool equal = true;
int ret, i;
/* check MAC first */
- cipher->length -= skey->md->md_size;
+ cipher->length -= md_size;
hmacbuf.value = mac;
ret = HMAC_BUFFER(skey, cipher, &hmacbuf);
if (ret != 0) goto done;
- if (hmacbuf.length != skey->md->md_size) goto done;
- for (i = 0; i < skey->md->md_size; i++) {
+ if (hmacbuf.length != md_size) goto done;
+ for (i = 0; i < md_size; i++) {
if (cipher->value[cipher->length + i] != mac[i]) equal = false;
/* not breaking intentionally,
* or we would allow an oracle attack */
}
if (!equal) goto done;
- EVP_CIPHER_CTX_init(&ctx);
+ ctx = EVP_CIPHER_CTX_new();
if (plain->length == 0) {
plain->length = cipher->length;
@@ -203,37 +248,37 @@ apr_status_t UNSEAL_BUFFER(apr_pool_t *p, struct seal_key *skey,
}
}
- ret = EVP_DecryptInit_ex(&ctx, skey->cipher, NULL, skey->ekey, NULL);
+ ret = EVP_DecryptInit_ex(ctx, skey->cipher, NULL, skey->ekey, NULL);
if (ret == 0) goto done;
totlen = 0;
outlen = plain->length;
- ret = EVP_DecryptUpdate(&ctx, plain->value, &outlen,
+ ret = EVP_DecryptUpdate(ctx, plain->value, &outlen,
cipher->value, cipher->length);
if (ret == 0) goto done;
totlen += outlen;
outlen = plain->length - totlen;
- ret = EVP_DecryptFinal_ex(&ctx, plain->value, &outlen);
+ ret = EVP_DecryptFinal_ex(ctx, plain->value, &outlen);
if (ret == 0) goto done;
totlen += outlen;
/* now remove the confounder */
- totlen -= skey->cipher->block_size;
- memmove(plain->value, plain->value + skey->cipher->block_size, totlen);
+ totlen -= blksz;
+ memmove(plain->value, plain->value + blksz, totlen);
plain->length = totlen;
err = 0;
done:
- EVP_CIPHER_CTX_cleanup(&ctx);
+ EVP_CIPHER_CTX_free(ctx);
return err;
}
int get_mac_size(struct seal_key *skey)
{
if (skey) {
- return skey->md->md_size;
+ return EVP_MD_size(skey->md);
} else {
return 0;
}