Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cert util: replace deprecated OpenSSL calls #7576

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 171 additions & 28 deletions src/util/cert/libcrypto/cert.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <openssl/x509.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/core_names.h>

#include "util/util.h"
#include "util/sss_endian.h"
Expand Down Expand Up @@ -176,30 +177,122 @@
#define IDENTIFIER_NISTP384 "nistp384"
#define IDENTIFIER_NISTP521 "nistp521"

static int sss_ec_get_key(BN_CTX *bn_ctx, const EVP_PKEY *cert_pub_key,
EC_GROUP **_ec_group, EC_POINT **_ec_public_key)
{
EC_GROUP *ec_group = NULL;
EC_POINT *ec_public_key = NULL;

#if OPENSSL_VERSION_NUMBER >= 0x30000000L
int ret;
static char curve_name[4096];
static unsigned char pubkey[4096];
size_t len;

ret = EVP_PKEY_get_utf8_string_param(cert_pub_key,
OSSL_PKEY_PARAM_GROUP_NAME,
curve_name, sizeof(curve_name), NULL);
if (ret != 1) {
ret = EINVAL;
goto done;
alexey-tikhonov marked this conversation as resolved.
Show resolved Hide resolved
}

ec_group = EC_GROUP_new_by_curve_name(OBJ_sn2nid(curve_name));
if (ec_group == NULL) {
ret = EINVAL;
goto done;
}

ret = EVP_PKEY_get_octet_string_param(cert_pub_key,
OSSL_PKEY_PARAM_PUB_KEY,
pubkey, sizeof(pubkey), &len);
if (ret != 1) {
EC_GROUP_free(ec_group);
ret = EINVAL;
goto done;
}

ec_public_key = EC_POINT_new(ec_group);
if (ec_public_key == NULL) {
EC_GROUP_free(ec_group);
ret = EINVAL;
goto done;
}

ret = EC_POINT_oct2point(ec_group, ec_public_key, pubkey, len, bn_ctx);
if (ret != 1) {
EC_GROUP_free(ec_group);
EC_POINT_free(ec_public_key);
ret = EINVAL;
goto done;
}

#else
EC_KEY *ec_key = NULL;
const EC_GROUP *gr;
const EC_POINT *pk;

ec_key = EVP_PKEY_get0_EC_KEY(cert_pub_key);
if (ec_key == NULL) {
ret = ENOMEM;
goto done;
}

gr = EC_KEY_get0_group(ec_key);

pk = EC_KEY_get0_public_key(ec_key);

ec_group = EC_GROUP_dup(gr);
if (*_ec_group == NULL) {
ret = ENOMEM;
goto done;
}

ec_public_key = EC_POINT_dup(pk, gr);
if (ec_public_key == NULL) {
EC_GROUP_free(ec_group);
ret = ENOMEM;
goto done;
}
#endif

*_ec_group = ec_group;
*_ec_public_key = ec_public_key;

ret = EOK;

done:
return ret;
}

static errno_t ec_pub_key_to_ssh(TALLOC_CTX *mem_ctx, EVP_PKEY *cert_pub_key,
uint8_t **key_blob, size_t *key_size)
{
int ret;
size_t c;
uint8_t *buf = NULL;
size_t buf_len;
EC_KEY *ec_key = NULL;
const EC_GROUP *ec_group = NULL;
const EC_POINT *ec_public_key = NULL;
EC_GROUP *ec_group = NULL;
EC_POINT *ec_public_key = NULL;
BN_CTX *bn_ctx = NULL;
int key_len;
const char *identifier = NULL;
int identifier_len;
const char *header = NULL;
int header_len;

ec_key = EVP_PKEY_get1_EC_KEY(cert_pub_key);
if (ec_key == NULL) {
bn_ctx = BN_CTX_new();
if (bn_ctx == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "BN_CTX_new failed.\n");
ret = ENOMEM;
goto done;
}

ec_group = EC_KEY_get0_group(ec_key);
ret = sss_ec_get_key(bn_ctx, cert_pub_key, &ec_group, &ec_public_key);
alexey-tikhonov marked this conversation as resolved.
Show resolved Hide resolved
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Failed to get curve details.\n");
goto done;
alexey-tikhonov marked this conversation as resolved.
Show resolved Hide resolved
}

