All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.jce.provider.X509LDAPCertStoreSpi Maven / Gradle / Ivy

Go to download

The Long Term Stable (LTS) Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains the JCA/JCE provider and low-level API for the BC LTS version 2.73.7 for Java 8 and later.

There is a newer version: 2.73.7
Show newest version
package org.bouncycastle.jce.provider;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.cert.CRL;
import java.security.cert.CRLSelector;
import java.security.cert.CertSelector;
import java.security.cert.CertStoreException;
import java.security.cert.CertStoreParameters;
import java.security.cert.CertStoreSpi;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRLSelector;
import java.security.cert.X509CertSelector;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.security.auth.x500.X500Principal;

import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.x509.CertificatePair;
import org.bouncycastle.jce.X509LDAPCertStoreParameters;

/**
 * This is a general purpose implementation to get X.509 certificates and CRLs
 * from a LDAP location.
 * 

* At first a search is performed in the ldap*AttributeNames of the * {@link org.bouncycastle.jce.X509LDAPCertStoreParameters} with the given * information of the subject (for all kind of certificates) or issuer (for * CRLs), respectively, if a X509CertSelector is given with that details. For * CRLs, CA certificates and cross certificates a coarse search is made only for * entries with that content to get more possibly matching results. */ public class X509LDAPCertStoreSpi extends CertStoreSpi { private static String[] FILTER_ESCAPE_TABLE = new String['\\' + 1]; static { // Filter encoding table ------------------------------------- // fill with char itself for (char c = 0; c < FILTER_ESCAPE_TABLE.length; c++) { FILTER_ESCAPE_TABLE[c] = String.valueOf(c); } // escapes (RFC2254) FILTER_ESCAPE_TABLE['*'] = "\\2a"; FILTER_ESCAPE_TABLE['('] = "\\28"; FILTER_ESCAPE_TABLE[')'] = "\\29"; FILTER_ESCAPE_TABLE['\\'] = "\\5c"; FILTER_ESCAPE_TABLE[0] = "\\00"; } /** * Initial Context Factory. */ private static String LDAP_PROVIDER = "com.sun.jndi.ldap.LdapCtxFactory"; /** * Processing referrals.. */ private static String REFERRALS_IGNORE = "ignore"; /** * Security level to be used for LDAP connections. */ private static final String SEARCH_SECURITY_LEVEL = "none"; /** * Package Prefix for loading URL context factories. */ private static final String URL_CONTEXT_PREFIX = "com.sun.jndi.url"; private X509LDAPCertStoreParameters params; public X509LDAPCertStoreSpi(CertStoreParameters params) throws InvalidAlgorithmParameterException { super(params); if (!(params instanceof X509LDAPCertStoreParameters)) { throw new InvalidAlgorithmParameterException( X509LDAPCertStoreSpi.class.getName() + ": parameter must be a " + X509LDAPCertStoreParameters.class.getName() + " object\n" + params.toString()); } this.params = (X509LDAPCertStoreParameters)params; } private DirContext connectLDAP() throws NamingException { Properties props = new Properties(); props.setProperty(Context.INITIAL_CONTEXT_FACTORY, LDAP_PROVIDER); props.setProperty(Context.BATCHSIZE, "0"); props.setProperty(Context.PROVIDER_URL, params.getLdapURL()); props.setProperty(Context.URL_PKG_PREFIXES, URL_CONTEXT_PREFIX); props.setProperty(Context.REFERRAL, REFERRALS_IGNORE); props.setProperty(Context.SECURITY_AUTHENTICATION, SEARCH_SECURITY_LEVEL); DirContext ctx = new InitialDirContext(props); return ctx; } private String parseDN(String subject, String subjectAttributeName) { String temp = subject; int begin = temp.toLowerCase().indexOf( subjectAttributeName.toLowerCase()); temp = temp.substring(begin + subjectAttributeName.length()); int end = temp.indexOf(','); if (end == -1) { end = temp.length(); } while (temp.charAt(end - 1) == '\\') { end = temp.indexOf(',', end + 1); if (end == -1) { end = temp.length(); } } temp = temp.substring(0, end); begin = temp.indexOf('='); temp = temp.substring(begin + 1); if (temp.charAt(0) == ' ') { temp = temp.substring(1); } if (temp.startsWith("\"")) { temp = temp.substring(1); } if (temp.endsWith("\"")) { temp = temp.substring(0, temp.length() - 1); } return filterEncode(temp); } public Collection engineGetCertificates(CertSelector selector) throws CertStoreException { if (!(selector instanceof X509CertSelector)) { throw new CertStoreException("selector is not a X509CertSelector"); } X509CertSelector xselector = (X509CertSelector)selector; Set certSet = new HashSet(); Set set = getEndCertificates(xselector); set.addAll(getCACertificates(xselector)); set.addAll(getCrossCertificates(xselector)); Iterator it = set.iterator(); try { CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); while (it.hasNext()) { byte[] bytes = (byte[])it.next(); if (bytes == null || bytes.length == 0) { continue; } List bytesList = new ArrayList(); bytesList.add(bytes); try { CertificatePair pair = CertificatePair .getInstance(new ASN1InputStream(bytes) .readObject()); bytesList.clear(); if (pair.getForward() != null) { bytesList.add(pair.getForward().getEncoded()); } if (pair.getReverse() != null) { bytesList.add(pair.getReverse().getEncoded()); } } catch (IOException e) { } catch (IllegalArgumentException e) { } for (Iterator it2 = bytesList.iterator(); it2.hasNext(); ) { ByteArrayInputStream bIn = new ByteArrayInputStream( (byte[])it2.next()); try { Certificate cert = cf.generateCertificate(bIn); // System.out.println(((X509Certificate) // cert).getSubjectX500Principal()); if (xselector.match(cert)) { certSet.add(cert); } } catch (Exception e) { } } } } catch (Exception e) { throw new CertStoreException( "certificate cannot be constructed from LDAP result: " + e); } return certSet; } private Set certSubjectSerialSearch(X509CertSelector xselector, String[] attrs, String attrName, String subjectAttributeName) throws CertStoreException { Set set = new HashSet(); try { if (xselector.getSubjectAsBytes() != null || xselector.getSubjectAsString() != null || xselector.getCertificate() != null) { String subject = null; String serial = null; if (xselector.getCertificate() != null) { subject = xselector.getCertificate() .getSubjectX500Principal().getName("RFC1779"); serial = xselector.getCertificate().getSerialNumber() .toString(); } else { if (xselector.getSubjectAsBytes() != null) { subject = new X500Principal(xselector .getSubjectAsBytes()).getName("RFC1779"); } else { subject = xselector.getSubjectAsString(); } } String attrValue = parseDN(subject, subjectAttributeName); set.addAll(search(attrName, "*" + attrValue + "*", attrs)); if (serial != null && params.getSearchForSerialNumberIn() != null) { attrValue = serial; attrName = params.getSearchForSerialNumberIn(); set.addAll(search(attrName, "*" + attrValue + "*", attrs)); } } else { set.addAll(search(attrName, "*", attrs)); } } catch (IOException e) { throw new CertStoreException("exception processing selector: " + e); } return set; } private Set getEndCertificates(X509CertSelector xselector) throws CertStoreException { String[] attrs = {params.getUserCertificateAttribute()}; String attrName = params.getLdapUserCertificateAttributeName(); String subjectAttributeName = params.getUserCertificateSubjectAttributeName(); Set set = certSubjectSerialSearch(xselector, attrs, attrName, subjectAttributeName); return set; } private Set getCACertificates(X509CertSelector xselector) throws CertStoreException { String[] attrs = {params.getCACertificateAttribute()}; String attrName = params.getLdapCACertificateAttributeName(); String subjectAttributeName = params .getCACertificateSubjectAttributeName(); Set set = certSubjectSerialSearch(xselector, attrs, attrName, subjectAttributeName); if (set.isEmpty()) { set.addAll(search(null, "*", attrs)); } return set; } private Set getCrossCertificates(X509CertSelector xselector) throws CertStoreException { String[] attrs = {params.getCrossCertificateAttribute()}; String attrName = params.getLdapCrossCertificateAttributeName(); String subjectAttributeName = params .getCrossCertificateSubjectAttributeName(); Set set = certSubjectSerialSearch(xselector, attrs, attrName, subjectAttributeName); if (set.isEmpty()) { set.addAll(search(null, "*", attrs)); } return set; } public Collection engineGetCRLs(CRLSelector selector) throws CertStoreException { String[] attrs = {params.getCertificateRevocationListAttribute()}; if (!(selector instanceof X509CRLSelector)) { throw new CertStoreException("selector is not a X509CRLSelector"); } X509CRLSelector xselector = (X509CRLSelector)selector; Set crlSet = new HashSet(); String attrName = params.getLdapCertificateRevocationListAttributeName(); Set set = new HashSet(); if (xselector.getIssuerNames() != null) { for (Iterator it = xselector.getIssuerNames().iterator(); it .hasNext(); ) { Object o = it.next(); String attrValue = null; if (o instanceof String) { String issuerAttributeName = params .getCertificateRevocationListIssuerAttributeName(); attrValue = parseDN((String)o, issuerAttributeName); } else { String issuerAttributeName = params .getCertificateRevocationListIssuerAttributeName(); attrValue = parseDN(new X500Principal((byte[])o) .getName("RFC1779"), issuerAttributeName); } set.addAll(search(attrName, "*" + attrValue + "*", attrs)); } } else { set.addAll(search(attrName, "*", attrs)); } set.addAll(search(null, "*", attrs)); Iterator it = set.iterator(); try { CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); while (it.hasNext()) { CRL crl = cf.generateCRL(new ByteArrayInputStream((byte[])it .next())); if (xselector.match(crl)) { crlSet.add(crl); } } } catch (Exception e) { throw new CertStoreException( "CRL cannot be constructed from LDAP result " + e); } return crlSet; } /** * Escape a value for use in a filter. * * @param value the value to escape. * @return a properly escaped representation of the supplied value. */ private String filterEncode(String value) { if (value == null) { return null; } // make buffer roomy StringBuilder encodedValue = new StringBuilder(value.length() * 2); int length = value.length(); for (int i = 0; i < length; i++) { char c = value.charAt(i); if (c < FILTER_ESCAPE_TABLE.length) { encodedValue.append(FILTER_ESCAPE_TABLE[c]); } else { // default: add the char encodedValue.append(c); } } return encodedValue.toString(); } /** * Returns a Set of byte arrays with the certificate or CRL encodings. * * @param attributeName The attribute name to look for in the LDAP. * @param attributeValue The value the attribute name must have. * @param attrs The attributes in the LDAP which hold the certificate, * certificate pair or CRL in a found entry. * @return Set of byte arrays with the certificate encodings. */ private Set search(String attributeName, String attributeValue, String[] attrs) throws CertStoreException { String filter = attributeName + "=" + attributeValue; // System.out.println(filter); if (attributeName == null) { filter = null; } DirContext ctx = null; Set set = new HashSet(); try { ctx = connectLDAP(); SearchControls constraints = new SearchControls(); constraints.setSearchScope(SearchControls.SUBTREE_SCOPE); constraints.setCountLimit(0); for (int i = 0; i < attrs.length; i++) { String temp[] = new String[1]; temp[0] = attrs[i]; constraints.setReturningAttributes(temp); String filter2 = "(&(" + filter + ")(" + temp[0] + "=*))"; if (filter == null) { filter2 = "(" + temp[0] + "=*)"; } NamingEnumeration results = ctx.search(params.getBaseDN(), filter2, constraints); while (results.hasMoreElements()) { SearchResult sr = (SearchResult)results.next(); // should only be one attribute in the attribute set with // one // attribute value as byte array NamingEnumeration enumeration = ((Attribute)(sr .getAttributes().getAll().next())).getAll(); while (enumeration.hasMore()) { Object o = enumeration.next(); set.add(o); } } } } catch (Exception e) { throw new CertStoreException( "Error getting results from LDAP directory " + e); } finally { try { if (null != ctx) { ctx.close(); } } catch (Exception e) { } } return set; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy