Esempio n. 1
0
/**
 * gnutls_verify_stored_pubkey:
 * @db_name: A file specifying the stored keys (use NULL for the default)
 * @tdb: A storage structure or NULL to use the default
 * @host: The peer's name
 * @service: non-NULL if this key is specific to a service (e.g. http)
 * @cert_type: The type of the certificate
 * @cert: The raw (der) data of the certificate
 * @flags: should be 0.
 *
 * This function will try to verify a raw public-key or a public-key provided via
 * a raw (DER-encoded) certificate using a list of stored public keys.
 * The @service field if non-NULL should be a port number.
 *
 * The @db_name variable if non-null specifies a custom backend for
 * the retrieval of entries. If it is NULL then the
 * default file backend will be used. In POSIX-like systems the
 * file backend uses the $HOME/.gnutls/known_hosts file.
 *
 * Note that if the custom storage backend is provided the
 * retrieval function should return %GNUTLS_E_CERTIFICATE_KEY_MISMATCH
 * if the host/service pair is found but key doesn't match,
 * %GNUTLS_E_NO_CERTIFICATE_FOUND if no such host/service with
 * the given key is found, and 0 if it was found. The storage
 * function should return 0 on success.
 *
 * As of GnuTLS 3.6.6 this function also verifies raw public keys.
 *
 * Returns: If no associated public key is found
 * then %GNUTLS_E_NO_CERTIFICATE_FOUND will be returned. If a key
 * is found but does not match %GNUTLS_E_CERTIFICATE_KEY_MISMATCH
 * is returned. On success, %GNUTLS_E_SUCCESS (0) is returned,
 * or a negative error value on other errors.
 *
 * Since: 3.0.13
 **/
int
gnutls_verify_stored_pubkey(const char *db_name,
			    gnutls_tdb_t tdb,
			    const char *host,
			    const char *service,
			    gnutls_certificate_type_t cert_type,
			    const gnutls_datum_t * cert,
			    unsigned int flags)
{
	gnutls_datum_t pubkey = { NULL, 0 }; // Holds the pubkey in subjectPublicKeyInfo format (DER encoded)
	int ret;
	char local_file[MAX_FILENAME];
	bool need_free;


	if (db_name == NULL && tdb == NULL) {
		ret = find_config_file(local_file, sizeof(local_file));
		if (ret < 0)
			return gnutls_assert_val(ret);
		db_name = local_file;
	}

	if (tdb == NULL)
		tdb = &default_tdb;

	/* Import the public key depending on the provided certificate type */
	switch (cert_type) {
		case GNUTLS_CRT_X509:
			/* Extract the pubkey from the cert. This function does a malloc
			 * deep down the call chain. We are responsible for freeing. */
			ret = _gnutls_x509_raw_crt_to_raw_pubkey(cert, &pubkey);

			if (ret < 0) {
				_gnutls_free_datum(&pubkey);
				return gnutls_assert_val(ret);
			}

			need_free = true;
			break;
		case GNUTLS_CRT_RAWPK:
			pubkey.data = cert->data;
			pubkey.size = cert->size;
			need_free = false;
			break;
		default:
			return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
	}

	// Verify our pubkey against the database
	ret = tdb->verify(db_name, host, service, &pubkey);
	if (ret < 0 && ret != GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
		ret = gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);

	if (need_free) {
		_gnutls_free_datum(&pubkey);
	}

	return ret;
}
/**
 * gnutls_store_pubkey:
 * @db_name: A file specifying the stored keys (use NULL for the default)
 * @tdb: A storage structure or NULL to use the default
 * @host: The peer's name
 * @service: non-NULL if this key is specific to a service (e.g. http)
 * @cert_type: The type of the certificate
 * @cert: The data of the certificate
 * @expiration: The expiration time (use 0 to disable expiration)
 * @flags: should be 0.
 *
 * This function will store the provided certificate to 
 * the list of stored public keys. The key will be considered valid until 
 * the provided expiration time.
 *
 * The @store variable if non-null specifies a custom backend for
 * the storage of entries. If it is NULL then the
 * default file backend will be used.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.0
 **/
