private Collection<X509Certificate> lookupFromConfigStore(String subjectName) { String domain; org.nhind.config.Certificate[] certificates; try { certificates = proxy.getCertificatesForOwner(subjectName, null); } catch (Exception e) { throw new NHINDException( "WebService error getting certificates by subject: " + e.getMessage(), e); } if (certificates == null || certificates.length == 0) { // try again with the domain name int index; if ((index = subjectName.indexOf("@")) > -1) domain = subjectName.substring(index + 1); else domain = subjectName; try { certificates = proxy.getCertificatesForOwner(domain, null); } catch (Exception e) { throw new NHINDException( "WebService error getting certificates by domain: " + e.getMessage(), e); } } if (certificates == null || certificates.length == 0) return Collections.emptyList(); Collection<X509Certificate> retVal = new ArrayList<X509Certificate>(); for (org.nhind.config.Certificate cert : certificates) { X509Certificate storeCert = certFromData(cert.getData()); retVal.add(storeCert); if (localStoreDelegate != null) { if (localStoreDelegate.contains(storeCert)) localStoreDelegate.update(storeCert); else localStoreDelegate.add(storeCert); } } // add to JCS and cache try { if (cache != null) cache.put(subjectName, retVal); } catch (CacheException e) { /* * TODO: handle exception */ } return retVal; }
/** {@inheritDoc} */ @Override public Collection<X509Certificate> getAllCertificates() { // get everything from the configuration service.... no caching here org.nhind.config.Certificate[] certificates; try { certificates = proxy.listCertificates(0L, 0x8FFF, null); // hard code to get everything } catch (Exception e) { throw new NHINDException("WebService error getting all certificates: " + e.getMessage(), e); } // purge everything this.flush(true); if (certificates == null || certificates.length == 0) return Collections.emptyList(); // convert to X509Certificates and store Collection<X509Certificate> retVal = new ArrayList<X509Certificate>(); for (org.nhind.config.Certificate cert : certificates) { X509Certificate storeCert = certFromData(cert.getData()); retVal.add(storeCert); // add to JCS and cache try { if (cache != null) cache.put(cert.getOwner(), retVal); } catch (CacheException e) { /* * TODO: handle exception */ } if (localStoreDelegate != null) { if (localStoreDelegate.contains(storeCert)) localStoreDelegate.update(storeCert); else localStoreDelegate.add(storeCert); } } return retVal; }
/** * Processes all DNS CERT requests. * * @param name The record name. In many cases this a email address. * @return Returns a set of record responses to the request. * @throws DNSException */ @SuppressWarnings("unused") protected RRset processCERTRecordRequest(String name) throws DNSException { if (name.endsWith(".")) name = name.substring(0, name.length() - 1); Certificate[] certs; // use the certificate configuration service try { certs = proxy.getCertificatesForOwner(name, null); } catch (Exception e) { throw new DNSException( DNSError.newError(Rcode.SERVFAIL), "DNS service proxy call for certificates failed: " + e.getMessage(), e); } if (certs == null || certs.length == 0) { // unless the call above was for an org level cert, it will probably always fail because the // "name" parameter has had all instances of "@" replaced with ".". The certificate service // stores owners using "@". // This is horrible, but try hitting the cert service replacing each "." with "@" one by one. // Start at the beginning of the address because this is more than likely where the "@" // character // will be. int previousIndex = 0; int replaceIndex = 0; while ((replaceIndex = name.indexOf(".", previousIndex)) > -1) { char[] chars = name.toCharArray(); chars[replaceIndex] = '@'; try { certs = proxy.getCertificatesForOwner(String.copyValueOf(chars), null); } catch (Exception e) { throw new DNSException( DNSError.newError(Rcode.SERVFAIL), "DNS service proxy call for certificates failed: " + e.getMessage(), e); } if (certs != null && certs.length > 0) break; if (replaceIndex >= (name.length() - 1)) break; previousIndex = replaceIndex + 1; } } if (certs == null || certs.length == 0) return null; if (!name.endsWith(".")) name += "."; RRset retVal = new RRset(); try { for (Certificate cert : certs) { int certRecordType = CERTRecord.PKIX; byte[] retData = null; X509Certificate xCert = null; try { // need to convert to cert container because this might be // a certificate with wrapped private key data final CertUtils.CertContainer cont = CertUtils.toCertContainer(cert.getData()); xCert = cont.getCert(); // check if this is a compliant certificate with the configured policy... if not, move on if (!isCertCompliantWithPolicy(xCert)) continue; retData = xCert.getEncoded(); } catch (CertificateConversionException e) { // probably not a Certificate... might be a URL } if (xCert == null) { // see if it's a URL try { retData = cert.getData(); URL url = new URL(new String(retData)); certRecordType = CERTRecord.URI; } catch (Exception e) { throw new DNSException( DNSError.newError(Rcode.SERVFAIL), "Failure while parsing CERT record data: " + e.getMessage(), e); } } int keyTag = 0; int alg = 0; if (xCert != null && xCert.getPublicKey() instanceof RSAKey) { RSAKey key = (RSAKey) xCert.getPublicKey(); byte[] modulus = key.getModulus().toByteArray(); keyTag = (modulus[modulus.length - 2] << 8) & 0xFF00; keyTag |= modulus[modulus.length - 1] & 0xFF; alg = 5; } CERTRecord rec = new CERTRecord( Name.fromString(name), DClass.IN, 86400L, certRecordType, keyTag, alg /*public key alg, RFC 4034*/, retData); retVal.addRR(rec); } } catch (Exception e) { throw new DNSException( DNSError.newError(Rcode.SERVFAIL), "Failure while parsing CERT record data: " + e.getMessage(), e); } // because of policy filtering, it's possible that we could have filtered out every cert // resulting in an empty RR set return (retVal.size() == 0) ? null : retVal; }