Subject: [Acme] Message Type/Version Identifiers

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

Hi List,
Back in the olden days when XML was king, we used a top-level element + namespace
(some even added a version attribute) to identify a particular message object.

I have "backported" these things to JSON because I think they were good.  A system like
ACME could also use such a scheme since there will undoubtedly be revisions over time.

A real-world example:
https://openkeystore.googlecode.com/svn/resources/trunk/docs/keygen2.html#Sample.KeyCreationResponse

In my particular take on this, the specific @context and @qualifier objects are registered with a
class-factory making the supporting parsing framework return a properly instantiated object of the
associated class as well as automatically rejecting unknown object types.  The framework is only
about 300 lines of java.

Anders

---

From: Martin Thomson <[email-masked]>
Date: Thu, 18 Dec 2014 11:53:24 -0800

> ACME could also use such a scheme since there will undoubtedly be revisions

I can appreciate the attraction, but this is a big "no" for me.
Absence of these features is one of the reasons that JSON has proven
successful over XML.

If you need versioning at that level, I'd recommend defining a content
type instead.

---

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

> If you need versioning at that level, I'd recommend defining a content

The ACME folks have their freedom to select, I just found it quite useful:
https://openkeystore.googlecode.com/svn/wcpp-payment-demo/trunk/docs/messages.html

Anders

---

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

+1

We are doing an IETF spec, not a W3C spec.

I have a lot of experience in using URIs as protocol identifiers, I
originally proposed using them in the PICS spec them and I don't think they
work at all. In the PICS spec the specific objective was to drive a wedge
between the Dworkin/Mackinon supporters of censorship and the Religious
Right supporters. If there had been one control lever they would have been
forced to work together to agree on its use. Giving each their own lever
collapsed their coalition.

In that particular instance it was essential to provide a mechanism that
allowed anyone to fork at any time. So it could not use a protocol registry.

Here we have a Web Service spec and the objective is to end up with a
common spec. So the starting point should be an IANA registration. Since we
are doing Web Services, the obvious registry is the SRV registry. It would
also be rather convenient to have a .well-known default URI.

I see no reason not to use the prefix ACME for both. So initial discovery
would be via SRV record:

_acme._ws.example.com SRV 1 1 443 acmehost.example.com

The host is acmehost.example.com, so the service URI is:

http://acmehost.example.com/.well-known/acme/

That leaves two other questions, one is protocol version and the other is
service feature set. These are independent. There might be a 1.0 service
that supports the issue of both server and client certs and a 3.0 service
that only supports server.

We discussed this earlier, but one of the features many folk have suggested
for the ACME protocol is a mechanism that allows a client to interrogate it
to ask what it supports. I think this can be described as an instance of a
general mechanism that can be copied by other specs.

For versioning, the usual Major.Minor convention works fine.
For feature sets, an IANA registry of text keywords using the RFC20 subset
of UTF8 (as we now refer to US-ASCII).

So I would see a conversation of the following sort:

http/1.1 GET http://acmehost.example.com/.well-known/acme/
.. headers ..

{ "Describe" {} }

Responses might be

{ "Versions" : ["1.0"] }

{ "Versions" :["1.0"],
  "Supports" : [
     {"ACME" : ["Server", "Client"] }] }

{ "Versions" : ["1.0", "2.0"]
  "Supports" : [
     {"ACME" : ["Server"] },
     { "Versions" :["2.0"], "ACME" : ["Server", "Client"] }] }

So the first only supports the default features. The second supports Client
and Server cert issue. The third supports the 2.0 version of the protocol
as well as 1.0 but only supports client cert issue for 2.0.

Specifying the Feature and Version numbers as strings allows for a lot of
flexibility. So for example, a service might support version 1.0 and 3.0
but not 2.0 which turned out to be a doofus version (think X.509v2 certs).

If we do this in a well defined fashion we can eventually push the same
attributes out into the DNS as part of the service registration interface
and publish them via some new RR that is TBS which would allow them to be
used for host selection.

Using the SRV/WKS label for the features tag identifies these as attributes
that would be defined in the ACME registry. this allows for better reuse of
code points in the case that we were to use this for other negotiation
dimensions.

An ACME service that does not support the Describe method would only
support the 0.0 version of the service by definition.

Like the signature scheme outlined earlier, this is a module that can be
reused very easily.

