KEYCLOAK-1881 Include key ID in <ds:KeyInfo> in SAML assertions and protocol message

Changes of SAML assertion creation/parsing that are required to allow
for validation of rotating realm key: signed SAML assertions and signed
SAML protocol message now contain signing key ID in XML <dsig:KeyName>
element.
This commit is contained in:
Hynek Mlnarik 2016-10-24 22:43:48 +02:00
parent 904a5c3ca5
commit 5d840500af
10 changed files with 68 additions and 52 deletions

View file

@ -79,7 +79,7 @@ public abstract class AbstractInitiateLogin implements AuthChallenge {
binding.canonicalizationMethod(deployment.getSignatureCanonicalizationMethod()); binding.canonicalizationMethod(deployment.getSignatureCanonicalizationMethod());
} }
binding.signWith(keypair); binding.signWith(null, keypair);
binding.signDocument(); binding.signDocument();
} }
return binding; return binding;

View file

@ -82,7 +82,7 @@ public class WebBrowserSsoAuthenticationHandler extends AbstractSamlAuthenticati
if (deployment.getSignatureCanonicalizationMethod() != null) if (deployment.getSignatureCanonicalizationMethod() != null)
binding.canonicalizationMethod(deployment.getSignatureCanonicalizationMethod()); binding.canonicalizationMethod(deployment.getSignatureCanonicalizationMethod());
binding.signatureAlgorithm(deployment.getSignatureAlgorithm()) binding.signatureAlgorithm(deployment.getSignatureAlgorithm())
.signWith(deployment.getSigningKeyPair()) .signWith(null, deployment.getSigningKeyPair())
.signDocument(); .signDocument();
} }
@ -113,7 +113,7 @@ public class WebBrowserSsoAuthenticationHandler extends AbstractSamlAuthenticati
if (deployment.getSignatureCanonicalizationMethod() != null) if (deployment.getSignatureCanonicalizationMethod() != null)
binding.canonicalizationMethod(deployment.getSignatureCanonicalizationMethod()); binding.canonicalizationMethod(deployment.getSignatureCanonicalizationMethod());
binding.signatureAlgorithm(deployment.getSignatureAlgorithm()); binding.signatureAlgorithm(deployment.getSignatureAlgorithm());
binding.signWith(deployment.getSigningKeyPair()) binding.signWith(null, deployment.getSigningKeyPair())
.signDocument(); .signDocument();
} }

View file

