function verify_taxonomy( $source, $public_key_pem )
	{
		$json = $source;
		$filename = $this->get_source_filename( $source );

		if ( $filename )
		{
			// Get the json from $source. It will throw an exception if there's a problem.
			$json = $this->get_json( $filename );
		}

		// Recreate the object hierarchy. It will throw an exception if there's a problem.
		$taxonomy = $this->get_taxonomy( $json );

		// Is there a signature?  If so remove it and re-generate the string
		if ( ! isset( $taxonomy['signature_block'] ) )
		{
			$message = "The taxonomy does not contain a signature block";
			throw new \Exception( $message );
		}

		// There is so grab it and delete it from the $taxonomy
		$signature_block = $taxonomy['signature_block'];
		unset( $taxonomy['signature_block'] );

		// Check the signature block
		if ( ! isset( $signature_block['signature'] ) || ! isset( $signature_block['algorithm'] ) )
		{
			$message = "The signature block is not valid";
			throw new \Exception( $message );
		}

		// The existing signature is base64 encoded
		$signature = base64_decode( $signature_block['signature'] );

		// Time to re-encode so the signature can be tested.
		$json = json_encode( $taxonomy );

		// The function openssl_pkey_get_public always works with URLs so if necessary convert
		// the $public_key_pem variable to a URL using a 'file' scheme.  If there is no scheme
		// or the scheme is a letter A-Z then a local path is being used and needs converting.
		$parts = parse_url( $public_key_pem );
		if ( ( ! isset( $parts['scheme'] ) || preg_match( "/^[A-Z]$/", $parts['scheme'] ) ) && ! isset( $parts['host'] ) )
		{
			$public_key_pem = "file://";
			if ( isset( $parts['scheme'] ) ) $public_key_pem .= $parts['scheme'] . ":";
			$public_key_pem .= $parts['path'];
		}

		// Check its possible to create a public key id
		$public_key = openssl_pkey_get_public( $public_key_pem );
		if ( $public_key === false )
		{
			$message = "Unable to create a key id from the public key resource $pem\n" . openssl_error_string();
			throw new \Exception( $message );
		}

		$result = openssl_verify( $json, $signature, $public_key, $signature_block['algorithm'] );
		if ( $result == -1 )
		{
			$message = "Error verifying: " . openssl_error_string();
		}

		openssl_free_key( $public_key );

		return $result;
	}