Ejemplo n.º 1
0
/*!
  Creates a self-signed certificate by signing the certificate with the specified
  key.
 */
QSslCertificate CertificateBuilder::signedCertificate(const QSslKey &qkey)
{
    gnutls_x509_privkey_t key = qsslkey_to_key(qkey, &d->errnumber);
    if (GNUTLS_E_SUCCESS != d->errnumber) {
        gnutls_x509_privkey_deinit(key);
        return QSslCertificate();
    };

    gnutls_privkey_t abstractKey;
    d->errnumber = gnutls_privkey_init(&abstractKey);
    if (GNUTLS_E_SUCCESS != d->errnumber) {
        gnutls_x509_privkey_deinit(key);
        return QSslCertificate();
    }

    gnutls_privkey_import_x509(abstractKey, key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);

    d->errnumber = gnutls_x509_crt_privkey_sign(d->crt, d->crt, abstractKey, GNUTLS_DIG_SHA1, 0);

    gnutls_x509_privkey_deinit(key);

    if (GNUTLS_E_SUCCESS != d->errnumber)
        return QSslCertificate();

    return crt_to_qsslcert(d->crt, &d->errnumber);    
}
Ejemplo n.º 2
0
static gnutls_privkey_t _load_pkcs11_privkey(const char* url)
{
int ret;
gnutls_pkcs11_privkey_t p11key;
gnutls_privkey_t key;

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

  ret = gnutls_pkcs11_privkey_init (&p11key);
  if (ret < 0)
    error (EXIT_FAILURE, 0, "pkcs11_privkey_init: %s", gnutls_strerror (ret));

  ret = gnutls_pkcs11_privkey_import_url(p11key, url, 0);
  if (ret < 0)
    error (EXIT_FAILURE, 0, "importing PKCS #11 key: %s: %s",
           url, gnutls_strerror (ret));

  ret = gnutls_privkey_import_pkcs11(key, p11key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);
  if (ret < 0)
    error (EXIT_FAILURE, 0, "gnutls_privkey_import_pkcs11: %s",
           gnutls_strerror (ret));
  
  return key;
}
Ejemplo n.º 3
0
static gnutls_privkey_t _load_privkey(gnutls_datum_t *dat, common_info_st * info)
{
int ret;
gnutls_privkey_t key;
unsigned int flags = 0;
const char* pass;

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

  ret = gnutls_privkey_import_x509_raw (key, dat, info->incert_format, NULL, 0);
  if (ret == GNUTLS_E_DECRYPTION_FAILED)
    {
      pass = get_password (info, &flags, 0);
      ret = gnutls_privkey_import_x509_raw (key, dat, info->incert_format, pass, flags);
    }

  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 #12 encoded");
    }

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

  return key;
}
Ejemplo n.º 4
0
/* Reads a private key from a token.
 */
static int
read_key_url(gnutls_certificate_credentials_t res, const char *url, gnutls_privkey_t *rkey)
{
	int ret;
	gnutls_privkey_t pkey = NULL;

	/* allocate space for the pkey list
	 */
	ret = gnutls_privkey_init(&pkey);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	if (res->pin.cb)
		gnutls_privkey_set_pin_function(pkey, res->pin.cb,
						res->pin.data);

	ret = gnutls_privkey_import_url(pkey, url, 0);
	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	*rkey = pkey;

	return 0;

      cleanup:
	if (pkey)
		gnutls_privkey_deinit(pkey);

	return ret;
}
Ejemplo n.º 5
0
/* Load the certificate and the private key.
 * (This code is largely taken from GnuTLS).
 */
static void
load_keys(const char *hostname,
          const char *CERT_FILE,
          const char *KEY_FILE)
{
  int ret;
  gnutls_datum_t data;
  struct Hosts *host;

  host = malloc (sizeof (struct Hosts));
  if (NULL == host)
    abort ();
  host->hostname = hostname;
  host->next = hosts;
  hosts = host;

  ret = gnutls_load_file (CERT_FILE, &data);
  if (ret < 0)
    {
      fprintf (stderr,
               "*** Error loading certificate file %s.\n",
               CERT_FILE);
      exit (1);
    }
  ret =
    gnutls_pcert_import_x509_raw (&host->pcrt, &data, GNUTLS_X509_FMT_PEM,
                                  0);
  if (ret < 0)
    {
      fprintf (stderr,
               "*** Error loading certificate file: %s\n",
               gnutls_strerror (ret));
      exit (1);
    }
  gnutls_free (data.data);

  ret = gnutls_load_file (KEY_FILE, &data);
  if (ret < 0)
    {
      fprintf (stderr,
               "*** Error loading key file %s.\n",
               KEY_FILE);
      exit (1);
    }

  gnutls_privkey_init (&host->key);
  ret =
    gnutls_privkey_import_x509_raw (host->key,
                                    &data, GNUTLS_X509_FMT_PEM,
                                    NULL, 0);
  if (ret < 0)
    {
      fprintf (stderr,
               "*** Error loading key file: %s\n",
               gnutls_strerror (ret));
      exit (1);
    }
  gnutls_free (data.data);
}
Ejemplo n.º 6
0
PrivateKey::PrivateKey(gnutls_x509_privkey_t k) : x509_key(k)
{
    if (gnutls_global_init() != GNUTLS_E_SUCCESS)
        throw CryptoException("Can't initialize GnuTLS.");
    gnutls_privkey_init(&key);
    if (gnutls_privkey_import_x509(key, k, GNUTLS_PRIVKEY_IMPORT_COPY) != GNUTLS_E_SUCCESS) {
        key = nullptr;
        throw CryptoException("Can't load generic private key !");
    }
}
Ejemplo n.º 7
0
void doit(void)
{
	int ret, status;
	const char *lib;
	gnutls_privkey_t pkey;
	pid_t pid;

	signal(SIGPIPE, SIG_IGN);

	gnutls_pkcs11_set_pin_function(pin_func, NULL);
	gnutls_global_set_log_function(tls_log_func);
	if (debug)
		gnutls_global_set_log_level(4711);

	lib = getenv("P11MOCKLIB1");
	if (lib == NULL)
		lib = P11LIB;

	ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_add_provider(lib, NULL);
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	assert(gnutls_privkey_init(&pkey) == 0);

	ret = gnutls_privkey_import_url(pkey, "pkcs11:object=test", GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
	if (ret < 0) {
		fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));
		exit(1);
	}

	/* fork to force PKCS#11 reinitialization */
	pid = fork();
	if (pid == -1) {
		exit(1);
	} else if (pid) {
                waitpid(pid, &status, 0);
                check_wait_status(status);
                goto cleanup;
	}

	do_thread_stuff(pkey);

 cleanup:
	gnutls_privkey_deinit(pkey);
}
Ejemplo n.º 8
0
static int
cert_callback(gnutls_session_t session,
	      const gnutls_datum_t * req_ca_rdn, int nreqs,
	      const gnutls_pk_algorithm_t * sign_algos,
	      int sign_algos_length, gnutls_pcert_st ** pcert,
	      unsigned int *pcert_length, gnutls_privkey_t * pkey)
{
	int ret;
	gnutls_pcert_st *p;
	gnutls_privkey_t lkey;

	if (gnutls_certificate_client_get_request_status(session) == 0) {
		fail("gnutls_certificate_client_get_request_status failed\n");
		return -1;
	}

	p = gnutls_malloc(sizeof(*p));
	if (p==NULL)
		return -1;

	if (g_pkey == NULL) {
		ret = gnutls_pcert_import_x509_raw(p, &cli_cert, GNUTLS_X509_FMT_PEM, 0);
		if (ret < 0)
			return -1;

		ret = gnutls_privkey_init(&lkey);
		if (ret < 0)
			return -1;

		ret = gnutls_privkey_import_x509_raw(lkey, &cli_key, GNUTLS_X509_FMT_PEM, NULL, 0);
		if (ret < 0)
			return -1;

		g_pcert = p;
		g_pkey = lkey;

		*pcert = p;
		*pcert_length = 1;
		*pkey = lkey;
	} else {
		*pcert = g_pcert;
		*pcert_length = 1;
		if (gnutls_certificate_client_get_request_status(session) == 0) {
		fail("gnutls_certificate_client_get_request_status failed\n");
		return -1;
	}
	*pkey = g_pkey;
	}

	return 0;
}
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;
    
}
Ejemplo n.º 10
0
/* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory.  Type
 * indicates the certificate format.
 *
 * It returns the private key read in @rkey.
 */
