mirror of https://github.com/shred/acme4j
				
				
				
			Make the challenge selectable
							parent
							
								
									7b6af21cd1
								
							
						
					
					
						commit
						78ccec7d1d
					
				| 
						 | 
				
			
			@ -26,7 +26,10 @@ import java.util.Collection;
 | 
			
		|||
 | 
			
		||||
import javax.swing.JOptionPane;
 | 
			
		||||
 | 
			
		||||
import org.shredzone.acme4j.challenge.Challenge;
 | 
			
		||||
import org.shredzone.acme4j.challenge.DnsChallenge;
 | 
			
		||||
import org.shredzone.acme4j.challenge.HttpChallenge;
 | 
			
		||||
import org.shredzone.acme4j.challenge.TlsSniChallenge;
 | 
			
		||||
import org.shredzone.acme4j.exception.AcmeConflictException;
 | 
			
		||||
import org.shredzone.acme4j.exception.AcmeException;
 | 
			
		||||
import org.shredzone.acme4j.exception.AcmeUnauthorizedException;
 | 
			
		||||
| 
						 | 
				
			
			@ -119,35 +122,12 @@ public class ClientTest {
 | 
			
		|||
            }
 | 
			
		||||
            LOG.info("New authorization for domain " + domain);
 | 
			
		||||
 | 
			
		||||
            // Find a single http-01 challenge
 | 
			
		||||
            HttpChallenge challenge = auth.findChallenge(HttpChallenge.TYPE);
 | 
			
		||||
            // Uncomment a challenge...
 | 
			
		||||
            Challenge challenge = httpChallenge(auth, account, domain);
 | 
			
		||||
//            Challenge challenge = dnsChallenge(auth, account, domain);
 | 
			
		||||
//            Challenge challenge = tlsSniChallenge(auth, account, domain);
 | 
			
		||||
 | 
			
		||||
            if (challenge == null) {
 | 
			
		||||
                LOG.error("Found no " + HttpChallenge.TYPE + " challenge, don't know what to do...");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Authorize the challenge
 | 
			
		||||
            challenge.authorize(account);
 | 
			
		||||
 | 
			
		||||
            // Output the challenge, wait for acknowledge...
 | 
			
		||||
            LOG.info("Please create a file in your web server's base directory.");
 | 
			
		||||
            LOG.info("It must be reachable at: http://" + domain + "/.well-known/acme-challenge/" + challenge.getToken());
 | 
			
		||||
            LOG.info("File name: " + challenge.getToken());
 | 
			
		||||
            LOG.info("Content: " + challenge.getAuthorization());
 | 
			
		||||
            LOG.info("The file must not contain any leading or trailing whitespaces or line breaks!");
 | 
			
		||||
            LOG.info("If you're ready, dismiss the dialog...");
 | 
			
		||||
 | 
			
		||||
            StringBuilder message = new StringBuilder();
 | 
			
		||||
            message.append("Please create a file in your web server's base directory.\n\n");
 | 
			
		||||
            message.append("http://").append(domain).append("/.well-known/acme-challenge/").append(challenge.getToken()).append("\n\n");
 | 
			
		||||
            message.append("Content:\n\n");
 | 
			
		||||
            message.append(challenge.getAuthorization());
 | 
			
		||||
            int option = JOptionPane.showConfirmDialog(null,
 | 
			
		||||
                            message.toString(),
 | 
			
		||||
                            "Prepare Challenge",
 | 
			
		||||
                            JOptionPane.OK_CANCEL_OPTION);
 | 
			
		||||
            if (option == JOptionPane.CANCEL_OPTION) {
 | 
			
		||||
                LOG.error("User cancelled challenge");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -211,6 +191,137 @@ public class ClientTest {
 | 
			
		|||
        // client.revokeCertificate(account, cert);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Prepares HTTP challenge.
 | 
			
		||||
     */
 | 
			
		||||
    public Challenge httpChallenge(Authorization auth, Account account, String domain) throws AcmeException {
 | 
			
		||||
        // Find a single http-01 challenge
 | 
			
		||||
        HttpChallenge challenge = auth.findChallenge(HttpChallenge.TYPE);
 | 
			
		||||
        if (challenge == null) {
 | 
			
		||||
            LOG.error("Found no " + HttpChallenge.TYPE + " challenge, don't know what to do...");
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Authorize the challenge
 | 
			
		||||
        challenge.authorize(account);
 | 
			
		||||
 | 
			
		||||
        // Output the challenge, wait for acknowledge...
 | 
			
		||||
        LOG.info("Please create a file in your web server's base directory.");
 | 
			
		||||
        LOG.info("It must be reachable at: http://" + domain + "/.well-known/acme-challenge/" + challenge.getToken());
 | 
			
		||||
        LOG.info("File name: " + challenge.getToken());
 | 
			
		||||
        LOG.info("Content: " + challenge.getAuthorization());
 | 
			
		||||
        LOG.info("The file must not contain any leading or trailing whitespaces or line breaks!");
 | 
			
		||||
        LOG.info("If you're ready, dismiss the dialog...");
 | 
			
		||||
 | 
			
		||||
        StringBuilder message = new StringBuilder();
 | 
			
		||||
        message.append("Please create a file in your web server's base directory.\n\n");
 | 
			
		||||
        message.append("http://").append(domain).append("/.well-known/acme-challenge/").append(challenge.getToken()).append("\n\n");
 | 
			
		||||
        message.append("Content:\n\n");
 | 
			
		||||
        message.append(challenge.getAuthorization());
 | 
			
		||||
        int option = JOptionPane.showConfirmDialog(null,
 | 
			
		||||
                        message.toString(),
 | 
			
		||||
                        "Prepare Challenge",
 | 
			
		||||
                        JOptionPane.OK_CANCEL_OPTION);
 | 
			
		||||
        if (option == JOptionPane.CANCEL_OPTION) {
 | 
			
		||||
            LOG.error("User cancelled challenge");
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return challenge;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Prepares DNS challenge.
 | 
			
		||||
     */
 | 
			
		||||
    public Challenge dnsChallenge(Authorization auth, Account account, String domain) throws AcmeException {
 | 
			
		||||
        // Find a single dns-01 challenge
 | 
			
		||||
        DnsChallenge challenge = auth.findChallenge(DnsChallenge.TYPE);
 | 
			
		||||
        if (challenge == null) {
 | 
			
		||||
            LOG.error("Found no " + DnsChallenge.TYPE + " challenge, don't know what to do...");
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Authorize the challenge
 | 
			
		||||
        challenge.authorize(account);
 | 
			
		||||
 | 
			
		||||
        // Output the challenge, wait for acknowledge...
 | 
			
		||||
        LOG.info("Please create a TXT record:");
 | 
			
		||||
        LOG.info("_acme-challenge." + domain + ". IN TXT " + challenge.getDigest());
 | 
			
		||||
        LOG.info("If you're ready, dismiss the dialog...");
 | 
			
		||||
 | 
			
		||||
        StringBuilder message = new StringBuilder();
 | 
			
		||||
        message.append("Please create a TXT record:\n\n");
 | 
			
		||||
        message.append("_acme-challenge." + domain + ". IN TXT " + challenge.getDigest());
 | 
			
		||||
        int option = JOptionPane.showConfirmDialog(null,
 | 
			
		||||
                        message.toString(),
 | 
			
		||||
                        "Prepare Challenge",
 | 
			
		||||
                        JOptionPane.OK_CANCEL_OPTION);
 | 
			
		||||
        if (option == JOptionPane.CANCEL_OPTION) {
 | 
			
		||||
            LOG.error("User cancelled challenge");
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return challenge;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Prepares TLS-SNI challenge.
 | 
			
		||||
     */
 | 
			
		||||
    public Challenge tlsSniChallenge(Authorization auth, Account account, String domain) throws AcmeException {
 | 
			
		||||
        // Find a single tls-sni-01 challenge
 | 
			
		||||
        TlsSniChallenge challenge = auth.findChallenge(TlsSniChallenge.TYPE);
 | 
			
		||||
        if (challenge == null) {
 | 
			
		||||
            LOG.error("Found no " + TlsSniChallenge.TYPE + " challenge, don't know what to do...");
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Authorize the challenge
 | 
			
		||||
        challenge.authorize(account);
 | 
			
		||||
 | 
			
		||||
        // Get the Subject
 | 
			
		||||
        String subject = challenge.getSubject();
 | 
			
		||||
 | 
			
		||||
        // Create a keypair
 | 
			
		||||
        KeyPair domainKeyPair;
 | 
			
		||||
        try (FileWriter fw = new FileWriter("tlssni.key")) {
 | 
			
		||||
            domainKeyPair = KeyPairUtils.createKeyPair(2048);
 | 
			
		||||
            KeyPairUtils.writeKeyPair(domainKeyPair, fw);
 | 
			
		||||
        } catch (IOException ex) {
 | 
			
		||||
            LOG.error("Could not create keypair", ex);
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Create a certificate
 | 
			
		||||
        try (FileWriter fw = new FileWriter("tlssni.crt")) {
 | 
			
		||||
            X509Certificate cert = CertificateUtils.createTlsSniCertificate(domainKeyPair, subject);
 | 
			
		||||
            CertificateUtils.writeX509Certificate(cert, fw);
 | 
			
		||||
        } catch (IOException ex) {
 | 
			
		||||
            LOG.error("Could not create certificate", ex);
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Output the challenge, wait for acknowledge...
 | 
			
		||||
        LOG.info("Please configure your web server.");
 | 
			
		||||
        LOG.info("It must return the certificate 'tlssni.crt' on a SNI request to:");
 | 
			
		||||
        LOG.info(subject);
 | 
			
		||||
        LOG.info("The matching keypair is available at 'tlssni.key'.");
 | 
			
		||||
        LOG.info("If you're ready, dismiss the dialog...");
 | 
			
		||||
 | 
			
		||||
        StringBuilder message = new StringBuilder();
 | 
			
		||||
        message.append("Please use 'tlssni.key' and 'tlssni.crt' cert for SNI requests to:\n\n");
 | 
			
		||||
        message.append("https://").append(subject).append("\n\n");
 | 
			
		||||
        int option = JOptionPane.showConfirmDialog(null,
 | 
			
		||||
                        message.toString(),
 | 
			
		||||
                        "Prepare Challenge",
 | 
			
		||||
                        JOptionPane.OK_CANCEL_OPTION);
 | 
			
		||||
        if (option == JOptionPane.CANCEL_OPTION) {
 | 
			
		||||
            LOG.error("User cancelled challenge");
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return challenge;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Presents the user a link to the Terms of Service, and asks for confirmation.
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue