Parse error reading JWS

Hi,

i'm currently programming a small acme-client in c++ and trying to create a new account with the following content (email is placeholder!):

{
    "alg": "ES384",
    "jwk": {
        "kty": "EC",
        "crv": "P-384",
        "x": "XN9e7Qpq_IxBHsLyKpZ06lNoY0pWe6UR3u8Ap11pz8g",
        "y": "ci1Xcsn1-EjUENpU51urr4wBtFzg7k96Bu8l_nAMUZk"
        },
    "nonce": "010183lVvkLxsFaLZL2meRRNpubBqUZ6HDGqQrPmPYSOLEI",
    "url": "https://acme-v02.api.letsencrypt.org/acme/new-acct"
}
{
    "termsOfServiceAgreed": true,
    "contact": ["mailto:test@example.com"]
}

The final request:

{
    "protected": "ewoiYWxnIjogIkVTMzg0IiwKImp3ayI6IHsKImt0eSI6ICJFQyIsCiJjcnYiOiAiUC0zODQiLAoieCI6ICJYTjllN1FwcV9JeEJIc0x5S3BaMDZsTm9ZMHBXZTZVUjN1OEFwMTFwejhnIiwKInkiOiAiY2kxWGNzbjEtRWpVRU5wVTUxdXJyNHdCdEZ6ZzdrOTZCdThsX25BTVVaayIsCiJ1c2UiOiAic2lnIgp9LAoibm9uY2UiOiAiMDEwMTgzbFZ2a0x4c0ZhTFpMMm1lUlJOcHViQnFVWjZIREdxUXJQbVBZU09MRUkiLAoidXJsIjogImh0dHBzOi8vYWNtZS12MDIuYXBpLmxldHNlbmNyeXB0Lm9yZy9hY21lL25ldy1hY2N0Igp9",
    "payload": "ewoidGVybXNPZlNlcnZpY2VBZ3JlZWQiOiB0cnVlLAoiY29udGFjdCI6IFsibWFpbHRvOnRlc3RAZXhhbXBsZS5jb20iXQp9",
    "signature": "MGQCMHVBEdasr-VnC6la2PUGPU-sNvHLcWq_FYcWrdB385vtf8SwzoKD-uyx4zfsI6DAcQIwZCz5tN_2NRrQYvUmpTzzxmqFGQCsQ4MmW9kiEV63jI6COa7yjqp2bLJoKmDHbUQ5"
}

But i get the following response:

{
  "type": "urn:ietf:params:acme:error:malformed",
  "detail": "Parse error reading JWS",
  "status": 400
}

I write the Client based on the ACME

What am I doing wrong?

The best way to handle this is to write a unit test that will read and decode whatever you write. I also hope you are testing this against Pebble and not the staging environment.

I don't see anything wrong with this from a quick glance. It's not really possible for anyone to debug this unless you share the key (which you shouldn't do) or code for a minimal reproduction (e.g. a SSCCE).

5 Likes

Looking at the url parameter, OP is testing this against the production API........... :sob:

4 Likes

No, i used the staging url all the time.
I just tested it with the active url last time and just forgot to "reset" in code before post.

Hm, i have to try it...
But that's not primarily the problem.

Ok, the parse error was because my x and y-coordinates were wrong.
In my for-loop where i convert the uncompressed hex-code of my public key to bytes (octet-string) a few were "skipped".

The new:

{
    "kty": "EC",
    "crv": "P-384",
    "x": "XB32Xl7dCtau_PjJQTHown8uKqltdN6iU6aGY7ShVqe5pVEV3u79ACp2XUaZz-yK",
    "y": "cgLcVxcoyT9Q-CSL1CEI2iVA52W6q2rwjAATtMXN4L7rT5egBv73JW_pcBDHUbmd"
}

I checked it with JWK to PEM converter and he gives me the correct key.

But now i get a "JWS verification error".
On the EC sign/verify generator with my key pair, base64url-signature and the message (base64url(protected_header) + "." + base64url(payload)) i get "error decoding signature bytes".

Message:

ewoiYWxnIjogIkVTMzg0IiwKImp3ayI6IHsKImt0eSI6ICJFQyIsCiJjcnYiOiAiUC0zODQiLAoieCI6ICJYQjMyWGw3ZEN0YXVfUGpKUVRIb3duOHVLcWx0ZE42aVU2YUdZN1NoVnFlNXBWRVYzdTc5QUNwMlhVYVp6LXlLIiwKInkiOiAiY2dMY1Z4Y295VDlRLUNTTDFDRUkyaVZBNTJXNnEycndqQUFUdE1YTjRMN3JUNWVnQnY3M0pXX3BjQkRIVWJtZCIKfSwKIm5vbmNlIjogIjAwMDJNODh0TTJfVGVGQU5TeFVnQzFGOW16UlVhOHEyYkFESHhDcG9PQTQ2cmo4IiwKInVybCI6ICJodHRwczovL2FjbWUtc3RhZ2luZy12MDIuYXBpLmxldHNlbmNyeXB0Lm9yZy9hY21lL25ldy1hY2N0Igp9.ewoidGVybXNPZlNlcnZpY2VBZ3JlZWQiOiB0cnVlLAoiY29udGFjdCI6IFsibWFpbHRvOnRlc3RAZXhhbXBsZS5jb20iXQp9

Signature:

MGYCMQDl2E7Y1_iwxu67pOF_Xyx78oj1UJsY_3cl7eAGeTrAs7-Zc4tYRaeRwtuZOpZzhWcCMQChbkRgn_y0ZIWyLsG8m_1emT-p72xxRFG7H0mkyJI2OuhGkL3Xzwk1OjCTcgkPPrw

I also tested with openssl:

openssl dgst -sha384 -verify public_key.pem -signature sig.sign sig_part.txt

It gives me "Verified ok"
But in "sig.sign" the signature is raw (not base64url encoded)

It looks like i have an mistake somewhere when converting the signature to base64url...

Edit:
Mh... the following

openssl base64 -in sig.sign -out signature.sha384

gives me the same base64 string (only "+" instead "-")...