Code Monkey home page Code Monkey logo

acme4j's Introduction

ACME Java Client build status maven central

This is a Java client for the Automatic Certificate Management Environment (ACME) protocol as specified in RFC 8555.

ACME is a protocol that a certificate authority (CA) and an applicant can use to automate the process of verification and certificate issuance.

This Java client helps connecting to an ACME server, and performing all necessary steps to manage certificates.

Features

  • Mature and stable code base. First release was in December 2015!
  • Fully RFC 8555 compliant
  • Supports the http-01, dns-01, and tls-alpn-01 (RFC 8737) challenges
  • Supports RFC 8738 IP identifier validation
  • Supports RFC 8739 short-term automatic certificate renewal (experimental)
  • Supports RFC 8823 for S/MIME certificates (experimental)
  • Supports RFC 9444 for subdomain validation
  • Supports draft-ietf-acme-ari-03 for renewal information (experimental)
  • Easy to use Java API
  • Requires JRE 11 or higher
  • Supports Let's Encrypt, SSL.com, ZeroSSL, and all other CAs that comply with the ACME protocol (RFC 8555). Note that acme4j is an independent project that is not supported or endorsed by any of the CAs.
  • Built with maven, packages available at Maven Central
  • Extensive unit and integration tests
  • Adheres to Semantic Versioning

If you require Java 8 or Android compatibility, you can use acme4j v2 instead. However, v2 is not actively developed anymore and will only receive security fixes.

Dependencies

Usage

Announcements

Follow our Mastodon feed for release notes and other acme4j related news.

Contribute

License

acme4j is open source software. The source code is distributed under the terms of Apache License 2.0.

Donate

If you would like to support my work on acme4j, you can do so on at GitHub Sponsors or at Ko-Fi. Thank you!

Acknowledgements

acme4j's People

Contributors

aarcloudera avatar alexandr-dolgov avatar alexey-anufriev avatar andersgm avatar dependabot[bot] avatar doom369 avatar fergadis avatar ifindthanh avatar kimmerin avatar mcpherrinm avatar mloesch avatar robaman avatar shred avatar sullis avatar thanhsmvn avatar ulfsauer0815 avatar xkr47 avatar zosocanuck avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

acme4j's Issues

Request: add example for using cert in a web server

Sorry, this isn't an issue but a request.

I'm having trouble using the downloaded x509 cert in an embedded undertow web server. Was wondering if it would be possible to add some examples of how to use the certificates once they've been downloaded. The ClientTest example was very useful.

The crux of the issue is that I need to create an SSLContext object for a server. There's plenty of opinion out there on how to do this but so far I've failed to get it working.

[Future Request] Refactoring at Kotlin language

Kotlin is a better Java on JVM language. I love kotlin. I think refactor acme4j at kotlin and do pull request.
If I request changes refactoring at kotlin, is it possible to merge this request?

Problem with private key and netty SslContext

Hello. I've successfully generated certs on staging server using your Test client. However, I'm getting the error when try to use it on my server that uses Netty:

Caused by: java.lang.IllegalArgumentException: File does not contain valid private key: /home/doom369/IdeaProjects/acme4j/domain.key
	at io.netty.handler.ssl.SslContextBuilder.keyManager(SslContextBuilder.java:252)
	at io.netty.handler.ssl.SslContextBuilder.keyManager(SslContextBuilder.java:207)
	at io.netty.handler.ssl.SslContextBuilder.forServer(SslContextBuilder.java:50)
	... 8 more
Caused by: java.security.spec.InvalidKeySpecException: Neither RSA, DSA nor EC worked
	at io.netty.handler.ssl.SslContext.getPrivateKeyFromByteBuffer(SslContext.java:1001)
	at io.netty.handler.ssl.SslContext.toPrivateKey(SslContext.java:970)
	at io.netty.handler.ssl.SslContextBuilder.keyManager(SslContextBuilder.java:250)
	... 12 more
Caused by: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
	at sun.security.ec.ECKeyFactory.engineGeneratePrivate(ECKeyFactory.java:169)
	at java.security.KeyFactory.generatePrivate(KeyFactory.java:372)
	at io.netty.handler.ssl.SslContext.getPrivateKeyFromByteBuffer(SslContext.java:999)
	... 14 more
Caused by: java.security.InvalidKeyException: IOException : algid parse error, not a sequence
	at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:351)
	at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:356)
	at sun.security.ec.ECPrivateKeyImpl.<init>(ECPrivateKeyImpl.java:73)
	at sun.security.ec.ECKeyFactory.implGeneratePrivate(ECKeyFactory.java:237)
	at sun.security.ec.ECKeyFactory.engineGeneratePrivate(ECKeyFactory.java:165)
	... 16 more

Generated private key and cert via certbot works fine:

fullchain.pem
privkey.pem

However, this

domain-chain.crt
domain.key

doesn't.

Could you please advise?

org.shredzone.acme4j.exception.AcmeServerException: JWS verification error

I am using the acme-v2 in a Domino server OSGi plugin ( DOTS )
I am trying to get a certificate using the DNS Challenge. I do not have configured my DNS server, so it is expected that LE cannot verify the challenge.
When I run my code for the first time, a new account is created and everything works as expected, incl. the challenge failure.

Running the code again, I get

org.shredzone.acme4j.exception.AcmeServerException: JWS verification error
	at org.shredzone.acme4j.connector.DefaultConnection.throwAcmeException(DefaultConnection.java:446)
	at org.shredzone.acme4j.connector.DefaultConnection.performRequest(DefaultConnection.java:365)
	at org.shredzone.acme4j.connector.DefaultConnection.sendSignedRequest(DefaultConnection.java:177)
	at org.shredzone.acme4j.connector.DefaultConnection.sendSignedRequest(DefaultConnection.java:162)
	at org.shredzone.acme4j.OrderBuilder.create(OrderBuilder.java:151)
	at de.midpoints.le4d.manager.Le4dManager.orderCertificateUseDNSChallenge(Le4dManager.java:252)
	at de.midpoints.le4d.manager.Le4dManager.process(Le4dManager.java:160)
	at de.midpoints.le4d.manager.Le4dManager.run(Le4dManager.java:119)
	at de.midpoints.le4d.runonstart.Le4d$1.doRun(Le4d.java:44)
	at de.midpoints.le4d.runonstart.Le4d$1.doRun(Le4d.java:39)
	at de.midpoints.le4d.tools.SessionDatabase.runWithSessionAndDatabase(SessionDatabase.java:32)
	at de.midpoints.le4d.runonstart.Le4d.doRun(Le4d.java:39)
	at com.ibm.dots.task.AbstractServerTaskExt.run(AbstractServerTaskExt.java:47)
	at com.ibm.dots.task.JobTaskService$ServiceTaskJob.doRun(JobTaskService.java:137)
	at com.ibm.dots.task.JobTaskService$ServiceTaskJob.run(JobTaskService.java:100)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)

I have stored the information from acct.getLocation() during the first run and use it now to bind the session to the already existing acct.


[162C:0018-1104] 07.01.2018 10:13:47   [DOTS] midpoints.le4d - midpoints.le4d started.
[162C:0018-1104] 07.01.2018 10:13:47   [DOTS] midpoints.le4d - LE4D (c) 2017, V 2.0.0.20180107101218-d9bb306 - started!
[162C:0018-1104] 07.01.2018 10:13:47   [DOTS] midpoints.le4d - Requesting certificates.
[162C:0018-1104] 07.01.2018 10:13:47   [DOTS] midpoints.le4d - Running in staging mode
[162C:0018-1104] 07.01.2018 10:13:47   [DOTS] midpoints.le4d - Using existing account.

This also seems to work.

line 252 in the stack trace corresponds to the following line of code.
Order order = account.newOrder().domains(domains).notBefore(notBefore).notAfter(notAfter).create();

Similar code is being used for HTTP Challenge without any issue.

ACME4Jv2 - java.io.IOException: Invalid keystore format

I try to use pebble for testing, but I cannot establish a connection because of the above error.
Any advice, how this can be fixed?

Here is the complete stacktrace

org.shredzone.acme4j.exception.AcmeNetworkException: Network error
	at org.shredzone.acme4j.connector.DefaultConnection.sendRequest(DefaultConnection.java:152)
	at org.shredzone.acme4j.provider.AbstractAcmeProvider.directory(AbstractAcmeProvider.java:53)
	at org.shredzone.acme4j.Session.readDirectory(Session.java:227)
	at org.shredzone.acme4j.Session.resourceUrl(Session.java:202)
	at org.shredzone.acme4j.AccountBuilder.create(AccountBuilder.java:163)
	at de.midpoints.le4d.manager.Le4dManager.orderCertificateUseDNSChallenge(Le4dManager.java:256)
	at de.midpoints.le4d.manager.Le4dManager.process(Le4dManager.java:163)
	at de.midpoints.le4d.manager.Le4dManager.run(Le4dManager.java:122)
	at de.midpoints.le4d.runonstart.Le4d$1.doRun(Le4d.java:44)
	at de.midpoints.le4d.runonstart.Le4d$1.doRun(Le4d.java:39)
	at de.midpoints.le4d.tools.SessionDatabase.runWithSessionAndDatabase(SessionDatabase.java:32)
	at de.midpoints.le4d.runonstart.Le4d.doRun(Le4d.java:39)
	at com.ibm.dots.task.AbstractServerTaskExt.run(AbstractServerTaskExt.java:47)
	at com.ibm.dots.task.JobTaskService$ServiceTaskJob.doRun(JobTaskService.java:136)
	at com.ibm.dots.task.JobTaskService$ServiceTaskJob.run(JobTaskService.java:99)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: java.io.IOException: Invalid keystore format
	at com.ibm.crypto.provider.JavaKeyStore.engineLoad(Unknown Source)
	at java.security.KeyStore.load(KeyStore.java:1456)
	at org.shredzone.acme4j.provider.pebble.PebbleHttpConnector.createSocketFactory(PebbleHttpConnector.java:57)
	at org.shredzone.acme4j.provider.pebble.PebbleHttpConnector.openConnection(PebbleHttpConnector.java:44)
	at org.shredzone.acme4j.connector.DefaultConnection.sendRequest(DefaultConnection.java:136)
	... 15 more

Linux is CentOS 7

java -version 
openjdk version "1.8.0_151"
OpenJDK Runtime Environment (build 1.8.0_151-b12)
OpenJDK 64-Bit Server VM (build 25.151-b12, mixed mode)

Update:

Domino uses its own JVM

./java -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build pxa6480sr3fp22-20161213_02(SR3 FP22))
IBM J9 VM (build 2.8, JRE 1.8.0 Linux amd64-64 Compressed References 20161209_329148 (JIT enabled, AOT enabled)
J9VM - R28_20161209_1345_B329148
JIT  - tr.r14.java.green_20161207_128946
GC   - R28_20161209_1345_B329148_CMPRSS
J9CL - 20161209_329148)
JCL - 20161213_01 based on Oracle jdk8u111-b14

AcmeException when try to delete an account (HTTP 202: Accepted)

Hello,

I noticed that registration.deactivate() throws an AcmeException :

org.shredzone.acme4j.exception.AcmeException: HTTP 202: Accepted
        at org.shredzone.acme4j.connector.DefaultConnection.throwAcmeException(DefaultConnection.java:359)
        at org.shredzone.acme4j.Registration.deactivate(Registration.java:342)

Here is logs:

14:35:03.544 [main] DEBUG o.s.a.Registration - deactivate
14:35:03.544 [main] DEBUG o.s.a.c.DefaultConnection - POST https://acme-staging.api.letsencrypt.org/acme/reg/528585 with claims: {"resource":"reg","status":"deactivated"}
14:35:03.777 [main] DEBUG o.s.a.c.DefaultConnection - HEADER null: HTTP/1.1 202 Accepted
14:35:03.778 [main] DEBUG o.s.a.c.DefaultConnection - HEADER Server: nginx
14:35:03.778 [main] DEBUG o.s.a.c.DefaultConnection - HEADER Replay-Nonce: 1zzaJPRTDx5pkV_03QPa7nLfINVTX0jyFgKikznRbwQ
14:35:03.778 [main] DEBUG o.s.a.c.DefaultConnection - HEADER Connection: keep-alive
14:35:03.778 [main] DEBUG o.s.a.c.DefaultConnection - HEADER Pragma: no-cache
14:35:03.778 [main] DEBUG o.s.a.c.DefaultConnection - HEADER Boulder-Requester: 528585
14:35:03.778 [main] DEBUG o.s.a.c.DefaultConnection - HEADER Date: Mon, 05 Dec 2016 12:35:03 GMT
14:35:03.778 [main] DEBUG o.s.a.c.DefaultConnection - HEADER Boulder-Request-Id: fa0orevYBC6V-q7aX0uwbRRdkZku5g_FS-djmKKLx-I
14:35:03.778 [main] DEBUG o.s.a.c.DefaultConnection - HEADER Cache-Control: max-age=0, no-cache, no-store
14:35:03.778 [main] DEBUG o.s.a.c.DefaultConnection - HEADER Expires: Mon, 05 Dec 2016 12:35:03 GMT
14:35:03.779 [main] DEBUG o.s.a.c.DefaultConnection - HEADER Content-Length: 643
14:35:03.779 [main] DEBUG o.s.a.c.DefaultConnection - HEADER Link: <https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf>;rel="terms-of-service"
14:35:03.779 [main] DEBUG o.s.a.c.DefaultConnection - HEADER Link: <https://acme-staging.api.letsencrypt.org/acme/new-authz>;rel="next"
14:35:03.779 [main] DEBUG o.s.a.c.DefaultConnection - HEADER Content-Type: application/json
14:35:03.779 [main] DEBUG o.s.a.c.DefaultConnection - Replay Nonce: 1zzaJPRTDx5pkV_03QPa7nLfINVTX0jyFgKikznRbwQ
14:35:03.783 [main] ERROR c.j.a.c.r.DeactivateAccountCommand - Can not deactivate account
org.shredzone.acme4j.exception.AcmeException: HTTP 202: Accepted
        at org.shredzone.acme4j.connector.DefaultConnection.throwAcmeException(DefaultConnection.java:359)

Sincerely,
Alexandr

Proxy

Is it possible to use a proxy at the ACME4J Client V2

Test Proof of Possession challenge

Proof of Possession challenge is implemented, but currently untested. It seems like it is not yet available at Let's Encrypt ACME servers.

[ACME2] : "Failed to read certificate"

Hi,

I am trying to get a certificate using HTTP Challenge, but I am getting an error when acme4j tries to get the certificate

`2018-20-03 12:39:19.267 ERROR - STACK TRACE
org.shredzone.acme4j.exception.AcmeProtocolException: Failed to read certificate
at org.shredzone.acme4j.connector.DefaultConnection.readCertificates(DefaultConnection.java:238)
at org.shredzone.acme4j.Certificate.download(Certificate.java:71)
at org.shredzone.acme4j.Certificate.lazyDownload(Certificate.java:207)
at org.shredzone.acme4j.Certificate.getCertificate(Certificate.java:82)
at de.midpoints.le4d.manager.Le4dManager.downloadCertificate(Le4dManager.java:433)
at de.midpoints.le4d.manager.Le4dManager.orderCertificateUseHTTPChallenge(Le4dManager.java:393)
at de.midpoints.le4d.manager.Le4dManager.process(Le4dManager.java:153)
at de.midpoints.le4d.manager.Le4dManager.run(Le4dManager.java:117)
at de.midpoints.le4d.runonstart.Le4d$1.doRun(Le4d.java:44)
at de.midpoints.le4d.runonstart.Le4d$1.doRun(Le4d.java:39)
at de.midpoints.le4d.tools.SessionDatabase.runWithSessionAndDatabase(SessionDatabase.java:32)
at de.midpoints.le4d.runonstart.Le4d.doRun(Le4d.java:39)
at com.ibm.dots.task.AbstractServerTaskExt.run(AbstractServerTaskExt.java:47)
at com.ibm.dots.task.JobTaskService$ServiceTaskJob.doRun(JobTaskService.java:136)
at com.ibm.dots.task.JobTaskService$ServiceTaskJob.run(JobTaskService.java:99)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Caused by: java.security.cert.CertificateException: Unable to initialize, java.io.IOException: insufficient data
at com.ibm.security.x509.X509CertImpl.(X509CertImpl.java:268)
at com.ibm.crypto.provider.X509Factory.b(Unknown Source)
at com.ibm.crypto.provider.X509Factory.engineGenerateCertificates(Unknown Source)
at java.security.cert.CertificateFactory.generateCertificates(CertificateFactory.java:448)
at org.shredzone.acme4j.connector.DefaultConnection.readCertificates(DefaultConnection.java:232)
... 15 more

`

acme4j debug log is

`2018-20-03 12:39:13.930 DEBUG - create
2018-20-03 12:39:13.930 DEBUG - GET https://acme-staging-v02.api.letsencrypt.org/directory
2018-20-03 12:39:14.377 DEBUG - HEADER X-Frame-Options: DENY
2018-20-03 12:39:14.378 DEBUG - HEADER null: HTTP/1.1 200 OK
2018-20-03 12:39:14.378 DEBUG - HEADER Strict-Transport-Security: max-age=604800
2018-20-03 12:39:14.378 DEBUG - HEADER Cache-Control: max-age=0, no-cache, no-store
2018-20-03 12:39:14.378 DEBUG - HEADER Server: nginx
2018-20-03 12:39:14.378 DEBUG - HEADER Connection: keep-alive
2018-20-03 12:39:14.378 DEBUG - HEADER Pragma: no-cache
2018-20-03 12:39:14.378 DEBUG - HEADER Expires: Tue, 20 Mar 2018 11:39:15 GMT
2018-20-03 12:39:14.378 DEBUG - HEADER Content-Length: 602
2018-20-03 12:39:14.378 DEBUG - HEADER Date: Tue, 20 Mar 2018 11:39:15 GMT
2018-20-03 12:39:14.379 DEBUG - HEADER Content-Type: application/json
2018-20-03 12:39:14.380 DEBUG - Result JSON: {"YE07SnbTCdg":"https://community.letsencrypt.org/t/adding-random-entries-to-the-directory/33417","keyChange":"https://acme-staging-v02.api.letsencrypt.org/acme/key-change","meta":{"termsOfService":"https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf"},"newAccount":"https://acme-staging-v02.api.letsencrypt.org/acme/new-acct","newNonce":"https://acme-staging-v02.api.letsencrypt.org/acme/new-nonce","newOrder":"https://acme-staging-v02.api.letsencrypt.org/acme/new-order","revokeCert":"https://acme-staging-v02.api.letsencrypt.org/acme/revoke-cert"}
2018-20-03 12:39:14.586 DEBUG - Replay Nonce: 4IRlJrfoX6Rfo-8XFutPnsfevjqbK8S0EWfI0sxSQx0
2018-20-03 12:39:14.603 DEBUG - POST https://acme-staging-v02.api.letsencrypt.org/acme/new-acct
2018-20-03 12:39:14.603 DEBUG - Payload: {"termsOfServiceAgreed":true}
2018-20-03 12:39:14.604 DEBUG - JWS Header: {"nonce":"4IRlJrfoX6Rfo-8XFutPnsfevjqbK8S0EWfI0sxSQx0","url":"https://acme-staging-v02.api.letsencrypt.org/acme/new-acct","jwk":{"kty":"RSA","n":"nEyrDMS6lgYZq-rjAa01zcxCKnRM047fyOmGoWua4yBzjNfbMYA5ixBZ4ekSMXSI4mmy07uCFaZhgfhEVJTxcdPPJs7qdSAHctqLrnwPlm9BLYa6traUBVYrKAWu34TZDlgBwOMKqGxKZ-5bHKyD_SW69NnpMObuomVl7JwdPtXGA649TcJcI58Ju7oz6xGADZ3W1Y5YhzsbAvjjeiwP_f1L8_CVFZmpjZNqKsX_C2K0XHLFM9LMw-7rW_82nyXKLB9wt5q5cyphYVLmv83EC18AEYM8DdLkuIVYkqJp7_EXB3kz4VMtyasudNx3eyIgFcEhV4Tg8MTZGJnUbCPh4Q","e":"AQAB"},"alg":"RS256"}
2018-20-03 12:39:15.126 DEBUG - HEADER X-Frame-Options: DENY
2018-20-03 12:39:15.126 DEBUG - HEADER null: HTTP/1.1 200 OK
2018-20-03 12:39:15.126 DEBUG - HEADER Strict-Transport-Security: max-age=604800
2018-20-03 12:39:15.126 DEBUG - HEADER Cache-Control: max-age=0, no-cache, no-store
2018-20-03 12:39:15.126 DEBUG - HEADER Server: nginx
2018-20-03 12:39:15.127 DEBUG - HEADER Replay-Nonce: Anrg65O8QkEP-HxyurbIk-5buWkF6CTSWNLpEdLZIfM
2018-20-03 12:39:15.127 DEBUG - HEADER Connection: keep-alive
2018-20-03 12:39:15.127 DEBUG - HEADER Pragma: no-cache
2018-20-03 12:39:15.127 DEBUG - HEADER Expires: Tue, 20 Mar 2018 11:39:15 GMT
2018-20-03 12:39:15.128 DEBUG - HEADER Content-Length: 0
2018-20-03 12:39:15.128 DEBUG - HEADER Date: Tue, 20 Mar 2018 11:39:15 GMT
2018-20-03 12:39:15.128 DEBUG - HEADER Location: https://acme-staging-v02.api.letsencrypt.org/acme/acct/5773622
2018-20-03 12:39:15.128 DEBUG - Replay Nonce: Anrg65O8QkEP-HxyurbIk-5buWkF6CTSWNLpEdLZIfM
2018-20-03 12:39:15.128 DEBUG - Location: https://acme-staging-v02.api.letsencrypt.org/acme/acct/5773622
2018-20-03 12:39:15.131 DEBUG - create
2018-20-03 12:39:15.146 DEBUG - POST https://acme-staging-v02.api.letsencrypt.org/acme/new-order
2018-20-03 12:39:15.146 DEBUG - Payload: {"identifiers":[{"type":"dns","value":"midpoints.spdns.de"}]}
2018-20-03 12:39:15.146 DEBUG - JWS Header: {"nonce":"Anrg65O8QkEP-HxyurbIk-5buWkF6CTSWNLpEdLZIfM","url":"https://acme-staging-v02.api.letsencrypt.org/acme/new-order","kid":"https://acme-staging-v02.api.letsencrypt.org/acme/acct/5773622","alg":"RS256"}
2018-20-03 12:39:15.368 DEBUG - HEADER null: HTTP/1.1 201 Created
2018-20-03 12:39:15.368 DEBUG - HEADER Server: nginx
2018-20-03 12:39:15.368 DEBUG - HEADER Replay-Nonce: FOE7hbGJHhr1e0VwdJQU_9iIACM9xzncgkeyeEGiD74
2018-20-03 12:39:15.368 DEBUG - HEADER Connection: keep-alive
2018-20-03 12:39:15.368 DEBUG - HEADER Pragma: no-cache
2018-20-03 12:39:15.368 DEBUG - HEADER Boulder-Requester: 5773622
2018-20-03 12:39:15.368 DEBUG - HEADER Date: Tue, 20 Mar 2018 11:39:16 GMT
2018-20-03 12:39:15.368 DEBUG - HEADER X-Frame-Options: DENY
2018-20-03 12:39:15.368 DEBUG - HEADER Strict-Transport-Security: max-age=604800
2018-20-03 12:39:15.369 DEBUG - HEADER Cache-Control: max-age=0, no-cache, no-store
2018-20-03 12:39:15.369 DEBUG - HEADER Expires: Tue, 20 Mar 2018 11:39:16 GMT
2018-20-03 12:39:15.369 DEBUG - HEADER Content-Length: 389
2018-20-03 12:39:15.369 DEBUG - HEADER Location: https://acme-staging-v02.api.letsencrypt.org/acme/order/5773622/100976
2018-20-03 12:39:15.369 DEBUG - HEADER Content-Type: application/json
2018-20-03 12:39:15.369 DEBUG - Replay Nonce: FOE7hbGJHhr1e0VwdJQU_9iIACM9xzncgkeyeEGiD74
2018-20-03 12:39:15.369 DEBUG - Location: https://acme-staging-v02.api.letsencrypt.org/acme/order/5773622/100976
2018-20-03 12:39:15.370 DEBUG - Result JSON: {"status":"pending","expires":"2018-03-27T11:39:16.150341542Z","identifiers":[{"type":"dns","value":"midpoints.spdns.de"}],"authorizations":["https://acme-staging-v02.api.letsencrypt.org/acme/authz/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k"],"finalize":"https://acme-staging-v02.api.letsencrypt.org/acme/finalize/5773622/100976"}
2018-20-03 12:39:15.370 DEBUG - update Authorization
2018-20-03 12:39:15.370 DEBUG - GET https://acme-staging-v02.api.letsencrypt.org/acme/authz/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k
2018-20-03 12:39:15.577 DEBUG - HEADER X-Frame-Options: DENY
2018-20-03 12:39:15.577 DEBUG - HEADER null: HTTP/1.1 200 OK
2018-20-03 12:39:15.578 DEBUG - HEADER Strict-Transport-Security: max-age=604800
2018-20-03 12:39:15.578 DEBUG - HEADER Cache-Control: max-age=0, no-cache, no-store
2018-20-03 12:39:15.578 DEBUG - HEADER Server: nginx
2018-20-03 12:39:15.578 DEBUG - HEADER Connection: keep-alive
2018-20-03 12:39:15.578 DEBUG - HEADER Pragma: no-cache
2018-20-03 12:39:15.578 DEBUG - HEADER Expires: Tue, 20 Mar 2018 11:39:16 GMT
2018-20-03 12:39:15.578 DEBUG - HEADER Content-Length: 1024
2018-20-03 12:39:15.578 DEBUG - HEADER Date: Tue, 20 Mar 2018 11:39:16 GMT
2018-20-03 12:39:15.578 DEBUG - HEADER Content-Type: application/json
2018-20-03 12:39:15.579 DEBUG - Result JSON: {"identifier":{"type":"dns","value":"midpoints.spdns.de"},"status":"valid","expires":"2018-04-19T11:24:36Z","challenges":[{"type":"dns-01","status":"pending","url":"https://acme-staging-v02.api.letsencrypt.org/acme/challenge/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k/110722823","token":"updkWCZbQyc3NpzvP-dI0oEs-Wh_7UnfreK2POo7J6Q"},{"type":"http-01","status":"valid","url":"https://acme-staging-v02.api.letsencrypt.org/acme/challenge/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k/110722824","token":"0CYdp5GTuu0OnBOLcgGaRgExJ0SR22d8omq8VteAyeE","validationRecord":[{"url":"http://midpoints.spdns.de/.well-known/acme-challenge/0CYdp5GTuu0OnBOLcgGaRgExJ0SR22d8omq8VteAyeE","hostname":"midpoints.spdns.de","port":"80","addressesResolved":["77.181.49.159"],"addressUsed":"77.181.49.159"}]}]}
2018-20-03 12:39:15.583 DEBUG - trigger
2018-20-03 12:39:15.597 DEBUG - POST https://acme-staging-v02.api.letsencrypt.org/acme/challenge/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k/110722824
2018-20-03 12:39:15.597 DEBUG - Payload: {"keyAuthorization":"0CYdp5GTuu0OnBOLcgGaRgExJ0SR22d8omq8VteAyeE.VB46BE0-T0pno9z28EzVrXQIHdXyUyX9qwIVUqtMTs8"}
2018-20-03 12:39:15.597 DEBUG - JWS Header: {"nonce":"FOE7hbGJHhr1e0VwdJQU_9iIACM9xzncgkeyeEGiD74","url":"https://acme-staging-v02.api.letsencrypt.org/acme/challenge/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k/110722824","kid":"https://acme-staging-v02.api.letsencrypt.org/acme/acct/5773622","alg":"RS256"}
2018-20-03 12:39:15.809 DEBUG - HEADER null: HTTP/1.1 200 OK
2018-20-03 12:39:15.809 DEBUG - HEADER Server: nginx
2018-20-03 12:39:15.809 DEBUG - HEADER Replay-Nonce: vErta0Lg5ORtL4WaNP1_HmHmJFEyUkF6OHU9YtMeMtc
2018-20-03 12:39:15.809 DEBUG - HEADER Connection: keep-alive
2018-20-03 12:39:15.809 DEBUG - HEADER Pragma: no-cache
2018-20-03 12:39:15.809 DEBUG - HEADER Boulder-Requester: 5773622
2018-20-03 12:39:15.809 DEBUG - HEADER Date: Tue, 20 Mar 2018 11:39:16 GMT
2018-20-03 12:39:15.810 DEBUG - HEADER X-Frame-Options: DENY
2018-20-03 12:39:15.810 DEBUG - HEADER Strict-Transport-Security: max-age=604800
2018-20-03 12:39:15.810 DEBUG - HEADER Cache-Control: max-age=0, no-cache, no-store
2018-20-03 12:39:15.810 DEBUG - HEADER Expires: Tue, 20 Mar 2018 11:39:16 GMT
2018-20-03 12:39:15.810 DEBUG - HEADER Content-Length: 541
2018-20-03 12:39:15.810 DEBUG - HEADER Link: https://acme-staging-v02.api.letsencrypt.org/acme/authz/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k;rel="up"
2018-20-03 12:39:15.810 DEBUG - HEADER Location: https://acme-staging-v02.api.letsencrypt.org/acme/challenge/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k/110722824
2018-20-03 12:39:15.810 DEBUG - HEADER Content-Type: application/json
2018-20-03 12:39:15.810 DEBUG - Replay Nonce: vErta0Lg5ORtL4WaNP1_HmHmJFEyUkF6OHU9YtMeMtc
2018-20-03 12:39:15.811 DEBUG - Result JSON: {"type":"http-01","status":"valid","url":"https://acme-staging-v02.api.letsencrypt.org/acme/challenge/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k/110722824","token":"0CYdp5GTuu0OnBOLcgGaRgExJ0SR22d8omq8VteAyeE","validationRecord":[{"url":"http://midpoints.spdns.de/.well-known/acme-challenge/0CYdp5GTuu0OnBOLcgGaRgExJ0SR22d8omq8VteAyeE","hostname":"midpoints.spdns.de","port":"80","addressesResolved":["77.181.49.159"],"addressUsed":"77.181.49.159"}]}
2018-20-03 12:39:16.813 DEBUG - update Authorization
2018-20-03 12:39:16.813 DEBUG - GET https://acme-staging-v02.api.letsencrypt.org/acme/authz/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k
2018-20-03 12:39:17.026 DEBUG - HEADER X-Frame-Options: DENY
2018-20-03 12:39:17.026 DEBUG - HEADER null: HTTP/1.1 200 OK
2018-20-03 12:39:17.028 DEBUG - HEADER Strict-Transport-Security: max-age=604800
2018-20-03 12:39:17.029 DEBUG - HEADER Cache-Control: max-age=0, no-cache, no-store
2018-20-03 12:39:17.029 DEBUG - HEADER Server: nginx
2018-20-03 12:39:17.029 DEBUG - HEADER Connection: keep-alive
2018-20-03 12:39:17.030 DEBUG - HEADER Pragma: no-cache
2018-20-03 12:39:17.030 DEBUG - HEADER Expires: Tue, 20 Mar 2018 11:39:17 GMT
2018-20-03 12:39:17.031 DEBUG - HEADER Content-Length: 1024
2018-20-03 12:39:17.031 DEBUG - HEADER Date: Tue, 20 Mar 2018 11:39:17 GMT
2018-20-03 12:39:17.031 DEBUG - HEADER Content-Type: application/json
2018-20-03 12:39:17.032 DEBUG - Result JSON: {"identifier":{"type":"dns","value":"midpoints.spdns.de"},"status":"valid","expires":"2018-04-19T11:24:36Z","challenges":[{"type":"dns-01","status":"pending","url":"https://acme-staging-v02.api.letsencrypt.org/acme/challenge/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k/110722823","token":"updkWCZbQyc3NpzvP-dI0oEs-Wh_7UnfreK2POo7J6Q"},{"type":"http-01","status":"valid","url":"https://acme-staging-v02.api.letsencrypt.org/acme/challenge/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k/110722824","token":"0CYdp5GTuu0OnBOLcgGaRgExJ0SR22d8omq8VteAyeE","validationRecord":[{"url":"http://midpoints.spdns.de/.well-known/acme-challenge/0CYdp5GTuu0OnBOLcgGaRgExJ0SR22d8omq8VteAyeE","hostname":"midpoints.spdns.de","port":"80","addressesResolved":["77.181.49.159"],"addressUsed":"77.181.49.159"}]}]}
2018-20-03 12:39:17.053 DEBUG - finalize
2018-20-03 12:39:17.069 DEBUG - POST https://acme-staging-v02.api.letsencrypt.org/acme/finalize/5773622/100976
2018-20-03 12:39:17.070 DEBUG - Payload: {"csr":"MIICkjCCAXoCAQAwHTEbMBkGA1UEAwwSbWlkcG9pbnRzLnNwZG5zLmRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo_ZWeMPtw34K-fcdKdqe5sT9xixBWMbI4cvoQVVyl5vyrVD8KRQjuD_atnu5bAefy5IH9eWdXN_XSyRwIDBBBWvapWBOy-rsOieRdPdrzloKrGR2UXVuWY_xlcfnlTChwVyJlyVUq2FVfW80tLX5pDOsBRkq4Kq3Gqz2Py6tNlPiDvNUo_CcpXfkWFJr1z8MfBQJGLgSGhQ-UCvf8bhmFoEhOc_u9qjGaKkvOe8QLt8JlcD5JW4J_1e-l_-4bsQh7K9zat6gvDxc3zulBbZzswGv9jhJlhB7P8xBRMhwIILMdIVjNU1U4BbyXbp6DJth9lrC9Y4yAMYVOmGRruuJfQIDAQABoDAwLgYJKoZIhvcNAQkOMSEwHzAdBgNVHREEFjAUghJtaWRwb2ludHMuc3BkbnMuZGUwDQYJKoZIhvcNAQELBQADggEBAByTINQjeisbjJZm0t83N70DnK-a4sMcyyuFFdU2ygV105XhOIdkKZID13WIk97autYJrmd8AlA7kDBi4mBlS2SY2ynjkBdWsczrr1ZKe9DlsgM2OXFqHH94MxGpJ4moW7B-M6DktlRQ_H1pmO5lCq8E5GP9XuDPw9mO1cNgFIUCPSBuJl1MRi0FknyJ5J9DdthxZuiPRL3HO-3c121hWP2thKZzZWgdnuS1bTR2LfdH0xnxRRyDoMxMVTxi4wRqVcSVTfDUg2wmOQ66OTJnlEc_NuCT8UXUcLgo9s03k__8Vfcp0_NPjeyE3elUzSkyfCXcvWnIWHM_Jb-TMF8EkHg"}
2018-20-03 12:39:17.070 DEBUG - JWS Header: {"nonce":"vErta0Lg5ORtL4WaNP1_HmHmJFEyUkF6OHU9YtMeMtc","url":"https://acme-staging-v02.api.letsencrypt.org/acme/finalize/5773622/100976","kid":"https://acme-staging-v02.api.letsencrypt.org/acme/acct/5773622","alg":"RS256"}
2018-20-03 12:39:17.583 DEBUG - HEADER null: HTTP/1.1 200 OK
2018-20-03 12:39:17.583 DEBUG - HEADER Server: nginx
2018-20-03 12:39:17.584 DEBUG - HEADER Replay-Nonce: lqRTJbowzMIb5FKpNxR_O1lx2zDI5qbHkl4bhx4jywg
2018-20-03 12:39:17.584 DEBUG - HEADER Connection: keep-alive
2018-20-03 12:39:17.584 DEBUG - HEADER Pragma: no-cache
2018-20-03 12:39:17.584 DEBUG - HEADER Boulder-Requester: 5773622
2018-20-03 12:39:17.585 DEBUG - HEADER Date: Tue, 20 Mar 2018 11:39:18 GMT
2018-20-03 12:39:17.585 DEBUG - HEADER X-Frame-Options: DENY
2018-20-03 12:39:17.585 DEBUG - HEADER Strict-Transport-Security: max-age=604800
2018-20-03 12:39:17.585 DEBUG - HEADER Cache-Control: max-age=0, no-cache, no-store
2018-20-03 12:39:17.585 DEBUG - HEADER Expires: Tue, 20 Mar 2018 11:39:18 GMT
2018-20-03 12:39:17.585 DEBUG - HEADER Content-Length: 489
2018-20-03 12:39:17.585 DEBUG - HEADER Location: https://acme-staging-v02.api.letsencrypt.org/acme/order/5773622/100976
2018-20-03 12:39:17.585 DEBUG - HEADER Content-Type: application/json
2018-20-03 12:39:17.586 DEBUG - Replay Nonce: lqRTJbowzMIb5FKpNxR_O1lx2zDI5qbHkl4bhx4jywg
2018-20-03 12:39:18.586 DEBUG - update Order
2018-20-03 12:39:18.587 DEBUG - GET https://acme-staging-v02.api.letsencrypt.org/acme/order/5773622/100976
2018-20-03 12:39:18.846 DEBUG - HEADER X-Frame-Options: DENY
2018-20-03 12:39:18.846 DEBUG - HEADER null: HTTP/1.1 200 OK
2018-20-03 12:39:18.846 DEBUG - HEADER Strict-Transport-Security: max-age=604800
2018-20-03 12:39:18.846 DEBUG - HEADER Cache-Control: max-age=0, no-cache, no-store
2018-20-03 12:39:18.846 DEBUG - HEADER Server: nginx
2018-20-03 12:39:18.846 DEBUG - HEADER Connection: keep-alive
2018-20-03 12:39:18.846 DEBUG - HEADER Pragma: no-cache
2018-20-03 12:39:18.846 DEBUG - HEADER Expires: Tue, 20 Mar 2018 11:39:19 GMT
2018-20-03 12:39:18.846 DEBUG - HEADER Content-Length: 489
2018-20-03 12:39:18.847 DEBUG - HEADER Date: Tue, 20 Mar 2018 11:39:19 GMT
2018-20-03 12:39:18.847 DEBUG - HEADER Content-Type: application/json
2018-20-03 12:39:18.847 DEBUG - Result JSON: {"status":"valid","expires":"2018-03-27T11:39:16Z","identifiers":[{"type":"dns","value":"midpoints.spdns.de"}],"authorizations":["https://acme-staging-v02.api.letsencrypt.org/acme/authz/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k"],"finalize":"https://acme-staging-v02.api.letsencrypt.org/acme/finalize/5773622/100976","certificate":"https://acme-staging-v02.api.letsencrypt.org/acme/cert/fa9a442da786ee5d87ad37d6dd3bbfac22db"}
2018-20-03 12:39:18.848 DEBUG - update Order
2018-20-03 12:39:18.848 DEBUG - GET https://acme-staging-v02.api.letsencrypt.org/acme/order/5773622/100976
2018-20-03 12:39:19.054 DEBUG - HEADER X-Frame-Options: DENY
2018-20-03 12:39:19.055 DEBUG - HEADER null: HTTP/1.1 200 OK
2018-20-03 12:39:19.055 DEBUG - HEADER Strict-Transport-Security: max-age=604800
2018-20-03 12:39:19.055 DEBUG - HEADER Cache-Control: max-age=0, no-cache, no-store
2018-20-03 12:39:19.055 DEBUG - HEADER Server: nginx
2018-20-03 12:39:19.055 DEBUG - HEADER Connection: keep-alive
2018-20-03 12:39:19.056 DEBUG - HEADER Pragma: no-cache
2018-20-03 12:39:19.056 DEBUG - HEADER Expires: Tue, 20 Mar 2018 11:39:19 GMT
2018-20-03 12:39:19.056 DEBUG - HEADER Content-Length: 489
2018-20-03 12:39:19.056 DEBUG - HEADER Date: Tue, 20 Mar 2018 11:39:19 GMT
2018-20-03 12:39:19.056 DEBUG - HEADER Content-Type: application/json
2018-20-03 12:39:19.057 DEBUG - Result JSON: {"status":"valid","expires":"2018-03-27T11:39:16Z","identifiers":[{"type":"dns","value":"midpoints.spdns.de"}],"authorizations":["https://acme-staging-v02.api.letsencrypt.org/acme/authz/pR283zYndZDx1cfVWQc5PBuPRfBb5ZfsfAq4HGtrj9k"],"finalize":"https://acme-staging-v02.api.letsencrypt.org/acme/finalize/5773622/100976","certificate":"https://acme-staging-v02.api.letsencrypt.org/acme/cert/fa9a442da786ee5d87ad37d6dd3bbfac22db"}
2018-20-03 12:39:19.057 DEBUG - download
2018-20-03 12:39:19.057 DEBUG - GET https://acme-staging-v02.api.letsencrypt.org/acme/cert/fa9a442da786ee5d87ad37d6dd3bbfac22db
2018-20-03 12:39:19.263 DEBUG - HEADER X-Frame-Options: DENY
2018-20-03 12:39:19.263 DEBUG - HEADER null: HTTP/1.1 200 OK
2018-20-03 12:39:19.263 DEBUG - HEADER Strict-Transport-Security: max-age=604800
2018-20-03 12:39:19.264 DEBUG - HEADER Cache-Control: max-age=0, no-cache, no-store
2018-20-03 12:39:19.264 DEBUG - HEADER Server: nginx
2018-20-03 12:39:19.264 DEBUG - HEADER Connection: keep-alive
2018-20-03 12:39:19.264 DEBUG - HEADER Pragma: no-cache
2018-20-03 12:39:19.264 DEBUG - HEADER Expires: Tue, 20 Mar 2018 11:39:20 GMT
2018-20-03 12:39:19.264 DEBUG - HEADER Content-Length: 3798
2018-20-03 12:39:19.264 DEBUG - HEADER Date: Tue, 20 Mar 2018 11:39:20 GMT
2018-20-03 12:39:19.264 DEBUG - HEADER Content-Type: application/pem-certificate-chain

`

Anything, I am missing?

Certificate.downloadChain API improvements

Hi,

Thanks to #16 we have a chance to get the certificate chain.

The issue I am currently experiencing with acme4j v.1.0 that it is not possible to get the full certificate chain in one go.

In order to achieve it, you have to combine the results of two calls:

Another minor problem that it is hard to guess it from the documentation.

It would be convenient to have something like Certificate.html#downloadFullChain providing a really full certificate chain.

From the backward compatibility perspective, changing behaviour of
Certificate.html#downloadChain is not welcome.

Thanks!

How to set tomcat ?

HI,I would like to ask a question.
I got six files(chain.crt,domain.crt,domain.csr,domain.key,domain-chain.crt,user.key) after running "acme4j-example" .
Which files can be used for generating .jks?

j

j

Add "title" member to the Problem object

Field is optional according to 7807, but would still useful:

    /**
     * Returns a short, human-readable summary of the problem type.
     */
    public String getTitle() {
        return problemJson.get("title").asString();
    }

Evaluate "Retry-After" header

If there is a Retry-After header, use it to throw an exception containing a Date when retries are accepted again.

need same domain auth when wildcard domain auth

When I need to authorization one domain(example.com) and this wildcard domain(*.example.com), Order give two Authorization object. But these Authorization Object is to same domain auth(to example.com).
Do I need to complete both authorization?

No ACME provider found for acme://letsencrypt.org/staging

Good day.
I'm trying to implement the acme4j into a Starface (http://www.starface.de/de/index.php)

The Starface has a great Module System, which allows to load additional libraries, and classes in runtime.

I've written and pre-tested all the code in eclipse, and it works fine.

Once loaded into the running System i already run into a problem when trying to create the session.

java.lang.IllegalArgumentException: No ACME provider found for acme://letsencrypt.org/staging

at org.shredzone.acme4j.Session.lambda$new$2(Session.java:91) at java.util.Optional.orElseThrow(Optional.java:290) at org.shredzone.acme4j.Session.<init>(Session.java:91) at org.shredzone.acme4j.Session.<init>(Session.java:63) at nucom.module.letsencrypt.session.RegisterSession.execute(RegisterSession.java:90) at de.vertico.starface.module.core....... //This part of the Stacktrace is no longer relevant

Line 90 in my Code is just:

Session S = new Session("acme://letsencrypt.org/staging", SessionKP);

The Target Platform is :
OS: Centos
Version: 6.8 Final
Java-SE: 1.8.0_144
Java HotSpot: 64 Bit Server 25.144

Sadly i cannot figure out the issue, i tested DNS/Firewall related problems, but everything seems fine.

Any ideas?

Sincerly

Fabian95qw

ClientTest.java: attempts can be 0 and challenge.getStatus() can be Status.VALID at the same time

In
org.shredzone.acme4j.ClientTest.java

in Method
public void fetchCertificate(Collection domains) throws IOException, AcmeException

in the code

            while (challenge.getStatus() != Status.VALID && attempts-- > 0) {
                if (challenge.getStatus() == Status.INVALID) {
                    LOG.error("Challenge failed... Giving up.");
                    return;
                }
                try {
                    Thread.sleep(3000L);
                } catch (InterruptedException ex) {
                    LOG.warn("interrupted", ex);
                }
                challenge.update();
            }
            if (attempts == 0) {

the last line should probably be changed to

if (challange.getStatus() != Status.VALID) {

because attempts can be 0 and challenge.getStatus() can be Status.VALID... (if I get it right...)

Example does not work with latest version available on Maven 0.11

Thank you for this project.

I have just linked the latest version of acme4j client to a test project:

<dependency>
  <groupId>org.shredzone.acme4j</groupId>
  <artifactId>acme4j-client</artifactId>
  <version>0.11</version>
</dependency>

Now when I try the example code from acme4j example, it does not work, since the following imports cannot be resolved:

import org.shredzone.acme4j.util.CSRBuilder;
import org.shredzone.acme4j.util.CertificateUtils;
import org.shredzone.acme4j.util.KeyPairUtils;

Is there a working example somewhere for version 0.11?

External account binding overwriting kid for subsequent requests?

Hello!

Using the current latest version of the master branch (622d579)

I'm trying to use acme4j's external account binding support and having some trouble with the kid getting set to the externalAccountBinding kid in subsequent requests (for example newOrder), instead of the account URL/kid generated by the server.

For example I have some test code that does external account binding with:
keyIdentifier: 242 and a hmac key.

This is an excerpt of the relevent parts of the debug log:

[main] DEBUG org.shredzone.acme4j.connector.DefaultConnection - POST http://localhost:15000/acme/new-order
[main] DEBUG org.shredzone.acme4j.connector.DefaultConnection -   Payload: {"identifiers":[{"type":"dns","value":"example.com"}]}
[main] DEBUG org.shredzone.acme4j.connector.DefaultConnection -   JWS Header: {"nonce":"_xRuseKZ4V8qIP9J-l5PL0o0gxFZ1jCJQoS19fxfWh0","url":"http://localhost:15000/acme/new-order","kid":"242","alg":"RS256"}
[main] DEBUG org.shredzone.acme4j.connector.DefaultConnection - HEADER null: HTTP/1.1 400 Bad Request
[main] DEBUG org.shredzone.acme4j.connector.DefaultConnection - Result JSON: {"type":"urn:ietf:params:acme:error:accountDoesNotExist","detail":"Account 242 not found.","status":400}

org.shredzone.acme4j.exception.AcmeServerException: Account 242 not found.

This is what the log looks like after I've applied my patches:

[main] DEBUG org.shredzone.acme4j.connector.DefaultConnection - POST http://localhost:15000/acme/new-order
[main] DEBUG org.shredzone.acme4j.connector.DefaultConnection -   Payload: {"identifiers":[{"type":"dns","value":"example.com"}]}
[main] DEBUG org.shredzone.acme4j.connector.DefaultConnection -   JWS Header: {"nonce":"MJxLH0m4HRm_TTAr5FVAfjlSLV1yBlHIJJB2loGjoNs","url":"http://localhost:15000/acme/new-order","kid":"http://localhost:15000/acme/acct/ddf3711393f599180a5648a03f3a7bda1ece81df22a9cc336a6fce75d279bee4","alg":"RS256"}

I've made the following changes to be able to solve it for me, but I would like to hear your thinking about the changes I've made, before I submit an eventual PR.

robaman@6bd9a49
robaman@dff96da

Thanks!

regards,
Robert Kästel

Unable to get details of a failed authorization.

Details are must have when it comes to configuring DDNS -> Port forwarding -> Nginx flows. They are available at:

{ ... , "error":{"type":"urn:acme:error:unauthorized","detail":"Invalid response from..."} ... }

I'm using version 0.11

acme4j 2.0 on maven central incompatible with recent pebble

It seems that the code published as stable 2.0 acme4j release on maven central contains code that is incompatible with the recent version of pebble, i.e. somewhat deprecated.
This also happened to me yesterday with my old 2.0-SNAPSHOT build, before the start of the official new ACMEv2 API at letsencrypt. However, updating to the most recent 2.0-SNAPSHOT based on your master branch fixed this issue.
Recent 2.0-SNAPSHOT builds do not suffer from this problem.
This is the stack trace when using the most recent pebble (based on master branch from letsencrypt repo) together with acme4j 2.0 from maven central:

Exception in thread "main" java.lang.RuntimeException: org.shredzone.acme4j.exception.AcmeServerException: Challenge response body contained legacy KeyAuthorzation field, POST body should be `{}`
	at de.fhg.aisec.ids.acmeclient.AcmeClientService.lambda$requestCertificate$2(AcmeClientService.java:105)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
	at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:291)
	at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:401)
	at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:734)
	at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:160)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:174)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
	at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
	at de.fhg.aisec.ids.acmeclient.AcmeClientService.requestCertificate(AcmeClientService.java:87)
	at de.fhg.aisec.ids.acmeclient.AcmeClientService.main(AcmeClientService.java:35)
Caused by: org.shredzone.acme4j.exception.AcmeServerException: Challenge response body contained legacy KeyAuthorzation field, POST body should be `{}`
	at org.shredzone.acme4j.connector.DefaultConnection.throwAcmeException(DefaultConnection.java:441)
	at org.shredzone.acme4j.connector.DefaultConnection.performRequest(DefaultConnection.java:366)
	at org.shredzone.acme4j.connector.DefaultConnection.sendSignedRequest(DefaultConnection.java:178)
	at org.shredzone.acme4j.connector.DefaultConnection.sendSignedRequest(DefaultConnection.java:157)
	at org.shredzone.acme4j.challenge.Challenge.trigger(Challenge.java:146)
	at de.fhg.aisec.ids.acmeclient.AcmeClientService.lambda$requestCertificate$2(AcmeClientService.java:91)
	... 15 more

How to extract chain/fullchain pem files

I successfully issued a new certificate (great work btw) using acme4j-client that saved a domain.key and a domain.crt in the cwd.

From what I understand these are the equivalent privkey.pem and cert.pem, according to Let's encrypt official acme client (certbot) filename conventions. cerbot also generates a chain.pem and a fullchain.pem that I'm exporting along with the private key in a PKC12 that will later be imported in a JKS keystore and used in Tomcat.

Is there a way to get the chain and full chain using acme4j?

Adding Subject to certificate :

Hi ,

Here is my certificate which is generated.

Certificate [
[
Version: V3
Subject: SERIALNUMBER=ff74f801146029188f9fe0b241e9c65afc06, CN=www.iconectivteam.com
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11

Key: Sun RSA public key, 2048 bits
modulus:

In this I need to add a value to subject column. The value is a static string. How can i add and what is the code to add subject to the certificate.

Adding custom ACME provider and building in Eclipse

Hi,

I'm attempting to create an additional ACME provider for Venafi, and have followed the necessary documentation, and just wondering if anyone has any experience developing against acme4j in Eclipse? I'm basically trying to package up a JAR file to be used by the acme4j-example project.

Thanks in advance.

-Ivan

Exception with Data-URI in ToS

Pebble delivers a Data-URI in Directory-Terms-Of-Service that acme4j is not able to process:

DEBUG 12:46:31,208 [] Link: terms-of-service -> data:text/plain,Do%20what%20thou%20wilt
org.shredzone.acme4j.exception.AcmeProtocolException: Cannot resolve relative link: data:text/plain,Do%20what%20thou%20wilt
at org.shredzone.acme4j.connector.DefaultConnection.resolveRelative(DefaultConnection.java:456)
at org.shredzone.acme4j.connector.DefaultConnection.getLinks(DefaultConnection.java:331)
at org.shredzone.acme4j.connector.DefaultConnection.getLink(DefaultConnection.java:305)
at org.shredzone.acme4j.connector.DefaultConnection.createAcmeException(DefaultConnection.java:392)
at org.shredzone.acme4j.connector.DefaultConnection.accept(DefaultConnection.java:205)
at org.shredzone.acme4j.RegistrationBuilder.create(RegistrationBuilder.java:87)

As far as I can tell, a Data-URI in that place is perfectly valid.

Mapping to Boulder

Hi,

I have got a local instance of Boulder. I want to map this ACME client to Boulder. Can you help me in doing so?

Revoke method sending account key as JWK

Using version 2.0 from maven repo using acmev2 protocol.

It looks like the revoke functionality is sending the account key as an embedded JWK while the specification states that it should be sent as a kid URL.

My understanding of the current spec is that you should only be sending an embedded JWK if you're trying to authenticate the revoke request with the key of the certificate, not account key.

Revoke specification:
https://ietf-wg-acme.github.io/acme/draft-ietf-acme-acme.html#rfc.section.7.6

This method:

conn.sendSignedRequest(resUrl, claims, getSession(), getLogin().getKeyPair());

Calls:

public int sendSignedRequest(URL url, JSONBuilder claims, Session session, KeyPair keypair)

Which specifies accountURL location as null,
which makes the code use an embedded JWK instead:

Here:

Am I correct in my assumptions?

regards,
Robert

Parsing certificate

Hi,

The certificate which is generated as the following error. I hope this extension is not getting parsed. May I know which class in acme client is trying to parse the certificate?

<Certificate Extensions: 2

[1]: ObjectId: 1.3.6.1.5.5.7.1.26 Criticality=false
Extension unknown: DER encoded OCTET string =
0000: 04 25 30 23 A0 14 16 08 33 39 20 61 62 20 32 36 .%0#....39 ab 26
0010: 16 08 32 31 20 63 36 20 30 31 A1 0B 16 06 31 32 ..21 c6 01....12
0020: 33 34 35 36 02 01 01>

NPE when reading version.properties

The following code in HttpConnector from the draft branch

    try (InputStream in = HttpConnector.class.getResourceAsStream("/org/shredzone/acme4j/version.properties")) {
        Properties prop = new Properties();
        prop.load(in);
        agent.append('/').append(prop.getProperty("version"));
    } catch (IOException ex) {
        // Ignore, just don't use a version
        LoggerFactory.getLogger(HttpConnector.class).warn("Could not read library version", ex);
    }

throws a NullPointerException in the load() method when running against a freshly checked out version.properties.

Since reading the version seems not to be critical, I'd rather change the catch(IOException) to a more generic catch(Exception).

Adding new Extention

Hi Shred,

Im trying to add a new OID TN authorization List which is not supported by Boulder Lets encrypt right now. So, Im trying to change the codes in boulder to accept this TN OID. But before that I have to make some changes in CSR builder to invoke this new OID "1.3.6.1.5.5.7.1.26".

image

Is this fine or i need to make changes else where. Kindly advice on this.

Thanks in advance.

Response stream is not read completely

DefaultConnection class does not read the whole response content from stream. The first line is read only. Methods affected:

  • readJsonResponse
  • readDirectory

How to get Certificates from Registration?

Hello,
First of all I want to thank you for this project. It is just awesome.

I have a small issue. When I try to get certificates from registration it always get 0 certificates even if my domains are already verifyed and I downloaded them.

Also the same problem with Authrization. Registration gets me 0 Authrizations always.

I am using Letsencrypt as my provider.

Do you know if it is the problem with letsencrypt or I do something wrong?

Sincerely,
Alexandr

Add support for Java 9 modules

Right now I'm getting compilation error with Java 9:

Error:java: the cc.blynk.acme module reads package org.shredzone.acme4j.util from both acme4j.client and acme4j.utils

pom.xml:

    <dependencies>

        <dependency>
            <groupId>org.shredzone.acme4j</groupId>
            <artifactId>acme4j-client</artifactId>
            <version>${acme4j-client.version}</version>
        </dependency>

        <dependency>
            <groupId>org.shredzone.acme4j</groupId>
            <artifactId>acme4j-utils</artifactId>
            <version>${acme4j-client.version}</version>
        </dependency>

    </dependencies>

module-info.java:

module cc.blynk.acme {
    requires acme4j.client;
    requires acme4j.utils;
}

Venafi doesn't escape challenge locations in JSON data.

Venafi does not escape the uri's in the json data

ex
https://domain.venafi.com/vacme/v1/authz/{11111111-222222-333333-44444-555555}/0

In org.shredzone.acme4j.challenge.Challenge::getLocation()

/**
 * Returns the location {@link URI} of the challenge.
 */
@Override
public URI getLocation() {
    return data.get(KEY_URI).asURI();
}

a java.net.URISyntaxException gets thrown because of "Illegal character in path at index ..."

I can work around it locally via Guava and modifying asURI in the org.shredzone.acme4j.toolbox.JSON::asURI()

import com.google.common.net.UrlEscapers;

...
...

/**
 * Returns the value as {@link URI}.
 *
 * @return {@link URI}, or {@code null} if the value was not set.
 */
public URI asURI() {
    if (val == null) {
        return null;
    }

    try {
        return new URI(UrlEscapers.urlFragmentEscaper().escape(val.toString()));
    } catch (URISyntaxException ex) {
        throw new AcmeProtocolException(path + ": bad URI " + val, ex);
    }
}

Im not sure if this is an issue with this client or the Venafi ACME V1 IMPL, but their impl does work with certbot.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.