1
0
mirror of https://git.code.sf.net/p/linux-ima/ima-evm-utils synced 2025-04-28 14:43:37 +02:00

ima-evm-utils: Add backward compatible support for openssl 1.1

Openssl 1.1 is really annoying in that it made certain objects opaque
and added accessors for the necessary componenets, but these accessors
often don't exist in 1.0 and before, so there's no way to create clean
code that will compile with both 1.0 and 1.1; instead you have to
compiled with both code bases to make sure everything is working).

The other problem is that since the structures are opaque, their size
isn't known, so having a structure declared as a variable is no longer
possible.

This change switches all uses of EVP_MD_CTX to be pointers initialised
with the correct EVP_MD_CTX_new() (not available in 1.0), does the
same for HMAC_CTX, and uses the 1.1 only primitve RSA_get0_key() to
extract the public modulus and exponent from an RSA key.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Tested-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
This commit is contained in:
James Bottomley 2018-01-28 09:40:02 -08:00 committed by Mimi Zohar
parent 6921833477
commit 81010f0d87
2 changed files with 55 additions and 25 deletions

View File

@ -316,7 +316,7 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
struct stat st; struct stat st;
int err; int err;
uint32_t generation = 0; uint32_t generation = 0;
EVP_MD_CTX ctx; EVP_MD_CTX *pctx;
unsigned int mdlen; unsigned int mdlen;
char **xattrname; char **xattrname;
char xattr_value[1024]; char xattr_value[1024];
@ -325,6 +325,12 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
char uuid[16]; char uuid[16];
struct h_misc_64 hmac_misc; struct h_misc_64 hmac_misc;
int hmac_size; int hmac_size;
#if OPENSSL_VERSION_NUMBER < 0x10100000
EVP_MD_CTX ctx;
pctx = &ctx;
#else
pctx = EVP_MD_CTX_new();
#endif
if (lstat(file, &st)) { if (lstat(file, &st)) {
log_err("Failed to stat: %s\n", file); log_err("Failed to stat: %s\n", file);
@ -368,7 +374,7 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
return -1; return -1;
} }
err = EVP_DigestInit(&ctx, EVP_sha1()); err = EVP_DigestInit(pctx, EVP_sha1());
if (!err) { if (!err) {
log_err("EVP_DigestInit() failed\n"); log_err("EVP_DigestInit() failed\n");
return 1; return 1;
@ -400,7 +406,7 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
/*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/ /*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/
log_info("name: %s, size: %d\n", *xattrname, err); log_info("name: %s, size: %d\n", *xattrname, err);
log_debug_dump(xattr_value, err); log_debug_dump(xattr_value, err);
err = EVP_DigestUpdate(&ctx, xattr_value, err); err = EVP_DigestUpdate(pctx, xattr_value, err);
if (!err) { if (!err) {
log_err("EVP_DigestUpdate() failed\n"); log_err("EVP_DigestUpdate() failed\n");
return 1; return 1;
@ -454,7 +460,7 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
log_debug("hmac_misc (%d): ", hmac_size); log_debug("hmac_misc (%d): ", hmac_size);
log_debug_dump(&hmac_misc, hmac_size); log_debug_dump(&hmac_misc, hmac_size);
err = EVP_DigestUpdate(&ctx, &hmac_misc, hmac_size); err = EVP_DigestUpdate(pctx, &hmac_misc, hmac_size);
if (!err) { if (!err) {
log_err("EVP_DigestUpdate() failed\n"); log_err("EVP_DigestUpdate() failed\n");
return 1; return 1;
@ -466,14 +472,14 @@ static int calc_evm_hash(const char *file, unsigned char *hash)
if (err) if (err)
return -1; return -1;
err = EVP_DigestUpdate(&ctx, (const unsigned char *)uuid, sizeof(uuid)); err = EVP_DigestUpdate(pctx, (const unsigned char *)uuid, sizeof(uuid));
if (!err) { if (!err) {
log_err("EVP_DigestUpdate() failed\n"); log_err("EVP_DigestUpdate() failed\n");
return 1; return 1;
} }
} }
err = EVP_DigestFinal(&ctx, hash, &mdlen); err = EVP_DigestFinal(pctx, hash, &mdlen);
if (!err) { if (!err) {
log_err("EVP_DigestFinal() failed\n"); log_err("EVP_DigestFinal() failed\n");
return 1; return 1;
@ -955,7 +961,7 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h
struct stat st; struct stat st;
int err = -1; int err = -1;
uint32_t generation = 0; uint32_t generation = 0;
HMAC_CTX ctx; HMAC_CTX *pctx;
unsigned int mdlen; unsigned int mdlen;
char **xattrname; char **xattrname;
unsigned char xattr_value[1024]; unsigned char xattr_value[1024];
@ -966,6 +972,12 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h
ssize_t list_size; ssize_t list_size;
struct h_misc_64 hmac_misc; struct h_misc_64 hmac_misc;
int hmac_size; int hmac_size;
#if OPENSSL_VERSION_NUMBER < 0x10100000
HMAC_CTX ctx;
pctx = &ctx;
#else
pctx = HMAC_CTX_new();
#endif
key = file2bin(keyfile, NULL, &keylen); key = file2bin(keyfile, NULL, &keylen);
if (!key) { if (!key) {
@ -1012,7 +1024,7 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h
goto out; goto out;
} }
err = !HMAC_Init(&ctx, evmkey, sizeof(evmkey), EVP_sha1()); err = !HMAC_Init_ex(pctx, evmkey, sizeof(evmkey), EVP_sha1(), NULL);
if (err) { if (err) {
log_err("HMAC_Init() failed\n"); log_err("HMAC_Init() failed\n");
goto out; goto out;
@ -1031,7 +1043,7 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h
/*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/ /*log_debug("name: %s, value: %s, size: %d\n", *xattrname, xattr_value, err);*/
log_info("name: %s, size: %d\n", *xattrname, err); log_info("name: %s, size: %d\n", *xattrname, err);
log_debug_dump(xattr_value, err); log_debug_dump(xattr_value, err);
err = !HMAC_Update(&ctx, xattr_value, err); err = !HMAC_Update(pctx, xattr_value, err);
if (err) { if (err) {
log_err("HMAC_Update() failed\n"); log_err("HMAC_Update() failed\n");
goto out_ctx_cleanup; goto out_ctx_cleanup;
@ -1072,16 +1084,20 @@ static int calc_evm_hmac(const char *file, const char *keyfile, unsigned char *h
log_debug("hmac_misc (%d): ", hmac_size); log_debug("hmac_misc (%d): ", hmac_size);
log_debug_dump(&hmac_misc, hmac_size); log_debug_dump(&hmac_misc, hmac_size);
err = !HMAC_Update(&ctx, (const unsigned char *)&hmac_misc, hmac_size); err = !HMAC_Update(pctx, (const unsigned char *)&hmac_misc, hmac_size);
if (err) { if (err) {
log_err("HMAC_Update() failed\n"); log_err("HMAC_Update() failed\n");
goto out_ctx_cleanup; goto out_ctx_cleanup;
} }
err = !HMAC_Final(&ctx, hash, &mdlen); err = !HMAC_Final(pctx, hash, &mdlen);
if (err) if (err)
log_err("HMAC_Final() failed\n"); log_err("HMAC_Final() failed\n");
out_ctx_cleanup: out_ctx_cleanup:
HMAC_CTX_cleanup(&ctx); #if OPENSSL_VERSION_NUMBER < 0x10100000
HMAC_CTX_cleanup(pctx);
#else
HMAC_CTX_free(pctx);
#endif
out: out:
free(key); free(key);
return err ?: mdlen; return err ?: mdlen;

View File

@ -271,9 +271,15 @@ int ima_calc_hash(const char *file, uint8_t *hash)
{ {
const EVP_MD *md; const EVP_MD *md;
struct stat st; struct stat st;
EVP_MD_CTX ctx; EVP_MD_CTX *pctx;
unsigned int mdlen; unsigned int mdlen;
int err; int err;
#if OPENSSL_VERSION_NUMBER < 0x10100000
EVP_MD_CTX ctx;
pctx = &ctx;
#else
pctx = EVP_MD_CTX_new();
#endif
/* Need to know the file length */ /* Need to know the file length */
err = lstat(file, &st); err = lstat(file, &st);
@ -288,7 +294,7 @@ int ima_calc_hash(const char *file, uint8_t *hash)
return 1; return 1;
} }
err = EVP_DigestInit(&ctx, md); err = EVP_DigestInit(pctx, md);
if (!err) { if (!err) {
log_err("EVP_DigestInit() failed\n"); log_err("EVP_DigestInit() failed\n");
return 1; return 1;
@ -296,17 +302,17 @@ int ima_calc_hash(const char *file, uint8_t *hash)
switch (st.st_mode & S_IFMT) { switch (st.st_mode & S_IFMT) {
case S_IFREG: case S_IFREG:
err = add_file_hash(file, &ctx); err = add_file_hash(file, pctx);
break; break;
case S_IFDIR: case S_IFDIR:
err = add_dir_hash(file, &ctx); err = add_dir_hash(file, pctx);
break; break;
case S_IFLNK: case S_IFLNK:
err = add_link_hash(file, &ctx); err = add_link_hash(file, pctx);
break; break;
case S_IFIFO: case S_IFSOCK: case S_IFIFO: case S_IFSOCK:
case S_IFCHR: case S_IFBLK: case S_IFCHR: case S_IFBLK:
err = add_dev_hash(&st, &ctx); err = add_dev_hash(&st, pctx);
break; break;
default: default:
log_errno("Unsupported file type"); log_errno("Unsupported file type");
@ -316,7 +322,7 @@ int ima_calc_hash(const char *file, uint8_t *hash)
if (err) if (err)
return err; return err;
err = EVP_DigestFinal(&ctx, hash, &mdlen); err = EVP_DigestFinal(pctx, hash, &mdlen);
if (!err) { if (!err) {
log_err("EVP_DigestFinal() failed\n"); log_err("EVP_DigestFinal() failed\n");
return 1; return 1;
@ -622,6 +628,14 @@ int key2bin(RSA *key, unsigned char *pub)
{ {
int len, b, offset = 0; int len, b, offset = 0;
struct pubkey_hdr *pkh = (struct pubkey_hdr *)pub; struct pubkey_hdr *pkh = (struct pubkey_hdr *)pub;
const BIGNUM *n, *e;
#if OPENSSL_VERSION_NUMBER < 0x10100000
n = key->n;
e = key->e;
#else
RSA_get0_key(key, &n, &e, NULL);
#endif
/* add key header */ /* add key header */
pkh->version = 1; pkh->version = 1;
@ -631,18 +645,18 @@ int key2bin(RSA *key, unsigned char *pub)
offset += sizeof(*pkh); offset += sizeof(*pkh);
len = BN_num_bytes(key->n); len = BN_num_bytes(n);
b = BN_num_bits(key->n); b = BN_num_bits(n);
pub[offset++] = b >> 8; pub[offset++] = b >> 8;
pub[offset++] = b & 0xff; pub[offset++] = b & 0xff;
BN_bn2bin(key->n, &pub[offset]); BN_bn2bin(n, &pub[offset]);
offset += len; offset += len;
len = BN_num_bytes(key->e); len = BN_num_bytes(e);
b = BN_num_bits(key->e); b = BN_num_bits(e);
pub[offset++] = b >> 8; pub[offset++] = b >> 8;
pub[offset++] = b & 0xff; pub[offset++] = b & 0xff;
BN_bn2bin(key->e, &pub[offset]); BN_bn2bin(e, &pub[offset]);
offset += len; offset += len;
return offset; return offset;