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.connector; 015 016import java.net.HttpURLConnection; 017import java.net.URL; 018import java.security.KeyPair; 019import java.security.cert.X509Certificate; 020import java.time.ZonedDateTime; 021import java.util.Collection; 022import java.util.List; 023import java.util.Optional; 024 025import edu.umd.cs.findbugs.annotations.Nullable; 026import org.shredzone.acme4j.Login; 027import org.shredzone.acme4j.Session; 028import org.shredzone.acme4j.exception.AcmeException; 029import org.shredzone.acme4j.exception.AcmeProtocolException; 030import org.shredzone.acme4j.exception.AcmeRetryAfterException; 031import org.shredzone.acme4j.toolbox.JSON; 032import org.shredzone.acme4j.toolbox.JSONBuilder; 033 034/** 035 * Connects to the ACME server and offers different methods for invoking the API. 036 */ 037public interface Connection extends AutoCloseable { 038 039 /** 040 * Resets the session nonce, by fetching a new one. 041 * 042 * @param session 043 * {@link Session} instance to fetch a nonce for 044 */ 045 void resetNonce(Session session) throws AcmeException; 046 047 /** 048 * Sends a simple GET request. 049 * <p> 050 * If the response code was not {@link HttpURLConnection#HTTP_OK}, an 051 * {@link AcmeException} matching the error is raised. 052 * 053 * @param url 054 * {@link URL} to send the request to. 055 * @param session 056 * {@link Session} instance to be used for tracking 057 * @param ifModifiedSince 058 * {@link ZonedDateTime} to be sent as "If-Modified-Since" header, or 059 * {@code null} if this header is not to be used 060 * @return HTTP status that was returned 061 */ 062 int sendRequest(URL url, Session session, @Nullable ZonedDateTime ifModifiedSince) 063 throws AcmeException; 064 065 /** 066 * Sends a signed POST-as-GET request for a certificate resource. Requires a 067 * {@link Login} for the session and {@link KeyPair}. The {@link Login} account 068 * location is sent in a "kid" protected header. 069 * <p> 070 * If the server does not return a 200 class status code, an {@link AcmeException} is 071 * raised matching the error. 072 * 073 * @param url 074 * {@link URL} to send the request to. 075 * @param login 076 * {@link Login} instance to be used for signing and tracking. 077 * @return HTTP 200 class status that was returned 078 */ 079 int sendCertificateRequest(URL url, Login login) throws AcmeException; 080 081 /** 082 * Sends a signed POST-as-GET request. Requires a {@link Login} for the session and 083 * {@link KeyPair}. The {@link Login} account location is sent in a "kid" protected 084 * header. 085 * <p> 086 * If the server does not return a 200 class status code, an {@link AcmeException} is 087 * raised matching the error. 088 * 089 * @param url 090 * {@link URL} to send the request to. 091 * @param login 092 * {@link Login} instance to be used for signing and tracking. 093 * @return HTTP 200 class status that was returned 094 */ 095 int sendSignedPostAsGetRequest(URL url, Login login) throws AcmeException; 096 097 /** 098 * Sends a signed POST request. Requires a {@link Login} for the session and 099 * {@link KeyPair}. The {@link Login} account location is sent in a "kid" protected 100 * header. 101 * <p> 102 * If the server does not return a 200 class status code, an {@link AcmeException} is 103 * raised matching the error. 104 * 105 * @param url 106 * {@link URL} to send the request to. 107 * @param claims 108 * {@link JSONBuilder} containing claims. 109 * @param login 110 * {@link Login} instance to be used for signing and tracking. 111 * @return HTTP 200 class status that was returned 112 */ 113 int sendSignedRequest(URL url, JSONBuilder claims, Login login) throws AcmeException; 114 115 /** 116 * Sends a signed POST request. Only requires a {@link Session}. The {@link KeyPair} 117 * is sent in a "jwk" protected header field. 118 * <p> 119 * If the server does not return a 200 class status code, an {@link AcmeException} is 120 * raised matching the error. 121 * 122 * @param url 123 * {@link URL} to send the request to. 124 * @param claims 125 * {@link JSONBuilder} containing claims. 126 * @param session 127 * {@link Session} instance to be used for tracking. 128 * @param keypair 129 * {@link KeyPair} to be used for signing. 130 * @return HTTP 200 class status that was returned 131 */ 132 int sendSignedRequest(URL url, JSONBuilder claims, Session session, KeyPair keypair) 133 throws AcmeException; 134 135 /** 136 * Reads a server response as JSON data. 137 * 138 * @return The JSON response. 139 * @throws AcmeProtocolException 140 * if the JSON response was empty. 141 */ 142 JSON readJsonResponse() throws AcmeException; 143 144 /** 145 * Reads a certificate and its issuers. 146 * 147 * @return List of X.509 certificate and chain that was read. 148 */ 149 List<X509Certificate> readCertificates() throws AcmeException; 150 151 /** 152 * Throws an {@link AcmeRetryAfterException} if the last status was HTTP Accepted and 153 * a Retry-After header was received. 154 * 155 * @param message 156 * Message to be sent along with the {@link AcmeRetryAfterException} 157 */ 158 void handleRetryAfter(String message) throws AcmeException; 159 160 /** 161 * Gets the nonce from the nonce header. 162 * 163 * @return Base64 encoded nonce, or {@code null} if no nonce header was set 164 */ 165 @Nullable 166 String getNonce(); 167 168 /** 169 * Gets a location from the {@code Location} header. 170 * <p> 171 * Relative links are resolved against the last request's URL. 172 * 173 * @return Location {@link URL}, or {@code null} if no Location header was set 174 */ 175 @Nullable 176 URL getLocation(); 177 178 /** 179 * Returns the content of the last-modified header, if present. 180 * 181 * @return Date in the Last-Modified header, or empty if the server did not provide 182 * this information. 183 * @since 2.10 184 */ 185 Optional<ZonedDateTime> getLastModified(); 186 187 /** 188 * Returns the expiration date of the resource, if present. 189 * 190 * @return Expiration date, either from the Cache-Control or Expires header. If empty, 191 * the server did not provide an expiration date, or forbid caching. 192 * @since 2.10 193 */ 194 Optional<ZonedDateTime> getExpiration(); 195 196 /** 197 * Gets one or more relation links from the header. The result is expected to be an URL. 198 * <p> 199 * Relative links are resolved against the last request's URL. 200 * 201 * @param relation 202 * Link relation 203 * @return Collection of links. Empty if there was no such relation. 204 */ 205 Collection<URL> getLinks(String relation); 206 207 /** 208 * Closes the {@link Connection}, releasing all resources. 209 */ 210 @Override 211 void close(); 212 213}