if (this.rejectUnsigned && !this.certificate && !this.fingerprint) {
throw new Error("when rejectUnsigned is specified, either a certificate or a fingerprint is required");
}
};
IdentityProvider.prototype.verify = function verify(doc, cb) {
var responseSignatureElement = xpath.select1("/*[namespace-uri()='urn:oasis:names:tc:SAML:2.0:protocol' and local-name()='Response']/*[namespace-uri()='http://www.w3.org/2000/09/xmldsig#' and local-name()='Signature']", doc),
assertionSignatureElement = xpath.select1("/*[namespace-uri()='urn:oasis:names:tc:SAML:2.0:protocol' and local-name()='Response']/*[namespace-uri()='urn:oasis:names:tc:SAML:2.0:assertion' and local-name()='Assertion']/*[namespace-uri()='http://www.w3.org/2000/09/xmldsig#' and local-name()='Signature']", doc);
if (!responseSignatureElement && !assertionSignatureElement) {
if (this.rejectUnsigned) {
return cb(Error("no signature element found, but at least one was expected"));
} else {
return cb();
}
}
var options = {};
if (this.certificate) {
options.keySelector = dsig.createKeySelector("specified", {
keyInfo: {
certificate: this.certificate,
},
});
}
var self = this;
return dsig.verifySignature(options, assertionSignatureElement || responseSignatureElement, function(err, signatureInfo) {
if (err) {
return cb(err);
}
if (self.fingerprint) {
if (!signatureInfo.keyInfo || !signatureInfo.keyInfo.certificate) {
return cb(Error("couldn't get certificate from signature"));
}
return pem.getFingerprint(signatureInfo.keyInfo.certificate, function(err, fingerprintInfo) {
if (err) {
return cb(err);
}
if (fingerprintInfo.fingerprint !== self.fingerprint) {
return cb(Error("the certificate that signed this message did not have the fingerprint we expected"));
}
return cb(null, signatureInfo);
});
} else {
return cb(null, signatureInfo);
}
});
};