How to add signed certificates to a bitcoin bip70 payment message? python
Question: References:

<https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki>
<https://github.com/aantonop/bitcoinbook/blob/develop/selected%20BIPs/bip-0070.mediawiki#paymentdetailspaymentrequest>

    
    
    message PaymentRequest {
        ##optional uint32 payment_details_version = 1 [default = 1]; # 'x509+sha256' in this case.
        ##optional string pki_type = 2 [default = "none"];
        optional bytes pki_data = 3;
        ##required bytes serialized_payment_details = 4;
        optional bytes signature = 5;
    }
    

The ones with `##` at the front are not a problem, I've solved them already.

`optional bytes pki_data` wants a byte encoded version of 'x509+sha256' so...

    
    
    x509_bytes = open('/path/to/x509.der', 'rb').read()
    pki_data = hashib.sha256(x509_bytes)
    

Is the above correct?

Next `optional bytes signature`, 'digital signature over a hash of the
protocol buffer serialized variation of the PaymentRequest message'

I'm not sure how to achieve this so any suggestions would be greatly
appreciated.

Finally I have...

    
    
    message X509Certificates {
            repeated bytes certificate = 1;
        }
    

`repeated bytes certificate` 'Each certificate is a DER [ITU.X690.1994] PKIX
certificate value. The certificate containing the public key of the entity
that digitally signed the PaymentRequest MUST be the first certificate.'

I only have the one cert I got from the comodo root authority so I think I
only need to supply the raw byte data of the cert to satisfy this one which
already exists in the form of `x509_bytes` above, so...

    
    
    repeated bytes certificate = x509_bytes
    

Am I close??

Also I notice that `repeated bytes certificate` comes after `optional bytes
signature` but shouldn't I deal with that before `message PaymentRequest` so
that I can serialise it into my http response somehow?

EDIT:

For what it's worth I'm aware that I need to import, instantiate and in some
cases serialise these methods before sending them as a request/response but
what I'm looking for are the methods on how to manipulate and supply the
information required.

Thanks :)


Answer: To add PKI data to the PaymentRequest object:

    
    
    pki_data = X509Certificates()
    certificates = [your_cert_der_data, root_cert_der_data]
    for cert in certificates:
        pki_data.certificate.append(cert)
    request.pki_data = pki_data.SerializeToString()
    

To add a signature (with
[pycrypto](https://www.dlitz.net/software/pycrypto/)):

    
    
    from Crypto.Hash import SHA256
    from Crypto.Signature import PKCS1_v1_5
    from Crypto.PublicKey import RSA
    
    # At this moment request object must contain serialized_payment_details, pki_type and pki_data
    request.signature = ""  # Add empty signature
    request_hash = SHA256.new(request.SerializeToString())
    private_key = RSA.importKey(private_key_der_data)
    signer = PKCS1_v1_5.new(private_key)
    request.signature = signer.sign(request_hash)
    result = request.SerializeToString()
    

