[TEST] Add SAML Redirect Signing test (#34562)

Add a test to verify that we generate correct signatures for our
SAML2 Single Logout requests when using the redirect binding.
This commit is contained in:
Ioannis Kakavas 2018-10-19 13:58:24 +03:00 committed by GitHub
parent fe623acf66
commit 59033e0e45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 49 additions and 0 deletions

View File

@ -12,6 +12,15 @@ import org.opensaml.saml.saml2.core.LogoutRequest;
import org.opensaml.saml.saml2.core.NameID;
import org.opensaml.security.x509.X509Credential;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.security.SignatureException;
import java.util.Base64;
import static java.util.Collections.emptySet;
import static java.util.Collections.singleton;
import static org.hamcrest.Matchers.equalTo;
@ -67,6 +76,46 @@ public class SamlRedirectTests extends SamlTestCase {
"1yHnLOX4Edtz0eDuf2uJjHy9Z%2Fl5ZEapyLQvGraBZdZm6ER59RV%2F8izGKwLg38VL4B1sji%2FPxxgeIb"));
}
public void testLogoutRequestSigning() throws Exception {
final X509Credential credential = (X509Credential) buildOpenSamlCredential(readRandomKeyPair()).get(0);
X509Credential invalidCredential = (X509Credential) buildOpenSamlCredential(readRandomKeyPair()).get(0);
while (invalidCredential.getEntityCertificate().getSerialNumber().equals(credential.getEntityCertificate().getSerialNumber())) {
invalidCredential = (X509Credential) buildOpenSamlCredential(readRandomKeyPair()).get(0);
}
final SigningConfiguration spConfig =
new SigningConfiguration(singleton("*"), credential);
final SamlRedirect redirect = new SamlRedirect(buildLogoutRequest(LOGOUT_URL + "?"), spConfig);
final String url = redirect.getRedirectUrl();
final String queryParam = url.split("\\?")[1].split("&Signature")[0];
final String params[] = url.split("\\?")[1].split("&");
assert (params.length == 3);
String sigAlg = parseAndUrlDecodeParameter(params[1]);
// We currently only support signing with SHA256withRSA, this test should be updated if we add support for more
assertThat(sigAlg, equalTo("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"));
sigAlg = "SHA256withRSA";
final String signature = parseAndUrlDecodeParameter(params[2]);
assertThat(validateSignature(queryParam, sigAlg, signature, credential), equalTo(true));
assertThat(validateSignature(queryParam, sigAlg, signature, invalidCredential), equalTo(false));
assertThat(validateSignature(queryParam.substring(0, queryParam.length() - 5), sigAlg, signature, credential), equalTo(false));
}
private String parseAndUrlDecodeParameter(String parameter) throws UnsupportedEncodingException {
final String value = parameter.split("=", 2)[1];
return URLDecoder.decode(value, "UTF-8");
}
private boolean validateSignature(String queryParam, String sigAlg, String signature, X509Credential credential) {
try {
Signature sig = Signature.getInstance(sigAlg);
sig.initVerify(credential.getPublicKey());
sig.update(queryParam.getBytes(StandardCharsets.UTF_8));
return sig.verify(Base64.getDecoder().decode(signature));
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
return false;
}
}
private LogoutRequest buildLogoutRequest(String logoutUrl) {
final LogoutRequest logoutRequest = SamlUtils.buildObject(LogoutRequest.class, LogoutRequest.DEFAULT_ELEMENT_NAME);
logoutRequest.setDestination(logoutUrl);