Avoid unnecessary de/encoding of nonces

pull/61/head
Richard Körber 2018-03-06 22:10:08 +01:00
parent 189d2d94a8
commit 69a23e7bf6
No known key found for this signature in database
GPG Key ID: AAB9FD19C78AA3E0
8 changed files with 27 additions and 30 deletions

View File

@ -40,8 +40,7 @@ public class Session {
private final URI serverUri;
private final AcmeProvider provider;
private byte[] nonce;
private JSON directoryJson;
private String nonce;
private Locale locale = Locale.getDefault();
protected Instant directoryCacheExpiry;
@ -101,16 +100,16 @@ public class Session {
}
/**
* Gets the last nonce, or {@code null} if the session is new.
* Gets the last base64 encoded nonce, or {@code null} if the session is new.
*/
public byte[] getNonce() {
public String getNonce() {
return nonce;
}
/**
* Sets the nonce received by the server.
* Sets the base64 encoded nonce received by the server.
*/
public void setNonce(byte[] nonce) {
public void setNonce(String nonce) {
this.nonce = nonce;
}

View File

@ -117,9 +117,9 @@ public interface Connection extends AutoCloseable {
/**
* Gets the nonce from the nonce header.
*
* @return Nonce, or {@code null} if no nonce header was set
* @return Base64 encoded nonce, or {@code null} if no nonce header was set
*/
byte[] getNonce();
String getNonce();
/**
* Gets a location from the {@code Location} header.

View File

@ -37,7 +37,6 @@ import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jose4j.base64url.Base64Url;
import org.jose4j.jwk.PublicJsonWebKey;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.lang.JoseException;
@ -112,7 +111,7 @@ public class DefaultConnection implements Connection {
throwAcmeException();
}
byte[] nonce = getNonce();
String nonce = getNonce();
if (nonce == null) {
throw new AcmeProtocolException("Server did not provide a nonce");
}
@ -247,12 +246,12 @@ public class DefaultConnection implements Connection {
}
@Override
public byte[] getNonce() {
public String getNonce() {
assertConnectionIsOpen();
String nonceHeader = conn.getHeaderField(REPLAY_NONCE_HEADER);
if (nonceHeader == null || nonceHeader.trim().isEmpty()) {
return null; //NOSONAR: consistent with other getters
return null;
}
if (!BASE64URL_PATTERN.matcher(nonceHeader).matches()) {
@ -261,7 +260,7 @@ public class DefaultConnection implements Connection {
LOG.debug("Replay Nonce: {}", nonceHeader);
return Base64Url.decode(nonceHeader);
return nonceHeader;
}
@Override
@ -323,7 +322,7 @@ public class DefaultConnection implements Connection {
final PublicJsonWebKey jwk = PublicJsonWebKey.Factory.newPublicJwk(keypair.getPublic());
JsonWebSignature jws = new JsonWebSignature();
jws.setPayload(claims.toString());
jws.getHeaders().setObjectHeaderValue("nonce", Base64Url.encode(session.getNonce()));
jws.getHeaders().setObjectHeaderValue("nonce", session.getNonce());
jws.getHeaders().setObjectHeaderValue("url", url);
if (accountLocation == null) {
jws.getHeaders().setJwkHeaderValue("jwk", jwk);

View File

@ -54,7 +54,7 @@ public abstract class AbstractAcmeProvider implements AcmeProvider {
conn.sendRequest(resolve(serverUri), session);
// use nonce header if there is one, saves a HEAD request...
byte[] nonce = conn.getNonce();
String nonce = conn.getNonce();
if (nonce != null) {
session.setNonce(nonce);
}

View File

@ -76,9 +76,8 @@ public class SessionTest {
Session session = new Session(serverUri);
assertThat(session.getNonce(), is(nullValue()));
byte[] data = "foo-nonce-bar".getBytes();
session.setNonce(data);
assertThat(session.getNonce(), is(equalTo(data)));
session.setNonce(DUMMY_NONCE);
assertThat(session.getNonce(), is(equalTo(DUMMY_NONCE)));
assertThat(session.getServerUri(), is(serverUri));
}

View File

@ -119,7 +119,7 @@ public class DefaultConnectionTest {
@Test
public void testGetNonceFromHeader() {
when(mockUrlConnection.getHeaderField("Replay-Nonce"))
.thenReturn(Base64Url.encode(TestUtils.DUMMY_NONCE));
.thenReturn(TestUtils.DUMMY_NONCE);
try (DefaultConnection conn = new DefaultConnection(mockHttpConnection)) {
conn.conn = mockUrlConnection;
@ -175,7 +175,7 @@ public class DefaultConnectionTest {
assertThat(session.getNonce(), is(nullValue()));
when(mockUrlConnection.getHeaderField("Replay-Nonce"))
.thenReturn(Base64Url.encode(TestUtils.DUMMY_NONCE));
.thenReturn(TestUtils.DUMMY_NONCE);
try (DefaultConnection conn = new DefaultConnection(mockHttpConnection)) {
conn.resetNonce(session);
@ -660,8 +660,8 @@ public class DefaultConnectionTest {
*/
@Test
public void testSendSignedRequest() throws Exception {
final byte[] nonce1 = "foo-nonce-1-foo".getBytes();
final byte[] nonce2 = "foo-nonce-2-foo".getBytes();
final String nonce1 = Base64Url.encode("foo-nonce-1-foo".getBytes());
final String nonce2 = Base64Url.encode("foo-nonce-2-foo".getBytes());
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
when(mockUrlConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK);
@ -679,7 +679,7 @@ public class DefaultConnectionTest {
}
@Override
public byte[] getNonce() {
public String getNonce() {
assertThat(session, is(sameInstance(DefaultConnectionTest.this.session)));
if (session.getNonce() == nonce1) {
return nonce2;
@ -714,7 +714,7 @@ public class DefaultConnectionTest {
StringBuilder expectedHeader = new StringBuilder();
expectedHeader.append('{');
expectedHeader.append("\"nonce\":\"").append(Base64Url.encode(nonce1)).append("\",");
expectedHeader.append("\"nonce\":\"").append(nonce1).append("\",");
expectedHeader.append("\"url\":\"").append(requestUrl).append("\",");
expectedHeader.append("\"alg\":\"RS256\",");
expectedHeader.append("\"kid\":\"").append(accountUrl).append('"');
@ -735,8 +735,8 @@ public class DefaultConnectionTest {
*/
@Test
public void testSendSignedRequestNoKid() throws Exception {
final byte[] nonce1 = "foo-nonce-1-foo".getBytes();
final byte[] nonce2 = "foo-nonce-2-foo".getBytes();
final String nonce1 = Base64Url.encode("foo-nonce-1-foo".getBytes());
final String nonce2 = Base64Url.encode("foo-nonce-2-foo".getBytes());
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
when(mockUrlConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK);
@ -754,7 +754,7 @@ public class DefaultConnectionTest {
}
@Override
public byte[] getNonce() {
public String getNonce() {
assertThat(session, is(sameInstance(DefaultConnectionTest.this.session)));
if (session.getNonce() == nonce1) {
return nonce2;
@ -789,7 +789,7 @@ public class DefaultConnectionTest {
StringBuilder expectedHeader = new StringBuilder();
expectedHeader.append('{');
expectedHeader.append("\"nonce\":\"").append(Base64Url.encode(nonce1)).append("\",");
expectedHeader.append("\"nonce\":\"").append(nonce1).append("\",");
expectedHeader.append("\"url\":\"").append(requestUrl).append("\",");
expectedHeader.append("\"alg\":\"RS256\",");
expectedHeader.append("\"jwk\":{");

View File

@ -69,7 +69,7 @@ public class DummyConnection implements Connection {
}
@Override
public byte[] getNonce() {
public String getNonce() {
throw new UnsupportedOperationException();
}

View File

@ -73,7 +73,7 @@ public final class TestUtils {
public static final String ACME_SERVER_URI = "https://example.com/acme";
public static final String ACCOUNT_URL = "https://example.com/acme/account/1";
public static final byte[] DUMMY_NONCE = "foo-nonce-foo".getBytes();
public static final String DUMMY_NONCE = Base64Url.encode("foo-nonce-foo".getBytes());
private TestUtils() {