Exemple #1
0
/**
  * gnutls_rsa_params_import_pkcs1 - This function will import RSA params from a pkcs1 structure
  * @params: A structure where the parameters will be copied to
  * @pkcs1_params: should contain a PKCS1 RSAPublicKey structure PEM or DER encoded
  * @format: the format of params. PEM or DER.
  *
  * This function will extract the RSAPublicKey found in a PKCS1 formatted
  * structure. 
  *
  * If the structure is PEM encoded, it should have a header
  * of "BEGIN RSA PRIVATE KEY".
  *
  * In case of failure a negative value will be returned, and
  * 0 on success.
  *
  **/
int
gnutls_rsa_params_import_pkcs1 (gnutls_rsa_params_t params,
				const gnutls_datum_t * pkcs1_params,
				gnutls_x509_crt_fmt_t format)
{
  return gnutls_x509_privkey_import (params, pkcs1_params, format);
}
Exemple #2
0
void SslContext::setKeyFile(const std::string& filename)
{
	if (error_) return;
	if (!enabled) return;

	TRACE("SslContext::setKeyFile: \"%s\"", filename.c_str());
	gnutls_datum_t data;
	if ((error_ = loadFile(data, filename))) {
		log(x0::Severity::error, "Error loading private key file(%s): %s", filename.c_str(), error_.message().c_str());
		return;
	}

	int rv;
	if ((rv = gnutls_x509_privkey_init(&x509PrivateKey_)) < 0) {
		freeFile(data);
		return;
	}

	if ((rv = gnutls_x509_privkey_import(x509PrivateKey_, &data, GNUTLS_X509_FMT_PEM)) < 0) {
		TRACE("setKeyFile: failed to import key as x509-fmt-pem. trying pkcs-plain.");
		rv = gnutls_x509_privkey_import_pkcs8(x509PrivateKey_, &data, GNUTLS_X509_FMT_PEM, nullptr, GNUTLS_PKCS_PLAIN);
	}

	if (rv < 0) {
		log(x0::Severity::error, "Error loading private key file(%s): %s", filename.c_str(), gnutls_strerror(rv));
		freeFile(data);
		return;
	}

	freeFile(data);
	TRACE("setKeyFile: success.");
}
Exemple #3
0
/**
 * FIXME Replace this with a tls_load_key function and use it
 * in tls_connection_create.
 *
 * Most probably we only need one context and key for all connections
 */
int
tls_check_keyfile(const char *keyfile)
{
    gnutls_x509_privkey_t key;
    gnutls_datum_t keycontent = { NULL, 0 };
    FILE *keyfp;
    size_t br;

    SSL_library_init();
    OpenSSL_add_all_algorithms();

    if (access(capture_get_keyfile(), R_OK) != 0)
        return 0;

    if (!(keyfp = fopen(capture_get_keyfile(), "rb")))
        return 0;

    fseek(keyfp, 0, SEEK_END);
    keycontent.size = ftell(keyfp);
    fseek(keyfp, 0, SEEK_SET);
    keycontent.data = sng_malloc(keycontent.size);
    br = fread(keycontent.data, 1, keycontent.size, keyfp);
    fclose(keyfp);

    gnutls_x509_privkey_init(&key);
    if (gnutls_x509_privkey_import(key, &keycontent, GNUTLS_X509_FMT_PEM) < 0)
        return 0;
    sng_free(keycontent.data);

    return 1;
}
gnutls_x509_privkey tls_load_privkey(requiem_client_profile_t *cp)
{
        int ret;
        size_t size;
        gnutls_datum data;
        char filename[256];
        gnutls_x509_privkey key;

        requiem_client_profile_get_tls_key_filename(cp, filename, sizeof(filename));

        ret = access(filename, F_OK);
        if ( ret < 0 )
                return gen_crypto(cp, filename,
                                  requiem_client_profile_get_uid(cp),
                                  requiem_client_profile_get_gid(cp));

        ret = _requiem_load_file(filename, &data.data, &size);
        if ( ret < 0 ) {
                fprintf(stderr, "could not load '%s': %s.\n", filename, requiem_strerror(ret));
                return NULL;
        }

        data.size = (unsigned int) size;

        gnutls_x509_privkey_init(&key);
        gnutls_x509_privkey_import(key, &data, GNUTLS_X509_FMT_PEM);

        _requiem_unload_file(data.data, size);

        return key;
}
Exemple #5
0
int mailstream_ssl_set_client_private_key_data(struct mailstream_ssl_context * ssl_context,
    unsigned char *pkey_der, size_t len)
{
#ifdef USE_SSL
#ifndef USE_GNUTLS
  EVP_PKEY *pkey = NULL;
  if (pkey_der != NULL && len > 0)
    pkey = d2i_AutoPrivateKey(NULL, (const unsigned char **)&pkey_der, len);
  ssl_context->client_pkey = (EVP_PKEY *)pkey;
  return 0;
#else
  gnutls_datum tmp;
  int r;
  ssl_context->client_pkey = NULL;
  if (len == 0)
    return 0;
  gnutls_x509_privkey_init(&(ssl_context->client_pkey));
  tmp.data = pkey_der;
  tmp.size = len;
  if ((r = gnutls_x509_privkey_import(ssl_context->client_pkey, &tmp, GNUTLS_X509_FMT_DER)) < 0) {
    gnutls_x509_privkey_deinit(ssl_context->client_pkey);
    ssl_context->client_pkey = NULL;
    return -1;
  }
  return 0;
#endif
#endif
  return -1;
}
Exemple #6
0
/*-
  * gnutls_x509_extract_key_pk_algorithm - This function returns the keys's PublicKey algorithm
  * @cert: is a DER encoded private key
  *
  * This function will return the public key algorithm of a DER encoded private
  * key.
  *
  * Returns a member of the gnutls_pk_algorithm_t enumeration on success,
  * or GNUTLS_E_UNKNOWN_PK_ALGORITHM on error.
  *
  -*/
int
gnutls_x509_extract_key_pk_algorithm (const gnutls_datum_t * key)
{
  gnutls_x509_privkey_t pkey;
  int ret, pk;

  ret = gnutls_x509_privkey_init (&pkey);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  ret = gnutls_x509_privkey_import (pkey, key, GNUTLS_X509_FMT_DER);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  pk = gnutls_x509_privkey_get_pk_algorithm (pkey);

  gnutls_x509_privkey_deinit (pkey);
  return pk;
}
void
doit (void)
{
  gnutls_x509_privkey_t key;
  gnutls_x509_crt_t crt;
  gnutls_digest_algorithm_t hash_algo;
  unsigned char _signature[128];
  size_t _signature_size = sizeof (_signature);
  gnutls_datum signature;
  int ret;
  size_t i;

  gnutls_global_init ();

  for (i = 0; i < sizeof (key_dat) / sizeof (key_dat[0]); i++)
    {
      success ("loop %d\n", i);

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

      ret = gnutls_x509_privkey_import (key, &key_dat[i], GNUTLS_X509_FMT_PEM);
      if (ret < 0)
	fail ("gnutls_x509_privkey_import\n");

      ret = gnutls_x509_privkey_sign_data (key, GNUTLS_DIG_SHA1, 0, &raw_data,
					   _signature, &_signature_size);
      if (ret < 0)
	fail ("gnutls_x509_privkey_sign_hash\n");

      ret = gnutls_x509_crt_init (&crt);
      if (ret < 0)
	fail ("gnutls_x509_crt_init\n");

      ret = gnutls_x509_crt_import (crt, &cert_dat[i], GNUTLS_X509_FMT_PEM);
      if (ret < 0)
	fail ("gnutls_x509_crt_import\n");

      signature.data = _signature;
      signature.size = _signature_size;

      ret = gnutls_x509_crt_get_verify_algorithm (crt, &signature, &hash_algo);
      if (ret < 0 || hash_algo != GNUTLS_DIG_SHA1)
	fail ("gnutls_x509_crt_get_verify_algorithm\n");

      ret = gnutls_x509_crt_verify_hash (crt, 0, &hash_data, &signature);
      if (ret < 0)
	fail ("gnutls_x509_privkey_verify_hash\n");

      gnutls_x509_privkey_deinit (key);
      gnutls_x509_crt_deinit (crt);
    }

  gnutls_global_deinit ();
}
Exemple #8
0
static int import_key(gnutls_certificate_credentials_t xcred, const gnutls_datum_t *skey, const gnutls_datum_t *cert)
{
	gnutls_x509_privkey_t key;
	gnutls_x509_crt_t *crt_list;
	unsigned crt_list_size, idx, i;
	gnutls_datum_t tcert;
	int ret;

	assert(gnutls_x509_privkey_init(&key)>=0);

	ret = gnutls_x509_crt_list_import2(&crt_list, &crt_list_size, cert, GNUTLS_X509_FMT_PEM, 0);
	if (ret < 0) {
		fail("error in gnutls_x509_crt_list_import2: %s\n", gnutls_strerror(ret));
	}

	ret = gnutls_x509_privkey_import(key, skey, GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fail("error in key import: %s\n", gnutls_strerror(ret));
	}

	ret = gnutls_certificate_set_x509_key(xcred, crt_list,
				crt_list_size, key);
	if (ret < 0) {
		success("error in gnutls_certificate_set_x509_key: %s\n", gnutls_strerror(ret));
		idx = ret;
		goto cleanup;
	}

	/* return index */
	idx = ret;

	/* verify whether the stored certificate match the ones we have */
	for (i=0;i<MIN(2, crt_list_size);i++) {
		ret = gnutls_certificate_get_crt_raw(xcred, idx, i, &tcert);
		if (ret < 0) {
			fail("error in %d: cert: %d: %s\n", __LINE__, i, gnutls_strerror(ret));
			exit(1);
		}

		compare(&tcert, cert->data+i);
	}

 cleanup:
	gnutls_x509_privkey_deinit(key);
	for (i=0;i<crt_list_size;i++) {
		gnutls_x509_crt_deinit(crt_list[i]);
	}
	gnutls_free(crt_list);

	return idx;
}
static gchar* _make_rsasha1_base64_signature(const gchar* base_string, 
                                             const gchar* key)
{
    gnutls_privkey_t pkey;
    gnutls_x509_privkey_t x509_pkey;
    gnutls_datum_t pkey_data;
    gnutls_datum_t signature;
    
    gchar* out = NULL;

    pkey_data.data = (guchar*)key;
    pkey_data.size = strlen(key);

    gnutls_privkey_init(&pkey);
    gnutls_x509_privkey_init(&x509_pkey);
    
    int res = gnutls_x509_privkey_import(x509_pkey, &pkey_data, GNUTLS_X509_FMT_PEM);
    if (res != GNUTLS_E_SUCCESS) {
        goto out;
    }
    
    res = gnutls_privkey_import_x509(pkey, x509_pkey, 0);
    
    if (res != GNUTLS_E_SUCCESS) {
        goto out;
    }

    res = gnutls_privkey_sign_data(pkey, GNUTLS_DIG_SHA1, 0, &pkey_data,
                                   &signature);
    if (res != GNUTLS_E_SUCCESS) {
        goto out;
    }

    out = g_malloc0((signature.size / 3 + 1) * 4 + 4);
    gint state = 0;
    gint save = 0;
    gchar* p = out;
    
    p += g_base64_encode_step(signature.data, signature.size,
                             FALSE, p, &state, &save);
    g_base64_encode_close(FALSE, p, &state, &save);
    
    gnutls_free(signature.data);
out:
    gnutls_x509_privkey_deinit(x509_pkey);
    gnutls_privkey_deinit(pkey);
    
    return out;
    
}
Exemple #10
0
/**
 * gnutls_x509_privkey_import2:
 * @key: The structure to store the parsed key
 * @data: The DER or PEM encoded key.
 * @format: One of DER or PEM
 * @password: A password (optional)
 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
 *
 * This function will import the given DER or PEM encoded key, to 
 * the native #gnutls_x509_privkey_t format, irrespective of the
 * input format. The input format is auto-detected.
 *
 * The supported formats are basic unencrypted key, PKCS8, PKCS12,
 * and the openssl format.
 *
 * If the provided key is encrypted but no password was given, then
 * %GNUTLS_E_DECRYPTION_FAILED is returned.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_privkey_import2(gnutls_x509_privkey_t key,
			    const gnutls_datum_t * data,
			    gnutls_x509_crt_fmt_t format,
			    const char *password, unsigned int flags)
{
	int ret = 0;

	if (password == NULL && !(flags & GNUTLS_PKCS_NULL_PASSWORD)) {
		ret = gnutls_x509_privkey_import(key, data, format);
		if (ret < 0) {
			gnutls_assert();
		}
	}

	if ((password != NULL || (flags & GNUTLS_PKCS_NULL_PASSWORD))
	    || ret < 0) {
		ret =
		    gnutls_x509_privkey_import_pkcs8(key, data, format,
						     password, flags);
		if (ret < 0) {
			if (ret == GNUTLS_E_DECRYPTION_FAILED)
				goto cleanup;
			ret =
			    import_pkcs12_privkey(key, data, format,
						  password, flags);
			if (ret < 0 && format == GNUTLS_X509_FMT_PEM) {
				if (ret == GNUTLS_E_DECRYPTION_FAILED)
					goto cleanup;

				ret =
				    gnutls_x509_privkey_import_openssl(key,
								       data,
								       password);
				if (ret < 0) {
					gnutls_assert();
					goto cleanup;
				}
			} else {
				gnutls_assert();
				goto cleanup;
			}
		}
	}

	ret = 0;

      cleanup:
	return ret;
}
Exemple #11
0
/** Private function which import the given key into a gnutls structure.
 *
 * @param key_name The filename of the private key to import.
 * @param key the gnutls key structure.
 *
 * @return 1 if the key was successfully imported.
 */
static userpref_error_t userpref_import_key(const char* key_name, gnutls_x509_privkey_t key)
{
	userpref_error_t ret = USERPREF_E_INVALID_CONF;
	gnutls_datum_t pem_key = { NULL, 0 };

	if (userpref_get_file_contents(key_name, &pem_key)) {
			if (GNUTLS_E_SUCCESS == gnutls_x509_privkey_import(key, &pem_key, GNUTLS_X509_FMT_PEM))
				ret = USERPREF_E_SUCCESS;
			else
				ret = USERPREF_E_SSL_ERROR;
	}
	gnutls_free(pem_key.data);
	return ret;
}
/* Load the private key.
 * @mand should be non zero if it is required to read a private key.
 */
gnutls_x509_privkey_t
load_x509_private_key (int mand, common_info_st * info)
{
  gnutls_x509_privkey_t key;
  int ret;
  gnutls_datum_t dat;
  size_t size;

  if (!info->privkey && !mand)
    return NULL;

  if (info->privkey == NULL)
    error (EXIT_FAILURE, 0, "missing --load-privkey");

  ret = gnutls_x509_privkey_init (&key);
  if (ret < 0)
    error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));

  dat.data = read_binary_file (info->privkey, &size);
  dat.size = size;

  if (!dat.data)
    error (EXIT_FAILURE, errno, "reading --load-privkey: %s", info->privkey);

  if (info->pkcs8)
    {
      const char *pass = get_pass ();
      ret =
        gnutls_x509_privkey_import_pkcs8 (key, &dat, info->incert_format,
                                          pass, 0);
    }
  else
    ret = gnutls_x509_privkey_import (key, &dat, info->incert_format);

  free (dat.data);

  if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
    {
      error (EXIT_FAILURE, 0,
             "import error: could not find a valid PEM header; "
             "check if your key is PKCS #8 or PKCS #12 encoded");
    }

  if (ret < 0)
    error (EXIT_FAILURE, 0, "importing --load-privkey: %s: %s",
           info->privkey, gnutls_strerror (ret));

  return key;
}
Exemple #13
0
void doit(void)
{
	gnutls_dh_params_t dh_params;
	gnutls_x509_privkey_t privkey;
	gnutls_datum_t p1, g1, p2, g2, q;
	unsigned bits = 0;
	int ret;

	/* import DH parameters from DSA key and verify they are the same */
	gnutls_dh_params_init(&dh_params);
	gnutls_x509_privkey_init(&privkey);

	ret = gnutls_x509_privkey_import(privkey, &dsa_key, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		fail("error in %s: %d\n", __FILE__, __LINE__);

	ret = gnutls_dh_params_import_dsa(dh_params, privkey);
	if (ret < 0)
		fail("error in %s: %d\n", __FILE__, __LINE__);

	ret = gnutls_dh_params_export_raw(dh_params, &p1, &g1, &bits);
	if (ret < 0)
		fail("error in %s: %d\n", __FILE__, __LINE__);

	ret = gnutls_x509_privkey_export_dsa_raw(privkey, &p2, &q, &g2, NULL, NULL);
	if (ret < 0)
		fail("error in %s: %d\n", __FILE__, __LINE__);

	if (bits > q.size*8  || bits < q.size*8-8)
		fail("error in %s: %d\n", __FILE__, __LINE__);

	if (compare(&p1, &p2) != 0)
		fail("error in %s: %d\n", __FILE__, __LINE__);

	if (compare(&g1, &g2) != 0)
		fail("error in %s: %d\n", __FILE__, __LINE__);

	gnutls_free(p1.data);
	gnutls_free(g1.data);
	gnutls_free(p2.data);
	gnutls_free(g2.data);
	gnutls_free(q.data);

	gnutls_dh_params_deinit(dh_params);
	gnutls_x509_privkey_deinit(privkey);
	success("all ok\n");
}
Exemple #14
0
struct SSLConnection *
tls_connection_create(struct in_addr caddr, uint16_t cport, struct in_addr saddr, uint16_t sport) {
    struct SSLConnection *conn = NULL;
    gnutls_datum_t keycontent = { NULL, 0 };
    FILE *keyfp;
    gnutls_x509_privkey_t spkey;
    size_t br;

    // Allocate memory for this connection
    conn = sng_malloc(sizeof(struct SSLConnection));

    memcpy(&conn->client_addr, &caddr, sizeof(struct in_addr));
    memcpy(&conn->server_addr, &saddr, sizeof(struct in_addr));
    memcpy(&conn->client_port, &cport, sizeof(uint16_t));
    memcpy(&conn->server_port, &sport, sizeof(uint16_t));

    SSL_library_init();
    OpenSSL_add_all_algorithms();

    if (!(conn->ssl_ctx = SSL_CTX_new(SSLv23_server_method())))
        return NULL;

    if (!(conn->ssl = SSL_new(conn->ssl_ctx)))
        return NULL;

    if (!(keyfp = fopen(capture_get_keyfile(), "rb")))
        return NULL;
    fseek(keyfp, 0, SEEK_END);
    keycontent.size = ftell(keyfp);
    fseek(keyfp, 0, SEEK_SET);
    keycontent.data = sng_malloc(keycontent.size);
    br = fread(keycontent.data, 1, keycontent.size, keyfp);
    fclose(keyfp);

    gnutls_x509_privkey_init(&spkey);
    gnutls_x509_privkey_import(spkey, &keycontent, GNUTLS_X509_FMT_PEM);
    sng_free(keycontent.data);
    gnutls_privkey_init(&conn->server_private_key);
    gnutls_privkey_import_x509(conn->server_private_key, spkey, 0);

    // Add this connection to the list
    conn->next = connections;
    connections = conn;

    return conn;
}
Exemple #15
0
static int import_Key(QWidget * w, gnutls_x509_privkey_t * privkey,
                      gnutls_datum_t * raw)
{
    int ret;

    if (raw->size == 0)
        return -1;

    gnutls_x509_privkey_init(privkey);

    ret =
        gnutls_x509_privkey_import2(*privkey, raw, GNUTLS_X509_FMT_PEM, NULL,
                                    0);
    if (ret == GNUTLS_E_DECRYPTION_FAILED && w != NULL) {
        bool ok;
        QString text;
        text =
            QInputDialog::getText(w,
                                  QLatin1String
                                  ("This file requires a password"),
                                  QLatin1String("Please enter your password"),
                                  QLineEdit::Password, QString(), &ok);
        if (!ok) {
            ret = -1;
            goto fail;
        }

        ret =
            gnutls_x509_privkey_import2(*privkey, raw, GNUTLS_X509_FMT_PEM,
                                        text.toAscii().data(), 0);
    }

    if (ret == GNUTLS_E_BASE64_DECODING_ERROR
            || ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
        ret = gnutls_x509_privkey_import(*privkey, raw, GNUTLS_X509_FMT_DER);
    if (ret < 0) {
        goto fail;
    }

    return 0;
fail:
    gnutls_x509_privkey_deinit(*privkey);
    *privkey = NULL;
    return ret;
}
Exemple #16
0
/* Load the certificate and the private key.
 */
static void
load_keys (void)
{
    int ret;
    gnutls_datum_t data;

    data = load_file (CERT_FILE);
    if (data.data == NULL)
    {
        fprintf (stderr, "*** Error loading cert file.\n");
        exit (1);
    }
    gnutls_x509_crt_init (&crt);

    ret = gnutls_x509_crt_import (crt, &data, GNUTLS_X509_FMT_PEM);
    if (ret < 0)
    {
        fprintf (stderr, "*** Error loading key file: %s\n",
                 gnutls_strerror (ret));
        exit (1);
    }

    unload_file (data);

    data = load_file (KEY_FILE);
    if (data.data == NULL)
    {
        fprintf (stderr, "*** Error loading key file.\n");
        exit (1);
    }

    gnutls_x509_privkey_init (&key);

    ret = gnutls_x509_privkey_import (key, &data, GNUTLS_X509_FMT_PEM);
    if (ret < 0)
    {
        fprintf (stderr, "*** Error loading key file: %s\n",
                 gnutls_strerror (ret));
        exit (1);
    }

    unload_file (data);

}
Exemple #17
0
int
_gnutls_x509_raw_privkey_to_gkey (gnutls_privkey * privkey,
				  const gnutls_datum_t * raw_key,
				  gnutls_x509_crt_fmt_t type)
{
  gnutls_x509_privkey_t tmpkey;
  int ret;

  ret = gnutls_x509_privkey_init (&tmpkey);
  if (ret < 0)
    {
      gnutls_assert ();
      return ret;
    }

  ret = gnutls_x509_privkey_import (tmpkey, raw_key, type);

#ifdef ENABLE_PKI
  /* If normal key decoding doesn't work try decoding a plain PKCS #8 key */
  if (ret < 0)
    ret = gnutls_x509_privkey_import_pkcs8 (tmpkey, raw_key, type,
					    NULL, GNUTLS_PKCS_PLAIN);
#endif

  if (ret < 0)
    {
      gnutls_assert ();
      gnutls_x509_privkey_deinit (tmpkey);
      return ret;
    }

  ret = _gnutls_x509_privkey_to_gkey (privkey, tmpkey);
  if (ret < 0)
    {
      gnutls_assert ();
      gnutls_x509_privkey_deinit (tmpkey);
      return ret;
    }

  gnutls_x509_privkey_deinit (tmpkey);

  return 0;
}
static gnutls_privkey_t _load_privkey(gnutls_datum_t *dat, common_info_st * info)
{
int ret;
gnutls_privkey_t key;
gnutls_x509_privkey_t xkey;

  ret = gnutls_x509_privkey_init (&xkey);
  if (ret < 0)
    error (EXIT_FAILURE, 0, "x509_privkey_init: %s", gnutls_strerror (ret));

  ret = gnutls_privkey_init (&key);
  if (ret < 0)
    error (EXIT_FAILURE, 0, "privkey_init: %s", gnutls_strerror (ret));

  if (info->pkcs8)
    {
      const char *pass = get_pass ();
      ret =
        gnutls_x509_privkey_import_pkcs8 (xkey, dat, info->incert_format,
                                          pass, 0);
    }
  else
    ret = gnutls_x509_privkey_import (xkey, dat, info->incert_format);

  if (ret == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
    {
      error (EXIT_FAILURE, 0,
             "import error: could not find a valid PEM header; "
             "check if your key is PKCS #8 or PKCS #12 encoded");
    }

  if (ret < 0)
    error (EXIT_FAILURE, 0, "importing --load-privkey: %s: %s",
           info->privkey, gnutls_strerror (ret));

  ret = gnutls_privkey_import_x509(key, xkey, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
  if (ret < 0)
    error (EXIT_FAILURE, 0, "gnutls_privkey_import_x509: %s",
           gnutls_strerror (ret));
  
  return key;
}
Exemple #19
0
static
int import_dsa_dh(gnutls_dh_params_t dh_params, gnutls_datum_t *params, gnutls_x509_crt_fmt_t format)
{
	gnutls_x509_privkey_t pkey;
	int ret;

	ret = gnutls_x509_privkey_init(&pkey);
	if (ret < 0)
		return ret;

	ret = gnutls_x509_privkey_import(pkey, params, format);
	if (ret < 0)
		return ret;

	ret = gnutls_dh_params_import_dsa(dh_params, pkey);

	gnutls_x509_privkey_deinit(pkey);

	return ret;
}
Exemple #20
0
/**
 * epc_tls_private_key_load:
 * @filename: name of a file to read the key from, in the GLib file name encoding
 * @error: return location for a #GError, or %NULL
 *
 * Reads a PEM encoded private X.509 key.
 *
 * If the call was successful, the newly created private key object is
 * returned. This key can be used with functions of the <citetitle>GNU
 * TLS</citetitle> library. If the call was not successful, it returns %NULL
 * and sets @error. The error domain is #EPC_TLS_ERROR. Error codes are taken
 * from the <citetitle>GNU TLS</citetitle> library.
 *
 * Returns: The newly created key object, or %NULL.
 */
gnutls_x509_privkey_t
epc_tls_private_key_load (const gchar *filename,
                          GError     **error)
{
  gnutls_x509_privkey_t key = NULL;
  gint rc = GNUTLS_E_SUCCESS;
  gchar *contents = NULL;
  gnutls_datum_t buffer;

  g_return_val_if_fail (NULL != filename, NULL);

  if (g_file_get_contents (filename, &contents, (gsize*) &buffer.size, error))
    {
      if (EPC_DEBUG_LEVEL (1))
        g_debug ("%s: Loading private key `%s'", G_STRLOC, filename);

      buffer.data = (guchar*) contents;

      epc_tls_check (rc = gnutls_x509_privkey_init (&key));
      epc_tls_check (rc = gnutls_x509_privkey_import (key, &buffer, GNUTLS_X509_FMT_PEM));
    }

out:
  if (GNUTLS_E_SUCCESS != rc)
    {
      g_set_error (error, EPC_TLS_ERROR, rc,
                   _("Cannot import private server key '%s': %s"),
                   filename, gnutls_strerror (rc));

      if (key)
        gnutls_x509_privkey_deinit (key);

      key = NULL;
    }

  g_free (contents);

  return key;
}
Exemple #21
0
/* Load the certificate and the private key.
 */
static void
load_keys (void)
{
  unsigned int crt_num;
  int ret;
  gnutls_datum_t data;

  if (x509_certfile != NULL && x509_keyfile != NULL)
    {
      data = load_file (x509_certfile);
      if (data.data == NULL)
	{
	  fprintf (stderr, "*** Error loading cert file.\n");
	  exit (1);
	}

      crt_num = MAX_CRT;
      ret =
	gnutls_x509_crt_list_import (x509_crt, &crt_num, &data,
				     GNUTLS_X509_FMT_PEM,
				     GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
      if (ret < 0)
	{
	  if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
	    {
	      fprintf (stderr,
		       "*** Error loading cert file: Too many certs %d\n",
		       crt_num);

	    }
	  else
	    {
	      fprintf (stderr,
		       "*** Error loading cert file: %s\n",
		       gnutls_strerror (ret));
	    }
	  exit (1);
	}
      x509_crt_size = ret;
      fprintf (stderr, "Processed %d client certificates...\n", ret);

      unload_file (data);

      data = load_file (x509_keyfile);
      if (data.data == NULL)
	{
	  fprintf (stderr, "*** Error loading key file.\n");
	  exit (1);
	}

      gnutls_x509_privkey_init (&x509_key);

      ret = gnutls_x509_privkey_import (x509_key, &data, GNUTLS_X509_FMT_PEM);
      if (ret < 0)
	{
	  fprintf (stderr, "*** Error loading key file: %s\n",
		   gnutls_strerror (ret));
	  exit (1);
	}

      unload_file (data);

      fprintf (stderr, "Processed %d client X.509 certificates...\n",
	       x509_crt_size);
    }
#ifdef ENABLE_OPENPGP
  if (pgp_certfile != NULL && pgp_keyfile != NULL)
    {
      data = load_file (pgp_certfile);
      if (data.data == NULL)
	{
	  fprintf (stderr, "*** Error loading PGP cert file.\n");
	  exit (1);
	}
      gnutls_openpgp_crt_init (&pgp_crt);

      ret =
	gnutls_openpgp_crt_import (pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64);
      if (ret < 0)
	{
	  fprintf (stderr,
		   "*** Error loading PGP cert file: %s\n",
		   gnutls_strerror (ret));
	  exit (1);
	}


      unload_file (data);

      data = load_file (pgp_keyfile);
      if (data.data == NULL)
	{
	  fprintf (stderr, "*** Error loading PGP key file.\n");
	  exit (1);
	}

      gnutls_openpgp_privkey_init (&pgp_key);

      ret =
	gnutls_openpgp_privkey_import (pgp_key, &data,
				       GNUTLS_OPENPGP_FMT_BASE64, NULL, 0);
      if (ret < 0)
	{
	  fprintf (stderr,
		   "*** Error loading PGP key file: %s\n",
		   gnutls_strerror (ret));
	  exit (1);
	}

      unload_file (data);

      if (info.pgp_subkey != NULL)
	{
	  gnutls_openpgp_keyid_t keyid;

	  if (strcasecmp (info.pgp_subkey, "auto") == 0)
	    {
	      ret = gnutls_openpgp_crt_get_auth_subkey (pgp_crt, keyid, 1);
	      if (ret < 0)
		{
		  fprintf (stderr,
			   "*** Error setting preferred sub key id (%s): %s\n",
			   info.pgp_subkey, gnutls_strerror (ret));
		  exit (1);
		}
	    }
	  else
	    get_keyid (keyid, info.pgp_subkey);

	  ret = gnutls_openpgp_crt_set_preferred_key_id (pgp_crt, keyid);
	  if (ret >= 0)
	    ret =
	      gnutls_openpgp_privkey_set_preferred_key_id (pgp_key, keyid);
	  if (ret < 0)
	    {
	      fprintf (stderr,
		       "*** Error setting preferred sub key id (%s): %s\n",
		       info.pgp_subkey, gnutls_strerror (ret));
	      exit (1);
	    }
	}

      fprintf (stderr, "Processed 1 client PGP certificate...\n");
    }
#endif

}
Exemple #22
0
void doit(void)
{
	gnutls_x509_privkey_t pkey;
	gnutls_x509_crt_t crt;
	gnutls_x509_crt_t crt2;
	const char *err = NULL;
	gnutls_datum_t out;
	size_t s = 0;
	int ret;

	ret = global_init();
	if (ret < 0)
		fail("global_init\n");

	gnutls_global_set_time_function(mytime);
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(4711);

	ret = gnutls_x509_crt_init(&crt);
	if (ret != 0)
		fail("gnutls_x509_crt_init\n");

	ret = gnutls_x509_crt_init(&crt2);
	if (ret != 0)
		fail("gnutls_x509_crt_init\n");

	ret = gnutls_x509_crt_import(crt2, &server_ecc_cert, GNUTLS_X509_FMT_PEM);
	if (ret != 0)
		fail("gnutls_x509_crt_import\n");

	ret = gnutls_x509_privkey_init(&pkey);
	if (ret != 0)
		fail("gnutls_x509_privkey_init\n");

	ret = gnutls_x509_privkey_import(pkey, &key_dat, GNUTLS_X509_FMT_PEM);
	if (ret != 0)
		fail("gnutls_x509_privkey_import\n");

	/* Setup CRT */

	ret = gnutls_x509_crt_set_version(crt, 3);
	if (ret != 0)
		fail("gnutls_x509_crt_set_version\n");

	ret = gnutls_x509_crt_set_serial(crt, "\x0a\x11\x00", 3);
	if (ret != 0)
		fail("gnutls_x509_crt_set_serial\n");

	ret = gnutls_x509_crt_set_expiration_time(crt, -1);
	if (ret != 0)
		fail("error\n");

	ret = gnutls_x509_crt_set_activation_time(crt, mytime(0));
	if (ret != 0)
		fail("error\n");

	ret = gnutls_x509_crt_set_key(crt, pkey);
	if (ret != 0)
		fail("gnutls_x509_crt_set_key\n");

	ret = gnutls_x509_crt_set_basic_constraints(crt, 0, -1);
	if (ret < 0) {
		fail("error\n");
	}

	ret = gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_DIGITAL_SIGNATURE);
	if (ret != 0)
		fail("gnutls_x509_crt_set_key_usage %d\n", ret);

	ret = gnutls_x509_crt_set_dn(crt, "o = none to\\, mention,cn = nikos", &err);
	if (ret < 0) {
		fail("gnutls_x509_crt_set_dn: %s, %s\n", gnutls_strerror(ret), err);
	}


	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME,
						   "foo", 3, 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME,
						   "*****@*****.**", strlen("*****@*****.**"), 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME,
						   "ινβάλιντ@bar.org", strlen("ινβάλιντ@bar.org"), 1);
	if (ret != GNUTLS_E_INVALID_UTF8_EMAIL)
		fail("gnutls_x509_crt_set_subject_alt_name\n");


	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS,
						   "\xc1\x5c\x96\x3", 4, 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_IPADDRESS,
						   "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 16, 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME,
						   "apa", 3, 0);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_DNSNAME,
						   "απαλό.com", strlen("απαλό.com"), 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");

#ifdef HAVE_LIBIDN
	ret = gnutls_x509_crt_set_subject_alt_name(crt, GNUTLS_SAN_RFC822NAME,
						   "test@νίκο.org", strlen("test@νίκο.org"), 1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_subject_alt_name\n");
#endif

	s = 0;
	ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL);
	if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
		fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret);

	s = 0;
	ret =
	    gnutls_x509_crt_set_key_purpose_oid(crt,
						GNUTLS_KP_TLS_WWW_SERVER,
						0);
	if (ret != 0)
		fail("gnutls_x509_crt_set_key_purpose_oid %d\n", ret);

	s = 0;
	ret = gnutls_x509_crt_get_key_purpose_oid(crt, 0, NULL, &s, NULL);
	if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
		fail("gnutls_x509_crt_get_key_purpose_oid %d\n", ret);

	s = 0;
	ret =
	    gnutls_x509_crt_set_key_purpose_oid(crt,
						GNUTLS_KP_TLS_WWW_CLIENT,
						1);
	if (ret != 0)
		fail("gnutls_x509_crt_set_key_purpose_oid2 %d\n", ret);

	ret = gnutls_x509_crt_set_issuer_dn(crt, "cn = my CA, o = big\\, and one", &err);
	if (ret < 0) {
		fail("gnutls_x509_crt_set_issuer_dn: %s, %s\n", gnutls_strerror(ret), err);
	}

	ret = gnutls_x509_crt_sign2(crt, crt, pkey, GNUTLS_DIG_SHA256, 0);
	if (ret < 0)
		fail("gnutls_x509_crt_sign2: %s\n", gnutls_strerror(ret));



	ret = gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_FULL, &out);
	if (ret != 0)
		fail("gnutls_x509_crt_print\n");
	if (debug)
		printf("crt: %.*s\n", out.size, out.data);
	gnutls_free(out.data);


	s = 0;
	ret = gnutls_x509_crt_get_extension_info(crt, 0, NULL, &s, NULL);
	if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
		fail("gnutls_x509_crt_get_extension_info2: %s\n", strerror(ret));

	s = 0;
	ret = gnutls_x509_crt_get_extension_data(crt, 0, NULL, &s);
	if (ret != 0)
		fail("gnutls_x509_crt_get_extension_data: %s\n", strerror(ret));

	ret = gnutls_x509_crt_get_raw_issuer_dn(crt, &out);
	if (ret < 0 || out.size == 0)
		fail("gnutls_x509_crt_get_raw_issuer_dn: %s\n", gnutls_strerror(ret));

	if (out.size != 45 ||
	    memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) {
		hexprint(out.data, out.size);
		fail("issuer DN comparison failed\n");
	}
	gnutls_free(out.data);

	ret = gnutls_x509_crt_get_raw_dn(crt, &out);
	if (ret < 0 || out.size == 0)
		fail("gnutls_x509_crt_get_raw_dn: %s\n", gnutls_strerror(ret));

	if (out.size != 45 ||
	    memcmp(out.data, "\x30\x2b\x31\x0e\x30\x0c\x06\x03\x55\x04\x03\x13\x05\x6e\x69\x6b\x6f\x73\x31\x19\x30\x17\x06\x03\x55\x04\x0a\x13\x10\x6e\x6f\x6e\x65\x20\x74\x6f\x2c\x20\x6d\x65\x6e\x74\x69\x6f\x6e", 45) != 0) {
		fail("DN comparison failed\n");
	}
	gnutls_free(out.data);

	ret = gnutls_x509_crt_equals(crt, crt);
	if (ret == 0) {
		fail("equality test failed\n");
	}

	ret = gnutls_x509_crt_equals(crt, crt2);
	if (ret != 0) {
		fail("equality test failed\n");
	}
	assert(gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_PEM, &out) >= 0);

