public inbox for bitcoindev@googlegroups.com
 help / color / mirror / Atom feed
* [Bitcoin-development] Cold Signing Payment Requests
@ 2013-04-24 23:01 Jeremy Spilman
  2013-04-24 23:07 ` Alan Reiner
  0 siblings, 1 reply; 19+ messages in thread
From: Jeremy Spilman @ 2013-04-24 23:01 UTC (permalink / raw)
  To: bitcoin-development

[-- Attachment #1: Type: text/plain, Size: 2585 bytes --]

Payment Protocol uses x509 certs to sign a Payment Request. This
allows wallets to display meta-data from the cert to the payer instead
of the address, which should make it easier to verify where money is
being sent, and make it harder for an attacker to change the address
displayed to a user so that coins are not sent to the wrong place.

The difficulty is that Payment Requests must be generated live, and
therefore the key used to sign those requests must also be live,
exposing the key to theft similar to a hot wallet. Steal the key,
forge payment requests, and the payer sees a 'green box' but the coins
go to the attacker. The question... is there a way to sign something
once, with a key kept offline, which verifies the address in the
Payment Request belongs to the payee?

1) Given a 'parent' cert which is kept offline, and a child
certificate of 'parent' which is kept hot on the payment server.

2) Given a public key and chain code { pubKey, code } under BIP32 we
generate child keys as I = HMAC(code, Kpar || i), Ki = I[0:32] * Kpar.

3) If we sign Kpar with the parent cert's key offline, we can sign the
remaining less critical data (address, I[0:32], amount, description,
etc.) with the child cert's key.

4) The payer verifies Kpar, and verifies the address by calculating
Hash160(Kpar * I[0:32])

In fact, there's no requirement to use BIP32 to calculate I[0:32], it
could also just be randomly generated.

Any I[0:32] included in the Payment Request, even if it is tampered
with, will correspond to an address for which the payee can calculate
the corresponding private key.

So the idea is your 'most trusted' cert would be used offline only to
sign a Kpar once, and a 'less trusted' cert would be used to sign the
other stuff, like 'amount', 'description', 'merchant-data', and the
'I[0:32]' as well.

I'm not an expert on x509, but I imagine the trouble is, how does the
payer know which cert is which? I was originally thinking the parent
cert would be an intermediate CA cert used to sign the child cert, but
I guess good look getting one of those, even with a name constraint,
from a Root CA. I'm not sure if you can do better than just a
'convention' such as one is an EV cert and one is not. Perhaps the
less trusted cert is actually self-signed using the EV cert, but that
requires special validation, since its no longer a standard
certificate chain. I would love to hear a better idea.

Any comments if this is something worth pursuing? I think there are
definitely benefits if merchants can keep the key signing the address
offline.

Thanks,--Jeremy

[-- Attachment #2: Type: text/html, Size: 3754 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-24 23:01 [Bitcoin-development] Cold Signing Payment Requests Jeremy Spilman
@ 2013-04-24 23:07 ` Alan Reiner
  2013-04-25  9:08   ` Mike Hearn
  0 siblings, 1 reply; 19+ messages in thread
From: Alan Reiner @ 2013-04-24 23:07 UTC (permalink / raw)
  To: bitcoin-development

[-- Attachment #1: Type: text/plain, Size: 3746 bytes --]

There's some good discussion about that here:

https://bitcointalk.org/index.php?topic=130749.msg1398972#msg1398972

thanke came up with this first, and then I reinvented it, and now you
have.  But the thread has some good discussion about how to move
forward.  I'm a big fan of putting the lower-case root hash160 in your
subdomain and getting and SSL cert for that.  Feel free to contribute to
that thread if you find it compelling.

-Alan


On 04/24/2013 07:01 PM, Jeremy Spilman wrote:
> Payment Protocol uses x509 certs to sign a Payment Request. This allows wallets to display meta-data from the cert to the payer instead of the address, which should make it easier to verify where money is being sent, and make it harder for an attacker to change the address displayed to a user so that coins are not sent to the wrong place.
>
> The difficulty is that Payment Requests must be generated live, and therefore the key used to sign those requests must also be live, exposing the key to theft similar to a hot wallet. Steal the key, forge payment requests, and the payer sees a 'green box' but the coins go to the attacker. The question... is there a way to sign something once, with a key kept offline, which verifies the address in the Payment Request belongs to the payee?
>
> 1) Given a 'parent' cert which is kept offline, and a child certificate of 'parent' which is kept hot on the payment server.
>
> 2) Given a public key and chain code { pubKey, code } under BIP32 we generate child keys as I = HMAC(code, Kpar || i), Ki = I[0:32] * Kpar.
>
> 3) If we sign Kpar with the parent cert's key offline, we can sign the remaining less critical data (address, I[0:32], amount, description, etc.) with the child cert's key.
>
> 4) The payer verifies Kpar, and verifies the address by calculating Hash160(Kpar * I[0:32])
>
> In fact, there's no requirement to use BIP32 to calculate I[0:32], it could also just be randomly generated.
>
> Any I[0:32] included in the Payment Request, even if it is tampered with, will correspond to an address for which the payee can calculate the corresponding private key.
> So the idea is your 'most trusted' cert would be used offline only to sign a Kpar once, and a 'less trusted' cert would be used to sign the other stuff, like 'amount', 'description', 'merchant-data', and the 'I[0:32]' as well.
> I'm not an expert on x509, but I imagine the trouble is, how does the payer know which cert is which? I was originally thinking the parent cert would be an intermediate CA cert used to sign the child cert, but I guess good look getting one of those, even with a name constraint, from a Root CA. I'm not sure if you can do better than just a 'convention' such as one is an EV cert and one is not. Perhaps the less trusted cert is actually self-signed using the EV cert, but that requires special validation, since its no longer a standard certificate chain. I would love to hear a better idea.
>
> Any comments if this is something worth pursuing? I think there are definitely benefits if merchants can keep the key signing the address offline.
> Thanks,
> --Jeremy
>
>
> ------------------------------------------------------------------------------
> Try New Relic Now & We'll Send You this Cool Shirt
> New Relic is the only SaaS-based application performance monitoring service 
> that delivers powerful full stack analytics. Optimize and monitor your
> browser, app, & servers with just a few lines of code. Try New Relic
> and get this awesome Nerd Life shirt! http://p.sf.net/sfu/newrelic_d2d_apr
>
>
> _______________________________________________
> Bitcoin-development mailing list
> Bitcoin-development@lists•sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/bitcoin-development


[-- Attachment #2: Type: text/html, Size: 5923 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-24 23:07 ` Alan Reiner
@ 2013-04-25  9:08   ` Mike Hearn
  0 siblings, 0 replies; 19+ messages in thread
From: Mike Hearn @ 2013-04-25  9:08 UTC (permalink / raw)
  To: Alan Reiner; +Cc: Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 1746 bytes --]

(for background: I did a lot of the design work with Gavin on the payment
protocol and suggested/prototyped using x.509 in the way we do).

So, I'm not a fan of weird hacks involving non-existent domain names.
There's a clean way to implement this and we decided to punt on it for v1
in order to get something shippable, but if you're volunteering ... :) then
indeed having a custom cert type that chains onto the end is the way to go.

It doesn't have to be X.509. It can just be a regular protocol buffer. Even
if we re-used X.509 it wouldn't be accepted by OpenSSL or any other SSL
stack, so it wouldn't buy us anything and it's not like ASN.1 is easy to
work with. Chaining an additional Bitcoin-specific cert onto the end also
solves the problem of delegation ... a lot of merchants are using BitPay
but probably don't want to share their SSL private keys with a third party.
That means today the payments would show up as paid to BitPay Inc which is
misleading and weird, they're just an intermediary. So if the merchant can
run a simple command line tool that you point to the private key, and it
spits out a signed protobuf that contains a new (ecdsa) public key and
saves the private key to a file, then you can send that cert and key off to
your payment processor. The identity is still taken from your CA cert but
the actual signing keys used are different.

Another use case - a company has a lot of roving sales agents, like in a
supermarket or waiters at a restaurant. The company wants the agents to be
able to sign with their corporate EV identity but the agents are not highly
trusted. So they can be issued a 24-hour expiring Bitcoin-specific cert at
the start of each working day and then they sign payment requests with that.

[-- Attachment #2: Type: text/html, Size: 1948 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-30 17:17                           ` Jeremy Spilman
@ 2013-05-06 21:29                             ` Peter Todd
  0 siblings, 0 replies; 19+ messages in thread
From: Peter Todd @ 2013-05-06 21:29 UTC (permalink / raw)
  To: Jeremy Spilman; +Cc: Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 1240 bytes --]

On Tue, Apr 30, 2013 at 10:17:23AM -0700, Jeremy Spilman wrote:
> [Aside] I was reading Peter's fidelitybond writeup for his idea on contract
> value accounting, and he points to Stephan's post from last September on
> payer-encoded metadata (
> https://bitcointalk.org/index.php?topic=108423.msg1178438#msg1178438) which
> Timo applies here. As a relative newcomer, this is what I am loving most
> about Bitcoin.

The widespread disclosure we do is a good thing for sure.

Keep in mind that Bitcoin is brand new technology, and brand new fields
tend to get lots of people coming in and trying to patent them. Public
disclosure, and bitcointalk, the email list, and github all count, is a
valuable tool to ward off potential threats in the future if it ever
comes to that.

FWIW it might not be a bad idea to see if archive.org would accept some
of the key documentation like the development section of the forum, the
email list archives, and the irc logs. Some issues, especially on the
forum, with people's ability to edit posts after the fact, but we're
breaking new ground here and the history should be archived.

-- 
'peter'[:-1]@petertodd.org
00000000000000f5a3175efc20cdac41f848d47dc7d00debe821ebfa69f91db9

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-30 13:14                         ` Gavin Andresen
@ 2013-04-30 17:17                           ` Jeremy Spilman
  2013-05-06 21:29                             ` Peter Todd
  0 siblings, 1 reply; 19+ messages in thread
From: Jeremy Spilman @ 2013-04-30 17:17 UTC (permalink / raw)
  To: Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 1712 bytes --]

> 1) The risk that the merchant's web server will be compromised and the
attacker will redirect refunds
> 2) The risk that the merchant will miss payments because they miss a POST
to the payment_url (maybe the customer's machine crashes during the HTTPS
handshake)
> If payments are a lot more common than refunds, then (2) will outweigh
(1).

I think that's oversimplifying.  (1) is theft, (2) is payment processing.
Reliable payment processing with refund handling is not simple nor free,
but it should be secure. The cost of (2) depends primarily on the failure
rate, which we can only guess at this point, and secondarily on how much
manual intervention is required to recover.

(2) is perhaps more of a problem if wallets broadcast before POST. It's
trading one failure mode (funds sent but not claimed) for another (coins
marked as spent but not). Either way, you fix it by just retrying the POST.
But only with Transmit-After-ACK can the payer's wallet detect the failure
automatically, and even recover automatically (simply unlock the outputs,
or to be sure, spend them back to self).

Since merchants get to choose whether to have a POST url, they get to
decide if the cost of keeping their server up is worth it. I think
eventually there are enough benefits to Transmit-After-ACK that it will
become a supported use case.

Thanks Mike for explaining the threat.

