Пример #1
0
static void dane_info(const char *host, const char *proto,
		      unsigned int port, unsigned int ca,
		      unsigned int domain, common_info_st * cinfo)
{
	gnutls_pubkey_t pubkey;
	gnutls_x509_crt_t crt;
	unsigned char digest[64];
	gnutls_datum_t t;
	int ret;
	unsigned int usage, selector, type;
	size_t size;

	if (proto == NULL)
		proto = "tcp";
	if (port == 0)
		port = 443;

	crt = load_cert(0, cinfo);
	if (crt != NULL && HAVE_OPT(X509)) {
		selector = 0;	/* X.509 */

		size = buffer_size;
		ret =
		    gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_DER,
					   buffer, &size);
		if (ret < 0) {
			fprintf(stderr, "export error: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		gnutls_x509_crt_deinit(crt);
	} else {		/* use public key only */

		selector = 1;

		ret = gnutls_pubkey_init(&pubkey);
		if (ret < 0) {
			fprintf(stderr, "pubkey_init: %s\n",
				gnutls_strerror(ret));
			exit(1);
		}

		if (crt != NULL) {

			ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
			if (ret < 0) {
				fprintf(stderr, "pubkey_import_x509: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}

			size = buffer_size;
			ret =
			    gnutls_pubkey_export(pubkey,
						 GNUTLS_X509_FMT_DER,
						 buffer, &size);
			if (ret < 0) {
				fprintf(stderr, "pubkey_export: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}

			gnutls_x509_crt_deinit(crt);
		} else {
			pubkey = load_pubkey(1, cinfo);

			size = buffer_size;
			ret =
			    gnutls_pubkey_export(pubkey,
						 GNUTLS_X509_FMT_DER,
						 buffer, &size);
			if (ret < 0) {
				fprintf(stderr, "export error: %s\n",
					gnutls_strerror(ret));
				exit(1);
			}
		}

		gnutls_pubkey_deinit(pubkey);
	}

	if (default_dig != GNUTLS_DIG_SHA256
	    && default_dig != GNUTLS_DIG_SHA512) {
		if (default_dig != GNUTLS_DIG_UNKNOWN)
			fprintf(stderr,
				"Unsupported digest. Assuming SHA256.\n");
		default_dig = GNUTLS_DIG_SHA256;
	}

	ret = gnutls_hash_fast(default_dig, buffer, size, digest);
	if (ret < 0) {
		fprintf(stderr, "hash error: %s\n", gnutls_strerror(ret));
		exit(1);
	}

	if (default_dig == GNUTLS_DIG_SHA256)
		type = 1;
	else
		type = 2;

	/* DANE certificate classification crap */
	if (domain == 0) {
		if (ca)
			usage = 0;
		else
			usage = 1;
	} else {
		if (ca)
			usage = 2;
		else
			usage = 3;
	}

	t.data = digest;
	t.size = gnutls_hash_get_len(default_dig);

	size = buffer_size;
	ret = gnutls_hex_encode(&t, (void *) buffer, &size);
	if (ret < 0) {
		fprintf(stderr, "hex encode error: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	fprintf(outfile, "_%u._%s.%s. IN TLSA ( %.2x %.2x %.2x %s )\n",
		port, proto, host, usage, selector, type, buffer);

}
Пример #2
0
int					/* O - 1 on success, 0 on failure */
cupsMakeServerCredentials(
    const char *path,			/* I - Path to keychain/directory */
    const char *common_name,		/* I - Common name */
    int        num_alt_names,		/* I - Number of subject alternate names */
    const char **alt_names,		/* I - Subject Alternate Names */
    time_t     expiration_date)		/* I - Expiration date */
{
  gnutls_x509_crt_t	crt;		/* Self-signed certificate */
  gnutls_x509_privkey_t	key;		/* Encryption private key */
  char			temp[1024],	/* Temporary directory name */
 			crtfile[1024],	/* Certificate filename */
			keyfile[1024];	/* Private key filename */
  cups_lang_t		*language;	/* Default language info */
  cups_file_t		*fp;		/* Key/cert file */
  unsigned char		buffer[8192];	/* Buffer for x509 data */
  size_t		bytes;		/* Number of bytes of data */
  unsigned char		serial[4];	/* Serial number buffer */
  time_t		curtime;	/* Current time */
  int			result;		/* Result of GNU TLS calls */


  DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, alt_names, (int)expiration_date));

 /*
  * Filenames...
  */

  if (!path)
    path = http_gnutls_default_path(temp, sizeof(temp));

  if (!path || !common_name)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

  http_gnutls_make_path(crtfile, sizeof(crtfile), path, common_name, "crt");
  http_gnutls_make_path(keyfile, sizeof(keyfile), path, common_name, "key");

 /*
  * Create the encryption key...
  */

  DEBUG_puts("1cupsMakeServerCredentials: Creating key pair.");

  gnutls_x509_privkey_init(&key);
  gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, 2048, 0);

  DEBUG_puts("1cupsMakeServerCredentials: Key pair created.");

 /*
  * Save it...
  */

  bytes = sizeof(buffer);

  if ((result = gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0)
  {
    DEBUG_printf(("1cupsMakeServerCredentials: Unable to export private key: %s", gnutls_strerror(result)));
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(result), 0);
    gnutls_x509_privkey_deinit(key);
    return (0);
  }
  else if ((fp = cupsFileOpen(keyfile, "w")) != NULL)
  {
    DEBUG_printf(("1cupsMakeServerCredentials: Writing private key to \"%s\".", keyfile));
    cupsFileWrite(fp, (char *)buffer, bytes);
    cupsFileClose(fp);
  }
  else
  {
    DEBUG_printf(("1cupsMakeServerCredentials: Unable to create private key file \"%s\": %s", keyfile, strerror(errno)));
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
    gnutls_x509_privkey_deinit(key);
    return (0);
  }

 /*
  * Create the self-signed certificate...
  */

  DEBUG_puts("1cupsMakeServerCredentials: Generating self-signed X.509 certificate.");

  language  = cupsLangDefault();
  curtime   = time(NULL);
  serial[0] = curtime >> 24;
  serial[1] = curtime >> 16;
  serial[2] = curtime >> 8;
  serial[3] = curtime;

  gnutls_x509_crt_init(&crt);
  if (strlen(language->language) == 5)
    gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0,
                                  language->language + 3, 2);
  else
    gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0,
                                  "US", 2);
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COMMON_NAME, 0,
                                common_name, strlen(common_name));
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATION_NAME, 0,
                                common_name, strlen(common_name));
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME,
                                0, "Unknown", 7);
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0,
                                "Unknown", 7);
  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_LOCALITY_NAME, 0,
                                "Unknown", 7);
/*  gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_PKCS9_EMAIL, 0,
                                ServerAdmin, strlen(ServerAdmin));*/
  gnutls_x509_crt_set_key(crt, key);
  gnutls_x509_crt_set_serial(crt, serial, sizeof(serial));
  gnutls_x509_crt_set_activation_time(crt, curtime);
  gnutls_x509_crt_set_expiration_time(crt, curtime + 10 * 365 * 86400);
  gnutls_x509_crt_set_ca_status(crt, 0);
  if (num_alt_names > 0)
    gnutls_x509_crt_set_subject_alternative_name(crt, GNUTLS_SAN_DNSNAME, alt_names[0]);
  gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0);
  gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_KEY_ENCIPHERMENT);
  gnutls_x509_crt_set_version(crt, 3);

  bytes = sizeof(buffer);
  if (gnutls_x509_crt_get_key_id(crt, 0, buffer, &bytes) >= 0)
    gnutls_x509_crt_set_subject_key_id(crt, buffer, bytes);

  gnutls_x509_crt_sign(crt, crt, key);

 /*
  * Save it...
  */

  bytes = sizeof(buffer);
  if ((result = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0)
  {
    DEBUG_printf(("1cupsMakeServerCredentials: Unable to export public key and X.509 certificate: %s", gnutls_strerror(result)));
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, gnutls_strerror(result), 0);
    gnutls_x509_crt_deinit(crt);
    gnutls_x509_privkey_deinit(key);
    return (0);
  }
  else if ((fp = cupsFileOpen(crtfile, "w")) != NULL)
  {
    DEBUG_printf(("1cupsMakeServerCredentials: Writing public key and X.509 certificate to \"%s\".", crtfile));
    cupsFileWrite(fp, (char *)buffer, bytes);
    cupsFileClose(fp);
  }
  else
  {
    DEBUG_printf(("1cupsMakeServerCredentials: Unable to create public key and X.509 certificate file \"%s\": %s", crtfile, strerror(errno)));
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
    gnutls_x509_crt_deinit(crt);
    gnutls_x509_privkey_deinit(key);
    return (0);
  }

 /*
  * Cleanup...
  */

  gnutls_x509_crt_deinit(crt);
  gnutls_x509_privkey_deinit(key);

  DEBUG_puts("1cupsMakeServerCredentials: Successfully created credentials.");

  return (1);
}
Пример #3
0
ssize_t mailstream_ssl_get_certificate(mailstream *stream, unsigned char **cert_DER)
{
#ifdef USE_SSL
  struct mailstream_ssl_data *data = NULL;
  ssize_t len = 0;
#ifndef USE_GNUTLS
  SSL *ssl_conn = NULL;
  X509 *cert = NULL;
#else
  gnutls_session session = NULL;
  const gnutls_datum *raw_cert_list;
  unsigned int raw_cert_list_length;
  gnutls_x509_crt cert = NULL;
  char output[10*1024];
  size_t cert_size;
#endif

  if (cert_DER == NULL || stream == NULL || stream->low == NULL)
    return -1;

  data = stream->low->data;
  if (data == NULL)
    return -1;

#ifndef USE_GNUTLS
  ssl_conn = data->ssl_conn;
  if (ssl_conn == NULL)
    return -1;
  
  cert = SSL_get_peer_certificate(ssl_conn);
  if (cert == NULL)
    return -1;
  
  *cert_DER = NULL;
  len = (ssize_t) i2d_X509(cert, cert_DER);
  
	X509_free(cert);

  return len;
#else
  session = data->session;
  raw_cert_list = gnutls_certificate_get_peers(session, &raw_cert_list_length);

  if (raw_cert_list 
  && gnutls_certificate_type_get(session) == GNUTLS_CRT_X509
  &&  gnutls_x509_crt_init(&cert) >= 0
  &&  gnutls_x509_crt_import(cert, &raw_cert_list[0], GNUTLS_X509_FMT_DER) >= 0) {
    cert_size = sizeof(output);
    if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, output, &cert_size) < 0)
      return -1;
    
    *cert_DER = malloc (cert_size + 1);
    if (*cert_DER == NULL)
      return -1;
    
    memcpy (*cert_DER, output, cert_size);
    len = (ssize_t)cert_size;
    gnutls_x509_crt_deinit(cert);
    
    return len;
  }