int
gnutls_store_pubkey(const char* db_name,
                    gnutls_tdb_t tdb,
                    const char* host,
                    const char* service,
                    gnutls_certificate_type_t cert_type,
                    const gnutls_datum_t * cert,
                    time_t expiration,
                    unsigned int flags)
{
FILE* fd = NULL;
gnutls_datum_t pubkey = { NULL, 0 };
int ret;
char local_file[MAX_FILENAME];

  if (cert_type != GNUTLS_CRT_X509 && cert_type != GNUTLS_CRT_OPENPGP)
    return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
  
  if (db_name == NULL && tdb == NULL)
    {
      ret = _gnutls_find_config_path(local_file, sizeof(local_file));
      if (ret < 0)
        return gnutls_assert_val(ret);
      
      _gnutls_debug_log("Configuration path: %s\n", local_file);
      mkdir(local_file, 0700);
      
      ret = find_config_file(local_file, sizeof(local_file));
      if (ret < 0)
        return gnutls_assert_val(ret);
      db_name = local_file;
    }

  if (tdb == NULL)
    tdb = &default_tdb;
    
  if (cert_type == GNUTLS_CRT_X509)
    ret = x509_crt_to_raw_pubkey(cert, &pubkey);
  else
    ret = pgp_crt_to_raw_pubkey(cert, &pubkey);
  if (ret < 0)
    {
      gnutls_assert();
      goto cleanup;
    }

  _gnutls_debug_log("Configuration file: %s\n", db_name);

  tdb->store(db_name, host, service, expiration, &pubkey);

  ret = 0;

cleanup:
  gnutls_free(pubkey.data);
  if (fd != NULL) fclose(fd);
  
  return ret;
}
Esempio n. 3
0
/**
 * gnutls_store_commitment:
 * @db_name: A file specifying the stored keys (use NULL for the default)
 * @tdb: A storage structure or NULL to use the default
 * @host: The peer's name
 * @service: non-NULL if this key is specific to a service (e.g. http)
 * @hash_algo: The hash algorithm type
 * @hash: The raw hash
 * @expiration: The expiration time (use 0 to disable expiration)
 * @flags: should be 0.
 *
 * This function will store the provided hash commitment to 
 * the list of stored public keys. The key with the given
 * hash will be considered valid until the provided expiration time.
 *
 * The @store variable if non-null specifies a custom backend for
 * the storage of entries. If it is NULL then the
 * default file backend will be used.
 *
 * Note that this function is not thread safe with the default backend.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.0
 **/
int
gnutls_store_commitment(const char *db_name,
			gnutls_tdb_t tdb,
			const char *host,
			const char *service,
			gnutls_digest_algorithm_t hash_algo,
			const gnutls_datum_t * hash,
			time_t expiration, unsigned int flags)
{
	FILE *fd = NULL;
	int ret;
	char local_file[MAX_FILENAME];
	const mac_entry_st *me = hash_to_entry(hash_algo);

	if (me == NULL || _gnutls_digest_is_secure(me) == 0)
		return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER);

	if (_gnutls_hash_get_algo_len(me) != hash->size)
		return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);

	if (db_name == NULL && tdb == NULL) {
		ret =
		    _gnutls_find_config_path(local_file,
					     sizeof(local_file));
		if (ret < 0)
			return gnutls_assert_val(ret);

		_gnutls_debug_log("Configuration path: %s\n", local_file);
		mkdir(local_file, 0700);

		ret = find_config_file(local_file, sizeof(local_file));
		if (ret < 0)
			return gnutls_assert_val(ret);
		db_name = local_file;
	}

	if (tdb == NULL)
		tdb = &default_tdb;

	_gnutls_debug_log("Configuration file: %s\n", db_name);

	tdb->cstore(db_name, host, service, expiration, 
		(gnutls_digest_algorithm_t)me->id, hash);

	ret = 0;

	if (fd != NULL)
		fclose(fd);

	return ret;
}
Esempio n. 4
0
/**
 * gnutls_verify_stored_pubkey:
 * @db_name: A file specifying the stored keys (use NULL for the default)
 * @tdb: A storage structure or NULL to use the default
 * @host: The peer's name
 * @service: non-NULL if this key is specific to a service (e.g. http)
 * @cert_type: The type of the certificate
 * @cert: The raw (der) data of the certificate
 * @flags: should be 0.
 *
 * This function will try to verify the provided (raw or DER-encoded) certificate 
 * using a list of stored public keys.  The @service field if non-NULL should
 * be a port number.
 *
 * The @retrieve variable if non-null specifies a custom backend for
 * the retrieval of entries. If it is NULL then the
 * default file backend will be used. In POSIX-like systems the
 * file backend uses the $HOME/.gnutls/known_hosts file.
 *
 * Note that if the custom storage backend is provided the
 * retrieval function should return %GNUTLS_E_CERTIFICATE_KEY_MISMATCH
 * if the host/service pair is found but key doesn't match,
 * %GNUTLS_E_NO_CERTIFICATE_FOUND if no such host/service with
 * the given key is found, and 0 if it was found. The storage
 * function should return 0 on success.
 *
 * Returns: If no associated public key is found
 * then %GNUTLS_E_NO_CERTIFICATE_FOUND will be returned. If a key
 * is found but does not match %GNUTLS_E_CERTIFICATE_KEY_MISMATCH
 * is returned. On success, %GNUTLS_E_SUCCESS (0) is returned, 
 * or a negative error value on other errors.
 *
 * Since: 3.0.13
 **/
