001/*
002 * Copyright 2017-2020 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2017-2020 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2017-2020 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.util.ssl.cert;
037
038
039
040import java.io.ByteArrayInputStream;
041import java.io.Serializable;
042import java.math.BigInteger;
043import java.security.KeyPair;
044import java.security.KeyPairGenerator;
045import java.security.MessageDigest;
046import java.security.PrivateKey;
047import java.security.PublicKey;
048import java.security.Signature;
049import java.security.cert.Certificate;
050import java.security.cert.CertificateException;
051import java.security.cert.CertificateFactory;
052import java.util.ArrayList;
053import java.util.Arrays;
054import java.util.Calendar;
055import java.util.Collections;
056import java.util.Date;
057import java.util.GregorianCalendar;
058import java.util.Iterator;
059import java.util.List;
060import java.util.UUID;
061
062import com.unboundid.asn1.ASN1BigInteger;
063import com.unboundid.asn1.ASN1BitString;
064import com.unboundid.asn1.ASN1Constants;
065import com.unboundid.asn1.ASN1Element;
066import com.unboundid.asn1.ASN1Exception;
067import com.unboundid.asn1.ASN1GeneralizedTime;
068import com.unboundid.asn1.ASN1Integer;
069import com.unboundid.asn1.ASN1ObjectIdentifier;
070import com.unboundid.asn1.ASN1OctetString;
071import com.unboundid.asn1.ASN1Sequence;
072import com.unboundid.asn1.ASN1Set;
073import com.unboundid.asn1.ASN1UTCTime;
074import com.unboundid.asn1.ASN1UTF8String;
075import com.unboundid.ldap.sdk.DN;
076import com.unboundid.ldap.sdk.RDN;
077import com.unboundid.ldap.sdk.schema.AttributeTypeDefinition;
078import com.unboundid.ldap.sdk.schema.Schema;
079import com.unboundid.util.Base64;
080import com.unboundid.util.Debug;
081import com.unboundid.util.NotMutable;
082import com.unboundid.util.OID;
083import com.unboundid.util.ObjectPair;
084import com.unboundid.util.StaticUtils;
085import com.unboundid.util.ThreadSafety;
086import com.unboundid.util.ThreadSafetyLevel;
087
088import static com.unboundid.util.ssl.cert.CertMessages.*;
089
090
091
092/**
093 * This class provides support for decoding an X.509 certificate as defined in
094 * <A HREF="https://www.ietf.org/rfc/rfc5280.txt">RFC 5280</A>.  The certificate
095 * is encoded using the ASN.1 Distinguished Encoding Rules (DER), which is a
096 * subset of BER, and is supported by the code in the
097 * {@code com.unboundid.asn1} package.  The ASN.1 specification is as follows:
098 * <PRE>
099 *   Certificate  ::=  SEQUENCE  {
100 *        tbsCertificate       TBSCertificate,
101 *        signatureAlgorithm   AlgorithmIdentifier,
102 *        signatureValue       BIT STRING  }
103 *
104 *   TBSCertificate  ::=  SEQUENCE  {
105 *        version         [0]  EXPLICIT Version DEFAULT v1,
106 *        serialNumber         CertificateSerialNumber,
107 *        signature            AlgorithmIdentifier,
108 *        issuer               Name,
109 *        validity             Validity,
110 *        subject              Name,
111 *        subjectPublicKeyInfo SubjectPublicKeyInfo,
112 *        issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
113 *                             -- If present, version MUST be v2 or v3
114 *        subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
115 *                             -- If present, version MUST be v2 or v3
116 *        extensions      [3]  EXPLICIT Extensions OPTIONAL
117 *                             -- If present, version MUST be v3
118 *        }
119 *
120 *   Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
121 *
122 *   CertificateSerialNumber  ::=  INTEGER
123 *
124 *   Validity ::= SEQUENCE {
125 *        notBefore      Time,
126 *        notAfter       Time }
127 *
128 *   Time ::= CHOICE {
129 *        utcTime        UTCTime,
130 *        generalTime    GeneralizedTime }
131 *
132 *   UniqueIdentifier  ::=  BIT STRING
133 *
134 *   SubjectPublicKeyInfo  ::=  SEQUENCE  {
135 *        algorithm            AlgorithmIdentifier,
136 *        subjectPublicKey     BIT STRING  }
137 *
138 *   Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
139 *
140 *   Extension  ::=  SEQUENCE  {
141 *        extnID      OBJECT IDENTIFIER,
142 *        critical    BOOLEAN DEFAULT FALSE,
143 *        extnValue   OCTET STRING
144 *                    -- contains the DER encoding of an ASN.1 value
145 *                    -- corresponding to the extension type identified
146 *                    -- by extnID
147 *        }
148 *
149 *   AlgorithmIdentifier  ::=  SEQUENCE  {
150 *        algorithm               OBJECT IDENTIFIER,
151 *        parameters              ANY DEFINED BY algorithm OPTIONAL  }
152 *
153 *   Name ::= CHOICE { -- only one possibility for now --
154 *     rdnSequence  RDNSequence }
155 *
156 *   RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
157 *
158 *   RelativeDistinguishedName ::=
159 *     SET SIZE (1..MAX) OF AttributeTypeAndValue
160 *
161 *   AttributeTypeAndValue ::= SEQUENCE {
162 *     type     AttributeType,
163 *     value    AttributeValue }
164 *
165 *   AttributeType ::= OBJECT IDENTIFIER
166 *
167 *   AttributeValue ::= ANY -- DEFINED BY AttributeType
168 * </PRE>
169 */
170@NotMutable()
171@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
172public final class X509Certificate
173       implements Serializable
174{
175  /**
176   * The DER type for the version number element, which is explicitly typed.
177   */
178  private static final byte TYPE_EXPLICIT_VERSION = (byte) 0xA0;
179
180
181
182  /**
183   * The DER type for the issuer unique ID element, which is implicitly typed.
184   */
185  private static final byte TYPE_IMPLICIT_ISSUER_UNIQUE_ID = (byte) 0x81;
186
187
188
189  /**
190   * The DER type for the subject unique ID element, which is implicitly typed.
191   */
192  private static final byte TYPE_IMPLICIT_SUBJECT_UNIQUE_ID = (byte) 0x82;
193
194
195
196  /**
197   * The DER type for the extensions element, which is explicitly typed.
198   */
199  private static final byte TYPE_EXPLICIT_EXTENSIONS = (byte) 0xA3;
200
201
202
203  /**
204   * The serial version UID for this serializable class.
205   */
206  private static final long serialVersionUID = -4680448103099282243L;
207
208
209
210  // The issuer unique identifier for the certificate.
211  private final ASN1BitString issuerUniqueID;
212
213  // The signature value for the certificate.
214  private final ASN1BitString signatureValue;
215
216  // The encoded certificate public key.
217  private final ASN1BitString encodedPublicKey;
218
219  // The subject unique identifier for the certificate.
220  private final ASN1BitString subjectUniqueID;
221
222  // The ASN.1 element with the encoded public key algorithm parameters.
223  private final ASN1Element publicKeyAlgorithmParameters;
224
225  // The ASN.1 element with the encoded signature algorithm parameters.
226  private final ASN1Element signatureAlgorithmParameters;
227
228  // The certificate serial number.
229  private final BigInteger serialNumber;
230
231  // The bytes that comprise the encoded representation of the X.509
232  // certificate.
233  private final byte[] x509CertificateBytes;
234
235  // The decoded public key for this certificate, if available.
236  private final DecodedPublicKey decodedPublicKey;
237
238  // The issuer DN for the certificate.
239  private final DN issuerDN;
240
241  // The subject DN for the certificate.
242  private final DN subjectDN;
243
244  // The list of extensions for the certificate.
245  private final List<X509CertificateExtension> extensions;
246
247  // The time that indicates the end of the certificate validity window.
248  private final long notAfter;
249
250  // The time that indicates the beginning of the certificate validity window.
251  private final long notBefore;
252
253  // The OID for the public key algorithm.
254  private final OID publicKeyAlgorithmOID;
255
256  // The OID for the signature algorithm.
257  private final OID signatureAlgorithmOID;
258
259  // The public key algorithm name that corresponds with the public key
260  // algorithm OID, if available.
261  private final String publicKeyAlgorithmName;
262
263  // The signature algorithm name that corresponds with the signature algorithm
264  // OID, if available.
265  private final String signatureAlgorithmName;
266
267  // The X.509 certificate version.
268  private final X509CertificateVersion version;
269
270
271
272  /**
273   * Creates a new X.509 certificate with the provided information.  This is
274   * primarily intended for unit testing and other internal use.
275   *
276   * @param  version                       The version number for the
277   *                                       certificate.
278   * @param  serialNumber                  The serial number for the
279   *                                       certificate.  This must not be
280   *                                       {@code null}.
281   * @param  signatureAlgorithmOID         The signature algorithm OID for the
282   *                                       certificate.  This must not be
283   *                                       {@code null}.
284   * @param  signatureAlgorithmParameters  The encoded signature algorithm
285   *                                       parameters for the certificate.  This
286   *                                       may be {@code null} if there are no
287   *                                       parameters.
288   * @param  signatureValue                The encoded signature for the
289   *                                       certificate.  This must not be
290   *                                       {@code null}.
291   * @param  issuerDN                      The issuer DN for the certificate.
292   *                                       This must not be {@code null}.
293   * @param  notBefore                     The validity start time for the
294   *                                       certificate.
295   * @param  notAfter                      The validity end time for the
296   *                                       certificate.
297   * @param  subjectDN                     The subject DN for the certificate.
298   *                                       This must not be {@code null}.
299   * @param  publicKeyAlgorithmOID         The OID of the public key algorithm
300   *                                       for the certificate.  This must not
301   *                                       be {@code null}.
302   * @param  publicKeyAlgorithmParameters  The encoded public key algorithm
303   *                                       parameters for the certificate.  This
304   *                                       may be {@code null} if there are no
305   *                                       parameters.
306   * @param  encodedPublicKey              The encoded public key for the
307   *                                       certificate.  This must not be
308   *                                       {@code null}.
309   * @param  decodedPublicKey              The decoded public key for the
310   *                                       certificate.  This may be
311   *                                       {@code null} if it is not available.
312   * @param  issuerUniqueID                The issuer unique ID for the
313   *                                       certificate.  This may be
314   *                                       {@code null} if the certificate does
315   *                                       not have an issuer unique ID.
316   * @param  subjectUniqueID               The subject unique ID for the
317   *                                       certificate.  This may be
318   *                                       {@code null} if the certificate does
319   *                                       not have a subject unique ID.
320   * @param  extensions                    The set of extensions to include in
321   *                                       the certificate.  This must not be
322   *                                       {@code null} but may be empty.
323   *
324   * @throws  CertException  If a problem is encountered while creating the
325   *                         certificate.
326   */
327  X509Certificate(final X509CertificateVersion version,
328                  final BigInteger serialNumber,
329                  final OID signatureAlgorithmOID,
330                  final ASN1Element signatureAlgorithmParameters,
331                  final ASN1BitString signatureValue,
332                  final DN issuerDN, final long notBefore, final long notAfter,
333                  final DN subjectDN, final OID publicKeyAlgorithmOID,
334                  final ASN1Element publicKeyAlgorithmParameters,
335                  final ASN1BitString encodedPublicKey,
336                  final DecodedPublicKey decodedPublicKey,
337                  final ASN1BitString issuerUniqueID,
338                  final ASN1BitString subjectUniqueID,
339                  final X509CertificateExtension... extensions)
340       throws CertException
341  {
342    this.version = version;
343    this.serialNumber = serialNumber;
344    this.signatureAlgorithmOID = signatureAlgorithmOID;
345    this.signatureAlgorithmParameters = signatureAlgorithmParameters;
346    this.signatureValue = signatureValue;
347    this.issuerDN = issuerDN;
348    this.notBefore = notBefore;
349    this.notAfter = notAfter;
350    this.subjectDN = subjectDN;
351    this.publicKeyAlgorithmOID = publicKeyAlgorithmOID;
352    this.publicKeyAlgorithmParameters = publicKeyAlgorithmParameters;
353    this.encodedPublicKey = encodedPublicKey;
354    this.decodedPublicKey = decodedPublicKey;
355    this.issuerUniqueID = issuerUniqueID;
356    this.subjectUniqueID = subjectUniqueID;
357    this.extensions = StaticUtils.toList(extensions);
358
359    final SignatureAlgorithmIdentifier signatureAlgorithmIdentifier =
360         SignatureAlgorithmIdentifier.forOID(signatureAlgorithmOID);
361    if (signatureAlgorithmIdentifier == null)
362    {
363      signatureAlgorithmName = null;
364    }
365    else
366    {
367      signatureAlgorithmName =
368           signatureAlgorithmIdentifier.getUserFriendlyName();
369    }
370
371    final PublicKeyAlgorithmIdentifier publicKeyAlgorithmIdentifier =
372         PublicKeyAlgorithmIdentifier.forOID(publicKeyAlgorithmOID);
373    if (publicKeyAlgorithmIdentifier == null)
374    {
375      publicKeyAlgorithmName = null;
376    }
377    else
378    {
379      publicKeyAlgorithmName = publicKeyAlgorithmIdentifier.getName();
380    }
381
382    x509CertificateBytes = encode().encode();
383  }
384
385
386
387  /**
388   * Decodes the contents of the provided byte array as an X.509 certificate.
389   *
390   * @param  encodedCertificate  The byte array containing the encoded X.509
391   *                             certificate.  This must not be {@code null}.
392   *
393   * @throws  CertException  If the contents of the provided byte array could
394   *                         not be decoded as a valid X.509 certificate.
395   */
396  public X509Certificate(final byte[] encodedCertificate)
397         throws CertException
398  {
399    x509CertificateBytes = encodedCertificate;
400
401    final ASN1Element[] certificateElements;
402    try
403    {
404      certificateElements =
405           ASN1Sequence.decodeAsSequence(encodedCertificate).elements();
406    }
407    catch (final Exception e)
408    {
409      Debug.debugException(e);
410      throw new CertException(
411           ERR_CERT_DECODE_NOT_SEQUENCE.get(StaticUtils.getExceptionMessage(e)),
412           e);
413    }
414
415    if (certificateElements.length != 3)
416    {
417      throw new CertException(
418           ERR_CERT_DECODE_UNEXPECTED_SEQUENCE_ELEMENT_COUNT.get(
419                certificateElements.length));
420    }
421
422    final ASN1Element[] tbsCertificateElements;
423    try
424    {
425      tbsCertificateElements =
426           ASN1Sequence.decodeAsSequence(certificateElements[0]).elements();
427    }
428    catch (final Exception e)
429    {
430      Debug.debugException(e);
431      throw new CertException(
432           ERR_CERT_DECODE_FIRST_ELEMENT_NOT_SEQUENCE.get(
433                StaticUtils.getExceptionMessage(e)),
434           e);
435    }
436
437    int tbsCertificateElementIndex;
438    try
439    {
440      // The version element may or may not be present in a certificate.  If it
441      // is present, then it will be explicitly tagged, which means that it's a
442      // constructed element with the DER-encoded integer inside it.  If it is
443      // absent, then a default version of v1 will be used.
444      if ((tbsCertificateElements[0].getType() & 0xFF) == 0xA0)
445      {
446        final int versionIntValue = ASN1Integer.decodeAsInteger(
447             tbsCertificateElements[0].getValue()).intValue();
448        version = X509CertificateVersion.valueOf(versionIntValue);
449        if (version == null)
450        {
451          throw new CertException(
452               ERR_CERT_DECODE_UNSUPPORTED_VERSION.get(version));
453        }
454
455        tbsCertificateElementIndex = 1;
456      }
457      else
458      {
459        version = X509CertificateVersion.V1;
460        tbsCertificateElementIndex = 0;
461      }
462    }
463    catch (final CertException e)
464    {
465      Debug.debugException(e);
466      throw e;
467    }
468    catch (final Exception e)
469    {
470      Debug.debugException(e);
471      throw new CertException(
472           ERR_CERT_DECODE_CANNOT_PARSE_VERSION.get(
473                StaticUtils.getExceptionMessage(e)),
474           e);
475    }
476
477    try
478    {
479      serialNumber = tbsCertificateElements[tbsCertificateElementIndex++].
480           decodeAsBigInteger().getBigIntegerValue();
481    }
482    catch (final Exception e)
483    {
484      Debug.debugException(e);
485      throw new CertException(
486           ERR_CERT_DECODE_CANNOT_PARSE_SERIAL_NUMBER.get(
487                StaticUtils.getExceptionMessage(e)),
488           e);
489    }
490
491    try
492    {
493      final ASN1Element[] signatureAlgorithmElements =
494           tbsCertificateElements[tbsCertificateElementIndex++].
495                decodeAsSequence().elements();
496      signatureAlgorithmOID =
497           signatureAlgorithmElements[0].decodeAsObjectIdentifier().getOID();
498      if (signatureAlgorithmElements.length > 1)
499      {
500        signatureAlgorithmParameters = signatureAlgorithmElements[1];
501      }
502      else
503      {
504        signatureAlgorithmParameters = null;
505      }
506    }
507    catch (final Exception e)
508    {
509      Debug.debugException(e);
510      throw new CertException(
511           ERR_CERT_DECODE_CANNOT_PARSE_SIG_ALG.get(
512                StaticUtils.getExceptionMessage(e)),
513           e);
514    }
515
516    final SignatureAlgorithmIdentifier signatureAlgorithmIdentifier =
517         SignatureAlgorithmIdentifier.forOID(signatureAlgorithmOID);
518    if (signatureAlgorithmIdentifier == null)
519    {
520      signatureAlgorithmName = null;
521    }
522    else
523    {
524      signatureAlgorithmName =
525           signatureAlgorithmIdentifier.getUserFriendlyName();
526    }
527
528    try
529    {
530      issuerDN =
531           decodeName(tbsCertificateElements[tbsCertificateElementIndex++]);
532    }
533    catch (final Exception e)
534    {
535      Debug.debugException(e);
536      throw new CertException(
537           ERR_CERT_DECODE_CANNOT_PARSE_ISSUER_DN.get(
538                StaticUtils.getExceptionMessage(e)),
539           e);
540    }
541
542    try
543    {
544      final ASN1Element[] validityElements =
545           tbsCertificateElements[tbsCertificateElementIndex++].
546                decodeAsSequence().elements();
547      switch (validityElements[0].getType())
548      {
549        case ASN1Constants.UNIVERSAL_UTC_TIME_TYPE:
550          notBefore = decodeUTCTime(validityElements[0]);
551          break;
552        case ASN1Constants.UNIVERSAL_GENERALIZED_TIME_TYPE:
553          notBefore = validityElements[0].decodeAsGeneralizedTime().getTime();
554          break;
555        default:
556          throw new CertException(
557               ERR_CERT_DECODE_NOT_BEFORE_UNEXPECTED_TYPE.get(
558                    StaticUtils.toHex(validityElements[0].getType()),
559                    StaticUtils.toHex(ASN1Constants.UNIVERSAL_UTC_TIME_TYPE),
560                    StaticUtils.toHex(ASN1Constants.
561                         UNIVERSAL_GENERALIZED_TIME_TYPE)));
562      }
563
564      switch (validityElements[1].getType())
565      {
566        case ASN1Constants.UNIVERSAL_UTC_TIME_TYPE:
567          notAfter = decodeUTCTime(validityElements[1]);
568          break;
569        case ASN1Constants.UNIVERSAL_GENERALIZED_TIME_TYPE:
570          notAfter = validityElements[1].decodeAsGeneralizedTime().getTime();
571          break;
572        default:
573          throw new CertException(
574               ERR_CERT_DECODE_NOT_AFTER_UNEXPECTED_TYPE.get(
575                    StaticUtils.toHex(validityElements[0].getType()),
576                    StaticUtils.toHex(ASN1Constants.UNIVERSAL_UTC_TIME_TYPE),
577                    StaticUtils.toHex(ASN1Constants.
578                         UNIVERSAL_GENERALIZED_TIME_TYPE)));
579      }
580    }
581    catch (final CertException e)
582    {
583      Debug.debugException(e);
584      throw e;
585    }
586    catch (final Exception e)
587    {
588      Debug.debugException(e);
589      throw new CertException(
590           ERR_CERT_DECODE_COULD_NOT_PARSE_VALIDITY.get(
591                StaticUtils.getExceptionMessage(e)),
592           e);
593    }
594
595    try
596    {
597      subjectDN =
598           decodeName(tbsCertificateElements[tbsCertificateElementIndex++]);
599    }
600    catch (final Exception e)
601    {
602      Debug.debugException(e);
603      throw new CertException(
604           ERR_CERT_DECODE_CANNOT_PARSE_SUBJECT_DN.get(
605                StaticUtils.getExceptionMessage(e)),
606           e);
607    }
608
609    try
610    {
611      final ASN1Element[] subjectPublicKeyInfoElements =
612           tbsCertificateElements[tbsCertificateElementIndex++].
613                decodeAsSequence().elements();
614      final ASN1Element[] publicKeyAlgorithmElements =
615           subjectPublicKeyInfoElements[0].decodeAsSequence().elements();
616      publicKeyAlgorithmOID =
617           publicKeyAlgorithmElements[0].decodeAsObjectIdentifier().getOID();
618      if (publicKeyAlgorithmElements.length > 1)
619      {
620        publicKeyAlgorithmParameters = publicKeyAlgorithmElements[1];
621      }
622      else
623      {
624        publicKeyAlgorithmParameters = null;
625      }
626
627      encodedPublicKey = subjectPublicKeyInfoElements[1].decodeAsBitString();
628    }
629    catch (final Exception e)
630    {
631      Debug.debugException(e);
632      throw new CertException(
633           ERR_CERT_DECODE_CANNOT_PARSE_PUBLIC_KEY_INFO.get(
634                StaticUtils.getExceptionMessage(e)),
635           e);
636    }
637
638    final PublicKeyAlgorithmIdentifier publicKeyAlgorithmIdentifier =
639         PublicKeyAlgorithmIdentifier.forOID(publicKeyAlgorithmOID);
640    if (publicKeyAlgorithmIdentifier == null)
641    {
642      publicKeyAlgorithmName = null;
643      decodedPublicKey = null;
644    }
645    else
646    {
647      publicKeyAlgorithmName = publicKeyAlgorithmIdentifier.getName();
648
649      DecodedPublicKey pk = null;
650      switch (publicKeyAlgorithmIdentifier)
651      {
652        case RSA:
653          try
654          {
655            pk = new RSAPublicKey(encodedPublicKey);
656          }
657          catch (final Exception e)
658          {
659            Debug.debugException(e);
660          }
661          break;
662
663        case EC:
664          try
665          {
666            pk = new EllipticCurvePublicKey(encodedPublicKey);
667          }
668          catch (final Exception e)
669          {
670            Debug.debugException(e);
671          }
672          break;
673      }
674
675      decodedPublicKey = pk;
676    }
677
678    ASN1BitString issuerID = null;
679    ASN1BitString subjectID = null;
680    final ArrayList<X509CertificateExtension> extList = new ArrayList<>(10);
681    for (;
682         tbsCertificateElementIndex < tbsCertificateElements.length;
683         tbsCertificateElementIndex++)
684    {
685      switch (tbsCertificateElements[tbsCertificateElementIndex].getType())
686      {
687        case (byte) 0x81:
688          try
689          {
690            issuerID = tbsCertificateElements[tbsCertificateElementIndex].
691                 decodeAsBitString();
692          }
693          catch (final Exception e)
694          {
695            Debug.debugException(e);
696            throw new CertException(
697                 ERR_CERT_DECODE_CANNOT_PARSE_ISSUER_UNIQUE_ID.get(
698                      StaticUtils.getExceptionMessage(e)),
699                 e);
700          }
701          break;
702        case (byte) 0x82:
703          try
704          {
705            subjectID = tbsCertificateElements[tbsCertificateElementIndex].
706                 decodeAsBitString();
707          }
708          catch (final Exception e)
709          {
710            Debug.debugException(e);
711            throw new CertException(
712                 ERR_CERT_DECODE_CANNOT_PARSE_SUBJECT_UNIQUE_ID.get(
713                      StaticUtils.getExceptionMessage(e)),
714                 e);
715          }
716          break;
717        case (byte) 0xA3:
718          try
719          {
720            // This element is explicitly tagged.
721            final ASN1Element[] extensionElements = ASN1Sequence.
722                 decodeAsSequence(tbsCertificateElements[
723                      tbsCertificateElementIndex].getValue()).elements();
724            for (final ASN1Element extensionElement : extensionElements)
725            {
726              extList.add(X509CertificateExtension.decode(extensionElement));
727            }
728          }
729          catch (final Exception e)
730          {
731            Debug.debugException(e);
732            throw new CertException(
733                 ERR_CERT_DECODE_CANNOT_PARSE_EXTENSION.get(
734                      StaticUtils.getExceptionMessage(e)),
735                 e);
736          }
737          break;
738      }
739    }
740
741    issuerUniqueID = issuerID;
742    subjectUniqueID = subjectID;
743    extensions = Collections.unmodifiableList(extList);
744
745    try
746    {
747      final ASN1Element[] signatureAlgorithmElements =
748           certificateElements[1].decodeAsSequence().elements();
749      final OID oid =
750           signatureAlgorithmElements[0].decodeAsObjectIdentifier().getOID();
751      if (! oid.equals(signatureAlgorithmOID))
752      {
753        throw new CertException(
754             ERR_CERT_DECODE_SIG_ALG_MISMATCH.get(
755                  signatureAlgorithmOID.toString(), oid.toString()));
756      }
757    }
758    catch (final CertException e)
759    {
760      Debug.debugException(e);
761      throw e;
762    }
763    catch (final Exception e)
764    {
765      Debug.debugException(e);
766      throw new CertException(
767           ERR_CERT_DECODE_CANNOT_PARSE_SIG_ALG.get(
768                StaticUtils.getExceptionMessage(e)),
769           e);
770    }
771
772    try
773    {
774      signatureValue = certificateElements[2].decodeAsBitString();
775    }
776    catch (final Exception e)
777    {
778      Debug.debugException(e);
779      throw new CertException(
780           ERR_CERT_DECODE_CANNOT_PARSE_SIG_VALUE.get(
781                StaticUtils.getExceptionMessage(e)),
782           e);
783    }
784  }
785
786
787
788  /**
789   * Decodes the provided ASN.1 element as an X.509 name.
790   *
791   * @param  element  The ASN.1 element to decode.
792   *
793   * @return  The DN created from the decoded X.509 name.
794   *
795   * @throws  CertException  If a problem is encountered while trying to decode
796   *                         the X.509 name.
797   */
798  static DN decodeName(final ASN1Element element)
799         throws CertException
800  {
801    Schema schema;
802    try
803    {
804      schema = Schema.getDefaultStandardSchema();
805    }
806    catch (final Exception e)
807    {
808      Debug.debugException(e);
809      schema = null;
810    }
811
812    final ASN1Element[] rdnElements;
813    try
814    {
815      rdnElements = ASN1Sequence.decodeAsSequence(element).elements();
816    }
817    catch (final Exception e)
818    {
819      Debug.debugException(e);
820      throw new CertException(
821           ERR_CERT_DECODE_NAME_NOT_SEQUENCE.get(
822                StaticUtils.getExceptionMessage(e)),
823           e);
824    }
825
826    final ArrayList<RDN> rdns = new ArrayList<>(rdnElements.length);
827    for (int i=0; i < rdnElements.length; i++)
828    {
829      try
830      {
831        final ASN1Element[] attributeSetElements =
832             rdnElements[i].decodeAsSet().elements();
833        final String[] attributeNames = new String[attributeSetElements.length];
834        final byte[][] attributeValues =
835             new byte[attributeSetElements.length][];
836        for (int j=0; j < attributeSetElements.length; j++)
837        {
838          final ASN1Element[] attributeTypeAndValueElements =
839               ASN1Sequence.decodeAsSequence(attributeSetElements[j]).
840                    elements();
841
842          final OID attributeTypeOID = attributeTypeAndValueElements[0].
843               decodeAsObjectIdentifier().getOID();
844          final AttributeTypeDefinition attributeType =
845               schema.getAttributeType(attributeTypeOID.toString());
846          if (attributeType == null)
847          {
848            attributeNames[j] = attributeTypeOID.toString();
849          }
850          else
851          {
852            attributeNames[j] = attributeType.getNameOrOID().toUpperCase();
853          }
854
855          attributeValues[j] = attributeTypeAndValueElements[1].
856               decodeAsOctetString().getValue();
857        }
858
859        rdns.add(new RDN(attributeNames, attributeValues, schema));
860      }
861      catch (final Exception e)
862      {
863        Debug.debugException(e);
864        throw new CertException(
865             ERR_CERT_DECODE_CANNOT_PARSE_NAME_SEQUENCE_ELEMENT.get(i,
866                  StaticUtils.getExceptionMessage(e)),
867             e);
868      }
869    }
870
871    Collections.reverse(rdns);
872    return new DN(rdns);
873  }
874
875
876
877  /**
878   * Decodes the provided ASN.1 element as a UTC time element and retrieves the
879   * corresponding time.  As per the X.509 specification, the resulting value
880   * will be guaranteed to fall between the years 1950 and 2049.
881   *
882   * @param  element  The ASN.1 element to decode as a UTC time value.
883   *
884   * @return  The decoded time value.
885   *
886   * @throws  ASN1Exception  If the provided element cannot be decoded as a UTC
887   *                         time element.
888   */
889  private static long decodeUTCTime(final ASN1Element element)
890          throws ASN1Exception
891  {
892    final long timeValue = ASN1UTCTime.decodeAsUTCTime(element).getTime();
893
894    final GregorianCalendar calendar = new GregorianCalendar();
895    calendar.setTimeInMillis(timeValue);
896
897    final int year = calendar.get(Calendar.YEAR);
898    if (year < 1949)
899    {
900      calendar.set(Calendar.YEAR, (year + 100));
901    }
902    else if (year > 2050)
903    {
904      calendar.set(Calendar.YEAR, (year - 100));
905    }
906
907    return calendar.getTimeInMillis();
908  }
909
910
911
912  /**
913   * Encodes this X.509 certificate to an ASN.1 element.
914   *
915   * @return  The encoded X.509 certificate.
916   *
917   * @throws  CertException  If a problem is encountered while trying to encode
918   *                         the X.509 certificate.
919   */
920  ASN1Element encode()
921       throws CertException
922  {
923    try
924    {
925      final ArrayList<ASN1Element> tbsCertificateElements = new ArrayList<>(10);
926
927      if (version != X509CertificateVersion.V1)
928      {
929        tbsCertificateElements.add(new ASN1Element(TYPE_EXPLICIT_VERSION,
930             new ASN1Integer(version.getIntValue()).encode()));
931      }
932
933      tbsCertificateElements.add(new ASN1BigInteger(serialNumber));
934
935      if (signatureAlgorithmParameters == null)
936      {
937        tbsCertificateElements.add(new ASN1Sequence(
938             new ASN1ObjectIdentifier(signatureAlgorithmOID)));
939      }
940      else
941      {
942        tbsCertificateElements.add(new ASN1Sequence(
943             new ASN1ObjectIdentifier(signatureAlgorithmOID),
944             signatureAlgorithmParameters));
945      }
946
947
948      tbsCertificateElements.add(encodeName(issuerDN));
949      tbsCertificateElements.add(encodeValiditySequence(notBefore, notAfter));
950      tbsCertificateElements.add(encodeName(subjectDN));
951
952      if (publicKeyAlgorithmParameters == null)
953      {
954        tbsCertificateElements.add(new ASN1Sequence(
955             new ASN1Sequence(
956                  new ASN1ObjectIdentifier(publicKeyAlgorithmOID)),
957             encodedPublicKey));
958      }
959      else
960      {
961        tbsCertificateElements.add(new ASN1Sequence(
962             new ASN1Sequence(
963                  new ASN1ObjectIdentifier(publicKeyAlgorithmOID),
964                  publicKeyAlgorithmParameters),
965             encodedPublicKey));
966      }
967
968      if (issuerUniqueID != null)
969      {
970        tbsCertificateElements.add(new ASN1BitString(
971             TYPE_IMPLICIT_ISSUER_UNIQUE_ID, issuerUniqueID.getBits()));
972      }
973
974      if (subjectUniqueID != null)
975      {
976        tbsCertificateElements.add(new ASN1BitString(
977             TYPE_IMPLICIT_SUBJECT_UNIQUE_ID, subjectUniqueID.getBits()));
978      }
979
980      if (! extensions.isEmpty())
981      {
982        final ArrayList<ASN1Element> extensionElements =
983             new ArrayList<>(extensions.size());
984        for (final X509CertificateExtension e : extensions)
985        {
986          extensionElements.add(e.encode());
987        }
988        tbsCertificateElements.add(new ASN1Element(TYPE_EXPLICIT_EXTENSIONS,
989             new ASN1Sequence(extensionElements).encode()));
990      }
991
992      final ArrayList<ASN1Element> certificateElements = new ArrayList<>(3);
993      certificateElements.add(new ASN1Sequence(tbsCertificateElements));
994
995      if (signatureAlgorithmParameters == null)
996      {
997        certificateElements.add(new ASN1Sequence(
998             new ASN1ObjectIdentifier(signatureAlgorithmOID)));
999      }
1000      else
1001      {
1002        certificateElements.add(new ASN1Sequence(
1003             new ASN1ObjectIdentifier(signatureAlgorithmOID),
1004             signatureAlgorithmParameters));
1005      }
1006
1007      certificateElements.add(signatureValue);
1008
1009      return new ASN1Sequence(certificateElements);
1010    }
1011    catch (final Exception e)
1012    {
1013      Debug.debugException(e);
1014      throw new CertException(
1015           ERR_CERT_ENCODE_ERROR.get(toString(),
1016                StaticUtils.getExceptionMessage(e)),
1017           e);
1018    }
1019  }
1020
1021
1022
1023  /**
1024   * Encodes the provided DN as an X.509 name for inclusion in an encoded
1025   * certificate.
1026   *
1027   * @param  dn  The DN to encode.
1028   *
1029   * @return  The encoded X.509 name.
1030   *
1031   * @throws  CertException  If a problem is encountered while encoding the
1032   *                         provided DN as an X.509 name.
1033   */
1034  static ASN1Element encodeName(final DN dn)
1035         throws CertException
1036  {
1037    final Schema schema;
1038    try
1039    {
1040      schema = Schema.getDefaultStandardSchema();
1041    }
1042    catch (final Exception e)
1043    {
1044      Debug.debugException(e);
1045      throw new CertException(
1046           ERR_CERT_ENCODE_NAME_CANNOT_GET_SCHEMA.get(String.valueOf(dn),
1047                StaticUtils.getExceptionMessage(e)),
1048           e);
1049    }
1050
1051    final RDN[] rdns = dn.getRDNs();
1052    final ArrayList<ASN1Element> rdnSequenceElements =
1053         new ArrayList<>(rdns.length);
1054    for (int i=rdns.length - 1; i >= 0; i--)
1055    {
1056      final RDN rdn =rdns[i];
1057      final String[] names = rdn.getAttributeNames();
1058      final String[] values = rdn.getAttributeValues();
1059
1060      final ArrayList<ASN1Element> rdnElements = new ArrayList<>(names.length);
1061      for (int j=0; j < names.length; j++)
1062      {
1063        final AttributeTypeDefinition at = schema.getAttributeType(names[j]);
1064        if (at == null)
1065        {
1066          throw new CertException(ERR_CERT_ENCODE_NAME_UNKNOWN_ATTR_TYPE.get(
1067               String.valueOf(dn), names[j]));
1068        }
1069
1070        try
1071        {
1072          rdnElements.add(new ASN1Sequence(
1073               new ASN1ObjectIdentifier(at.getOID()),
1074               new ASN1UTF8String(values[j])));
1075        }
1076        catch (final Exception e)
1077        {
1078          Debug.debugException(e);
1079          throw new CertException(
1080               ERR_CERT_ENCODE_NAME_ERROR.get(String.valueOf(dn),
1081                    StaticUtils.getExceptionMessage(e)),
1082               e);
1083        }
1084      }
1085
1086      rdnSequenceElements.add(new ASN1Set(rdnElements));
1087    }
1088
1089    return new ASN1Sequence(rdnSequenceElements);
1090  }
1091
1092
1093
1094  /**
1095   * Encodes the certificate validity sequence, using a UTC time encoding if
1096   * both notBefore and notAfter values fall within the range 1950-2049, and
1097   * using generalized time if either value falls outside that range.
1098   *
1099   * @param  notBefore  The notBefore value to include in the sequence.
1100   * @param  notAfter   The notAfter value to include in the sequence.
1101   *
1102   * @return  The encoded validity sequence.
1103   */
1104  static ASN1Sequence encodeValiditySequence(final long notBefore,
1105                                             final long notAfter)
1106  {
1107    final GregorianCalendar notBeforeCalendar = new GregorianCalendar();
1108    notBeforeCalendar.setTimeInMillis(notBefore);
1109    final int notBeforeYear = notBeforeCalendar.get(Calendar.YEAR);
1110
1111    final GregorianCalendar notAfterCalendar = new GregorianCalendar();
1112    notAfterCalendar.setTimeInMillis(notAfter);
1113    final int notAfterYear = notAfterCalendar.get(Calendar.YEAR);
1114
1115    if ((notBeforeYear >= 1950) && (notBeforeYear <= 2049) &&
1116        (notAfterYear >= 1950) && (notAfterYear <= 2049))
1117    {
1118      return new ASN1Sequence(
1119           new ASN1UTCTime(notBefore),
1120           new ASN1UTCTime(notAfter));
1121    }
1122    else
1123    {
1124      return new ASN1Sequence(
1125           new ASN1GeneralizedTime(notBefore),
1126           new ASN1GeneralizedTime(notAfter));
1127    }
1128  }
1129
1130
1131
1132  /**
1133   * Generates a self-signed X.509 certificate with the provided information.
1134   *
1135   * @param  signatureAlgorithm  The algorithm to use to generate the signature.
1136   *                             This must not be {@code null}.
1137   * @param  publicKeyAlgorithm  The algorithm to use to generate the key pair.
1138   *                             This must not be {@code null}.
1139   * @param  keySizeBits         The size of the key to generate, in bits.
1140   * @param  subjectDN           The subject DN for the certificate.  This must
1141   *                             not be {@code null}.
1142   * @param  notBefore           The validity start time for the certificate.
1143   * @param  notAfter            The validity end time for the certificate.
1144   * @param  extensions          The set of extensions to include in the
1145   *                             certificate.  This may be {@code null} or empty
1146   *                             if the certificate should not include any
1147   *                             custom extensions.  Note that the generated
1148   *                             certificate will automatically include a
1149   *                             {@link SubjectKeyIdentifierExtension}, so that
1150   *                             should not be provided.
1151   *
1152   * @return  An {@code ObjectPair} that contains both the self-signed
1153   *          certificate and its corresponding key pair.
1154   *
1155   * @throws  CertException  If a problem is encountered while creating the
1156   *                         certificate.
1157   */
1158  public static ObjectPair<X509Certificate,KeyPair>
1159              generateSelfSignedCertificate(
1160                   final SignatureAlgorithmIdentifier signatureAlgorithm,
1161                   final PublicKeyAlgorithmIdentifier publicKeyAlgorithm,
1162                   final int keySizeBits, final DN subjectDN,
1163                   final long notBefore, final long notAfter,
1164                   final X509CertificateExtension... extensions)
1165         throws CertException
1166  {
1167    // Generate the key pair for the certificate.
1168    final KeyPairGenerator keyPairGenerator;
1169    try
1170    {
1171      keyPairGenerator =
1172           KeyPairGenerator.getInstance(publicKeyAlgorithm.getName());
1173    }
1174    catch (final Exception e)
1175    {
1176      Debug.debugException(e);
1177      throw new CertException(
1178           ERR_CERT_GEN_SELF_SIGNED_CANNOT_GET_KEY_GENERATOR.get(
1179                publicKeyAlgorithm.getName(),
1180                StaticUtils.getExceptionMessage(e)),
1181           e);
1182    }
1183
1184    try
1185    {
1186      keyPairGenerator.initialize(keySizeBits);
1187    }
1188    catch (final Exception e)
1189    {
1190      Debug.debugException(e);
1191      throw new CertException(
1192           ERR_CERT_GEN_SELF_SIGNED_INVALID_KEY_SIZE.get(keySizeBits,
1193                publicKeyAlgorithm.getName(),
1194                StaticUtils.getExceptionMessage(e)),
1195           e);
1196    }
1197
1198    final KeyPair keyPair;
1199    try
1200    {
1201      keyPair = keyPairGenerator.generateKeyPair();
1202    }
1203    catch (final Exception e)
1204    {
1205      Debug.debugException(e);
1206      throw new CertException(
1207           ERR_CERT_GEN_SELF_SIGNED_CANNOT_GENERATE_KEY_PAIR.get(
1208                keySizeBits, publicKeyAlgorithm.getName(),
1209                StaticUtils.getExceptionMessage(e)),
1210           e);
1211    }
1212
1213
1214    // Generate the certificate and return it along with the key pair.
1215    final X509Certificate certificate = generateSelfSignedCertificate(
1216         signatureAlgorithm, keyPair, subjectDN, notBefore, notAfter,
1217         extensions);
1218    return new ObjectPair<>(certificate, keyPair);
1219  }
1220
1221
1222
1223  /**
1224   * Generates a self-signed X.509 certificate with the provided information.
1225   *
1226   * @param  signatureAlgorithm  The algorithm to use to generate the signature.
1227   *                             This must not be {@code null}.
1228   * @param  keyPair             The key pair for the certificate.  This must
1229   *                             not be {@code null}.
1230   * @param  subjectDN           The subject DN for the certificate.  This must
1231   *                             not be {@code null}.
1232   * @param  notBefore           The validity start time for the certificate.
1233   * @param  notAfter            The validity end time for the certificate.
1234   * @param  extensions          The set of extensions to include in the
1235   *                             certificate.  This may be {@code null} or empty
1236   *                             if the certificate should not include any
1237   *                             custom extensions.  Note that the generated
1238   *                             certificate will automatically include a
1239   *                             {@link SubjectKeyIdentifierExtension}, so that
1240   *                             should not be provided.
1241   *
1242   * @return  An {@code ObjectPair} that contains both the self-signed
1243   *          certificate and its corresponding key pair.
1244   *
1245   * @throws  CertException  If a problem is encountered while creating the
1246   *                         certificate.
1247   */
1248  public static X509Certificate generateSelfSignedCertificate(
1249                   final SignatureAlgorithmIdentifier signatureAlgorithm,
1250                   final KeyPair keyPair, final DN subjectDN,
1251                   final long notBefore, final long notAfter,
1252                   final X509CertificateExtension... extensions)
1253         throws CertException
1254  {
1255    // Extract the parameters and encoded public key from the generated key
1256    // pair.  And while we're at it, generate a subject key identifier from
1257    // the encoded public key.
1258    DecodedPublicKey decodedPublicKey = null;
1259    final ASN1BitString encodedPublicKey;
1260    final ASN1Element publicKeyAlgorithmParameters;
1261    final byte[] subjectKeyIdentifier;
1262    final OID publicKeyAlgorithmOID;
1263    try
1264    {
1265      final ASN1Element[] pkElements = ASN1Sequence.decodeAsSequence(
1266           keyPair.getPublic().getEncoded()).elements();
1267      final ASN1Element[] pkAlgIDElements = ASN1Sequence.decodeAsSequence(
1268           pkElements[0]).elements();
1269      publicKeyAlgorithmOID =
1270           pkAlgIDElements[0].decodeAsObjectIdentifier().getOID();
1271      if (pkAlgIDElements.length == 1)
1272      {
1273        publicKeyAlgorithmParameters = null;
1274      }
1275      else
1276      {
1277        publicKeyAlgorithmParameters = pkAlgIDElements[1];
1278      }
1279
1280      encodedPublicKey = pkElements[1].decodeAsBitString();
1281
1282      try
1283      {
1284        if (publicKeyAlgorithmOID.equals(
1285             PublicKeyAlgorithmIdentifier.RSA.getOID()))
1286        {
1287          decodedPublicKey = new RSAPublicKey(encodedPublicKey);
1288        }
1289        else if (publicKeyAlgorithmOID.equals(
1290             PublicKeyAlgorithmIdentifier.EC.getOID()))
1291        {
1292          decodedPublicKey = new EllipticCurvePublicKey(encodedPublicKey);
1293        }
1294      }
1295      catch (final Exception e)
1296      {
1297        Debug.debugException(e);
1298      }
1299
1300      final MessageDigest sha256 = MessageDigest.getInstance(
1301           SubjectKeyIdentifierExtension.
1302                SUBJECT_KEY_IDENTIFIER_DIGEST_ALGORITHM);
1303      subjectKeyIdentifier = sha256.digest(encodedPublicKey.getBytes());
1304    }
1305    catch (final Exception e)
1306    {
1307      Debug.debugException(e);
1308      throw new CertException(
1309           ERR_CERT_GEN_SELF_SIGNED_CANNOT_PARSE_KEY_PAIR.get(
1310                StaticUtils.getExceptionMessage(e)),
1311           e);
1312    }
1313
1314
1315    // Construct the set of all extensions for the certificate.
1316    final ArrayList<X509CertificateExtension> extensionList =
1317         new ArrayList<>(10);
1318    extensionList.add(new SubjectKeyIdentifierExtension(false,
1319         new ASN1OctetString(subjectKeyIdentifier)));
1320    if (extensions != null)
1321    {
1322      for (final X509CertificateExtension e : extensions)
1323      {
1324        if (! e.getOID().equals(SubjectKeyIdentifierExtension.
1325             SUBJECT_KEY_IDENTIFIER_OID))
1326        {
1327          extensionList.add(e);
1328        }
1329      }
1330    }
1331
1332    final X509CertificateExtension[] allExtensions =
1333         new X509CertificateExtension[extensionList.size()];
1334    extensionList.toArray(allExtensions);
1335
1336
1337    // Encode the tbsCertificate sequence for the certificate and use it to
1338    // generate the certificate's signature.
1339    final BigInteger serialNumber = generateSerialNumber();
1340    final ASN1BitString encodedSignature = generateSignature(signatureAlgorithm,
1341         keyPair.getPrivate(), serialNumber, subjectDN, notBefore, notAfter,
1342         subjectDN, publicKeyAlgorithmOID, publicKeyAlgorithmParameters,
1343         encodedPublicKey, allExtensions);
1344
1345
1346    // Construct and return the signed certificate and the private key.
1347    return new X509Certificate(X509CertificateVersion.V3, serialNumber,
1348         signatureAlgorithm.getOID(), null, encodedSignature, subjectDN,
1349         notBefore, notAfter, subjectDN, publicKeyAlgorithmOID,
1350         publicKeyAlgorithmParameters, encodedPublicKey, decodedPublicKey, null,
1351         null, allExtensions);
1352  }
1353
1354
1355
1356  /**
1357   * Generates an issuer-signed X.509 certificate with the provided information.
1358   *
1359   * @param  signatureAlgorithm
1360   *              The algorithm to use to generate the signature.  This must not
1361   *              be {@code null}.
1362   * @param  issuerCertificate
1363   *              The certificate for the issuer.  This must not be
1364   *              {@code null}.
1365   * @param  issuerPrivateKey
1366   *              The private key for the issuer.  This  must not be
1367   *              {@code null}.
1368   * @param  publicKeyAlgorithmOID
1369   *              The OID for the certificate's public key algorithm.  This must
1370   *              not be {@code null}.
1371   * @param  publicKeyAlgorithmParameters
1372   *              The encoded public key algorithm parameters for the
1373   *              certificate.  This may be {@code null} if there are no
1374   *              parameters.
1375   * @param  encodedPublicKey
1376   *              The encoded public key for the certificate.  This must not be
1377   *              {@code null}.
1378   * @param  decodedPublicKey
1379   *              The decoded public key for the certificate.  This may be
1380   *              {@code null} if it is not available.
1381   * @param  subjectDN
1382   *              The subject DN for the certificate.  This must not be
1383   *              {@code null}.
1384   * @param  notBefore
1385   *              The validity start time for the certificate.
1386   * @param  notAfter
1387   *              The validity end time for the certificate.
1388   * @param  extensions
1389   *              The set of extensions to include in the certificate.  This
1390   *              may be {@code null} or empty if the certificate should not
1391   *              include any custom extensions.  Note that the generated
1392   *              certificate will automatically include a
1393   *              {@link SubjectKeyIdentifierExtension}, so that should not be
1394   *              provided.  In addition, if the issuer certificate includes its
1395   *              own {@code SubjectKeyIdentifierExtension}, then its value will
1396   *              be used to generate an
1397   *              {@link AuthorityKeyIdentifierExtension}.
1398   *
1399   * @return  The issuer-signed certificate.
1400   *
1401   * @throws  CertException  If a problem is encountered while creating the
1402   *                         certificate.
1403   */
1404  public static X509Certificate generateIssuerSignedCertificate(
1405              final SignatureAlgorithmIdentifier signatureAlgorithm,
1406              final X509Certificate issuerCertificate,
1407              final PrivateKey issuerPrivateKey,
1408              final OID publicKeyAlgorithmOID,
1409              final ASN1Element publicKeyAlgorithmParameters,
1410              final ASN1BitString encodedPublicKey,
1411              final DecodedPublicKey decodedPublicKey, final DN subjectDN,
1412              final long notBefore, final long notAfter,
1413              final X509CertificateExtension... extensions)
1414         throws CertException
1415  {
1416    // Generate a subject key identifier from the encoded public key.
1417    final byte[] subjectKeyIdentifier;
1418    try
1419    {
1420      final MessageDigest sha256 = MessageDigest.getInstance(
1421           SubjectKeyIdentifierExtension.
1422                SUBJECT_KEY_IDENTIFIER_DIGEST_ALGORITHM);
1423      subjectKeyIdentifier = sha256.digest(encodedPublicKey.getBytes());
1424    }
1425    catch (final Exception e)
1426    {
1427      Debug.debugException(e);
1428      throw new CertException(
1429           ERR_CERT_GEN_ISSUER_SIGNED_CANNOT_GENERATE_KEY_ID.get(
1430                StaticUtils.getExceptionMessage(e)),
1431           e);
1432    }
1433
1434
1435    // If the issuer certificate contains a subject key identifier, then
1436    // extract it to use as the authority key identifier.
1437    ASN1OctetString authorityKeyIdentifier = null;
1438    for (final X509CertificateExtension e : issuerCertificate.extensions)
1439    {
1440      if (e instanceof SubjectKeyIdentifierExtension)
1441      {
1442        authorityKeyIdentifier =
1443             ((SubjectKeyIdentifierExtension) e).getKeyIdentifier();
1444      }
1445    }
1446
1447
1448    // Construct the set of all extensions for the certificate.
1449    final ArrayList<X509CertificateExtension> extensionList =
1450         new ArrayList<>(10);
1451    extensionList.add(new SubjectKeyIdentifierExtension(false,
1452         new ASN1OctetString(subjectKeyIdentifier)));
1453
1454    if (authorityKeyIdentifier == null)
1455    {
1456      extensionList.add(new AuthorityKeyIdentifierExtension(false, null,
1457           new GeneralNamesBuilder().addDirectoryName(
1458                issuerCertificate.subjectDN).build(),
1459           issuerCertificate.serialNumber));
1460    }
1461    else
1462    {
1463      extensionList.add(new AuthorityKeyIdentifierExtension(false,
1464           authorityKeyIdentifier, null, null));
1465    }
1466
1467    if (extensions != null)
1468    {
1469      for (final X509CertificateExtension e : extensions)
1470      {
1471        if (e.getOID().equals(
1472             SubjectKeyIdentifierExtension.SUBJECT_KEY_IDENTIFIER_OID) ||
1473            e.getOID().equals(
1474                 AuthorityKeyIdentifierExtension.AUTHORITY_KEY_IDENTIFIER_OID))
1475        {
1476          continue;
1477        }
1478
1479        extensionList.add(e);
1480      }
1481    }
1482
1483    final X509CertificateExtension[] allExtensions =
1484         new X509CertificateExtension[extensionList.size()];
1485    extensionList.toArray(allExtensions);
1486
1487
1488    // Encode the tbsCertificate sequence for the certificate and use it to
1489    // generate the certificate's signature.
1490    final BigInteger serialNumber = generateSerialNumber();
1491    final ASN1BitString encodedSignature = generateSignature(signatureAlgorithm,
1492         issuerPrivateKey, serialNumber, issuerCertificate.subjectDN, notBefore,
1493         notAfter, subjectDN, publicKeyAlgorithmOID,
1494         publicKeyAlgorithmParameters, encodedPublicKey, allExtensions);
1495
1496
1497    // Construct and return the signed certificate.
1498    return new X509Certificate(X509CertificateVersion.V3, serialNumber,
1499         signatureAlgorithm.getOID(), null, encodedSignature,
1500         issuerCertificate.subjectDN, notBefore, notAfter, subjectDN,
1501         publicKeyAlgorithmOID, publicKeyAlgorithmParameters, encodedPublicKey,
1502         decodedPublicKey, null, null, allExtensions);
1503  }
1504
1505
1506
1507  /**
1508   * Generates a serial number for the certificate.
1509   *
1510   * @return  The generated serial number.
1511   */
1512  private static BigInteger generateSerialNumber()
1513  {
1514    final UUID uuid = UUID.randomUUID();
1515    final long msb = uuid.getMostSignificantBits() & 0x7FFF_FFFF_FFFF_FFFFL;
1516    final long lsb = uuid.getLeastSignificantBits() & 0x7FFF_FFFF_FFFF_FFFFL;
1517    return BigInteger.valueOf(msb).shiftLeft(64).add(BigInteger.valueOf(lsb));
1518  }
1519
1520
1521
1522  /**
1523   * Generates a signature for the certificate with the provided information.
1524   *
1525   * @param  signatureAlgorithm            The signature algorithm to use to
1526   *                                       generate the signature.  This must
1527   *                                       not be {@code null}.
1528   * @param  privateKey                    The private key to use to sign the
1529   *                                       certificate.  This must not be
1530   *                                       {@code null}.
1531   * @param  serialNumber                  The serial number for the
1532   *                                       certificate.  This must not be
1533   *                                       {@code null}.
1534   * @param  issuerDN                      The issuer DN for the certificate.
1535   *                                       This must not be {@code null}.
1536   * @param  notBefore                     The validity start time for the
1537   *                                       certificate.
1538   * @param  notAfter                      The validity end time for the
1539   *                                       certificate.
1540   * @param  subjectDN                     The subject DN for the certificate.
1541   *                                       This must not be {@code null}.
1542   * @param  publicKeyAlgorithmOID         The OID for the public key algorithm.
1543   *                                       This must not be {@code null}.
1544   * @param  publicKeyAlgorithmParameters  The encoded public key algorithm
1545   *                                       parameters.  This may be
1546   *                                       {@code null} if no parameters are
1547   *                                       needed.
1548   * @param  encodedPublicKey              The encoded representation of the
1549   *                                       public key.  This must not be
1550   *                                       {@code null}.
1551   * @param  extensions                    The set of extensions to include in
1552   *                                       the certificate.  This must not be
1553   *                                       {@code null} but may be empty.
1554   *
1555   * @return  An encoded representation of the generated signature.
1556   *
1557   * @throws  CertException  If a problem is encountered while generating the
1558   *                         certificate.
1559   */
1560  private static ASN1BitString generateSignature(
1561                      final SignatureAlgorithmIdentifier signatureAlgorithm,
1562                      final PrivateKey privateKey,
1563                      final BigInteger serialNumber,
1564                      final DN issuerDN, final long notBefore,
1565                      final long notAfter, final DN subjectDN,
1566                      final OID publicKeyAlgorithmOID,
1567                      final ASN1Element publicKeyAlgorithmParameters,
1568                      final ASN1BitString encodedPublicKey,
1569                      final X509CertificateExtension... extensions)
1570          throws CertException
1571  {
1572    // Get and initialize the signature generator.
1573    final Signature signature;
1574    try
1575    {
1576      signature = Signature.getInstance(signatureAlgorithm.getJavaName());
1577    }
1578    catch (final Exception e)
1579    {
1580      Debug.debugException(e);
1581      throw new CertException(
1582           ERR_CERT_GEN_SIGNATURE_CANNOT_GET_SIGNATURE_GENERATOR.get(
1583                signatureAlgorithm.getJavaName(),
1584                StaticUtils.getExceptionMessage(e)),
1585           e);
1586    }
1587
1588    try
1589    {
1590      signature.initSign(privateKey);
1591    }
1592    catch (final Exception e)
1593    {
1594      Debug.debugException(e);
1595      throw new CertException(
1596           ERR_CERT_GEN_SIGNATURE_CANNOT_INIT_SIGNATURE_GENERATOR.get(
1597                signatureAlgorithm.getJavaName(),
1598                StaticUtils.getExceptionMessage(e)),
1599           e);
1600    }
1601
1602
1603    // Construct the tbsCertificate element of the certificate and compute its
1604    // signature.
1605    try
1606    {
1607      final ArrayList<ASN1Element> tbsCertificateElements = new ArrayList<>(8);
1608      tbsCertificateElements.add(new ASN1Element(TYPE_EXPLICIT_VERSION,
1609           new ASN1Integer(X509CertificateVersion.V3.getIntValue()).encode()));
1610      tbsCertificateElements.add(new ASN1BigInteger(serialNumber));
1611      tbsCertificateElements.add(new ASN1Sequence(
1612           new ASN1ObjectIdentifier(signatureAlgorithm.getOID())));
1613      tbsCertificateElements.add(encodeName(issuerDN));
1614      tbsCertificateElements.add(encodeValiditySequence(notBefore, notAfter));
1615      tbsCertificateElements.add(encodeName(subjectDN));
1616
1617      if (publicKeyAlgorithmParameters == null)
1618      {
1619        tbsCertificateElements.add(new ASN1Sequence(
1620             new ASN1Sequence(
1621                  new ASN1ObjectIdentifier(publicKeyAlgorithmOID)),
1622             encodedPublicKey));
1623      }
1624      else
1625      {
1626        tbsCertificateElements.add(new ASN1Sequence(
1627             new ASN1Sequence(
1628                  new ASN1ObjectIdentifier(publicKeyAlgorithmOID),
1629                  publicKeyAlgorithmParameters),
1630             encodedPublicKey));
1631      }
1632
1633      final ArrayList<ASN1Element> extensionElements =
1634           new ArrayList<>(extensions.length);
1635      for (final X509CertificateExtension e : extensions)
1636      {
1637        extensionElements.add(e.encode());
1638      }
1639      tbsCertificateElements.add(new ASN1Element(TYPE_EXPLICIT_EXTENSIONS,
1640           new ASN1Sequence(extensionElements).encode()));
1641
1642      final byte[] tbsCertificateBytes =
1643           new ASN1Sequence(tbsCertificateElements).encode();
1644      signature.update(tbsCertificateBytes);
1645      final byte[] signatureBytes = signature.sign();
1646
1647      return new ASN1BitString(ASN1BitString.getBitsForBytes(signatureBytes));
1648    }
1649    catch (final Exception e)
1650    {
1651      Debug.debugException(e);
1652      throw new CertException(
1653           ERR_CERT_GEN_SIGNATURE_CANNOT_COMPUTE.get(
1654                signatureAlgorithm.getJavaName(),
1655                StaticUtils.getExceptionMessage(e)),
1656           e);
1657    }
1658  }
1659
1660
1661
1662  /**
1663   * Retrieves the bytes that comprise the encoded representation of this X.509
1664   * certificate.
1665   *
1666   * @return  The bytes that comprise the encoded representation of this X.509
1667   *          certificate.
1668   */
1669  public byte[] getX509CertificateBytes()
1670  {
1671    return x509CertificateBytes;
1672  }
1673
1674
1675
1676  /**
1677   * Retrieves the certificate version.
1678   *
1679   * @return  The certificate version.
1680   */
1681  public X509CertificateVersion getVersion()
1682  {
1683    return version;
1684  }
1685
1686
1687
1688  /**
1689   * Retrieves the certificate serial number.
1690   *
1691   * @return  The certificate serial number.
1692   */
1693  public BigInteger getSerialNumber()
1694  {
1695    return serialNumber;
1696  }
1697
1698
1699
1700  /**
1701   * Retrieves the certificate signature algorithm OID.
1702   *
1703   * @return  The certificate signature algorithm OID.
1704   */
1705  public OID getSignatureAlgorithmOID()
1706  {
1707    return signatureAlgorithmOID;
1708  }
1709
1710
1711
1712  /**
1713   * Retrieves the certificate signature algorithm name, if available.
1714   *
1715   * @return  The certificate signature algorithm name, or {@code null} if the
1716   *          signature algorithm OID does not correspond to any known algorithm
1717   *          name.
1718   */
1719  public String getSignatureAlgorithmName()
1720  {
1721    return signatureAlgorithmName;
1722  }
1723
1724
1725
1726  /**
1727   * Retrieves the signature algorithm name if it is available, or the string
1728   * representation of the signature algorithm OID if not.
1729   *
1730   * @return  The signature algorithm name or OID.
1731   */
1732  public String getSignatureAlgorithmNameOrOID()
1733  {
1734    if (signatureAlgorithmName != null)
1735    {
1736      return signatureAlgorithmName;
1737    }
1738    else
1739    {
1740      return signatureAlgorithmOID.toString();
1741    }
1742  }
1743
1744
1745
1746  /**
1747   * Retrieves the encoded signature algorithm parameters, if present.
1748   *
1749   * @return  The encoded signature algorithm parameters, or {@code null} if
1750   *          there are no signature algorithm parameters.
1751   */
1752  public ASN1Element getSignatureAlgorithmParameters()
1753  {
1754    return signatureAlgorithmParameters;
1755  }
1756
1757
1758
1759  /**
1760   * Retrieves the certificate issuer DN.
1761   *
1762   * @return  The certificate issuer DN.
1763   */
1764  public DN getIssuerDN()
1765  {
1766    return issuerDN;
1767  }
1768
1769
1770
1771  /**
1772   * Retrieves the certificate validity start time as the number of milliseconds
1773   * since the epoch (January 1, 1970 UTC).
1774   *
1775   * @return  The certificate validity start time as the number of milliseconds
1776   *          since the epoch.
1777   */
1778  public long getNotBeforeTime()
1779  {
1780    return notBefore;
1781  }
1782
1783
1784
1785  /**
1786   * Retrieves the certificate validity start time as a {@code Date}.
1787   *
1788   * @return  The certificate validity start time as a {@code Date}.
1789   */
1790  public Date getNotBeforeDate()
1791  {
1792    return new Date(notBefore);
1793  }
1794
1795
1796
1797  /**
1798   * Retrieves the certificate validity end time as the number of milliseconds
1799   * since the epoch (January 1, 1970 UTC).
1800   *
1801   * @return  The certificate validity end time as the number of milliseconds
1802   *          since the epoch.
1803   */
1804  public long getNotAfterTime()
1805  {
1806    return notAfter;
1807  }
1808
1809
1810
1811  /**
1812   * Retrieves the certificate validity end time as a {@code Date}.
1813   *
1814   * @return  The certificate validity end time as a {@code Date}.
1815   */
1816  public Date getNotAfterDate()
1817  {
1818    return new Date(notAfter);
1819  }
1820
1821
1822
1823  /**
1824   * Indicates whether the current time is within the certificate's validity
1825   * window.
1826   *
1827   * @return  {@code true} if the current time is within the certificate's
1828   *          validity window, or {@code false} if not.
1829   */
1830  public boolean isWithinValidityWindow()
1831  {
1832    return isWithinValidityWindow(System.currentTimeMillis());
1833  }
1834
1835
1836
1837  /**
1838   * Indicates whether the provided {@code Date} represents a time within the
1839   * certificate's validity window.
1840   *
1841   * @param  date  The {@code Date} for which to make the determination.  It
1842   *               must not be {@code null}.
1843   *
1844   * @return  {@code true} if the provided {@code Date} is within the
1845   *          certificate's validity window, or {@code false} if not.
1846   */
1847  public boolean isWithinValidityWindow(final Date date)
1848  {
1849    return isWithinValidityWindow(date.getTime());
1850  }
1851
1852
1853
1854  /**
1855   * Indicates whether the specified time is within the certificate's validity
1856   * window.
1857   *
1858   * @param  time  The time to for which to make the determination.
1859   *
1860   * @return  {@code true} if the specified time is within the certificate's
1861   *          validity window, or {@code false} if not.
1862   */
1863  public boolean isWithinValidityWindow(final long time)
1864  {
1865    return ((time >= notBefore) && (time <= notAfter));
1866  }
1867
1868
1869
1870  /**
1871   * Retrieves the certificate subject DN.
1872   *
1873   * @return  The certificate subject DN.
1874   */
1875  public DN getSubjectDN()
1876  {
1877    return subjectDN;
1878  }
1879
1880
1881
1882  /**
1883   * Retrieves the certificate public key algorithm OID.
1884   *
1885   * @return  The certificate public key algorithm OID.
1886   */
1887  public OID getPublicKeyAlgorithmOID()
1888  {
1889    return publicKeyAlgorithmOID;
1890  }
1891
1892
1893
1894  /**
1895   * Retrieves the certificate public key algorithm name, if available.
1896   *
1897   * @return  The certificate public key algorithm name, or {@code null} if the
1898   *          public key algorithm OID does not correspond to any known
1899   *          algorithm name.
1900   */
1901  public String getPublicKeyAlgorithmName()
1902  {
1903    return publicKeyAlgorithmName;
1904  }
1905
1906
1907
1908  /**
1909   * Retrieves the public key algorithm name if it is available, or the string
1910   * representation of the public key algorithm OID if not.
1911   *
1912   * @return  The signature algorithm name or OID.
1913   */
1914  public String getPublicKeyAlgorithmNameOrOID()
1915  {
1916    if (publicKeyAlgorithmName != null)
1917    {
1918      return publicKeyAlgorithmName;
1919    }
1920    else
1921    {
1922      return publicKeyAlgorithmOID.toString();
1923    }
1924  }
1925
1926
1927
1928  /**
1929   * Retrieves the encoded public key algorithm parameters, if present.
1930   *
1931   * @return  The encoded public key algorithm parameters, or {@code null} if
1932   *          there are no public key algorithm parameters.
1933   */
1934  public ASN1Element getPublicKeyAlgorithmParameters()
1935  {
1936    return publicKeyAlgorithmParameters;
1937  }
1938
1939
1940
1941  /**
1942   * Retrieves the encoded public key as a bit string.
1943   *
1944   * @return  The encoded public key as a bit string.
1945   */
1946  public ASN1BitString getEncodedPublicKey()
1947  {
1948    return encodedPublicKey;
1949  }
1950
1951
1952
1953  /**
1954   * Retrieves a decoded representation of the public key, if available.
1955   *
1956   * @return  A decoded representation of the public key, or {@code null} if the
1957   *          public key could not be decoded.
1958   */
1959  public DecodedPublicKey getDecodedPublicKey()
1960  {
1961    return decodedPublicKey;
1962  }
1963
1964
1965
1966  /**
1967   * Retrieves the issuer unique identifier for the certificate, if any.
1968   *
1969   * @return  The issuer unique identifier for the certificate, or {@code null}
1970   *          if there is none.
1971   */
1972  public ASN1BitString getIssuerUniqueID()
1973  {
1974    return issuerUniqueID;
1975  }
1976
1977
1978
1979  /**
1980   * Retrieves the subject unique identifier for the certificate, if any.
1981   *
1982   * @return  The subject unique identifier for the certificate, or {@code null}
1983   *          if there is none.
1984   */
1985  public ASN1BitString getSubjectUniqueID()
1986  {
1987    return subjectUniqueID;
1988  }
1989
1990
1991
1992  /**
1993   * Retrieves the list of certificate extensions.
1994   *
1995   * @return  The list of certificate extensions.
1996   */
1997  public List<X509CertificateExtension> getExtensions()
1998  {
1999    return extensions;
2000  }
2001
2002
2003
2004  /**
2005   * Retrieves the signature value for the certificate.
2006   *
2007   * @return  The signature value for the certificate.
2008   */
2009  public ASN1BitString getSignatureValue()
2010  {
2011    return signatureValue;
2012  }
2013
2014
2015
2016  /**
2017   * Verifies the signature for this certificate.
2018   *
2019   * @param  issuerCertificate  The issuer certificate for this certificate.  It
2020   *                            may be {@code null} if this is a self-signed
2021   *                            certificate.  It must not be {@code null} if it
2022   *                            is not a self-signed certificate.
2023   *
2024   * @throws  CertException  If the certificate signature could not be verified.
2025   */
2026  public void verifySignature(final X509Certificate issuerCertificate)
2027         throws CertException
2028  {
2029    // Get the issuer certificate.  If the certificate is self-signed, then it
2030    // might be the current certificate.
2031    final X509Certificate issuer;
2032    if (issuerCertificate == null)
2033    {
2034      if (isSelfSigned())
2035      {
2036        issuer = this;
2037      }
2038      else
2039      {
2040        throw new CertException(
2041             ERR_CERT_VERIFY_SIGNATURE_ISSUER_CERT_NOT_PROVIDED.get());
2042      }
2043    }
2044    else
2045    {
2046      issuer = issuerCertificate;
2047    }
2048
2049
2050    // Get the public key from the issuer certificate.
2051    final PublicKey publicKey;
2052    try
2053    {
2054      publicKey = issuer.toCertificate().getPublicKey();
2055    }
2056    catch (final Exception e)
2057    {
2058      Debug.debugException(e);
2059      throw new CertException(
2060           ERR_CERT_VERIFY_SIGNATURE_CANNOT_GET_PUBLIC_KEY.get(
2061                StaticUtils.getExceptionMessage(e)),
2062           e);
2063    }
2064
2065
2066    // Get and initialize the signature generator.
2067    final Signature signature;
2068    final SignatureAlgorithmIdentifier signatureAlgorithm;
2069    try
2070    {
2071      signatureAlgorithm =
2072           SignatureAlgorithmIdentifier.forOID(signatureAlgorithmOID);
2073      signature = Signature.getInstance(signatureAlgorithm.getJavaName());
2074    }
2075    catch (final Exception e)
2076    {
2077      Debug.debugException(e);
2078      throw new CertException(
2079           ERR_CERT_VERIFY_SIGNATURE_CANNOT_GET_SIGNATURE_VERIFIER.get(
2080                getSignatureAlgorithmNameOrOID(),
2081                StaticUtils.getExceptionMessage(e)),
2082           e);
2083    }
2084
2085    try
2086    {
2087      signature.initVerify(publicKey);
2088    }
2089    catch (final Exception e)
2090    {
2091      Debug.debugException(e);
2092      throw new CertException(
2093           ERR_CERT_VERIFY_SIGNATURE_CANNOT_INIT_SIGNATURE_VERIFIER.get(
2094                signatureAlgorithm.getJavaName(),
2095                StaticUtils.getExceptionMessage(e)),
2096           e);
2097    }
2098
2099
2100    // Construct the tbsCertificate element of the certificate and compute its
2101    // signature.
2102    try
2103    {
2104      final ASN1Element[] x509CertificateElements =
2105           ASN1Sequence.decodeAsSequence(x509CertificateBytes).elements();
2106      final byte[] tbsCertificateBytes = x509CertificateElements[0].encode();
2107      signature.update(tbsCertificateBytes);
2108    }
2109    catch (final Exception e)
2110    {
2111      Debug.debugException(e);
2112      throw new CertException(
2113           ERR_CERT_GEN_SIGNATURE_CANNOT_COMPUTE.get(
2114                signatureAlgorithm.getJavaName(),
2115                StaticUtils.getExceptionMessage(e)),
2116           e);
2117    }
2118
2119
2120    try
2121    {
2122      if (! signature.verify(signatureValue.getBytes()))
2123      {
2124        throw new CertException(
2125             ERR_CERT_VERIFY_SIGNATURE_NOT_VALID.get(subjectDN));
2126      }
2127    }
2128    catch (final CertException ce)
2129    {
2130      Debug.debugException(ce);
2131      throw ce;
2132    }
2133    catch (final Exception e)
2134    {
2135      Debug.debugException(e);
2136      throw new CertException(
2137           ERR_CERT_VERIFY_SIGNATURE_ERROR.get(subjectDN,
2138                StaticUtils.getExceptionMessage(e)),
2139           e);
2140    }
2141  }
2142
2143
2144
2145  /**
2146   * Retrieves the bytes that comprise a SHA-1 fingerprint of this certificate.
2147   *
2148   * @return  The bytes that comprise a SHA-1 fingerprint of this certificate.
2149   *
2150   * @throws  CertException  If a problem is encountered while computing the
2151   *                         fingerprint.
2152   */
2153  public byte[] getSHA1Fingerprint()
2154         throws CertException
2155  {
2156    return getFingerprint("SHA-1");
2157  }
2158
2159
2160
2161  /**
2162   * Retrieves the bytes that comprise a 256-bit SHA-2 fingerprint of this
2163   * certificate.
2164   *
2165   * @return  The bytes that comprise a 256-bit SHA-2 fingerprint of this
2166   *          certificate.
2167   *
2168   * @throws  CertException  If a problem is encountered while computing the
2169   *                         fingerprint.
2170   */
2171  public byte[] getSHA256Fingerprint()
2172         throws CertException
2173  {
2174    return getFingerprint("SHA-256");
2175  }
2176
2177
2178
2179  /**
2180   * Retrieves the bytes that comprise a fingerprint of this certificate.
2181   *
2182   * @param  digestAlgorithm  The digest algorithm to use to generate the
2183   *                          fingerprint.
2184   *
2185   * @return  The bytes that comprise a fingerprint of this certificate.
2186   *
2187   * @throws  CertException  If a problem is encountered while computing the
2188   *                         fingerprint.
2189   */
2190  private byte[] getFingerprint(final String digestAlgorithm)
2191          throws CertException
2192  {
2193    try
2194    {
2195      final MessageDigest digest = MessageDigest.getInstance(digestAlgorithm);
2196      return digest.digest(x509CertificateBytes);
2197    }
2198    catch (final Exception e)
2199    {
2200      // This should never happen.
2201      Debug.debugException(e);
2202      throw new CertException(
2203           ERR_CERT_CANNOT_COMPUTE_FINGERPRINT.get(digestAlgorithm,
2204                StaticUtils.getExceptionMessage(e)),
2205           e);
2206    }
2207  }
2208
2209
2210
2211  /**
2212   * Indicates whether this certificate is self-signed.  The following criteria
2213   * will be used to make the determination:
2214   * <OL>
2215   *   <LI>
2216   *     If the certificate has both subject key identifier and authority
2217   *     key identifier extensions, then it will be considered self-signed if
2218   *     and only if the subject key identifier matches the authority key
2219   *     identifier.
2220   *   </LI>
2221   *   <LI>
2222   *     If the certificate does not have both a subject key identifier and an
2223   *     authority key identifier, then it will be considered self-signed if and
2224   *     only if its subject DN matches its issuer DN.
2225   *   </LI>
2226   * </OL>
2227   *
2228   * @return  {@code true} if this certificate is self-signed, or {@code false}
2229   *          if it is not.
2230   */
2231  public boolean isSelfSigned()
2232  {
2233    AuthorityKeyIdentifierExtension akie = null;
2234    SubjectKeyIdentifierExtension skie = null;
2235    for (final X509CertificateExtension e : extensions)
2236    {
2237      if (e instanceof AuthorityKeyIdentifierExtension)
2238      {
2239        akie = (AuthorityKeyIdentifierExtension) e;
2240      }
2241      else if (e instanceof SubjectKeyIdentifierExtension)
2242      {
2243        skie = (SubjectKeyIdentifierExtension) e;
2244      }
2245    }
2246
2247    if ((akie != null) && (skie != null))
2248    {
2249      return ((akie.getKeyIdentifier() != null) &&
2250           Arrays.equals(akie.getKeyIdentifier().getValue(),
2251                skie.getKeyIdentifier().getValue()));
2252    }
2253    else
2254    {
2255      return subjectDN.equals(issuerDN);
2256    }
2257  }
2258
2259
2260
2261  /**
2262   * Indicates whether this certificate is the issuer for the provided
2263   * certificate.  In order for this to be true, the following conditions must
2264   * be met:
2265   * <OL>
2266   *   <LI>
2267   *     The subject DN of this certificate must match the issuer DN for the
2268   *     provided certificate.
2269   *   </LI>
2270   *   <LI>
2271   *     If the provided certificate has an authority key identifier extension,
2272   *     then this certificate must have a subject key identifier extension with
2273   *     a matching identifier value.
2274   *   </LI>
2275   * </OL>
2276   *
2277   * @param  c  The certificate for which to make the determination.  This must
2278   *            not be {@code null}.
2279   *
2280   * @return  {@code true} if this certificate is considered the issuer for the
2281   *          provided certificate, or {@code } false if not.
2282   */
2283  public boolean isIssuerFor(final X509Certificate c)
2284  {
2285    return isIssuerFor(c, null);
2286  }
2287
2288
2289
2290  /**
2291   * Indicates whether this certificate is the issuer for the provided
2292   * certificate.  In order for this to be true, the following conditions must
2293   * be met:
2294   * <OL>
2295   *   <LI>
2296   *     The subject DN of this certificate must match the issuer DN for the
2297   *     provided certificate.
2298   *   </LI>
2299   *   <LI>
2300   *     If the provided certificate has an authority key identifier extension,
2301   *     then this certificate must have a subject key identifier extension with
2302   *     a matching identifier value.
2303   *   </LI>
2304   * </OL>
2305   *
2306   * @param  c               The certificate for which to make the
2307   *                         determination.  This must not be {@code null}.
2308   * @param  nonMatchReason  An optional buffer that may be updated with the
2309   *                         reason that this certificate is not considered the
2310   *                         issuer for the provided certificate.  This may be
2311   *                         {@code null} if the caller does not require a
2312   *                         reason.
2313   *
2314   * @return  {@code true} if this certificate is considered the issuer for the
2315   *          provided certificate, or {@code } false if not.
2316   */
2317  public boolean isIssuerFor(final X509Certificate c,
2318                             final StringBuilder nonMatchReason)
2319  {
2320    if (! c.issuerDN.equals(subjectDN))
2321    {
2322      if (nonMatchReason != null)
2323      {
2324        nonMatchReason.append(INFO_CERT_IS_ISSUER_FOR_DN_MISMATCH.get(
2325             subjectDN, c.subjectDN, issuerDN));
2326      }
2327
2328      return false;
2329    }
2330
2331
2332    byte[] authorityKeyIdentifier = null;
2333    for (final X509CertificateExtension extension : c.extensions)
2334    {
2335      if (extension instanceof AuthorityKeyIdentifierExtension)
2336      {
2337        final AuthorityKeyIdentifierExtension akie =
2338             (AuthorityKeyIdentifierExtension) extension;
2339        if (akie.getKeyIdentifier() != null)
2340        {
2341          authorityKeyIdentifier = akie.getKeyIdentifier().getValue();
2342          break;
2343        }
2344      }
2345    }
2346
2347    if (authorityKeyIdentifier != null)
2348    {
2349      boolean matchFound = false;
2350      for (final X509CertificateExtension extension : extensions)
2351      {
2352        if (extension instanceof SubjectKeyIdentifierExtension)
2353        {
2354          final SubjectKeyIdentifierExtension skie =
2355               (SubjectKeyIdentifierExtension) extension;
2356          matchFound = Arrays.equals(authorityKeyIdentifier,
2357               skie.getKeyIdentifier().getValue());
2358          break;
2359        }
2360      }
2361
2362      if (! matchFound)
2363      {
2364        if (nonMatchReason != null)
2365        {
2366          nonMatchReason.append(INFO_CERT_IS_ISSUER_FOR_KEY_ID_MISMATCH.get(
2367               subjectDN, c.subjectDN));
2368        }
2369
2370        return false;
2371      }
2372    }
2373
2374
2375    return true;
2376  }
2377
2378
2379
2380  /**
2381   * Converts this X.509 certificate object to a Java {@code Certificate}
2382   * object.
2383   *
2384   * @return  The Java {@code Certificate} object that corresponds to this
2385   *          X.509 certificate.
2386   *
2387   * @throws  CertificateException  If a problem is encountered while performing
2388   *                                the conversion.
2389   */
2390  public Certificate toCertificate()
2391         throws CertificateException
2392  {
2393    return CertificateFactory.getInstance("X.509").generateCertificate(
2394         new ByteArrayInputStream(x509CertificateBytes));
2395  }
2396
2397
2398
2399  /**
2400   * Retrieves a string representation of the decoded X.509 certificate.
2401   *
2402   * @return  A string representation of the decoded X.509 certificate.
2403   */
2404  @Override()
2405  public String toString()
2406  {
2407    final StringBuilder buffer = new StringBuilder();
2408    toString(buffer);
2409    return buffer.toString();
2410  }
2411
2412
2413
2414  /**
2415   * Appends a string representation of the decoded X.509 certificate to the
2416   * provided buffer.
2417   *
2418   * @param  buffer  The buffer to which the information should be appended.
2419   */
2420  public void toString(final StringBuilder buffer)
2421  {
2422    buffer.append("X509Certificate(version='");
2423    buffer.append(version.getName());
2424    buffer.append("', serialNumber='");
2425    StaticUtils.toHex(serialNumber.toByteArray(), ":", buffer);
2426    buffer.append("', signatureAlgorithmOID='");
2427    buffer.append(signatureAlgorithmOID.toString());
2428    buffer.append('\'');
2429
2430    if (signatureAlgorithmName != null)
2431    {
2432      buffer.append(", signatureAlgorithmName='");
2433      buffer.append(signatureAlgorithmName);
2434      buffer.append('\'');
2435    }
2436
2437    buffer.append(", issuerDN='");
2438    buffer.append(issuerDN.toString());
2439    buffer.append("', notBefore='");
2440    buffer.append(StaticUtils.encodeGeneralizedTime(notBefore));
2441    buffer.append("', notAfter='");
2442    buffer.append(StaticUtils.encodeGeneralizedTime(notAfter));
2443    buffer.append("', subjectDN='");
2444    buffer.append(subjectDN.toString());
2445    buffer.append("', publicKeyAlgorithmOID='");
2446    buffer.append(publicKeyAlgorithmOID.toString());
2447    buffer.append('\'');
2448
2449    if (publicKeyAlgorithmName != null)
2450    {
2451      buffer.append(", publicKeyAlgorithmName='");
2452      buffer.append(publicKeyAlgorithmName);
2453      buffer.append('\'');
2454    }
2455
2456    buffer.append(", subjectPublicKey=");
2457    if (decodedPublicKey == null)
2458    {
2459      buffer.append('\'');
2460
2461      try
2462      {
2463        StaticUtils.toHex(encodedPublicKey.getBytes(), ":", buffer);
2464      }
2465      catch (final Exception e)
2466      {
2467        Debug.debugException(e);
2468        encodedPublicKey.toString(buffer);
2469      }
2470
2471      buffer.append('\'');
2472    }
2473    else
2474    {
2475      decodedPublicKey.toString(buffer);
2476
2477      if (decodedPublicKey instanceof EllipticCurvePublicKey)
2478      {
2479        try
2480        {
2481          final OID namedCurveOID =
2482               publicKeyAlgorithmParameters.decodeAsObjectIdentifier().getOID();
2483          buffer.append(", ellipticCurvePublicKeyParameters=namedCurve='");
2484          buffer.append(NamedCurve.getNameOrOID(namedCurveOID));
2485          buffer.append('\'');
2486        }
2487        catch (final Exception e)
2488        {
2489          Debug.debugException(e);
2490        }
2491      }
2492    }
2493
2494    if (issuerUniqueID != null)
2495    {
2496      buffer.append(", issuerUniqueID='");
2497      buffer.append(issuerUniqueID.toString());
2498      buffer.append('\'');
2499    }
2500
2501    if (subjectUniqueID != null)
2502    {
2503      buffer.append(", subjectUniqueID='");
2504      buffer.append(subjectUniqueID.toString());
2505      buffer.append('\'');
2506    }
2507
2508    if (! extensions.isEmpty())
2509    {
2510      buffer.append(", extensions={");
2511
2512      final Iterator<X509CertificateExtension> iterator = extensions.iterator();
2513      while (iterator.hasNext())
2514      {
2515        iterator.next().toString(buffer);
2516        if (iterator.hasNext())
2517        {
2518          buffer.append(", ");
2519        }
2520      }
2521
2522      buffer.append('}');
2523    }
2524
2525    buffer.append(", signatureValue='");
2526
2527    try
2528    {
2529      StaticUtils.toHex(signatureValue.getBytes(), ":", buffer);
2530    }
2531    catch (final Exception e)
2532    {
2533      Debug.debugException(e);
2534      buffer.append(signatureValue.toString());
2535    }
2536
2537    buffer.append("')");
2538  }
2539
2540
2541
2542  /**
2543   * Retrieves a list of the lines that comprise a PEM representation of this
2544   * X.509 certificate.
2545   *
2546   * @return  A list of the lines that comprise a PEM representation of this
2547   *          X.509 certificate.
2548   */
2549  public List<String> toPEM()
2550  {
2551    final ArrayList<String> lines = new ArrayList<>(10);
2552    lines.add("-----BEGIN CERTIFICATE-----");
2553
2554    final String certBase64 = Base64.encode(x509CertificateBytes);
2555    lines.addAll(StaticUtils.wrapLine(certBase64, 64));
2556
2557    lines.add("-----END CERTIFICATE-----");
2558
2559    return Collections.unmodifiableList(lines);
2560  }
2561
2562
2563
2564  /**
2565   * Retrieves a multi-line string containing a PEM representation of this X.509
2566   * certificate.
2567   *
2568   * @return  A multi-line string containing a PEM representation of this X.509
2569   *          certificate.
2570   */
2571  public String toPEMString()
2572  {
2573    final StringBuilder buffer = new StringBuilder();
2574    buffer.append("-----BEGIN CERTIFICATE-----");
2575    buffer.append(StaticUtils.EOL);
2576
2577    final String certBase64 = Base64.encode(x509CertificateBytes);
2578    for (final String line : StaticUtils.wrapLine(certBase64, 64))
2579    {
2580      buffer.append(line);
2581      buffer.append(StaticUtils.EOL);
2582    }
2583    buffer.append("-----END CERTIFICATE-----");
2584    buffer.append(StaticUtils.EOL);
2585
2586    return buffer.toString();
2587  }
2588}