package org.bouncycastle.cert.dane.fetcher;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

import org.bouncycastle.cert.dane.DANEEntry;
import org.bouncycastle.cert.dane.DANEEntryFetcher;
import org.bouncycastle.cert.dane.DANEEntryFetcherFactory;
import org.bouncycastle.cert.dane.DANEException;

A DANE entry fetcher implemented using JNDI.
/** * A DANE entry fetcher implemented using JNDI. */
public class JndiDANEFetcherFactory implements DANEEntryFetcherFactory { private static final String DANE_TYPE = "53"; private List dnsServerList = new ArrayList(); private boolean isAuthoritative;
Specify the dnsServer to use.
Params:
  • dnsServer – IP address/name of the dns server
Returns:the current factory.
/** * Specify the dnsServer to use. * * @param dnsServer IP address/name of the dns server * @return the current factory. */
public JndiDANEFetcherFactory usingDNSServer(String dnsServer) { this.dnsServerList.add(dnsServer); return this; }
Specify requests must be authoritative, or not (default false).
Params:
  • isAuthoritative – true if requests must be authoritative, false otherwise.
Returns:the current factory..
/** * Specify requests must be authoritative, or not (default false). * * @param isAuthoritative true if requests must be authoritative, false otherwise. * @return the current factory.. */
public JndiDANEFetcherFactory setAuthoritative(boolean isAuthoritative) { this.isAuthoritative = isAuthoritative; return this; }
Build an entry fetcher for the specified domain name.
Params:
  • domainName – the domain name of interest.
Returns:a resolver for fetching entry's associated with domainName.
/** * Build an entry fetcher for the specified domain name. * * @param domainName the domain name of interest. * @return a resolver for fetching entry's associated with domainName. */
public DANEEntryFetcher build(final String domainName) { final Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory"); env.put(Context.AUTHORITATIVE, isAuthoritative ? "true" : "false"); // JDK compatibility if (dnsServerList.size() > 0) { StringBuffer dnsServers = new StringBuffer(); for (Iterator it = dnsServerList.iterator(); it.hasNext(); ) { if (dnsServers.length() > 0) { dnsServers.append(" "); } dnsServers.append("dns://" + it.next()); } env.put(Context.PROVIDER_URL, dnsServers.toString()); } return new DANEEntryFetcher() { public List getEntries() throws DANEException { List entries = new ArrayList(); try { DirContext ctx = new InitialDirContext(env); NamingEnumeration bindings; if (domainName.indexOf("_smimecert.") > 0) { // need to use fully qualified domain name if using named DNS server. Attributes attrs = ctx.getAttributes(domainName, new String[]{DANE_TYPE}); Attribute smimeAttr = attrs.get(DANE_TYPE); if (smimeAttr != null) { addEntries(entries, domainName, smimeAttr); } } else { bindings = ctx.listBindings("_smimecert." + domainName); while (bindings.hasMore()) { Binding b = (Binding)bindings.next(); DirContext sc = (DirContext)b.getObject(); String name = sc.getNameInNamespace().substring(1, sc.getNameInNamespace().length() - 1); // need to use fully qualified domain name if using named DNS server. Attributes attrs = ctx.getAttributes(name, new String[]{DANE_TYPE}); Attribute smimeAttr = attrs.get(DANE_TYPE); if (smimeAttr != null) { String fullName = sc.getNameInNamespace(); String domainName = fullName.substring(1, fullName.length() - 1); addEntries(entries, domainName, smimeAttr); } } } return entries; } catch (NamingException e) { throw new DANEException("Exception dealing with DNS: " + e.getMessage(), e); } } }; } private void addEntries(List entries, String domainName, Attribute smimeAttr) throws NamingException, DANEException { for (int index = 0; index != smimeAttr.size(); index++) { byte[] data = (byte[])smimeAttr.get(index); if (DANEEntry.isValidCertificate(data)) { try { entries.add(new DANEEntry(domainName, data)); } catch (IOException e) { throw new DANEException("Exception parsing entry: " + e.getMessage(), e); } } } } }