Example #1
0
int
crypto_cert_get_pub_exp_mod(CryptoCert cert, uint32 * key_len,
		uint8 * exponent, uint32 exp_len, uint8 * modulus, uint32 mod_len)
{
	gnutls_datum_t m;
	gnutls_datum_t e;
	/* GnuTLS 2.10.1 contains patches for "MD5 with RSA Encryption" and "SHA with RSA Encryption" */
	int x = gnutls_x509_crt_get_pk_rsa_raw(cert->cert, &m, &e);
	ASSERT(!x);
	*key_len = m.size;

	size_t l = e.size;
	ASSERT(l <= exp_len);
	memset(exponent, 0, exp_len - l);
	memcpy(exponent + exp_len - l, e.data, l);
	gnutls_free(e.data);

	l = m.size;
	ASSERT(l <= *key_len);
	memset(modulus, 0, *key_len - l);
	memcpy(modulus + *key_len - l, m.data, l);
	gnutls_free(m.data);

	return 0;
}
Example #2
0
gpg_err_code_t
keyutil_get_cert_mpi (
	unsigned char *der,
	size_t len,
	gcry_mpi_t *p_n_mpi,
	gcry_mpi_t *p_e_mpi
) {
	gpg_err_code_t error = GPG_ERR_GENERAL;
	gcry_mpi_t n_mpi = NULL;
	gcry_mpi_t e_mpi = NULL;
#if defined(ENABLE_GNUTLS)
	gnutls_x509_crt_t cert = NULL;
	gnutls_datum_t datum = {der, len};
	gnutls_datum_t m = {NULL, 0}, e = {NULL, 0};
#elif defined(ENABLE_OPENSSL)
	X509 *x509 = NULL;
	EVP_PKEY *pubkey = NULL;
	char *n_hex = NULL, *e_hex = NULL;
#endif

	*p_n_mpi = NULL;
	*p_e_mpi = NULL;

#if defined(ENABLE_GNUTLS)
	if (gnutls_x509_crt_init (&cert) != GNUTLS_E_SUCCESS) {
		cert = NULL;
		error = GPG_ERR_ENOMEM;
		goto cleanup;
	}

	if (gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER) != GNUTLS_E_SUCCESS) {
		error = GPG_ERR_BAD_CERT;
		goto cleanup;
	}

	if (gnutls_x509_crt_get_pk_rsa_raw (cert, &m, &e) != GNUTLS_E_SUCCESS) {
		error = GPG_ERR_BAD_KEY;
		m.data = NULL;
		e.data = NULL;
		goto cleanup;
	}

	if (
		gcry_mpi_scan(&n_mpi, GCRYMPI_FMT_USG, m.data, m.size, NULL) ||
		gcry_mpi_scan(&e_mpi, GCRYMPI_FMT_USG, e.data, e.size, NULL)
	) {
		error = GPG_ERR_BAD_KEY;
		goto cleanup;
	}
#elif defined(ENABLE_OPENSSL)
	if (!d2i_X509 (&x509, (my_openssl_d2i_t *)&der, len)) {
		error = GPG_ERR_BAD_CERT;
		goto cleanup;
	}
 
	if ((pubkey = X509_get_pubkey (x509)) == NULL) {
		error = GPG_ERR_BAD_CERT;
		goto cleanup;
	}
 
	if (pubkey->type != EVP_PKEY_RSA) {
		error = GPG_ERR_WRONG_PUBKEY_ALGO;
		goto cleanup;
	}
	
	n_hex = BN_bn2hex (pubkey->pkey.rsa->n);
	e_hex = BN_bn2hex (pubkey->pkey.rsa->e);
		
	if(n_hex == NULL || e_hex == NULL) {
		error = GPG_ERR_BAD_KEY;
		goto cleanup;
	}
 
	if (
		gcry_mpi_scan (&n_mpi, GCRYMPI_FMT_HEX, n_hex, 0, NULL) ||
		gcry_mpi_scan (&e_mpi, GCRYMPI_FMT_HEX, e_hex, 0, NULL)
	) {
		error = GPG_ERR_BAD_KEY;
		goto cleanup;
	}
#else
#error Invalid configuration.
#endif

	*p_n_mpi = n_mpi;
	n_mpi = NULL;
	*p_e_mpi = e_mpi;
	e_mpi = NULL;
	error = GPG_ERR_NO_ERROR;

cleanup:

	if (n_mpi != NULL) {
		gcry_mpi_release (n_mpi);
		n_mpi = NULL;
	}

	if (e_mpi != NULL) {
		gcry_mpi_release (e_mpi);
		e_mpi = NULL;
	}

#if defined(ENABLE_GNUTLS)

	if (m.data != NULL) {
		gnutls_free (m.data);
		m.data = NULL;
	}

	if (e.data != NULL) {
		gnutls_free (e.data);
		e.data = NULL;
	}

	if (cert != NULL) {
		gnutls_x509_crt_deinit (cert);
		cert = NULL;
	}