int
_gnutls_read_key_mem(gnutls_certificate_credentials_t res,
	     const void *key, int key_size, gnutls_x509_crt_fmt_t type,
	     const char *pass, unsigned int flags,
	     gnutls_privkey_t *rkey)
{
	int ret;
	gnutls_datum_t tmp;
	gnutls_privkey_t privkey;

	if (key) {
		tmp.data = (uint8_t *) key;
		tmp.size = key_size;

		ret = gnutls_privkey_init(&privkey);
		if (ret < 0) {
			gnutls_assert();
			return ret;
		}

		if (res->pin.cb) {
			gnutls_privkey_set_pin_function(privkey,
							res->pin.cb,
							res->pin.data);
		} else if (pass != NULL) {
			snprintf(res->pin_tmp, sizeof(res->pin_tmp), "%s",
				 pass);
			gnutls_privkey_set_pin_function(privkey,
							tmp_pin_cb,
							res->pin_tmp);
		}

		ret =
		    gnutls_privkey_import_x509_raw(privkey, &tmp, type,
						   pass, flags);
		if (ret < 0) {
			gnutls_assert();
			gnutls_privkey_deinit(privkey);
			return ret;
		}

		*rkey = privkey;
	} else {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	return 0;
}
Ejemplo n.º 11
0
static gnutls_privkey_t _load_url_privkey(const char* url)
{
int ret;
gnutls_privkey_t key;

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

  ret = gnutls_privkey_import_url(key, url, 0);
  if (ret < 0)
    error (EXIT_FAILURE, 0, "importing key: %s: %s",
           url, gnutls_strerror (ret));

  return key;
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
0
/*!
 * Create GnuTLS private key from unencrypted PEM data.
 */
int pem_to_privkey(const dnssec_binary_t *data, gnutls_privkey_t *key, char **id_ptr)
{
	assert(data);
	assert(key);
	assert(id_ptr);

	// create abstract private key

	gnutls_x509_privkey_t key_x509 = NULL;
	int r = pem_to_x509(data, &key_x509);
	if (r != DNSSEC_EOK) {
		return r;
	}

	gnutls_privkey_t key_abs = NULL;
	r = gnutls_privkey_init(&key_abs);
	if (r != GNUTLS_E_SUCCESS) {
		gnutls_x509_privkey_deinit(key_x509);
		return DNSSEC_ENOMEM;
	}

	int flags = GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE;
	r = gnutls_privkey_import_x509(key_abs, key_x509, flags);
	if (r != GNUTLS_E_SUCCESS) {
		gnutls_x509_privkey_deinit(key_x509);
		gnutls_privkey_deinit(key_abs);
		return DNSSEC_ENOMEM;
	}

	// extract keytag

	char *id = gnutls_x509_privkey_hex_key_id(key_x509);
	if (id == NULL) {
		gnutls_privkey_deinit(key_abs);
		return DNSSEC_ENOMEM;
	}

	*key = key_abs;
	*id_ptr = id;

	return DNSSEC_EOK;
}
Ejemplo n.º 14
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;
}
Ejemplo n.º 15
0
/*!
  Creates a certificate signed by the specified CA certificate using the
  CA key.
 */
QSslCertificate CertificateBuilder::signedCertificate(const QSslCertificate &qcacert, const QSslKey &qcakey)
{
    //
    // Extract the CA key
    //
    gnutls_x509_privkey_t key = qsslkey_to_key(qcakey, &d->errnumber);
    if (GNUTLS_E_SUCCESS != d->errnumber) {
        gnutls_x509_privkey_deinit(key);
        return QSslCertificate();
    };

    gnutls_privkey_t abstractKey;
    d->errnumber = gnutls_privkey_init(&abstractKey);
    if (GNUTLS_E_SUCCESS != d->errnumber) {
        gnutls_x509_privkey_deinit(key);
        return QSslCertificate();
    }

    gnutls_privkey_import_x509(abstractKey, key, GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE);

    //
    // Extract the CA cert
    //
    gnutls_x509_crt_t cacrt = qsslcert_to_crt(qcacert, &d->errnumber);
    if (GNUTLS_E_SUCCESS != d->errnumber) {
        gnutls_x509_privkey_deinit(key);
        return QSslCertificate();
    }

    //
    // Sign the cert
    //
    d->errnumber = gnutls_x509_crt_privkey_sign(d->crt, cacrt, abstractKey, GNUTLS_DIG_SHA1, 0);

    gnutls_x509_crt_deinit(cacrt);
    gnutls_x509_privkey_deinit(key);

    if (GNUTLS_E_SUCCESS != d->errnumber)
        return QSslCertificate();

    return crt_to_qsslcert(d->crt, &d->errnumber);
}
Ejemplo n.º 16
0
static int
cert_callback(gnutls_session_t session,
	      const gnutls_datum_t * req_ca_rdn, int nreqs,
	      const gnutls_pk_algorithm_t * sign_algos,
	      int sign_algos_length, gnutls_pcert_st ** pcert,
	      unsigned int *pcert_length, gnutls_privkey_t * pkey)
{
	int ret;
	gnutls_pcert_st *p;
	gnutls_privkey_t lkey;

	p = gnutls_malloc(sizeof(*p));
	if (p==NULL)
		return -1;

	if (g_pkey == NULL) {
		ret = gnutls_pcert_import_x509_raw(p, &server_cert, GNUTLS_X509_FMT_PEM, 0);
		if (ret < 0)
			return -1;

		ret = gnutls_privkey_init(&lkey);
		if (ret < 0)
			return -1;

		ret = gnutls_privkey_import_x509_raw(lkey, &server_key, GNUTLS_X509_FMT_PEM, NULL, 0);
		if (ret < 0)
			return -1;

		g_pcert = p;
		g_pkey = lkey;

		*pcert = p;
		*pcert_length = 1;
		*pkey = lkey;
	} else {
		*pcert = g_pcert;
		*pcert_length = 1;
	}
	*pkey = g_pkey;

	return 0;
}
Ejemplo n.º 17
0
/* Load the certificate and the private key.
 */
static void
load_keys (void)
{
  int ret;
  gnutls_datum_t data;

  ret = gnutls_load_file (CERT_FILE, &data);
  if (ret < 0)
    {
      fprintf (stderr, "*** Error loading certificate file.\n");
      exit (1);
    }

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

  gnutls_free(data.data);

  ret = gnutls_load_file (KEY_FILE, &data);
  if (ret < 0)
    {
      fprintf (stderr, "*** Error loading key file.\n");
      exit (1);
    }

  gnutls_privkey_init (&key);

  ret = gnutls_privkey_import_x509_raw (key, &data, GNUTLS_X509_FMT_PEM, NULL, 0);
  if (ret < 0)
    {
      fprintf (stderr, "*** Error loading key file: %s\n",
               gnutls_strerror (ret));
      exit (1);
    }
    
  gnutls_free(data.data);
}
Ejemplo n.º 18
0
static gnutls_privkey_t _load_url_privkey(const char *url)
{
	int ret;
	gnutls_privkey_t key;

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

	ret = gnutls_privkey_import_url(key, url, 0);
	if (ret < 0) {
		fprintf(stderr, "importing key: %s: %s\n",
			url, gnutls_strerror(ret));
		exit(1);
	}

	return key;
}
Ejemplo n.º 19
0
static
int dcrypt_gnutls_generate_keypair(struct dcrypt_keypair *pair_r, enum dcrypt_key_type kind, unsigned int bits, const char *curve, const char **error_r)
{
	gnutls_pk_algorithm_t pk_algo;
	gnutls_ecc_curve_t pk_curve;

        if (kind == DCRYPT_KEY_EC) {
		pk_curve = gnutls_ecc_curve_get_id(curve);
		if (pk_curve == GNUTLS_ECC_CURVE_INVALID) {
			*error_r = "Invalid curve";
			return -1;
		}
		bits = GNUTLS_CURVE_TO_BITS(pk_curve);
#if GNUTLS_VERSION_NUMBER >= 0x030500
		pk_algo = gnutls_curve_get_pk(pk_curve);
#else
		pk_algo = GNUTLS_PK_EC;
#endif 
        } else if (kind == DCRYPT_KEY_RSA) {
                pk_algo = gnutls_pk_get_id("RSA");
        } else {
		*error_r = "Unsupported key type";
		return -1;
	}

	int ec;
	gnutls_privkey_t priv;
	if ((ec = gnutls_privkey_init(&priv)) != GNUTLS_E_SUCCESS) return dcrypt_gnutls_error(ec, error_r);
#if GNUTLS_VERSION_NUMBER >= 0x030500
	gnutls_privkey_set_flags(priv, GNUTLS_PRIVKEY_FLAG_EXPORT_COMPAT);
#endif
	ec = gnutls_privkey_generate(priv, pk_algo, bits, 0);
	if (ec != GNUTLS_E_SUCCESS) {
		gnutls_privkey_deinit(priv);
		return dcrypt_gnutls_error(ec, error_r);
	}

	pair_r->priv = (struct dcrypt_private_key*)priv;

	return dcrypt_gnutls_private_to_public_key(pair_r->priv, &pair_r->pub, error_r);
} 
Ejemplo n.º 20
0
/**
 * gnutls_x509_crt_sign2:
 * @crt: a certificate of type #gnutls_x509_crt_t
 * @issuer: is the certificate of the certificate issuer
 * @issuer_key: holds the issuer's private key
 * @dig: The message digest to use, %GNUTLS_DIG_SHA1 is a safe choice
 * @flags: must be 0
 *
 * This function will sign the certificate with the issuer's private key, and
 * will copy the issuer's information into the certificate.
 *
 * This must be the last step in a certificate generation since all
 * the previously set parameters are now signed.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_crt_sign2(gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
		      gnutls_x509_privkey_t issuer_key,
		      gnutls_digest_algorithm_t dig, unsigned int flags)
{
	int result;
	gnutls_privkey_t privkey;

	if (crt == NULL || issuer == NULL || issuer_key == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	result = gnutls_privkey_init(&privkey);
	if (result < 0) {
		gnutls_assert();
		return result;
	}

	result = gnutls_privkey_import_x509(privkey, issuer_key, 0);
	if (result < 0) {
		gnutls_assert();
		goto fail;
	}

	result =
	    gnutls_x509_crt_privkey_sign(crt, issuer, privkey, dig, flags);
	if (result < 0) {
		gnutls_assert();
		goto fail;
	}

	result = 0;

      fail:
	gnutls_privkey_deinit(privkey);

	return result;
}
Ejemplo n.º 21
0
PrivateKey::PrivateKey(const Blob& import)
{
    if (gnutls_global_init() != GNUTLS_E_SUCCESS)
        throw CryptoException("Can't initialize GnuTLS.");
    int err = gnutls_x509_privkey_init(&x509_key);
    if (err != GNUTLS_E_SUCCESS)
        throw CryptoException("Can't initialize private key !");

    const gnutls_datum_t dt {(uint8_t*)import.data(), static_cast<unsigned>(import.size())};
    err = gnutls_x509_privkey_import2(x509_key, &dt, GNUTLS_X509_FMT_PEM, nullptr, GNUTLS_PKCS_PLAIN);
    if (err != GNUTLS_E_SUCCESS)
        err = gnutls_x509_privkey_import2(x509_key, &dt, GNUTLS_X509_FMT_DER, nullptr, GNUTLS_PKCS_PLAIN);
    if (err != GNUTLS_E_SUCCESS) {
        gnutls_x509_privkey_deinit(x509_key);
        throw CryptoException("Can't load private key !");
    }

    gnutls_privkey_init(&key);
    if (gnutls_privkey_import_x509(key, x509_key, GNUTLS_PRIVKEY_IMPORT_COPY) != GNUTLS_E_SUCCESS) {
        throw CryptoException("Can't load generic private key !");
    }
}
Ejemplo n.º 22
0
void
sec_mod_server(struct cfg_st* config, const char* socket_file)
{
struct sockaddr_un sa;
socklen_t sa_len;
int cfd, ret, e;
unsigned i, buffer_size, type;
gnutls_privkey_t *key;
uint8_t *buffer;
unsigned key_size = config->key_size;
struct pin_st pins;
gnutls_datum_t data, out;
uint16_t length;
struct iovec iov[2];
int sd;
#if defined(SO_PEERCRED) && defined(HAVE_STRUCT_UCRED)
struct ucred cr;
socklen_t cr_len;
#endif

	ocsignal(SIGHUP, SIG_IGN);
	ocsignal(SIGINT, SIG_DFL);
	ocsignal(SIGTERM, SIG_DFL);

#ifdef HAVE_PKCS11
	ret = gnutls_pkcs11_reinit();
	if (ret < 0) {
	 	syslog(LOG_WARNING, "error in PKCS #11 reinitialization: %s", gnutls_strerror(ret));
	}
#endif

	buffer_size = 8*1024;
	buffer = malloc(buffer_size);
	if (buffer == NULL) {
	 	syslog(LOG_ERR, "error in memory allocation");
	 	exit(1);
	}	

	memset(&sa, 0, sizeof(sa));	
	sa.sun_family = AF_UNIX;
	snprintf(sa.sun_path, sizeof(sa.sun_path), "%s", socket_file);
	remove(socket_file);

	sd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (sd == -1) {
		e = errno;
		syslog(LOG_ERR, "could not create socket '%s': %s", socket_file, strerror(e));
		exit(1);
	}
	
	umask(066);
	ret = bind(sd, (struct sockaddr *)&sa, SUN_LEN(&sa));
	if (ret == -1) {
		e = errno;
		syslog(LOG_ERR, "could not bind socket '%s': %s", socket_file, strerror(e));
		exit(1);
	}

	ret = chown(socket_file, config->uid, config->gid);
	if (ret == -1) {
		e = errno;
		syslog(LOG_ERR, "could not chown socket '%s': %s", socket_file, strerror(e));
	}

	ret = listen(sd, 1024);
	if (ret == -1) {
		e = errno;
		syslog(LOG_ERR, "could not listen to socket '%s': %s", socket_file, strerror(e));
		exit(1);
	}

	ret = load_pins(config, &pins);
	if (ret < 0) {
	 	syslog(LOG_ERR, "error loading PIN files");
	 	exit(1);
	}	
	
	key = malloc(sizeof(*key)*config->key_size);
	if (key == NULL) {
	 	syslog(LOG_ERR, "error in memory allocation");
	 	exit(1);
	}	

	/* read private keys */
	for (i=0;i<key_size;i++) {
		ret = gnutls_privkey_init(&key[i]);
		GNUTLS_FATAL_ERR(ret);

		/* load the private key */
		if (gnutls_url_is_supported(config->key[i]) != 0) {
			gnutls_privkey_set_pin_function (key[i], pin_callback, &pins);
			ret = gnutls_privkey_import_url(key[i], config->key[i], 0);
			GNUTLS_FATAL_ERR(ret);
		} else {
			ret = gnutls_load_file(config->key[i], &data);
			if (ret < 0) {
				syslog(LOG_ERR, "error loading file '%s'", config->key[i]);
				GNUTLS_FATAL_ERR(ret);
			}

			ret = gnutls_privkey_import_x509_raw(key[i], &data, GNUTLS_X509_FMT_PEM, NULL, 0);
			GNUTLS_FATAL_ERR(ret);

			gnutls_free(data.data);
		}
	}

	syslog(LOG_INFO, "sec-mod initialized (socket: %s)", socket_file);
	for (;;) {
		sa_len = sizeof(sa);
		cfd = accept(sd, (struct sockaddr *)&sa, &sa_len);
		if (cfd == -1) {
		 	e = errno;
		 	syslog(LOG_ERR, "sec-mod error accepting connection: %s", strerror(e));
		 	continue;
		}

#if defined(SO_PEERCRED) && defined(HAVE_STRUCT_UCRED)
		cr_len = sizeof(cr);
		ret = getsockopt(cfd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len);
		if (ret == -1) {
		 	e = errno;
		 	syslog(LOG_ERR, "sec-mod error obtaining peer credentials: %s", strerror(e));
		 	goto cont;
		}

	 	syslog(LOG_DEBUG, "sec-mod received request from pid %u and uid %u", (unsigned)cr.pid, (unsigned)cr.uid);
		if (cr.uid != config->uid || cr.gid != config->gid) {
		 	syslog(LOG_ERR, "sec-mod received unauthorized request from pid %u and uid %u", (unsigned)cr.pid, (unsigned)cr.uid);
		 	goto cont;
		}
#endif
		/* read request */
		ret = recv(cfd, buffer, buffer_size, 0);
		if (ret == 0)
			goto cont;
		else if (ret <= 2) {
		 	e = errno;
		 	syslog(LOG_ERR, "error receiving sec-mod data: %s", strerror(e));
		 	goto cont;
		}
		 
		/* calculate */
		i = buffer[0];
		type = buffer[1];

		if (i >= key_size) {
		 	syslog(LOG_ERR, "sec-mod received out-of-bounds key index");
			goto cont;
		}
		 
		data.data = &buffer[2];
		data.size = ret - 2;
		 
		if (type == 'S') {
#if GNUTLS_VERSION_NUMBER >= 0x030200
		 	ret = gnutls_privkey_sign_hash(key[i], 0, GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA, &data, &out);
#else
		 	ret = gnutls_privkey_sign_raw_data(key[i], 0, &data, &out);
#endif
		} else if (type == 'D') {
		 	ret = gnutls_privkey_decrypt_data(key[i], 0, &data, &out);
		} else {
		 	syslog(LOG_ERR, "unknown type 0x%.2x", type);
			goto cont;
		}
		
		if (ret < 0) {
		 	syslog(LOG_ERR, "sec-mod error in crypto operation: %s", gnutls_strerror(ret));
			goto cont;
		}
		 
		/* write reply */
		length = out.size;
		
		iov[0].iov_base = &length;
		iov[0].iov_len = 2;
		
		iov[1].iov_base = out.data;
		iov[1].iov_len = out.size;
		ret = writev(cfd, iov, 2);
		if (ret == -1) {
		        e = errno;
		 	syslog(LOG_ERR, "sec-mod error in writev: %s", strerror(e));
		}

		gnutls_free(out.data);
cont:
		close(cfd);
	}
}
Ejemplo n.º 23
0
int load_tpm_key(struct openconnect_info *vpninfo, gnutls_datum_t *fdata,
		 gnutls_privkey_t *pkey, gnutls_datum_t *pkey_sig)
{
	static const TSS_UUID SRK_UUID = TSS_UUID_SRK;
	gnutls_datum_t asn1;
	unsigned int tss_len;
	char *pass;
	int ofs, err;

	err = gnutls_pem_base64_decode_alloc("TSS KEY BLOB", fdata, &asn1);
	if (err) {
		vpn_progress(vpninfo, PRG_ERR,
			     _("Error decoding TSS key blob: %s\n"),
			     gnutls_strerror(err));
		return -EINVAL;
	}
	/* Ick. We have to parse the ASN1 OCTET_STRING for ourselves. */
	if (asn1.size < 2 || asn1.data[0] != 0x04 /* OCTET_STRING */) {
		vpn_progress(vpninfo, PRG_ERR,
			     _("Error in TSS key blob\n"));
		goto out_blob;
	}

	tss_len = asn1.data[1];
	ofs = 2;
	if (tss_len & 0x80) {
		int lenlen = tss_len & 0x7f;

		if (asn1.size < 2 + lenlen || lenlen > 3) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Error in TSS key blob\n"));
			goto out_blob;
		}

		tss_len = 0;
		while (lenlen) {
			tss_len <<= 8;
			tss_len |= asn1.data[ofs++];
			lenlen--;
		}
	}
	if (tss_len + ofs != asn1.size) {
		vpn_progress(vpninfo, PRG_ERR,
			     _("Error in TSS key blob\n"));
		goto out_blob;
	}

	err = Tspi_Context_Create(&vpninfo->tpm_context);
	if (err) {
		vpn_progress(vpninfo, PRG_ERR,
			     _("Failed to create TPM context: %s\n"),
			     Trspi_Error_String(err));
		goto out_blob;
	}
	err = Tspi_Context_Connect(vpninfo->tpm_context, NULL);
	if (err) {
		vpn_progress(vpninfo, PRG_ERR,
			     _("Failed to connect TPM context: %s\n"),
			     Trspi_Error_String(err));
		goto out_context;
	}
	err = Tspi_Context_LoadKeyByUUID(vpninfo->tpm_context, TSS_PS_TYPE_SYSTEM,
					 SRK_UUID, &vpninfo->srk);
	if (err) {
		vpn_progress(vpninfo, PRG_ERR,
			     _("Failed to load TPM SRK key: %s\n"),
			     Trspi_Error_String(err));
		goto out_context;
	}
	err = Tspi_GetPolicyObject(vpninfo->srk, TSS_POLICY_USAGE, &vpninfo->srk_policy);
	if (err) {
		vpn_progress(vpninfo, PRG_ERR,
			     _("Failed to load TPM SRK policy object: %s\n"),
			     Trspi_Error_String(err));
		goto out_srk;
	}

	pass = vpninfo->cert_password;
	vpninfo->cert_password = NULL;
	while (1) {
		static const char nullpass[20];

		/* We don't seem to get the error here... */
		if (pass)
			err = Tspi_Policy_SetSecret(vpninfo->srk_policy,
						    TSS_SECRET_MODE_PLAIN,
						    strlen(pass), (BYTE *)pass);
		else /* Well-known NULL key */
			err = Tspi_Policy_SetSecret(vpninfo->srk_policy,
						    TSS_SECRET_MODE_SHA1,
						    sizeof(nullpass), (BYTE *)nullpass);
		if (err) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to set TPM PIN: %s\n"),
				     Trspi_Error_String(err));
			goto out_srkpol;
		}

		free(pass);

		/* ... we get it here instead. */
		err = Tspi_Context_LoadKeyByBlob(vpninfo->tpm_context, vpninfo->srk,
						 tss_len, asn1.data + ofs,
						 &vpninfo->tpm_key);
		if (!err)
			break;

		if (pass)
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to load TPM key blob: %s\n"),
				     Trspi_Error_String(err));

		if (err != TPM_E_AUTHFAIL)
			goto out_srkpol;

		err = request_passphrase(vpninfo, "openconnect_tpm_srk",
					 &pass, _("Enter TPM SRK PIN:"));
		if (err)
			goto out_srkpol;
	}

