diff options
author | Simo Sorce <simo@redhat.com> | 2016-07-01 10:30:42 -0400 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2016-07-06 16:16:22 -0400 |
commit | 86aaf37e4ca95145512c56e3643bcbcb0e534b57 (patch) | |
tree | ccc92f2597f15894848be2c5c850345b82eb5c7f /src | |
parent | 7156420b179143f969cf5edf898385327f4d5e84 (diff) | |
download | mod_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.c | 107 |
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; } |