diff --git a/Gemfile b/Gemfile index 606eb0c..7f90b10 100644 --- a/Gemfile +++ b/Gemfile @@ -11,6 +11,8 @@ gem "rake", "~> 13.0" gem "rspec", "~> 3.0" +gem "securerandom" + gem "standard", "~> 1.3" gem "simplecov", require: false, group: :test diff --git a/Gemfile.lock b/Gemfile.lock index 77e2030..34965c1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,7 +2,6 @@ PATH remote: . specs: linzer (0.6.1) - ed25519 (~> 1.3, >= 1.3.0) openssl (~> 3.0, >= 3.0.0) rack (>= 2.2, < 4.0) starry (~> 0.2) @@ -15,7 +14,6 @@ GEM base64 (0.2.0) diff-lcs (1.5.1) docile (1.4.0) - ed25519 (1.3.0) json (2.7.2) language_server-protocol (3.17.0.3) lint_roller (1.1.0) @@ -60,6 +58,7 @@ GEM rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.30.0, < 2.0) ruby-progressbar (1.13.0) + securerandom (0.4.0) simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) @@ -92,6 +91,7 @@ DEPENDENCIES linzer! rake (~> 13.0) rspec (~> 3.0) + securerandom simplecov standard (~> 1.3) diff --git a/README.md b/README.md index e21fc3c..59bab7f 100644 --- a/README.md +++ b/README.md @@ -97,13 +97,10 @@ response = http.post("/some_uri", "data", headers.merge(signature.to_h)) ### To verify a valid signature: ```ruby -test_ed25519_key_pub = Base64.strict_encode64(key.material.verify_key.to_bytes) -# => "EUra7KsJ8B/lSZJVhDaopMycmZ6T7KtJqKVNJTHKIw0=" +test_ed25519_key_pub = key.material.public_to_pem +# => "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAK1ZrC4JqC356pRsUiLVJdFZ3dAjo909VfWs1li33MCQ=\n-----END PUBLIC KEY-----\n" -raw_pubkey = Base64.strict_decode64(test_ed25519_key_pub) -# => "\xB1rM\xFFR\x1F\xDDw\x00\x89\..." - -pubkey = Linzer.new_ed25519_public_key(raw_pubkey, "some-key-ed25519") +pubkey = Linzer.new_ed25519_public_key(test_ed25519_key_pub, "some-key-ed25519") # => # 3.0", ">= 3.0.0" - spec.add_runtime_dependency "ed25519", "~> 1.3", ">= 1.3.0" spec.add_runtime_dependency "starry", "~> 0.2" spec.add_runtime_dependency "rack", ">= 2.2", "< 4.0" spec.add_runtime_dependency "uri", "~> 1.0", ">= 1.0.2" diff --git a/spec/ed25519_spec.rb b/spec/ed25519_spec.rb index 371edae..00795ed 100644 --- a/spec/ed25519_spec.rb +++ b/spec/ed25519_spec.rb @@ -1,26 +1,5 @@ # frozen_string_literal: true -def decode_asn1_blob_from_rfc_examples(key) - Linzer::RFC9421::Examples - .public_send(key) - .lines - .reject { |l| l.start_with?("-----") } - .shift - .chomp - .yield_self { |str| Base64.strict_decode64(str) } - .yield_self { |str| OpenSSL::ASN1.decode(str) } -end - -def load_ed25519_pubkey_from_rfc_examples - asn_seq = decode_asn1_blob_from_rfc_examples(:test_key_ed25519_pub) - asn_seq.value[1].value -end - -def load_ed25519_private_key_from_rfc_examples - asn_seq = decode_asn1_blob_from_rfc_examples(:test_key_ed25519) - asn_seq.value[2].value[2..] -end - RSpec.describe Linzer::Signer do context "with Ed25519" do let(:request) do @@ -29,31 +8,8 @@ def load_ed25519_private_key_from_rfc_examples Linzer.new_request(:post, path, {}, request_data[:headers]) end - # B.1.4. Example Ed25519 Test Key - # - # -----BEGIN PUBLIC KEY----- - # MCowBQYDK2VwAyEAJrQLj5P/89iXES9+vFgrIy29clF9CC/oPPsw3c5D0bs= - # -----END PUBLIC KEY----- - # - # -----BEGIN PRIVATE KEY----- - # MC4CAQAwBQYDK2VwBCIEIJ+DYvh6SEqVTm50DFtMDoQikTmiCqirVv9mWG9qfSnF - # -----END PRIVATE KEY----- - # - # ed25519 ruby library works with raw byte strings, so you have - # to extract them from the PKCS #8 encoded file PEM format. - # - # XXX: should I write a helper method for that? - # XXX: if such a helper is needed, the helper method above - # XXX: decode_asn1_blob_from_rfc_examples can be used as starting point. - # - # $ openssl asn1parse -in private.pem -offset 14 - # 0:d=0 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:9F8362F87A484A954E6E740C5B4C0E84229139A20AA8AB56FF66586F6A7D29C5 - # - # %w[9F8362F87A484A954E6E740C5B4C0E84229139A20AA8AB56FF66586F6A7D29C5].pack("H*") - # => "\x9F\x83b\xF8zHJ\x95Nnt\f[L\x0E\x84\"\x919\xA2\n\xA8\xABV\xFFfXoj})\xC5" - # let(:test_key_ed25519) do - load_ed25519_private_key_from_rfc_examples + Linzer::RFC9421::Examples.test_key_ed25519 end let(:key_id) { "test-key-ed25519" } @@ -77,8 +33,8 @@ def load_ed25519_private_key_from_rfc_examples end it "derives public key from private key" do - pubkey = key.material.verify_key.to_bytes - expect(pubkey).to eq(load_ed25519_pubkey_from_rfc_examples) + pubkey = key.material.public_to_pem + expect(pubkey).to eq(Linzer::RFC9421::Examples.test_key_ed25519_pub) end end end @@ -91,22 +47,7 @@ def load_ed25519_private_key_from_rfc_examples Linzer.new_request(:post, path, {}, request_data[:headers]) end - # $ openssl pkey -pubin -inform pem -in public.pem -noout -text - # ED25519 Public-Key: - # pub: - # 26:b4:0b:8f:93:ff:f3:d8:97:11:2f:7e:bc:58:2b: - # 23:2d:bd:72:51:7d:08:2f:e8:3c:fb:30:dd:ce:43: - # d1:bb - # - # %w[26B40B8F93FFF3D897112F7EBC582B232DBD72517D082FE83CFB30DDCE43D1BB].pack("H*") - # => "&\xB4\v\x8F\x93\xFF\xF3\xD8\x97\x11/~\xBCX+#-\xBDrQ}\b/\xE8<\xFB0\xDD\xCEC\xD1\xBB" - # - # public key can also be derived from private key object, - # as is shown above in the examples: - # key.material.verify_key.to_bytes - # => "&\xB4\v\x8F\x93\xFF\xF3\xD8\x97\x11/~\xBCX+#-\xBDrQ}\b/\xE8<\xFB0\xDD\xCEC\xD1\xBB" - - let(:test_key_ed25519_pub) { load_ed25519_pubkey_from_rfc_examples } + let(:test_key_ed25519_pub) { Linzer::RFC9421::Examples.test_key_ed25519_pub } let(:key_id) { "test-key-ed25519" } diff --git a/spec/readme_spec.rb b/spec/readme_spec.rb index 56891a9..9f897b4 100644 --- a/spec/readme_spec.rb +++ b/spec/readme_spec.rb @@ -8,9 +8,8 @@ def build_random_signature(label) let(:key) { Linzer.generate_ed25519_key } let(:pubkey) do - exported_pubkey = Base64.strict_encode64(key.material.verify_key.to_bytes) - raw_pubkey = Base64.strict_decode64(exported_pubkey) - Linzer.new_ed25519_public_key(raw_pubkey, "some-key-ed25519") + exported_pubkey = key.material.public_to_pem + Linzer.new_ed25519_public_key(exported_pubkey, "some-key-ed25519") end describe "HTTP request examples" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 346d46f..6b97dfd 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,6 +3,8 @@ require "simplecov" SimpleCov.start +require "securerandom" + require "linzer" require_relative "rfc9421_examples"