int
gnutls_verify_stored_pubkey(const char *db_name,
			    gnutls_tdb_t tdb,
			    const char *host,
			    const char *service,
			    gnutls_certificate_type_t cert_type,
			    const gnutls_datum_t * cert,
			    unsigned int flags)
{
	gnutls_datum_t pubkey = { NULL, 0 };
	int ret;
	char local_file[MAX_FILENAME];

	if (cert_type != GNUTLS_CRT_X509
	    && cert_type != GNUTLS_CRT_OPENPGP)
		return
		    gnutls_assert_val
		    (GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);

	if (db_name == NULL && tdb == NULL) {
		ret = find_config_file(local_file, sizeof(local_file));
		if (ret < 0)
			return gnutls_assert_val(ret);
		db_name = local_file;
	}

	if (tdb == NULL)
		tdb = &default_tdb;

	if (cert_type == GNUTLS_CRT_X509)
		ret = x509_crt_to_raw_pubkey(cert, &pubkey);
	else
		ret = pgp_crt_to_raw_pubkey(cert, &pubkey);

	if (ret < 0) {
		gnutls_assert();
		goto cleanup;
	}

	ret = tdb->verify(db_name, host, service, &pubkey);
	if (ret < 0 && ret != GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
		ret = gnutls_assert_val(GNUTLS_E_NO_CERTIFICATE_FOUND);

      cleanup:
	gnutls_free(pubkey.data);
	return ret;
}
Esempio n. 5
0
/**
 * gnutls_store_pubkey:
 * @db_name: A file specifying the stored keys (use NULL for the default)
 * @tdb: A storage structure or NULL to use the default
 * @host: The peer's name
 * @service: non-NULL if this key is specific to a service (e.g. http)
 * @cert_type: The type of the certificate
 * @cert: The data of the certificate
 * @expiration: The expiration time (use 0 to disable expiration)
 * @flags: should be 0.
 *
 * This function will store a raw public-key or a public-key provided via
 * a raw (DER-encoded) certificate to the list of stored public keys. The key
 * will be considered valid until the provided expiration time.
 *
 * The @tdb variable if non-null specifies a custom backend for
 * the storage of entries. If it is NULL then the
 * default file backend will be used.
 *
 * Unless an alternative @tdb is provided, the storage format is a textual format
 * consisting of a line for each host with fields separated by '|'. The contents of
 * the fields are a format-identifier which is set to 'g0', the hostname that the
 * rest of the data applies to, the numeric port or host name, the expiration
 * time in seconds since the epoch (0 for no expiration), and a base64
 * encoding of the raw (DER) public key information (SPKI) of the peer.
 *
 * As of GnuTLS 3.6.6 this function also accepts raw public keys.
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 *
 * Since: 3.0.13
 **/
int
gnutls_store_pubkey(const char *db_name,
		    gnutls_tdb_t tdb,
		    const char *host,
		    const char *service,
		    gnutls_certificate_type_t cert_type,
		    const gnutls_datum_t * cert,
		    time_t expiration, unsigned int flags)
{
	gnutls_datum_t pubkey = { NULL, 0 }; // Holds the pubkey in subjectPublicKeyInfo format (DER encoded)
	int ret;
	char local_file[MAX_FILENAME];
	bool need_free;


	if (db_name == NULL && tdb == NULL) {
		ret =
		    _gnutls_find_config_path(local_file,
					     sizeof(local_file));
		if (ret < 0)
			return gnutls_assert_val(ret);

		_gnutls_debug_log("Configuration path: %s\n", local_file);
		mkdir(local_file, 0700);

		ret = find_config_file(local_file, sizeof(local_file));
		if (ret < 0)
			return gnutls_assert_val(ret);
		db_name = local_file;
	}

	if (tdb == NULL)
		tdb = &default_tdb;

	/* Import the public key depending on the provided certificate type */
	switch (cert_type) {
		case GNUTLS_CRT_X509:
			/* Extract the pubkey from the cert. This function does a malloc
			 * deep down the call chain. We are responsible for freeing. */
			ret = _gnutls_x509_raw_crt_to_raw_pubkey(cert, &pubkey);

			if (ret < 0) {
				_gnutls_free_datum(&pubkey);
				return gnutls_assert_val(ret);
			}

			need_free = true;
			break;
		case GNUTLS_CRT_RAWPK:
			pubkey.data = cert->data;
			pubkey.size = cert->size;
			need_free = false;
			break;
		default:
			return gnutls_assert_val(GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE);
	}

	_gnutls_debug_log("Configuration file: %s\n", db_name);

	tdb->store(db_name, host, service, expiration, &pubkey);

	if (need_free) {
		_gnutls_free_datum(&pubkey);
	}

	return GNUTLS_E_SUCCESS;
}