Skip to content

Commit

Permalink
utils: remove unused code from cert utils
Browse files Browse the repository at this point in the history
Related to https://pagure.io/SSSD/sssd/issue/3489

Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
  • Loading branch information
sumit-bose authored and fidencio committed Jun 5, 2018
1 parent 4f63a1a commit 7190e0e
Show file tree
Hide file tree
Showing 3 changed files with 0 additions and 328 deletions.
34 changes: 0 additions & 34 deletions src/tests/cmocka/test_cert_utils.c
Expand Up @@ -343,38 +343,6 @@ void test_sss_cert_derb64_to_ldap_filter(void **state)
talloc_free(filter);
}

void test_cert_to_ssh_key(void **state)
{
int ret;
uint8_t *key;
size_t key_size;
uint8_t *exp_key;
size_t exp_key_size;
uint8_t *der;
size_t der_size;
struct cert_verify_opts cert_verify_opts = { .do_ocsp = false,
.do_verification = true };

struct test_state *ts = talloc_get_type_abort(*state, struct test_state);
assert_non_null(ts);

der = sss_base64_decode(ts, SSSD_TEST_CERT_0001, &der_size);
assert_non_null(der);

exp_key = sss_base64_decode(ts, SSSD_TEST_CERT_SSH_KEY_0001, &exp_key_size);
assert_non_null(exp_key);

ret = cert_to_ssh_key(ts, "sql:" ABS_BUILD_DIR "/src/tests/test_CA/p11_nssdb",
der, der_size, &cert_verify_opts, &key, &key_size);
assert_int_equal(ret, EOK);
assert_int_equal(key_size, exp_key_size);
assert_memory_equal(key, exp_key, exp_key_size);

talloc_free(der);
talloc_free(key);
talloc_free(exp_key);
}

void test_cert_to_ssh_key_done(struct tevent_req *req)
{
int ret;
Expand Down Expand Up @@ -610,8 +578,6 @@ int main(int argc, const char *argv[])
setup, teardown),
#ifdef HAVE_NSS
#ifdef HAVE_TEST_CA
cmocka_unit_test_setup_teardown(test_cert_to_ssh_key,
setup, teardown),
cmocka_unit_test_setup_teardown(test_cert_to_ssh_key_send,
setup, teardown),
cmocka_unit_test_setup_teardown(test_cert_to_ssh_2keys_send,
Expand Down
106 changes: 0 additions & 106 deletions src/util/cert/libcrypto/cert.c
Expand Up @@ -171,112 +171,6 @@ errno_t sss_cert_pem_to_der(TALLOC_CTX *mem_ctx, const char *pem,
#define SSH_RSA_HEADER "ssh-rsa"
#define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1)

errno_t cert_to_ssh_key(TALLOC_CTX *mem_ctx, const char *ca_db,
const uint8_t *der_blob, size_t der_size,
struct cert_verify_opts *cert_verify_opts,
uint8_t **key, size_t *key_size)
{
int ret;
size_t size;
const unsigned char *d;
uint8_t *buf = NULL;
size_t c;
X509 *cert = NULL;
EVP_PKEY *cert_pub_key = NULL;
const BIGNUM *n;
const BIGNUM *e;
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 (der_blob == NULL || der_size == 0) {
return EINVAL;
}

d = (const unsigned char *) der_blob;

cert = d2i_X509(NULL, &d, (int) der_size);
if (cert == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "d2i_X509 failed.\n");
return EINVAL;
}

/* TODO: verify certificate !!!!! */

cert_pub_key = X509_get_pubkey(cert);
if (cert_pub_key == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "X509_get_pubkey failed.\n");
ret = EIO;
goto done;
}

if (EVP_PKEY_base_id(cert_pub_key) != EVP_PKEY_RSA) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Expected RSA public key, found unsupported [%d].\n",
EVP_PKEY_base_id(cert_pub_key));
ret = EINVAL;
goto done;
}

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
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, &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);

size = SSH_RSA_HEADER_LEN + 3 * sizeof(uint32_t)
+ modulus_len
+ exponent_len
+ 1; /* see comment about missing 00 below */

