X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=lib%2Fpaymentrequest.py;h=9d5bae9a06f37c3d7601298967a18c3bf5e03846;hb=9a3ca0dc310d58cef1428d5cfaa200c3b4fd1754;hp=0dae7f6336d9f7c07c23945ddc95daed254da7d2;hpb=4e1068b34307786642045dfa1122d8429d73202d;p=electrum-nvc.git diff --git a/lib/paymentrequest.py b/lib/paymentrequest.py index 0dae7f6..9d5bae9 100644 --- a/lib/paymentrequest.py +++ b/lib/paymentrequest.py @@ -49,22 +49,14 @@ import x509 REQUEST_HEADERS = {'Accept': 'application/bitcoin-paymentrequest', 'User-Agent': 'Electrum'} ACK_HEADERS = {'Content-Type':'application/bitcoin-payment','Accept':'application/bitcoin-paymentack','User-Agent':'Electrum'} -# status can be: -PR_UNPAID = 0 -PR_EXPIRED = 1 -PR_SENT = 2 # sent but not propagated -PR_PAID = 3 # send and propagated -PR_ERROR = 4 # could not parse - ca_list = {} -ca_path = os.path.expanduser("~/.electrum/ca/ca-bundle.crt") +ca_path = requests.certs.where() def load_certificates(): - try: ca_f = open(ca_path, 'r') except Exception: @@ -84,7 +76,7 @@ def load_certificates(): try: x.parse(c) except Exception as e: - print "cannot parse cert:", e + util.print_error("cannot parse cert:", e) ca_list[x.getFingerprint()] = x ca_f.close() util.print_error("%d certificates"%len(ca_list)) @@ -141,6 +133,8 @@ class PaymentRequest: with open(filename,'r') as f: r = f.read() + assert key == bitcoin.sha256(r)[0:16].encode('hex') + self.id = key self.parse(r) @@ -175,8 +169,11 @@ class PaymentRequest: x.slow_parse() x509_chain.append(x) if i == 0: - if not x.check_name(self.domain): - self.error = "Certificate Domain Mismatch" + try: + x.check_date() + x.check_name(self.domain) + except Exception as e: + self.error = str(e) return else: if not x.check_ca(): @@ -192,13 +189,19 @@ class PaymentRequest: prev_x = x509_chain[i-1] algo, sig, data = prev_x.extract_sig() - if algo.getComponentByName('algorithm') != x509.ALGO_RSA_SHA1: - self.error = "Algorithm not suported" - return - sig = bytearray(sig[5:]) pubkey = x.publicKey - verify = pubkey.hashAndVerify(sig, data) + if algo.getComponentByName('algorithm') == x509.ALGO_RSA_SHA1: + verify = pubkey.hashAndVerify(sig, data) + elif algo.getComponentByName('algorithm') == x509.ALGO_RSA_SHA256: + hashBytes = bytearray(hashlib.sha256(data).digest()) + prefixBytes = bytearray([0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20]) + verify = pubkey.verify(sig, prefixBytes + hashBytes) + else: + self.error = "Algorithm not supported" + util.print_error(self.error, algo.getComponentByName('algorithm')) + return + if not verify: self.error = "Certificate not Signed by Provided CA Certificate Chain" return @@ -257,15 +260,14 @@ class PaymentRequest: self.payment_url = self.details.payment_url - #if self.has_expired(): - # self.error = "ERROR: Payment Request has Expired." - # return False - return True def has_expired(self): return self.details.expires and self.details.expires < int(time.time()) + def get_expiration_date(self): + return self.details.expires + def get_amount(self): return sum(map(lambda x:x[1], self.outputs)) @@ -327,12 +329,17 @@ if __name__ == "__main__": uri = sys.argv[1] except: print "usage: %s url"%sys.argv[0] - print "example url: \"bitcoin:mpu3yTLdqA1BgGtFUwkVJmhnU3q5afaFkf?r=https%3A%2F%2Fbitcoincore.org%2F%7Egavin%2Ff.php%3Fh%3D2a828c05b8b80dc440c80a5d58890298&amount=1\"" + print "example url: \"bitcoin:17KjQgnXC96jakzJe9yo8zxqerhqNptmhq?amount=0.0018&r=https%3A%2F%2Fbitpay.com%2Fi%2FMXc7qTM5f87EC62SWiS94z\"" sys.exit(1) - address, amount, label, message, request_url, url = util.parse_url(uri) - pr = PaymentRequest(request_url) + address, amount, label, message, request_url = util.parse_URI(uri) + from simple_config import SimpleConfig + config = SimpleConfig() + pr = PaymentRequest(config) + pr.read(request_url) if not pr.verify(): + print 'verify failed' + print pr.error sys.exit(1) print 'Payment Request Verified Domain: ', pr.domain