rework paymentrequest methods

This commit is contained in:
ThomasV 2015-07-11 20:26:30 +02:00
parent 35aba0c14b
commit dff8f6b338
2 changed files with 70 additions and 48 deletions

View File

@ -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")

View File

@ -287,60 +287,82 @@ class PaymentRequest:
def make_payment_request(outputs, memo, time, expires, key_path, cert_path, alias, alias_privkey):
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.memo = memo
pr = pb2.PaymentRequest()
pr.serialized_payment_details = pd.SerializeToString()
pr.signature = ''
requestor = None
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'
return pr, requestor
def make_request(config, req, alias=None, alias_privkey=None):
def make_unsigned_request(req):
from transaction import Transaction
addr = req['address']
time = req['timestamp']
amount = req['amount']
expiration = req['expiration']
message = req['memo']
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 = time + expires if expires else 0
pd.memo = memo
pr = pb2.PaymentRequest()
pr.serialized_payment_details = pd.SerializeToString()
pr.signature = ''
return pr
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
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):
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