[Aside] I was reading Peter's fidelitybond writeup for his idea on contract
value accounting, and he points to Stephan's post from last September on
payer-encoded metadata (
https://bitcointalk.org/index.php?topic=108423.msg1178438#msg1178438) which
Timo applies here. As a relative newcomer, this is what I am loving most
about Bitcoin.

[-- Attachment #2: Type: text/html, Size: 2752 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-30 11:32                       ` Jouke Hofman
@ 2013-04-30 13:14                         ` Gavin Andresen
  2013-04-30 17:17                           ` Jeremy Spilman
  0 siblings, 1 reply; 19+ messages in thread
From: Gavin Andresen @ 2013-04-30 13:14 UTC (permalink / raw)
  To: Jouke Hofman; +Cc: bitcoin-development

[-- Attachment #1: Type: text/plain, Size: 697 bytes --]

RE: Timo's proposal for protecting the refund address:

Seems to me there are two risks:

1) The risk that the merchant's web server will be compromised and the
attacker will redirect refunds
2) The risk that the merchant will miss payments because they miss a POST
to the payment_url (maybe the customer's machine crashes during the HTTPS
handshake)

If payments are a lot more common than refunds, then (2) will outweigh (1).

I also think an attacker who compromises the front-end web server would
probably just have it start generating plain-old pay-to-bitcoin-address
payment requests, and hope that lots of customers pay them directly before
the attack is discovered.

-- 
--
Gavin Andresen

[-- Attachment #2: Type: text/html, Size: 869 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-30  9:17                     ` Mike Hearn
@ 2013-04-30 11:32                       ` Jouke Hofman
  2013-04-30 13:14                         ` Gavin Andresen
  0 siblings, 1 reply; 19+ messages in thread
From: Jouke Hofman @ 2013-04-30 11:32 UTC (permalink / raw)
  To: bitcoin-development

We do automatic refunds. When bitcoins arrive after an offer has expired
(which happens quite often with webwallets that don't broadcast
transactions immediately), we return all the bitcoins to a specified
bitcoin-address. This happens a couple of times per day and can amount
to a couple of hundred bitcoins per offer.



On 04/30/2013 11:17 AM, Mike Hearn wrote:

> If there are merchants that offer large, automatic refunds, it could be
> an issue. I'm not sure how common that might be in reality. Steven or
> Tony would know. Timo's protocol is an interesting solution, but again,
> at this point the feature set for v1 is pretty much locked down.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-29 18:40                   ` Jeremy Spilman
@ 2013-04-30  9:17                     ` Mike Hearn
  2013-04-30 11:32                       ` Jouke Hofman
  0 siblings, 1 reply; 19+ messages in thread
From: Mike Hearn @ 2013-04-30  9:17 UTC (permalink / raw)
  To: Jeremy Spilman; +Cc: Bitcoin Dev, timo.hanke

[-- Attachment #1: Type: text/plain, Size: 1015 bytes --]

>  Backing up a step, I'm not sure what the threat model is for signing the
> refund address? The same process that's signing the transaction is doing an
> HTTPS POST with the refund address.
>

It's a real threat, albeit an exotic one. The threat model is a malware
compromised host, with a wallet (possibly a low power hardware wallet like
a Trezor) that can understand the payment protocol and sign transactions,
but maybe not do a whole lot more than that. For instance, probably it
cannot do HTTPS connections itself. So a virus on the host could swap the
refund address for one that is owned by the attacker, and then try to make
the merchant issue an automatic refund, thus bouncing the funds back off
the merchant to the them.

If there are merchants that offer large, automatic refunds, it could be an
issue. I'm not sure how common that might be in reality. Steven or Tony
would know. Timo's protocol is an interesting solution, but again, at this
point the feature set for v1 is pretty much locked down.

[-- Attachment #2: Type: text/html, Size: 1351 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-28 18:03                 ` Timo Hanke
@ 2013-04-29 18:40                   ` Jeremy Spilman
  2013-04-30  9:17                     ` Mike Hearn
  0 siblings, 1 reply; 19+ messages in thread
From: Jeremy Spilman @ 2013-04-29 18:40 UTC (permalink / raw)
  To: timo.hanke, Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 1645 bytes --]

It's neat to use the payment address as an implicit signature by hashing
something and multiplying it into the payee's pubKey.

 One downside is that it complicates the merchant's wallet. In this case
the payment is going to a pseudo-random address which the merchant will
have to explicitly add to their wallet, complicating backups, etc.

 The other challenge is how to handle an error when you POST to the
payment_url. In the original spec, the payer would only broadcast the
transaction themselves if there wasn't a payment_url. In the current
version it looks like the payer will broadcast the transaction(s) either
way. I only saw some of the discussions around this, but I think part of
the problem is what state do you put the payer's wallet into if you POST a
Payment and don't get a PaymentAck? If the payer always broadcasts the
transaction, then wallet state becomes obvious. With your proposal you
would not want the payer to broadcast the transaction without a PaymentAck,
since you need the merchant to acknowledge they know where to look for the
payment.

 Backing up a step, I'm not sure what the threat model is for signing the
refund address? The same process that's signing the transaction is doing an
HTTPS POST with the refund address. If an attacker can defeat that, then
they can just redirect the payment in the first place. The only benefit I
can think of is the payer can prove what refund address they specified with
the payment.

 Wouldn't it be easier to just get the merchant to sign the PaymentAck?
Technically they already are signing it, but a TLS stream probably isn't
the most convenient way to capture that.

[-- Attachment #2: Type: text/html, Size: 1887 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-26  1:07               ` Gavin Andresen
@ 2013-04-28 18:03                 ` Timo Hanke
  2013-04-29 18:40                   ` Jeremy Spilman
  0 siblings, 1 reply; 19+ messages in thread
From: Timo Hanke @ 2013-04-28 18:03 UTC (permalink / raw)
  To: Gavin Andresen; +Cc: Bitcoin Dev

On Thu, Apr 25, 2013 at 09:07:07PM -0400, Gavin Andresen wrote:
> On Thu, Apr 25, 2013 at 3:12 PM, Jeremy Spilman <jeremy.spilman@gmail•com>wrote:
> 
> > Right now I'm leaning towards writing a prototype using a single cert with
> > a fingerprint of PubKey in the Subject Alternate Name, and getting PubKey
> > and InvoiceID in the Payment Request.  Gavin, would the best way to work on
> > this be to just fork your code on Github?
> >
> 
> As usual, our bottleneck is code review / testing, so it would be nice if
> you spent some time reviewing code and helping test v0.9 so we can actually
> ship a v1 sometime in the next several months before you start working on a
> v2.

How does the current protocol protect the refund address? Protecting the
payee against a compromised webserver may be out of scope for now, due
to the lack of a suitable PKI, as Mike Hearn explained. But signing the
refund address is a more immediate issue. There is no obvious key that
the payer can use to sign the refund address. However, this can be
solved right now with marginal changes to the protocol, like this:

- Payee creates his PaymentDetails message with an explicit pubkey in
  output.script, not an address.
- If payment_url is not specified then payer pays as before (he cannot
  sign his refund address) 
- If payment_url is specified then payer hashes his Payment message
  (with transactions zeroed out) and pays to h*pubkey, where h is the
  computed hash; then submits his Payment message.
- Upon receiving the Payment message, payee computes the same hash and
  can pick his funds from h*pubkey. 

As long as it is trivial to reconstruct the Payment message this is
completely safe. But probably this isn't the case in general. So the
drawback is that the payer has to backup the Payment message before
submitting it or before broadcasting the transaction, in order to keep a
proof. If the payer trusted the payee then it would suffice to wait for
an ACK before broadcasting. Because of the backup issue, refund address
signing should probably be an option that the payer can choose after
reading a backup warning.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-25 19:12             ` Jeremy Spilman
@ 2013-04-26  1:07               ` Gavin Andresen
  2013-04-28 18:03                 ` Timo Hanke
  0 siblings, 1 reply; 19+ messages in thread
From: Gavin Andresen @ 2013-04-26  1:07 UTC (permalink / raw)
  To: Jeremy Spilman; +Cc: Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 613 bytes --]

On Thu, Apr 25, 2013 at 3:12 PM, Jeremy Spilman <jeremy.spilman@gmail•com>wrote:

> Right now I'm leaning towards writing a prototype using a single cert with
> a fingerprint of PubKey in the Subject Alternate Name, and getting PubKey
> and InvoiceID in the Payment Request.  Gavin, would the best way to work on
> this be to just fork your code on Github?
>

As usual, our bottleneck is code review / testing, so it would be nice if
you spent some time reviewing code and helping test v0.9 so we can actually
ship a v1 sometime in the next several months before you start working on a
v2.

-- 
--
Gavin Andresen

[-- Attachment #2: Type: text/html, Size: 963 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-25 14:31           ` Mike Hearn
@ 2013-04-25 19:12             ` Jeremy Spilman
  2013-04-26  1:07               ` Gavin Andresen
  0 siblings, 1 reply; 19+ messages in thread
From: Jeremy Spilman @ 2013-04-25 19:12 UTC (permalink / raw)
  To: Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 2809 bytes --]

There are definitely ways to keep the pay-to address secure even if the web
server is compromised, just perhaps not perfectly clean standard X.509 ways
under the current ecosystem which would be easier for everyone to agree on.

 - If a more trusted cert is an EV end cert, and a less trusted is a DV end
cert (not chained off the EV) then it's easy for the wallet to distinguish
between the two, and they are both valid certs. EV signs pubKey offline, DV
used hot on the web server.
 - If the more trusted cert is an EV or DV end cert, and the less trusted
cert is chained off that end cert, it's technically 'invalid' so again its
obvious which one is more/less trusted, but it's easier for an attacker to
get their own DV end cert for your domain.
 - The third way is getting the pubKey into the cert attributes, such as
encoding the pubKey, or a fingerprint of the pubKey, as a Subject Alternate
Name, so the attacker would need to get their own cert to change the
address, meaning it's not as critical if your cert key is stolen.

On the wallet side, it comes down to additional validation code paths which
get triggered by some detection logic. For example, if you pass PubKey and
InvoiceID in the Payment Request, the wallet needs to know if it should
check for a Subject Alternate Name in the cert for a fingerprint of the
PubKey, how the fingerprint is calculated, and then verify the Address is
indeed PubKey * InvoiceID.  I think falsely rejecting a legacy Payment
Request would get the extra validation code path commented out pretty
quickly.

I really like Mike Hearn's idea of 'You have paid this recipient 4 times'
but also agree completely on the crying wolf due to expiration or
revocation. At least such a message could be based on the domain name only,
to try to prevent phishing with similar domain names, then there's no
expiration issue. Slightly more restrictive would be domain + CA, again not
considering expiration, but pinning the pay count to the CA seems to have
little downside and makes it harder for an attacker to get their own cert
for your domain if you choose your CA 'wisely'.

I assume the ship has sailed on v1, but if we can get consensus on how we
want this to work in the near-term, we can start prototyping it and maybe
get this available sooner than later. In any case we should be confirm v1
doesn't do anything to prevent this from working in a clean, extensible
manor, which I think means prototyping it and seeing the new Payment
Request is handled transparently by v1 code.

Right now I'm leaning towards writing a prototype using a single cert with
a fingerprint of PubKey in the Subject Alternate Name, and getting PubKey
and InvoiceID in the Payment Request.  Gavin, would the best way to work on
this be to just fork your code on Github?

Thanks,
--Jeremy

[-- Attachment #2: Type: text/html, Size: 3163 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
       [not found]         ` <FDF215AE-F9A4-4EE3-BDC9-0A4EF027423A@swipeclock.com>
@ 2013-04-25 14:31           ` Mike Hearn
  2013-04-25 19:12             ` Jeremy Spilman
  0 siblings, 1 reply; 19+ messages in thread
From: Mike Hearn @ 2013-04-25 14:31 UTC (permalink / raw)
  To: Mike Caldwell; +Cc: Bitcoin Dev, timo.hanke

[-- Attachment #1: Type: text/plain, Size: 2569 bytes --]

On Thu, Apr 25, 2013 at 4:13 PM, Mike Caldwell <mcaldwell@swipeclock•com>wrote:

> I am not sure if my replies hit the list. If not, can anyone who sees this
> help?
>
> In the past, I have pre signed (with PGP) large batches of Bitcoin
> addresses for distribution on my server. This way, even in the event of
> compromise, there is no way someone could substitute an address of their
> own and have it have the same characteristics as other addresses I have
> signed.  The same general concept could be used to keep signing keys off
> the web server.
>
> Mike
>

I didn't see your other replies but got this one.

The assumption you made by doing that is that people can obtain your PGP
key. This leads to the question of how someone knows what your key is or
that you signed the list in the first place. The most obvious way is to go
to https://www.casascius.com/ and click "My PGP key" -> but we already
failed at this point if your web server was hacked. I'd have to learn about
your cryptographic identity via some other secure channel, but usually that
doesn't exist.

Being able to survive web server hacks is intuitively attractive because
web servers tend to be so insecure. But unfortunately there doesn't seem to
be any good way to do this with todays infrastructure because for most
businesses, their website *is* their identity, and if a hacker controls
that they it's very hard for anyone (including CAs) to know that something
has gone wrong.

I think there are some simple mitigations we can use in the short term.

One is that wallets could count how many times you paid to addresses signed
by a particular cert. If you're a repeat customer and your wallet says "You
have never paid this recipient before" instead of "You have paid this
recipient 4 times" then you might be suspicious. Someone pointed out to me
that the current payment protocol has nothing to say on phishing using
confusible domains - this could help with that too, and it's easy to
implement. Of course it means you get reset whenever your certificate
expires and has to be renewed, and crying wolf is often worse than doing
nothing at all. So that's an issue.

With time there might be more complex solutions available, like extensions
to X.509/CA infrastructure (if bitcoin stays growing and popular). Also,
alternative PKIs like DNSSEC or the ePassport PKI might be useful. In your
case Mike you aren't really a company, you're trading under your own name,
so signing the key list under your legal identity is really the best
solution. It's just not easily available right now.

[-- Attachment #2: Type: text/html, Size: 3308 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-25 10:45       ` Mike Hearn
  2013-04-25 10:52         ` Mike Hearn
@ 2013-04-25 11:55         ` Timo Hanke
       [not found]         ` <FDF215AE-F9A4-4EE3-BDC9-0A4EF027423A@swipeclock.com>
  2 siblings, 0 replies; 19+ messages in thread
From: Timo Hanke @ 2013-04-25 11:55 UTC (permalink / raw)
  To: Mike Hearn; +Cc: Bitcoin Dev

On Thu, Apr 25, 2013 at 12:45:33PM +0200, Mike Hearn wrote:
>     > That's a pointless goal to try and solve right now, because the SSL
>     > PKI cannot handle compromised web servers and so neither can we (with
>     > v1 of the payments spec).
> 
>     I don't think the OP intended to solve it "right now", i.e. in v1.
> 
>     He differentiated between "most trusted" and "less trusted" keys
>     (certs). So he can clearly live with the SSL PKI being "less trusted"
>     for his purpose.
> 
> 
> Yes, but my point is if the SSL key lives on the web server, and there are CAs
> that issue you certs based on control of a web server at the given domain name
> (there are), then you can simply issue yourself a new SSL cert with whatever
> data in it you want and pose as the merchant.

True, I forgot about that, though we already had discussed this in the
past..

-- 
Timo Hanke
PGP AB967DA8, Key fingerprint = 1EFF 69BC 6FB7 8744 14DB  631D 1BB5 D6E3 AB96 7DA8



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-25 10:45       ` Mike Hearn
@ 2013-04-25 10:52         ` Mike Hearn
  2013-04-25 11:55         ` Timo Hanke
       [not found]         ` <FDF215AE-F9A4-4EE3-BDC9-0A4EF027423A@swipeclock.com>
  2 siblings, 0 replies; 19+ messages in thread
From: Mike Hearn @ 2013-04-25 10:52 UTC (permalink / raw)
  To: timo.hanke; +Cc: Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 1248 bytes --]

>
> So I don't see how you can have a payment request signing key that's safer
> than an SSL key. As Jeremy notes, CAs will not issue you intermediate
> certificates. Perhaps if one existed that would do the necessary things for
> a reasonable price you could indeed give yourself an offline intermediate
> cert and then use that to sign one cert for SSL and another for payment
> request signing, but as far as anyone is aware no such CA exists.
>

Re-reading what I wrote, it's not really clear.

Even if possible, the intermediate cert setup still wouldn't work for most
merchants but I didn't make that clear. It might work for EV certs. For
most sites that are just DV there's nothing you can do because CA
verification is just "do you control this domain name". So if your web
server is compromised it's game over. They can issue themselves a new cert,
and what's more, unless wallets are checking revocation lists you can't
stop them signing as you until their certificate expires.

The process for getting an EV cert is harder and there, an offline
restricted intermediate cert might make more sense because you could have a
compromised SSL key whilst not having a compromised identity, but it's
still not possible with todays CA policies.

[-- Attachment #2: Type: text/html, Size: 1695 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-25 10:28     ` Timo Hanke
@ 2013-04-25 10:45       ` Mike Hearn
  2013-04-25 10:52         ` Mike Hearn
                           ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Mike Hearn @ 2013-04-25 10:45 UTC (permalink / raw)
  To: timo.hanke; +Cc: Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 1436 bytes --]

>
> > That's a pointless goal to try and solve right now, because the SSL
> > PKI cannot handle compromised web servers and so neither can we (with
> > v1 of the payments spec).
>
> I don't think the OP intended to solve it "right now", i.e. in v1.
>
> He differentiated between "most trusted" and "less trusted" keys
> (certs). So he can clearly live with the SSL PKI being "less trusted"
> for his purpose.


Yes, but my point is if the SSL key lives on the web server, and there are
CAs that issue you certs based on control of a web server at the given
domain name (there are), then you can simply issue yourself a new SSL cert
with whatever data in it you want and pose as the merchant.

So I don't see how you can have a payment request signing key that's safer
than an SSL key. As Jeremy notes, CAs will not issue you intermediate
certificates. Perhaps if one existed that would do the necessary things for
a reasonable price you could indeed give yourself an offline intermediate
cert and then use that to sign one cert for SSL and another for payment
request signing, but as far as anyone is aware no such CA exists.

The interesting case is where the thing signing payment requests is less
trusted than the web server. The scenario you're trying to solve is the
inverse - the payment request signing process is more trusted than the web
server. But unless/until the CA landscape changes we don't have a way to
implement that.

[-- Attachment #2: Type: text/html, Size: 1861 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-25 10:05   ` Mike Hearn
@ 2013-04-25 10:28     ` Timo Hanke
  2013-04-25 10:45       ` Mike Hearn
  0 siblings, 1 reply; 19+ messages in thread
From: Timo Hanke @ 2013-04-25 10:28 UTC (permalink / raw)
  To: Mike Hearn; +Cc: Bitcoin Dev

On Thu, Apr 25, 2013 at 12:05:06PM +0200, Mike Hearn wrote:
>     Chaining a custom cert onto the end doesn't work, at least not if your
>     "end" is the SSL cert. Chaining it to the SSL cert defeats the OP's
>     intention of "cold signing", as the SSL private key is usually kept
>     online, therefore can't be used to sign a pubkey that is supposed to stay offline.
i meant:                                              ^whose privkey is supposed to stay offline.

> the goal of all this is not to protect against web server compromise.

> The goal of this is to allow delegation of signing authority without giving the
> delegate the SSL private key.

This is not how I understand the OP, which I said I was addressing:

> The difficulty is that Payment Requests must be generated live, and
> therefore the key used to sign those requests must also be live,
> exposing the key to theft similar to a hot wallet. Steal the key,
> forge payment requests, and the payer sees a 'green box' but the coins
> go to the attacker. The question... is there a way to sign something
> once, with a key kept offline, which verifies the address in the
> Payment Request belongs to the payee?



> That's a pointless goal to try and solve right now, because the SSL
> PKI cannot handle compromised web servers and so neither can we (with
> v1 of the payments spec).

I don't think the OP intended to solve it "right now", i.e. in v1. 

He differentiated between "most trusted" and "less trusted" keys
(certs). So he can clearly live with the SSL PKI being "less trusted"
for his purpose.  

-- 
Timo Hanke
PGP AB967DA8, Key fingerprint = 1EFF 69BC 6FB7 8744 14DB  631D 1BB5 D6E3 AB96 7DA8



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
  2013-04-25  9:58 ` Timo Hanke
@ 2013-04-25 10:05   ` Mike Hearn
  2013-04-25 10:28     ` Timo Hanke
  0 siblings, 1 reply; 19+ messages in thread
From: Mike Hearn @ 2013-04-25 10:05 UTC (permalink / raw)
  To: timo.hanke; +Cc: Bitcoin Dev

[-- Attachment #1: Type: text/plain, Size: 759 bytes --]

> Chaining a custom cert onto the end doesn't work, at least not if your
> "end" is the SSL cert. Chaining it to the SSL cert defeats the OP's
> intention of "cold signing", as the SSL private key is usually kept
> online, therefore can't be used to sign a pubkey that is supposed to
> stay offline.


What you wrote doesn't make any sense to me, sorry.

Yes, SSL private keys are kept online. That's irrelevant - the goal of all
this is not to protect against web server compromise. That's a pointless
goal to try and solve right now, because the SSL PKI cannot handle
compromised web servers and so neither can we (with v1 of the payments
spec).

The goal of this is to allow delegation of signing authority without giving
the delegate the SSL private key.

[-- Attachment #2: Type: text/html, Size: 1136 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [Bitcoin-development] Cold Signing Payment Requests
       [not found] <mailman.38128.1366844895.4905.bitcoin-development@lists.sourceforge.net>
@ 2013-04-25  9:58 ` Timo Hanke
  2013-04-25 10:05   ` Mike Hearn
  0 siblings, 1 reply; 19+ messages in thread
From: Timo Hanke @ 2013-04-25  9:58 UTC (permalink / raw)
  To: bitcoin-development

> So, I'm not a fan of weird hacks involving non-existent domain names.
> There's a clean way to implement this and we decided to punt on it for
> v1 in order to get something shippable, but if you're volunteering ...
> :) then indeed having a custom cert type that chains onto the end is
> the way to go.

Chaining a custom cert onto the end doesn't work, at least not if your
"end" is the SSL cert. Chaining it to the SSL cert defeats the OP's
intention of "cold signing", as the SSL private key is usually kept
online, therefore can't be used to sign a pubkey that is supposed to
stay offline. Hence the idea of the "hack", to get two independent
things signed by the CA in just one cert: 1) your SSL pubkey, 2) your
custom cert (by including its cryptograhic hash). This hack seems the
easiest possible solution.

It also seems the only solution if you want to stick with domain-names
as identifiers for the payment protocol (and I think you do). A cleaner
way would be to get a cert signed by your CA that contains an extended
"bitcoin" attribute in compliance with X.509, but this seems a little
far off.

So I am in favor of the "hack" (properly thought out where to place the
hash).

ps. In the long run I would of course like to see payee identities based
on alt-chains rather than domain-names plus CAs. But that's rather a
concern for v3 than v2. Of course, you can also chain custom certs to
non-SSL identities like PGP-keys. You probably don't want to do that,
but it would solve Melvin Carvalho's problem of sending to RSA keys
(assuming the RSA key holder previously published his custom cert with a
cert server). 

-- 
Timo Hanke
PGP AB967DA8, Key fingerprint = 1EFF 69BC 6FB7 8744 14DB  631D 1BB5 D6E3 AB96 7DA8



^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2013-05-06 21:30 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-04-24 23:01 [Bitcoin-development] Cold Signing Payment Requests Jeremy Spilman
2013-04-24 23:07 ` Alan Reiner
2013-04-25  9:08   ` Mike Hearn
     [not found] <mailman.38128.1366844895.4905.bitcoin-development@lists.sourceforge.net>
2013-04-25  9:58 ` Timo Hanke
2013-04-25 10:05   ` Mike Hearn
2013-04-25 10:28     ` Timo Hanke
2013-04-25 10:45       ` Mike Hearn
2013-04-25 10:52         ` Mike Hearn
2013-04-25 11:55         ` Timo Hanke
     [not found]         ` <FDF215AE-F9A4-4EE3-BDC9-0A4EF027423A@swipeclock.com>
2013-04-25 14:31           ` Mike Hearn
2013-04-25 19:12             ` Jeremy Spilman
2013-04-26  1:07               ` Gavin Andresen
2013-04-28 18:03                 ` Timo Hanke
2013-04-29 18:40                   ` Jeremy Spilman
2013-04-30  9:17                     ` Mike Hearn
2013-04-30 11:32                       ` Jouke Hofman
2013-04-30 13:14                         ` Gavin Andresen
2013-04-30 17:17                           ` Jeremy Spilman
2013-05-06 21:29                             ` Peter Todd

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox