You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

84 lines
2.1 KiB

# frozen_string_literal: true
# gem install base32
require 'openssl'
require 'base32'
require 'pp'
require 'resolv'
def pad(base32str)
base32str +
case base32str.length % 8
when 2 then '======'
when 4 then '===='
when 5 then '==='
when 7 then '='
else ''
end
end
def rm_pad(base32text)
base32text.gsub '=', ''
end
def download(pub_key_link)
Resolv::DNS.open do |dns|
resource = dns.getresource(pub_key_link, Resolv::DNS::Resource::IN::TXT)
key = resource.data.split('\n').join("\n")
unless key.include? '-----BEGIN PUBLIC KEY-----'
key = "-----BEGIN PUBLIC KEY-----\n#{key}\n-----END PUBLIC KEY-----\n"
end
return key
end
nil
end
def parse_and_verify_qr(qr)
(schema, qrtype, version, signature_b32, pub_key_link, payload) = qr.split(/:/)
puts "Parsed QR\t #{schema} #{qrtype} #{version} #{signature_b32} #{pub_key_link} #{payload}"
sha_payload = Digest::SHA256.digest(payload)
signature = Base32.decode(pad(signature_b32))
puts "Payload Bytes\t #{sha_payload.bytes}"
puts "Signature DER\t #{signature.bytes}"
vk = OpenSSL::PKey::EC.new(download(pub_key_link))
verified = vk.dsa_verify_asn1(sha_payload, signature)
puts "\nVerify Payload\t #{verified}"
verified
end
def sign_and_format_qr(sk, schema, qrtype, version, pub_key_link, payload)
sha_payload = Digest::SHA256.digest(payload)
sig = sk.dsa_sign_asn1(sha_payload)
formatted_sig = rm_pad(Base32.encode(sig))
[schema, qrtype, version, formatted_sig, pub_key_link, payload].join ':'
end
uri = 'CRED:STATUS:2:GBCAEIAHV2J6PWDSYVLI67RN55WVHIMUTKLFF5GZ4NPHPZ7ZSIJE4MP5M4BCAU6QVDHUP4RQCPXW6XJDAM54VMZ7XURUN34WFT2RWL5ETTZDNHUF:KEYS.PATHCHECK.ORG:1/BUQHHANUB4Z5KHBZTYCWMNI4RQ6CP5WFVVQCUXYHCQVY5WLDDFPA/'
puts ''
puts 'Loading hardcoded QR'
puts ''
parse_and_verify_qr(uri)
puts ''
puts 'Resigning same payload'
puts ''
(schema, qrtype, version, _, pub_key_link, payload) = uri.split(/:/)
sk = OpenSSL::PKey::EC.new(File.read('keys/ecdsa_private_key'))
new_qr = sign_and_format_qr(sk, schema, qrtype, version, pub_key_link, payload)
puts "New QR Signed\t #{new_qr}"
puts ''
parse_and_verify_qr(new_qr)