From 1acc306ff3dd749def6a2727bdca6dc79f50d728 Mon Sep 17 00:00:00 2001 From: Luca Belluccini Date: Fri, 12 Oct 2018 00:28:53 +0200 Subject: [PATCH] Allow usage of base64url encoding / Issue #34 --- docs/index.asciidoc | 10 +++++++++ lib/logstash/filters/fingerprint.rb | 17 ++++++++++++-- spec/filters/fingerprint_spec.rb | 35 +++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/docs/index.asciidoc b/docs/index.asciidoc index 3f9380a..706a948 100644 --- a/docs/index.asciidoc +++ b/docs/index.asciidoc @@ -41,6 +41,7 @@ This plugin supports the following configuration options plus the <> |<>|No +| <> |<>|No | <> |<>|No | <> |<>|No | <> |<>|No @@ -63,6 +64,15 @@ filter plugins. When set to `true`, the `SHA1`, `SHA256`, `SHA384`, `SHA512` and `MD5` fingerprint methods will produce base64 encoded rather than hex encoded strings. +[id="plugins-{type}s-{plugin}-base64url"] +===== `base64url` + + * Value type is <> + * Default value is `false` + +Requires `base64encode` to be set to `true`. +When set to `true`, the base64url variant will be used, as described in [RFC4648 section 5](https://tools.ietf.org/html/rfc4648#section-5). + [id="plugins-{type}s-{plugin}-concatenate_sources"] ===== `concatenate_sources` diff --git a/lib/logstash/filters/fingerprint.rb b/lib/logstash/filters/fingerprint.rb index 6df1361..a9740cf 100644 --- a/lib/logstash/filters/fingerprint.rb +++ b/lib/logstash/filters/fingerprint.rb @@ -41,6 +41,10 @@ class LogStash::Filters::Fingerprint < LogStash::Filters::Base # base64 encoded rather than hex encoded strings. config :base64encode, :validate => :boolean, :default => false + # When set to `true`, the base64url encoder https://tools.ietf.org/html/rfc4648 is used. + # Requires `base64encode` to be enabled. + config :base64url, :validate => :boolean, :default => false + # The fingerprint method to use. # # If set to `SHA1`, `SHA256`, `SHA384`, `SHA512`, or `MD5` and a key is set, @@ -156,14 +160,23 @@ def fingerprint_openssl(data) # in JRuby 1.7.11 outputs as ASCII-8BIT if @key.nil? if @base64encode - @digest.base64digest(data.to_s).force_encoding(Encoding::UTF_8) + if @base64url + # Borrowed by Base64 implementation + @digest.base64digest(data.to_s).tr("+/", "-_").force_encoding(Encoding::UTF_8) + else + @digest.base64digest(data.to_s).force_encoding(Encoding::UTF_8) + end else @digest.hexdigest(data.to_s).force_encoding(Encoding::UTF_8) end else if @base64encode hash = OpenSSL::HMAC.digest(@digest, @key, data.to_s) - Base64.strict_encode64(hash).force_encoding(Encoding::UTF_8) + if @base64url + Base64.urlsafe_encode64(hash).force_encoding(Encoding::UTF_8) + else + Base64.strict_encode64(hash).force_encoding(Encoding::UTF_8) + end else OpenSSL::HMAC.hexdigest(@digest, @key, data.to_s).force_encoding(Encoding::UTF_8) end diff --git a/spec/filters/fingerprint_spec.rb b/spec/filters/fingerprint_spec.rb index 24ebf3d..2761af5 100644 --- a/spec/filters/fingerprint_spec.rb +++ b/spec/filters/fingerprint_spec.rb @@ -99,6 +99,23 @@ end end + describe "fingerprint string with SHA1 algorithm and base64url encoding" do + config <<-CONFIG + filter { + fingerprint { + source => ["clientip"] + method => 'SHA256' + base64encode => true + base64url => true + } + } + CONFIG + + sample("clientip" => "123.123.123.123") do + insist { subject.get("fingerprint") } == "TavKshB2bjXwPncSDmmG1ubUdSsqn_IpgLklPQJggNg=" + end + end + describe "fingerprint string with SHA1 HMAC algorithm and base64 encoding" do config <<-CONFIG filter { @@ -116,6 +133,24 @@ end end + describe "fingerprint string with SHA1 HMAC algorithm and base64url encoding" do + config <<-CONFIG + filter { + fingerprint { + source => ["clientip"] + key => "longencryptionkey" + method => 'SHA1' + base64encode => true + base64url => true + } + } + CONFIG + + sample("clientip" => "123.123.123.123") do + insist { subject.get("fingerprint") } == "_cYKzEdz3FrFaf-3j8uTyWMHl_Q=" + end + end + describe "fingerprint string with SHA256 algorithm" do config <<-CONFIG filter {