use of java.security.Principal in project Openfire by igniterealtime.
the class ClientTrustManager method checkClientTrusted.
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String string) throws CertificateException {
Log.debug("ClientTrustManager: checkClientTrusted(x509Certificates," + string + ") called");
loadCRL();
ArrayList<X509Certificate> certs = new ArrayList<>();
for (int i = 0; i < x509Certificates.length; i++) {
certs.add(x509Certificates[i]);
}
boolean verify = JiveGlobals.getBooleanProperty("xmpp.client.certificate.verify", true);
if (verify) {
int nSize = x509Certificates.length;
List<String> peerIdentities = CertificateManager.getClientIdentities(x509Certificates[0]);
if (JiveGlobals.getBooleanProperty("xmpp.client.certificate.verify.chain", true)) {
// Working down the chain, for every certificate in the chain,
// verify that the subject of the certificate is the issuer of the
// next certificate in the chain.
Principal principalLast = null;
for (int i = nSize - 1; i >= 0; i--) {
X509Certificate x509certificate = x509Certificates[i];
Principal principalIssuer = x509certificate.getIssuerDN();
Principal principalSubject = x509certificate.getSubjectDN();
if (principalLast != null) {
if (principalIssuer.equals(principalLast)) {
try {
PublicKey publickey = x509Certificates[i + 1].getPublicKey();
x509Certificates[i].verify(publickey);
} catch (GeneralSecurityException generalsecurityexception) {
throw new CertificateException("signature verification failed of " + peerIdentities);
}
} else {
throw new CertificateException("subject/issuer verification failed of " + peerIdentities);
}
}
principalLast = principalSubject;
}
}
if (JiveGlobals.getBooleanProperty("xmpp.client.certificate.verify.root", true)) {
// Verify that the the last certificate in the chain was issued
// by a third-party that the client trusts, or is trusted itself
boolean trusted = false;
try {
Enumeration<String> aliases = trustStore.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
X509Certificate tCert = (X509Certificate) trustStore.getCertificate(alias);
if (x509Certificates[nSize - 1].equals(tCert)) {
try {
PublicKey publickey = tCert.getPublicKey();
x509Certificates[nSize - 1].verify(publickey);
} catch (GeneralSecurityException generalsecurityexception) {
throw new CertificateException("signature verification failed of " + peerIdentities);
}
trusted = true;
break;
} else {
if (x509Certificates[nSize - 1].getIssuerDN().equals(tCert.getSubjectDN())) {
try {
PublicKey publickey = tCert.getPublicKey();
x509Certificates[nSize - 1].verify(publickey);
} catch (GeneralSecurityException generalsecurityexception) {
throw new CertificateException("signature verification failed of " + peerIdentities);
}
trusted = true;
break;
}
}
}
} catch (KeyStoreException e) {
Log.error(e.getMessage(), e);
}
if (!trusted) {
//Log.debug("certificate not trusted of "+peerIdentities);
throw new CertificateException("root certificate not trusted of " + peerIdentities);
}
}
if (JiveGlobals.getBooleanProperty("xmpp.client.certificate.verify.validity", true)) {
// For every certificate in the chain, verify that the certificate
// is valid at the current time.
Date date = new Date();
for (int i = 0; i < nSize; i++) {
try {
x509Certificates[i].checkValidity(date);
} catch (GeneralSecurityException generalsecurityexception) {
throw new CertificateException("invalid date of " + peerIdentities);
}
}
}
//Verify certificate path
try {
CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
X509CertSelector certSelector = new X509CertSelector();
certSelector.setCertificate(x509Certificates[0]);
PKIXBuilderParameters params = new PKIXBuilderParameters(trustStore, certSelector);
if (useCRLs) {
params.addCertStore(crlStore);
} else {
Log.debug("ClientTrustManager: no CRL's found, so setRevocationEnabled(false)");
params.setRevocationEnabled(false);
}
CertPathBuilderResult cpbr = cpb.build(params);
CertPath cp = cpbr.getCertPath();
if (JiveGlobals.getBooleanProperty("ocsp.enable", false)) {
Log.debug("ClientTrustManager: OCSP requested");
OCSPChecker ocspChecker = new OCSPChecker(cp, params);
params.addCertPathChecker(ocspChecker);
}
PKIXCertPathValidatorResult cpvResult = (PKIXCertPathValidatorResult) cpv.validate(cp, params);
X509Certificate trustedCert = cpvResult.getTrustAnchor().getTrustedCert();
if (trustedCert == null) {
throw new CertificateException("certificate path failed: Trusted CA is NULL");
} else {
Log.debug("ClientTrustManager: Trusted CA: " + trustedCert.getSubjectDN());
}
} catch (CertPathBuilderException | CertPathValidatorException e) {
Log.debug("ClientTrustManager:", e);
throw new CertificateException("certificate path failed: " + e.getMessage());
} catch (Exception e) {
Log.debug("ClientTrustManager:", e);
throw new CertificateException("unexpected error: " + e.getMessage());
}
}
}
use of java.security.Principal in project Openfire by igniterealtime.
the class CertificateManager method validateReply.
/**
* Validates chain in certification reply, and returns the ordered
* elements of the chain (with user certificate first, and root
* certificate last in the array).
*
* @param alias the alias name
* @param userCert the user certificate of the alias
* @param certs the chain provided in the reply
*/
private static List<X509Certificate> validateReply(KeyStore keyStore, KeyStore trustStore, String alias, X509Certificate userCert, Collection<X509Certificate> certs) throws Exception {
List<X509Certificate> replyCerts = new ArrayList<>(certs);
// order the certs in the reply (bottom-up).
int i;
X509Certificate tmpCert;
if (userCert != null) {
PublicKey userPubKey = userCert.getPublicKey();
for (i = 0; i < replyCerts.size(); i++) {
if (userPubKey.equals(replyCerts.get(i).getPublicKey())) {
break;
}
}
if (i == replyCerts.size()) {
throw new Exception("Certificate reply does not contain public key for <alias>: " + alias);
}
tmpCert = replyCerts.get(0);
replyCerts.set(0, replyCerts.get(i));
replyCerts.set(i, tmpCert);
}
Principal issuer = replyCerts.get(0).getIssuerDN();
for (i = 1; i < replyCerts.size() - 1; i++) {
// find a cert in the reply whose "subject" is the same as the
// given "issuer"
int j;
for (j = i; j < replyCerts.size(); j++) {
Principal subject = replyCerts.get(j).getSubjectDN();
if (subject.equals(issuer)) {
tmpCert = replyCerts.get(i);
replyCerts.set(i, replyCerts.get(j));
replyCerts.set(j, tmpCert);
issuer = replyCerts.get(i).getIssuerDN();
break;
}
}
if (j == replyCerts.size()) {
throw new Exception("Incomplete certificate chain in reply");
}
}
// now verify each cert in the ordered chain
for (i = 0; i < replyCerts.size() - 1; i++) {
PublicKey pubKey = replyCerts.get(i + 1).getPublicKey();
try {
replyCerts.get(i).verify(pubKey);
} catch (Exception e) {
throw new Exception("Certificate chain in reply does not verify: " + e.getMessage());
}
}
// do we trust the (root) cert at the top?
X509Certificate topCert = replyCerts.get(replyCerts.size() - 1);
boolean foundInKeyStore = keyStore.getCertificateAlias(topCert) != null;
boolean foundInCAStore = trustStore.getCertificateAlias(topCert) != null;
if (!foundInKeyStore && !foundInCAStore) {
boolean verified = false;
X509Certificate rootCert = null;
for (Enumeration<String> aliases = trustStore.aliases(); aliases.hasMoreElements(); ) {
String name = aliases.nextElement();
rootCert = (X509Certificate) trustStore.getCertificate(name);
if (rootCert != null) {
try {
topCert.verify(rootCert.getPublicKey());
verified = true;
break;
} catch (Exception e) {
// Ignore
}
}
}
if (!verified) {
return null;
} else {
// Check if the cert is a self-signed cert
if (!topCert.getSubjectDN().equals(topCert.getIssuerDN())) {
// append the (self-signed) root CA cert to the chain
replyCerts.add(rootCert);
}
}
}
return replyCerts;
}
use of java.security.Principal in project Openfire by igniterealtime.
the class CertificateManager method buildChain.
/**
* Builds the certificate chain of the specified certificate based on the known list of certificates
* that were issued by their respective Principals. Returns true if the entire chain of all certificates
* was successfully built.
*
* @param certificate certificate to build its chain.
* @param answer the certificate chain for the corresponding certificate.
* @param knownCerts list of known certificates grouped by their issues (i.e. Principals).
* @return true if the entire chain of all certificates was successfully built.
*/
private static boolean buildChain(X509Certificate certificate, LinkedList<X509Certificate> answer, Map<String, List<X509Certificate>> knownCerts) {
Principal subject = certificate.getSubjectDN();
Principal issuer = certificate.getIssuerDN();
// is present in the subject)
if (subject.equals(issuer)) {
answer.addFirst(certificate);
return true;
}
// Get the list of known certificates of the certificate's issuer
List<X509Certificate> issuerCerts = knownCerts.get(issuer.getName());
if (issuerCerts == null || issuerCerts.isEmpty()) {
// No certificates were found so building of chain failed
return false;
}
for (X509Certificate issuerCert : issuerCerts) {
PublicKey publickey = issuerCert.getPublicKey();
try {
// Verify the certificate with the specified public key
certificate.verify(publickey);
// Certificate was verified successfully so build chain of issuer's certificate
if (!buildChain(issuerCert, answer, knownCerts)) {
return false;
}
} catch (Exception exception) {
// Failed to verify certificate
return false;
}
}
answer.addFirst(certificate);
return true;
}
use of java.security.Principal in project Openfire by igniterealtime.
the class CertificateUtils method order.
/**
* Orders certificates, starting from the entity to be validated and progressing back toward the CA root.
*
* This implementation matches "issuers" to "subjects" of certificates in such a way that "issuer" value of a
* certificate matches the "subject" value of the next certificate.
*
* When certificates are provided that do not belong to the same chain, a CertificateException is thrown.
*
* @param certificates an unordered collection of certificates (cannot be null).
* @return An ordered list of certificates (possibly empty, but never null).
*/
public static List<X509Certificate> order(Collection<X509Certificate> certificates) throws CertificateException {
final LinkedList<X509Certificate> orderedResult = new LinkedList<>();
if (certificates.isEmpty()) {
return orderedResult;
}
if (certificates.size() == 1) {
orderedResult.addAll(certificates);
return orderedResult;
}
final Map<Principal, X509Certificate> byIssuer = new HashMap<>();
final Map<Principal, X509Certificate> bySubject = new HashMap<>();
for (final X509Certificate certificate : certificates) {
final Principal issuer = certificate.getIssuerDN();
final Principal subject = certificate.getSubjectDN();
// By issuer
if (issuer.equals(subject)) {
// self-signed: use null key.
final X509Certificate sameIssuer = byIssuer.put(null, certificate);
if (sameIssuer != null) {
throw new CertificateException("The provided input should not contain multiple root CA certificates. Issuer of first detected Root CA certificate: " + issuer + " Issuer of second detected Root CA certificate: : " + sameIssuer);
}
} else {
// regular issuer
if (byIssuer.put(issuer, certificate) != null) {
throw new CertificateException("The provided input should not contain multiple certificates with identical issuerDN values. Offending value: " + issuer);
}
}
// By subject
if (bySubject.put(subject, certificate) != null) {
throw new CertificateException("The provided input should not contain multiple certificates with identical subjectDN values. Offending value: " + subject);
}
}
// The first certificate will have a 'subject' value that's not an 'issuer' of any other chain.
X509Certificate first = null;
for (Map.Entry<Principal, X509Certificate> entry : bySubject.entrySet()) {
final Principal subject = entry.getKey();
final X509Certificate certificate = entry.getValue();
if (!byIssuer.containsKey(subject)) {
if (first == null) {
first = certificate;
} else {
throw new CertificateException("The provided input should not contain more than one certificates that has a subjectDN value that's not equal to the issuerDN value of another certificate.");
}
}
}
if (first == null) {
throw new CertificateException("The provided input should contain a certificate that has a subjectDN value that's not equal to the issuerDN value of any other certificate.");
}
orderedResult.add(first);
// With the first certificate in hand, every following certificate should have a subject that's equal to the previous issuer value.
X509Certificate next = bySubject.remove(first.getIssuerDN());
while (next != null) {
orderedResult.add(next);
next = bySubject.remove(next.getIssuerDN());
}
// final check
if (orderedResult.size() != certificates.size()) {
throw new CertificateException("Unable to recreate a certificate chain from the provided input.");
}
return orderedResult;
}
use of java.security.Principal in project Openfire by igniterealtime.
the class OpenfireLoginService method login.
public UserIdentity login(String userName, Object credential) {
UserIdentity identity = null;
if (identities.containsKey(userName)) {
identity = identities.get(userName);
if (authTokens.containsKey(userName) == false) {
Log.debug("UserIdentity login " + userName + " ");
try {
if (AdminManager.getInstance().isUserAdmin(userName, true)) {
AuthToken authToken = AuthFactory.authenticate(userName, (String) credential);
authTokens.put(userName, authToken);
} else {
Log.error("access denied, not admin user " + userName);
return null;
}
} catch (UnauthorizedException e) {
Log.error("access denied, bad password " + userName);
return null;
} catch (Exception e) {
Log.error("access denied " + userName);
return null;
}
}
} else {
Log.debug("UserIdentity login " + userName + " ");
try {
userManager.getUser(userName);
} catch (UserNotFoundException e) {
//Log.error( "user not found " + userName, e );
return null;
}
try {
if (AdminManager.getInstance().isUserAdmin(userName, true)) {
AuthToken authToken = AuthFactory.authenticate(userName, (String) credential);
authTokens.put(userName, authToken);
} else {
Log.error("access denied, not admin user " + userName);
return null;
}
} catch (UnauthorizedException e) {
Log.error("access denied, bad password " + userName);
return null;
} catch (Exception e) {
Log.error("access denied " + userName);
return null;
}
Principal userPrincipal = new KnownUser(userName, credential);
Subject subject = new Subject();
subject.getPrincipals().add(userPrincipal);
subject.getPrivateCredentials().add(credential);
subject.getPrincipals().add(new RolePrincipal("jmxweb"));
subject.setReadOnly();
identity = _identityService.newUserIdentity(subject, userPrincipal, new String[] { "jmxweb" });
identities.put(userName, identity);
}
return identity;
}
Aggregations