JSON web signature format for registration object/request

Thanks, @jsha

I’m pretty close to getting it working but thanks for the suggestion. Looking at the go-jose code helps a bit.

Out of interest, is there a reason go-jose has its own encoding functions to strip padding and put it back from base64.URLEncoding instead of using base64.RawURLEncoding?

I think RawURLEncoding may be new in Go 1.5.

Ah that would make sense.

Okay so it looks like I need to use my recipient’s public key?

I’m going give go-jose a go right now actually. Hopefully it will simplify things.

I'm not sure what you mean by this. You'll need to generate a public / private key pair, which you will pass to go-jose for signing your ACME requests.

No sorry I meant that go-jose does this:

for i, recipient := range ctx.recipients {
	protected := &rawHeader{
		Alg: string(recipient.sigAlg),
	}

	if recipient.publicKey != nil {
		protected.Jwk = recipient.publicKey
		protected.Kid = recipient.publicKey.KeyID
	}

So if I don’t use go-jose I would need to do that to create the protected header.

@jsha

In go-jose, JsonWebSignature’s FullSerialize method doesn’t put an unprotected header into the resulting JSON object.

Is the unprotected header necessary?

Nope, it shouldn’t be. You do need to put the pubkey somewhere though. If it’s not in unprotected, it needs to go in protected.

You may also be interested in checking out the lego project, which is a Let’s Encrypt client in Go. It should have working examples you can compare against.

Okay cool no unprotected header. One less thing to worry about is always nice.

When you say “the pubkey” I assume you mean my pubkey. Not the pubkey of the ACME server/CA (i.e. a “recipient”).

Thanks for all your help, by the way. I will check out lego also. :smile:

Yep, that's correct.

From what I can discern, lego echoes the nonces that the server sends. I understand that this is a challenge/response mechanism. Is this a strict one-for-one setup where the client must sign the nonce on the last message it received from the server (or is that a choice lego made)? [edit: Note for future readers: the server supplies nonces with its responses but these clients can request a new nonce each time it POSTs a message to the server by first GETting the /directory path and looking at the Replay-Nonce header. This is more expensive but it simplified the client code and the whole register->request process is still super fast - at least in staging.]

Since the protocol is initiated by the client, does the first message require a nonce? [edit: Okay I see that it does. See above for GETting a nonce from /directory.]

Does a client ever challenge a server to sign a client-generated nonce? [edit: No the client authenticates the server using its existing certificate because of course it does that is the sensible choice]

That looks like just a confusing naming convention, since 'recipients' makes more sense in the context of encrypting with potentially-multiple keys, than when signing with potentially-multiple keys that the sender has. (Unless it's symmetric signing/MAC.)

I thought I’d thank you all again for your help.

In case you’re interested my client is working on staging now. Once it’s more refined and battle tested I’ll see what I can do about open sourcing it. :smile:

Thanks for this article, I understood some parts but not everything, does anybody know of a good executive overview? I am just starting to get into programming so the code parts confused me a bit :slight_smile: