Package codec.util

Source Code of codec.util.CertificateStore$IdxKey

/* ========================================================================
*
*  This file is part of CODEC, which is a Java package for encoding
*  and decoding ASN.1 data structures.
*
*  Author: Fraunhofer Institute for Computer Graphics Research IGD
*          Department A8: Security Technology
*          Fraunhoferstr. 5, 64283 Darmstadt, Germany
*
*  Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
*          zur Foerderung der angewandten Forschung e.V.
*          Hansastr. 27c, 80686 Munich, Germany.
*
* ------------------------------------------------------------------------
*
*  The software package is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public License as
*  published by the Free Software Foundation; either version 2.1 of the
*  License, or (at your option) any later version.
*
*  This library is distributed in the hope that it will be useful, but
*  WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this software package; if not, write to the Free
*  Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
*  MA 02110-1301, USA or obtain a copy of the license at
*  http://www.fsf.org/licensing/licenses/lgpl.txt.
*
* ------------------------------------------------------------------------
*
*  The CODEC library can solely be used and distributed according to
*  the terms and conditions of the GNU Lesser General Public License .
*
*  The CODEC library has not been tested for the use or application
*  for a determined purpose. It is a developing version that can
*  possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
*  Foerderung der angewandten Forschung e.V. does not warrant that the
*  operation of the CODEC library will be uninterrupted or error-free.
*  Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
*  Forschung e.V. warrant that the CODEC library will operate and
*  interact in an uninterrupted or error-free way together with the
*  computer program libraries of third parties which the CODEC library
*  accesses and which are distributed together with the CODEC library.
*
*  Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
*  does not warrant that the operation of the third parties's computer
*  program libraries themselves which the CODEC library accesses will
*  be uninterrupted or error-free.
*
*  Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
*  shall not be liable for any errors or direct, indirect, special,
*  incidental or consequential damages, including lost profits resulting
*  from the combination of the CODEC library with software of any user
*  or of any third party or resulting from the implementation of the
*  CODEC library in any products, systems or services of any user or
*  of any third party.
*
*  Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
*  does not provide any warranty nor any liability that utilization of
*  the CODEC library will not interfere with third party intellectual
*  property rights or with any other protected third party rights or will
*  cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
*  der angewandten Forschung e.V. is currently not aware of any such
*  rights.
*
*  The CODEC library is supplied without any accompanying services.
*
* ========================================================================
*/
package codec.util;

import java.math.BigInteger;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.Principal;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import codec.x501.BadNameException;
import codec.x501.Name;

/**
* This class wraps around regular <code>KeyStore</code> instances and
* supports retrieval of certificates in it by means of the
* {@link CertificateSource CertificateSource} interface.
*
* @author Volker Roth
* @version "$Id: CertificateStore.java,v 1.4 2000/12/06 17:47:34 vroth Exp $"
*/
public class CertificateStore extends Object implements CertificateSource {
    /**
     * The cached certificates indexed by their subject names.
     */
    protected Map sdnIdx_ = new HashMap();

    /**
     * The cached certificates indexed by their issuer names and serial numbers.
     */
    protected Map isnIdx_ = new HashMap();

    /**
     * Creates an instance that loads certificates from the given
     * <code>KeyStore</code>.
     *
     * @param keystore
     *                The <code>KeyStore</code> to load certificates from.
     * @throws KeyStoreException
     *                 if a certificate could not be retrieved from the
     *                 <code>KeyStore</code>.
     */
    public CertificateStore(KeyStore keystore) throws KeyStoreException {
  init(keystore);
    }

    /**
     * Creates an instance that loads certificates from the given
     * <code>Collection</code>.
     *
     * @param c
     *                The <code>Collection</code> to load certificates from.
     */
    public CertificateStore(Collection c) {
  init(c);
    }

    /**
     * Initializes this instance. Only X.509 certificates are cached and can be
     * retrieved since only those are known to have issuers and subjects and
     * serial numbers.
     */
    protected void init(KeyStore keystore) throws KeyStoreException {
  Enumeration e;
  String alias;

  if (keystore == null) {
      throw new NullPointerException("KeyStore");
  }
  for (e = keystore.aliases(); e.hasMoreElements();) {
      alias = (String) e.nextElement();

      try {
    addCert((X509Certificate) keystore.getCertificate(alias));
      } catch (ClassCastException ex) {
    /* Ignore, we deal only with X.509 certificates */
      }
  }
    }

    /**
     * Initializes this instance. Only X.509 certificates are cached and can be
     * retrieved since only those are known to have issuers and subjects and
     * serial numbers.
     */
    protected void init(Collection c) {
  Iterator i;

  if (c == null) {
      throw new NullPointerException("Collection");
  }
  for (i = c.iterator(); i.hasNext();) {
      try {
    addCert((X509Certificate) i.next());
      } catch (ClassCastException e) {
    /* Ignore, we deal only with X.509 certificates */
      }
  }
    }

    private void addCert(X509Certificate cert) {
  IdxKey entry;
  Object obj;
  List list;

  if (cert == null) {
      return;
  }
  entry = new IdxKey(cert.getSubjectDN());
  obj = sdnIdx_.get(entry);

  if (obj != null) {
      if (obj instanceof List) {
    list = (List) obj;
      } else {
    list = new ArrayList(3);
    list.add(obj);

    sdnIdx_.put(entry, list);
      }
      list.add(cert);
  } else {
      sdnIdx_.put(entry, cert);
  }
  entry = new IdxKey(cert.getIssuerDN(), cert.getSerialNumber());

  isnIdx_.put(entry, cert);
    }

    /**
     * This method retrieves a certificate based on the distinguished name of
     * the certificate's issuer as well as its serial number, as assigned by the
     * issuer.
     *
     * @param issuer
     *                The issuer distinguished name.
     * @param serial
     *                The serial number.
     * @return The certificate or <code>null</code> if it is not found.
     */
    public X509Certificate getCertificate(Principal issuer, BigInteger serial) {
  return (X509Certificate) isnIdx_.get(new IdxKey(issuer, serial));
    }

    /**
     * @return An <code>Iterator</code> of all known certificates with the
     *         given subject DN.
     * @param subject
     *                The subject DN of the certificate that should be
     *                retrieved.
     * @see CertificateIterator
     */
    public Iterator certificates(Principal subject) {
  return certificates(subject, CertificateSource.ALL);
    }

    /**
     * @return An <code>Iterator</code> of all known certificates with the
     *         given subject DN that match at least one of the given key usage
     *         bits.
     * @param subject
     *                The subject DN of the certificate that should be
     *                retrieved. A value of <code>null</code> matches every
     *                subject DN.
     * @param keyUsage
     *                The mask of key usage bits; at least one of these bits
     *                must be set in the key usage extension of matching
     *                certificates. A value of 0 disables key usage checking.
     * @see CertificateIterator
     */
    public Iterator certificates(Principal subject, int keyUsage) {
  Object obj;
  List list;

  obj = sdnIdx_.get(new IdxKey(subject));

  if (obj == null) {
      return Collections.EMPTY_LIST.iterator();
  }
  if (obj instanceof X509Certificate) {
      list = new ArrayList(1);
      list.add(obj);
  } else {
      list = (List) obj;
  }
  return new CertificateIterator(subject, keyUsage, list.iterator());
    }

    /**
     * This class represents an entry in the map that maps subject, issuer and
     * serial number info to an alias.
     */
    public class IdxKey extends Object {
  /**
   * The serial number
   */
  protected BigInteger serial_;

  /**
   * The issuer name.
   */
  protected String issuer_;

  /**
   * The subject name.
   */
  protected String subject_;

  /**
   * Creates an instance with the given issuer name and serial number.
   *
   * @param issuer
   *                The issuer name.
   * @param serial
   *                The serial number.
   * @throws IllegalArgumentException
   *                 if the given <code>Principal</code> cannot be
   *                 parsed into a <code>Name</code>.
   */
  public IdxKey(Principal issuer, BigInteger serial) {
      Name name;

      /*
       * Sun's implementation of the DN Principal SUCKS!!! Its equals(..)
       * method screws up, presumably does comparisons of RDNs only in the
       * order in which they appear in the DN. In order to get a
       * normalized string I have to do encoding plus decoding of names,
       * and I have to cope with a potential parsing error.
       */
      try {
    name = new Name(issuer.getName(), -1);
    issuer_ = name.toString();
      } catch (BadNameException e) {
    throw new IllegalArgumentException(e.getMessage());
      }
      serial_ = serial;
  }

  /**
   * Creates an instance with the given subject name.
   *
   * @param subject
   *                The subject.
   * @throws IllegalArgumentException
   *                 if the given <code>Principal</code> cannot be
   *                 parsed into a <code>Name</code>.
   */
  public IdxKey(Principal subject) {
      Name name;

      /*
       * Sun's implementation of the DN Principal SUCKS!!! See above for
       * an explanation of this rant.
       */
      try {
    name = new Name(subject.getName(), -1);
    subject_ = name.toString();
      } catch (BadNameException e) {
    throw new IllegalArgumentException(e.getMessage());
      }
  }

  /**
   * Compares two entries for equality. Two entries are equal if all
   * parameters that are not <code>null</code> in either instance are
   * equal. The parameters are the subject, issuer and serial number
   * information.
   *
   * @return <code>true</code> iff both instances are equal.
   */
  public boolean equals(Object o) {
      IdxKey e;

      if (o == this) {
    return true;
      }
      if (o == null || !(o instanceof IdxKey)) {
    return false;
      }
      e = (IdxKey) o;

      if (issuer_ != null || e.issuer_ != null) {
    if (issuer_ == null || e.issuer_ == null) {
        return false;
    }
    if (!issuer_.equals(e.issuer_)) {
        return false;
    }
      }
      if (subject_ != null || e.subject_ != null) {
    if (subject_ == null || e.subject_ == null) {
        return false;
    }
    if (!subject_.equals(e.subject_)) {
        return false;
    }
      }
      if (serial_ != null || e.serial_ != null) {
    if (serial_ == null || e.serial_ == null) {
        return false;
    }
    if (!serial_.equals(e.serial_)) {
        return false;
    }
      }
      return true;
  }

  /**
   * Returns the hash code of this instance. The hash code is computed
   * simply by exclusive or-ing the hash codes of all the parameters of
   * this instance.
   */
  public int hashCode() {
      int h = 0;

      if (issuer_ != null) {
    h = h ^ issuer_.hashCode();
      }
      if (subject_ != null) {
    h = h ^ subject_.hashCode();
      }
      if (serial_ != null) {
    h = h ^ serial_.hashCode();
      }
      return h;
  }

    }
}
TOP

Related Classes of codec.util.CertificateStore$IdxKey

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.