#endif
#endif
  return -1;
}
Пример #4
0
/* lists certificates from a token
 */
void
pkcs11_list (FILE * outfile, const char *url, int type, unsigned int login,
             unsigned int detailed, common_info_st * info)
{
  gnutls_pkcs11_obj_t *crt_list;
  gnutls_x509_crt_t xcrt;
  unsigned int crt_list_size = 0;
  int ret;
  char *output;
  int i, attrs;
  unsigned int obj_flags = 0;

  if (login)
    obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN;

  pkcs11_common ();

  if (url == NULL)
    url = "pkcs11:";

  if (type == PKCS11_TYPE_TRUSTED)
    {
      attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED;
    }
  else if (type == PKCS11_TYPE_PK)
    {
      attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY;
    }
  else if (type == PKCS11_TYPE_CRT_ALL)
    {
      attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL;
    }
  else if (type == PKCS11_TYPE_PRIVKEY)
    {
      attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY;
    }
  else
    {
      attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL;
    }

  /* give some initial value to avoid asking for the pkcs11 pin twice.
   */
  crt_list_size = 128;
  crt_list = malloc (sizeof (*crt_list) * crt_list_size);
  if (crt_list == NULL)
    {
      fprintf (stderr, "Memory error\n");
      exit (1);
    }

  ret = gnutls_pkcs11_obj_list_import_url (crt_list, &crt_list_size, url,
                                           attrs, obj_flags);
  if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
    {
      fprintf (stderr, "Error in crt_list_import (1): %s\n",
               gnutls_strerror (ret));
      exit (1);
    }

  if (crt_list_size == 0)
    {
      fprintf (stderr, "No matching objects found\n");
      exit (0);
    }

  if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
    {
      crt_list = realloc (crt_list, sizeof (*crt_list) * crt_list_size);
      if (crt_list == NULL)
        {
          fprintf (stderr, "Memory error\n");
          exit (1);
        }

      ret =
        gnutls_pkcs11_obj_list_import_url (crt_list, &crt_list_size, url,
                                           attrs, obj_flags);
      if (ret < 0)
        {
          fprintf (stderr, "Error in crt_list_import: %s\n",
                   gnutls_strerror (ret));
          exit (1);
        }
    }

  for (i = 0; i < crt_list_size; i++)
    {
      char buf[128];
      size_t size;

      ret = gnutls_pkcs11_obj_export_url (crt_list[i], detailed, &output);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      fprintf (outfile, "Object %d:\n\tURL: %s\n", i, output);

      fprintf (outfile, "\tType: %s\n",
               gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_get_type
                                            (crt_list[i])));

      size = sizeof (buf);
      ret =
        gnutls_pkcs11_obj_get_info (crt_list[i], GNUTLS_PKCS11_OBJ_LABEL, buf,
                                    &size);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }
      fprintf (outfile, "\tLabel: %s\n", buf);

      size = sizeof (buf);
      ret =
        gnutls_pkcs11_obj_get_info (crt_list[i], GNUTLS_PKCS11_OBJ_ID_HEX,
                                    buf, &size);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }
      fprintf (outfile, "\tID: %s\n\n", buf);



      if (attrs == GNUTLS_PKCS11_OBJ_ATTR_ALL
          || attrs == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY)
        continue;

      ret = gnutls_x509_crt_init (&xcrt);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      ret = gnutls_x509_crt_import_pkcs11 (xcrt, crt_list[i]);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

#if 0
      size = buffer_size;
      ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      fwrite (buffer, 1, size, outfile);
      fputs ("\n\n", outfile);
#endif

      gnutls_x509_crt_deinit (xcrt);


    }

  return;
}
Пример #5
0
void
pkcs11_export (FILE * outfile, const char *url, unsigned int login,
               common_info_st * info)
{
  gnutls_pkcs11_obj_t crt;
  gnutls_x509_crt_t xcrt;
  gnutls_pubkey_t pubkey;
  int ret;
  size_t size;
  unsigned int obj_flags = 0;

  if (login)
    obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN;

  pkcs11_common ();

  if (url == NULL)
    url = "pkcs11:";

  ret = gnutls_pkcs11_obj_init (&crt);
  if (ret < 0)
    {
      fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
               gnutls_strerror (ret));
      exit (1);
    }

  ret = gnutls_pkcs11_obj_import_url (crt, url, obj_flags);
  if (ret < 0)
    {
      fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
               gnutls_strerror (ret));
      exit (1);
    }

  switch (gnutls_pkcs11_obj_get_type (crt))
    {
    case GNUTLS_PKCS11_OBJ_X509_CRT:
      ret = gnutls_x509_crt_init (&xcrt);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      ret = gnutls_x509_crt_import_pkcs11 (xcrt, crt);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      size = buffer_size;
      ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }
      fwrite (buffer, 1, size, outfile);

      gnutls_x509_crt_deinit (xcrt);
      break;
    case GNUTLS_PKCS11_OBJ_PUBKEY:
      ret = gnutls_pubkey_init (&pubkey);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      ret = gnutls_pubkey_import_pkcs11 (pubkey, crt, 0);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }

      size = buffer_size;
      ret = gnutls_pubkey_export (pubkey, GNUTLS_X509_FMT_PEM, buffer, &size);
      if (ret < 0)
        {
          fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                   gnutls_strerror (ret));
          exit (1);
        }
      fwrite (buffer, 1, size, outfile);

      gnutls_pubkey_deinit (pubkey);
      break;
    default:
      {
        gnutls_datum_t data, enc;

        size = buffer_size;
        ret = gnutls_pkcs11_obj_export (crt, buffer, &size);
        if (ret < 0)
          {
            break;
          }

        data.data = buffer;
        data.size = size;

        ret = gnutls_pem_base64_encode_alloc ("DATA", &data, &enc);
        if (ret < 0)
          {
            fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__,
                     gnutls_strerror (ret));
            exit (1);
          }

        fwrite (enc.data, 1, enc.size, outfile);

        gnutls_free (enc.data);
        break;
      }
    }
  fputs ("\n\n", outfile);


  gnutls_pkcs11_obj_deinit (crt);

  return;

}
void
empathy_tls_certificate_store_ca (EmpathyTLSCertificate *self)
{
  GArray *last_cert;
  gnutls_x509_crt_t cert;
  gnutls_datum_t datum = { NULL, 0 };
  gsize exported_len;
  guchar *exported_cert = NULL;
  gint res, offset;
  gchar *user_certs_dir = NULL, *filename = NULL, *path = NULL;
  gchar *hostname = NULL;
  GError *error = NULL;
  EmpathyTLSCertificatePriv *priv = GET_PRIV (self);

  last_cert = g_ptr_array_index (priv->cert_data, priv->cert_data->len - 1);
  datum.data = (guchar *) last_cert->data;
  datum.size = last_cert->len;

  gnutls_x509_crt_init (&cert);
  gnutls_x509_crt_import (cert, &datum, GNUTLS_X509_FMT_DER);

  /* make sure it's self-signed, otherwise it's not a CA */
  if (gnutls_x509_crt_check_issuer (cert, cert) <= 0)
    {
      DEBUG ("Can't import the CA, as it's not self-signed");
      gnutls_x509_crt_deinit (cert);

      return;
    }

  if (gnutls_x509_crt_get_ca_status (cert, NULL) <= 0)
    {
      DEBUG ("Can't import the CA, it's not a valid CA certificate");
      gnutls_x509_crt_deinit (cert);

      goto out;
    }

  exported_len = get_exported_size (cert);
  exported_cert = g_malloc (sizeof (guchar) * exported_len);

  res = gnutls_x509_crt_export (cert, GNUTLS_X509_FMT_PEM,
      exported_cert, &exported_len);

  if (res < 0)
    {
      DEBUG ("Failed to export the CA certificate; GnuTLS returned %d,"
          "and should be %lu bytes long", res, (gulong) exported_len);
      gnutls_x509_crt_deinit (cert);

      goto out;
    }

  hostname = empathy_get_x509_certificate_hostname (cert);

  if (hostname == NULL)
    hostname = g_strdup ("ca");

  gnutls_x509_crt_deinit (cert);

  /* write the file */
  user_certs_dir = g_build_filename (g_get_user_config_dir (),
      "telepathy", "certs", NULL);

  res = g_mkdir_with_parents (user_certs_dir, S_IRWXU | S_IRWXG);

  if (res < 0)
    {
      DEBUG ("Failed to create the user certificate directory: %s",
          g_strerror (errno));

      goto out;
    }

  offset = 0;

  do
    {
      g_free (path);

      if (offset == 0)
        filename = g_strdup_printf ("cert-%s", hostname);
      else
        filename = g_strdup_printf ("cert-%s-%d", hostname, offset);

      path = g_build_filename (user_certs_dir, filename, NULL);

      offset++;
      g_free (filename);
    }
  while (g_file_test (path, G_FILE_TEST_EXISTS));

  DEBUG ("Will save to %s", path);

  g_file_set_contents (path, (const gchar *) exported_cert, exported_len,
      &error);

  if (error != NULL)
    {
      DEBUG ("Can't save the CA certificate to %s: %s",
          path, error->message);

      g_error_free (error);
    }

 out:
  g_free (path);
  g_free (exported_cert);
  g_free (user_certs_dir);
  g_free (hostname);
}
Пример #7
0
static void
print_x509_info (gnutls_session_t session, const char *hostname, int insecure)
{
  gnutls_x509_crt_t crt;
  const gnutls_datum_t *cert_list;
  unsigned int cert_list_size = 0, j;
  int hostname_ok = 0;
  int ret;

  cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
  if (cert_list_size == 0)
    {
      fprintf (stderr, "No certificates found!\n");
      return;
    }

  printf (" - Got a certificate list of %d certificates.\n", cert_list_size);

  for (j = 0; j < cert_list_size; j++)
    {
      gnutls_datum_t cinfo;

      gnutls_x509_crt_init (&crt);
      ret = gnutls_x509_crt_import (crt, &cert_list[j], GNUTLS_X509_FMT_DER);
      if (ret < 0)
	{
	  fprintf (stderr, "Decoding error: %s\n", gnutls_strerror (ret));
	  return;
	}

      printf (" - Certificate[%d] info:\n  - ", j);

      if (verbose)
	ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_FULL, &cinfo);
      else
	ret = gnutls_x509_crt_print (crt, GNUTLS_CRT_PRINT_ONELINE, &cinfo);
      if (ret == 0)
	{
	  printf ("%s\n", cinfo.data);
	  gnutls_free (cinfo.data);
	}

      if (print_cert)
	{
	  size_t size;

	  size = sizeof (buffer);

	  ret = gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_PEM,
					buffer, &size);
	  if (ret < 0)
	    {
	      fprintf (stderr, "Encoding error: %s\n", gnutls_strerror (ret));
	      return;
	    }

	  fputs ("\n", stdout);
	  fputs (buffer, stdout);
	  fputs ("\n", stdout);
	}

      if (j == 0 && hostname != NULL)
	{
	  /* Check the hostname of the first certificate if it matches
	   * the name of the host we connected to.
	   */
	  if (gnutls_x509_crt_check_hostname (crt, hostname) == 0)
	    hostname_ok = 1;
	  else
	    hostname_ok = 2;
	}

      gnutls_x509_crt_deinit (crt);
    }

  if (hostname_ok == 1)
    {
      printf ("- The hostname in the certificate does NOT match '%s'\n",
	      hostname);
      if (!insecure)
	exit (1);
    }
  else if (hostname_ok == 2)
    {
      printf ("- The hostname in the certificate matches '%s'.\n", hostname);
    }
}
Пример #8
0
shared_ptr <security::cert::certificateChain> TLSSocket_GnuTLS::getPeerCertificates() {

	if (getTracer()) {
		getTracer()->traceSend("Getting peer certificates");
	}

	unsigned int certCount = 0;
	const gnutls_datum_t* rawData = gnutls_certificate_get_peers(
		*m_session->m_gnutlsSession, &certCount
	);

	if (rawData == NULL) {
		return null;
	}

	// Try X.509
	gnutls_x509_crt_t* x509Certs = new gnutls_x509_crt_t[certCount];

	for (unsigned int i = 0; i < certCount; ++i) {

		gnutls_x509_crt_init(x509Certs + i);

		int res = gnutls_x509_crt_import(x509Certs[i], rawData + i, GNUTLS_X509_FMT_DER);

		if (res < 0) {

			for (unsigned int j = 0 ; j <= i ; ++j) {
				gnutls_x509_crt_deinit(x509Certs[j]);
			}

			// XXX more fine-grained error reporting?
			delete [] x509Certs;
			return null;
		}
	}

	std::vector <shared_ptr <security::cert::certificate> > certs;
	bool error = false;

	for (unsigned int i = 0 ; i < certCount ; ++i) {

		size_t dataSize = 0;

		gnutls_x509_crt_export(x509Certs[i], GNUTLS_X509_FMT_DER, NULL, &dataSize);

		std::vector <byte_t> data(dataSize);

		gnutls_x509_crt_export(x509Certs[i], GNUTLS_X509_FMT_DER, &data[0], &dataSize);

		shared_ptr <security::cert::X509Certificate> cert =
			security::cert::X509Certificate::import(&data[0], dataSize);

		if (cert != NULL) {
			certs.push_back(cert);
		} else {
			error = true;
		}

		gnutls_x509_crt_deinit(x509Certs[i]);
	}

	delete [] x509Certs;

	if (error) {
		return null;
	}

	return make_shared <security::cert::certificateChain>(certs);
}