}
sig.addResourceResolver(EnvelopeIdResolver.getInstance());
KeyInfo info = sig.getKeyInfo();
UsernameToken ut = null;
DerivedKeyToken dkt = null;
SAMLKeyInfo samlKi = null;
String customTokenId = null;
java.security.PublicKey publicKey = null;
X509Certificate[] certs = null;
boolean validateCertificateChain = false;
if (info != null && info.containsKeyValue()) {
try {
publicKey = info.getPublicKey();
} catch (Exception ex) {
throw new WSSecurityException(ex.getMessage(), ex);
}
} else if (info != null) {
Node node =
WSSecurityUtil.getDirectChild(
info.getElement(),
SecurityTokenReference.SECURITY_TOKEN_REFERENCE,
WSConstants.WSSE_NS
);
if (node == null) {
throw new WSSecurityException(
WSSecurityException.INVALID_SECURITY, "unsupportedKeyInfo"
);
}
SecurityTokenReference secRef = new SecurityTokenReference((Element) node);
//
// Here we get some information about the document that is being
// processed, in particular the crypto implementation, and already
// detected BST that may be used later during dereferencing.
//
if (secRef.containsReference()) {
org.apache.ws.security.message.token.Reference ref = secRef.getReference();
String uri = ref.getURI();
if (uri.charAt(0) == '#') {
uri = uri.substring(1);
}
Processor processor = wsDocInfo.getProcessor(uri);
if (processor == null) {
Element token = secRef.getTokenElement(elem.getOwnerDocument(), wsDocInfo, cb);
//
// at this point check token type: Binary, SAML, EncryptedKey, Custom
//
QName el = new QName(token.getNamespaceURI(), token.getLocalName());
if (el.equals(WSSecurityEngine.binaryToken)) {
certs = getCertificatesTokenReference(token, crypto);
if (certs != null && certs.length > 1) {
validateCertificateChain = true;
}
} else if (el.equals(WSSecurityEngine.SAML_TOKEN)) {
if (crypto == null) {
throw new WSSecurityException(
WSSecurityException.FAILURE, "noSigCryptoFile"
);
}
samlKi = SAMLUtil.getSAMLKeyInfo(token, crypto, cb);
certs = samlKi.getCerts();
secretKey = samlKi.getSecret();
} else if (el.equals(WSSecurityEngine.ENCRYPTED_KEY)){
if (crypto == null) {
throw new WSSecurityException(
WSSecurityException.FAILURE, "noSigCryptoFile"
);
}
EncryptedKeyProcessor encryptKeyProcessor = new EncryptedKeyProcessor();
encryptKeyProcessor.handleEncryptedKey(token, cb, crypto);
secretKey = encryptKeyProcessor.getDecryptedBytes();
} else {
// Try custom token through callback handler
// try to find a custom token
String id = secRef.getReference().getURI();
if (id.charAt(0) == '#') {
id = id.substring(1);
}
WSPasswordCallback pwcb =
new WSPasswordCallback(id, WSPasswordCallback.CUSTOM_TOKEN);
try {
Callback[] callbacks = new Callback[]{pwcb};
cb.handle(callbacks);
} catch (Exception e) {
throw new WSSecurityException(
WSSecurityException.FAILURE,
"noPassword",
new Object[] {id},
e
);
}
secretKey = pwcb.getKey();
customTokenId = id;
if (secretKey == null) {
throw new WSSecurityException(
WSSecurityException.INVALID_SECURITY,
"unsupportedKeyInfo",
new Object[]{el.toString()}
);
}
}
} else if (processor instanceof UsernameTokenProcessor) {
ut = ((UsernameTokenProcessor)processor).getUt();
if (ut.isDerivedKey()) {
secretKey = ut.getDerivedKey();
} else {
secretKey = ut.getSecretKey(secretKeyLength);
}
} else if (processor instanceof BinarySecurityTokenProcessor) {
certs = ((BinarySecurityTokenProcessor)processor).getCertificates();
if (certs != null && certs.length > 1) {
validateCertificateChain = true;
}
} else if (processor instanceof EncryptedKeyProcessor) {
EncryptedKeyProcessor ekProcessor = (EncryptedKeyProcessor)processor;
secretKey = ekProcessor.getDecryptedBytes();
customTokenId = ekProcessor.getId();
} else if (processor instanceof SecurityContextTokenProcessor) {
SecurityContextTokenProcessor sctProcessor =
(SecurityContextTokenProcessor)processor;
secretKey = sctProcessor.getSecret();
customTokenId = sctProcessor.getIdentifier();
} else if (processor instanceof DerivedKeyTokenProcessor) {
DerivedKeyTokenProcessor dktProcessor =
(DerivedKeyTokenProcessor) processor;
String signatureMethodURI = sig.getSignedInfo().getSignatureMethodURI();
dkt = dktProcessor.getDerivedKeyToken();
int keyLength = (dkt.getLength() > 0) ? dkt.getLength() :
WSSecurityUtil.getKeyLength(signatureMethodURI);
secretKey = dktProcessor.getKeyBytes(keyLength);
} else if (processor instanceof SAMLTokenProcessor) {
if (crypto == null) {
throw new WSSecurityException(
WSSecurityException.FAILURE, "noSigCryptoFile"
);
}
SAMLTokenProcessor samlp = (SAMLTokenProcessor) processor;
samlKi = SAMLUtil.getSAMLKeyInfo(samlp.getSamlTokenElement(), crypto, cb);
certs = samlKi.getCerts();
secretKey = samlKi.getSecret();
publicKey = samlKi.getPublicKey();
}
} else if (secRef.containsX509Data() || secRef.containsX509IssuerSerial()) {
certs = secRef.getX509IssuerSerial(crypto);
} else if (secRef.containsKeyIdentifier()) {
if (secRef.getKeyIdentifierValueType().equals(SecurityTokenReference.ENC_KEY_SHA1_URI)) {
String id = secRef.getKeyIdentifierValue();
WSPasswordCallback pwcb =
new WSPasswordCallback(
id,
null,
SecurityTokenReference.ENC_KEY_SHA1_URI,
WSPasswordCallback.ENCRYPTED_KEY_TOKEN
);
try {
Callback[] callbacks = new Callback[]{pwcb};
cb.handle(callbacks);
} catch (Exception e) {
throw new WSSecurityException(
WSSecurityException.FAILURE,
"noPassword",
new Object[] {id},
e
);
}
secretKey = pwcb.getKey();
} else if (WSConstants.WSS_SAML_KI_VALUE_TYPE.equals(secRef.getKeyIdentifierValueType())) {
Element token =
secRef.getKeyIdentifierTokenElement(elem.getOwnerDocument(), wsDocInfo, cb);
if (crypto == null) {
throw new WSSecurityException(
WSSecurityException.FAILURE, "noSigCryptoFile"
);
}
samlKi = SAMLUtil.getSAMLKeyInfo(token, crypto, cb);
certs = samlKi.getCerts();
secretKey = samlKi.getSecret();
publicKey = samlKi.getPublicKey();
} else {
certs = secRef.getKeyIdentifier(crypto);
}
} else {
throw new WSSecurityException(
WSSecurityException.INVALID_SECURITY,
"unsupportedKeyInfo",
new Object[]{node.toString()}
);
}
} else {
if (crypto == null) {
throw new WSSecurityException(WSSecurityException.FAILURE, "noSigCryptoFile");
}
if (crypto.getDefaultX509Alias() != null) {
certs = crypto.getCertificates(crypto.getDefaultX509Alias());
} else {
throw new WSSecurityException(
WSSecurityException.INVALID_SECURITY, "unsupportedKeyInfo"
);
}
}
if (tlog.isDebugEnabled()) {
t1 = System.currentTimeMillis();
}
if ((certs == null || certs.length == 0 || certs[0] == null)
&& secretKey == null
&& publicKey == null) {
throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
}
if (certs != null) {
try {
for (int i = 0; i < certs.length; i++) {
certs[i].checkValidity();
}
} catch (CertificateExpiredException e) {
throw new WSSecurityException(
WSSecurityException.FAILED_CHECK, "invalidCert", null, e
);
} catch (CertificateNotYetValidException e) {
throw new WSSecurityException(
WSSecurityException.FAILED_CHECK, "invalidCert", null, e
);
}
}
//
// Delegate verification of a public key to a Callback Handler
//
if (publicKey != null) {
PublicKeyCallback pwcb =
new PublicKeyCallback(publicKey);
try {
Callback[] callbacks = new Callback[]{pwcb};
cb.handle(callbacks);
if (!pwcb.isVerified()) {
throw new WSSecurityException(
WSSecurityException.FAILED_AUTHENTICATION, null, null, null
);
}
} catch (Exception e) {
throw new WSSecurityException(
WSSecurityException.FAILED_AUTHENTICATION, null, null, e
);
}
}
try {
boolean signatureOk = false;
if (certs != null) {
signatureOk = sig.checkSignatureValue(certs[0]);
} else if (publicKey != null) {
signatureOk = sig.checkSignatureValue(publicKey);
} else {
signatureOk = sig.checkSignatureValue(sig.createSecretKey(secretKey));
}
if (signatureOk) {
if (tlog.isDebugEnabled()) {
t2 = System.currentTimeMillis();
tlog.debug(
"Verify: total= " + (t2 - t0) + ", prepare-cert= " + (t1 - t0)
+ ", verify= " + (t2 - t1)
);
}
signatureValue[0] = sig.getSignatureValue();
//
// Now dig into the Signature element to get the elements that
// this Signature covers. Build the QName of these Elements and
// return them to caller
//
SignedInfo si = sig.getSignedInfo();
int numReferences = si.getLength();
for (int i = 0; i < numReferences; i++) {
Reference siRef;
try {
siRef = si.item(i);
} catch (XMLSecurityException e3) {
throw new WSSecurityException(
WSSecurityException.FAILED_CHECK, null, null, e3
);
}
String uri = siRef.getURI();
if (uri != null && !"".equals(uri)) {
Element se = null;
try {
Transforms transforms = siRef.getTransforms();
for (int j = 0; j < transforms.getLength(); j++) {
Transform transform = transforms.item(j);
// We have some transforming to do before we can
// determine the protected element.
if (STRTransform.implementedTransformURI
.equals(transform.getURI())) {
XMLSignatureInput signatureInput =
siRef.getContentsBeforeTransformation();
if (signatureInput.isElement()) {
// The signature was already validated,
// meaning that this element was already
// parsed. We can therefore be pretty
// confident that this constructor will work.
SecurityTokenReference secTokenRef =
new SecurityTokenReference(
(Element) signatureInput.getSubNode());
// Use the utility to extract the element (or
// generate a new one in some cases) from the
// message.
se = STRTransformUtil.dereferenceSTR(
transform.getDocument(),
secTokenRef, wsDocInfo);
} else {
// The internal impl of Reference changed.
// We expect it to return the signature input
// based on a node/element.
throw new WSSecurityException(
WSSecurityException.FAILURE);
}
}
}
}
catch (XMLSecurityException e) {
log.warn("Error processing signature coverage elements.", e);
throw new WSSecurityException(WSSecurityException.FAILURE);
}
if (se == null) {
se = WSSecurityUtil.getElementByWsuId(elem.getOwnerDocument(), uri);
}
if (se == null) {
se = WSSecurityUtil.getElementByGenId(elem.getOwnerDocument(), uri);
}
if (se == null) {
throw new WSSecurityException(WSSecurityException.FAILED_CHECK);
}
WSDataRef ref = new WSDataRef(uri);
ref.setWsuId(uri);
ref.setName(new QName(se.getNamespaceURI(), se.getLocalName()));
ref.setProtectedElement(se);
ref.setXpath(ReferenceListProcessor.getXPath(se));
ref.setAlgorithm(si.getSignatureMethodURI());
ref.setDigestAlgorithm(siRef.getMessageDigestAlgorithm().getAlgorithmURI());
protectedElements.add(ref);
returnElements.add(WSSecurityUtil.getIDFromReference(uri));
} else {
// This is the case where the signed element is identified
// by a transform such as XPath filtering
// We add the complete reference element to the return
// elements
returnElements.add(siRef);
}
}
// Algorithms used for signature and c14n
signatureMethod = si.getSignatureMethodURI();
c14nMethod = si.getCanonicalizationMethodURI();
if (certs != null) {
returnCert[0] = certs[0];
if (validateCertificateChain) {
certificates = certs;
}
return certs[0].getSubjectX500Principal();
} else if (publicKey != null) {
return new PublicKeyPrincipal(publicKey);
} else if (ut != null) {
WSUsernameTokenPrincipal principal =
new WSUsernameTokenPrincipal(ut.getName(), ut.isHashed());
principal.setNonce(ut.getNonce());
principal.setPassword(ut.getPassword());
principal.setCreatedTime(ut.getCreated());
return principal;
} else if (dkt != null) {
WSDerivedKeyTokenPrincipal principal = new WSDerivedKeyTokenPrincipal(dkt.getID());
principal.setNonce(dkt.getNonce());
principal.setLabel(dkt.getLabel());