/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.rs.security.jose.jws;
import java.security.Key;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Logger;
import org.apache.cxf.Bus;
import org.apache.cxf.common.logging.LogUtils;
import org.apache.cxf.common.util.PropertyUtils;
import org.apache.cxf.message.Message;
import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.PhaseInterceptorChain;
import org.apache.cxf.rs.security.jose.common.JoseConstants;
import org.apache.cxf.rs.security.jose.common.JoseUtils;
import org.apache.cxf.rs.security.jose.common.KeyManagementUtils;
import org.apache.cxf.rs.security.jose.jwa.AlgorithmUtils;
import org.apache.cxf.rs.security.jose.jwa.SignatureAlgorithm;
import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
import org.apache.cxf.rs.security.jose.jwk.JsonWebKeys;
import org.apache.cxf.rs.security.jose.jwk.JwkUtils;
import org.apache.cxf.rs.security.jose.jwk.KeyOperation;
import org.apache.cxf.rs.security.jose.jwk.KeyType;
import org.apache.cxf.rs.security.jose.jwk.PublicKeyUse;
import org.apache.cxf.rt.security.crypto.MessageDigestUtils;
public final class JwsUtils {
private static final Logger LOG = LogUtils.getL7dLogger(JwsUtils.class);
private JwsUtils() {
}
public static String sign(PrivateKey key, SignatureAlgorithm algo, String content) {
return sign(key, algo, content, null);
}
public static String sign(PrivateKey key, SignatureAlgorithm algo, String content, String ct) {
return sign(getPrivateKeySignatureProvider(key, algo), content, ct);
}
public static String sign(String encodedKey, SignatureAlgorithm algo, String content) {
return sign(JoseUtils.decode(encodedKey), algo, content);
}
public static String sign(byte[] key, SignatureAlgorithm algo, String content) {
return sign(key, algo, content, null);
}
public static String sign(byte[] key, SignatureAlgorithm algo, String content, String ct) {
return sign(getHmacSignatureProvider(key, algo), content, ct);
}
public static String verify(PublicKey key, SignatureAlgorithm algo, String content) {
JwsCompactConsumer jws = verify(getPublicKeySignatureVerifier(key, algo), content);
return jws.getDecodedJwsPayload();
}
public static String verify(String encodedKey, SignatureAlgorithm algo, String content) {
return verify(JoseUtils.decode(encodedKey), algo, content);
}
public static String verify(byte[] key, SignatureAlgorithm algo, String content) {
JwsCompactConsumer jws = verify(getHmacSignatureVerifier(key, algo), content);
return jws.getDecodedJwsPayload();
}
public static JwsSignatureProvider getSignatureProvider(JsonWebKey jwk) {
return getSignatureProvider(jwk, null);
}
public static JwsSignatureProvider getSignatureProvider(JsonWebKey jwk,
SignatureAlgorithm defaultAlgorithm) {
SignatureAlgorithm sigAlgo = jwk.getAlgorithm() == null ? defaultAlgorithm
: SignatureAlgorithm.getAlgorithm(jwk.getAlgorithm());
JwsSignatureProvider theSigProvider = null;
KeyType keyType = jwk.getKeyType();
if (KeyType.RSA == keyType) {
theSigProvider = getPrivateKeySignatureProvider(JwkUtils.toRSAPrivateKey(jwk),
sigAlgo);
} else if (KeyType.OCTET == keyType) {
byte[] key = JoseUtils.decode((String)jwk.getProperty(JsonWebKey.OCTET_KEY_VALUE));
theSigProvider = getHmacSignatureProvider(key, sigAlgo);
} else if (KeyType.EC == jwk.getKeyType()) {
theSigProvider = getPrivateKeySignatureProvider(JwkUtils.toECPrivateKey(jwk),
sigAlgo);
}
return theSigProvider;
}
public static JwsSignatureProvider getPrivateKeySignatureProvider(PrivateKey key, SignatureAlgorithm algo) {
if (algo == null) {
LOG.warning("No signature algorithm was defined");
throw new JwsException(JwsException.Error.ALGORITHM_NOT_SET);
}
if (key instanceof ECPrivateKey) {
return new EcDsaJwsSignatureProvider((ECPrivateKey)key, algo);
} else if (key instanceof RSAPrivateKey) {
return new PrivateKeyJwsSignatureProvider(key, algo);
}
return null;
}
public static JwsSignatureProvider getHmacSignatureProvider(String encodedKey, SignatureAlgorithm algo) {
return getHmacSignatureProvider(JoseUtils.decode(encodedKey), algo);
}
public static JwsSignatureProvider getHmacSignatureProvider(byte[] key, SignatureAlgorithm algo) {
if (algo == null) {
LOG.warning("No signature algorithm was defined");
throw new JwsException(JwsException.Error.ALGORITHM_NOT_SET);
}
if (AlgorithmUtils.isHmacSign(algo.getJwaName())) {
return new HmacJwsSignatureProvider(key, algo);
}
return null;
}
public static JwsSignatureVerifier getSignatureVerifier(JsonWebKey jwk) {
return getSignatureVerifier(jwk, null);
}
public static JwsSignatureVerifier getSignatureVerifier(JsonWebKey jwk, SignatureAlgorithm defaultAlgorithm) {
SignatureAlgorithm sigAlgo = jwk.getAlgorithm() == null ? defaultAlgorithm
: SignatureAlgorithm.getAlgorithm(jwk.getAlgorithm());
JwsSignatureVerifier theVerifier = null;
KeyType keyType = jwk.getKeyType();
if (KeyType.RSA == keyType) {
theVerifier = getPublicKeySignatureVerifier(JwkUtils.toRSAPublicKey(jwk, true), sigAlgo);
} else if (KeyType.OCTET == keyType) {
byte[] key = JoseUtils.decode((String)jwk.getProperty(JsonWebKey.OCTET_KEY_VALUE));
theVerifier = getHmacSignatureVerifier(key, sigAlgo);
} else if (KeyType.EC == keyType) {
theVerifier = getPublicKeySignatureVerifier(JwkUtils.toECPublicKey(jwk), sigAlgo);
}
return theVerifier;
}
public static JwsSignatureVerifier getPublicKeySignatureVerifier(X509Certificate cert, SignatureAlgorithm algo) {
if (cert != null) {
if (algo == null) {
algo = getDefaultPublicKeyAlgorithm(cert.getPublicKey());
}
if (algo == null) {
LOG.warning("No signature algorithm was defined");
throw new JwsException(JwsException.Error.ALGORITHM_NOT_SET);
}
if (cert.getPublicKey() instanceof RSAPublicKey) {
return new PublicKeyJwsSignatureVerifier(cert, algo);
} else if (cert.getPublicKey() instanceof ECPublicKey) {
return new EcDsaJwsSignatureVerifier(cert, algo);
}
}
return null;
}
public static JwsSignatureVerifier getPublicKeySignatureVerifier(PublicKey key, SignatureAlgorithm algo) {
if (algo == null) {
LOG.warning("No signature algorithm was defined");
throw new JwsException(JwsException.Error.ALGORITHM_NOT_SET);
}
if (key instanceof RSAPublicKey) {
return new PublicKeyJwsSignatureVerifier(key, algo);
} else if (key instanceof ECPublicKey) {
return new EcDsaJwsSignatureVerifier(key, algo);
}
return null;
}
public static JwsSignatureVerifier getHmacSignatureVerifier(String encodedKey, SignatureAlgorithm algo) {
return getHmacSignatureVerifier(JoseUtils.decode(encodedKey), algo);
}
public static JwsSignatureVerifier getHmacSignatureVerifier(byte[] key, SignatureAlgorithm algo) {
if (algo == null) {
LOG.warning("No signature algorithm was defined");
throw new JwsException(JwsException.Error.ALGORITHM_NOT_SET);
}
if (AlgorithmUtils.isHmacSign(algo.getJwaName())) {
return new HmacJwsSignatureVerifier(key, algo);
}
return null;
}
public static Map<SignatureAlgorithm, List<JwsJsonSignatureEntry>> getJwsJsonSignatureMap(
List<JwsJsonSignatureEntry> signatures) {
Map<SignatureAlgorithm, List<JwsJsonSignatureEntry>> map = new HashMap<>();
for (JwsJsonSignatureEntry entry : signatures) {
SignatureAlgorithm sigAlgorithm = entry.getUnionHeader().getSignatureAlgorithm();
List<JwsJsonSignatureEntry> entries = map.get(sigAlgorithm);
if (entries == null) {
entries = new ArrayList<>();
}
entries.add(entry);
map.put(sigAlgorithm, entries);
}
return map;
}
public static JwsSignatureProvider loadSignatureProvider(boolean required) {
return loadSignatureProvider(null, required);
}
public static JwsSignatureProvider loadSignatureProvider(JwsHeaders headers, boolean required) {
Properties props = loadSignatureOutProperties(required);
if (props == null) {
return null;
}
JwsSignatureProvider theSigProvider = loadSignatureProvider(props, headers);
if (headers != null) {
headers.setSignatureAlgorithm(theSigProvider.getAlgorithm());
}
return theSigProvider;
}
public static Properties loadSignatureOutProperties(boolean required) {
Message m = PhaseInterceptorChain.getCurrentMessage();
return KeyManagementUtils.loadStoreProperties(m, required,
JoseConstants.RSSEC_SIGNATURE_OUT_PROPS,
JoseConstants.RSSEC_SIGNATURE_PROPS);
}
public static Properties loadSignatureInProperties(boolean required) {
Message m = PhaseInterceptorChain.getCurrentMessage();
return KeyManagementUtils.loadStoreProperties(m, required,
JoseConstants.RSSEC_SIGNATURE_IN_PROPS,
JoseConstants.RSSEC_SIGNATURE_PROPS);
}
public static Properties loadSignatureProperties(String propertiesName, boolean required) {
Message m = PhaseInterceptorChain.getCurrentMessage();
return KeyManagementUtils.loadStoreProperties(m, required, propertiesName, null);
}
public static Properties loadSignatureProperties(String propertiesLoc, Bus bus) {
try {
return JoseUtils.loadProperties(propertiesLoc, bus);
} catch (Exception ex) {
throw new JwsException(JwsException.Error.NO_INIT_PROPERTIES, ex);
}
}
public static JwsSignatureVerifier loadSignatureVerifier(boolean required) {
return loadSignatureVerifier(null, required);
}
public static JwsSignatureVerifier loadSignatureVerifier(String propertiesLoc, Bus bus) {
Properties props = loadSignatureProperties(propertiesLoc, bus);
return loadSignatureVerifier(props, null);
}
public static JwsSignatureVerifier loadSignatureVerifier(JwsHeaders headers, boolean required) {
Properties props = loadSignatureInProperties(required);
return loadSignatureVerifier(props, headers);
}
public static List<JwsSignatureProvider> loadSignatureProviders(String propLoc, Message m) {
Properties props = loadJwsProperties(m, propLoc);
JwsSignatureProvider theSigProvider = loadSignatureProvider(m, props, null, true);
if (theSigProvider != null) {
return Collections.singletonList(theSigProvider);
}
List<JwsSignatureProvider> theSigProviders = null;
if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
List<JsonWebKey> jwks = JwkUtils.loadJsonWebKeys(m, props, KeyOperation.SIGN);
if (jwks != null) {
theSigProviders = new ArrayList<>(jwks.size());
for (JsonWebKey jwk : jwks) {
theSigProviders.add(JwsUtils.getSignatureProvider(jwk));
}
}
}
if (theSigProviders == null) {
LOG.warning("Providers are not available");
throw new JwsException(JwsException.Error.NO_PROVIDER);
}
return theSigProviders;
}
public static List<JwsSignatureVerifier> loadSignatureVerifiers(String propLoc, Message m) {
Properties props = loadJwsProperties(m, propLoc);
JwsSignatureVerifier theVerifier = loadSignatureVerifier(m, props, null, true);
if (theVerifier != null) {
return Collections.singletonList(theVerifier);
}
List<JwsSignatureVerifier> theVerifiers = null;
if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
List<JsonWebKey> jwks = JwkUtils.loadJsonWebKeys(m, props, KeyOperation.VERIFY);
if (jwks != null) {
theVerifiers = new ArrayList<>(jwks.size());
for (JsonWebKey jwk : jwks) {
theVerifiers.add(JwsUtils.getSignatureVerifier(jwk));
}
}
}
if (theVerifiers == null) {
LOG.warning("Verifiers are not available");
throw new JwsException(JwsException.Error.NO_VERIFIER);
}
return theVerifiers;
}
public static boolean validateCriticalHeaders(JwsHeaders headers) {
//TODO: validate JWS specific constraints
return JoseUtils.validateCriticalHeaders(headers);
}
public static JwsSignatureProvider loadSignatureProvider(Properties props,
JwsHeaders headers) {
return loadSignatureProvider(PhaseInterceptorChain.getCurrentMessage(),
props, headers);
}
public static JwsSignatureProvider loadSignatureProvider(Message m,
Properties props,
JwsHeaders headers) {
return loadSignatureProvider(m, props, headers, false);
}
public static JwsSignatureProvider loadSignatureProvider(String propertiesLoc, Bus bus) {
Properties props = loadSignatureProperties(propertiesLoc, bus);
return loadSignatureProvider(props, null);
}
private static JwsSignatureProvider loadSignatureProvider(Message m,
Properties props,
JwsHeaders headers,
boolean ignoreNullProvider) {
JwsSignatureProvider theSigProvider = null;
boolean includeCert = headers != null && MessageUtils.getContextualBoolean(
m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT, false);
boolean includeCertSha1 = headers != null && MessageUtils.getContextualBoolean(
m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT_SHA1, false);
boolean includeCertSha256 = !includeCertSha1 && headers != null && MessageUtils.getContextualBoolean(
m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT_SHA256, false);
boolean includeKeyId = headers != null && MessageUtils.getContextualBoolean(
m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_KEY_ID, false);
if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, KeyOperation.SIGN);
if (jwk != null) {
SignatureAlgorithm signatureAlgo = getSignatureAlgorithm(m,
props,
SignatureAlgorithm.getAlgorithm(jwk.getAlgorithm()),
getDefaultKeyAlgorithm(jwk));
theSigProvider = JwsUtils.getSignatureProvider(jwk, signatureAlgo);
boolean includePublicKey = headers != null && MessageUtils.getContextualBoolean(
m, JoseConstants.RSSEC_SIGNATURE_INCLUDE_PUBLIC_KEY, false);
if (includeCert) {
JwkUtils.includeCertChain(jwk, headers, signatureAlgo.getJwaName());
}
if (includeCertSha1) {
String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m,
props, MessageDigestUtils.ALGO_SHA_1);
if (digest != null) {
headers.setX509Thumbprint(digest);
}
} else if (includeCertSha256) {
String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m,
props, MessageDigestUtils.ALGO_SHA_256);
if (digest != null) {
headers.setX509ThumbprintSHA256(digest);
}
}
if (includePublicKey) {
JwkUtils.includePublicKey(jwk, headers, signatureAlgo.getJwaName());
}
if (includeKeyId && jwk.getKeyId() != null) {
headers.setKeyId(jwk.getKeyId());
}
}
} else {
SignatureAlgorithm signatureAlgo = getSignatureAlgorithm(m, props, null, null);
if (signatureAlgo == SignatureAlgorithm.NONE) {
theSigProvider = new NoneJwsSignatureProvider();
} else {
PrivateKey pk = KeyManagementUtils.loadPrivateKey(m, props, KeyOperation.SIGN);
if (signatureAlgo == null) {
signatureAlgo = getDefaultPrivateKeyAlgorithm(pk);
}
theSigProvider = getPrivateKeySignatureProvider(pk, signatureAlgo);
if (includeCert) {
headers.setX509Chain(KeyManagementUtils.loadAndEncodeX509CertificateOrChain(m, props));
}
if (includeCertSha1) {
String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m,
props, MessageDigestUtils.ALGO_SHA_1);
if (digest != null) {
headers.setX509Thumbprint(digest);
}
} else if (includeCertSha256) {
String digest = KeyManagementUtils.loadDigestAndEncodeX509Certificate(m,
props, MessageDigestUtils.ALGO_SHA_256);
if (digest != null) {
headers.setX509ThumbprintSHA256(digest);
}
}
if (includeKeyId && props.containsKey(JoseConstants.RSSEC_KEY_STORE_ALIAS)) {
headers.setKeyId(props.getProperty(JoseConstants.RSSEC_KEY_STORE_ALIAS));
}
}
}
if (theSigProvider == null && !ignoreNullProvider) {
LOG.warning("Provider is not available");
throw new JwsException(JwsException.Error.NO_PROVIDER);
}
return theSigProvider;
}
public static JwsSignatureVerifier loadSignatureVerifier(Properties props,
JwsHeaders inHeaders) {
return loadSignatureVerifier(PhaseInterceptorChain.getCurrentMessage(),
props, inHeaders, false);
}
public static JwsSignatureVerifier loadSignatureVerifier(Message m,
Properties props,
JwsHeaders inHeaders,
boolean ignoreNullVerifier) {
JwsSignatureVerifier theVerifier = null;
String inHeaderKid = null;
if (inHeaders != null) {
inHeaderKid = inHeaders.getKeyId();
//TODO: optionally validate inHeaders.getAlgorithm against a property in props
if (inHeaders.getHeader(JoseConstants.HEADER_JSON_WEB_KEY) != null) {
JsonWebKey publicJwk = inHeaders.getJsonWebKey();
if (inHeaderKid != null && !inHeaderKid.equals(publicJwk.getKeyId())
|| !MessageUtils.getContextualBoolean(m, JoseConstants.RSSEC_ACCEPT_PUBLIC_KEY, false)) {
throw new JwsException(JwsException.Error.INVALID_KEY);
}
return getSignatureVerifier(publicJwk,
inHeaders.getSignatureAlgorithm());
} else if (inHeaders.getHeader(JoseConstants.HEADER_X509_CHAIN) != null) {
List<X509Certificate> chain = KeyManagementUtils.toX509CertificateChain(inHeaders.getX509Chain());
KeyManagementUtils.validateCertificateChain(props, chain);
return getPublicKeySignatureVerifier(chain.get(0),
inHeaders.getSignatureAlgorithm());
} else if (inHeaders.getHeader(JoseConstants.HEADER_X509_THUMBPRINT) != null) {
X509Certificate foundCert =
KeyManagementUtils.getCertificateFromThumbprint(inHeaders.getX509Thumbprint(),
MessageDigestUtils.ALGO_SHA_1,
m, props);
if (foundCert != null) {
return getPublicKeySignatureVerifier(foundCert,
inHeaders.getSignatureAlgorithm());
}
} else if (inHeaders.getHeader(JoseConstants.HEADER_X509_THUMBPRINT_SHA256) != null) {
X509Certificate foundCert =
KeyManagementUtils.getCertificateFromThumbprint(inHeaders.getX509ThumbprintSHA256(),
MessageDigestUtils.ALGO_SHA_256,
m, props);
if (foundCert != null) {
return getPublicKeySignatureVerifier(foundCert,
inHeaders.getSignatureAlgorithm());
}
}
}
if (JoseConstants.HEADER_JSON_WEB_KEY.equals(props.get(JoseConstants.RSSEC_KEY_STORE_TYPE))) {
JsonWebKey jwk = JwkUtils.loadJsonWebKey(m, props, KeyOperation.VERIFY, inHeaderKid);
if (jwk != null) {
SignatureAlgorithm signatureAlgo = getSignatureAlgorithm(m, props,
SignatureAlgorithm.getAlgorithm(jwk.getAlgorithm()),
getDefaultKeyAlgorithm(jwk));
theVerifier = getSignatureVerifier(jwk, signatureAlgo);
}
} else {
SignatureAlgorithm signatureAlgo = getSignatureAlgorithm(m, props, null, null);
if (signatureAlgo == SignatureAlgorithm.NONE
&& SignatureAlgorithm.NONE.getJwaName().equals(inHeaders.getAlgorithm())) {
theVerifier = new NoneJwsSignatureVerifier();
} else {
X509Certificate[] certs = KeyManagementUtils.loadX509CertificateOrChain(m, props);
if (certs != null && certs.length > 0) {
theVerifier = getPublicKeySignatureVerifier(certs[0], signatureAlgo);
}
}
}
if (theVerifier == null && !ignoreNullVerifier) {
LOG.warning("Verifier is not available");
throw new JwsException(JwsException.Error.NO_VERIFIER);
}
return theVerifier;
}
private static Properties loadJwsProperties(Message m, String propLoc) {
try {
return JoseUtils.loadProperties(propLoc, m.getExchange().getBus());
} catch (Exception ex) {
LOG.warning("JWS init properties are not available");
throw new JwsException(JwsException.Error.NO_INIT_PROPERTIES);
}
}
public static SignatureAlgorithm getSignatureAlgorithm(Message m, Properties props,
SignatureAlgorithm algo,
SignatureAlgorithm defaultAlgo) {
if (algo == null) {
algo = getSignatureAlgorithm(m, props, defaultAlgo);
}
return algo;
}
public static SignatureAlgorithm getSignatureAlgorithm(Properties props,
SignatureAlgorithm defaultAlgo) {
return getSignatureAlgorithm(PhaseInterceptorChain.getCurrentMessage(),
props, defaultAlgo);
}
public static SignatureAlgorithm getSignatureAlgorithm(Message m,
Properties props,
SignatureAlgorithm defaultAlgo) {
String algo = KeyManagementUtils.getKeyAlgorithm(m,
props,
JoseConstants.RSSEC_SIGNATURE_ALGORITHM,
defaultAlgo == null ? null : defaultAlgo.getJwaName());
return SignatureAlgorithm.getAlgorithm(algo);
}
private static SignatureAlgorithm getDefaultKeyAlgorithm(JsonWebKey jwk) {
KeyType keyType = jwk.getKeyType();
if (KeyType.OCTET == keyType) {
return SignatureAlgorithm.HS256;
} else if (KeyType.EC == keyType) {
return SignatureAlgorithm.ES256;
} else {
return SignatureAlgorithm.RS256;
}
}
private static SignatureAlgorithm getDefaultPrivateKeyAlgorithm(PrivateKey key) {
if (key instanceof RSAPrivateKey) {
return SignatureAlgorithm.RS256;
} else if (key instanceof ECPrivateKey) {
return SignatureAlgorithm.ES256;
} else {
return null;
}
}
private static SignatureAlgorithm getDefaultPublicKeyAlgorithm(PublicKey key) {
if (key instanceof RSAPublicKey) {
return SignatureAlgorithm.RS256;
} else if (key instanceof ECPublicKey) {
return SignatureAlgorithm.ES256;
} else {
return null;
}
}
public static JwsCompactConsumer verify(JwsSignatureVerifier v, String content) {
JwsCompactConsumer jws = new JwsCompactConsumer(content);
if (!jws.verifySignatureWith(v)) {
throw new JwsException(JwsException.Error.INVALID_SIGNATURE);
}
return jws;
}
public static String sign(JwsSignatureProvider jwsSig, String content, String ct) {
JwsHeaders headers = new JwsHeaders();
if (ct != null) {
headers.setContentType(ct);
}
JwsCompactProducer jws = new JwsCompactProducer(headers, content);
jws.signWith(jwsSig);
return jws.getSignedEncodedJws();
}
public static void validateJwsCertificateChain(List<X509Certificate> certs) {
Properties props = loadSignatureInProperties(true);
KeyManagementUtils.validateCertificateChain(props, certs);
}
public static boolean isPayloadUnencoded(JwsHeaders jwsHeaders) {
return jwsHeaders.getPayloadEncodingStatus() == Boolean.FALSE;
}
public static void checkSignatureKeySize(Key key) {
if (key instanceof RSAKey && ((RSAKey)key).getModulus().bitLength() < 2048) {
LOG.fine("A key of size: " + ((RSAKey)key).getModulus().bitLength()
+ " was used with an RSA signature algorithm. 2048 is the minimum size that is accepted");
throw new JwsException(JwsException.Error.INVALID_KEY);
}
}
public static JsonWebKeys loadPublicVerificationKeys(Message m, Properties props) {
String storeType = props.getProperty(JoseConstants.RSSEC_KEY_STORE_TYPE);
if ("jwk".equals(storeType)) {
return JwkUtils.loadPublicJwkSet(m, props);
} else {
X509Certificate[] certs = null;
if (PropertyUtils.isTrue(props.get(JoseConstants.RSSEC_SIGNATURE_INCLUDE_CERT))) {
certs = KeyManagementUtils.loadX509CertificateOrChain(m, props);
}
PublicKey key = certs != null && certs.length > 0
? certs[0].getPublicKey() : KeyManagementUtils.loadPublicKey(m, props);
JsonWebKey jwk = JwkUtils.fromPublicKey(key, props, JoseConstants.RSSEC_SIGNATURE_ALGORITHM);
jwk.setPublicKeyUse(PublicKeyUse.SIGN);
if (certs != null) {
jwk.setX509Chain(KeyManagementUtils.encodeX509CertificateChain(certs));
}
return new JsonWebKeys(jwk);
}
}
}