On Thu, Dec 18, 2014 at 2:53 PM, Martin Thomson <[email-masked]>
wrote:
> > I have "backported" these things to JSON because I think they were
> good.  A
> > system like
> > ACME could also use such a scheme since there will undoubtedly be
> revisions
> > over time.
>
> _______________________________________________
> Acme mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/acme
>

---

From: Anders Rundgren <[email-masked]>
Date: Fri, 19 Dec 2014 06:07:18 +0100

Just for the record, service discovery will in your opinion eliminate the
need for explicit version information at the message object level (because this is
really what I'm asking for)?

I prefer URIs but of course traditional minor.major works as well.

Anders

> I have a lot of experience in using URIs as protocol identifiers, I originally proposed using them in the PICS spec them and I don't think they work at all. In the PICS spec the specific objective was to drive a wedge between the Dworkin/Mackinon supporters of censorship and the Religious Right supporters. If there had been one control lever they would have been forced to work together to agree on its use. Giving each their own lever collapsed their coalition.
>
> In that particular instance it was essential to provide a mechanism that allowed anyone to fork at any time. So it could not use a protocol registry.
>
>
> Here we have a Web Service spec and the objective is to end up with a common spec. So the starting point should be an IANA registration. Since we are doing Web Services, the obvious registry is the SRV registry. It would also be rather convenient to have a .well-known default URI.
>
> I see no reason not to use the prefix ACME for both. So initial discovery would be via SRV record:
>
> _acme._ws.example.com <http://ws.example.com> SRV 1 1 443 acmehost.example.com <http://acmehost.example.com>
>
>
> The host is acmehost.example.com <http://acmehost.example.com>, so the service URI is:
>
> That leaves two other questions, one is protocol version and the other is service feature set. These are independent. There might be a 1.0 service that supports the issue of both server and client certs and a 3.0 service that only supports server.
>
> We discussed this earlier, but one of the features many folk have suggested for the ACME protocol is a mechanism that allows a client to interrogate it to ask what it supports. I think this can be described as an instance of a general mechanism that can be copied by other specs.
>
> For feature sets, an IANA registry of text keywords using the RFC20 subset of UTF8 (as we now refer to US-ASCII).
>
>
> So the first only supports the default features. The second supports Client and Server cert issue. The third supports the 2.0 version of the protocol as well as 1.0 but only supports client cert issue for 2.0.
>
> Specifying the Feature and Version numbers as strings allows for a lot of flexibility. So for example, a service might support version 1.0 and 3.0 but not 2.0 which turned out to be a doofus version (think X.509v2 certs).
>
>
> If we do this in a well defined fashion we can eventually push the same attributes out into the DNS as part of the service registration interface and publish them via some new RR that is TBS which would allow them to be used for host selection.
>
> Using the SRV/WKS label for the features tag identifies these as attributes that would be defined in the ACME registry. this allows for better reuse of code points in the case that we were to use this for other negotiation dimensions.
>
>
> An ACME service that does not support the Describe method would only support the 0.0 version of the service by definition.
>
>
> Like the signature scheme outlined earlier, this is a module that can be reused very easily.
>
>
> On Thu, Dec 18, 2014 at 2:53 PM, Martin Thomson <[email-masked] <mailto:[email-masked]>> wrote:
>
>     <[email-masked] <mailto:[email-masked]>> wrote:
>     [email-masked] <mailto:[email-masked]>

---

From: Martin Thomson <[email-masked]>
Date: Fri, 19 Dec 2014 10:12:51 -0800

> I prefer URIs but of course traditional minor.major works as well.

I think that you are both over-engineering it.  Identify this as
"acme".  If you need to make changes that aren't backward compatible,
call it "acmi".

---

From: Richard Barnes <[email-masked]>
Date: Fri, 19 Dec 2014 13:34:13 -0500

On Fri, Dec 19, 2014 at 1:12 PM, Martin Thomson <[email-masked]>
wrote:
> > need for explicit version information at the message object level
> (because
> > this is

And then, "acmii", "acmiii", "acmiv", ...?  :)

I think the idea of separating things by URI is the right track.  That
punts the versioning question to discovery/configuration.

--Richard

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Fri, 19 Dec 2014 13:46:28 -0500

> punts the versioning question to discovery/configuration.

Noooooo

The URI that the Web Service is provided from has no connection to the
unique identifier for the specification.

I am not wedged on the Major.Minor version thing. We could just as easily
use keywords for both and that is a little simpler. We very rarely make
backwards incompatible changes in any case and we don't add features
monotonically so minor version numbers don't add anything that can't be
said in a feature tag.

SMTP has worked fine with a Feature tag approach. We have POP3 and IMAP4.

Whether we structure them as tags or URIs the structure is exactly the
same. The URI is an opaque identifier. Defining semantics on the internal
syntax of a URI is bad juju.

So the difference is

POP3
urn:ietf:service-names-port-numbers:TCP:POP3

The second does not provide anything the first does not. All it does is
make the protocol longer and harder to read.

---

From: Richard Barnes <[email-masked]>
Date: Fri, 19 Dec 2014 14:02:47 -0500

On Fri, Dec 19, 2014 at 1:46 PM, Phillip Hallam-Baker <[email-masked]
>> On Fri, Dec 19, 2014 at 1:12 PM, Martin Thomson <[email-masked]
>> > wrote:
>>>

Yeeeeees :)

