예제 #1
0
static void privkey_info_int(FILE *outfile, common_info_st * cinfo,
			     gnutls_x509_privkey_t key)
{
	int ret, key_type;
	unsigned int bits = 0;
	size_t size;
	const char *cprint;

	/* Public key algorithm
	 */
	fprintf(outfile, "Public Key Info:\n");
	ret = gnutls_x509_privkey_get_pk_algorithm2(key, &bits);
	fprintf(outfile, "\tPublic Key Algorithm: ");

	key_type = ret;

	cprint = gnutls_pk_algorithm_get_name(key_type);
	fprintf(outfile, "%s\n", cprint ? cprint : "Unknown");
	fprintf(outfile, "\tKey Security Level: %s (%u bits)\n\n",
		gnutls_sec_param_get_name(gnutls_x509_privkey_sec_param
					  (key)), bits);

	/* Print the raw public and private keys
	 */
	if (key_type == GNUTLS_PK_RSA) {
		gnutls_datum_t m, e, d, p, q, u, exp1, exp2;

		ret =
		    gnutls_x509_privkey_export_rsa_raw2(key, &m, &e, &d,
							&p, &q, &u, &exp1,
							&exp2);
		if (ret < 0)
			fprintf(stderr,
				"Error in key RSA data export: %s\n",
				gnutls_strerror(ret));
		else {
			print_rsa_pkey(outfile, &m, &e, &d, &p, &q, &u,
				       &exp1, &exp2, cinfo->cprint);

			gnutls_free(m.data);
			gnutls_free(e.data);
			gnutls_free(d.data);
			gnutls_free(p.data);
			gnutls_free(q.data);
			gnutls_free(u.data);
			gnutls_free(exp1.data);
			gnutls_free(exp2.data);
		}
	} else if (key_type == GNUTLS_PK_DSA) {
		gnutls_datum_t p, q, g, y, x;

		ret =
		    gnutls_x509_privkey_export_dsa_raw(key, &p, &q, &g, &y,
						       &x);
		if (ret < 0)
			fprintf(stderr,
				"Error in key DSA data export: %s\n",
				gnutls_strerror(ret));
		else {
			print_dsa_pkey(outfile, &x, &y, &p, &q, &g,
				       cinfo->cprint);

			gnutls_free(x.data);
			gnutls_free(y.data);
			gnutls_free(p.data);
			gnutls_free(q.data);
			gnutls_free(g.data);
		}
	} else if (key_type == GNUTLS_PK_EC) {
		gnutls_datum_t y, x, k;
		gnutls_ecc_curve_t curve;

		ret =
		    gnutls_x509_privkey_export_ecc_raw(key, &curve, &x, &y,
						       &k);
		if (ret < 0)
			fprintf(stderr,
				"Error in key ECC data export: %s\n",
				gnutls_strerror(ret));
		else {
			cprint = gnutls_ecc_curve_get_name(curve);
			bits = 0;

			print_ecc_pkey(outfile, curve, &k, &x, &y,
				       cinfo->cprint);

			gnutls_free(x.data);
			gnutls_free(y.data);
			gnutls_free(k.data);
		}
	}

	fprintf(outfile, "\n");

	size = lbuffer_size;
	ret = gnutls_x509_privkey_get_seed(key, NULL, lbuffer, &size);
	if (ret >= 0) {
		fprintf(outfile, "Seed: %s\n",
			raw_to_string(lbuffer, size));
	}

	size = lbuffer_size;
	ret =
	     gnutls_x509_privkey_get_key_id(key, GNUTLS_KEYID_USE_SHA256, lbuffer, &size);
	if (ret < 0) {
		fprintf(stderr, "Error in key id calculation: %s\n",
			gnutls_strerror(ret));
	} else {
		gnutls_datum_t art;

		fprintf(outfile, "Public Key ID:\n\tsha256:%s\n",
			raw_to_string(lbuffer, size));

		size = lbuffer_size;
		ret =
		     gnutls_x509_privkey_get_key_id(key, GNUTLS_KEYID_USE_SHA1, lbuffer, &size);
		if (ret >= 0) {
			fprintf(outfile, "\tsha1:%s\n",
				raw_to_string(lbuffer, size));
		}

		ret =
		    gnutls_random_art(GNUTLS_RANDOM_ART_OPENSSH, cprint,
				      bits, lbuffer, size, &art);
		if (ret >= 0) {
			fprintf(outfile, "Public key's random art:\n%s\n",
				art.data);
			gnutls_free(art.data);
		}

	}
	fprintf(outfile, "\n");

}
예제 #2
0
char *
irc_sasl_mechanism_ecdsa_nist256p_challenge (struct t_irc_server *server,
                                             const char *data_base64,
                                             const char *sasl_username,
                                             const char *sasl_key)
{
#if defined(HAVE_GNUTLS) && (LIBGNUTLS_VERSION_NUMBER >= 0x030015) /* 3.0.21 */
    char *data, *string, *answer_base64;
    int length_data, length_username, length, ret;
    char *str_privkey;
    gnutls_x509_privkey_t x509_privkey;
    gnutls_privkey_t privkey;
    gnutls_datum_t filedatum, decoded_data, signature;
#if LIBGNUTLS_VERSION_NUMBER >= 0x030300 /* 3.3.0 */
    gnutls_ecc_curve_t curve;
    gnutls_datum_t x, y, k;
    char *pubkey, *pubkey_base64;
#endif /* LIBGNUTLS_VERSION_NUMBER >= 0x030300 */

    answer_base64 = NULL;
    string = NULL;
    length = 0;

    if (strcmp (data_base64, "+") == 0)
    {
        /* send "username" + '\0' + "username" */
        answer_base64 = NULL;
        length_username = strlen (sasl_username);
        length = length_username + 1 + length_username;
        string = malloc (length + 1);
        if (string)
        {
            snprintf (string, length + 1, "%s|%s", sasl_username, sasl_username);
            string[length_username] = '\0';
        }
    }
    else
    {
        /* sign the challenge with the private key and return the result */

        /* decode the challenge */
        data = malloc (strlen (data_base64) + 1);
        if (!data)
            return NULL;
        length_data = dogechat_string_decode_base64 (data_base64, data);

        /* read file with private key */
        str_privkey = irc_sasl_get_key_content (server, sasl_key);
        if (!str_privkey)
        {
            free (data);
            return NULL;
        }

        /* import key */
        gnutls_x509_privkey_init (&x509_privkey);
        gnutls_privkey_init (&privkey);
        filedatum.data = (unsigned char *)str_privkey;
        filedatum.size = strlen (str_privkey);
        ret = gnutls_x509_privkey_import (x509_privkey, &filedatum,
                                          GNUTLS_X509_FMT_PEM);
        free (str_privkey);
        if (ret != GNUTLS_E_SUCCESS)
        {
            dogechat_printf (
                server->buffer,
                _("%sgnutls: invalid private key file: error %d %s"),
                dogechat_prefix ("error"),
                ret,
                gnutls_strerror (ret));
            gnutls_x509_privkey_deinit (x509_privkey);
            gnutls_privkey_deinit (privkey);
            free (data);
            return NULL;
        }

#if LIBGNUTLS_VERSION_NUMBER >= 0x030300 /* 3.3.0 */
        /* read raw values in key, to display public key */
        ret = gnutls_x509_privkey_export_ecc_raw (x509_privkey,
                                                  &curve, &x, &y, &k);
        if (ret == GNUTLS_E_SUCCESS)
        {
            pubkey = malloc (x.size + 1);
            if (pubkey)
            {
                pubkey[0] = (y.data[y.size - 1] & 1) ? 0x03 : 0x02;
                memcpy (pubkey + 1, x.data, x.size);
                pubkey_base64 = malloc ((x.size + 1 + 1) * 4);
                if (pubkey_base64)
                {
                    dogechat_string_encode_base64 (pubkey, x.size + 1,
                                                  pubkey_base64);
                    dogechat_printf (
                        server->buffer,
                        _("%s%s: signing the challenge with ECC public key: "
                          "%s"),
                        dogechat_prefix ("network"),
                        IRC_PLUGIN_NAME,
                        pubkey_base64);
                    free (pubkey_base64);
                }
                free (pubkey);
            }
            gnutls_free (x.data);
            gnutls_free (y.data);
            gnutls_free (k.data);
        }
#endif /* LIBGNUTLS_VERSION_NUMBER >= 0x030300 */

        /* import private key in an abstract key structure */
        ret = gnutls_privkey_import_x509 (privkey, x509_privkey, 0); /* gnutls >= 2.11.0 */
        if (ret != GNUTLS_E_SUCCESS)
        {
            dogechat_printf (
                server->buffer,
                _("%sgnutls: unable to import the private key: error %d %s"),
                dogechat_prefix ("error"),
                ret,
                gnutls_strerror (ret));
            gnutls_x509_privkey_deinit (x509_privkey);
            gnutls_privkey_deinit (privkey);
            free (data);
            return NULL;
        }

        decoded_data.data = (unsigned char *)data;
        decoded_data.size = length_data;
        ret = gnutls_privkey_sign_hash (privkey, GNUTLS_DIG_SHA256, 0, /* gnutls >= 2.11.0 */
                                        &decoded_data, &signature);
        if (ret != GNUTLS_E_SUCCESS)
        {
            dogechat_printf (
                server->buffer,
                _("%sgnutls: unable to sign the hashed data: error %d %s"),
                dogechat_prefix ("error"),
                ret,
                gnutls_strerror (ret));
            gnutls_x509_privkey_deinit (x509_privkey);
            gnutls_privkey_deinit (privkey);
            free (data);
            return NULL;
        }

        gnutls_x509_privkey_deinit (x509_privkey);
        gnutls_privkey_deinit (privkey);

        string = malloc (signature.size);
        if (string)
            memcpy (string, signature.data, signature.size);
        length = signature.size;

        gnutls_free (signature.data);

        free (data);
    }

    if (string && (length > 0))
    {
        answer_base64 = malloc ((length + 1) * 4);
        if (answer_base64)
            dogechat_string_encode_base64 (string, length, answer_base64);
        free (string);
    }

    return answer_base64;

#else /* no gnutls or gnutls < 3.0.21 */

    /* make C compiler happy */
    (void) data_base64;
    (void) sasl_username;
    (void) sasl_key;

    dogechat_printf (server->buffer,
                    _("%sgnutls: version >= 3.0.21 is required for SASL "
                      "\"ecdsa-nist256p-challenge\""),
                    dogechat_prefix ("error"));

    return NULL;
#endif /* defined(HAVE_GNUTLS) && (LIBGNUTLS_VERSION_NUMBER >= 0x030015) */
}
예제 #3
0
static
int check_x509_privkey(void)
{
	gnutls_x509_privkey_t key;
	gnutls_datum_t p, q, g, y, x;
	gnutls_datum_t m, e, u, e1, e2, d;
	gnutls_ecc_curve_t curve;
	int ret;

	global_init();

	ret = gnutls_x509_privkey_init(&key);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_x509_privkey_import(key, &dsa_key, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_x509_privkey_export_dsa_raw(key, &p, &q, &g, &y, &x);
	if (ret < 0)
		fail("error\n");

	CMP("p", &p, dsa_p);
	CMP("q", &q, dsa_q);
	CMP("g", &g, dsa_g);
	CMP("y", &y, dsa_y);
	CMP("x", &x, dsa_x);
	gnutls_free(p.data);
	gnutls_free(q.data);
	gnutls_free(g.data);
	gnutls_free(y.data);
	gnutls_free(x.data);
	gnutls_x509_privkey_deinit(key);

	/* RSA */
	ret = gnutls_x509_privkey_init(&key);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_x509_privkey_import(key, &rsa_key, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_x509_privkey_export_rsa_raw2(key, &m, &e, &d, &p, &q, &u, &e1, &e2);
	if (ret < 0)
		fail("error\n");

	CMP("m", &m, rsa_m);
	CMP("e", &e, rsa_e);
	CMP("d", &d, rsa_d);
	CMP("p", &p, rsa_p);
	CMP("q", &q, rsa_q);
	CMP("u", &u, rsa_u);
	CMP("e1", &e1, rsa_e1);
	CMP("e2", &e2, rsa_e2);
	gnutls_free(m.data);
	gnutls_free(e.data);
	gnutls_free(d.data);
	gnutls_free(p.data);
	gnutls_free(q.data);
	gnutls_free(u.data);
	gnutls_free(e1.data);
	gnutls_free(e2.data);
	gnutls_x509_privkey_deinit(key);

	/* ECC */
	ret = gnutls_x509_privkey_init(&key);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_x509_privkey_import(key, &server_ecc_key, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_x509_privkey_export_ecc_raw(key, &curve, &x, &y, &p);
	if (ret < 0)
		fail("error\n");

	if (curve != GNUTLS_ECC_CURVE_SECP256R1) {
		fprintf(stderr, "unexpected curve value: %d\n", (int)curve);
		exit(1);
	}
	CMP("x", &x, ecc_x);
	CMP("y", &y, ecc_y);
	CMP("k", &p, ecc_k);
	gnutls_free(x.data);
	gnutls_free(y.data);
	gnutls_free(p.data);
	gnutls_x509_privkey_deinit(key);

	return 0;
}