buf = talloc_size(mem_ctx, size);
if (buf == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n");
ret = ENOMEM;
goto done;
}

c = 0;

SAFEALIGN_SET_UINT32(buf, htobe32(SSH_RSA_HEADER_LEN), &c);
safealign_memcpy(&buf[c], SSH_RSA_HEADER, SSH_RSA_HEADER_LEN, &c);
SAFEALIGN_SET_UINT32(&buf[c], htobe32(exponent_len), &c);
safealign_memcpy(&buf[c], exponent, exponent_len, &c);

/* Adding missing 00 which AFAIK is added to make sure
* the bigint is handled as positive number */
/* TODO: make a better check if 00 must be added or not, e.g. ... & 0x80)
*/
SAFEALIGN_SET_UINT32(&buf[c], htobe32(modulus_len + 1), &c);
SAFEALIGN_SETMEM_VALUE(&buf[c], '\0', unsigned char, &c);
safealign_memcpy(&buf[c], modulus, modulus_len, &c);

*key = buf;
*key_size = size;

ret = EOK;

done:
if (ret != EOK) {
talloc_free(buf);
}
EVP_PKEY_free(cert_pub_key);
X509_free(cert);

return ret;
}

errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx,
const uint8_t *der_blob, size_t der_size,
uint8_t **key_blob, size_t *key_size)
Expand Down
188 changes: 0 additions & 188 deletions src/util/cert/nss/cert.c
Expand Up @@ -223,194 +223,6 @@ errno_t sss_cert_pem_to_der(TALLOC_CTX *mem_ctx, const char *pem,
#define SSH_RSA_HEADER "ssh-rsa"
#define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1)

errno_t cert_to_ssh_key(TALLOC_CTX *mem_ctx, const char *ca_db,
const uint8_t *der_blob, size_t der_size,
struct cert_verify_opts *cert_verify_opts,
uint8_t **key, size_t *key_size)
{
CERTCertDBHandle *handle;
CERTCertificate *cert = NULL;
SECItem der_item;
SECKEYPublicKey *cert_pub_key = NULL;
int ret;
size_t size;
uint8_t *buf = NULL;
size_t c;
NSSInitContext *nss_ctx;
NSSInitParameters parameters = { 0 };
parameters.length = sizeof (parameters);
SECStatus rv;
SECStatus rv_verify;
size_t exponent_prefix_len;
size_t modulus_prefix_len;

if (der_blob == NULL || der_size == 0) {
return EINVAL;
}

/* initialize NSS with context, we might have already called
* NSS_NoDB_Init() but for validation we need to have access to a DB with
* the trusted issuer cert. Only NSS_InitContext will really open the DB
* in this case. I'm not sure about how long validation might need e.g. if
* CRLs or OSCP is enabled, maybe it would be better to run validation in
* p11_child? */
nss_ctx = NSS_InitContext(ca_db, "", "", SECMOD_DB, &parameters,
NSS_INIT_READONLY);
if (nss_ctx == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "NSS_InitContext failed [%d].\n",
PR_GetError());
return EIO;
}

handle = CERT_GetDefaultCertDB();

if (cert_verify_opts->do_ocsp) {
rv = CERT_EnableOCSPChecking(handle);
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE, "CERT_EnableOCSPChecking failed: [%d].\n",
PR_GetError());
return EIO;
}

if (cert_verify_opts->ocsp_default_responder != NULL
&& cert_verify_opts->ocsp_default_responder_signing_cert != NULL) {
rv = CERT_SetOCSPDefaultResponder(handle,
cert_verify_opts->ocsp_default_responder,
cert_verify_opts->ocsp_default_responder_signing_cert);
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE,
"CERT_SetOCSPDefaultResponder failed: [%d].\n",
PR_GetError());
return EIO;
}

rv = CERT_EnableOCSPDefaultResponder(handle);
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE,
"CERT_EnableOCSPDefaultResponder failed: [%d].\n",
PR_GetError());
return EIO;
}
}
}

der_item.len = der_size;
der_item.data = discard_const(der_blob);

