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;
  }
Example #3
0
  /**
   * 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;
  }