Subject: Re: [Acme] ACME signature mechanics

From: Anders Rundgren <[email-masked]>
Date: Tue, 16 Dec 2014 10:22:43 +0100

When the transition to JWS has been made, human-readable ACME messages like

    {
      "type": "certificateRequest",
      "csr": "5jNudRx6Ye4HzKEqT5...FS6aKdZeGsysoCo4H9P",
      "signature": {
        "alg": "RS256",
        "nonce": "h5aYpWVkq-xlJh6cpR-3cw",
        "sig": "KxITJ0rNlfDMAtfDr8eAw...fSSoehDFNZKQKzTZPtQ",
        "jwk": {
          "kty":"RSA",
          "e":"AQAB",
          "n":"KxITJ0rNlfDMAtfDr8eAw...fSSoehDFNZKQKzTZPtQ"
   }  }  }

will rather look like

{
   "payload":"<base64>",
   "protected":"<base64>",
   "header":<base64>,
   "signature":"<base64>"
}

Which apart from being ugly JWS also requires a JSON schema validator (or similar
mechanism) to work on separate, unpacked parts of the message.

Although I don't expect this to change, you may (or may not) want to know that
clear-text JSON signatures (without the complexity of XML DSig), is not black magic,
you only have to use JSON parsers that doesn't "manipulate" input data:
https://openkeystore.googlecode.com/svn/resources/trunk/docs/jcs.html#Sample_Signature

Cheers
AndersR

---

From: Richard Barnes <[email-masked]>
Date: Tue, 16 Dec 2014 11:27:39 -0500

I think there might be a middle way here.  I've been musing about making a
"Content-Signature" header that just carries a JWS signature over the
payload (no HTTP headers).  Since HTTP has to carry the payload bit-exact,
there's no c14n nonsense, so this could be much simpler than other HTTP
signing proposals.  It's sort of like JCS, except that there is actually a
guarantee that the payload stays the same ;)

That said, if your concern is really human readability, I don't think it's
a tragedy to make someone copy/paste into a base64 decoder.

On Tue, Dec 16, 2014 at 4:22 AM, Anders Rundgren <
[email-masked]> wrote:
> _______________________________________________
> Acme mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/acme
>

---

From: Anders Rundgren <[email-masked]>
Date: Wed, 17 Dec 2014 05:53:39 +0100

On 2014-12-16 17:27, Richard Barnes wrote:
> I think there might be a middle way here.  I've been musing about making a "Content-Signature" header that just carries a JWS signature over the payload (no HTTP headers).  Since HTTP has to carry the payload bit-exact, there's no c14n nonsense, so this could be much simpler than other HTTP signing proposals.  It's sort of like JCS, except that there is actually a guarantee that the payload stays the same ;)

I see.  This looks possible but is also a bit of a hack since such signatures can only be verified in a HTTP context.  I would stick to your original JWS transition plan.

BTW, JCS does not depend on any c14n nonsense; it only requires that JSON property order is respected by the serializer/deserializer while whitespace is entirely insignificant.  You can even verify pretty-printed signatures!

>
> That said, if your concern is really human readability, I don't think it's a tragedy to make someone copy/paste into a base64 decoder.

Human readability happens on several levels from documentation to debugging.
That headers and payload are disjunct makes these things slightly less appealing.
It also means that you can't make a unified JSON schema for a message object.

But it surely isn't a show-stopper :-)

For KeyGen2 and my payment related work-items the situation is different since these schemes use multiple and wrapping signatures which JWS doesn't handle in a way that I feel would be acceptable.

If the CSR would be rewritten in JSON, ACME would be in a comparable position...

Cheers,
Anders

>
> On Tue, Dec 16, 2014 at 4:22 AM, Anders Rundgren <[email-masked] <mailto:[email-masked]>> wrote:
>
>     [email-masked] <mailto:[email-masked]>

---

From: Anders Rundgren <[email-masked]>
Date: Wed, 17 Dec 2014 11:07:16 +0100

FWIW, it seems that Python can do JCS with floating point data as the (expected) exception:

import json
import collections

jcs_signed_data = (
'{ '
'  "now": "2014-12-08T10:25:17Z", '
'  "escapeMe": "\\u20ac$\\u000F\\u000aA\'\\u0042\\u0022\\u005c\\\\\\"\\/", '
'  "numbers": [1e0, 4.50, 6], '
'  "signature": '
'    { '
'      "algorithm": "ES256", '
'      "publicKey": '
'        { '
'          "type": "EC", '
'          "curve": "P-256", '
'          "x": "lNxNvAUEE8t7DSQBft93LVSXxKCiVjhbWWfyg023FCk", '
'          "y": "LmTlQxXB3LgZrNLmhOfMaCnDizczC_RfQ6Kx8iNwfFA" '
'        }, '
'      "value": "MEYCIQDGP3HL5aCGaMlgNlqqnPbq-Dhkli4SkfV_ZoGlhGroowIhAPlPhXOsjpPHgQ8E8M-jUQo8lfgO_GRZUJKsg_-u-aJO" '
'    } '
'}'
)

jsonObject = json.loads(jcs_signed_data, object_pairs_hook=collections.OrderedDict)
parsed_signature = json.dumps(jsonObject,separators=(',',':'),ensure_ascii=False)
print parsed_signature
#get all but the signature value
jsonObject['signature'].pop('value')
normalized_result = json.dumps(jsonObject,separators=(',',':'),ensure_ascii=False)
print normalized_result

expected_result_adjusted_for_FP = (
u'{"now":"2014-12-08T10:25:17Z","escapeMe":"\u20ac$\\u000f\\nA\'B\\"\\\\\\\\\\"/","numbers":[1.0,4.5,6],"signature":'
u'{"algorithm":"ES256","publicKey":{"type":"EC","curve":"P-256","x":"lNxNvAUEE8t7DSQBft93LVSXxKCiVjhbWW'
u'fyg023FCk","y":"LmTlQxXB3LgZrNLmhOfMaCnDizczC_RfQ6Kx8iNwfFA"}}}'
)

print expected_result_adjusted_for_FP == normalized_result

---

From: Nico Williams <[email-masked]>
Date: Wed, 17 Dec 2014 10:04:06 -0600

On Wed, Dec 17, 2014 at 05:53:39AM +0100, Anders Rundgren wrote:
> >I think there might be a middle way here.  I've been musing about
> >making a "Content-Signature" header that just carries a JWS signature
> >over the payload (no HTTP headers).  Since HTTP has to carry the
> >payload bit-exact, there's no c14n nonsense, so this could be much
> >simpler than other HTTP signing proposals.  It's sort of like JCS,
> >except that there is actually a guarantee that the payload stays the
> >same ;)
> 
> [...]
> 
> BTW, JCS does not depend on any c14n nonsense; it only requires that
> JSON property order is respected by the serializer/deserializer while
> whitespace is entirely insignificant.  You can even verify
> pretty-printed signatures!

You lost me.  If whitespace is insignificant, then you must be
canonicalizing.  Also, I assume you mean object name order by "property
order", but this is not required to be preserved by JSON parsers.

> >That said, if your concern is really human readability, I don't think
> >it's a tragedy to make someone copy/paste into a base64 decoder.

I don't either.

Nico
--

---

From: Nico Williams <[email-masked]>
Date: Wed, 17 Dec 2014 10:05:00 -0600

> FWIW, it seems that Python can do JCS with floating point data as the

JSON parsers are not required to preserve number form.

Nico
--

---

From: Anders Rundgren <[email-masked]>
Date: Wed, 17 Dec 2014 17:38:42 +0100

> JSON parsers are not required to preserve number form.

Correct.  That's hardly a problem since many real-world JSON-using applications
must anyway "emulate" missing JS number features like big decimals for money
and certificate serial numbers for PKI:
https://openkeystore.googlecode.com/svn/resources/trunk/docs/keygen2.html#Data_Types

Anders

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Wed, 17 Dec 2014 12:02:10 -0500

> a tragedy to make someone copy/paste into a base64 decoder.

I do. If we are going to write protocols that can't be easily interpreted
in wireline form then why not go binary with JSON-B, CBOR or what have you.

I like the idea of using a header like container for the signature. It
makes good architectural sense and it is easy to code. A signature is
logically meta-data and so it should be expressed as a header.

I don't see any value in the 'protected' or 'header' slots. They just
confuse the issue. We should have ONE JSON blob that has all the data that
we need and sigh that. All the data that is the case shall be signed and
any data that is not signed shall be ignored.

So the running example would be written thus:

Signature: alg=RS256; nonce=h5aYpWVkq-xlJh6cpR-3cw;
sig=KxITJ0rNlfDMAtfDr8eAw...fSSoehDFNZKQKzTZPtQ; KeyID=???TBS

 { "certificateRequest" : {
     "csr": "5jNudRx6Ye4HzKEqT5...FS6aKdZeGsysoCo4H9P",
  }  }

The "certificateRequest" object contains exactly the sequence of octets
that is signed. No moving bits round, no splicing, no complications at all.
What is in the signature scope and what is not is clear and unambiguous.

The only objection I can see to this approach is that it makes JOSE pretty
much redundant.

That does leave two open issues to be decided though:

1 Should the signature header be part of the HTTP header or the payload?
2 How to encode the KeyID?

I have a marginal preference for making the signature header part of the
HTTP header because that is how most Web servers and support libraries are
designed to work. They make it really easy to pull data out of a header. On
many platforms the RFC822 tag value pairs are automatically mapped to
corresponding data structures.

There is an argument for making the signature part of the payload though.
It is not a HTTP protocol header, it is content metadata and these should
have always been kept separate.

The second one is a little bit more subtle as we definitely need a way to
identify which key is used and I don't like the way it is done in the
example because we end up specifying the key twice and relying on some
party to check they are the same. There lies the path to tears, weeping and
gnashing of teeth.

I would rather make the KeyID implicit in the case and require the
application to ferret it out from whatever CSR type object it is using. It
would be perfectly OK in my view to define a parallel JSON structure to
allow an all-JSON certificate issue path as an alternative to PKCS#10. It
would also be OK to use a combination of both to allow additional
information to be provided. But presenting security critical information
through redundant paths without a means of forcing cross checking is a bad
plan.

---

From: Nico Williams <[email-masked]>
Date: Wed, 17 Dec 2014 11:19:20 -0600

> in wireline form then why not go binary with JSON-B, CBOR or what have you.

Well, it does mean having to implement one of those...

> any data that is not signed shall be ignored.

I'd rather have the signature in a JSON text and the signed text encoded
as a string in the same text as bears the signature.

> The only objection I can see to this approach is that it makes JOSE pretty

And that it uses new headers.

> 1 Should the signature header be part of the HTTP header or the payload?

The payload.  And then you've created a new MIME type.

> corresponding data structures.

I'd rather it be in the payload because then you have less dependence on
the transport.  E.g., if you're using an IPC mechanism in your server
implementation, with a less-privileged front-end passing validated
payloads to a more-privileged back-end.

> have always been kept separate.

Exactly.

Nico
--

---

From: Anders Rundgren <[email-masked]>
Date: Wed, 17 Dec 2014 18:27:01 +0100

The "csr" object holds a public key and an associated signature that goes over
the public key and a hypothetical attribute.  This is a bare-bones CSR.

The counter/attestation-signature goes over the entire package.

{
   "type": "certificateRequest",
   "csr":
     {
       "domain": "acme.com",
       "signature":
         {
           "algorithm": "ES256",
           "publicKey":
             {
               "type": "EC",
               "curve": "P-256",
               "x": "vlYxD4dtFJOp1_8_QUcieWCW-4KrLMmFL2rpkY1bQDs",
               "y": "fxEF70yJenP3SPHM9hv-EnvhG6nXr3_S-fDqoj-F6yM"
             },
           "value": "MEUCIF8p4ZY7YGJFaG8X41S-7ZCv...zesjHVc_pUqAa-IcbqefCTR9AvwivtbKA"
         }
     },
   "signature":
     {
       "algorithm": "RS256",
       "certificatePath":
         [
           "MIIETTCCAjWgAwIBAgIGAUoqo740MA0GCS...s9Zi90RyQ7UzWNrQjoLERGLkuetIw",
           "MIIFOjCCAyKgAwIBAgIBATANBgkqhkiG9w...O4Zfwjxug_CkeRb2m2sKaBNgCpJig"
         ],
       "value": "EmEcktZ2gyG639-vzCf_3b3A6CF8N_...gXLy-zDCUnXVv_P7kqkJlABNgnNRbeLmtFgw"
     }
}

---

From: Trevor Freeman <[email-masked]>
Date: Wed, 17 Dec 2014 11:53:44 -0800

Hi Richard,

There is an alternative to using PKCS#10 as the CSR structure. The ACME request is using TLS as a transport. You could use the client certificate portion of TLS to send an X.509 certificate containing the ACME client public key to the ACME server. All the data the ACME server needs is in the X.509 structure. You can sign the X.509 certificate containing the leaf certificate with the authorization public key in the normal X.509 way.  There is just as much X.509 certificate creation code out there as pkcs#10 creation code so I don’t see that as a big issue. An upside to this is you also get a meaningful POP in that the ACME client submitting the request has to use the private key as part of the TLS negotiation which is a better proof they actually have the private key. Also all of the ASN.1 structures and the signatures for the request would be part of the TLS protocol. 

Trevor

From: Acme [mailto:[email-masked]] On Behalf Of Phillip Hallam-Baker
Sent: Wednesday, December 17, 2014 9:02 AM
To: Richard Barnes
Cc: [email-masked]; Anders Rundgren
Subject: Re: [Acme] ACME signature mechanics

I do. If we are going to write protocols that can't be easily interpreted in wireline form then why not go binary with JSON-B, CBOR or what have you.

I like the idea of using a header like container for the signature. It makes good architectural sense and it is easy to code. A signature is logically meta-data and so it should be expressed as a header.

I don't see any value in the 'protected' or 'header' slots. They just confuse the issue. We should have ONE JSON blob that has all the data that we need and sigh that. All the data that is the case shall be signed and any data that is not signed shall be ignored.

 

Signature: alg=RS256; nonce=h5aYpWVkq-xlJh6cpR-3cw; sig=KxITJ0rNlfDMAtfDr8eAw...fSSoehDFNZKQKzTZPtQ; KeyID=???TBS

The "certificateRequest" object contains exactly the sequence of octets that is signed. No moving bits round, no splicing, no complications at all. What is in the signature scope and what is not is clear and unambiguous.

The only objection I can see to this approach is that it makes JOSE pretty much redundant.

 

I have a marginal preference for making the signature header part of the HTTP header because that is how most Web servers and support libraries are designed to work. They make it really easy to pull data out of a header. On many platforms the RFC822 tag value pairs are automatically mapped to corresponding data structures.

There is an argument for making the signature part of the payload though. It is not a HTTP protocol header, it is content metadata and these should have always been kept separate.

The second one is a little bit more subtle as we definitely need a way to identify which key is used and I don't like the way it is done in the example because we end up specifying the key twice and relying on some party to check they are the same. There lies the path to tears, weeping and gnashing of teeth.

I would rather make the KeyID implicit in the case and require the application to ferret it out from whatever CSR type object it is using. It would be perfectly OK in my view to define a parallel JSON structure to allow an all-JSON certificate issue path as an alternative to PKCS#10. It would also be OK to use a combination of both to allow additional information to be provided. But presenting security critical information through redundant paths without a means of forcing cross checking is a bad plan.

---

From: Martin Thomson <[email-masked]>
Date: Wed, 17 Dec 2014 11:59:56 -0800

I think that there is the kernel of an idea here.  Richard might not
like this, but it does have a certain ring to it:

See:
https://tools.ietf.org/html/draft-thomson-httpbis-cant

Maybe the whole signing thing isn't needed.

The part about the CSR I get.  This isn't just a matter of ensuring
that the right pieces of information traverse the network in the
protocol, it's also about dealing with the toolchain that exists for
generating the certificates.  The CSR is valuable in the sense that it
is input to what is probably an existing process.

On 17 December 2014 at 11:53, Trevor Freeman
<[email-masked]> wrote:
> Hi Richard,
>
>
>
> There is an alternative to using PKCS#10 as the CSR structure. The ACME
> request is using TLS as a transport. You could use the client certificate
> portion of TLS to send an X.509 certificate containing the ACME client
> public key to the ACME server. All the data the ACME server needs is in the
> X.509 structure. You can sign the X.509 certificate containing the leaf
> certificate with the authorization public key in the normal X.509 way.
> There is just as much X.509 certificate creation code out there as pkcs#10
> creation code so I don’t see that as a big issue. An upside to this is you
> also get a meaningful POP in that the ACME client submitting the request has
> to use the private key as part of the TLS negotiation which is a better
> proof they actually have the private key. Also all of the ASN.1 structures
> and the signatures for the request would be part of the TLS protocol.
>
>
>
> Trevor
>
>
>
> That said, if your concern is really human readability, I don't think it's a
> tragedy to make someone copy/paste into a base64 decoder.
>
>
>
> I do. If we are going to write protocols that can't be easily interpreted in
> wireline form then why not go binary with JSON-B, CBOR or what have you.
>
>
>
> I like the idea of using a header like container for the signature. It makes
> good architectural sense and it is easy to code. A signature is logically
> meta-data and so it should be expressed as a header.
>
>
>
> we need and sigh that. All the data that is the case shall be signed and any
> data that is not signed shall be ignored.
>
>
>
> The "certificateRequest" object contains exactly the sequence of octets that
> is signed. No moving bits round, no splicing, no complications at all. What
> is in the signature scope and what is not is clear and unambiguous.
>
>
>
> There is an argument for making the signature part of the payload though. It
> is not a HTTP protocol header, it is content metadata and these should have
> always been kept separate.
>
>
>
>
>
> example because we end up specifying the key twice and relying on some party
> to check they are the same. There lies the path to tears, weeping and
> gnashing of teeth.
>
>
>

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Wed, 17 Dec 2014 15:17:11 -0500

On Wed, Dec 17, 2014 at 2:53 PM, Trevor Freeman <[email-masked]
> wrote:
> also get a meaningful POP in that the ACME client submitting the request
> has to use the private key as part of the TLS negotiation which is a better
Not in .NET there isn't. Certificate creation is only supported in the C++
stuff.

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Wed, 17 Dec 2014 15:28:27 -0500

> The payload.  And then you've created a new MIME type.

*message/rfc822*

> payloads to a more-privileged back-end.

Well so long as the payload is divided into a header portion and a payload
portion, I am fine.

In fact we could even make both the header and the payload portion JSON
encoded and then just use the JSON list spec to put them both in the same
wrapper. The only hard part here is that we have a sequence of octets and
we need to unambiguously specify exactly where the dividing line is between
them:

{ <header JSON> } CR LF CR LF { <payload JSON> }

I am perfectly happy with any one of the following, or with additional
control characters thrown in to season the pot if you really must. But I am
really insistent that there be exactly one choice:

Header = [ { <header JSON> } ]
Payload = [ CR LF CR LF { <payload JSON> } ]

