示例#1
0
  /**
   * Register instance key-pair public-key certificate provided in serverProperties: generate a
   * key-id attribute if one is not provided (as expected); add an instance key public-key
   * certificate entry for the key certificate; and associate the certificate entry with the server
   * entry via the key ID attribute.
   *
   * @param ctx the InitialLdapContext on the server we want to update.
   * @param serverProperties Properties of the server being registered to which the instance key
   *     entry belongs.
   * @param serverEntryDn The server's ADS entry DN.
   * @throws ADSContextException In case some JNDI operation fails or there is a problem getting the
   *     instance public key certificate ID.
   */
  void registerInstanceKeyCertificate(
      InitialLdapContext ctx, Map<ServerProperty, Object> serverProperties, LdapName serverEntryDn)
      throws ADSContextException {
    assert serverProperties.containsKey(ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE);
    if (!serverProperties.containsKey(ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE)) {
      return;
    }

    // the key ID might be supplied in serverProperties (although, I am unaware of any such case).
    String keyID = (String) serverProperties.get(ServerProperty.INSTANCE_KEY_ID);

    /* these attributes are used both to search for an existing certificate
    entry and, if one does not exist, add a new certificate entry */
    final BasicAttributes keyAttrs = new BasicAttributes();
    final Attribute oc = new BasicAttribute("objectclass");
    oc.add("top");
    oc.add("ds-cfg-instance-key");
    keyAttrs.put(oc);
    if (null != keyID) {
      keyAttrs.put(new BasicAttribute(ServerProperty.INSTANCE_KEY_ID.getAttributeName(), keyID));
    }
    keyAttrs.put(
        new BasicAttribute(
            ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE.getAttributeName() + ";binary",
            serverProperties.get(ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE)));

    /* search for public-key certificate entry in ADS DIT */
    final String attrIDs[] = {"ds-cfg-key-id"};
    NamingEnumeration<SearchResult> results = null;
    try {
      results = ctx.search(ADSContext.getInstanceKeysContainerDN(), keyAttrs, attrIDs);
      boolean found = false;
      while (results.hasMore()) {
        final Attribute keyIdAttr = results.next().getAttributes().get(attrIDs[0]);
        if (null != keyIdAttr) {
          /* attribute ds-cfg-key-id is the entry is a MUST in the schema */
          keyID = (String) keyIdAttr.get();
        }
        found = true;
      }
      /* TODO: It is possible (but unexpected) that the caller specifies a
      ds-cfg-key-id value for which there is a certificate entry in ADS, but
      the certificate value does not match that supplied by the caller. The
      above search would not return the entry, but the below attempt to add
      an new entry with the supplied ds-cfg-key-id will fail (throw a
      NameAlreadyBoundException) */
      if (!found) {
        /* create key ID, if it was not supplied in serverProperties */
        if (null == keyID) {
          keyID =
              CryptoManagerImpl.getInstanceKeyID(
                  (byte[]) serverProperties.get(ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE));
          keyAttrs.put(
              new BasicAttribute(ServerProperty.INSTANCE_KEY_ID.getAttributeName(), keyID));
        }

        /* add public-key certificate entry */
        final LdapName keyDn =
            new LdapName(
                ServerProperty.INSTANCE_KEY_ID.getAttributeName()
                    + "="
                    + Rdn.escapeValue(keyID)
                    + ","
                    + ADSContext.getInstanceKeysContainerDN());
        ctx.createSubcontext(keyDn, keyAttrs).close();
      }

      if (serverEntryDn != null) {
        /* associate server entry with certificate entry via key ID attribute */
        ctx.modifyAttributes(
            serverEntryDn,
            InitialLdapContext.REPLACE_ATTRIBUTE,
            new BasicAttributes(ServerProperty.INSTANCE_KEY_ID.getAttributeName(), keyID));
      }
    } catch (NamingException | CryptoManagerException ne) {
      throw new ADSContextException(ErrorType.ERROR_UNEXPECTED, ne);
    } finally {
      handleCloseNamingEnumeration(results);
    }
  }