Support ECC in JWS

pull/17/merge
Richard Körber 2016-01-31 14:47:02 +01:00
parent 2da97c2dc9
commit 162c2c3773
3 changed files with 73 additions and 4 deletions

View File

@ -34,7 +34,6 @@ import java.util.regex.Pattern;
import org.jose4j.base64url.Base64Url; import org.jose4j.base64url.Base64Url;
import org.jose4j.json.JsonUtil; import org.jose4j.json.JsonUtil;
import org.jose4j.jwk.PublicJsonWebKey; import org.jose4j.jwk.PublicJsonWebKey;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature; import org.jose4j.jws.JsonWebSignature;
import org.jose4j.lang.JoseException; import org.jose4j.lang.JoseException;
import org.shredzone.acme4j.Registration; import org.shredzone.acme4j.Registration;
@ -47,6 +46,7 @@ import org.shredzone.acme4j.exception.AcmeRateLimitExceededException;
import org.shredzone.acme4j.exception.AcmeServerException; import org.shredzone.acme4j.exception.AcmeServerException;
import org.shredzone.acme4j.exception.AcmeUnauthorizedException; import org.shredzone.acme4j.exception.AcmeUnauthorizedException;
import org.shredzone.acme4j.util.ClaimBuilder; import org.shredzone.acme4j.util.ClaimBuilder;
import org.shredzone.acme4j.util.SignatureUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -148,7 +148,7 @@ public class DefaultConnection implements Connection {
jws.setPayload(claims.toString()); jws.setPayload(claims.toString());
jws.getHeaders().setObjectHeaderValue("nonce", Base64Url.encode(session.getNonce())); jws.getHeaders().setObjectHeaderValue("nonce", Base64Url.encode(session.getNonce()));
jws.getHeaders().setJwkHeaderValue("jwk", jwk); jws.getHeaders().setJwkHeaderValue("jwk", jwk);
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); jws.setAlgorithmHeaderValue(SignatureUtils.keyAlgorithm(jwk));
jws.setKey(keypair.getPrivate()); jws.setKey(keypair.getPrivate());
byte[] outputData = jws.getCompactSerialization().getBytes("utf-8"); byte[] outputData = jws.getCompactSerialization().getBytes("utf-8");

View File

@ -0,0 +1,70 @@
/*
* acme4j - Java ACME client
*
* Copyright (C) 2016 Richard "Shred" Körber
* http://acme4j.shredzone.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
package org.shredzone.acme4j.util;
import org.jose4j.jwk.EllipticCurveJsonWebKey;
import org.jose4j.jwk.JsonWebKey;
import org.jose4j.jwk.RsaJsonWebKey;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
/**
* Utility class for signatures.
*
* @author Richard "Shred" Körber
*/
public final class SignatureUtils {
private SignatureUtils() {
// Utility class without constructor
}
/**
* Analyzes the key used in the {@link JsonWebKey}, and returns the key algorithm
* identifier for {@link JsonWebSignature}.
*
* @param jwk
* {@link JsonWebKey} to analyze
* @return algorithm identifier
* @throws IllegalArgumentException
* there is no corresponding algorithm identifier for the key
*/
public static String keyAlgorithm(JsonWebKey jwk) {
if (jwk instanceof EllipticCurveJsonWebKey) {
EllipticCurveJsonWebKey ecjwk = (EllipticCurveJsonWebKey) jwk;
switch (ecjwk.getCurveName()) {
case "P-256":
return AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256;
case "P-384":
return AlgorithmIdentifiers.ECDSA_USING_P384_CURVE_AND_SHA384;
case "P-512":
return AlgorithmIdentifiers.ECDSA_USING_P521_CURVE_AND_SHA512;
default:
throw new IllegalArgumentException("Unknown EC name "
+ ecjwk.getCurveName());
}
} else if (jwk instanceof RsaJsonWebKey) {
return AlgorithmIdentifiers.RSA_USING_SHA256;
} else {
throw new IllegalArgumentException("Unknown algorithm " + jwk.getAlgorithm());
}
}
}

View File

@ -21,7 +21,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.jose4j.jwk.PublicJsonWebKey; import org.jose4j.jwk.PublicJsonWebKey;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature; import org.jose4j.jws.JsonWebSignature;
import org.jose4j.lang.JoseException; import org.jose4j.lang.JoseException;
import org.shredzone.acme4j.Registration; import org.shredzone.acme4j.Registration;
@ -112,7 +111,7 @@ public class ValidationBuilder {
JsonWebSignature jws = new JsonWebSignature(); JsonWebSignature jws = new JsonWebSignature();
jws.setPayload(claims.toString()); jws.setPayload(claims.toString());
jws.getHeaders().setJwkHeaderValue("jwk", jwk); jws.getHeaders().setJwkHeaderValue("jwk", jwk);
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); jws.setAlgorithmHeaderValue(SignatureUtils.keyAlgorithm(jwk));
jws.setKey(keypair.getPrivate()); jws.setKey(keypair.getPrivate());
jws.sign(); jws.sign();