in src/main/java/org/apache/xml/security/stax/impl/processor/input/AbstractSignatureInputHandler.java [245:418]
protected abstract SignatureVerifier newSignatureVerifier(InputProcessorChain inputProcessorChain,
XMLSecurityProperties securityProperties,
final SignatureType signatureType) throws XMLSecurityException;
/*
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="Signature-1022834285">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<ds:Reference URI="#id-1612925417">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>cy/khx5N6UobCJ1EbX+qnrGID2U=</ds:DigestValue>
</ds:Reference>
<ds:Reference URI="#Timestamp-1106985890">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<ds:DigestValue>+p5YRII6uvUdsJ7XLKkWx1CBewE=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>
Izg1FlI9oa4gOon2vTXi7V0EpiyCUazECVGYflbXq7/3GF8ThKGDMpush/fo1I2NVjEFTfmT2WP/
+ZG5N2jASFptrcGbsqmuLE5JbxUP1TVKb9SigKYcOQJJ8klzmVfPXnSiRZmIU+DUT2UXopWnGNFL
TwY0Uxja4ZuI6U8m8Tg=
</ds:SignatureValue>
<ds:KeyInfo Id="KeyId-1043455692">
<wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="STRId-1008354042">
<wsse:Reference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
URI="#CertId-3458500" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
</wsse:SecurityTokenReference>
</ds:KeyInfo>
</ds:Signature>
*/
public abstract class SignatureVerifier {
private final SignatureType signatureType;
private final InboundSecurityToken inboundSecurityToken;
private SignerOutputStream signerOutputStream;
private OutputStream bufferedSignerOutputStream;
private Transformer transformer;
public SignatureVerifier(SignatureType signatureType, InboundSecurityContext inboundSecurityContext,
XMLSecurityProperties securityProperties) throws XMLSecurityException {
this.signatureType = signatureType;
InboundSecurityToken inboundSecurityToken =
retrieveSecurityToken(signatureType, securityProperties, inboundSecurityContext);
this.inboundSecurityToken = inboundSecurityToken;
createSignatureAlgorithm(inboundSecurityToken, signatureType);
}
protected abstract InboundSecurityToken retrieveSecurityToken(SignatureType signatureType,
XMLSecurityProperties securityProperties,
InboundSecurityContext inboundSecurityContext) throws XMLSecurityException;
public InboundSecurityToken getInboundSecurityToken() {
return inboundSecurityToken;
}
protected void createSignatureAlgorithm(InboundSecurityToken inboundSecurityToken, SignatureType signatureType)
throws XMLSecurityException {
Key verifyKey;
final String algorithmURI = signatureType.getSignedInfo().getSignatureMethod().getAlgorithm();
if (inboundSecurityToken.isAsymmetric()) {
verifyKey = inboundSecurityToken.getPublicKey(algorithmURI, XMLSecurityConstants.Asym_Sig, signatureType.getId());
} else {
verifyKey = inboundSecurityToken.getSecretKey(
algorithmURI, XMLSecurityConstants.Sym_Sig, signatureType.getId());
if (verifyKey != null) {
verifyKey = XMLSecurityUtils.prepareSecretKey(algorithmURI, verifyKey.getEncoded());
}
}
if (verifyKey == null) {
throw new XMLSecurityException("KeyInfo.nokey", new Object[]{"the inbound security token"});
}
try {
SignatureAlgorithm signatureAlgorithm =
SignatureAlgorithmFactory.getInstance().getSignatureAlgorithm(
algorithmURI);
if (XMLSignature.ALGO_ID_SIGNATURE_RSA_PSS.equals(algorithmURI)) {
PSSParameterSpec spec = rsaPSSParameterSpec(signatureType);
signatureAlgorithm.engineSetParameter(spec);
}
signatureAlgorithm.engineInitVerify(verifyKey);
signerOutputStream = new SignerOutputStream(signatureAlgorithm);
bufferedSignerOutputStream = new UnsyncBufferedOutputStream(signerOutputStream);
final CanonicalizationMethodType canonicalizationMethodType =
signatureType.getSignedInfo().getCanonicalizationMethod();
InclusiveNamespaces inclusiveNamespacesType =
XMLSecurityUtils.getQNameType(
canonicalizationMethodType.getContent(),
XMLSecurityConstants.TAG_c14nExcl_InclusiveNamespaces
);
Map<String, Object> transformerProperties = null;
if (inclusiveNamespacesType != null) {
transformerProperties = new HashMap<>();
transformerProperties.put(
Canonicalizer20010315_Excl.INCLUSIVE_NAMESPACES_PREFIX_LIST,
inclusiveNamespacesType.getPrefixList());
}
transformer = XMLSecurityUtils.getTransformer(
null,
this.bufferedSignerOutputStream,
transformerProperties,
canonicalizationMethodType.getAlgorithm(),
XMLSecurityConstants.DIRECTION.IN);
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
throw new XMLSecurityException(e);
}
// Clean the secret key from memory now that we're done with it
if (verifyKey instanceof Destroyable) {
try {
((Destroyable)verifyKey).destroy();
} catch (DestroyFailedException e) {
LOG.log(Level.DEBUG, "Error destroying key: {0}", e.getMessage());
}
}
}
private PSSParameterSpec rsaPSSParameterSpec(SignatureType signatureType) throws XMLSecurityException {
SignatureMethodType signatureMethod = signatureType.getSignedInfo().getSignatureMethod();
RSAPSSParamsType rsapssParams = null;
for (Object o : signatureMethod.getContent()) {
if (o instanceof RSAPSSParamsType) {
rsapssParams = (RSAPSSParamsType) o;
break;
}
}
if (rsapssParams == null) {
throw new XMLSecurityException("algorithms.MissingRSAPSSParams");
}
String digestMethod = rsapssParams.getDigestMethod() == null ? SHA256.getXmlDigestAlgorithm() : rsapssParams.getDigestMethod().getAlgorithm();
String maskGenerationDigestMethod = rsapssParams.getMaskGenerationFunction() == null ? SHA256.getXmlDigestAlgorithm() : rsapssParams.getMaskGenerationFunction().getDigestMethod().getAlgorithm();
DigestAlgorithm digestAlgorithm = fromXmlDigestAlgorithm(digestMethod);
int saltLength = rsapssParams.getSaltLength() == null ? digestAlgorithm.getSaltLength() : rsapssParams.getSaltLength();
int trailerField = rsapssParams.getTrailerField() == null ? 1 : rsapssParams.getTrailerField();
String maskDigestAlgorithm = fromXmlDigestAlgorithm(maskGenerationDigestMethod).getDigestAlgorithm();
return new PSSParameterSpec(digestAlgorithm.getDigestAlgorithm(), "MGF1",
new MGF1ParameterSpec(maskDigestAlgorithm), saltLength, trailerField);
}
protected void processEvent(XMLSecEvent xmlSecEvent) throws XMLStreamException {
transformer.transform(xmlSecEvent);
}
protected void doFinal() throws XMLSecurityException {
try {
transformer.doFinal();
bufferedSignerOutputStream.close();
} catch (IOException | XMLStreamException e) {
throw new XMLSecurityException(e);
}
if (!signerOutputStream.verify(signatureType.getSignatureValue().getValue())) {
throw new XMLSecurityException("errorMessages.InvalidSignatureValueException");
}
}
}