#ifdef HAVE_LIBIDN
	assert(out.size == saved_crt.size);
	assert(memcmp(out.data, saved_crt.data, out.size)==0);
#endif

	gnutls_free(out.data);

	gnutls_x509_crt_deinit(crt);
	gnutls_x509_crt_deinit(crt2);
	gnutls_x509_privkey_deinit(pkey);

	gnutls_global_deinit();
}
Exemple #23
0
EAPI Eet_Key *
eet_identity_open(const char               *certificate_file,
                  const char               *private_key_file,
                  Eet_Key_Password_Callback cb)
{
#ifdef HAVE_SIGNATURE
   /* Signature declarations */
   Eet_Key *key = NULL;
# ifdef HAVE_GNUTLS
   /* Gnutls private declarations */
   Eina_File *f = NULL;
   void *data = NULL;
   gnutls_datum_t load_file = { NULL, 0 };
   char pass[1024];

   if (!emile_cipher_init()) return NULL;

   /* Init */
   if (!(key = malloc(sizeof(Eet_Key))))
     goto on_error;

   key->references = 1;

   if (gnutls_x509_crt_init(&(key->certificate)))
     goto on_error;

   if (gnutls_x509_privkey_init(&(key->private_key)))
     goto on_error;

   /* Mmap certificate_file */
   f = eina_file_open(certificate_file, 0);
   if (!f)
     goto on_error;

   /* let's make mmap safe and just get 0 pages for IO erro */
   eina_mmap_safety_enabled_set(EINA_TRUE);

   data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
   if (!data) goto on_error;

   /* Import the certificate in Eet_Key structure */
   load_file.data = data;
   load_file.size = eina_file_size_get(f);
   if (gnutls_x509_crt_import(key->certificate, &load_file,
                              GNUTLS_X509_FMT_PEM) < 0)
     goto on_error;

   eina_file_map_free(f, data);

   /* Reset values */
   eina_file_close(f);
   f = NULL;
   data = NULL;
   load_file.data = NULL;
   load_file.size = 0;

   /* Mmap private_key_file */
   f = eina_file_open(private_key_file, 0);
   if (!f)
     goto on_error;

   /* let's make mmap safe and just get 0 pages for IO erro */
   eina_mmap_safety_enabled_set(EINA_TRUE);

   data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
   if (!data)
     goto on_error;

   /* Import the private key in Eet_Key structure */
   load_file.data = data;
   load_file.size = eina_file_size_get(f);
   /* Try to directly import the PEM encoded private key */
   if (gnutls_x509_privkey_import(key->private_key, &load_file,
                                  GNUTLS_X509_FMT_PEM) < 0)
     {
        /* Else ask for the private key pass */
         if (cb && cb(pass, 1024, 0, NULL))
           {
     /* If pass then try to decode the pkcs 8 private key */
               if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file,
                                                    GNUTLS_X509_FMT_PEM, pass, 0))
                 goto on_error;
           }
         else
         /* Else try to import the pkcs 8 private key without pass */
         if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file,
                                              GNUTLS_X509_FMT_PEM, NULL, 1))
           goto on_error;
     }

   eina_file_map_free(f, data);
   eina_file_close(f);

   return key;

on_error:
   if (data) eina_file_map_free(f, data);
   if (f) eina_file_close(f);

   if (key)
     {
        if (key->certificate)
          gnutls_x509_crt_deinit(key->certificate);

        if (key->private_key)
          gnutls_x509_privkey_deinit(key->private_key);

        free(key);
     }

# else /* ifdef HAVE_GNUTLS */
   /* Openssl private declarations */
   FILE *fp;
   EVP_PKEY *pkey = NULL;
   X509 *cert = NULL;

   if (!emile_cipher_init()) return NULL;

   /* Load the X509 certificate in memory. */
   fp = fopen(certificate_file, "rb");
   if (!fp)
     return NULL;

   cert = PEM_read_X509(fp, NULL, NULL, NULL);
   fclose(fp);
   if (!cert)
     goto on_error;

   /* Check the presence of the public key. Just in case. */
   pkey = X509_get_pubkey(cert);
   if (!pkey)
     goto on_error;

   /* Load the private key in memory. */
   fp = fopen(private_key_file, "rb");
   if (!fp)
     goto on_error;

   pkey = PEM_read_PrivateKey(fp, NULL, cb, NULL);
   fclose(fp);
   if (!pkey)
     goto on_error;

   /* Load the certificate and the private key in Eet_Key structure */
   key = malloc(sizeof(Eet_Key));
   if (!key)
     goto on_error;

   key->references = 1;
   key->certificate = cert;
   key->private_key = pkey;

   return key;

on_error:
   if (cert)
     X509_free(cert);

   if (pkey)
     EVP_PKEY_free(pkey);

# endif /* ifdef HAVE_GNUTLS */
#else
   (void) certificate_file;
   (void) private_key_file;
   (void) cb;
#endif /* ifdef HAVE_SIGNATURE */
   return NULL;
}
Exemple #24
0
/* Load the certificate and the private key.
 */
static void
load_keys (void)
{
  unsigned int crt_num;
  int ret, i;
  gnutls_datum_t data = { NULL, 0 };
  gnutls_x509_crt_t crt_list[MAX_CRT];
#ifdef ENABLE_PKCS11
  gnutls_pkcs11_privkey_t pkcs11_key;
#endif
  gnutls_x509_privkey_t tmp_key;
  unsigned char keyid[GNUTLS_OPENPGP_KEYID_SIZE];

  if (x509_certfile != NULL && x509_keyfile != NULL)
    {
#ifdef ENABLE_PKCS11
      if (strncmp (x509_certfile, "pkcs11:", 7) == 0)
        {
          crt_num = 1;
          gnutls_x509_crt_init (&crt_list[0]);

          ret =
            gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile, 0);

          if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
            ret =
              gnutls_x509_crt_import_pkcs11_url (crt_list[0], x509_certfile,
                                                 GNUTLS_PKCS11_OBJ_FLAG_LOGIN);

          if (ret < 0)
            {
              fprintf (stderr, "*** Error loading cert file.\n");
              exit (1);
            }
          x509_crt_size = 1;
        }
      else
#endif /* ENABLE_PKCS11 */
        {

          data = load_file (x509_certfile);
          if (data.data == NULL)
            {
              fprintf (stderr, "*** Error loading cert file.\n");
              exit (1);
            }

          crt_num = MAX_CRT;
          ret =
            gnutls_x509_crt_list_import (crt_list, &crt_num, &data,
                                         GNUTLS_X509_FMT_PEM,
                                         GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
          if (ret < 0)
            {
              if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
                {
                  fprintf (stderr,
                           "*** Error loading cert file: Too many certs %d\n",
                           crt_num);

                }
              else
                {
                  fprintf (stderr,
                           "*** Error loading cert file: %s\n",
                           gnutls_strerror (ret));
                }
              exit (1);
            }
          x509_crt_size = ret;
        }
      
      for (i=0;i<x509_crt_size;i++)
        {
          ret = gnutls_pcert_import_x509(&x509_crt[i], crt_list[i], 0);
          if (ret < 0)
            {
              fprintf(stderr, "*** Error importing crt to pcert: %s\n",
                gnutls_strerror(ret));
              exit(1);
            }
          gnutls_x509_crt_deinit(crt_list[i]);
        }

      unload_file (&data);

      ret = gnutls_privkey_init(&x509_key);
      if (ret < 0)
         {
           fprintf (stderr, "*** Error initializing key: %s\n",
                    gnutls_strerror (ret));
           exit (1);
         }

#ifdef ENABLE_PKCS11
      if (strncmp (x509_keyfile, "pkcs11:", 7) == 0)
        {
          gnutls_pkcs11_privkey_init (&pkcs11_key);

          ret =
            gnutls_pkcs11_privkey_import_url (pkcs11_key, x509_keyfile, 0);
          if (ret < 0)
            {
              fprintf (stderr, "*** Error loading url: %s\n",
                       gnutls_strerror (ret));
              exit (1);
            }

          ret = gnutls_privkey_import_pkcs11( x509_key, pkcs11_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
          if (ret < 0)
            {
              fprintf (stderr, "*** Error loading url: %s\n",
                       gnutls_strerror (ret));
              exit (1);
            }
        }
      else
#endif /* ENABLE_PKCS11 */
        {
          data = load_file (x509_keyfile);
          if (data.data == NULL)
            {
              fprintf (stderr, "*** Error loading key file.\n");
              exit (1);
            }

          gnutls_x509_privkey_init (&tmp_key);

          ret =
            gnutls_x509_privkey_import (tmp_key, &data, GNUTLS_X509_FMT_PEM);
          if (ret < 0)
            {
              fprintf (stderr, "*** Error loading key file: %s\n",
                       gnutls_strerror (ret));
              exit (1);
            }

          ret = gnutls_privkey_import_x509( x509_key, tmp_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
          if (ret < 0)
            {
              fprintf (stderr, "*** Error loading url: %s\n",
                       gnutls_strerror (ret));
              exit (1);
            }

          unload_file (&data);
        }

      fprintf (stdout, "Processed %d client X.509 certificates...\n",
               x509_crt_size);
    }


#ifdef ENABLE_OPENPGP
  if (info.pgp_subkey != NULL)
    {
      get_keyid (keyid, info.pgp_subkey);
    }

  if (pgp_certfile != NULL && pgp_keyfile != NULL)
    {
      gnutls_openpgp_crt_t tmp_pgp_crt;

      data = load_file (pgp_certfile);
      if (data.data == NULL)
        {
          fprintf (stderr, "*** Error loading PGP cert file.\n");
          exit (1);
        }

      gnutls_openpgp_crt_init (&tmp_pgp_crt);

      ret =
        gnutls_pcert_import_openpgp_raw (&pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64, info.pgp_subkey!=NULL?keyid:NULL, 0);
      if (ret < 0)
        {
          fprintf (stderr,
                   "*** Error loading PGP cert file: %s\n",
                   gnutls_strerror (ret));
          exit (1);
        }
 
      unload_file (&data);

      ret = gnutls_privkey_init(&pgp_key);
      if (ret < 0)
         {
           fprintf (stderr, "*** Error initializing key: %s\n",
                    gnutls_strerror (ret));
           exit (1);
         }

#ifdef ENABLE_PKCS11
      if (strncmp (pgp_keyfile, "pkcs11:", 7) == 0)
        {
          gnutls_pkcs11_privkey_init (&pkcs11_key);

          ret = gnutls_pkcs11_privkey_import_url (pkcs11_key, pgp_keyfile, 0);
          if (ret < 0)
            {
              fprintf (stderr, "*** Error loading url: %s\n",
                       gnutls_strerror (ret));
              exit (1);
            }

          ret = gnutls_privkey_import_pkcs11( pgp_key, pkcs11_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
          if (ret < 0)
            {
              fprintf (stderr, "*** Error loading url: %s\n",
                       gnutls_strerror (ret));
              exit (1);
            }
        }
      else
#endif /* ENABLE_PKCS11 */
        {
          gnutls_openpgp_privkey_t tmp_pgp_key;

          data = load_file (pgp_keyfile);
          if (data.data == NULL)
            {
              fprintf (stderr, "*** Error loading PGP key file.\n");
              exit (1);
            }

          gnutls_openpgp_privkey_init (&tmp_pgp_key);

          ret =
            gnutls_openpgp_privkey_import (tmp_pgp_key, &data,
                                           GNUTLS_OPENPGP_FMT_BASE64, NULL,
                                           0);
          if (ret < 0)
            {
              fprintf (stderr,
                       "*** Error loading PGP key file: %s\n",
                       gnutls_strerror (ret));
              exit (1);
            }

          if (info.pgp_subkey != NULL)
            {
              ret =
                gnutls_openpgp_privkey_set_preferred_key_id (tmp_pgp_key, keyid);
              if (ret < 0)
                {
                  fprintf (stderr,
                      "*** Error setting preferred sub key id (%s): %s\n",
                      info.pgp_subkey, gnutls_strerror (ret));
                  exit (1);
                }
            }

          ret = gnutls_privkey_import_openpgp( pgp_key, tmp_pgp_key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
          if (ret < 0)
            {
              fprintf (stderr, "*** Error loading url: %s\n",
                       gnutls_strerror (ret));
              exit (1);
            }

          unload_file (&data);
        }


      fprintf (stdout, "Processed 1 client PGP certificate...\n");
    }
#endif

}
Exemple #25
0
static
void test_failure(const char *name, const char *prio)
{
	int ret;
	/* Server stuff. */
	gnutls_certificate_credentials_t serverx509cred;
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t clientx509cred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN;
	gnutls_x509_crt_t *crts;
	unsigned int crts_size;
	unsigned i;
	gnutls_typed_vdata_st vdata[2];
	gnutls_x509_privkey_t pkey;
	unsigned status;

	success("testing cert verification failure for %s\n", name);

	to_server_len = 0;
	to_client_len = 0;

	ret = gnutls_x509_crt_list_import2(&crts, &crts_size, &server_cert, GNUTLS_X509_FMT_PEM,
			GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_x509_privkey_init(&pkey);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_x509_privkey_import(pkey, &server_key,
					GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	/* Init server */
	gnutls_certificate_allocate_credentials(&serverx509cred);
	gnutls_certificate_set_x509_key(serverx509cred, crts, crts_size, pkey);
	gnutls_x509_privkey_deinit(pkey);
	for (i=0;i<crts_size;i++)
		gnutls_x509_crt_deinit(crts[i]);
	gnutls_free(crts);

	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				serverx509cred);
	assert(gnutls_priority_set_direct(server,
				   prio,
				   NULL) >= 0);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);
	gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);

	/* Init client */
	/* Init client */
	ret = gnutls_certificate_allocate_credentials(&clientx509cred);
	if (ret < 0)
		exit(1);

	ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		exit(1);

	ret = gnutls_certificate_set_x509_key_mem(clientx509cred,
						  &cli_cert, &cli_key,
						  GNUTLS_X509_FMT_PEM);

	ret = gnutls_init(&client, GNUTLS_CLIENT);
	if (ret < 0)
		exit(1);

	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				clientx509cred);
	if (ret < 0)
		exit(1);

	assert(gnutls_priority_set_direct(client, prio, NULL) >= 0);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	memset(vdata, 0, sizeof(vdata));

	/* check with wrong hostname */
	vdata[0].type = GNUTLS_DT_DNS_HOSTNAME;
	vdata[0].data = (void*)"localhost1";

	vdata[1].type = GNUTLS_DT_KEY_PURPOSE_OID;
	vdata[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER;

	gnutls_session_set_verify_cert2(client, vdata, 2, 0);

	HANDSHAKE_EXPECT(client, server, GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR, GNUTLS_E_AGAIN);

	status = gnutls_session_get_verify_cert_status(client);

	if (status == 0) {
		fail("should not have accepted!\n");
		exit(1);
	}

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);
}
Exemple #26
0
/*
 * initialize a new TLS context
 */
static int
tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
{
	tlsg_ctx *ctx = lo->ldo_tls_ctx;
	int rc;

 	if ( lo->ldo_tls_ciphersuite &&
		tlsg_parse_ciphers( ctx, lt->lt_ciphersuite )) {
 		Debug( LDAP_DEBUG_ANY,
 			   "TLS: could not set cipher list %s.\n",
 			   lo->ldo_tls_ciphersuite, 0, 0 );
		return -1;
 	}

	if (lo->ldo_tls_cacertdir != NULL) {
		Debug( LDAP_DEBUG_ANY, 
		       "TLS: warning: cacertdir not implemented for gnutls\n",
		       NULL, NULL, NULL );
	}

	if (lo->ldo_tls_cacertfile != NULL) {
		rc = gnutls_certificate_set_x509_trust_file( 
			ctx->cred,
			lt->lt_cacertfile,
			GNUTLS_X509_FMT_PEM );
		if ( rc < 0 ) return -1;
	}

	if ( lo->ldo_tls_certfile && lo->ldo_tls_keyfile ) {
		gnutls_x509_privkey_t key;
		gnutls_datum_t buf;
		gnutls_x509_crt_t certs[VERIFY_DEPTH];
		unsigned int max = VERIFY_DEPTH;

		rc = gnutls_x509_privkey_init( &key );
		if ( rc ) return -1;

		/* OpenSSL builds the cert chain for us, but GnuTLS
		 * expects it to be present in the certfile. If it's
		 * not, we have to build it ourselves. So we have to
		 * do some special checks here...
		 */
		rc = tlsg_getfile( lt->lt_keyfile, &buf );
		if ( rc ) return -1;
		rc = gnutls_x509_privkey_import( key, &buf,
			GNUTLS_X509_FMT_PEM );
		LDAP_FREE( buf.data );
		if ( rc < 0 ) return rc;

		rc = tlsg_getfile( lt->lt_certfile, &buf );
		if ( rc ) return -1;
		rc = gnutls_x509_crt_list_import( certs, &max, &buf,
			GNUTLS_X509_FMT_PEM, 0 );
		LDAP_FREE( buf.data );
		if ( rc < 0 ) return rc;

		/* If there's only one cert and it's not self-signed,
		 * then we have to build the cert chain.
		 */
		if ( max == 1 && !gnutls_x509_crt_check_issuer( certs[0], certs[0] )) {
			gnutls_x509_crt_t *cas;
			unsigned int i, j, ncas;

			gnutls_certificate_get_x509_cas( ctx->cred, &cas, &ncas );
			for ( i = 1; i<VERIFY_DEPTH; i++ ) {
				for ( j = 0; j<ncas; j++ ) {
					if ( gnutls_x509_crt_check_issuer( certs[i-1], cas[j] )) {
						certs[i] = cas[j];
						max++;
						/* If this CA is self-signed, we're done */
						if ( gnutls_x509_crt_check_issuer( cas[j], cas[j] ))
							j = ncas;
						break;
					}
				}
				/* only continue if we found a CA and it was not self-signed */
				if ( j == ncas )
					break;
			}
		}
		rc = gnutls_certificate_set_x509_key( ctx->cred, certs, max, key );
		if ( rc ) return -1;
	} else if ( lo->ldo_tls_certfile || lo->ldo_tls_keyfile ) {
		Debug( LDAP_DEBUG_ANY, 
		       "TLS: only one of certfile and keyfile specified\n",
		       NULL, NULL, NULL );
		return -1;
	}

	if ( lo->ldo_tls_dhfile ) {
		Debug( LDAP_DEBUG_ANY, 
		       "TLS: warning: ignoring dhfile\n", 
		       NULL, NULL, NULL );
	}

	if ( lo->ldo_tls_crlfile ) {
		rc = gnutls_certificate_set_x509_crl_file( 
			ctx->cred,
			lt->lt_crlfile,
			GNUTLS_X509_FMT_PEM );
		if ( rc < 0 ) return -1;
		rc = 0;
	}

	/* FIXME: ITS#5992 - this should go be configurable,
	 * and V1 CA certs should be phased out ASAP.
	 */
	gnutls_certificate_set_verify_flags( ctx->cred,
		GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT );

	if ( is_server ) {
		gnutls_dh_params_init(&ctx->dh_params);
		gnutls_dh_params_generate2(ctx->dh_params, DH_BITS);
	}
	return 0;
}
void doit(void)
{
	int exit_code = EXIT_SUCCESS;
	int ret;
	/* Server stuff. */
	gnutls_certificate_credentials_t serverx509cred;
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t clientx509cred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN;
	gnutls_x509_crt_t *crts;
	unsigned int crts_size;
	unsigned i;
	gnutls_x509_privkey_t pkey;

	/* General init. */
	global_init();
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(2);

	ret = gnutls_x509_crt_list_import2(&crts, &crts_size, &server_cert, GNUTLS_X509_FMT_PEM,
			GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_x509_privkey_init(&pkey);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_x509_privkey_import(pkey, &server_key,
				       GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	/* Init server */
	gnutls_certificate_allocate_credentials(&serverx509cred);
	gnutls_certificate_set_x509_key(serverx509cred, crts, crts_size, pkey);
	gnutls_x509_privkey_deinit(pkey);
	for (i=0;i<crts_size;i++)
		gnutls_x509_crt_deinit(crts[i]);
	gnutls_free(crts);

	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
			       serverx509cred);
	gnutls_priority_set_direct(server,
				   "NORMAL:-CIPHER-ALL:+AES-128-GCM",
				   NULL);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);
	gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);

	/* Init client */
	/* Init client */
	ret = gnutls_certificate_allocate_credentials(&clientx509cred);
	if (ret < 0)
		exit(1);

	ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		exit(1);

	gnutls_certificate_set_retrieve_function2(clientx509cred, cert_callback);

	ret = gnutls_init(&client, GNUTLS_CLIENT);
	if (ret < 0)
		exit(1);

	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
			       clientx509cred);
	if (ret < 0)
		exit(1);

	gnutls_priority_set_direct(client, "NORMAL", NULL);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	HANDSHAKE(client, server);

	if (gnutls_certificate_get_ours(client) == NULL) {
		fail("client certificate was not sent!\n");
		exit(1);
	}

	/* check gnutls_certificate_get_ours() - server side */
	{
		const gnutls_datum_t *mcert;
		gnutls_datum_t scert;
		gnutls_x509_crt_t crt;

		mcert = gnutls_certificate_get_ours(server);
		if (mcert == NULL) {
			fail("gnutls_certificate_get_ours(): failed\n");
			exit(1);
		}

		gnutls_x509_crt_init(&crt);
		ret = gnutls_x509_crt_import(crt, &server_cert, GNUTLS_X509_FMT_PEM);
		if (ret < 0) {
			fail("gnutls_x509_crt_import: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		ret = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_DER, &scert);
		if (ret < 0) {
			fail("gnutls_x509_crt_export2: %s\n", gnutls_strerror(ret));
			exit(1);
		}
		gnutls_x509_crt_deinit(crt);

		if (scert.size != mcert->size || memcmp(scert.data, mcert->data, mcert->size) != 0) {
			fail("gnutls_certificate_get_ours output doesn't match cert\n");
			exit(1);
		}
		gnutls_free(scert.data);
	}

	/* check gnutls_certificate_get_ours() - client side */
	{
		const gnutls_datum_t *mcert;
		gnutls_datum_t ccert;
		gnutls_x509_crt_t crt;

		mcert = gnutls_certificate_get_ours(client);
		if (mcert == NULL) {
			fail("gnutls_certificate_get_ours(): failed\n");
			exit(1);
		}

		gnutls_x509_crt_init(&crt);
		ret = gnutls_x509_crt_import(crt, &cli_cert, GNUTLS_X509_FMT_PEM);
		if (ret < 0) {
			fail("gnutls_x509_crt_import: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		ret = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_DER, &ccert);
		if (ret < 0) {
			fail("gnutls_x509_crt_export2: %s\n", gnutls_strerror(ret));
			exit(1);
		}
		gnutls_x509_crt_deinit(crt);

		if (ccert.size != mcert->size || memcmp(ccert.data, mcert->data, mcert->size) != 0) {
			fail("gnutls_certificate_get_ours output doesn't match cert\n");
			exit(1);
		}
		gnutls_free(ccert.data);
	}

	/* check the number of certificates received */
	{
		unsigned cert_list_size = 0;
		gnutls_typed_vdata_st data[2];
		unsigned status;

		memset(data, 0, sizeof(data));

		/* check with wrong hostname */
		data[0].type = GNUTLS_DT_DNS_HOSTNAME;
		data[0].data = (void*)"localhost1";

		data[1].type = GNUTLS_DT_KEY_PURPOSE_OID;
		data[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER;

		gnutls_certificate_get_peers(client, &cert_list_size);
		if (cert_list_size < 2) {
			fprintf(stderr, "received a certificate list of %d!\n", cert_list_size);
			exit(1);
		}

		ret = gnutls_certificate_verify_peers(client, data, 2, &status);
		if (ret < 0) {
			fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status == 0) {
			fprintf(stderr, "should not have accepted!\n");
			exit(1);
		}

		/* check with wrong purpose */
		data[0].type = GNUTLS_DT_DNS_HOSTNAME;
		data[0].data = (void*)"localhost";

		data[1].type = GNUTLS_DT_KEY_PURPOSE_OID;
		data[1].data = (void*)GNUTLS_KP_TLS_WWW_CLIENT;

		gnutls_certificate_get_peers(client, &cert_list_size);
		if (cert_list_size < 2) {
			fprintf(stderr, "received a certificate list of %d!\n", cert_list_size);
			exit(1);
		}

		ret = gnutls_certificate_verify_peers(client, data, 2, &status);
		if (ret < 0) {
			fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status == 0) {
			fprintf(stderr, "should not have accepted!\n");
			exit(1);
		}

		/* check with correct purpose */
		data[0].type = GNUTLS_DT_DNS_HOSTNAME;
		data[0].data = (void*)"localhost";

		data[1].type = GNUTLS_DT_KEY_PURPOSE_OID;
		data[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER;

		ret = gnutls_certificate_verify_peers(client, data, 2, &status);
		if (ret < 0) {
			fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret));
			exit(1);
		}

		if (status != 0) {
			fprintf(stderr, "could not verify certificate: %.4x\n", status);
			exit(1);
		}
	}

	if (gnutls_certificate_client_get_request_status(client) == 0) {
		fail("gnutls_certificate_client_get_request_status - 2 failed\n");
		exit(1);
	}

	gnutls_bye(client, GNUTLS_SHUT_RDWR);
	gnutls_bye(server, GNUTLS_SHUT_RDWR);

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);

	gnutls_global_deinit();

	if (debug > 0) {
		if (exit_code == 0)
			puts("Self-test successful");
		else
			puts("Self-test failed");
	}
}
void
doit (void)
{
  gnutls_x509_privkey_t pkey;
  gnutls_x509_crt_t crt;
  gnutls_x509_crq_t crq;

  gnutls_datum_t out;

  size_t s = 0;

  char smallbuf[10];

  int ret;

  ret = gnutls_global_init ();
  if (ret < 0)
    fail ("gnutls_global_init\n");

  gnutls_global_set_log_function (tls_log_func);
  if (debug)
    gnutls_global_set_log_level (4711);

  ret = gnutls_x509_crq_init (&crq);
  if (ret != 0)
    fail ("gnutls_x509_crq_init\n");

  ret = gnutls_x509_privkey_init (&pkey);
  if (ret != 0)
    fail ("gnutls_x509_privkey_init\n");

  ret = gnutls_x509_crt_init (&crt);
  if (ret != 0)
    fail ("gnutls_x509_crt_init\n");

  ret = gnutls_x509_privkey_import (pkey, &key, GNUTLS_X509_FMT_PEM);
  if (ret != 0)
    fail ("gnutls_x509_privkey_import\n");

  ret = gnutls_x509_crq_set_version (crq, 0);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_version\n");

  ret = gnutls_x509_crq_set_key (crq, pkey);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_key\n");

  s = 0;
  ret = gnutls_x509_crq_get_extension_info (crq, 0, NULL, &s, NULL);
  if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
    fail ("gnutls_x509_crq_get_extension_info\n");

  ret = gnutls_x509_crq_set_basic_constraints (crq, 0, 0);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_basic_constraints %d\n", ret);

  ret = gnutls_x509_crq_set_key_usage (crq, 0);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_key_usage %d\n", ret);

  ret = gnutls_x509_crq_get_challenge_password (crq, NULL, &s);
  if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
    fail ("gnutls_x509_crq_get_challenge_password %d\n", ret);

  ret = gnutls_x509_crq_set_challenge_password (crq, "foo");
  if (ret != 0)
    fail ("gnutls_x509_crq_set_challenge_password %d\n", ret);

  s = 0;
  ret = gnutls_x509_crq_get_challenge_password (crq, NULL, &s);
  if (ret != 0 || s != 3)
    fail ("gnutls_x509_crq_get_challenge_password2 %d/%d\n", ret, (int) s);

  s = 10;
  ret = gnutls_x509_crq_get_challenge_password (crq, smallbuf, &s);
  if (ret != 0 || s != 3 || strcmp (smallbuf, "foo") != 0)
    fail ("gnutls_x509_crq_get_challenge_password3 %d/%d/%s\n",
          ret, (int) s, smallbuf);

  s = 0;
  ret = gnutls_x509_crq_get_extension_info (crq, 0, NULL, &s, NULL);
  if (ret != 0)
    fail ("gnutls_x509_crq_get_extension_info2\n");

  s = 0;
  ret = gnutls_x509_crq_get_extension_data (crq, 0, NULL, &s);
  if (ret != 0)
    fail ("gnutls_x509_crq_get_extension_data\n");

  ret = gnutls_x509_crq_set_subject_alt_name (crq, GNUTLS_SAN_DNSNAME,
                                              "foo", 3, 1);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_subject_alt_name\n");

  ret = gnutls_x509_crq_set_subject_alt_name (crq, GNUTLS_SAN_DNSNAME,
                                              "bar", 3, 1);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_subject_alt_name\n");

  ret = gnutls_x509_crq_set_subject_alt_name (crq, GNUTLS_SAN_DNSNAME,
                                              "apa", 3, 0);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_subject_alt_name\n");

  ret = gnutls_x509_crq_set_subject_alt_name (crq, GNUTLS_SAN_DNSNAME,
                                              "foo", 3, 1);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_subject_alt_name\n");

  s = 0;
  ret = gnutls_x509_crq_get_key_purpose_oid (crq, 0, NULL, &s, NULL);
  if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
    fail ("gnutls_x509_crq_get_key_purpose_oid %d\n", ret);

  s = 0;
  ret =
    gnutls_x509_crq_set_key_purpose_oid (crq, GNUTLS_KP_TLS_WWW_SERVER, 0);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_key_purpose_oid %d\n", ret);

  s = 0;
  ret = gnutls_x509_crq_get_key_purpose_oid (crq, 0, NULL, &s, NULL);
  if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
    fail ("gnutls_x509_crq_get_key_purpose_oid %d\n", ret);

  s = 0;
  ret =
    gnutls_x509_crq_set_key_purpose_oid (crq, GNUTLS_KP_TLS_WWW_CLIENT, 1);
  if (ret != 0)
    fail ("gnutls_x509_crq_set_key_purpose_oid2 %d\n", ret);

  ret = gnutls_x509_crq_print (crq, GNUTLS_CRT_PRINT_FULL, &out);
  if (ret != 0)
    fail ("gnutls_x509_crq_print\n");
  if (debug)
    printf ("crq: %.*s\n", out.size, out.data);
  gnutls_free (out.data);

  ret = gnutls_x509_crt_set_version (crt, 3);
  if (ret != 0)
    fail ("gnutls_x509_crt_set_version\n");

  ret = gnutls_x509_crt_set_crq_extensions (crt, crq);
  if (ret != 0)
    fail ("gnutls_x509_crt_set_crq_extensions\n");

  ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &out);
  if (ret != 0)
    fail ("gnutls_x509_crt_print\n");
  if (debug)
    printf ("crt: %.*s\n", out.size, out.data);
  gnutls_free (out.data);

  gnutls_x509_crq_deinit (crq);
  gnutls_x509_crt_deinit (crt);
  gnutls_x509_privkey_deinit (pkey);

  gnutls_global_deinit ();
}
Exemple #29
0
static
void test_success2(const char *name, const char *prio)
{
	int ret;
	/* Server stuff. */
	gnutls_certificate_credentials_t serverx509cred;
	gnutls_session_t server;
	int sret = GNUTLS_E_AGAIN;
	/* Client stuff. */
	gnutls_certificate_credentials_t clientx509cred;
	gnutls_session_t client;
	int cret = GNUTLS_E_AGAIN;
	gnutls_x509_crt_t *crts;
	unsigned int crts_size;
	unsigned i;
	gnutls_x509_privkey_t pkey;
	unsigned status;

	success("testing cert verification success2 for %s\n", name);

	to_server_len = 0;
	to_client_len = 0;

	ret = gnutls_x509_crt_list_import2(&crts, &crts_size, &server_cert, GNUTLS_X509_FMT_PEM,
			GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_x509_privkey_init(&pkey);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	ret =
	    gnutls_x509_privkey_import(pkey, &server_key,
					GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fprintf(stderr, "error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	/* Init server */
	gnutls_certificate_allocate_credentials(&serverx509cred);
	gnutls_certificate_set_x509_key(serverx509cred, crts, crts_size, pkey);
	gnutls_x509_privkey_deinit(pkey);
	for (i=0;i<crts_size;i++)
		gnutls_x509_crt_deinit(crts[i]);
	gnutls_free(crts);

	gnutls_init(&server, GNUTLS_SERVER);
	gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE,
				serverx509cred);
	assert(gnutls_priority_set_direct(server,
				   prio,
				   NULL)>=0);
	gnutls_transport_set_push_function(server, server_push);
	gnutls_transport_set_pull_function(server, server_pull);
	gnutls_transport_set_ptr(server, server);
	gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST);

	/* Init client */
	/* Init client */
	ret = gnutls_certificate_allocate_credentials(&clientx509cred);
	if (ret < 0)
		exit(1);

	ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		exit(1);

	ret = gnutls_certificate_set_x509_key_mem(clientx509cred,
						  &cli_cert, &cli_key,
						  GNUTLS_X509_FMT_PEM);

	ret = gnutls_init(&client, GNUTLS_CLIENT);
	if (ret < 0)
		exit(1);

	ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE,
				clientx509cred);
	if (ret < 0)
		exit(1);

	assert(gnutls_priority_set_direct(client, prio, NULL)>=0);
	gnutls_transport_set_push_function(client, client_push);
	gnutls_transport_set_pull_function(client, client_pull);
	gnutls_transport_set_ptr(client, client);

	gnutls_session_set_verify_cert(client, "localhost", 0);

	HANDSHAKE(client, server);

	status = gnutls_session_get_verify_cert_status(client);

	if (status != 0) {
		fail("%s: should have accepted: %u!\n", __func__, status);
		exit(1);
	}

	gnutls_deinit(client);
	gnutls_deinit(server);

	gnutls_certificate_free_credentials(serverx509cred);
	gnutls_certificate_free_credentials(clientx509cred);
}
Exemple #30
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) */
}