electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit dff8f6b338563bf211cafd877c0f7c67e493f94f
parent 35aba0c14bb9ae29a3bbcdb7153ce72e8692f7c5
Author: ThomasV <thomasv@gitorious>
Date:   Sat, 11 Jul 2015 20:26:30 +0200

rework paymentrequest methods

Diffstat:
Mgui/qt/main_window.py | 4++--
Mlib/paymentrequest.py | 98++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
2 files changed, 62 insertions(+), 40 deletions(-)

diff --git a/gui/qt/main_window.py b/gui/qt/main_window.py @@ -78,7 +78,7 @@ class StatusBarButton(QPushButton): from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED -from electrum.paymentrequest import PaymentRequest, InvoiceStore, get_payment_request, make_payment_request +from electrum.paymentrequest import PaymentRequest, InvoiceStore, get_payment_request pr_icons = { PR_UNPAID:":icons/unpaid.png", @@ -752,7 +752,7 @@ class ElectrumWindow(QMainWindow): def export_payment_request(self, addr): r = self.wallet.receive_requests.get(addr) - pr, requestor = paymentrequest.make_request(self.config, r) + pr = paymentrequest.serialize_request(r) pr = pr.SerializeToString() name = r['id'] + '.bip70' fileName = self.getSaveFileName(_("Select where to save your payment request"), name, "*.bip70") diff --git a/lib/paymentrequest.py b/lib/paymentrequest.py @@ -287,60 +287,82 @@ class PaymentRequest: -def make_payment_request(outputs, memo, time, expires, key_path, cert_path, alias, alias_privkey): +def make_unsigned_request(req): + from transaction import Transaction + addr = req['address'] + time = req['timestamp'] + amount = req['amount'] + expires = req['expiration'] + memo = req['memo'] + script = Transaction.pay_script('address', addr).decode('hex') + outputs = [(script, amount)] pd = pb2.PaymentDetails() for script, amount in outputs: pd.outputs.add(amount=amount, script=script) pd.time = time - pd.expires = expires if expires else 0 + pd.expires = time + expires if expires else 0 pd.memo = memo pr = pb2.PaymentRequest() pr.serialized_payment_details = pd.SerializeToString() pr.signature = '' - requestor = None + return pr - if alias and alias_privkey: - pr.pki_type = 'dnssec+btc' - pr.pki_data = str(alias) - message = pr.SerializeToString() - ec_key = bitcoin.regenerate_key(alias_privkey) - address = bitcoin.address_from_private_key(alias_privkey) - compressed = bitcoin.is_compressed(alias_privkey) - pr.signature = ec_key.sign_message(message, compressed, address) - requestor = alias - if key_path and cert_path: - import tlslite - with open(key_path, 'r') as f: - rsakey = tlslite.utils.python_rsakey.Python_RSAKey.parsePEM(f.read()) - with open(cert_path, 'r') as f: - chain = tlslite.X509CertChain() - chain.parsePemList(f.read()) - certificates = pb2.X509Certificates() - certificates.certificate.extend(map(lambda x: str(x.bytes), chain.x509List)) - pr.pki_type = 'x509+sha256' - pr.pki_data = certificates.SerializeToString() - msgBytes = bytearray(pr.SerializeToString()) - hashBytes = bytearray(hashlib.sha256(msgBytes).digest()) - sig = rsakey.sign(x509.PREFIX_RSA_SHA256 + hashBytes) - pr.signature = bytes(sig) - requestor = 'x' +def sign_request_with_alias(pr, alias, alias_privkey): + pr.pki_type = 'dnssec+btc' + pr.pki_data = str(alias) + message = pr.SerializeToString() + ec_key = bitcoin.regenerate_key(alias_privkey) + address = bitcoin.address_from_private_key(alias_privkey) + compressed = bitcoin.is_compressed(alias_privkey) + pr.signature = ec_key.sign_message(message, compressed, address) + return pr - return pr, requestor + +def sign_request_with_x509(pr, alias, alias_privkey): + import tlslite + with open(key_path, 'r') as f: + rsakey = tlslite.utils.python_rsakey.Python_RSAKey.parsePEM(f.read()) + with open(cert_path, 'r') as f: + chain = tlslite.X509CertChain() + chain.parsePemList(f.read()) + certificates = pb2.X509Certificates() + certificates.certificate.extend(map(lambda x: str(x.bytes), chain.x509List)) + pr.pki_type = 'x509+sha256' + pr.pki_data = certificates.SerializeToString() + msgBytes = bytearray(pr.SerializeToString()) + hashBytes = bytearray(hashlib.sha256(msgBytes).digest()) + sig = rsakey.sign(x509.PREFIX_RSA_SHA256 + hashBytes) + pr.signature = bytes(sig) + return pr + + +def serialize_request(req): + pr = make_unsigned_request(req) + signature = req.get('signature') + if signature: + requestor = req.get('requestor') + pr.signature = signature.decode('hex') + pr.pki_type = 'dnssec+btc' + pr.pki_data = str(requestor) + return pr def make_request(config, req, alias=None, alias_privkey=None): - from transaction import Transaction - addr = req['address'] - time = req['timestamp'] - amount = req['amount'] - expiration = req['expiration'] - message = req['memo'] - script = Transaction.pay_script('address', addr).decode('hex') - outputs = [(script, amount)] + pr = make_unsigned_request(req) key_path = config.get('ssl_privkey') cert_path = config.get('ssl_chain') - return make_payment_request(outputs, message, time, time + expiration if expiration else None, key_path, cert_path, alias, alias_privkey) + + if key_path and cert_path: + sign_request_with_x509(pr, key_path, cert_path) + requestor = pr.requestor + + elif alias and alias_privkey: + requestor = alias + sign_request_with_alias(pr, alias, alias_privkey) + + return pr, requestor +