001/*
002 * acme4j - Java ACME client
003 *
004 * Copyright (C) 2015 Richard "Shred" Körber
005 *   http://acme4j.shredzone.org
006 *
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
013 */
014package org.shredzone.acme4j.challenge;
015
016import static org.shredzone.acme4j.toolbox.AcmeUtils.base64UrlEncode;
017import static org.shredzone.acme4j.toolbox.AcmeUtils.sha256hash;
018
019import org.shredzone.acme4j.Identifier;
020import org.shredzone.acme4j.Login;
021import org.shredzone.acme4j.toolbox.JSON;
022
023/**
024 * Implements the {@value TYPE} challenge. It requires a specific DNS record for domain
025 * validation. See the acme4j documentation for a detailed explanation.
026 */
027public class Dns01Challenge extends TokenChallenge {
028    private static final long serialVersionUID = 6964687027713533075L;
029
030    /**
031     * Challenge type name: {@value}
032     */
033    public static final String TYPE = "dns-01";
034
035    /**
036     * The prefix of the domain name to be used for the DNS TXT record.
037     */
038    public static final String RECORD_NAME_PREFIX = "_acme-challenge";
039
040    /**
041     * Converts a domain identifier to the Resource Record name to be used for the DNS TXT
042     * record.
043     *
044     * @param identifier
045     *         Domain {@link Identifier} of the domain to be validated
046     * @return Resource Record name (e.g. {@code _acme-challenge.www.example.org.}, note
047     * the trailing full stop character).
048     * @since 2.14
049     */
050    public static String toRRName(Identifier identifier) {
051        return toRRName(identifier.getDomain());
052    }
053
054    /**
055     * Converts a domain identifier to the Resource Record name to be used for the DNS TXT
056     * record.
057     *
058     * @param domain
059     *         Domain name to be validated
060     * @return Resource Record name (e.g. {@code _acme-challenge.www.example.org.}, note
061     * the trailing full stop character).
062     * @since 2.14
063     */
064    public static String toRRName(String domain) {
065        return RECORD_NAME_PREFIX + '.' + domain + '.';
066    }
067
068    /**
069     * Creates a new generic {@link Dns01Challenge} object.
070     *
071     * @param login
072     *         {@link Login} the resource is bound with
073     * @param data
074     *         {@link JSON} challenge data
075     */
076    public Dns01Challenge(Login login, JSON data) {
077        super(login, data);
078    }
079
080    /**
081     * Returns the digest string to be set in the domain's {@code _acme-challenge} TXT
082     * record.
083     */
084    public String getDigest() {
085        return base64UrlEncode(sha256hash(getAuthorization()));
086    }
087
088    @Override
089    protected boolean acceptable(String type) {
090        return TYPE.equals(type);
091    }
092
093}