Header = [ { <header JSON> } CR LF ]
Payload = [  CR LF { <payload JSON> } ]

Header = [ { <header JSON> } CR LF CR LF ]
Payload = [ { <payload JSON> } ]

Header = [ { <header JSON> } WS* ]
Payload = [ { <payload JSON> } ]

The third is consistent with the approach for HTTP, the last is probably
the easiest to implement and is a superset of the third. The only problem
is that then this approach only works for JSON payloads.

---

From: Nico Williams <[email-masked]>
Date: Wed, 17 Dec 2014 16:23:13 -0600

> > The payload.  And then you've created a new MIME type.

I guess that works.

> we need to unambiguously specify exactly where the dividing line is between

Might as well just have a single JSON value wrapping both (or a JSON
text sequence!), but whatever.

Nico
--

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Wed, 17 Dec 2014 17:54:09 -0500

> text sequence!), but whatever.

No, not at all. At every layer in the stack we have a separation of
Header/Payload. And the Payload for one layer contains the Header and
Payload for the one above.

If the architecture was clean we would have this pattern all the way up the
stack. But instead we have rather a lot of places where things are
confused. and intertwingled. HTTP being especially bad as part of the
header is application protocol and part is message content.

Where this becomes a problem is when trying to sign stuff. I want the scope
of the signature to be exactly the scope of the payload. Right now my code
all works on the basis that the payload is the HTTP payload. But I am more
than happy to move to a model where the payload is the message payload.

This has other advantages we could make use of later on. For example, we
could add encryption without problems. Or we could make it a general
metadata prefix for content. Or we could add in slots for content metadata
that tends to get conflated with SMTP or HTTP headers making signature and
encryption harder than needed.

If we try to wrap a JSON object then we are committed to the payload being
JSON and we have two areas of ambiguity in the signature scope, the start
and the end.

Prefixing a signed object with a JSON blob and CRLF is rather simpler.

---

From: Nico Williams <[email-masked]>
Date: Wed, 17 Dec 2014 17:03:15 -0600

> > The payload.  And then you've created a new MIME type.

Wouldn't you need to subtype it?

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Wed, 17 Dec 2014 18:05:34 -0500

> Wouldn't you need to subtype it?

No, not at all. The Content-type field can be ignored completely.

---

From: Trevor Freeman <[email-masked]>
Date: Wed, 17 Dec 2014 23:29:17 -0800

The pkcs#10 is a product of the disconnected state we are trying to fix and was designed to be transport independent.
It works of HTTP, in Windows we used it over RPC and DCOM as well so it achieved its objective such as they were back then.

If we are designing something to run over TLS then we can take advantage of features in the transport such as client auth. PKCS#10 is an input into the request process but it's not the only game in town. In Windows we also use X.509 as an input to the signing process. We could convert a root certificate into a subordinate certificate which freaked a whole bunch of folks out. We use the X.509 certificate to create a degenerate pkcs#10 then signed that with an RA certificate. We could take root certificates like Comodo and Verisign and subordinate them.  All you really need to make this work is a way to encode the public key and parameters using a format which is widely supported and X.509 does just that. The TLS protocol provides the POP for the leaf certificate. If you want to sign the leaf certificate with an authorizing certificate, that too is possible.

-----Original Message-----
From: Acme [mailto:[email-masked]] On Behalf Of Martin Thomson
Sent: Wednesday, December 17, 2014 12:00 PM
To: Trevor Freeman
Cc: Richard Barnes; Phillip Hallam-Baker; [email-masked]; Anders Rundgren
Subject: Re: [Acme] ACME signature mechanics

I think that there is the kernel of an idea here.  Richard might not like this, but it does have a certain ring to it:

See:

The part about the CSR I get.  This isn't just a matter of ensuring that the right pieces of information traverse the network in the protocol, it's also about dealing with the toolchain that exists for generating the certificates.  The CSR is valuable in the sense that it is input to what is probably an existing process.

On 17 December 2014 at 11:53, Trevor Freeman <[email-masked]> wrote:
> Hi Richard,
>
>
>
> There is an alternative to using PKCS#10 as the CSR structure. The 
> ACME request is using TLS as a transport. You could use the client 
> certificate portion of TLS to send an X.509 certificate containing the 
> ACME client public key to the ACME server. All the data the ACME 
> server needs is in the
> X.509 structure. You can sign the X.509 certificate containing the 
> leaf certificate with the authorization public key in the normal X.509 way.
> There is just as much X.509 certificate creation code out there as 
> pkcs#10 creation code so I don’t see that as a big issue. An upside to 
> this is you also get a meaningful POP in that the ACME client 
> submitting the request has to use the private key as part of the TLS 
> negotiation which is a better proof they actually have the private 
> key. Also all of the ASN.1 structures and the signatures for the request would be part of the TLS protocol.
>
>
>
> Trevor
>
>
>
> I do. If we are going to write protocols that can't be easily 
> interpreted in wireline form then why not go binary with JSON-B, CBOR or what have you.
>
>
>
> confuse the issue. We should have ONE JSON blob that has all the data 
> that we need and sigh that. All the data that is the case shall be 
> signed and any data that is not signed shall be ignored.
>
>
>
> The "certificateRequest" object contains exactly the sequence of 
> octets that is signed. No moving bits round, no splicing, no 
> complications at all. What is in the signature scope and what is not is clear and unambiguous.
>
>
>
> I have a marginal preference for making the signature header part of 
> the HTTP header because that is how most Web servers and support 
> libraries are designed to work. They make it really easy to pull data 
> out of a header. On many platforms the RFC822 tag value pairs are 
> automatically mapped to corresponding data structures.
>
>
>
> There is an argument for making the signature part of the payload 
> though. It is not a HTTP protocol header, it is content metadata and 
> these should have always been kept separate.
>
>
>
>
>
> The second one is a little bit more subtle as we definitely need a way 
> to identify which key is used and I don't like the way it is done in 
> the example because we end up specifying the key twice and relying on 
> some party to check they are the same. There lies the path to tears, 
> weeping and gnashing of teeth.
>
>
>
> application to ferret it out from whatever CSR type object it is 
> using. It would be perfectly OK in my view to define a parallel JSON 
> structure to allow an all-JSON certificate issue path as an 
> alternative to PKCS#10. It would also be OK to use a combination of 
> both to allow additional information to be provided. But presenting 
> security critical information through redundant paths without a means 
> of forcing cross checking is a bad plan.
>
>

---

From: Anders Rundgren <[email-masked]>
Date: Thu, 18 Dec 2014 08:54:15 +0100

Having worked with Europe's EAC (e-passport biometric data protection PKI),
which works as described below, I would strongly recommend NOT using HTTPS
client-certificate authentication because it doesn't fit a normal installation
with an external security-proxy.

Anders

---

From: Anders Rundgren <[email-masked]>
Date: Thu, 18 Dec 2014 08:54:21 +0100

Anders

---

From: Anders Rundgren <[email-masked]>
Date: Thu, 18 Dec 2014 09:12:33 +0100

I would recommend playing a bit with JCS before dismissing it:

https://mobilepki.org/jcs

The (IMO...) ultimate ACME solution:
http://www.ietf.org/mail-archive/web/acme/current/msg00127.html

Cheers
Anders

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Thu, 18 Dec 2014 07:33:56 -0500

> with an external security-proxy.

+1

Part of the objective here should be to put the end customer in control by
running their own issue point that is a proxy to a CA or another proxy.
Binding the authentication to the transport means that the proof of
possession can only be verified by the proxy which breaks the model.

On top of which, it is really yucky to implement. The less time spent
traveling unimplemented, unexplored and un-debugged code paths, the better.

Minimal TLS stacks for embedded devices don't typically do client auth. See
'minimal'.

---

From: Hannes Tschofenig <[email-masked]>
Date: Thu, 18 Dec 2014 13:56:59 +0100

Hi Phillip,

this statement caught my attention:

On 12/18/2014 01:33 PM, Phillip Hallam-Baker wrote:
> Minimal TLS stacks for embedded devices don't typically do client auth.
> See 'minimal'.

It depends what devices you are talking about, for what purpose they use
TLS/DTLS, and what the overall design pattern of the device is.

With the work we are doing in other working groups, such as DICE, we are
trying to give guidance on how to use TLS/DTLS for use with  Internet of
Things (=small embedded devices) in an effort to bring more
(standardized) security protocols into those devices.

With that work we are heavily relying on mutual authentication at the
DTLS/TLS level.

Ciao
Hannes

PS: I also don't think that the discussion on this list is relevant to
embedded devices.

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Thu, 18 Dec 2014 08:17:57 -0500

> PS: I also don't think that the discussion on this list is relevant to

Why not?

Support for embedded devices and the cloud is the main forcing function
here. We already have mechanisms that support automated certificate
management, there are dozens. There is little need for these when a
customer only has one cert and no need for standardization unless the
customer has multiple CAs which is very rare except for the very largest
customers.

The best justification for making ACME an IETF standard as opposed to
LetsEncrypt going off and doing their own thing like every CA to date is
that we want to move to an environment where every device uses TLS all the
time. Internet of Things and Cloud computing are the two forcing factors
that make a standardized, automated issue scheme essential.

I want to be able to unpack my Nest thermostat, plug it in and have it grab
a certificate from my local cert issue point as part of the mechanism by
which I grant it access to my home network.

This is an application layer protocol. It should have authentication at the
application layer. The reason TLS client auth isn't very useful is that
client authentication is an application layer concern, not a transport
layer concern.

---

From: Hannes Tschofenig <[email-masked]>
Date: Thu, 18 Dec 2014 14:23:20 +0100

Hi Phillip,

we already have a mechanism for issuing certificates to embedded
devices, namely OMA Lightweight M2M. It is already used today.
That specification is a version of the OMA device management protocol
(which is also widely used) but uses different protocols that are more
suitable for the embedded side, such as CoAP and JSON.

Hence, I doubt that this work is something the IoT community is asking for.

Ciao
Hannes

On 12/18/2014 02:17 PM, Phillip Hallam-Baker wrote:
> 
> 
> On Thu, Dec 18, 2014 at 7:56 AM, Hannes Tschofenig
> <[email-masked] <mailto:[email-masked]>> wrote:
> 
>     Hi Phillip,
> 
> that we want to move to an environment where every device uses TLS all
> the time. Internet of Things and Cloud computing are the two forcing
> factors that make a standardized, automated issue scheme essential. 
> 
> 
> I want to be able to unpack my Nest thermostat, plug it in and have it
> grab a certificate from my local cert issue point as part of the
> mechanism by which I grant it access to my home network.
> 
> This is an application layer protocol. It should have authentication at
> the application layer. The reason TLS client auth isn't very useful is
> that client authentication is an application layer concern, not a
> transport layer concern.
> 
>

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Thu, 18 Dec 2014 09:11:43 -0500

> Hence, I doubt that this work is something the IoT community is asking for.

Is there a pointer to the spec that is publicly accessible?

In the short term that might be the case. But in the longer term IoT is not
going to be a special case of the Internet, it is going to be the Internet.

I think you are making a case for looking at the OMA protocol and deciding
if we can use it.

---

From: Hannes Tschofenig <[email-masked]>
Date: Thu, 18 Dec 2014 15:42:50 +0100

Hi Phillip,

the relevant OMA specification can be found here:
http://openmobilealliance.org/about-oma/work-program/m2m-enablers/
(Click on the 'OMA Lightweight M2M (LWM2M) protocol' for the version for
IoT devices and 'OMA Device Management (DM)' for the stuff that is used
on mobile phones.)

Here is a tutorial:
http://community.arm.com/servlet/JiveServlet/previewBody/8693-102-3-15745/ARM%20OMA%20Lightweight%20M2M%20Tutorial.pdf

When you look through the tutorial then you will see that IoT devices
need more than just credentials (which is why the specification talks a
lot about device management).

Here is open source code:
https://github.com/jvermillard/leshan
https://github.com/01org/liblwm2m

The next interop event will take place in January 2015:
http://openmobilealliance.org/oma-lwm2m-testfest-registration-now-open/

> IoT is not going to be a special case of the Internet

The LWM2M specification re-uses the work from the CORE working group
(including CoAP, and CoAP resource server), DTLS, JSON and many IETF
other specifications.

Still, the needs for provisioning a certificate to a Web server are,
however, different from provisioning a light bulb.

Judging from the abstract of the ACME specification their document is
focused on the Web and nothing else. That's fine (delta the duplication
of already existing work in that area).

Ciao
Hannes

On 12/18/2014 03:11 PM, Phillip Hallam-Baker wrote:
> 
> 
> On Thu, Dec 18, 2014 at 8:23 AM, Hannes Tschofenig
> In the short term that might be the case. But in the longer term IoT is
> not going to be a special case of the Internet, it is going to be the
> Internet.
> 
> I think you are making a case for looking at the OMA protocol and
> deciding if we can use it.
>

---

From: Anders Rundgren <[email-masked]>
Date: Thu, 18 Dec 2014 15:46:45 +0100

On 2014-12-18 15:11, Phillip Hallam-Baker wrote:
>
>
> On Thu, Dec 18, 2014 at 8:23 AM, Hannes Tschofenig <[email-masked] <mailto:[email-masked]>> wrote:
>
>     Hi Phillip,
>
> In the short term that might be the case. But in the longer term IoT is not going to be a special case of the Internet, it is going to be the Internet.
>
> I think you are making a case for looking at the OMA protocol and deciding if we can use it.

I think the key-word here is "managed".  ACME is not a management protocol.

Just to add more confusion, there is another large class of devices which (IMO...)
isn't served by ACME or OMA-DM and that are privately owned mobile computing devices
(phones tablets).  This is what SKS/KeyGen2 is targeting.

So (in principle) we may need three protocols which I guess will leave us with 10 or so :-)

Anders
https://play.google.com/store/apps/details?id=org.webpki.mobile.android

---

From: Trevor Freeman <[email-masked]>
Date: Thu, 18 Dec 2014 10:50:30 -0800

From: Acme [mailto:[email-masked]] On Behalf Of Phillip Hallam-Baker
Sent: Thursday, December 18, 2014 4:34 AM
To: Anders Rundgren
Cc: Richard Barnes; Martin Thomson; [email-masked]; Trevor Freeman
Subject: Re: [Acme] ACME signature mechanics

On Thu, Dec 18, 2014 at 2:54 AM, Anders Rundgren <[email-masked]> wrote:

[TF] Strange, I have worked with similar constraints with cloud based services and this model worked just fine.

+1

Part of the objective here should be to put the end customer in control by running their own issue point that is a proxy to a CA or another proxy. Binding the authentication to the transport means that the proof of possession can only be verified by the proxy which breaks the model.

[TF] If you trust the proxy enough to terminal the TLS then you trust it enough to pass a flag to indicate authentication succeeded

Have you considered what value the POP on a pkcs#10 actually delivers? It does not show the subject submitting the request is the same as the one in control of the key pair. It just proves to the CA the key pair is functional. 

On top of which, it is really yucky to implement. The less time spent traveling unimplemented, unexplored and un-debugged code paths, the better.

Minimal TLS stacks for embedded devices don't typically do client auth. See 'minimal'.

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Thu, 18 Dec 2014 14:24:38 -0500

On Thu, Dec 18, 2014 at 1:50 PM, Trevor Freeman <[email-masked]
> *[TF] If you trust the proxy enough to terminal the TLS then you trust it
> enough to pass a flag to indicate authentication succeeded*
>
> *Have you considered what value the POP on a pkcs#10 actually delivers? It
> does not show the subject submitting the request is the same as the one in
> control of the key pair. It just proves to the CA the key pair is
> functional.*
>

That is really fuzzy argument there Trevor. Who do you mean by 'you'?

In my model there are two parties, the CA and the Subscriber. Both can have
a proxy but the proxy is trusted by exactly one party. A proxy deployed by
the subscriber for their convenience is not going to be trustworthy as far
as the CA is concerned for proof of possession purposes.

The only circumstance in which the proxy is trusted by both is where they
are the same party. And that is not the main application for ACME.

If this was a transport layer concern then it would have been added to TLS
as an option in 1995. It is an application layer concern, hence the need
for an application layer spec.

---

From: Anders Rundgren <[email-masked]>
Date: Thu, 18 Dec 2014 20:30:24 +0100

On 2014-12-18 19:50, Trevor Freeman wrote:
>
> *From:*Acme [mailto:[email-masked]] *On Behalf Of *Phillip Hallam-Baker
> *Sent:* Thursday, December 18, 2014 4:34 AM
> *To:* Anders Rundgren
> *Cc:* Richard Barnes; Martin Thomson; [email-masked]; Trevor Freeman
> *Subject:* Re: [Acme] ACME signature mechanics
>
> On Thu, Dec 18, 2014 at 2:54 AM, Anders Rundgren <[email-masked] <mailto:[email-masked]>> wrote:
>
> */[TF] Strange, I have worked with similar constraints with cloud based services and this model worked just fine./*
>

It is possibly that I didn't completely understood the scenario you described but
you also need a trust anchor in the proxy end, don't you?  This seems to not work
with a CSR unless you already have a certificate.

What am I missing here?

> *//*
> *//*
> */[TF] If you trust the proxy enough to terminal the TLS then you trust it enough to pass a flag to indicate authentication succeeded/*
>
> */Have you considered what value the POP on a pkcs#10 actually delivers? It does not show the subject submitting the request is the same as the one in control of the key pair. It just proves to the CA the key pair is functional. /*
>

I agree that the PoP provided by PKCS #10 is essentially useless.
I got the impression that AMCE relies on other data to authenticate the request.

In the proxy systems I have worked with messages were checked for sanity before transferred to the secure world.

Related question:
http://www.ietf.org/mail-archive/web/acme/current/msg00143.html

Anders

---

From: Anders Rundgren <[email-masked]>
Date: Tue, 30 Dec 2014 07:16:33 +0100

Before you bury the ACME semantics in Base64 or settle on a HTTP-based signature
scheme it might be interesting to know that the following 130 lines of Python
represents a fully JCS-compliant RSA and EC signature validator:
https://code.google.com/p/openkeystore/source/browse/python/trunk/src/org/webpki/json/JCSValidator.py

I still haven't tried JCS on .NET but since MSFT is putting the entire foundation
as open source I don't expect this to be a major issue.

BTW, undefined object serialization order isn't exactly as popular as claimed :-)
https://code.google.com/p/v8/issues/detail?id=164

Anders

---

From: Martin Thomson <[email-masked]>
Date: Mon, 29 Dec 2014 22:33:24 -0800

> BTW, undefined object serialization order isn't exactly as popular as

Or you could implement using a map that is secure and end up with a
properly unpredictable enumeration order.

---

From: Anders Rundgren <[email-masked]>
Date: Tue, 30 Dec 2014 07:46:46 +0100

> properly unpredictable enumeration order.

Right.

But by honoring insertion order as the default, everyone get what they want
at the cost of a minor overhead.

A core idea behind JCS is to do as little as is technically possible.

Anders