switch(EC_GROUP_get_curve_name(ec_group)) {
case NID_X9_62_prime256v1:
Expand All @@ -224,15 +317,6 @@
header_len = strlen(header);
identifier_len = strlen(identifier);

ec_public_key = EC_KEY_get0_public_key(ec_key);

bn_ctx = BN_CTX_new();
if (bn_ctx == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "BN_CTX_new failed.\n");
ret = ENOMEM;
goto done;
}

key_len = EC_POINT_point2oct(ec_group, ec_public_key,
POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx);
if (key_len == 0) {
Expand Down Expand Up @@ -279,7 +363,8 @@
}

BN_CTX_free(bn_ctx);
EC_KEY_free(ec_key);
EC_GROUP_free(ec_group);
EC_POINT_free(ec_public_key);

return ret;
}
Expand All @@ -288,33 +373,88 @@
#define SSH_RSA_HEADER "ssh-rsa"
#define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1)

static int sss_rsa_get_key(const EVP_PKEY *cert_pub_key,
BIGNUM **_n, BIGNUM **_e)
{
int ret;
BIGNUM *n = NULL;

Check warning on line 380 in src/util/cert/libcrypto/cert.c

View workflow job for this annotation

GitHub Actions / cppcheck

Possible null pointer dereference: n

Check warning on line 380 in src/util/cert/libcrypto/cert.c

View workflow job for this annotation

GitHub Actions / cppcheck

Possible null pointer dereference: n
BIGNUM *e = NULL;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
ret = EVP_PKEY_get_bn_param(cert_pub_key, OSSL_PKEY_PARAM_RSA_N, &n);
if (ret != 1) {
ret = EINVAL;
goto done;
}

ret = EVP_PKEY_get_bn_param(cert_pub_key, OSSL_PKEY_PARAM_RSA_E, &e);
if (ret != 1) {
BN_clear_free(n);
ret = EINVAL;
alexey-tikhonov marked this conversation as resolved.
Show resolved Hide resolved
goto done;
}

#else

const BIGNUM *tmp_n;
const BIGNUM *tmp_e:

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
const RSA *rsa_pub_key = NULL;
rsa_pub_key = EVP_PKEY_get0_RSA(cert_pub_key);
if (rsa_pub_key == NULL) {
ret = ENOMEM;
goto done;
}

RSA_get0_key(rsa_pub_key, tmp_n, tmp_e, NULL);
#else
alexey-tikhonov marked this conversation as resolved.
Show resolved Hide resolved
tmp_n = cert_pub_key->pkey.rsa->n;
tmp_e = cert_pub_key->pkey.rsa->e;
#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */

*n = BN_dup(tmp_n);
if (*n == NULL) {
ret = ENOMEM;
goto done;
}

*e = BN_dup(tmp_e);
if (*e == NULL) {
BN_clear_free(n);
ret = ENOME;
goto done;
}

#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */

*_e = e;
*_n = n;

ret = EOK;

done:
return ret;
}

static errno_t rsa_pub_key_to_ssh(TALLOC_CTX *mem_ctx, EVP_PKEY *cert_pub_key,
uint8_t **key_blob, size_t *key_size)
{
int ret;
size_t c;
size_t size;
uint8_t *buf = NULL;
const BIGNUM *n;
const BIGNUM *e;
BIGNUM *n = NULL;
BIGNUM *e = NULL;
int modulus_len;
unsigned char modulus[OPENSSL_RSA_MAX_MODULUS_BITS/8];
int exponent_len;
unsigned char exponent[OPENSSL_RSA_MAX_PUBEXP_BITS/8];

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
const RSA *rsa_pub_key = NULL;
rsa_pub_key = EVP_PKEY_get0_RSA(cert_pub_key);
if (rsa_pub_key == NULL) {
ret = ENOMEM;
ret = sss_rsa_get_key(cert_pub_key, &n, &e);
if (ret != EOK) {
goto done;
alexey-tikhonov marked this conversation as resolved.
Show resolved Hide resolved
}

RSA_get0_key(rsa_pub_key, &n, &e, NULL);
#else
n = cert_pub_key->pkey.rsa->n;
e = cert_pub_key->pkey.rsa->e;
#endif
modulus_len = BN_bn2bin(n, modulus);
exponent_len = BN_bn2bin(e, exponent);

Expand Down Expand Up @@ -358,6 +498,9 @@
ret = EOK;

done:
BN_clear_free(n);
BN_clear_free(e);

if (ret != EOK) {
talloc_free(buf);
}
Expand Down
Loading