#elif defined(ENABLE_OPENSSL)

	if (x509 != NULL) {
		X509_free (x509);
		x509 = NULL;
	}

	if (pubkey != NULL) {
		EVP_PKEY_free(pubkey);
		pubkey = NULL;
	}

	if (n_hex != NULL) {
		OPENSSL_free (n_hex);
		n_hex = NULL;
	}

	if (e_hex != NULL) {
		OPENSSL_free (e_hex);
		e_hex = NULL;
	}

#else
#error Invalid configuration.
#endif

	return error;
}
Example #3
0
void __certificate_properties_fill_cert_subjectPublicKeyInfo (GtkTreeStore *store,
        GtkTreeIter *parent,
        gnutls_x509_crt_t *certificate)
{
    int result;
    unsigned int bits = 0;
    const gchar * name = NULL;
    GtkTreeIter j;
    GtkTreeIter k;
    GtkTreeIter l;
    gchar *value;
    GtkTreeIter m;
    gnutls_datum_t modulus, publicExponent;
    gnutls_datum_t p, q, g, y;

    result = gnutls_x509_crt_get_pk_algorithm(*certificate, &bits);
    name = gnutls_pk_algorithm_get_name(result);

    gtk_tree_store_append(store, &j, parent);
    gtk_tree_store_set(store, &j, CERTIFICATE_PROPERTIES_COL_NAME, _("Subject Public Key Info"), -1);

    gtk_tree_store_append(store, &k, &j);
    gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("Algorithm"), -1);

    gtk_tree_store_append(store, &l, &k);
    gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Algorithm"), CERTIFICATE_PROPERTIES_COL_VALUE, name, -1);

    switch (result) {
    case GNUTLS_PK_RSA:
        gtk_tree_store_append(store, &l, &k);
        gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Parameters"), CERTIFICATE_PROPERTIES_COL_VALUE, _("(unknown)"), -1);
        gtk_tree_store_append(store, &k, &j);
        gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("RSA PublicKey"), -1);
        result = gnutls_x509_crt_get_pk_rsa_raw(*certificate, &modulus, &publicExponent);
        if (result < 0) {
            fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
            break;
        }
        value = __certificate_properties_dump_raw_data(modulus.data, modulus.size);
        gnutls_free(modulus.data);

        gtk_tree_store_append(store, &l, &k);
        gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Modulus"), CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
        g_free(value);

        value = __certificate_properties_dump_raw_data(publicExponent.data, publicExponent.size);
        gnutls_free(publicExponent.data);
        gtk_tree_store_append(store, &l, &k);
        gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Public Exponent"), CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
        g_free(value);
        break;
    case GNUTLS_PK_DSA:
        result = gnutls_x509_crt_get_pk_dsa_raw(*certificate, &p, &q, &g, &y);
        if (result < 0) {
            fprintf(stderr, "Error: (%s,%d): %s\n", __FILE__, __LINE__, gnutls_strerror(result));
            break;
        }
        gtk_tree_store_append(store, &l, &k);
        gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Parameters"), -1);

        value = __certificate_properties_dump_raw_data(p.data, p.size);
        gnutls_free(p.data);
        gtk_tree_store_append(store, &m, &l);
        gtk_tree_store_set(store, &m, CERTIFICATE_PROPERTIES_COL_NAME, "p", CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
        g_free(value);

        value = __certificate_properties_dump_raw_data(q.data, q.size);
        gnutls_free(q.data);
        gtk_tree_store_append(store, &m, &l);
        gtk_tree_store_set(store, &m, CERTIFICATE_PROPERTIES_COL_NAME, "p", CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
        g_free(value);

        value = __certificate_properties_dump_raw_data(g.data, g.size);
        gnutls_free(g.data);
        gtk_tree_store_append(store, &m, &l);
        gtk_tree_store_set(store, &m, CERTIFICATE_PROPERTIES_COL_NAME, "g", CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
        g_free(value);

        value = __certificate_properties_dump_raw_data(y.data, y.size);
        gnutls_free(y.data);
        gtk_tree_store_append(store, &k, &j);
        gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("DSA PublicKey"), CERTIFICATE_PROPERTIES_COL_VALUE, value, -1);
        g_free(value);
        break;
    default:
        gtk_tree_store_append(store, &l, &k);
        gtk_tree_store_set(store, &l, CERTIFICATE_PROPERTIES_COL_NAME, _("Parameters"), CERTIFICATE_PROPERTIES_COL_VALUE, _("(unknown)"), -1);
        gtk_tree_store_append(store, &k, &j);
        gtk_tree_store_set(store, &k, CERTIFICATE_PROPERTIES_COL_NAME, _("Subject Public Key"), CERTIFICATE_PROPERTIES_COL_VALUE, _("(unknown)"), -1);
        break;
    }
}
Example #4
0
unsigned char *crypto_decrypt_signature(crypto_ctx *ctx,
                                        const unsigned char *sig_data,
                                        size_t sig_len,
                                        size_t *out_len,
                                        unsigned int padding,
                                        crypto_error **error)
{
    unsigned char *buf = NULL, *rec_hash = NULL;
    gnutls_datum_t n = { NULL, 0 }, e = { NULL, 0 };
    int err, algo;
    gcry_sexp_t key = NULL, sig = NULL, decrypted = NULL, child = NULL;
    gcry_mpi_t n_mpi = NULL, e_mpi = NULL, sig_mpi = NULL, dec_mpi = NULL;
    size_t buf_len = 0, hash_len = 0;

    if (!ctx) {
        crypto_error_set(error, 1, 0, "invalid crypto context");
        return NULL;
    }

    if (!ctx->num) {
        crypto_error_set(error, 1, 0, "no certificates in the stack");
        return NULL;
    }

    algo = gnutls_x509_crt_get_pk_algorithm(ctx->stack[ctx->num - 1], NULL);
    if (algo != GNUTLS_PK_RSA) {
        crypto_error_set(error, 1, 0, "certificate public key algorithm not RSA");
        return NULL;
    }

    err = gnutls_x509_crt_get_pk_rsa_raw(ctx->stack[ctx->num - 1], &n, &e);
    if (err != GNUTLS_E_SUCCESS) {
        crypto_error_set(error, 1, 0, "error getting certificate public key");
        return NULL;
    }

    err = gcry_mpi_scan(&n_mpi, GCRYMPI_FMT_USG, n.data, n.size, NULL);
    if (err) {
        crypto_error_set(error, 1, 0, "invalid RSA key 'n' format");
        goto out;
    }

    err = gcry_mpi_scan(&e_mpi, GCRYMPI_FMT_USG, e.data, e.size, NULL);
    if (err) {
        crypto_error_set(error, 1, 0, "invalid RSA key 'e' format");
        goto out;
    }

    err = gcry_sexp_build(&key, NULL, "(public-key (rsa (n %m) (e %m)))", n_mpi, e_mpi);
    if (err) {
        crypto_error_set(error, 1, 0, "could not create public-key expression");
        goto out;
    }

    err = gcry_mpi_scan(&sig_mpi, GCRYMPI_FMT_USG, sig_data, sig_len, NULL);
    if (err) {
        crypto_error_set(error, 1, 0, "invalid signature format");
        goto out;
    }

    err = gcry_sexp_build(&sig, NULL, "(data (flags raw) (value %m))", sig_mpi);
    if (err) {
        crypto_error_set(error, 1, 0, "could not create signature expression");
        goto out;
    }

    /* encrypt is equivalent to public key decryption for RSA keys */
    err = gcry_pk_encrypt(&decrypted, sig, key);
    if (err) {
        crypto_error_set(error, 1, 0, "could not decrypt signature");
        goto out;
    }

    child = gcry_sexp_find_token(decrypted, "a", 1);
    if (!child) {
        crypto_error_set(error, 1, 0, "could not get decrypted signature result");
        goto out;
    }

    dec_mpi = gcry_sexp_nth_mpi(child, 1, GCRYMPI_FMT_USG);
    gcry_sexp_release(child);

    if (!dec_mpi) {
        crypto_error_set(error, 1, 0, "could not get decrypted signature result");
        goto out;
    }

    gcry_mpi_aprint(GCRYMPI_FMT_USG, &buf, &buf_len, dec_mpi);
    if (!buf) {
        crypto_error_set(error, 1, 0, "could not get extract decrypted signature");
        goto out;
    }

    switch (padding) {
    case CRYPTO_PAD_NONE:
        rec_hash = buf;
        hash_len = buf_len;
        buf = NULL;
        *out_len = (int) hash_len;
        break;
    case CRYPTO_PAD_PKCS1:
        rec_hash = check_pkcs1_padding(buf, buf_len, &hash_len, error);
        if (!rec_hash) {
            crypto_error_set(error, 1, 0, "could not get extract decrypted padded signature");
            goto out;
        }
        *out_len = (int) hash_len;
        break;
    default:
        crypto_error_set(error, 1, 0, "unknown padding mechanism %d", padding);
        break;
    }

out:
    if (buf)
        free(buf);
    if (dec_mpi)
        gcry_mpi_release(dec_mpi);
    if (decrypted)
        gcry_sexp_release(decrypted);
    if (key)
        gcry_sexp_release(key);
    if (sig)
        gcry_sexp_release(sig);
    if (sig_mpi)
        gcry_mpi_release(sig_mpi);
    if (n_mpi)
        gcry_mpi_release(n_mpi);
    if (e_mpi)
        gcry_mpi_release(e_mpi);
    if (n.data)
        gcry_free(n.data);
    if (e.data)
        gcry_free(e.data);

    return rec_hash;
}