From 6c32b2679af7d9cb9255d9423bed9bf242e1fa8e Mon Sep 17 00:00:00 2001 From: Glenn Rempe Date: Mon, 12 Aug 2019 17:02:09 -0700 Subject: [PATCH] Fix issue with string keys for the proof. Fixes https://github.com/grempe/sirp/issues/7 --- lib/sirp/verifier.rb | 11 ++++++++++- spec/verifier_spec.rb | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/lib/sirp/verifier.rb b/lib/sirp/verifier.rb index 5792acc..eaeec0e 100644 --- a/lib/sirp/verifier.rb +++ b/lib/sirp/verifier.rb @@ -66,6 +66,14 @@ def get_challenge_and_proof(username, xverifier, xsalt, xaa) } end + def symbolize_keys_deep!(h) + h.keys.each do |k| + ks = k.respond_to?(:to_sym) ? k.to_sym : k + h[ks] = h.delete k # Preserve order even when k == ks + symbolize_keys_deep! h[ks] if h[ks].kind_of? Hash + end + end + # # Phase 2 : Step 1 : See Client#start_authentication # @@ -86,7 +94,7 @@ def get_challenge_and_proof(username, xverifier, xsalt, xaa) # @return [String, false] the H_AMK value in hex for the client, or false if verification failed def verify_session(proof, client_M) raise ArgumentError, 'proof must be a hash' unless proof.is_a?(Hash) - proof = Hash[proof.map {|k,v| [k.to_sym, v]}] + symbolize_keys_deep!(proof) raise ArgumentError, 'proof must have required hash keys' unless proof.keys == [:A, :B, :b, :I, :s, :v] raise ArgumentError, 'client_M must be a string' unless client_M.is_a?(String) raise ArgumentError, 'client_M must be a hex string' unless client_M =~ /^[a-fA-F0-9]+$/ @@ -120,3 +128,4 @@ def verify_session(proof, client_M) end end end + diff --git a/spec/verifier_spec.rb b/spec/verifier_spec.rb index 6957ae8..3f7eff5 100644 --- a/spec/verifier_spec.rb +++ b/spec/verifier_spec.rb @@ -103,6 +103,20 @@ expect(verifier.K).to eq '404bf923682abeeb3c8c9164d2cdb6b6ba21b64d' end + it 'should calculate server session and key with string keys for the proof' do + # A is received in phase 1 + aa = '165366e23a10006a62fb8a0793757a299e2985103ad2e8cdee0cc37cac109f3f338ee12e2440eda97bfa7c75697709a5dc66faadca7806d43ea5839757d134ae7b28dd3333049198cc8d328998b8cd8352ff4e64b3bd5f08e40148d69b0843bce18cbbb30c7e4760296da5c92717fcac8bddc7875f55302e55d90a34226868d2' + # B and b are saved from phase 1 + bb = '56777d24af1121bd6af6aeb84238ff8d250122fe75ed251db0f47c289642ae7adb9ef319ce3ab23b6ecc97e5904749fc42f12bb016ecf39691db541f066667b8399bfa685c82b03ad8f92f75975ed086dbe0d470d4dd907ce11b19ee41b74aee72bd8445cde6b58c01f678e39ed9cd6b93c79382637df90777a96c10a768c510' + # v is from db + v = '321307d87ca3462f5b0cb5df295bea04498563794e5401899b2f32dd5cab5b7de9da78e7d62ea235e6d7f43a4ea09fea7c0dafdee6e79a1d12e2e374048deeaf5ba7c68e2ad952a3f5dc084400a7f1599a31d6d9d50269a9208db88f84090e8aa3c7b019f39529dcc19baa985a8d7ffb2d7628071d2313c9eaabc504d3333688' + _proof = { "A" => aa, "B" => bb, "b" => @b, "I" => @username, "s" => @salt, "v" => v } + verifier = SIRP::Verifier.new(1024) + verifier.verify_session(_proof, 'abc123') + expect(verifier.S).to eq '7f44592cc616e0d761b2d3309d513b69b386c35f3ed9b11e6d43f15799b673d6dcfa4117b4456af978458d62ad61e1a37be625f46d2a5bd9a50aae359e4541275f0f4bd4b4caed9d2da224b491231f905d47abd9953179aa608854b84a0e0c6195e73715932b41ab8d0d4a2977e7642163be6802c5907fb9e233b8c96e457314' + expect(verifier.K).to eq '404bf923682abeeb3c8c9164d2cdb6b6ba21b64d' + end + it 'should calculate verifier M and server proof' do # A is received in phase 1 aa = '165366e23a10006a62fb8a0793757a299e2985103ad2e8cdee0cc37cac109f3f338ee12e2440eda97bfa7c75697709a5dc66faadca7806d43ea5839757d134ae7b28dd3333049198cc8d328998b8cd8352ff4e64b3bd5f08e40148d69b0843bce18cbbb30c7e4760296da5c92717fcac8bddc7875f55302e55d90a34226868d2'