Ejemplo n.º 1
0
/**
 * gnutls_certificate_set_x509_key_file2:
 * @res: is a #gnutls_certificate_credentials_t type.
 * @certfile: is a file that containing the certificate list (path) for
 *   the specified private key, in PKCS7 format, or a list of certificates
 * @keyfile: is a file that contains the private key
 * @type: is PEM or DER
 * @pass: is the password of the key
 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
 *
 * This function sets a certificate/private key pair in the
 * gnutls_certificate_credentials_t type.  This function may be
 * called more than once, in case multiple keys/certificates exist for
 * the server.  For clients that need to send more than its own end
 * entity certificate, e.g., also an intermediate CA cert, then the
 * @certfile must contain the ordered certificate chain.
 *
 * Note that the names in the certificate provided will be considered
 * when selecting the appropriate certificate to use (in case of multiple
 * certificate/key pairs).
 *
 * This function can also accept URLs at @keyfile and @certfile. In that case it
 * will use the private key and certificate indicated by the URLs. Note
 * that the supported URLs are the ones indicated by gnutls_url_is_supported().
 * Before GnuTLS 3.4.0 when a URL was specified, the @pass part was ignored and a
 * PIN callback had to be registered, this is no longer the case in current releases.
 *
 * In case the @certfile is provided as a PKCS #11 URL, then the certificate, and its
 * present issuers in the token are imported (i.e., forming the required trust chain).
 *
 * If that function fails to load the @res structure is at an undefined state, it must
 * not be reused to load other keys or certificates.
 *
 * Note that, this function by default returns zero on success and a negative value on error.
 * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
 * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
 *
 * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
 *
 **/
int
gnutls_certificate_set_x509_key_file2(gnutls_certificate_credentials_t res,
				      const char *certfile,
				      const char *keyfile,
				      gnutls_x509_crt_fmt_t type,
				      const char *pass, unsigned int flags)
{
	int ret;
	gnutls_privkey_t rkey;

	/* this should be first
	 */
	if ((ret = _gnutls_read_key_file(res, keyfile, type, pass, flags, &rkey)) < 0)
		return ret;

	if ((ret = read_cert_file(res, rkey, certfile, type)) < 0) {
		gnutls_privkey_deinit(rkey);
		return ret;
	}

	res->ncerts++;

	if ((ret = _gnutls_check_key_cert_match(res)) < 0) {
		gnutls_assert();
		return ret;
	}

	CRED_RET_SUCCESS(res);
}
Ejemplo n.º 2
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.º 3
0
/**
 * gnutls_certificate_free_keys:
 * @sc: is a #gnutls_certificate_credentials_t structure.
 *
 * This function will delete all the keys and the certificates associated
 * with the given credentials. This function must not be called when a
 * TLS negotiation that uses the credentials is in progress.
 *
 **/
void
gnutls_certificate_free_keys (gnutls_certificate_credentials_t sc)
{
  unsigned i, j;

  for (i = 0; i < sc->ncerts; i++)
    {
      for (j = 0; j < sc->certs[i].cert_list_length; j++)
        {
          gnutls_pcert_deinit (&sc->certs[i].cert_list[j]);
        }
      gnutls_free (sc->certs[i].cert_list);
      _gnutls_str_array_clear (&sc->certs[i].names);
    }

  gnutls_free (sc->certs);
  sc->certs = NULL;

  for (i = 0; i < sc->ncerts; i++)
    {
      gnutls_privkey_deinit (sc->pkey[i]);
    }

  gnutls_free (sc->pkey);
  sc->pkey = NULL;

  sc->ncerts = 0;
}
Ejemplo n.º 4
0
/**
 * gnutls_certificate_set_x509_key_mem2:
 * @res: is a #gnutls_certificate_credentials_t type.
 * @cert: contains a certificate list (path) for the specified private key
 * @key: is the private key, or %NULL
 * @type: is PEM or DER
 * @pass: is the key's password
 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
 *
 * This function sets a certificate/private key pair in the
 * gnutls_certificate_credentials_t type. This function may be called
 * more than once, in case multiple keys/certificates exist for the
 * server.
 *
 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
 * is supported. This means that certificates intended for signing cannot
 * be used for ciphersuites that require encryption.
 *
 * If the certificate and the private key are given in PEM encoding
 * then the strings that hold their values must be null terminated.
 *
 * The @key may be %NULL if you are using a sign callback, see
 * gnutls_sign_callback_set().
 *
 * Note that, this function by default returns zero on success and a negative value on error.
 * Since 3.5.6, when the flag %GNUTLS_CERTIFICATE_API_V2 is set using gnutls_certificate_set_flags()
 * it returns an index (greater or equal to zero). That index can be used to other functions to refer to the added key-pair.
 *
 * Returns: On success this functions returns zero, and otherwise a negative value on error (see above for modifying that behavior).
 **/
