use of org.jivesoftware.openfire.keystore.TrustStore in project Openfire by igniterealtime.
the class ExternalClientSaslServer method evaluateResponse.
@Override
public byte[] evaluateResponse(byte[] response) throws SaslException {
if (isComplete()) {
throw new IllegalStateException("Authentication exchange already completed.");
}
// There will be no further steps. Either authentication succeeds or fails, but in any case, we're done.
complete = true;
final Connection connection = session.getConnection();
Certificate[] peerCertificates = connection.getPeerCertificates();
if (peerCertificates == null || peerCertificates.length < 1) {
throw new SaslException("No peer certificates.");
}
final X509Certificate trusted;
if (SASLAuthentication.SKIP_PEER_CERT_REVALIDATION_CLIENT.getValue()) {
// Trust that the peer certificate has been validated when TLS got established.
trusted = (X509Certificate) peerCertificates[0];
} else {
// Re-evaluate the validity of the peer certificate.
final TrustStore trustStore = connection.getConfiguration().getTrustStore();
trusted = trustStore.getEndEntityCertificate(peerCertificates);
}
if (trusted == null) {
throw new SaslException("Certificate chain of peer is not trusted.");
}
// Process client identities / principals.
final ArrayList<String> principals = new ArrayList<>();
principals.addAll(CertificateManager.getClientIdentities(trusted));
String principal;
switch(principals.size()) {
case 0:
principal = "";
break;
default:
Log.debug("More than one principal found, using the first one.");
// intended fall-through;
case 1:
principal = principals.get(0);
break;
}
// Process requested user name.
String username;
if (response != null && response.length > 0) {
username = new String(response, StandardCharsets.UTF_8);
if (PROPERTY_SASL_EXTERNAL_CLIENT_SUPPRESS_MATCHING_REALMNAME.getValue() && username.contains("@")) {
String userUser = username.substring(0, username.lastIndexOf("@"));
String userRealm = username.substring((username.lastIndexOf("@") + 1));
if (XMPPServer.getInstance().getServerInfo().getXMPPDomain().equals(userRealm)) {
username = userUser;
}
}
} else {
username = null;
}
if (username == null || username.length() == 0) {
// cause an authorization failure.
for (String princ : principals) {
final String mappedUsername = AuthorizationManager.map(princ);
if (!mappedUsername.equals(princ)) {
username = mappedUsername;
principal = princ;
break;
}
}
if (username == null || username.length() == 0) {
// Still no username. Punt.
username = principal;
}
Log.debug("No username requested, using: {}", username);
}
// Its possible that either/both username and principal are null here. The providers should not allow a null authorization
if (AuthorizationManager.authorize(username, principal)) {
Log.debug("Principal {} authorized to username {}", principal, username);
authorizationID = username;
// Success!
return null;
}
throw new SaslException();
}
use of org.jivesoftware.openfire.keystore.TrustStore in project Openfire by igniterealtime.
the class SASLAuthentication method getSASLMechanismsElement.
public static Element getSASLMechanismsElement(LocalIncomingServerSession session) {
final Element result = DocumentHelper.createElement(new QName("mechanisms", new Namespace("", SASL_NAMESPACE)));
if (session.isSecure()) {
final Connection connection = session.getConnection();
final TrustStore trustStore = connection.getConfiguration().getTrustStore();
final X509Certificate trusted = trustStore.getEndEntityCertificate(session.getConnection().getPeerCertificates());
boolean haveTrustedCertificate = trusted != null;
if (trusted != null && session.getDefaultIdentity() != null) {
haveTrustedCertificate = verifyCertificate(trusted, session.getDefaultIdentity());
}
if (haveTrustedCertificate) {
// Offer SASL EXTERNAL only if TLS has already been negotiated and the peer has a trusted cert.
final Element mechanism = result.addElement("mechanism");
mechanism.setText("EXTERNAL");
}
}
// OF-2072: Return null instead of an empty element, if so configured.
if (JiveGlobals.getBooleanProperty("sasl.server.suppressEmpty", false) && result.elements().isEmpty()) {
return null;
}
return result;
}
use of org.jivesoftware.openfire.keystore.TrustStore in project Openfire by igniterealtime.
the class SASLAuthentication method verifyCertificates.
public static boolean verifyCertificates(Certificate[] chain, String hostname, boolean isS2S) {
final CertificateStoreManager certificateStoreManager = XMPPServer.getInstance().getCertificateStoreManager();
final ConnectionType connectionType = isS2S ? ConnectionType.SOCKET_S2S : ConnectionType.SOCKET_C2S;
final TrustStore trustStore = certificateStoreManager.getTrustStore(connectionType);
final X509Certificate trusted = trustStore.getEndEntityCertificate(chain);
if (trusted != null) {
return verifyCertificate(trusted, hostname);
}
return false;
}
use of org.jivesoftware.openfire.keystore.TrustStore in project Openfire by igniterealtime.
the class SASLAuthentication method getSASLMechanismsElement.
public static Element getSASLMechanismsElement(ClientSession session) {
final Element result = DocumentHelper.createElement(new QName("mechanisms", new Namespace("", SASL_NAMESPACE)));
for (String mech : getSupportedMechanisms()) {
if (mech.equals("EXTERNAL")) {
boolean trustedCert = false;
if (session.isSecure()) {
final Connection connection = ((LocalClientSession) session).getConnection();
if (SKIP_PEER_CERT_REVALIDATION_CLIENT.getValue()) {
// Trust that the peer certificate has been validated when TLS got established.
trustedCert = connection.getPeerCertificates() != null && connection.getPeerCertificates().length > 0;
} else {
// Re-evaluate the validity of the peer certificate.
final TrustStore trustStore = connection.getConfiguration().getTrustStore();
trustedCert = trustStore.isTrusted(connection.getPeerCertificates());
}
}
if (!trustedCert) {
// Do not offer EXTERNAL.
continue;
}
}
final Element mechanism = result.addElement("mechanism");
mechanism.setText(mech);
}
// OF-2072: Return null instead of an empty element, if so configured.
if (JiveGlobals.getBooleanProperty("sasl.client.suppressEmpty", false) && result.elements().isEmpty()) {
return null;
}
return result;
}
Aggregations