Tls-alpn-01 "Invalid acmeValidationV1 extension value"

I’m implementing the new challenge in a client, create a self signed certificate with the new ACME Identifier extension, but it is always rejected. From looking at the Boulder code, it seems my new extension is found correctly, but fails at the last stage checking the DER octet string. So no idea what I’m doing wrong:.

“type”: “tls-alpn-01”, “status”: “invalid”, “error”: {
“type”: “urn:ietf:params:acme:error:unauthorized”,
“detail”: “Incorrect validation certificate for tls-alpn-01 challenge. Invalid acmeValidationV1 extension value.”, “status”: 403 },
“token”: “9D5Cx9PPKa-NWQqWX1dhTy9PZ2j3IjXkOKSxXPxy3do”,

OpenSSL dump of the extensions:
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Alternative Name:
DNS:test7.comcap.co.uk
X509v3 ACME Identifier: critical
. .|…GO.8…n…z.m.==…".t…

Dump of the extension DER acmeIdentifier = 04:20:9A:7C:1B:AA:47:4F:E4:38:07:A1:6E:B2:E0:7A:C6:6D:89:3D:3D:C5:84:EA:9E:22:1A:74:BD:A3:97:F1:06:D4

Any suggestions?

Angus

That error message is telling you that the SHA-256 digest of your key authorization was not valid.

keyAuthorization = token || '.' || base64url(Thumbprint(accountKey))

We already know your token, but what is your JWK thumbprint? From that, we can calculate the correct key authorization, digest, and acmeIdentifier extension value.

Thanks, long time since I wrote the older challenges, forgotten about the fingerprint. The ACME-TLS-ALPN draft says only “The acmeIdentifier extension MUST contain the SHA-256 digest [FIPS180-4] of the key authorization [I-D.ietf-acme-acme] for the challenge.” when a reference to section 8.1 of the RFC and/or the line you copied from it, would have saved a lot of wasted time.

Unfortunately, hashing the same key I use for the other two challenges does not seem to work, I still get the same error from Boulder. Maybe my hashing is broken, the http challenge uses clear text, not tested the hashed DNS challenge for a while.

Angus

Has anyone got the tls-alpn-01 challenge to work successfully? I appreciate few web servers support customised ALPN so it is not common. I’ve done more testing against the staging server this time, still fails.

“identifier”: {
“type”: “dns”,
“value”: “test7.comcap.co.uk
},
“status”: “pending”,
“expires”: “2019-07-16T10:06:00Z”,
“challenges”: [
{
“type”: “tls-alpn-01”,
“status”: “pending”,
“url”: “https://acme-staging-v02.api.letsencrypt.org/acme/challenge/pt0cGQet36ISTteJ4pM911hp-U9gF5rUyXDav9Qm-hM/327827668”,
“token”: “c9NUm44fbkNNYsoQd1RtVe6mQlsrGgm8hWcoPcBigkg”
},

keyAuthorization: c9NUm44fbkNNYsoQd1RtVe6mQlsrGgm8hWcoPcBigkg.a5rj97nmHP-zZQWBUFriV3NaiSzS_RiRHO817U-6UuM
Hashed AcmeIdentifier: 716F83157415782346F041648F29F2E92BB3CCA9AFCC6F0353B0531C9155C766, Len=64

    X509v3 extensions:
        X509v3 Basic Constraints: critical
            CA:FALSE
        X509v3 Subject Alternative Name: 
            DNS:test7.comcap.co.uk
        X509v3 ACME Identifier: critical
            . qo..t.x#F.Ad.)..+.....o.S.S..U.f

extension DER acmeIdentifier=04:20:71:6F:83:15:74:15:78:23:46:F0:41:64:8F:29:F2:E9:2B:B3:CC:A9:AF:CC:6F:03:53:B0:53:1C:91:55:C7:66

“type”: “tls-alpn-01”,
“status”: “invalid”,
“error”: {
“type”: “urn:ietf:params:acme:error:unauthorized”,
“detail”: “Incorrect validation certificate for tls-alpn-01 challenge. Invalid acmeValidationV1 extension value.”,
“status”: 403
},
“url”: “https://acme-staging-v02.api.letsencrypt.org/acme/challenge/pt0cGQet36ISTteJ4pM911hp-U9gF5rUyXDav9Qm-hM/327827668”,
“token”: “c9NUm44fbkNNYsoQd1RtVe6mQlsrGgm8hWcoPcBigkg”,

If I repeat the same order with the HTTP challenge, same account and thus same JWK thumbprint, it works OK.

“type”: “http-01”,
“status”: “valid”,
“url”: “https://acme-staging-v02.api.letsencrypt.org/acme/challenge/MQbqr0TZJCu0XP3G48unFyw1gu0IyXbtdcUlN8fugqQ/327829690”,
“token”: “ot0rd4S4XS0TP8YDDupeNdMdPfeJDHVwvSsMJrHIdaw”,

The DNS challenge also works fine so my hashing is okay. It could be a badly formed certificate, I’ve not found any example certificates anywhere with the new extension to compare to my own. I create it with OpenSSL APIs, but those for X509v3 extensions like X509_add_ext are poorly documented so one has to look at sample source code instead.

Angus

I agree that your hashing of the key authorization, and ASN.1 encoded value looks okay.

Can you post the DER/PEM of your generated certificate?

I’m posting two other examples from functional clients for your domain & key authorization.

First is from acme.sh (edit: whoops, I realized after posting that the key-authz from this one, of course, won’t match, but the next one will):

-----BEGIN CERTIFICATE-----
MIIDGzCCAgOgAwIBAgIUcy08aRjsU+c2KgIytE8UK+zfK3EwDQYJKoZIhvcNAQEL
BQAwFjEUMBIGA1UEAwwLdGxzLmFjbWUuc2gwHhcNMTkwNzA5MTEyNTIwWhcNMjAw
NzA4MTEyNTIwWjAWMRQwEgYDVQQDDAt0bHMuYWNtZS5zaDCCASIwDQYJKoZIhvcN
AQEBBQADggEPADCCAQoCggEBAMvOU79SYwKuBXDBcYeoAtpnRX0rra0F+tsw5biM
0MB3dB8iPYY5lV6otp4LLmG675bFdaiiEN9ZfvG8sQlW0o5A1ZNLb9ykNeGf70V/
JqIuI1Ky/uaFvDwzyz0NtdBb4vduJuE+d9vPmCvRDvnWUgt8/r91uYbtjnGKczY1
CtVxsfTHRwGxfRT/Af6bqNStEZ4Xph4rFbq2hUXLG2+ciGzByweqLGVMMrOxTGQp
NnwQOJ9zE//pRaUzmpoKQ9To5Oo9cdP/UoU3rjGYwG5TvVOS9yVrtdyLgD8X3Uxg
ujVU94ZY4O1FfvOXntoLdjPIsiUmOk15FmGjyr9yGjpl34sCAwEAAaNhMF8wCwYD
VR0PBAQDAgXgMB0GA1UdEQQWMBSCEnRlc3Q3LmNvbWNhcC5jby51azAxBggrBgEF
BQcBHwEB/wQiBCBW3C0TzBQ+7rajkM6yJSSmeoG0lNfOeYT65Ezx/FNoKjANBgkq
hkiG9w0BAQsFAAOCAQEAE+5CRtj0JXP6ou+nPYOL8rsuitlKhyyNxS/e4Mvp3O7l
uOh98jty+Xmp8mi0/19cHjdpPqFo+FTdzWvQZvvD/XzSyuuMvAtgTWcwgJ5lNQdo
vdwLOH5zkTTH78Xp24FhxcPqhDS+uq4E8rjaol/wsAMLV/uoAx8TySjcmIjbCmpa
ZkQmX+BlynWrt5pizrB6YQukmEgAQUxXufDHofQGyzAF0uBEwp8nVv2V7ThWBF1Q
1bEaGkfIYICvl52DPppSQDdXXjYy7mdzu7qv1VAWMgnlJbu37GBOtwNkPcERn2zh
a1mg7ZwrjeEVDQ6cxKBgg3aTsCs0mHD3/6Y6T0lduA==
-----END CERTIFICATE-----

Second is generated by /x/crypto/acme:

-----BEGIN CERTIFICATE-----
MIIBsTCCAVigAwIBAgIBATAKBggqhkjOPQQDAjAdMRswGQYDVQQDExJ0ZXN0Ny5j
b21jYXAuY28udWswHhcNMTkwNzA5MTEzNjA4WhcNMTkwNzEwMTEzNjA4WjAdMRsw
GQYDVQQDExJ0ZXN0Ny5jb21jYXAuY28udWswWTATBgcqhkjOPQIBBggqhkjOPQMB
BwNCAASN4u8yX4HfQ4iqcm84WR0lCn2wpMzG7iCF4IZRJELrU6UGfGgsT6nZnNWm
NTtGDCgZldULv72PO/liK4FtNLHFo4GIMIGFMA4GA1UdDwEB/wQEAwIFoDATBgNV
HSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMB0GA1UdEQQWMBSCEnRlc3Q3
LmNvbWNhcC5jby51azAxBggrBgEFBQcBHwEB/wQiBCBxb4MVdBV4I0bwQWSPKfLp
K7PMqa/MbwNTsFMckVXHZjAKBggqhkjOPQQDAgNHADBEAiANp7RN8ccwhIP2q8W9
vDWrXlcACKR4ZHdqmjpLqXNrCAIgXKL/buuasJAiaHYIY9e2f6kVpcEYp405Dcw7
LAQshog=
-----END CERTIFICATE-----

Would be interesting to compare what’s happening in your certificate.

It’s really odd that your challenges for HTTP and DNS succeeded, because the error message from Boulder refers specifically to the extension value being wrong, not anything else. To me, that strongly implies the only place the error could be is in the 04:20:<sha256 digest> … but it seems correct from what you have posted.

1 Like

Thanks, attached is the certificate my tool created, from Delphi. If
it helps, this is all being tested using a Windows executable
standalone application, which is part of an open source internet
library.

http://wiki.overbyte.eu/wiki/index.php/FAQ_Order_SSL_Certificates

If you are using Windows, you can run it locally.

I’ll look at your certificates after lunch, due out at 1pm, now.

Angus

(Attachment alpn-test7_comcap_co_uk.pem is missing)

The certificate got lost last time, here it is:

-----BEGIN CERTIFICATE-----
MIIDHjCCAgagAwIBAgIIP/B1+x/bbb0wDQYJKoZIhvcNAQELBQAwHTEbMBkGA1UE
AwwSdGVzdDcuY29tY2FwLmNvLnVrMB4XDTE5MDcwOTEwMDYwMVoXDTE5MDcxNjEw
MDYwMVowHTEbMBkGA1UEAwwSdGVzdDcuY29tY2FwLmNvLnVrMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqD4cM+rvRE6BSw+ShBlHdTJl6stM8ZnWzVyS
kjgeaEl3l6GwfVklzkboZx3UwkTHSMcIWHVchoHwnTXnPpyGCjU9ahoODw0NBMqg
b7/iVOR6ZvNf/E36xdkw7FEj7LRPMQASnoXSEohdcl7OLkuBmRVhOJPhP2kNgADw
4wAwQP+anlSbiskTBtmN0nugjJsa5+I9UF5dxsKbZgv/EabdTT3FmFjtKmMs5mgv
NAUA51YS8myqct3iKo8Sqr5lN4u3/fpMerBbJiI+WHUHJGg9ASPJadJgaB3SEL2B
SkNv8R9Tuw6OXY+7GTwm30hDEEYGICKd03dyfq3RLqu8R+uc1wIDAQABo2IwYDAM
BgNVHRMBAf8EAjAAMB0GA1UdEQQWMBSCEnRlc3Q3LmNvbWNhcC5jby51azAxBggr
BgEFBQcBHwEB/wQiBCBxb4MVdBV4I0bwQWSPKfLpK7PMqa/MbwNTsFMckVXHZjAN
BgkqhkiG9w0BAQsFAAOCAQEAEurC/UfN2vy/dFZfZ+tCTCET2zi31mqgO1SJ/jDS
jZVZ2qwjvhto1ylZjUneDKvz7qRd1pmalz0W9u9Y5EjAkYkguDzW52fqkpwGs0IT
Nvd2pFz6je1Zhl40Q6G1Tj69VYw1YiMqA3T2chjkJHvNB7eD3yrMBiJQC94WwrTf
WS2qm0QrX7uz1xL9E8c1yObEfnylmpCL8UK+4MVh9j7Q2ZdlRzl8LTxvzLV7Qewa
9y+YTd5mFti/WD1Yn3uyEjyDSSzmllPuPNqe7ux6pxCublveH3q02x8FVJ+tgd4e
2Pnod4ENNK4cXtjW0aqwG1qXz2ablVx/EiiESdwQKXpwyg==
-----END CERTIFICATE-----

Comparing the two certificates above, the /x/crypto/acme: version has an identical extension to my certificate, but the acme.sh is different, as you said.

Both certificates had differing key usage extensions, which I tried adding to my own version, but still same error from Boulder.

Angus

Hi Angus,

Can you try performing TLS-ALPN validation using https://acme-v02.letsdebug.net/directory for your ACME server?

I’ve added some CA-side logging to compare all of the expected/actual key authorization values for that challenge.

1 Like

Thanks, first did a successful http challenge for test7.comcap.co.uk, then a failed alpn challenge for test6.comcap.co.uk with the same account.

The challenge came from:
2019-07-10T10:02:08 Client Connected from Address 45.33.76.145
ALPN Protocols: acme-tls/1, SNI: test6.comcap.co.uk
Checking for tls-alpn-01 challenge Acme SSL certificate

Is there anything more you need from me? As I said yesterday, you can test this yourself, my Windows test tool includes a built in web server to handle challenges at the same time as making them, provided it’s available from public addresses.

Angus

Unfortunately I don’t have access to Windows, but I did take a peek at your Delphi code yesterday. That a lot of it seemed to be totally original work (like the JOSE functions), meaning there’s a lot of places for errors to hide :worried:. But no matter.

So, here is the VA log from the HTTP-01 validation:

I085832 boulder-va [AUDIT] Attempting to validate HTTP-01 for "test7.comcap.co.uk" with GET to "http://test7.comcap.co.uk/.well-known/acme-challenge/IlXys-yWY0bWaOVgZ6PlZSqb-NnOerdGOO1GqI9nmWs"
I085832 boulder-va [AUDIT] Validation result JSON={"ID":"jY_ENfW82W1kG56GHy1dE8gXW6vLlkPZFCinLGJhWEA","Requester":7,"Hostname":"test7.comcap.co.uk","Challenge":{"id":24,"type":"http-01","status":"valid","token":"IlXys-yWY0bWaOVgZ6PlZSqb-NnOerdGOO1GqI9nmWs","keyAuthorization":"IlXys-yWY0bWaOVgZ6PlZSqb-NnOerdGOO1GqI9nmWs.75P6ZfKtKZwN8WVzk29aSA4fubepo3cSOP1rD_oaSjg","validationRecord":[{"url":"http://test7.comcap.co.uk/.well-known/acme-challenge/IlXys-yWY0bWaOVgZ6PlZSqb-NnOerdGOO1GqI9nmWs","hostname":"test7.comcap.co.uk","port":"80","addressesResolved":["217.146.115.85"],"addressUsed":"217.146.115.85"}]},"ValidationLatency":0.266}
I085832 boulder-va Validations: {ID:jY_ENfW82W1kG56GHy1dE8gXW6vLlkPZFCinLGJhWEA Identifier:{Type: Value:} RegistrationID:7 Status: Expires:<nil> Challenges:[] Combinations:[] Wildcard:false V2:false}

Successful, with a key authorization of

IlXys-yWY0bWaOVgZ6PlZSqb-NnOerdGOO1GqI9nmWs.75P6ZfKtKZwN8WVzk29aSA4fubepo3cSOP1rD_oaSjg

So we know that your JWK thumbprint is definitely:

75P6ZfKtKZwN8WVzk29aSA4fubepo3cSOP1rD_oaSjg

and that is correct when we re-generate it from your JWK public key:

{"kty":"RSA","n":"tuNK74nsKfaILJkuHfZpc3u8QfEGneRPRaJ69msDzFHdPhzyKh2pd4EodxkQWgc4eeVp4RgW-mAjpS0RWbX4yuQl41XVOUXY0VwAwO1X7BZ4vnVdU0y322p8hfFzaXh2Mmki6ga2rqMEC96dsaoVKH_Gyd0sLhHcDYSXOcfkIMk07CcOrsYCsAUCGv5t9Or5XU1KlIBmNEnFiDi3E1LYeZYxm5f-4phy7MO2S4Bg32yR7Tgc9EKngzfCTWLC5WiC7kjLk1jAdEIq34u53xTvsCnDDapVw36Y4Ok-l8ZtortgfTNfXSBKrmJz4qqhnE4g9xz7Y4wnzRAHQyZf_l5mlQ","e":"AQAB"}

Moving onto the TLS-ALPN challenge:

I090209 boulder-va [AUDIT] tls-alpn-01 challenge for test6.comcap.co.uk received certificate (1 of 1): cert=[3082032e30820216a00302010202086597eef661eff1ed300d06092a864886f70d01010b0500301d311b301906035504030c1274657374362e636f6d6361702e636f2e756b301e170d3139303731303039303135375a170d3139303731373039303135375a301d311b301906035504030c1274657374362e636f6d6361702e636f2e756b30820122300d06092a864886f70d01010105000382010f003082010a0282010100cf63c026292d698168215513fc3f735629d3630a9c3957cf6b990bc3921de58c0ee1ef35e49400d7aaf3fa4bf2e0205744997418222d5251c320b0006cb8c66e51034b601b74ff0c793ce9a778e3d06bed18290466dbd7a88e589ed720e2a226915124f4c6c8b1095a191518712ffe3c1e9d6c96ff1bfcfe9e207d3aa1e7d37d9aa37011f6d9e36faa713f843c2dadfa0f82b09096825aa88e2577bf81f7f819d06d9b0e39b251b5338b9916fb28bfcd1197c2aa4a63e7b142a03aeddbeccfd58b8ffc3cef9eeeaa3a876ad7e2e2c74d8935daa6e44e45ed7a33b9e7e432156083443516e3249a4567ebf7863ca8e5d6eba93603e236e388bbed7e011aa7ac370203010001a3723070300c0603551d130101ff04023000300e0603551d0f0101ff0404030202e4301d0603551d1104163014821274657374362e636f6d6361702e636f2e756b303106082b0601050507011f0101ff0422042003ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4300d06092a864886f70d01010b050003820101008c4064f352c9109dc0deab2845088e1270a69a782f54ea442d4899be316b39fecd96f8e3a8daac2c41bdb1a8a9602fd2f0ba29a4dbe1706c19499d0ec91612227c1e227e5051e52bcc7db414bdff5f450a4c4f439e47a63933a5a004594902bd9e523df4763e50829eca1f82f50166f25bdbc1b748f370f8a7258cf3359b6816b1e4542c616d49343ebead13140c5cdb520c4941b73c8103aa5d95d024c88694a06a34e7f6e57b99e4d04750c34ae1659056c8aa8fd302ee53cb932ea84b1c0db2f4212eed5d932579248f8ae35b117559667cb5953fe0acc6d4704d8e2f1b48fcee1f4032975c6093eb8b635fe67657fe5c54ec27f68040438ad69a8fa40b54]
I090209 boulder-va Expected key authorization: 1bYr0-Las8Lc6WXQ2KoFNb0JhkYYMW6ARkUJ1miQAX8.75P6ZfKtKZwN8WVzk29aSA4fubepo3cSOP1rD_oaSjg
I090209 boulder-va Expected key authorization hash: 7c861dfb59ff7a1e0cae45ba8d0b180b946b09cde36b413c4df24760e692cddf
I090209 boulder-va Unmarshaled ASN.1 ext value: 03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4
I090209 boulder-va [AUDIT] Validation result JSON={"ID":"430wSHnYbsoSp5_H1bSs3KUzNfxFgMUIWcQX59Pg8o0","Requester":7,"Hostname":"test6.comcap.co.uk","Challenge":{"id":25,"type":"tls-alpn-01","status":"invalid","error":{"type":"unauthorized","detail":"Incorrect validation certificate for tls-alpn-01 challenge. Invalid acmeValidationV1 extension value.","status":403},"token":"1bYr0-Las8Lc6WXQ2KoFNb0JhkYYMW6ARkUJ1miQAX8","keyAuthorization":"1bYr0-Las8Lc6WXQ2KoFNb0JhkYYMW6ARkUJ1miQAX8.75P6ZfKtKZwN8WVzk29aSA4fubepo3cSOP1rD_oaSjg","validationRecord":[{"hostname":"test6.comcap.co.uk","port":"443","addressesResolved":["217.146.115.85"],"addressUsed":"217.146.115.85"}]},"ValidationLatency":0.375,"Error":"unauthorized :: Incorrect validation certificate for tls-alpn-01 challenge. Invalid acmeValidationV1 extension value."}
I090209 boulder-va Validations: {ID:430wSHnYbsoSp5_H1bSs3KUzNfxFgMUIWcQX59Pg8o0 Identifier:{Type: Value:} RegistrationID:7 Status: Expires:<nil> Challenges:[] Combinations:[] Wildcard:false V2:false}

Key authorization should have been (and verifiable by looking at https://acme-v02.letsdebug.net/acme/challenge/430wSHnYbsoSp5_H1bSs3KUzNfxFgMUIWcQX59Pg8o0/25):

1bYr0-Las8Lc6WXQ2KoFNb0JhkYYMW6ARkUJ1miQAX8.75P6ZfKtKZwN8WVzk29aSA4fubepo3cSOP1rD_oaSjg

Which gives us a SHA256 digest of (verifiable with https://play.golang.org/p/iqi4Au92Wr9):

7c861dfb59ff7a1e0cae45ba8d0b180b946b09cde36b413c4df24760e692cddf

but your certificate came with the SHA256 digest of:

03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4

In ASN.1:

491  49:         SEQUENCE {
493   8:           OBJECT IDENTIFIER '1 3 6 1 5 5 7 1 31'
503   1:           BOOLEAN TRUE
506  34:           OCTET STRING, encapsulates {
508  32:             OCTET STRING
      :               03 AC 67 42 16 F3 E1 5C    ..gB...\
      :               76 1E E1 A5 E2 55 F0 67    v....U.g
      :               95 36 23 C8 B3 88 B4 45    .6#....E
      :               9E 13 F9 78 D7 C8 46 F4
      :             }
      :           }

So, question is, how you got to 03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4. I tried a couple of variations to try reverse engineer that digest, but not much luck.

Can you debug what values you used to generate it?

Maybe something weird happening in translation between Delphi strings and C/OpenSSL?

2 Likes

Uhhhh:

$ echo -n 1234 | sha256sum
03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4  -

I think you have some placeholder values left over in your build dude :frowning:

Many thanks, it’s sending the wrong certificate! Bad code.

Before I start the ACME order, I do a local challenge test to my local server to make sure it’s accessible from the internet, using a certificate with a key of 1234, and that certificate is used to start the web server. Once ALPN challenge comes in, the newly created certificate is swapped just like SNI changes, but is clearly failing.

I should double check my local challenge after creating the correct certificate. None of these changes are in SVN yet, not until they are working.

Angus