Skip to content

Commit 40eadef

Browse files
authored
Merge pull request bitcoin#439 from techguy613/master
BIP75 Update: Versioning, Cancellation, Unknown Message Type, New PKI_TYPEs, Status Codes, Motivation
2 parents 1501dd9 + 45f5c56 commit 40eadef

File tree

2 files changed

+99
-62
lines changed

2 files changed

+99
-62
lines changed

bip-0075.mediawiki

Lines changed: 72 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,19 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S
3030

3131
==Motivation==
3232

33-
The motivation for defining this extension to the [[bip-0070.mediawiki|BIP70]] Payment Protocol is to allow 2 parties to exchange payment information in a permissioned and encrypted way such that wallet address communication can become a more automated process. Additionally, this extension allows for the requester of a PaymentRequest to supply a certificate and signature in order to facilitate identification for address release. This also allows for automated creation of off blockchain transaction logs that are human readable, containing who you transacted with, in addition to the information that it contains today.
33+
The motivation for defining this extension to the [[bip-0070.mediawiki|BIP70]] Payment Protocol is to allow two parties to exchange payment information in a permissioned and encrypted way, such that wallet address communication can become a more automated process. This extension also expands the types of PKI (public-key infrastructure) data that is supported, and allows it to be shared by both parties (with [[bip-0070.mediawiki|BIP70]], only the receiver could provide PKI information). This allows for automated creation of off-blockchain transaction logs that are human readable, now including information about the sender and not just the recipient.
3434

3535
The motivation for this extension to [[bip-0070.mediawiki|BIP70]] is threefold:
3636

3737
# Ensure that the payment details can only be seen by the participants in the transaction, and not by any third party.
3838
3939
# Enhance the Payment Protocol to allow for store and forward servers in order to allow, for example, mobile wallets to sign and serve Payment Requests.
4040
41-
# Allow a sender of funds the option of sharing their identity with the receiver. This information could then be used to:
41+
# Allow a sender of funds the option of sharing their identity with the receiver. This information could then be used to:
4242
43-
#* Make Bitcoin logs more human readable
44-
#* Give the user the ability to decide who to release payment details to
45-
#* Allow an entity such as a political campaign to ensure donors match regulatory and legal requirements
46-
#* Allow for an open standards based way for regulated financial entities to meet regulatory requirements
43+
#* Make Bitcoin logs (wallet transaction history) more human readable
44+
#* Give the user the ability to decide whether or not they share their Bitcoin address and other payment details when requested
45+
#* Allow for an open standards based way for businesses to keep verifiable records of their financial transactions, to better meet the needs of accounting practices or other reporting and statutory requirements
4746
#* Automate the active exchange of payment addresses, so static addresses and BIP32 X-Pubs can be avoided to maintain privacy and convenience
4847
4948
In short we wanted to make Bitcoin more human, while at the same time improving transaction privacy.
@@ -58,16 +57,31 @@ With this BIP, Bitcoin wallets could maintain an "address book" that only needs
5857

5958
2. Individual Permissioned Address Release
6059

61-
A Bitcoin wallet developer would like to allow users to view a potential sending party's identifying information before deciding whether or not to share payment information with them. Currently, [[bip-0070.mediawiki|BIP70]] specifies that the Merchant Server respond to a "pay now" style request with a PaymentRequest, releasing address and X.509 certificate identity information of the potential receiving party.
60+
A Bitcoin wallet developer would like to allow users to view a potential sending party's identifying information before deciding whether or not to share payment information with them. Currently, [[bip-0070.mediawiki|BIP70]] shares the receiver’s payment address and identity information with anyone who requests it.
6261

63-
With this BIP, Bitcoin wallets could prompt a wallet user to release payment information while displaying identity information about the potential sending party via an included certificate. This gives the receiving party more control over who receives their payment and identity information, and could be helpful for businesses that need to follow KYC policies or wallets that want to focus on privacy.
62+
With this BIP, Bitcoin wallets could use the sender’s identifying information to make a determination of whether or not to share their own information. This gives the receiving party more control over who receives their payment and identity information. Additionally, this could be used to automatically provide new payment addresses to whitelisted senders, or to protect users’ privacy from unsolicited payment requests.
6463

6564
3. Using Store & Forward Servers
6665

6766
A Bitcoin wallet developer would like to use a public Store & Forward service for an asynchronous address exchange. This is a common case for mobile and offline wallets.
6867

6968
With this BIP, returned payment information is encrypted with an ECDH-computed shared key before sending to a Store & Forward service. In this case, a successful attack against a Store & Forward service would not be able to read or modify wallet address or payment information, only delete encrypted messages.
7069

70+
==Modifying BIP70 pki_type==
71+
This BIP adds additional possible values for the pki_type variable in the PaymentRequest message. The complete list is now as follows:
72+
73+
{| class="wikitable"
74+
! pki_type !! Description
75+
|-
76+
| x509+sha256 || A x.509 certificate, as described in BIP70
77+
|-
78+
| pgp+sha256 || An [[https://en.wikipedia.org/wiki/Pretty_Good_Privacy#OpenPGP|OpenPGP]] certificate
79+
|-
80+
| ecdsa+sha256 || A [[https://en.bitcoin.it/wiki/Secp256k1|secp256k1]] [[https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm|ECDSA]] public key
81+
|}
82+
83+
'''NOTE''': Although SHA1 was supported in BIP70, it has been deprecated and BIP75 only supports SHA256. The hashing algorithm is still specified in the values listed above for forward and backwards compatibility.
84+
7185
==New Messages==
7286
Updated [/bip-0075/paymentrequest.proto paymentrequest.proto] contains the existing PaymentRequest Protocol Buffer messages as well as the messages newly defined in this BIP.
7387

@@ -95,7 +109,7 @@ message InvoiceRequest {
95109
|-
96110
| amount || amount is integer-number-of-satoshis (default: 0)
97111
|-
98-
| pki_type || none / x509+sha256 (default: "none")
112+
| pki_type || none / x509+sha256 / pgp+sha256 / ecdsa+sha256 (default: "none")
99113
|-
100114
| pki_data || Depends on pki_type
101115
|-
@@ -110,57 +124,71 @@ message InvoiceRequest {
110124
This enum is used in the newly defined [[#ProtocolMessage|ProtocolMessage]] and [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] messages to define the serialized message type. The '''ProtocolMessageType''' enum is defined in an extensible way to allow for new message type additions to the Payment Protocol.
111125
<pre>
112126
enum ProtocolMessageType {
113-
INVOICE_REQUEST = 0;
114-
PAYMENT_REQUEST = 1;
115-
PAYMENT = 2;
116-
PAYMENT_ACK = 3;
127+
UNKNOWN_MESSAGE_TYPE = 0;
128+
INVOICE_REQUEST = 1;
129+
PAYMENT_REQUEST = 2;
130+
PAYMENT = 3;
131+
PAYMENT_ACK = 4;
117132
}
118133
</pre>
119134

120135
===ProtocolMessage===
121136
The '''ProtocolMessage''' message is an encapsulating wrapper for any Payment Protocol message. It allows two-way, non-encrypted communication of Payment Protocol messages. The message also includes a status code and a status message that is used for error communication such that the protocol does not rely on transport-layer error handling.
122137
<pre>
123138
message ProtocolMessage {
124-
required ProtocolMessageType message_type = 1;
125-
required bytes serialized_message = 2;
126-
optional uint64 status_code = 3;
127-
optional string status_message = 4;
128-
optional bytes identifier = 5;
139+
required uint64 version = 1
140+
required uint64 status_code = 2;
141+
required ProtocolMessageType message_type = 3;
142+
required bytes serialized_message = 4;
143+
optional string status_message = 5;
144+
optional bytes identifier = 6;
129145
}
130146
</pre>
131147

132148
{| class="wikitable"
133149
! Field Name !! Description
134150
|-
151+
|version || Protocol version number (Currently 1)
152+
|-
153+
|status_code || Payment Protocol Status Code
154+
|-
135155
|message_type || Message Type of serialized_message
136156
|-
137157
|serialized_message || Serialized Payment Protocol Message
138158
|-
139-
|status_code || Payment Protocol Status Code
140-
|-
141159
|status_message || Human-readable Payment Protocol status message
142160
|-
143161
|identifier || Unique key to identify this entire exchange on the server. SHA256 of initial serialized InvoiceRequest SHOULD be used by default
144162
|}
145163

164+
===Versioning===
165+
This BIP introduces version 1 of this protocol. All messages sent using these base requirements MUST use a value of 1 for the version number. Any future BIPs that modify this protocol (encryption schemes, etc) MUST each increment the version number by 1.
166+
167+
When initiating communication, the version field of the first message SHOULD be set to the highest verison number the sender understands. All clients MUST be able to understand all version numbers less than the highest number they support. If a client receives a message with a version number higher than they understand, they MUST send the message back to the sender with a status code of 101 ("version too high") and the version field set to the highest version number the recipient understands. The sender must then resend the original message using the same version number returned by the recipient or abort.
168+
146169
===EncryptedProtocolMessage===
147170
The '''EncryptedProtocolMessage''' message is an encapsualting wrapper for any Payment Protocol message. It allows two-way, authenticated and encrypted communication of Payment Protocol messages in order to keep their contents secret. The message also includes a status code and status message that is used for error communication such that the protocol does not rely on transport-layer error handling.
148171
<pre>
149172
message EncryptedProtocolMessage {
150-
required ProtocolMessageType message_type = 1;
151-
required bytes encrypted_message = 2;
152-
required bytes receiver_public_key = 3;
153-
required bytes sender_public_key = 4;
154-
required uint64 nonce = 5;
155-
optional bytes signature = 6;
156-
optional bytes identifier = 7;
157-
optional uint64 status_code = 8;
173+
required uint64 version = 1 [default = 1];
174+
required uint64 status_code = 2 [default = 1];
175+
required ProtocolMessageType message_type = 3;
176+
required bytes encrypted_message = 4;
177+
required bytes receiver_public_key = 5;
178+
required bytes sender_public_key = 6;
179+
required uint64 nonce = 7;
180+
optional bytes identifier = 8;
158181
optional string status_message = 9;
182+
optional bytes signature = 10;
159183
}
160184
</pre>
161185
{| class="wikitable"
162186
! Field Name !! Description
163187
|-
188+
| version || Protocol version number
189+
|-
190+
| status_code || Payment Protocol Status Code
191+
|-
164192
| message_type || Message Type of Decrypted encrypted_message
165193
|-
166194
| encrypted_message || AES-256-GCM Encrypted (as defined in BIP75) Payment Protocol Message
@@ -171,13 +199,11 @@ message EncryptedProtocolMessage {
171199
|-
172200
| nonce || Microseconds since epoch
173201
|-
174-
| signature || DER-encoded Signature over the full EncryptedProtocolMessage with EC Key Belonging to Sender / Receiver, respectively
175-
|-
176202
| identifier || Unique key to identify this entire exchange on the server. SHA256 of initial serialized InvoiceRequest SHOULD be used by default
177203
|-
178-
| status_code || Payment Protocol Status Code
179-
|-
180204
| status_message || Human-readable Payment Protocol status message
205+
|-
206+
| signature || DER-encoded Signature over the full EncryptedProtocolMessage with EC Key Belonging to Sender / Receiver, respectively
181207
|}
182208

183209
==Payment Protocol Process with InvoiceRequests==
@@ -221,21 +247,25 @@ When communicated via '''HTTP''', the listed messages MUST be transmitted via TL
221247

222248
===Payment Protocol Status Communication===
223249

224-
In the case of an error that causes the Payment Protocol process to be stopped or requires that message be retried, a [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] MUST be returned by the party generating the error status_code. The content of the message MUST contain the same '''serialized_message''' or '''encrypted_message''' and identifier (if present) and MUST have the status_code set appropriately.
250+
Every [[#ProtocolMessage|ProtocolMessage]] or [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] MUST include a status code which conveys information about the last message received, if any (for the first message sent, use a status of 1 "OK" even though there was no previous message). In the case of an error that causes the Payment Protocol process to be stopped or requires that message be retried, a ProtocolMessage or EncryptedProtocolMessage SHOULD be returned by the party generating the error. The content of the message MUST contain the same '''serialized_message''' or '''encrypted_message''' and identifier (if present) and MUST have the status_code set appropriately.
225251
<br/><br/>
226-
The status_message value SHOULD be set with a human readable explanation of the status code. For example, if in an [[#EncryptedProtocolMessage|EncryptedProtocolMessage]], the AES-256-GCM decryption fails to authenticate, an Authentication Failed (102) '''status_code''' MUST be returned to prevent oracle attacks.
252+
The status_message value SHOULD be set with a human readable explanation of the status code.
227253

228254
====Payment Protocol Status Codes====
229255
{| class="wikitable"
230256
! Status Code !! Description
231257
|-
232258
| 1 || OK
233259
|-
260+
| 2 || Cancel
261+
|-
234262
| 100 || General / Unknown Error
235263
|-
264+
| 101 || Version Too High
265+
|-
236266
| 102 || Authentication Failed
237267
|-
238-
| 102 || Encrypted Message Required
268+
| 103 || Encrypted Message Required
239269
|-
240270
| 200 || Amount Too High
241271
|-
@@ -257,8 +287,10 @@ The status_message value SHOULD be set with a human readable explanation of the
257287
|-
258288
|}
259289

260-
===Transport Layer Communication Errors===
290+
+==Canceling A Message==+
291+
If a participant to a transaction would like to inform the other party that a previous message should be canceled, they can send the same message with a status code of 2 ("Cancel") and, where applicable, an updated nonce. How recipients make use of the "Cancel" message is up to developers. For example, wallet developers may want to offer users the ability to cancel payment requests they have sent to other users, and have that change reflected in the recipient's UI. Developers using the non-encrypted ProtocolMessage may want to ignore "Cancel" messages, as it may be difficult to authenticate that the message originated from the same user.
261292

293+
===Transport Layer Communication Errors===
262294
Communication errors MUST be communicated to the party that initiated the communication via the communication layer's existing error messaging faciltiies. In the case of TLS-protected HTTP, this SHOULD be done through standard HTTP Status Code messaging ([https://tools.ietf.org/html/rfc7231 RFC 7231 Section 6]).
263295

264296
==Extended Payment Protocol Process Details==
@@ -291,6 +323,7 @@ For the following we assume the Sender already knows the Receiver's public key,
291323
* Encrypt the serialized Payment Protocol message using AES-256-CBC setup as described in [[#ECDH_Point_Generation_and_AES256_GCM_Mode_Setup|ECDH Point Generation and AES-256 (GCM Mode) Setup]]
292324
* Create [[#EncryptedProtocolMessage|EncryptedProtocolMessage]] message
293325
* Set '''encrypted_message''' to be the encrypted value of the Payment Protocol message
326+
* '''version''' SHOULD be set to the highest version number the client understands (currently 1)
294327
* '''sender_public_key''' MUST be set to the public key of the Sender's EC keypair
295328
* '''receiver_public_key''' MUST be set to the public key of the Receiver's EC keypair
296329
* '''nonce''' MUST be set to the nonce used in the AES-256-CBC encryption operation
@@ -312,7 +345,7 @@ For the following we assume the Sender already knows the Receiver's public key,
312345
* Generate the '''secret point''' using [https://en.wikipedia.org/wiki/Elliptic_curve_Diffie–Hellman ECDH] using the local entity's private key and the remote entity's public key as inputs
313346
* Initialize [http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf HMAC_DRBG]
314347
** Use '''SHA512(secret point's X value in Big-Endian bytes)''' for Entropy
315-
** Use the given message's '''nonce''' field for Nonce
348+
** Use the given message's '''nonce''' field for Nonce, converted to byte string (Big Endian)
316349
317350
* Initialize AES-256 in GCM Mode
318351
** Initialize HMAC_DRBG with Security Strength of 256 bits
@@ -343,8 +376,9 @@ If a Store & Forward server wishes to protect themselves from spam or abuse, the
343376
Clients SHOULD keep in mind Receivers can broadcast a transaction without returning an ACK. If a Payment message needs to be updated, it SHOULD include at least one input referenced in the original transaction to prevent the Receiver from broadcasting both transactions and getting paid twice.
344377

345378
==Public Key & Signature Encoding==
346-
* All EC public keys ('''sender_public_key''', '''receiver_public_key''') included in any message defined in this BIP MUST be DER [ITU.X690.1994] encoded.
379+
* All EC public keys ('''sender_public_key''', '''receiver_public_key''') or x.509 certificates included in any message defined in this BIP MUST be DER [ITU.X690.1994] encoded.
347380
* All ECC signatures included in any message defined in this BIP MUST use the SHA-256 hashing algorithm and MUST be DER [ITU.X690.1994] encoded.
381+
* All OpenPGP certificates must follow [[https://tools.ietf.org/html/rfc4880|RFC4880]], sections 5.5 and 12.1.
348382
349383
==Implementation==
350384
A reference implementation for a Store & Forward server supporting this proposal can be found here:

0 commit comments

Comments
 (0)