cert = CERT_NewTempCertificate(handle, &der_item, NULL, PR_FALSE, PR_TRUE);
if (cert == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "CERT_NewTempCertificate failed.\n");
ret = EINVAL;
goto done;
}

if (cert_verify_opts->do_verification) {
rv_verify = CERT_VerifyCertificateNow(handle, cert, PR_TRUE,
certificateUsageSSLClient,
NULL, NULL);

/* Disable OCSP default responder so that NSS can shutdown properly */
if (cert_verify_opts->do_ocsp
&& cert_verify_opts->ocsp_default_responder != NULL
&& cert_verify_opts->ocsp_default_responder_signing_cert
!= NULL) {
rv = CERT_DisableOCSPDefaultResponder(handle);
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE,
"CERT_DisableOCSPDefaultResponder failed: [%d].\n",
PR_GetError());
}
}

if (rv_verify != SECSuccess) {
DEBUG(SSSDBG_CRIT_FAILURE, "CERT_VerifyCertificateNow failed [%d].\n",
PR_GetError());
ret = EACCES;
goto done;
}
}

cert_pub_key = CERT_ExtractPublicKey(cert);
if (cert_pub_key == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "CERT_ExtractPublicKey failed.\n");
ret = EIO;
goto done;
}

if (cert_pub_key->keyType != rsaKey) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Expected RSA public key, found unsupported [%d].\n",
cert_pub_key->keyType);
ret = EINVAL;
goto done;
}

/* Looks like nss drops the leading 00 which AFAIK is added to make sure
* the bigint is handled as positive number if the leading bit is set. */
exponent_prefix_len = 0;
if (cert_pub_key->u.rsa.publicExponent.data[0] & 0x80) {
exponent_prefix_len = 1;
}

modulus_prefix_len = 0;
if (cert_pub_key->u.rsa.modulus.data[0] & 0x80) {
modulus_prefix_len = 1;
}
size = SSH_RSA_HEADER_LEN + 3 * sizeof(uint32_t)
+ cert_pub_key->u.rsa.modulus.len
+ cert_pub_key->u.rsa.publicExponent.len
+ exponent_prefix_len + modulus_prefix_len;

buf = talloc_size(mem_ctx, size);
if (buf == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n");
ret = ENOMEM;
goto done;
}

c = 0;

SAFEALIGN_SET_UINT32(buf, htobe32(SSH_RSA_HEADER_LEN), &c);
safealign_memcpy(&buf[c], SSH_RSA_HEADER, SSH_RSA_HEADER_LEN, &c);
SAFEALIGN_SET_UINT32(&buf[c],
htobe32(cert_pub_key->u.rsa.publicExponent.len
+ exponent_prefix_len), &c);
if (exponent_prefix_len == 1) {
SAFEALIGN_SETMEM_VALUE(&buf[c], '\0', unsigned char, &c);
}
safealign_memcpy(&buf[c], cert_pub_key->u.rsa.publicExponent.data,
cert_pub_key->u.rsa.publicExponent.len, &c);

SAFEALIGN_SET_UINT32(&buf[c],
htobe32(cert_pub_key->u.rsa.modulus.len
+ modulus_prefix_len ), &c);
if (modulus_prefix_len == 1) {
SAFEALIGN_SETMEM_VALUE(&buf[c], '\0', unsigned char, &c);
}
safealign_memcpy(&buf[c], cert_pub_key->u.rsa.modulus.data,
cert_pub_key->u.rsa.modulus.len, &c);

*key = buf;
*key_size = size;

ret = EOK;

done:
if (ret != EOK) {
talloc_free(buf);
}
SECKEY_DestroyPublicKey(cert_pub_key);
CERT_DestroyCertificate(cert);

rv = NSS_ShutdownContext(nss_ctx);
if (rv != SECSuccess) {
DEBUG(SSSDBG_OP_FAILURE, "NSS_ShutdownContext failed [%d].\n",
PR_GetError());
}

return ret;
}

errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx,
uint8_t *der_blob, size_t der_size,
uint8_t **key_blob, size_t *key_size)
Expand Down

0 comments on commit 7190e0e

Please sign in to comment.