int
gnutls_certificate_set_x509_key_mem2(gnutls_certificate_credentials_t res,
				     const gnutls_datum_t * cert,
				     const gnutls_datum_t * key,
				     gnutls_x509_crt_fmt_t type,
				     const char *pass, unsigned int flags)
{
	int ret;
	gnutls_privkey_t rkey;

	/* this should be first
	 */
	if ((ret = _gnutls_read_key_mem(res, key ? key->data : NULL,
				key ? key->size : 0, type, pass,
				flags, &rkey)) < 0)
		return ret;

	if ((ret = read_cert_mem(res, rkey, cert->data, cert->size, type)) < 0) {
		gnutls_privkey_deinit(rkey);
		return ret;
	}

	res->ncerts++;

	if (key && (ret = _gnutls_check_key_cert_match(res)) < 0) {
		gnutls_assert();
		return ret;
	}

	CRED_RET_SUCCESS(res);
}
Ejemplo n.º 5
0
static void check_other_work(sec_mod_st *sec)
{
	if (need_exit) {
		unsigned i;

		for (i = 0; i < sec->key_size; i++) {
			gnutls_privkey_deinit(sec->key[i]);
		}

		sec_mod_client_db_deinit(sec);
		tls_cache_deinit(&sec->tls_db);
		talloc_free(sec);
		exit(0);
	}

	if (need_reload) {
		seclog(sec, LOG_DEBUG, "reloading configuration");
		reload_cfg_file(sec, sec->perm_config, 0);
		sec->config = sec->perm_config->config;
		load_keys(sec, 0);
		need_reload = 0;
	}

	if (need_maintainance) {
		seclog(sec, LOG_DEBUG, "performing maintenance");
		cleanup_client_entries(sec);
		expire_tls_sessions(sec);
		seclog(sec, LOG_DEBUG, "active sessions %d", 
			sec_mod_client_db_elems(sec));
		alarm(MAINTAINANCE_TIME);
		need_maintainance = 0;
	}
}
Ejemplo n.º 6
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.º 7
0
PrivateKey::~PrivateKey()
{
    if (key) {
        gnutls_privkey_deinit(key);
        key = nullptr;
    }
    if (x509_key) {
        gnutls_x509_privkey_deinit(x509_key);
        x509_key = nullptr;
    }
    gnutls_global_deinit();
}
Ejemplo n.º 8
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.º 9
0
void doit(void)
{
	server_check();
	reset_buffers();
	client_check();

	if (g_pcert) {
		gnutls_pcert_deinit(g_pcert);
		gnutls_free(g_pcert);
	}
	if (g_pkey) {
		gnutls_privkey_deinit(g_pkey);
	}
}
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.º 11
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.º 12
0
PrivateKey&
PrivateKey::operator=(PrivateKey&& o) noexcept
{
    if (key) {
        gnutls_privkey_deinit(key);
        key = nullptr;
    }
    if (x509_key) {
        gnutls_x509_privkey_deinit(x509_key);
        x509_key = nullptr;
    }
    key = o.key; x509_key = o.x509_key;
    o.key = nullptr; o.x509_key = nullptr;
    return *this;
}
Ejemplo n.º 13
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.º 14
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.º 15
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.º 16
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.º 17
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.º 18
0
static int load_keys(sec_mod_st *sec, unsigned force)
{
	unsigned i, need_reload = 0;
	int ret;
	struct pin_st pins;
	static time_t last_access = 0;

	for (i = 0; i < sec->perm_config->key_size; i++) {
		if (need_file_reload(sec->perm_config->key[i], last_access) != 0) {
			need_reload = 1;
			break;
		}
	}

	if (need_reload == 0)
		return 0;

	last_access = time(0);

	ret = load_pins(sec->perm_config, &pins);
	if (ret < 0) {
		seclog(sec, LOG_ERR, "error loading PIN files");
		exit(1);
	}

	/* Reminder: the number of private keys or their filenames cannot be changed on reload
	 */
	if (sec->key == NULL) {
		sec->key_size = sec->perm_config->key_size;
		sec->key = talloc_zero_size(sec, sizeof(*sec->key) * sec->perm_config->key_size);
		if (sec->key == NULL) {
			seclog(sec, LOG_ERR, "error in memory allocation");
			exit(1);
		}
	}

	/* read private keys */
	for (i = 0; i < sec->key_size; i++) {
		gnutls_privkey_t p;

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

			ret =
			    gnutls_privkey_import_x509_raw(p, &data,
							   GNUTLS_X509_FMT_PEM,
							   NULL, 0);
			if (ret == GNUTLS_E_DECRYPTION_FAILED && pins.pin[0]) {
				ret =
				    gnutls_privkey_import_x509_raw(p, &data,
								   GNUTLS_X509_FMT_PEM,
								   pins.pin, 0);
			}
			CHECK_LOOP_ERR(ret);

			gnutls_free(data.data);
		}

		if (sec->key[i] != NULL) {
			gnutls_privkey_deinit(sec->key[i]);
		}
		sec->key[i] = p;
	}

	return 0;
}
Ejemplo n.º 19
0
void doit(void)
{
	int ret;
	const char *lib;
	gnutls_privkey_t key;
	gnutls_pubkey_t pub;
	gnutls_datum_t m1, e1;
	gnutls_datum_t m2, e2;

	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);

	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);
	}

	ret = gnutls_privkey_init(&key);
	assert(ret>=0);
	ret = gnutls_pubkey_init(&pub);
	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);
	}

	ret = gnutls_pubkey_import_privkey(pub, key, 0, 0);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pubkey_export_rsa_raw(pub, &m1, &e1);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	gnutls_pubkey_deinit(pub);
	gnutls_privkey_deinit(key);

	/* try again using gnutls_pubkey_import_url */	
	ret = gnutls_pubkey_init(&pub);
	assert(ret>=0);

	ret = gnutls_pubkey_import_url(pub, "pkcs11:object=test;type=public", 0);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pubkey_export_rsa_raw(pub, &m2, &e2);
	if (ret < 0) {
		fail("%d: %s\n", ret, gnutls_strerror(ret));
		exit(1);
	}

	assert(m1.size == m2.size);
	assert(e1.size == e2.size);
	assert(memcmp(e1.data, e2.data, e2.size)==0);
	assert(memcmp(m1.data, m2.data, m2.size)==0);

	gnutls_pubkey_deinit(pub);
	gnutls_free(m1.data);
	gnutls_free(e1.data);
	gnutls_free(m2.data);
	gnutls_free(e2.data);
	gnutls_pkcs11_deinit();
	gnutls_global_deinit();
}
Ejemplo n.º 20
0
static
int check_privkey_import_export(void)
{
	gnutls_privkey_t key;
	gnutls_datum_t p, q, g, y, x;
	gnutls_datum_t m, e, u, e1, e2, d;
	gnutls_ecc_curve_t curve;
	gnutls_digest_algorithm_t digest;
	gnutls_gost_paramset_t paramset;
	int ret;

	global_init();

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

	ret = gnutls_privkey_import_dsa_raw(key, &_dsa_p, &_dsa_q, &_dsa_g, &_dsa_y, &_dsa_x);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_privkey_export_dsa_raw2(key, &p, &q, &g, &y, &x, 0);
	if (ret < 0)
		fail("error: %s\n", gnutls_strerror(ret));

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

	ret = gnutls_privkey_export_dsa_raw2(key, &p, &q, &g, &y, &x, GNUTLS_EXPORT_FLAG_NO_LZ);
	if (ret < 0)
		fail("error: %s\n", gnutls_strerror(ret));

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

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

	ret = gnutls_privkey_import_rsa_raw(key, &_rsa_m, &_rsa_e, &_rsa_d, &_rsa_p, &_rsa_q, &_rsa_u, &_rsa_e1, &_rsa_e2);
	if (ret < 0)
		fail("error\n");

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

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

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

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

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

	ret = gnutls_privkey_import_ecc_raw(key, GNUTLS_ECC_CURVE_SECP256R1, &_ecc_x, &_ecc_y, &_ecc_k);
	if (ret < 0)
		fail("error\n");

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

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

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

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

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

	/* test whether an invalid size would fail */
	ret = gnutls_privkey_import_ecc_raw(key, GNUTLS_ECC_CURVE_ED25519, &_rsa_m, NULL, &_rsa_m);
	if (ret != GNUTLS_E_INVALID_REQUEST)
		fail("error\n");

	ret = gnutls_privkey_import_ecc_raw(key, GNUTLS_ECC_CURVE_ED25519, &_ed25519_x, NULL, &_ed25519_k);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_privkey_verify_params(key);
	if (ret != 0)
		fail("error: %s\n", gnutls_strerror(ret));

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

	if (curve != GNUTLS_ECC_CURVE_ED25519) {
		fail("unexpected curve value: %d\n", (int)curve);
	}
	CMP("x", &x, ed25519_x);
	CMP("k", &p, ed25519_k);
	gnutls_free(x.data);
	gnutls_free(p.data);
	gnutls_privkey_deinit(key);

	/* Ed25519 with incorrect public key */
	ret = gnutls_privkey_init(&key);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_privkey_import_ecc_raw(key, GNUTLS_ECC_CURVE_ED25519, &_false_ed25519_x, NULL, &_ed25519_k);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_privkey_verify_params(key);
	if (ret != GNUTLS_E_ILLEGAL_PARAMETER)
		fail("error: %s\n", gnutls_strerror(ret));

	gnutls_privkey_deinit(key);

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

	ret = gnutls_privkey_import_gost_raw(key, GNUTLS_ECC_CURVE_GOST256CPXA, GNUTLS_DIG_GOSTR_94, GNUTLS_GOST_PARAMSET_CP_A, &_gost_x, &_gost_y, &_gost_k);
	if (ret < 0)
		fail("error\n");

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

	if (curve != GNUTLS_ECC_CURVE_GOST256CPXA) {
		fprintf(stderr, "unexpected curve value: %d\n", (int)curve);
		exit(1);
	}
	if (digest != GNUTLS_DIG_GOSTR_94) {
		fprintf(stderr, "unexpected digest value: %d\n", (int)digest);
		exit(1);
	}
	if (paramset != GNUTLS_GOST_PARAMSET_CP_A) {
		fprintf(stderr, "unexpected paramset value: %d\n", (int)paramset);
		exit(1);
	}
	CMP("x", &x, gost_x);
	CMP("y", &y, gost_y);
	CMP("k", &p, gost_k);
	gnutls_free(x.data);
	gnutls_free(y.data);
	gnutls_free(p.data);

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

	if (curve != GNUTLS_ECC_CURVE_GOST256CPXA) {
		fprintf(stderr, "unexpected curve value: %d\n", (int)curve);
		exit(1);
	}
	if (digest != GNUTLS_DIG_GOSTR_94) {
		fprintf(stderr, "unexpected digest value: %d\n", (int)digest);
		exit(1);
	}
	if (paramset != GNUTLS_GOST_PARAMSET_CP_A) {
		fprintf(stderr, "unexpected paramset value: %d\n", (int)paramset);
		exit(1);
	}
	CMP_NO_LZ("x", &x, gost_x);
	CMP_NO_LZ("y", &y, gost_y);
	CMP_NO_LZ("k", &p, gost_k);
	gnutls_free(x.data);
	gnutls_free(y.data);
	gnutls_free(p.data);
	gnutls_privkey_deinit(key);

	return 0;
}
Ejemplo n.º 21
0
void doit(void)
{
	char buf[128];
	int ret;
	const char *lib, *bin;
	gnutls_x509_crt_t crt;
	gnutls_x509_privkey_t key;
	gnutls_datum_t tmp, sig;
	gnutls_privkey_t pkey;
	gnutls_pubkey_t pubkey;
	gnutls_pubkey_t pubkey2;
	unsigned i, sigalgo;

	bin = softhsm_bin();

	lib = softhsm_lib();

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

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

	set_softhsm_conf(CONFIG);
	snprintf(buf, sizeof(buf),
		 "%s --init-token --slot 0 --label test --so-pin " PIN " --pin "
		 PIN, bin);
	system(buf);

	ret = gnutls_pkcs11_add_provider(lib, NULL);
	if (ret < 0) {
		fail("gnutls_x509_crt_init: %s\n", gnutls_strerror(ret));
	}

	if (verify_eddsa_presence() == 0) {
		fprintf(stderr, "Skipping test as no EDDSA mech is supported\n");
		exit(77);
	}

	ret = gnutls_x509_crt_init(&crt);
	if (ret < 0)
		fail("gnutls_x509_crt_init: %s\n", gnutls_strerror(ret));

	ret =
	    gnutls_x509_crt_import(crt, &server_ca3_eddsa_cert,
				   GNUTLS_X509_FMT_PEM);
	if (ret < 0)
		fail("gnutls_x509_crt_import: %s\n", gnutls_strerror(ret));

	if (debug) {
		gnutls_x509_crt_print(crt, GNUTLS_CRT_PRINT_ONELINE, &tmp);

		printf("\tCertificate: %.*s\n", tmp.size, tmp.data);
		gnutls_free(tmp.data);
	}

	ret = gnutls_x509_privkey_init(&key);
	if (ret < 0) {
		fail("gnutls_x509_privkey_init: %s\n", gnutls_strerror(ret));
	}

	ret =
	    gnutls_x509_privkey_import(key, &server_ca3_eddsa_key,
				       GNUTLS_X509_FMT_PEM);
	if (ret < 0) {
		fail("gnutls_x509_privkey_import: %s\n", gnutls_strerror(ret));
	}

	/* initialize softhsm token */
	ret = gnutls_pkcs11_token_init(SOFTHSM_URL, PIN, "test");
	if (ret < 0) {
		fail("gnutls_pkcs11_token_init: %s\n", gnutls_strerror(ret));
	}

	ret =
	    gnutls_pkcs11_token_set_pin(SOFTHSM_URL, NULL, PIN,
					GNUTLS_PIN_USER);
	if (ret < 0) {
		fail("gnutls_pkcs11_token_set_pin: %s\n", gnutls_strerror(ret));
	}

	ret = gnutls_pkcs11_copy_x509_crt(SOFTHSM_URL, crt, "cert",
					  GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE |
					  GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
	if (ret < 0) {
		fail("gnutls_pkcs11_copy_x509_crt: %s\n", gnutls_strerror(ret));
	}

	ret =
	    gnutls_pkcs11_copy_x509_privkey(SOFTHSM_URL, key, "cert",
					    GNUTLS_KEY_DIGITAL_SIGNATURE |
					    GNUTLS_KEY_KEY_ENCIPHERMENT,
					    GNUTLS_PKCS11_OBJ_FLAG_MARK_PRIVATE
					    |
					    GNUTLS_PKCS11_OBJ_FLAG_MARK_SENSITIVE
					    | GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
	if (ret < 0) {
		fail("gnutls_pkcs11_copy_x509_privkey: %s\n",
		     gnutls_strerror(ret));
	}

	gnutls_x509_crt_deinit(crt);
	gnutls_x509_privkey_deinit(key);
	gnutls_pkcs11_set_pin_function(NULL, NULL);

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

	ret =
	    gnutls_privkey_import_pkcs11_url(pkey,
					     SOFTHSM_URL
					     ";object=cert;object-type=private;pin-value="
					     PIN);
	if (ret < 0) {
		fail("error in gnutls_privkey_import_pkcs11_url: %s\n", gnutls_strerror(ret));
	}

	assert(gnutls_pubkey_init(&pubkey) == 0);
	assert(gnutls_pubkey_import_privkey(pubkey, pkey, 0, 0) == 0);

	assert(gnutls_pubkey_init(&pubkey2) == 0);
	assert(gnutls_pubkey_import_x509_raw
	       (pubkey2, &server_ca3_eddsa_cert, GNUTLS_X509_FMT_PEM, 0) == 0);

	/* this is the algorithm supported by the certificate */
	sigalgo = GNUTLS_SIGN_EDDSA_ED25519;

	for (i = 0; i < 20; i++) {
		/* check whether privkey and pubkey are operational
		 * by signing and verifying */
		ret =
		    gnutls_privkey_sign_data2(pkey, sigalgo, 0,
					      &testdata, &sig);
		if (ret < 0)
			myfail("Error signing data %s\n", gnutls_strerror(ret));

		/* verify against the pubkey in PKCS #11 */
		ret =
		    gnutls_pubkey_verify_data2(pubkey, sigalgo, 0,
					       &testdata, &sig);
		if (ret < 0)
			myfail("Error verifying data1: %s\n",
			       gnutls_strerror(ret));

		/* verify against the raw pubkey */
		ret =
		    gnutls_pubkey_verify_data2(pubkey2, sigalgo, 0,
					       &testdata, &sig);
		if (ret < 0)
			myfail("Error verifying data2: %s\n",
			       gnutls_strerror(ret));

		gnutls_free(sig.data);
	}

	gnutls_pubkey_deinit(pubkey2);
	gnutls_pubkey_deinit(pubkey);
	gnutls_privkey_deinit(pkey);

	gnutls_global_deinit();

	remove(CONFIG);
}
Ejemplo n.º 22
0
static
int check_dsa(void)
{
	gnutls_privkey_t key;
	gnutls_pubkey_t pub;
	gnutls_datum_t p, q, g, y, x;
	int ret;

	global_init();

	success("Checking DSA key operations\n");

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

	ret = gnutls_pubkey_init(&pub);
	if (ret < 0)
		fail("error\n");

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

	ret = gnutls_pubkey_import_privkey(pub, key, 0, 0);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_pubkey_export_dsa_raw2(pub, &p, &q, &g, &y, 0);
	if (ret < 0)
		fail("error\n");

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

	ret = gnutls_pubkey_export_dsa_raw2(pub, &p, &q, &g, &y, GNUTLS_EXPORT_FLAG_NO_LZ);
	if (ret < 0)
		fail("error\n");

	CMP_NO_LZ("p", &p, dsa_p);
	CMP_NO_LZ("q", &q, dsa_q);
	CMP_NO_LZ("g", &g, dsa_g);
	CMP_NO_LZ("y", &y, dsa_y);
	gnutls_free(p.data);
	gnutls_free(q.data);
	gnutls_free(g.data);
	gnutls_free(y.data);

	ret = gnutls_privkey_export_dsa_raw(key, &p, &q, &g, &y, &x);
	if (ret < 0)
		fail("error\n");
	CMP("p", &p, dsa_p);
	CMP("q", &q, dsa_q);
	CMP("g", &g, dsa_g);
	CMP("y", &y, dsa_y);
	CMP("x", &x, dsa_x);
	gnutls_free(p.data);
	gnutls_free(q.data);
	gnutls_free(g.data);
	gnutls_free(y.data);
	gnutls_free(x.data);

	ret = _gnutls_privkey_export2_pkcs8(key, GNUTLS_X509_FMT_DER, NULL, 0, &x);
	if (ret < 0 || x.size == 0)
		fail("error in pkcs8 export\n");
	gnutls_free(x.data);

	gnutls_privkey_deinit(key);
	gnutls_pubkey_deinit(pub);

	return 0;
}
Ejemplo n.º 23
0
static
int check_rsa(void)
{
	gnutls_privkey_t key;
	gnutls_pubkey_t pub;
	gnutls_datum_t m, e, d, p, q, u, e1, e2;
	int ret;

	success("Checking RSA key operations\n");

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

	ret = gnutls_pubkey_init(&pub);
	if (ret < 0)
		fail("error\n");

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

	ret = gnutls_pubkey_import_privkey(pub, key, 0, 0);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_pubkey_export_rsa_raw2(pub, &m, &e, 0);
	if (ret < 0)
		fail("error\n");

	CMP("m", &m, rsa_m);
	CMP("e", &e, rsa_e);
	gnutls_free(m.data);
	gnutls_free(e.data);

	ret = gnutls_pubkey_export_rsa_raw2(pub, &m, &e, GNUTLS_EXPORT_FLAG_NO_LZ);
	if (ret < 0)
		fail("error\n");

	CMP_NO_LZ("m", &m, rsa_m);
	CMP_NO_LZ("e", &e, rsa_e);
	gnutls_free(m.data);
	gnutls_free(e.data);

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

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

	ret = _gnutls_privkey_export2_pkcs8(key, GNUTLS_X509_FMT_DER, NULL, 0, &m);
	if (ret < 0 || m.size == 0)
		fail("error in pkcs8 export\n");
	gnutls_free(m.data);

	gnutls_privkey_deinit(key);
	gnutls_pubkey_deinit(pub);

	return 0;
}
Ejemplo n.º 24
0
static
int check_ecc(void)
{
	gnutls_privkey_t key;
	gnutls_pubkey_t pub;
	gnutls_datum_t y, x, k;
	gnutls_ecc_curve_t curve;
	int ret;

	success("Checking SECP256R1 key operations\n");

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

	ret = gnutls_pubkey_init(&pub);
	if (ret < 0)
		fail("error\n");

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

	ret = gnutls_pubkey_import_privkey(pub, key, 0, 0);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_pubkey_export_ecc_raw2(pub, &curve, &x, &y, 0);
	if (ret < 0)
		fail("error\n");

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

	ret = gnutls_pubkey_export_ecc_raw2(pub, &curve, &x, &y, GNUTLS_EXPORT_FLAG_NO_LZ);
	if (ret < 0)
		fail("error\n");

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


	/* check the private key export */
	ret = gnutls_privkey_export_ecc_raw(key, &curve, &x, &y, &k);
	if (ret < 0)
		fail("error\n");

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

	ret = _gnutls_privkey_export2_pkcs8(key, GNUTLS_X509_FMT_DER, NULL, 0, &x);
	if (ret < 0 || x.size == 0)
		fail("error in pkcs8 export\n");
	gnutls_free(x.data);

	gnutls_privkey_deinit(key);

	/* More public key ops */

	ret = gnutls_pubkey_export_ecc_x962(pub, &x, &y);
	if (ret < 0)
		fail("error\n");

	CMP("parameters", &x, ecc_params);
	CMP("ecpoint", &y, ecc_point);

	ret = gnutls_pubkey_import_ecc_x962(pub, &x, &y);
	if (ret < 0)
		fail("error\n");
	gnutls_free(x.data);
	gnutls_free(y.data);

	/* check again */
	ret = gnutls_pubkey_export_ecc_raw(pub, &curve, &x, &y);
	if (ret < 0)
		fail("error\n");

	if (curve != GNUTLS_ECC_CURVE_SECP256R1) {
		fprintf(stderr, "unexpected curve value: %d\n", (int)curve);
		fail("error\n");
	}
	CMP("x", &x, ecc_x);
	CMP("y", &y, ecc_y);
	gnutls_free(x.data);
	gnutls_free(y.data);

	gnutls_pubkey_deinit(pub);

	return 0;
}
Ejemplo n.º 25
0
static
int check_ed25519(void)
{
	gnutls_privkey_t key;
	gnutls_pubkey_t pub;
	gnutls_datum_t y, x, k;
	gnutls_ecc_curve_t curve;
	int ret;

	success("Checking ed25519 key operations\n");

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

	ret = gnutls_pubkey_init(&pub);
	if (ret < 0)
		fail("error\n");

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

	ret = gnutls_pubkey_import_privkey(pub, key, 0, 0);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_pubkey_export_ecc_raw(pub, &curve, &x, NULL);
	if (ret < 0)
		fail("error\n");
	gnutls_free(x.data);

	ret = gnutls_pubkey_export_ecc_raw(pub, &curve, &x, &y);
	if (ret < 0)
		fail("error\n");

	if (curve != GNUTLS_ECC_CURVE_ED25519) {
		fail("unexpected curve value: %d\n", (int)curve);
	}
	CMP("x", &x, ed25519_x);

	if (y.data != NULL) {
		fail("expected NULL value in Y\n");
	}
	gnutls_free(x.data);


	/* check the private key export */
	ret = gnutls_privkey_export_ecc_raw(key, &curve, &x, NULL, &k);
	if (ret < 0)
		fail("error\n");
	gnutls_free(x.data);
	gnutls_free(k.data);

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

	if (curve != GNUTLS_ECC_CURVE_ED25519) {
		fail("unexpected curve value: %d\n", (int)curve);
	}
	CMP("x", &x, ed25519_x);
	CMP("k", &k, ed25519_k);
	gnutls_free(x.data);
	gnutls_free(k.data);

	if (y.data != NULL) {
		fail("expected NULL value in Y\n");
	}

	ret = _gnutls_privkey_export2_pkcs8(key, GNUTLS_X509_FMT_DER, NULL, 0, &x);
	if (ret < 0 || x.size == 0)
		fail("error in pkcs8 export\n");
	gnutls_free(x.data);

	gnutls_privkey_deinit(key);

	/* More public key ops */

	ret = gnutls_pubkey_export_ecc_x962(pub, &x, &y);
	if (ret != GNUTLS_E_INVALID_REQUEST)
		fail("error\n");

	gnutls_pubkey_deinit(pub);

	return 0;
}
Ejemplo n.º 26
0
static
int check_gost(void)
{
	gnutls_privkey_t key;
	gnutls_pubkey_t pub;
	gnutls_datum_t y, x, k;
	gnutls_ecc_curve_t curve;
	gnutls_digest_algorithm_t digest;
	gnutls_gost_paramset_t paramset;
	int ret;

	success("Checking GOST key operations\n");

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

	ret = gnutls_pubkey_init(&pub);
	if (ret < 0)
		fail("error\n");

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

	ret = gnutls_pubkey_import_privkey(pub, key, 0, 0);
	if (ret < 0)
		fail("error\n");

	ret = gnutls_pubkey_export_gost_raw2(pub, &curve, &digest, &paramset, &x, &y, 0);
	if (ret < 0)
		fail("error\n");

	if (curve != GNUTLS_ECC_CURVE_GOST256CPXA) {
		fprintf(stderr, "unexpected curve value: %d\n", (int)curve);
		exit(1);
	}
	if (digest != GNUTLS_DIG_GOSTR_94) {
		fprintf(stderr, "unexpected digest value: %d\n", (int)digest);
		exit(1);
	}
	if (paramset != GNUTLS_GOST_PARAMSET_CP_A) {
		fprintf(stderr, "unexpected paramset value: %d\n", (int)paramset);
		exit(1);
	}
	CMP("x", &x, gost_x);
	CMP("y", &y, gost_y);
	gnutls_free(x.data);
	gnutls_free(y.data);

	ret = gnutls_pubkey_export_gost_raw2(pub, &curve, &digest, &paramset, &x, &y, GNUTLS_EXPORT_FLAG_NO_LZ);
	if (ret < 0)
		fail("error\n");

	if (curve != GNUTLS_ECC_CURVE_GOST256CPXA) {
		fprintf(stderr, "unexpected curve value: %d\n", (int)curve);
		exit(1);
	}
	if (digest != GNUTLS_DIG_GOSTR_94) {
		fprintf(stderr, "unexpected digest value: %d\n", (int)digest);
		exit(1);
	}
	if (paramset != GNUTLS_GOST_PARAMSET_CP_A) {
		fprintf(stderr, "unexpected paramset value: %d\n", (int)paramset);
		exit(1);
	}
	CMP_NO_LZ("x", &x, gost_x);
	CMP_NO_LZ("y", &y, gost_y);
	gnutls_free(x.data);
	gnutls_free(y.data);


	/* check the private key export */
	ret = gnutls_privkey_export_gost_raw2(key, &curve, &digest, &paramset, &x, &y, &k, 0);
	if (ret < 0)
		fail("error\n");

	if (curve != GNUTLS_ECC_CURVE_GOST256CPXA) {
		fprintf(stderr, "unexpected curve value: %d\n", (int)curve);
		exit(1);
	}
	if (digest != GNUTLS_DIG_GOSTR_94) {
		fprintf(stderr, "unexpected digest value: %d\n", (int)digest);
		exit(1);
	}
	if (paramset != GNUTLS_GOST_PARAMSET_CP_A) {
		fprintf(stderr, "unexpected paramset value: %d\n", (int)paramset);
		exit(1);
	}
	CMP("x", &x, gost_x);
	CMP("y", &y, gost_y);
	CMP("k", &k, gost_k);
	gnutls_free(x.data);
	gnutls_free(y.data);
	gnutls_free(k.data);

	ret = _gnutls_privkey_export2_pkcs8(key, GNUTLS_X509_FMT_DER, NULL, 0, &x);
	if (ret < 0 || x.size == 0)
		fail("error in pkcs8 export\n");
	gnutls_free(x.data);

	gnutls_privkey_deinit(key);

	gnutls_pubkey_deinit(pub);

	return 0;
}
Ejemplo n.º 27
0
void doit(void)
{
	gnutls_x509_privkey_t key;
	gnutls_x509_crt_t crt;
	gnutls_pubkey_t pubkey;
	gnutls_privkey_t privkey;
	gnutls_sign_algorithm_t sign_algo;
	gnutls_datum_t signature;
	gnutls_datum_t signature2;
	int ret;
	size_t i;

	global_init();

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

	for (i = 0; i < sizeof(key_dat) / sizeof(key_dat[0]); i++) {
		if (debug)
			success("loop %d\n", (int) 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_pubkey_init(&pubkey);
		if (ret < 0)
			fail("gnutls_privkey_init\n");

		ret = gnutls_privkey_init(&privkey);
		if (ret < 0)
			fail("gnutls_pubkey_init\n");

		ret = gnutls_privkey_import_x509(privkey, key, 0);
		if (ret < 0)
			fail("gnutls_privkey_import_x509\n");

		ret = gnutls_privkey_sign_hash(privkey, GNUTLS_DIG_SHA1, 0,
						&hash_data, &signature2);
		if (ret < 0)
			fail("gnutls_privkey_sign_hash\n");

		ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0,
						&raw_data, &signature);
		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");

		ret = gnutls_pubkey_import_x509(pubkey, crt, 0);
		if (ret < 0)
			fail("gnutls_x509_pubkey_import\n");

		ret =
		    gnutls_x509_crt_get_signature_algorithm(crt);
		if (ret != GNUTLS_SIGN_RSA_SHA1)
			fail("gnutls_crt_get_signature_algorithm\n");

		ret =
		    gnutls_pubkey_verify_hash2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0, &hash_data,
					      &signature);
		if (ret < 0)
			fail("gnutls_x509_pubkey_verify_hash2\n");

		ret =
		    gnutls_pubkey_verify_hash2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0, &hash_data,
					      &signature2);
		if (ret < 0)
			fail("gnutls_x509_pubkey_verify_hash-1 (hashed data)\n");

		/* should fail */
		ret =
		    gnutls_pubkey_verify_hash2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0,
					      &invalid_hash_data,
					      &signature2);
		if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED)
			fail("gnutls_x509_pubkey_verify_hash-2 (hashed data)\n");

		sign_algo =
		    gnutls_pk_to_sign(gnutls_pubkey_get_pk_algorithm
				      (pubkey, NULL), GNUTLS_DIG_SHA1);

		ret =
		    gnutls_pubkey_verify_hash2(pubkey, sign_algo, 0,
						&hash_data, &signature2);
		if (ret < 0)
			fail("gnutls_x509_pubkey_verify_hash2-1 (hashed data)\n");

		/* should fail */
		ret =
		    gnutls_pubkey_verify_hash2(pubkey, sign_algo, 0,
						&invalid_hash_data,
						&signature2);
		if (ret != GNUTLS_E_PK_SIG_VERIFY_FAILED)
			fail("gnutls_x509_pubkey_verify_hash2-2 (hashed data)\n");

		/* test the raw interface */
		gnutls_free(signature.data);
		signature.data = NULL;

		if (gnutls_pubkey_get_pk_algorithm(pubkey, NULL) ==
		    GNUTLS_PK_RSA) {
			ret =
			    gnutls_privkey_sign_hash(privkey,
						     GNUTLS_DIG_SHA1,
						     GNUTLS_PRIVKEY_SIGN_FLAG_TLS1_RSA,
						     &hash_data,
						     &signature);
			if (ret < 0)
				fail("gnutls_privkey_sign_hash: %s\n",
				     gnutls_strerror(ret));

			sign_algo =
			    gnutls_pk_to_sign
			    (gnutls_pubkey_get_pk_algorithm(pubkey, NULL),
			     GNUTLS_DIG_SHA1);

			ret =
			    gnutls_pubkey_verify_hash2(pubkey, sign_algo,
							GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA,
							&hash_data,
							&signature);
			if (ret < 0)
				fail("gnutls_pubkey_verify_hash-3 (raw hashed data)\n");

			gnutls_free(signature.data);
			/* test the legacy API */
			ret =
			    gnutls_privkey_sign_raw_data(privkey, 0,
							 &hash_data,
							 &signature);
			if (ret < 0)
				fail("gnutls_privkey_sign_raw_data: %s\n",
				     gnutls_strerror(ret));

			ret =
			    gnutls_pubkey_verify_hash2(pubkey, sign_algo,
							GNUTLS_PUBKEY_VERIFY_FLAG_TLS1_RSA,
							&hash_data,
							&signature);
			if (ret < 0)
				fail("gnutls_pubkey_verify_hash-4 (legacy raw hashed data)\n");
		}
		gnutls_free(signature.data);
		gnutls_free(signature2.data);
		gnutls_x509_privkey_deinit(key);
		gnutls_x509_crt_deinit(crt);
		gnutls_privkey_deinit(privkey);
		gnutls_pubkey_deinit(pubkey);
	}

	gnutls_global_deinit();
}
Ejemplo n.º 28
0
void
pkcs11_test_sign(FILE * outfile, const char *url, unsigned int flags,
	    common_info_st * info)
{
	gnutls_privkey_t privkey;
	gnutls_pubkey_t pubkey;
	int ret;
	gnutls_datum_t data, sig = {NULL, 0};
	int pk;

	pkcs11_common(info);

	FIX(url, outfile, 0, info);

	data.data = (void*)TEST_DATA;
	data.size = sizeof(TEST_DATA)-1;

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

	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_privkey_import_url(privkey, url, flags);
	if (ret < 0) {
		fprintf(stderr, "Cannot import private key: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_pubkey_import_privkey(pubkey, privkey, GNUTLS_KEY_DIGITAL_SIGNATURE, flags);
	if (ret < 0) {
		fprintf(stderr, "Cannot import public key: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, &data, &sig);
	if (ret < 0) {
		fprintf(stderr, "Cannot sign data: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	pk = gnutls_pubkey_get_pk_algorithm(pubkey, NULL);

	fprintf(stderr, "Verifying against private key parameters... ");
	ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1),
		0, &data, &sig);
	if (ret < 0) {
		fprintf(stderr, "Cannot verify signed data: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	fprintf(stderr, "ok\n");

	/* now try to verify against a public key within the token */
	gnutls_pubkey_deinit(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_url(pubkey, url, flags);
	if (ret < 0) {
		fprintf(stderr, "Cannot find a corresponding public key object in token: %s\n",
			gnutls_strerror(ret));
		if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
			exit(0);
		exit(1);
	}

	fprintf(stderr, "Verifying against public key in the token... ");
	ret = gnutls_pubkey_verify_data2(pubkey, gnutls_pk_to_sign(pk, GNUTLS_DIG_SHA1),
		0, &data, &sig);
	if (ret < 0) {
		fprintf(stderr, "Cannot verify signed data: %s\n",
			gnutls_strerror(ret));
		exit(1);
	}

	fprintf(stderr, "ok\n");

	gnutls_free(sig.data);
	gnutls_pubkey_deinit(pubkey);
	gnutls_privkey_deinit(privkey);
	UNFIX;
}
Ejemplo n.º 29
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.º 30
0
void    Plugin::_loadCertificate()
{
    QFile            file(this->crtFile);
    gnutls_datum_t   datum;
    size_t           size = 2048;
    QByteArray       data;
    gnutls_privkey_t privkey;
    gnutls_pubkey_t  pubkey;
    gnutls_pubkey_t  pubkeyCrt;
    int              error;
    QMap<char *, QByteArray> oid;
    gnutls_digest_algorithm_t digest;

    if (!file.open(QIODevice::ReadWrite))
        throw Properties("error", "Unable to open the certificate file").add("file", this->crtFile);
    ASSERT_INIT(gnutls_x509_crt_init(&this->crt), "crt");
    ASSERT(gnutls_privkey_init(&privkey));
    ASSERT(gnutls_privkey_import_x509(privkey, this->key, 0));
    ASSERT(gnutls_pubkey_init(&pubkey));
    ASSERT(gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0));
    // Verifies that the certificate is valid
    if (file.size() > 0)
    {
        ASSERT(gnutls_pubkey_init(&pubkeyCrt));
        data = file.readAll();
        datum.size = data.size();
        datum.data = (unsigned char *)data.data();
        if (gnutls_x509_crt_import(this->crt, &datum, GNUTLS_X509_FMT_PEM) != GNUTLS_E_SUCCESS)
            file.resize(0);
        else if (gnutls_x509_crt_get_expiration_time(this->crt) < ::time(NULL) + CRT_EXPIRATION_REGEN)
            file.resize(0);
        else if (gnutls_pubkey_import_x509(pubkeyCrt, this->crt, 0) != GNUTLS_E_SUCCESS)
            file.resize(0);
        // Ensures that the public keys of the certificate and the private key match
        size_t size1 = size, size2 = size;
        QByteArray pub1((int)size1, 0), pub2((int)size2, 0);
        if (gnutls_pubkey_export(pubkey, GNUTLS_X509_FMT_PEM, pub1.data(), &size1) != GNUTLS_E_SUCCESS
            || gnutls_pubkey_export(pubkeyCrt, GNUTLS_X509_FMT_PEM, pub2.data(), &size2) != GNUTLS_E_SUCCESS
            || size1 != size2 || pub1 != pub2)
            file.resize(0);
        gnutls_pubkey_deinit(pubkeyCrt);
    }
    // Generates a new certificate
    if (file.size() == 0)
    {
        gnutls_x509_crt_deinit(this->crt);
        this->init.removeAll("crt");
        ASSERT_INIT(gnutls_x509_crt_init(&this->crt), "crt");
        LOG_INFO("Generating a new certificate", "Plugin", "_generateCertificate");
        oid.insert((char *)GNUTLS_OID_X520_COMMON_NAME, "LightBird");
        oid.insert((char *)GNUTLS_OID_X520_ORGANIZATION_NAME, "LightBird");
        QMapIterator<char *, QByteArray> it(oid);
        while (it.hasNext())
            ASSERT(gnutls_x509_crt_set_dn_by_oid(this->crt, it.key(), 0, it.value().data(), it.next().value().size()));
        ASSERT(gnutls_x509_crt_set_pubkey(this->crt, pubkey));
        data = this->_generateSerial();
        ASSERT(gnutls_x509_crt_set_serial(this->crt, data.data(), data.size()));
        ASSERT(gnutls_x509_crt_set_activation_time(this->crt, ::time(NULL)));
        ASSERT(gnutls_x509_crt_set_expiration_time(this->crt, ::time(NULL) + CRT_EXPIRATION));
        ASSERT(gnutls_x509_crt_set_basic_constraints(this->crt, 0, -1));
        ASSERT(gnutls_x509_crt_set_key_purpose_oid(this->crt, GNUTLS_KP_TLS_WWW_SERVER, 0));
        ASSERT(gnutls_x509_crt_set_key_usage(this->crt, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT));
        data.resize((int)size);
        ASSERT(gnutls_x509_crt_get_key_id(this->crt, 0, (unsigned char *)data.data(), &size));
        ASSERT(gnutls_x509_crt_set_subject_key_id(this->crt, (unsigned char *)data.data(), size));
        ASSERT(gnutls_x509_crt_set_version(this->crt, 3));
        ASSERT(gnutls_pubkey_get_preferred_hash_algorithm(pubkey, &digest, NULL));
        ASSERT(gnutls_x509_crt_privkey_sign(this->crt, this->crt, privkey, digest, 0));
        size = data.size();
        ASSERT(gnutls_x509_crt_export(this->crt, GNUTLS_X509_FMT_PEM, data.data(), &size));
        data.resize((int)size);
        file.write(data);
    }
    gnutls_pubkey_deinit(pubkey);
    gnutls_privkey_deinit(privkey);
}