001/*
002 * Copyright 2017-2018 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2017-2018 Ping Identity Corporation
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.util.ssl.cert;
022
023
024
025import java.util.Collections;
026import java.util.EnumSet;
027import java.util.Set;
028
029import com.unboundid.asn1.ASN1BitString;
030import com.unboundid.util.ThreadSafety;
031import com.unboundid.util.ThreadSafetyLevel;
032
033
034
035/**
036 * This enum defines a set of reasons for which a CRL distribution point may
037 * revoke a certificate.
038 */
039@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
040public enum CRLDistributionPointRevocationReason
041{
042  /**
043   * Indicates that a CRL distribution point may revoke a certificate for an
044   * unspecified reason.
045   */
046  UNSPECIFIED("unspecified", 0),
047
048
049
050  /**
051   * Indicates that a CRL distribution point may revoke a certificate if the
052   * certificate's private key may have been compromised.
053   */
054  KEY_COMPROMISE("keyCompromise", 1),
055
056
057
058  /**
059   * Indicates that a CRL distribution point may revoke a certificate if the
060   * certificate issuer's private key may have been compromised.
061   */
062  CA_COMPROMISE("caCompromise", 2),
063
064
065
066  /**
067   * Indicates that a CRL distribution point may revoke a certificate if the
068   * owner of a certificate is no longer affiliated with its issuer.
069   */
070  AFFILIATION_CHANGED("affiliationChanged", 3),
071
072
073
074  /**
075   * Indicates that a CRL distribution point may revoke a certificate if it has
076   * been superseded by a newer certificate.
077   */
078  SUPERSEDED("superseded", 4),
079
080
081
082  /**
083   * Indicates that a CRL distribution point may revoke a certificate if the
084   * certification authority is no longer in operation.
085   */
086  CESSATION_OF_OPERATION("cessationOfOperation", 5),
087
088
089
090  /**
091   * Indicates that a CRL distribution point may revoke a certificate if the
092   * certificate has been put on hold.
093   */
094  CERTIFICATE_HOLD("certificateHold", 6),
095
096
097
098  /**
099   * Indicates that a CRL distribution point may revoke a certificate if one
100   * or more of the privileges granted to the certificate have been withdrawn.
101   */
102  PRIVILEGE_WITHDRAWN("privilegeWithdrawn", 7),
103
104
105
106  /**
107   * Indicates that a CRL distribution point may revoke a certificate if an
108   * associated attribute authority has been compromised.
109   */
110  AA_COMPROMISE("aaCompromise", 8);
111
112
113
114  // The position of this revocation reason value in the bit string.
115  private final int bitPosition;
116
117  // A human-readable name for this revocation reason.
118  private final String name;
119
120
121
122  /**
123   * Creates a CRL distribution point revocation reason value with the provided
124   * information.
125   *
126   * @param  name         A human-readable name for this revocation reason.
127   * @param  bitPosition  The bit string index of the bit that indicates whether
128   *                      this reason applies.
129   */
130  CRLDistributionPointRevocationReason(final String name,
131                                       final int bitPosition)
132  {
133    this.name = name;
134    this.bitPosition = bitPosition;
135  }
136
137
138
139  /**
140   * Retrieves a human-readable name for this CRL distribution point revocation
141   * reason.
142   *
143   * @return  A human-readable name for this CRL distribution point revocation
144   *          reason.
145   */
146  public String getName()
147  {
148    return name;
149  }
150
151
152
153  /**
154   * Retrieves the bit string index of the bit that indicates whether this
155   * reason applies.
156   *
157   * @return  The bit string index of the bit that indicates whether this reason
158   *          applies.
159   */
160  int getBitPosition()
161  {
162    return bitPosition;
163  }
164
165
166
167  /**
168   * Retrieves a set that contains all of the revocation reasons that are set in
169   * the provided bit string.
170   *
171   * @param  bitString  The bit string to examine.
172   *
173   * @return  A set that contains all of the revocation reasons that are set in
174   *          the provided bit string.
175   */
176  static Set<CRLDistributionPointRevocationReason>
177              getReasonSet(final ASN1BitString bitString)
178  {
179    final boolean[] bits = bitString.getBits();
180
181    final EnumSet<CRLDistributionPointRevocationReason> s =
182         EnumSet.noneOf(CRLDistributionPointRevocationReason.class);
183    for (final CRLDistributionPointRevocationReason r : values())
184    {
185      if ((bits.length > r.bitPosition) && bits[r.bitPosition])
186      {
187        s.add(r);
188      }
189    }
190
191    return Collections.unmodifiableSet(s);
192  }
193
194
195
196  /**
197   * Encodes the provided set of reasons to a bit string.
198   *
199   * @param  type     The DER to use for the bit string.
200   * @param  reasons  The set of reasons to encode.
201   *
202   * @return  The bit string that represents the encoded set of reasons.
203   */
204  static ASN1BitString toBitString(final byte type,
205              final Set<CRLDistributionPointRevocationReason> reasons)
206  {
207    final CRLDistributionPointRevocationReason[] values = values();
208    final boolean[] bits = new boolean[values.length];
209    for (final CRLDistributionPointRevocationReason r : values)
210    {
211      bits[r.bitPosition] = reasons.contains(r);
212    }
213
214    return new ASN1BitString(type, bits);
215  }
216}