/** * Creates a {@code KeyValueType} that wraps the specified public key. This method supports DSA * and RSA keys. * * @param key the {@code PublicKey} that will be represented as a {@code KeyValueType}. * @return the constructed {@code KeyValueType} or {@code null} if the specified key is neither a * DSA nor a RSA key. */ public static KeyValueType createKeyValue(PublicKey key) { if (key instanceof RSAPublicKey) { RSAPublicKey pubKey = (RSAPublicKey) key; byte[] modulus = pubKey.getModulus().toByteArray(); byte[] exponent = pubKey.getPublicExponent().toByteArray(); RSAKeyValueType rsaKeyValue = new RSAKeyValueType(); rsaKeyValue.setModulus(Base64.encodeBytes(modulus).getBytes()); rsaKeyValue.setExponent(Base64.encodeBytes(exponent).getBytes()); return rsaKeyValue; } else if (key instanceof DSAPublicKey) { DSAPublicKey pubKey = (DSAPublicKey) key; byte[] P = pubKey.getParams().getP().toByteArray(); byte[] Q = pubKey.getParams().getQ().toByteArray(); byte[] G = pubKey.getParams().getG().toByteArray(); byte[] Y = pubKey.getY().toByteArray(); DSAKeyValueType dsaKeyValue = new DSAKeyValueType(); dsaKeyValue.setP(Base64.encodeBytes(P).getBytes()); dsaKeyValue.setQ(Base64.encodeBytes(Q).getBytes()); dsaKeyValue.setG(Base64.encodeBytes(G).getBytes()); dsaKeyValue.setY(Base64.encodeBytes(Y).getBytes()); return dsaKeyValue; } throw logger.unsupportedType(key.toString()); }
public void verifyRedirectBindingSignature(PublicKey publicKey, String paramKey) throws VerificationException { String request = facade.getRequest().getQueryParamValue(paramKey); String algorithm = facade.getRequest().getQueryParamValue(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY); String signature = facade.getRequest().getQueryParamValue(GeneralConstants.SAML_SIGNATURE_REQUEST_KEY); String decodedAlgorithm = facade.getRequest().getQueryParamValue(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY); if (request == null) { throw new VerificationException("SAML Request was null"); } if (algorithm == null) throw new VerificationException("SigAlg was null"); if (signature == null) throw new VerificationException("Signature was null"); // Shibboleth doesn't sign the document for redirect binding. // todo maybe a flag? String relayState = facade.getRequest().getQueryParamValue(GeneralConstants.RELAY_STATE); KeycloakUriBuilder builder = KeycloakUriBuilder.fromPath("/").queryParam(paramKey, request); if (relayState != null) { builder.queryParam(GeneralConstants.RELAY_STATE, relayState); } builder.queryParam(GeneralConstants.SAML_SIG_ALG_REQUEST_KEY, algorithm); String rawQuery = builder.build().getRawQuery(); try { // byte[] decodedSignature = RedirectBindingUtil.urlBase64Decode(signature); byte[] decodedSignature = Base64.decode(signature); SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.getFromXmlMethod(decodedAlgorithm); Signature validator = signatureAlgorithm.createSignature(); // todo plugin signature alg validator.initVerify(publicKey); validator.update(rawQuery.getBytes("UTF-8")); if (!validator.verify(decodedSignature)) { throw new VerificationException("Invalid query param signature"); } } catch (Exception e) { throw new VerificationException(e); } }