You're missing my point.  The version identifier is not in band to the
protocol.

We can define a protocol that says "We assume you have a URL as a starting
point for this protocol."  That URL only has to provide one version of the
protocol, so there's no need for the protocol itself to have a notion of
version.

Then the question is just how you find the URL for the version you want.
That's a question for a separate discovery protocol.

--Richard

---

From: Martin Thomson <[email-masked]>
Date: Fri, 19 Dec 2014 11:28:32 -0800

> That's a question for a separate discovery protocol.

Yes. This.

It is rare that you have a situation where you need to negotiate the
intended protocol in band.  Engineering situations where that is
necessary would be a bad idea.

---

From: "Salz, Rich" <[email-masked]>
Date: Fri, 19 Dec 2014 14:38:35 -0500

> It is rare that you have a situation where you need to negotiate the intended
> protocol in band.  Engineering situations where that is necessary would be a
> bad idea.

Yeah, because it's worked so well with SSL/TLS :)

If you incompatibly rev the protocol you change the URI.  Nothing could be simpler.

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Fri, 19 Dec 2014 14:43:06 -0500

On Fri, Dec 19, 2014 at 2:02 PM, Richard Barnes <[email-masked]> wrote:
>
>
>
> On Fri, Dec 19, 2014 at 1:46 PM, Phillip Hallam-Baker <
> [email-masked]> wrote:
>>
>>
>>
>>> On Fri, Dec 19, 2014 at 1:12 PM, Martin Thomson <
>>> [email-masked]> wrote:
>>>>

Where the version identifier shows up on the wire is secondary to how it is
expressed. I don't mind taking negotiation out of the ACME spec, it is
something that should be common to all JSON services.

If we want to make use of DNS to do service version discover we had
probably best not make the tag any larger than necessary.

As a separate issue, we are going to be signing messages and so there
should be an identifier inside the signed content that specifies the
semantics of what is being signed so as to prevent a downgrade attack,
substitution attack or whatever.

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Fri, 19 Dec 2014 14:46:00 -0500

On Fri, Dec 19, 2014 at 2:38 PM, Salz, Rich <[email-masked]> wrote:
> intended

Please disambiguate the binding of 'you' in that sentence since the first
cannot possibly be the same as the last.

What I think you mean is:

If we, the IETF incompatibly rev the protocol the service provider must use
separate URIs to provide the different versions of the service.

The protocol version identifier is the SRV record prefix and/or the
well-known service prefix.

---

From: "Salz, Rich" <[email-masked]>
Date: Fri, 19 Dec 2014 14:51:44 -0500

> If we, the IETF incompatibly rev the protocol the service provider must use separate URIs to provide the different versions of the service.

Yes.  I expect the RFC will include "reference" URI's.  For example, h2://www.example.org/acme/v1/register

> The protocol version identifier is the SRV record prefix and/or the well-known service prefix.

No opinion expressed on SRV records.  No real interest right now, either :)

--  
Principal Security Engineer, Akamai Technologies
IM: [email-masked] Twitter: RichSalz

---

From: Anders Rundgren <[email-masked]>
Date: Fri, 19 Dec 2014 20:51:42 +0100

On 2014-12-19 20:46, Phillip Hallam-Baker wrote:
[...]
> The protocol version identifier is the SRV record prefix and/or the well-known service prefix.

Why must we mix service discovery with versioning?
Couldn't you search in DNS for a generic ACME service and then from that find out what versions (=URIs) that are actually served?
It would add one level of indirection but this is not a real-time system so I shouldn't matter.

Anders

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Fri, 19 Dec 2014 15:19:23 -0500

On Fri, Dec 19, 2014 at 2:51 PM, Salz, Rich <[email-masked]> wrote:
>
> > If we, the IETF incompatibly rev the protocol the service provider must
> use separate URIs to provide the different versions of the service.
>

That is the cardinal sin I was objecting to. The URI defines the Web
Service end point. It is opaque as far as the Web Service is concerned.

There are some IDs with really long rants on why encoding semantics into
Web Service URLs is a really bad idea.

---

From: Martin Thomson <[email-masked]>
Date: Fri, 19 Dec 2014 12:29:56 -0800

On 19 December 2014 at 12:19, Phillip Hallam-Baker
<[email-masked]> wrote:
> That is the cardinal sin I was objecting to. The URI defines the Web Service
> end point. It is opaque as far as the Web Service is concerned.

"The web service" is a little too squishy to have any concrete meaning.

Do you mean to say that there is some value in identifying the
abstract thing that is "ACME of any version"?  Even when that refers
to multiple, potentially incompatible things?  I mean, yes, you can do
that.  I don't see why you would take on that complexity burden when
"ACME of this particular version" is usually perfectly adequate.

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Fri, 19 Dec 2014 15:56:49 -0500

On Fri, Dec 19, 2014 at 3:29 PM, Martin Thomson <[email-masked]>
wrote:
> Service

The Web-Service-End-Point is the URL at which the Web Service is delivered.
It is a very well defined concept in SOAP lore.

There are three options:

A) A single Web-Service-End-Point can support multiple versions of the
protocol with the client engaging in a two step negotiation for protocol
version [and features]

2) A single Web-Service-End-Point can support multiple versions of the
protocol [the client might negotiate features though], different versions
of the protocol being disambiguated by means of a Version identifier

3) We require that different versions of the protocol have different
Web-Service-End-Points.

I don't think anyone is keen on (1) or (2).

Unfortunately (3) isn't something we can rely on. Consider the following
scenario.

There are two versions of the ACME protocol ACME1 and ACME2, presenting an
ACME2 message to an ACME1 service permits a downgrade attack.

So I think that what we end up having to do is to tell people to do (3) but
design the protocol so bad things don't happen if they do (2).

Even if we don't want to distinguish ACME protocol versions, there is the
possibility that a signed ACME message gets injected into some other
protocol that uses the same signature format.

---

From: Martin Thomson <[email-masked]>
Date: Fri, 19 Dec 2014 15:33:35 -0800

> ACME2 message to an ACME1 service permits a downgrade attack.

I can certainly imagine a case where discovery was subverted in some
fashion, causing the ACME2 client to send a message to an ACME1
endpoint.  If it is the case that the ACME1 endpoint can somehow
produce a response to that message that the ACME2 endpoint will
happily consume, AND that the ACME1 endpoint consequently fails to
take into account some ACME2 features.  An attack might also require
that the ACME2 client also subsequently consumes the ACME1 response.
Yes, that is potentially possible, and we will need to ensure that
this doesn't happen.  A version parameter is one way to achieve that,
yes.

> Even if we don't want to distinguish ACME protocol versions, there is the possibility that a signed ACME message gets injected into some other protocol that uses the same signature format.

Unambiguously identifying the purpose of the signed object within the
object is probably good practice.  That requires more than a mere
version identifier.  I'd prefer that approach.

---

From: Phillip Hallam-Baker <[email-masked]>
Date: Fri, 19 Dec 2014 18:39:50 -0500

On Fri, Dec 19, 2014 at 6:33 PM, Martin Thomson <[email-masked]>
wrote:
> > Even if we don't want to distinguish ACME protocol versions, there is
> the possibility that a signed ACME message gets injected into some other

I think conflating the version with the protocol identifier is the way to
go. We should not need to do an incompatible change so there should not be
a need for a major version number upgrade ever. If there is, an
incompatible protocol should probably be considered a different one.

BTW, we should capture this for reuse in other protocols.

---

From: Richard Barnes <[email-masked]>
Date: Fri, 19 Dec 2014 19:27:06 -0500

> version identifier.  I'd prefer that approach.

"cty": "acme+json"