@ -55,6 +55,7 @@ import static org.keycloak.saml.common.util.StringUtil.isNotNull;
public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> { public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
protected static final Logger logger = Logger.getLogger(BaseSAML2BindingBuilder.class); protected static final Logger logger = Logger.getLogger(BaseSAML2BindingBuilder.class);
protected String signingKeyId;
protected KeyPair signingKeyPair; protected KeyPair signingKeyPair;
protected X509Certificate signingCertificate; protected X509Certificate signingCertificate;
protected boolean sign; protected boolean sign;
@ -82,23 +83,27 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
return (T)this; return (T)this;
} }
public T signWith(KeyPair keyPair) { public T signWith(String signingKeyId, KeyPair keyPair) {
this.signingKeyId = signingKeyId;
this.signingKeyPair = keyPair; this.signingKeyPair = keyPair;
return (T)this; return (T)this;
} }
public T signWith(PrivateKey privateKey, PublicKey publicKey) { public T signWith(String signingKeyId, PrivateKey privateKey, PublicKey publicKey) {
this.signingKeyId = signingKeyId;
this.signingKeyPair = new KeyPair(publicKey, privateKey); this.signingKeyPair = new KeyPair(publicKey, privateKey);
return (T)this; return (T)this;
} }
public T signWith(KeyPair keyPair, X509Certificate cert) { public T signWith(String signingKeyId, KeyPair keyPair, X509Certificate cert) {
this.signingKeyId = signingKeyId;
this.signingKeyPair = keyPair; this.signingKeyPair = keyPair;
this.signingCertificate = cert; this.signingCertificate = cert;
return (T)this; return (T)this;
} }
public T signWith(PrivateKey privateKey, PublicKey publicKey, X509Certificate cert) { public T signWith(String signingKeyId, PrivateKey privateKey, PublicKey publicKey, X509Certificate cert) {
this.signingKeyId = signingKeyId;
this.signingKeyPair = new KeyPair(publicKey, privateKey); this.signingKeyPair = new KeyPair(publicKey, privateKey);
this.signingCertificate = cert; this.signingCertificate = cert;
return (T)this; return (T)this;
@ -263,7 +268,7 @@ public class BaseSAML2BindingBuilder<T extends BaseSAML2BindingBuilder> {
samlSignature.setX509Certificate(signingCertificate); samlSignature.setX509Certificate(signingCertificate);
} }
samlSignature.signSAMLDocument(samlDocument, signingKeyPair, canonicalizationMethodType); samlSignature.signSAMLDocument(samlDocument, signingKeyId, signingKeyPair, canonicalizationMethodType);
} }
public void signAssertion(Document samlDocument) throws ProcessingException { public void signAssertion(Document samlDocument) throws ProcessingException {

View file

@ -121,7 +121,7 @@ public class SAML2Signature {
* @throws MarshalException * @throws MarshalException
* @throws GeneralSecurityException * @throws GeneralSecurityException
*/ */
public Document sign(Document doc, String referenceID, KeyPair keyPair, String canonicalizationMethodType) throws ParserConfigurationException, public Document sign(Document doc, String referenceID, String keyId, KeyPair keyPair, String canonicalizationMethodType) throws ParserConfigurationException,
GeneralSecurityException, MarshalException, XMLSignatureException { GeneralSecurityException, MarshalException, XMLSignatureException {
String referenceURI = "#" + referenceID; String referenceURI = "#" + referenceID;
@ -130,6 +130,7 @@ public class SAML2Signature {
if (sibling != null) { if (sibling != null) {
SignatureUtilTransferObject dto = new SignatureUtilTransferObject(); SignatureUtilTransferObject dto = new SignatureUtilTransferObject();
dto.setDocumentToBeSigned(doc); dto.setDocumentToBeSigned(doc);
dto.setKeyId(keyId);
dto.setKeyPair(keyPair); dto.setKeyPair(keyPair);
dto.setDigestMethod(digestMethod); dto.setDigestMethod(digestMethod);
dto.setSignatureMethod(signatureMethod); dto.setSignatureMethod(signatureMethod);
@ -142,7 +143,7 @@ public class SAML2Signature {
return XMLSignatureUtil.sign(dto, canonicalizationMethodType); return XMLSignatureUtil.sign(dto, canonicalizationMethodType);
} }
return XMLSignatureUtil.sign(doc, keyPair, digestMethod, signatureMethod, referenceURI, canonicalizationMethodType); return XMLSignatureUtil.sign(doc, keyId, keyPair, digestMethod, signatureMethod, referenceURI, canonicalizationMethodType);
} }
/** /**
@ -153,11 +154,11 @@ public class SAML2Signature {
* *
* @throws org.keycloak.saml.common.exceptions.ProcessingException * @throws org.keycloak.saml.common.exceptions.ProcessingException
*/ */
public void signSAMLDocument(Document samlDocument, KeyPair keypair, String canonicalizationMethodType) throws ProcessingException { public void signSAMLDocument(Document samlDocument, String keyId, KeyPair keypair, String canonicalizationMethodType) throws ProcessingException {
// Get the ID from the root // Get the ID from the root
String id = samlDocument.getDocumentElement().getAttribute(ID_ATTRIBUTE_NAME); String id = samlDocument.getDocumentElement().getAttribute(ID_ATTRIBUTE_NAME);
try { try {
sign(samlDocument, id, keypair, canonicalizationMethodType); sign(samlDocument, id, keyId, keypair, canonicalizationMethodType);
} catch (Exception e) { } catch (Exception e) {
throw new ProcessingException(logger.signatureError(e)); throw new ProcessingException(logger.signatureError(e));
} }

View file

@ -32,6 +32,9 @@ public class SignatureUtilTransferObject {
private X509Certificate x509Certificate; private X509Certificate x509Certificate;
private Document documentToBeSigned; private Document documentToBeSigned;
private String keyId;
private KeyPair keyPair; private KeyPair keyPair;
private Node nextSibling; private Node nextSibling;
@ -111,4 +114,12 @@ public class SignatureUtilTransferObject {
public void setX509Certificate(X509Certificate x509Certificate) { public void setX509Certificate(X509Certificate x509Certificate) {
this.x509Certificate = x509Certificate; this.x509Certificate = x509Certificate;
} }
public String getKeyId() {
return keyId;
}
public void setKeyId(String keyId) {
this.keyId = keyId;
}
} }

View file

@ -79,7 +79,9 @@ import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPublicKey; import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import javax.xml.crypto.dsig.keyinfo.KeyName;
/** /**
* Utility for XML Signature <b>Note:</b> You can change the canonicalization method type by using the system property * Utility for XML Signature <b>Note:</b> You can change the canonicalization method type by using the system property
@ -157,7 +159,7 @@ public class XMLSignatureUtil {
* @throws MarshalException * @throws MarshalException
* @throws GeneralSecurityException * @throws GeneralSecurityException
*/ */
public static Document sign(Document doc, Node nodeToBeSigned, KeyPair keyPair, String digestMethod, public static Document sign(Document doc, Node nodeToBeSigned, String keyId, KeyPair keyPair, String digestMethod,
String signatureMethod, String referenceURI, X509Certificate x509Certificate, String signatureMethod, String referenceURI, X509Certificate x509Certificate,
String canonicalizationMethodType) throws ParserConfigurationException, GeneralSecurityException, String canonicalizationMethodType) throws ParserConfigurationException, GeneralSecurityException,
MarshalException, XMLSignatureException { MarshalException, XMLSignatureException {
@ -179,7 +181,7 @@ public class XMLSignatureUtil {
if (!referenceURI.isEmpty()) { if (!referenceURI.isEmpty()) {
propagateIDAttributeSetup(nodeToBeSigned, newDoc.getDocumentElement()); propagateIDAttributeSetup(nodeToBeSigned, newDoc.getDocumentElement());
} }
newDoc = sign(newDoc, keyPair, digestMethod, signatureMethod, referenceURI, x509Certificate, canonicalizationMethodType); newDoc = sign(newDoc, keyId, keyPair, digestMethod, signatureMethod, referenceURI, x509Certificate, canonicalizationMethodType);
// if the signed element is a SAMLv2.0 assertion we need to move the signature element to the position // if the signed element is a SAMLv2.0 assertion we need to move the signature element to the position
// specified in the schema (before the assertion subject element). // specified in the schema (before the assertion subject element).
@ -220,10 +222,10 @@ public class XMLSignatureUtil {
* @throws MarshalException * @throws MarshalException
* @throws XMLSignatureException * @throws XMLSignatureException
*/ */
public static void sign(Element elementToSign, Node nextSibling, KeyPair keyPair, String digestMethod, public static void sign(Element elementToSign, Node nextSibling, String keyId, KeyPair keyPair, String digestMethod,
String signatureMethod, String referenceURI, String canonicalizationMethodType) String signatureMethod, String referenceURI, String canonicalizationMethodType)
throws GeneralSecurityException, MarshalException, XMLSignatureException { throws GeneralSecurityException, MarshalException, XMLSignatureException {
sign(elementToSign, nextSibling, keyPair, digestMethod, signatureMethod, referenceURI, null, canonicalizationMethodType); sign(elementToSign, nextSibling, keyId, keyPair, digestMethod, signatureMethod, referenceURI, null, canonicalizationMethodType);
} }
/** /**
@ -242,7 +244,7 @@ public class XMLSignatureUtil {
* @throws XMLSignatureException * @throws XMLSignatureException
* @since 2.5.0 * @since 2.5.0
*/ */
public static void sign(Element elementToSign, Node nextSibling, KeyPair keyPair, String digestMethod, public static void sign(Element elementToSign, Node nextSibling, String keyId, KeyPair keyPair, String digestMethod,
String signatureMethod, String referenceURI, X509Certificate x509Certificate, String canonicalizationMethodType) String signatureMethod, String referenceURI, X509Certificate x509Certificate, String canonicalizationMethodType)
throws GeneralSecurityException, MarshalException, XMLSignatureException { throws GeneralSecurityException, MarshalException, XMLSignatureException {
PrivateKey signingKey = keyPair.getPrivate(); PrivateKey signingKey = keyPair.getPrivate();
@ -250,7 +252,7 @@ public class XMLSignatureUtil {
DOMSignContext dsc = new DOMSignContext(signingKey, elementToSign, nextSibling); DOMSignContext dsc = new DOMSignContext(signingKey, elementToSign, nextSibling);
signImpl(dsc, digestMethod, signatureMethod, referenceURI, publicKey, x509Certificate, canonicalizationMethodType); signImpl(dsc, digestMethod, signatureMethod, referenceURI, keyId, publicKey, x509Certificate, canonicalizationMethodType);
} }
/** /**
@ -284,9 +286,9 @@ public class XMLSignatureUtil {
* @throws XMLSignatureException * @throws XMLSignatureException
* @throws MarshalException * @throws MarshalException
*/ */
public static Document sign(Document doc, KeyPair keyPair, String digestMethod, String signatureMethod, String referenceURI, String canonicalizationMethodType) public static Document sign(Document doc, String keyId, KeyPair keyPair, String digestMethod, String signatureMethod, String referenceURI, String canonicalizationMethodType)
throws GeneralSecurityException, MarshalException, XMLSignatureException { throws GeneralSecurityException, MarshalException, XMLSignatureException {
return sign(doc, keyPair, digestMethod, signatureMethod, referenceURI, null, canonicalizationMethodType); return sign(doc, keyId, keyPair, digestMethod, signatureMethod, referenceURI, null, canonicalizationMethodType);
} }
/** /**
@ -304,7 +306,7 @@ public class XMLSignatureUtil {
* @throws MarshalException * @throws MarshalException
* @since 2.5.0 * @since 2.5.0
*/ */
public static Document sign(Document doc, KeyPair keyPair, String digestMethod, String signatureMethod, String referenceURI, public static Document sign(Document doc, String keyId, KeyPair keyPair, String digestMethod, String signatureMethod, String referenceURI,
X509Certificate x509Certificate, String canonicalizationMethodType) X509Certificate x509Certificate, String canonicalizationMethodType)
throws GeneralSecurityException, MarshalException, XMLSignatureException { throws GeneralSecurityException, MarshalException, XMLSignatureException {
logger.trace("Document to be signed=" + DocumentUtil.asString(doc)); logger.trace("Document to be signed=" + DocumentUtil.asString(doc));
@ -313,7 +315,7 @@ public class XMLSignatureUtil {
DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement()); DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement());
signImpl(dsc, digestMethod, signatureMethod, referenceURI, publicKey, x509Certificate, canonicalizationMethodType); signImpl(dsc, digestMethod, signatureMethod, referenceURI, keyId, publicKey, x509Certificate, canonicalizationMethodType);
return doc; return doc;
} }
@ -344,7 +346,7 @@ public class XMLSignatureUtil {
DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement(), nextSibling); DOMSignContext dsc = new DOMSignContext(signingKey, doc.getDocumentElement(), nextSibling);
signImpl(dsc, digestMethod, signatureMethod, referenceURI, publicKey, dto.getX509Certificate(), canonicalizationMethodType); signImpl(dsc, digestMethod, signatureMethod, referenceURI, dto.getKeyId(), publicKey, dto.getX509Certificate(), canonicalizationMethodType);
return doc; return doc;
} }
@ -594,7 +596,7 @@ public class XMLSignatureUtil {
throw logger.unsupportedType(key.toString()); throw logger.unsupportedType(key.toString());
} }
private static void signImpl(DOMSignContext dsc, String digestMethod, String signatureMethod, String referenceURI, PublicKey publicKey, private static void signImpl(DOMSignContext dsc, String digestMethod, String signatureMethod, String referenceURI, String keyId, PublicKey publicKey,
X509Certificate x509Certificate, String canonicalizationMethodType) X509Certificate x509Certificate, String canonicalizationMethodType)
throws GeneralSecurityException, MarshalException, XMLSignatureException { throws GeneralSecurityException, MarshalException, XMLSignatureException {
dsc.setDefaultNamespacePrefix("dsig"); dsc.setDefaultNamespacePrefix("dsig");
@ -618,35 +620,32 @@ public class XMLSignatureUtil {
KeyInfo ki = null; KeyInfo ki = null;
if (includeKeyInfoInSignature) { if (includeKeyInfoInSignature) {
ki = createKeyInfo(publicKey, x509Certificate); ki = createKeyInfo(keyId, publicKey, x509Certificate);
} else {
ki = createKeyInfo(keyId, null, null);
} }
XMLSignature signature = fac.newXMLSignature(si, ki); XMLSignature signature = fac.newXMLSignature(si, ki);
signature.sign(dsc); signature.sign(dsc);
} }
private static KeyInfo createKeyInfo(PublicKey publicKey, X509Certificate x509Certificate) throws KeyException { private static KeyInfo createKeyInfo(String keyId, PublicKey publicKey, X509Certificate x509Certificate) throws KeyException {
KeyInfoFactory keyInfoFactory = fac.getKeyInfoFactory(); KeyInfoFactory keyInfoFactory = fac.getKeyInfoFactory();
KeyInfo keyInfo = null;
KeyValue keyValue = null; List<Object> items = new LinkedList<>();
//Just with public key
if (publicKey != null) { if (keyId != null) {
keyValue = keyInfoFactory.newKeyValue(publicKey); items.add(keyInfoFactory.newKeyName(keyId));
keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(keyValue));
} }
if (x509Certificate != null) { if (x509Certificate != null) {
List x509list = new ArrayList(); items.add(keyInfoFactory.newX509Data(Collections.singletonList(x509Certificate)));
x509list.add(x509Certificate);
X509Data x509Data = keyInfoFactory.newX509Data(x509list);
List items = new ArrayList();
items.add(x509Data);
if (keyValue != null) {
items.add(keyValue);
}
keyInfo = keyInfoFactory.newKeyInfo(items);
} }
return keyInfo;
if (publicKey != null) {
items.add(keyInfoFactory.newKeyValue(publicKey));
}
return keyInfoFactory.newKeyInfo(items);
} }
} }

View file

@ -267,7 +267,7 @@ public class SAMLEndpoint {
.relayState(relayState); .relayState(relayState);
if (config.isWantAuthnRequestsSigned()) { if (config.isWantAuthnRequestsSigned()) {
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm); KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
binding.signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()) binding.signWith(keys.getKid(), keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate())
.signatureAlgorithm(provider.getSignatureAlgorithm()) .signatureAlgorithm(provider.getSignatureAlgorithm())
.signDocument(); .signDocument();
} }

View file

@ -103,7 +103,7 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
KeyPair keypair = new KeyPair(keys.getPublicKey(), keys.getPrivateKey()); KeyPair keypair = new KeyPair(keys.getPublicKey(), keys.getPrivateKey());
binding.signWith(keypair); binding.signWith(keys.getKid(), keypair);
binding.signatureAlgorithm(getSignatureAlgorithm()); binding.signatureAlgorithm(getSignatureAlgorithm());
binding.signDocument(); binding.signDocument();
} }
@ -198,7 +198,7 @@ public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityP
.relayState(userSession.getId()); .relayState(userSession.getId());
if (getConfig().isWantAuthnRequestsSigned()) { if (getConfig().isWantAuthnRequestsSigned()) {
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm); KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
binding.signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()) binding.signWith(keys.getKid(), keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate())
.signatureAlgorithm(getSignatureAlgorithm()) .signatureAlgorithm(getSignatureAlgorithm())
.signDocument(); .signDocument();
} }

View file

@ -402,14 +402,14 @@ public class SamlProtocol implements LoginProtocol {
if (canonicalization != null) { if (canonicalization != null) {
bindingBuilder.canonicalizationMethod(canonicalization); bindingBuilder.canonicalizationMethod(canonicalization);
} }
bindingBuilder.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument(); bindingBuilder.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keys.getKid(), keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument();
} }
if (samlClient.requiresAssertionSignature()) { if (samlClient.requiresAssertionSignature()) {
String canonicalization = samlClient.getCanonicalizationMethod(); String canonicalization = samlClient.getCanonicalizationMethod();
if (canonicalization != null) { if (canonicalization != null) {
bindingBuilder.canonicalizationMethod(canonicalization); bindingBuilder.canonicalizationMethod(canonicalization);
} }
bindingBuilder.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signAssertions(); bindingBuilder.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keys.getKid(), keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signAssertions();
} }
if (samlClient.requiresEncryption()) { if (samlClient.requiresEncryption()) {
PublicKey publicKey = null; PublicKey publicKey = null;
@ -541,7 +541,7 @@ public class SamlProtocol implements LoginProtocol {
binding.canonicalizationMethod(canonicalization); binding.canonicalizationMethod(canonicalization);
} }
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm); KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
binding.signatureAlgorithm(algorithm).signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument(); binding.signatureAlgorithm(algorithm).signWith(keys.getKid(), keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument();
} }
try { try {
@ -639,7 +639,7 @@ public class SamlProtocol implements LoginProtocol {
JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder(); JaxrsSAML2BindingBuilder binding = new JaxrsSAML2BindingBuilder();
if (samlClient.requiresRealmSignature()) { if (samlClient.requiresRealmSignature()) {
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm); KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
binding.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument(); binding.signatureAlgorithm(samlClient.getSignatureAlgorithm()).signWith(keys.getKid(), keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument();
} }
return binding; return binding;
} }

View file

@ -400,7 +400,7 @@ public class SamlService extends AuthorizationEndpointBase {
if (samlClient.requiresRealmSignature()) { if (samlClient.requiresRealmSignature()) {
SignatureAlgorithm algorithm = samlClient.getSignatureAlgorithm(); SignatureAlgorithm algorithm = samlClient.getSignatureAlgorithm();
KeyManager.ActiveKey keys = session.keys().getActiveKey(realm); KeyManager.ActiveKey keys = session.keys().getActiveKey(realm);
binding.signatureAlgorithm(algorithm).signWith(keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument(); binding.signatureAlgorithm(algorithm).signWith(keys.getKid(), keys.getPrivateKey(), keys.getPublicKey(), keys.getCertificate()).signDocument();
} }
try { try {