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