#ifdef HAVE_GNUTLS_CERTIFICATE_SET_KEY
	gnutls_privkey_init(pkey);
	/* This would be nicer if there was a destructor callback. I could
	   allocate a data structure with the TPM handles and the vpninfo
	   pointer, and destroy that properly when the key is destroyed. */
	gnutls_privkey_import_ext(*pkey, GNUTLS_PK_RSA, vpninfo, tpm_sign_fn, NULL, 0);
#else
	*pkey = OPENCONNECT_TPM_PKEY;
#endif

 retry_sign:
	err = sign_dummy_data(vpninfo, *pkey, fdata, pkey_sig);
	if (err == GNUTLS_E_INSUFFICIENT_CREDENTIALS) {
		if (!vpninfo->tpm_key_policy) {
			err = Tspi_Context_CreateObject(vpninfo->tpm_context,
							TSS_OBJECT_TYPE_POLICY,
							TSS_POLICY_USAGE,
							&vpninfo->tpm_key_policy);
			if (err) {
				vpn_progress(vpninfo, PRG_ERR,
					     _("Failed to create key policy object: %s\n"),
					     Trspi_Error_String(err));
				goto out_key;
			}
			err = Tspi_Policy_AssignToObject(vpninfo->tpm_key_policy,
							 vpninfo->tpm_key);
			if (err) {
				vpn_progress(vpninfo, PRG_ERR,
					     _("Failed to assign policy to key: %s\n"),
					     Trspi_Error_String(err));
				goto out_key_policy;
			}
		}
	        err = request_passphrase(vpninfo, "openconnect_tpm_key",
					 &pass, _("Enter TPM key PIN:"));
		if (err)
			goto out_key_policy;

		err = Tspi_Policy_SetSecret(vpninfo->tpm_key_policy,
					    TSS_SECRET_MODE_PLAIN,
					    strlen(pass), (void *)pass);
		free (pass);

		if (err) {
			vpn_progress(vpninfo, PRG_ERR,
				     _("Failed to set key PIN: %s\n"),
				     Trspi_Error_String(err));
			goto out_key_policy;
		}
		goto retry_sign;
	}

	free (asn1.data);
	return 0;
 out_key_policy:
	Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key_policy);
	vpninfo->tpm_key_policy = 0;
 out_key:
	Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->tpm_key);
	vpninfo->tpm_key = 0;
 out_srkpol:
	Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk_policy);
	vpninfo->srk_policy = 0;
 out_srk:
	Tspi_Context_CloseObject(vpninfo->tpm_context, vpninfo->srk);
	vpninfo->srk = 0;
 out_context:
	Tspi_Context_Close(vpninfo->tpm_context);
	vpninfo->tpm_context = 0;
 out_blob:
	free (asn1.data);
	return -EIO;
}
Ejemplo n.º 24
0
void doit(void)
{
	int ret;
	unsigned int mode;
	gnutls_cipher_hd_t ch;
	gnutls_hmac_hd_t mh;
	gnutls_session_t session;
	gnutls_pubkey_t pubkey;
	gnutls_x509_privkey_t xprivkey;
	gnutls_privkey_t privkey;
	gnutls_datum_t key = { key16, sizeof(key16) };
	gnutls_datum_t iv = { iv16, sizeof(iv16) };

	fprintf(stderr,
		"Please note that if in FIPS140 mode, you need to assure the library's integrity prior to running this test\n");

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

	mode = gnutls_fips140_mode_enabled();
	if (mode == 0) {
		success("We are not in FIPS140 mode\n");
		exit(77);
	}

	ret = global_init();
	if (ret < 0) {
		fail("Cannot initialize library\n");
	}

	/* Try crypto.h functionality */
	ret =
	    gnutls_cipher_init(&ch, GNUTLS_CIPHER_AES_128_CBC, &key, &iv);
	if (ret < 0) {
		fail("gnutls_cipher_init failed\n");
	}
	gnutls_cipher_deinit(ch);

	ret = gnutls_hmac_init(&mh, GNUTLS_MAC_SHA1, key.data, key.size);
	if (ret < 0) {
		fail("gnutls_hmac_init failed\n");
	}
	gnutls_hmac_deinit(mh, NULL);

	ret = gnutls_rnd(GNUTLS_RND_NONCE, key16, sizeof(key16));
	if (ret < 0) {
		fail("gnutls_rnd failed\n");
	}

	ret = gnutls_pubkey_init(&pubkey);
	if (ret < 0) {
		fail("gnutls_pubkey_init failed\n");
	}
	gnutls_pubkey_deinit(pubkey);

	ret = gnutls_privkey_init(&privkey);
	if (ret < 0) {
		fail("gnutls_privkey_init failed\n");
	}
	gnutls_privkey_deinit(privkey);

	ret = gnutls_x509_privkey_init(&xprivkey);
	if (ret < 0) {
		fail("gnutls_privkey_init failed\n");
	}
	gnutls_x509_privkey_deinit(xprivkey);

	ret = gnutls_init(&session, 0);
	if (ret < 0) {
		fail("gnutls_init failed\n");
	}
	gnutls_deinit(session);

	/* Test when FIPS140 is set to error state */
	_gnutls_lib_simulate_error();


	/* Try crypto.h functionality */
	ret =
	    gnutls_cipher_init(&ch, GNUTLS_CIPHER_AES_128_CBC, &key, &iv);
	if (ret >= 0) {
		fail("gnutls_cipher_init succeeded when in FIPS140 error state\n");
	}

	ret = gnutls_hmac_init(&mh, GNUTLS_MAC_SHA1, key.data, key.size);
	if (ret >= 0) {
		fail("gnutls_hmac_init succeeded when in FIPS140 error state\n");
	}

	ret = gnutls_rnd(GNUTLS_RND_NONCE, key16, sizeof(key16));
	if (ret >= 0) {
		fail("gnutls_rnd succeeded when in FIPS140 error state\n");
	}

	ret = gnutls_pubkey_init(&pubkey);
	if (ret >= 0) {
		fail("gnutls_pubkey_init succeeded when in FIPS140 error state\n");
	}

	ret = gnutls_privkey_init(&privkey);
	if (ret >= 0) {
		fail("gnutls_privkey_init succeeded when in FIPS140 error state\n");
	}

	ret = gnutls_x509_privkey_init(&xprivkey);
	if (ret >= 0) {
		fail("gnutls_x509_privkey_init succeeded when in FIPS140 error state\n");
	}

	ret = gnutls_init(&session, 0);
	if (ret >= 0) {
		fail("gnutls_init succeeded when in FIPS140 error state\n");
	}

	gnutls_global_deinit();
	return;
}
Ejemplo n.º 25
0
void
doit (void)
{
  gnutls_x509_privkey_t pkey;
  gnutls_privkey_t abs_pkey;
  gnutls_x509_crq_t crq;

  size_t pkey_key_id_len;
  unsigned char *pkey_key_id = NULL;

  size_t crq_key_id_len;
  unsigned char *crq_key_id = NULL;

  gnutls_pk_algorithm_t algorithm;

  int ret;

  ret = global_init ();
  if (ret < 0)
    fail ("global_init: %d\n", ret);

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

  for (algorithm = GNUTLS_PK_RSA; algorithm <= GNUTLS_PK_DSA; algorithm++)
    {
      ret = gnutls_x509_crq_init (&crq);
      if (ret < 0)
        fail ("gnutls_x509_crq_init: %d\n", ret);

      ret = gnutls_x509_privkey_init (&pkey);
      if (ret < 0)
        {
          fail ("gnutls_x509_privkey_init: %d\n", ret);
        }

      ret = gnutls_privkey_init (&abs_pkey);
      if (ret < 0)
        {
          fail ("gnutls_privkey_init: %d\n", ret);
        }

      ret = gnutls_x509_privkey_generate (pkey, algorithm, 1024, 0);
      if (ret < 0)
        {
          fail ("gnutls_x509_privkey_generate (rsa): %d\n", ret);
        }
      else if (debug)
        {
          success ("Key[%s] generation ok: %d\n",
                   gnutls_pk_algorithm_get_name (algorithm), ret);
        }

      pkey_key_id_len = 0;
      ret = gnutls_x509_privkey_get_key_id (pkey, 0, pkey_key_id,
                                            &pkey_key_id_len);
      if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
        {
          fail ("gnutls_x509_privkey_get_key_id incorrectly returns %d\n",
                ret);
        }

      pkey_key_id = malloc (sizeof (unsigned char) * pkey_key_id_len);
      ret = gnutls_x509_privkey_get_key_id (pkey, 0, pkey_key_id,
                                            &pkey_key_id_len);
      if (ret != GNUTLS_E_SUCCESS)
        {
          fail ("gnutls_x509_privkey_get_key_id incorrectly returns %d\n",
                ret);
        }

      ret = gnutls_x509_crq_set_version (crq, 1);
      if (ret < 0)
        {
          fail ("gnutls_x509_crq_set_version: %d\n", ret);
        }

      ret = gnutls_x509_crq_set_key (crq, pkey);
      if (ret < 0)
        {
          fail ("gnutls_x509_crq_set_key: %d\n", ret);
        }

      ret = gnutls_x509_crq_set_dn_by_oid (crq, GNUTLS_OID_X520_COMMON_NAME,
                                           0, "CN-Test", 7);
      if (ret < 0)
        {
          fail ("gnutls_x509_crq_set_dn_by_oid: %d\n", ret);
        }

      ret = gnutls_privkey_import_x509( abs_pkey, pkey, 0);
      if (ret < 0)
        {
          fail ("gnutls_privkey_import_x509: %d\n", ret);
        }

      ret = gnutls_x509_crq_privkey_sign (crq, abs_pkey, GNUTLS_DIG_SHA1, 0);
      if (ret < 0)
        {
          fail ("gnutls_x509_crq_sign: %d\n", ret);
        }

      ret = gnutls_x509_crq_verify (crq, 0);
      if (ret < 0)
        {
          fail ("gnutls_x509_crq_verify: %d\n", ret);
        }

      crq_key_id_len = 0;
      ret = gnutls_x509_crq_get_key_id (crq, 0, crq_key_id, &crq_key_id_len);
      if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
        {
          fail ("gnutls_x509_crq_get_key_id incorrectly returns %d\n", ret);
        }

      crq_key_id = malloc (sizeof (unsigned char) * crq_key_id_len);
      ret = gnutls_x509_crq_get_key_id (crq, 0, crq_key_id, &crq_key_id_len);
      if (ret != GNUTLS_E_SUCCESS)
        {
          fail ("gnutls_x509_crq_get_key_id incorrectly returns %d\n", ret);
        }

      if (crq_key_id_len == pkey_key_id_len)
        {
          ret = memcmp (crq_key_id, pkey_key_id, crq_key_id_len);
          if (ret == 0)
            {
              if (debug)
                success ("Key ids are identical. OK.\n");
            }
          else
            {
              fail ("Key ids differ incorrectly: %d\n", ret);
            }
        }
      else
        {
          fail ("Key_id lengths differ incorrectly: %d - %d\n",
                (int) crq_key_id_len, (int) pkey_key_id_len);
        }


      if (pkey_key_id)
        {
          free (pkey_key_id);
          pkey_key_id = NULL;
        }

      if (crq_key_id)
        {
          free (crq_key_id);
          crq_key_id = NULL;
        }

      gnutls_x509_crq_deinit (crq);
      gnutls_x509_privkey_deinit (pkey);
      gnutls_privkey_deinit (abs_pkey);
    }

  gnutls_global_deinit ();
}
Ejemplo n.º 26
0
Eet_Error
eet_identity_sign(FILE    *fp,
                  Eet_Key *key)
{
#ifdef HAVE_SIGNATURE
   Eet_Error err = EET_ERROR_NONE;
   struct stat st_buf;
   void *data;
   int fd;
   int head[3];
   unsigned char *sign = NULL;
   unsigned char *cert = NULL;
# ifdef HAVE_GNUTLS
   gnutls_datum_t datum = { NULL, 0 };
   size_t sign_len = 0;
   size_t cert_len = 0;
   gnutls_datum_t signum = { NULL, 0 };
   gnutls_privkey_t privkey;
# else /* ifdef HAVE_GNUTLS */
#  if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
   EVP_MD_CTX *md_ctx;
#  else
   EVP_MD_CTX md_ctx;
#  endif
   unsigned int sign_len = 0;
   int cert_len = 0;
# endif /* ifdef HAVE_GNUTLS */

   /* A few check and flush pending write. */
   if (!fp || !key || !key->certificate || !key->private_key)
     return EET_ERROR_BAD_OBJECT;

   if (!emile_cipher_init()) return EET_ERROR_NOT_IMPLEMENTED;

   /* Get the file size. */
   fd = fileno(fp);
   if (fd < 0)
     return EET_ERROR_BAD_OBJECT;

   if (fstat(fd, &st_buf) < 0)
     return EET_ERROR_MMAP_FAILED;

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

   /* Map the file in memory. */
   data = mmap(NULL, st_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
   if (data == MAP_FAILED)
     return EET_ERROR_MMAP_FAILED;

# ifdef HAVE_GNUTLS
   datum.data = data;
   datum.size = st_buf.st_size;

   /* Get the signature length */
   if (gnutls_privkey_init(&privkey) < 0)
     {
        err = EET_ERROR_SIGNATURE_FAILED;
        goto on_error;
     }

   if (gnutls_privkey_import_x509(privkey, key->private_key, 0) < 0)
     {
        err = EET_ERROR_SIGNATURE_FAILED;
        goto on_error;
     }

   if (gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, &datum, &signum) < 0)
     {
        err = EET_ERROR_SIGNATURE_FAILED;
        goto on_error;
     }

   sign = signum.data;
   sign_len = signum.size;

   /* Get the certificate length */
   if (gnutls_x509_crt_export(key->certificate, GNUTLS_X509_FMT_DER, cert,
                              &cert_len) &&
       !cert_len)
     {
        err = EET_ERROR_SIGNATURE_FAILED;
        goto on_error;
     }

   /* Get the certificate */
   cert = malloc(cert_len);
   if (!cert ||
       gnutls_x509_crt_export(key->certificate, GNUTLS_X509_FMT_DER, cert,
                              &cert_len))
     {
        if (!cert)
          err = EET_ERROR_OUT_OF_MEMORY;
        else
          err = EET_ERROR_SIGNATURE_FAILED;

        goto on_error;
     }

# else /* ifdef HAVE_GNUTLS */
   sign_len = EVP_PKEY_size(key->private_key);
   sign = malloc(sign_len);
   if (!sign)
     {
        err = EET_ERROR_OUT_OF_MEMORY;
        goto on_error;
     }

   /* Do the signature. */
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
   md_ctx = EVP_MD_CTX_new();
   EVP_SignInit(md_ctx, EVP_sha1());
   EVP_SignUpdate(md_ctx, data, st_buf.st_size);
   err = EVP_SignFinal(md_ctx,
                       sign,
                       (unsigned int *)&sign_len,
                       key->private_key);
   EVP_MD_CTX_free(md_ctx);
#else
   EVP_SignInit(&md_ctx, EVP_sha1());
   EVP_SignUpdate(&md_ctx, data, st_buf.st_size);
   err = EVP_SignFinal(&md_ctx,
                       sign,
                       (unsigned int *)&sign_len,
                       key->private_key);
   EVP_MD_CTX_cleanup(&md_ctx);
#endif
   if (err != 1)
     {
        ERR_print_errors_fp(stdout);
        err = EET_ERROR_SIGNATURE_FAILED;
        goto on_error;
     }

   /* Give me the der (binary form for X509). */
   cert_len = i2d_X509(key->certificate, &cert);
   if (cert_len < 0)
     {
        ERR_print_errors_fp(stdout);
        err = EET_ERROR_X509_ENCODING_FAILED;
        goto on_error;
     }

# endif /* ifdef HAVE_GNUTLS */
   /* Append the signature at the end of the file. */
   head[0] = (int)htonl ((unsigned int)EET_MAGIC_SIGN);
   head[1] = (int)htonl ((unsigned int)sign_len);
   head[2] = (int)htonl ((unsigned int)cert_len);

   if (fwrite(head, sizeof(head), 1, fp) != 1)
     {
        err = EET_ERROR_WRITE_ERROR;
        goto on_error;
     }

   if (fwrite(sign, sign_len, 1, fp) != 1)
     {
        err = EET_ERROR_WRITE_ERROR;
        goto on_error;
     }

   if (fwrite(cert, cert_len, 1, fp) != 1)
     {
        err = EET_ERROR_WRITE_ERROR;
        goto on_error;
     }

on_error:
# ifdef HAVE_GNUTLS
   if (cert)
     free(cert);

# else /* ifdef HAVE_GNUTLS */
   if (cert)
     OPENSSL_free(cert);

# endif /* ifdef HAVE_GNUTLS */
   if (sign)
     free(sign);

   munmap(data, st_buf.st_size);
   return err;
#else /* ifdef HAVE_SIGNATURE */
   fp = NULL;
   key = NULL;
   return EET_ERROR_NOT_IMPLEMENTED;
#endif /* ifdef HAVE_SIGNATURE */
}
Ejemplo n.º 27
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) */
}
Ejemplo n.º 28
0
static int
server_cert_callback(gnutls_session_t session,
		     const struct gnutls_cert_retr_st *info,
		     gnutls_pcert_st **pcert,
		     unsigned int *pcert_length,
		     gnutls_ocsp_data_st **ocsp,
		     unsigned int *ocsp_length,
		     gnutls_privkey_t *pkey,
		     unsigned int *flags)
{
	int ret;
	gnutls_pcert_st *p;
	gnutls_privkey_t lkey;
	gnutls_x509_crt_t *certs;
	unsigned certs_size, i;

	if (server_pkey == NULL) {
		p = gnutls_malloc(2 * sizeof(*p));
		if (p == NULL)
			return -1;

		ocspdata[0].response.data = (void*)OCSP_DATA;
		ocspdata[0].response.size = OCSP_SIZE;
		ocspdata[0].exptime = 0;

		ocspdata[1].response.data = (void*)OCSP_DATA;
		ocspdata[1].response.size = OCSP_SIZE;
		ocspdata[1].exptime = 0;

		ret = gnutls_x509_crt_list_import2(&certs, &certs_size,
						   &server_ca3_localhost_cert_chain,
						   GNUTLS_X509_FMT_PEM, 0);
		if (ret < 0)
			return -1;
		ret = gnutls_pcert_import_x509_list(p, certs, &certs_size, 0);
		if (ret < 0)
			return -1;
		for (i = 0; i < certs_size; i++)
			gnutls_x509_crt_deinit(certs[i]);
		gnutls_free(certs);

		ret = gnutls_privkey_init(&lkey);
		if (ret < 0)
			return -1;

		ret =
		    gnutls_privkey_import_x509_raw(lkey, &server_ca3_key,
						   GNUTLS_X509_FMT_PEM, NULL,
						   0);
		if (ret < 0)
			return -1;

		server_pcert = p;
		server_pkey = lkey;

		*pcert = p;
		*pcert_length = 2;
		*pkey = lkey;
		*ocsp = ocspdata;
		*ocsp_length = 2;
	} else {
		*pcert = server_pcert;
		*pcert_length = 2;
		*pkey = server_pkey;
		*ocsp = ocspdata;
		*ocsp_length = 2;
	}

	return 0;
}
Ejemplo n.º 29
0
void doit(void)
{
	int ret;
	const char *lib;
	gnutls_privkey_t key;
	gnutls_pkcs11_obj_t obj;
	gnutls_datum_t sig = {NULL, 0}, data;
	unsigned flags = 0;

	lib = getenv("P11MOCKLIB1");
	if (lib == NULL)
		lib = P11LIB;

	{
		void *dl;
		unsigned int *pflags;

		dl = dlopen(lib, RTLD_NOW);
		if (dl == NULL) {
			fail("could not dlopen %s\n", lib);
			exit(1);
		}

		pflags = dlsym(dl, "pkcs11_mock_flags");
		if (pflags == NULL) {
			fail("could find pkcs11_mock_flags\n");
			exit(1);
		}

		*pflags = MOCK_FLAG_ALWAYS_AUTH;
	}

	data.data = (void*)"\x38\x17\x0c\x08\xcb\x45\x8f\xd4\x87\x9c\x34\xb6\xf6\x08\x29\x4c\x50\x31\x2b\xbb";
	data.size = 20;

	ret = global_init();
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

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

	ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_add_provider(lib, NULL);
	if (ret != 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pkcs11_obj_init(&obj);
	assert(ret>=0);

	gnutls_pkcs11_obj_set_pin_function(obj, pin_func, NULL);

	ret = gnutls_pkcs11_obj_import_url(obj, "pkcs11:object=test;type=private", GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
	assert(ret>=0);

	ret = gnutls_pkcs11_obj_get_flags(obj, &flags);
	assert(ret>=0);

	if (!(flags & GNUTLS_PKCS11_OBJ_FLAG_MARK_ALWAYS_AUTH)) {
		fail("key object doesn't have the always authenticate flag\n");
	}
	gnutls_pkcs11_obj_deinit(obj);


	ret = gnutls_privkey_init(&key);
	assert(ret>=0);

	gnutls_privkey_set_pin_function(key, pin_func, NULL);

	ret = gnutls_privkey_import_url(key, "pkcs11:object=test", GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	pin_called = 0;

	ret = gnutls_privkey_sign_hash(key, GNUTLS_DIG_SHA1, 0, &data, &sig);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	if (pin_called == 0) {
		fail("PIN function wasn't called!\n");
	}
	pin_called = 0;

	gnutls_free(sig.data);

	/* call again - should re-authenticate */
	ret = gnutls_privkey_sign_hash(key, GNUTLS_DIG_SHA1, 0, &data, &sig);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	if (pin_called == 0) {
		fail("PIN function wasn't called twice!\n");
	}
	pin_called = 0;

	gnutls_free(sig.data);

	if (debug)
		printf("done\n\n\n");

	gnutls_privkey_deinit(key);
	gnutls_pkcs11_deinit();
	gnutls_global_deinit();
}
Ejemplo n.º 30
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

}