001/*
002 * Copyright 2017-2018 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2017-2018 Ping Identity Corporation
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.util.ssl.cert;
022
023
024
025import java.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("SHA-256");
1286      subjectKeyIdentifier = sha256.digest(encodedPublicKey.getBytes());
1287    }
1288    catch (final Exception e)
1289    {
1290      Debug.debugException(e);
1291      throw new CertException(
1292           ERR_CERT_GEN_SELF_SIGNED_CANNOT_PARSE_KEY_PAIR.get(
1293                StaticUtils.getExceptionMessage(e)),
1294           e);
1295    }
1296
1297
1298    // Construct the set of all extensions for the certificate.
1299    final ArrayList<X509CertificateExtension> extensionList =
1300         new ArrayList<>(10);
1301    extensionList.add(new SubjectKeyIdentifierExtension(false,
1302         new ASN1OctetString(subjectKeyIdentifier)));
1303    if (extensions != null)
1304    {
1305      for (final X509CertificateExtension e : extensions)
1306      {
1307        if (! e.getOID().equals(SubjectKeyIdentifierExtension.
1308             SUBJECT_KEY_IDENTIFIER_OID))
1309        {
1310          extensionList.add(e);
1311        }
1312      }
1313    }
1314
1315    final X509CertificateExtension[] allExtensions =
1316         new X509CertificateExtension[extensionList.size()];
1317    extensionList.toArray(allExtensions);
1318
1319
1320    // Encode the tbsCertificate sequence for the certificate and use it to
1321    // generate the certificate's signature.
1322    final BigInteger serialNumber = generateSerialNumber();
1323    final ASN1BitString encodedSignature = generateSignature(signatureAlgorithm,
1324         keyPair.getPrivate(), serialNumber, subjectDN, notBefore, notAfter,
1325         subjectDN, publicKeyAlgorithmOID, publicKeyAlgorithmParameters,
1326         encodedPublicKey, allExtensions);
1327
1328
1329    // Construct and return the signed certificate and the private key.
1330    return new X509Certificate(X509CertificateVersion.V3, serialNumber,
1331         signatureAlgorithm.getOID(), null, encodedSignature, subjectDN,
1332         notBefore, notAfter, subjectDN, publicKeyAlgorithmOID,
1333         publicKeyAlgorithmParameters, encodedPublicKey, decodedPublicKey, null,
1334         null, allExtensions);
1335  }
1336
1337
1338
1339  /**
1340   * Generates an issuer-signed X.509 certificate with the provided information.
1341   *
1342   * @param  signatureAlgorithm
1343   *              The algorithm to use to generate the signature.  This must not
1344   *              be {@code null}.
1345   * @param  issuerCertificate
1346   *              The certificate for the issuer.  This must not be
1347   *              {@code null}.
1348   * @param  issuerPrivateKey
1349   *              The private key for the issuer.  This  must not be
1350   *              {@code null}.
1351   * @param  publicKeyAlgorithmOID
1352   *              The OID for the certificate's public key algorithm.  This must
1353   *              not be {@code null}.
1354   * @param  publicKeyAlgorithmParameters
1355   *              The encoded public key algorithm parameters for the
1356   *              certificate.  This may be {@code null} if there are no
1357   *              parameters.
1358   * @param  encodedPublicKey
1359   *              The encoded public key for the certificate.  This must not be
1360   *              {@code null}.
1361   * @param  decodedPublicKey
1362   *              The decoded public key for the certificate.  This may be
1363   *              {@code null} if it is not available.
1364   * @param  subjectDN
1365   *              The subject DN for the certificate.  This must not be
1366   *              {@code null}.
1367   * @param  notBefore
1368   *              The validity start time for the certificate.
1369   * @param  notAfter
1370   *              The validity end time for the certificate.
1371   * @param  extensions
1372   *              The set of extensions to include in the certificate.  This
1373   *              may be {@code null} or empty if the certificate should not
1374   *              include any custom extensions.  Note that the generated
1375   *              certificate will automatically include a
1376   *              {@link SubjectKeyIdentifierExtension}, so that should not be
1377   *              provided.  In addition, if the issuer certificate includes its
1378   *              own {@code SubjectKeyIdentifierExtension}, then its value will
1379   *              be used to generate an
1380   *              {@link AuthorityKeyIdentifierExtension}.
1381   *
1382   * @return  The issuer-signed certificate.
1383   *
1384   * @throws  CertException  If a problem is encountered while creating the
1385   *                         certificate.
1386   */
1387  public static X509Certificate generateIssuerSignedCertificate(
1388              final SignatureAlgorithmIdentifier signatureAlgorithm,
1389              final X509Certificate issuerCertificate,
1390              final PrivateKey issuerPrivateKey,
1391              final OID publicKeyAlgorithmOID,
1392              final ASN1Element publicKeyAlgorithmParameters,
1393              final ASN1BitString encodedPublicKey,
1394              final DecodedPublicKey decodedPublicKey, final DN subjectDN,
1395              final long notBefore, final long notAfter,
1396              final X509CertificateExtension... extensions)
1397         throws CertException
1398  {
1399    // Generate a subject key identifier from the encoded public key.
1400    final byte[] subjectKeyIdentifier;
1401    try
1402    {
1403      final MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
1404      subjectKeyIdentifier = sha256.digest(encodedPublicKey.getBytes());
1405    }
1406    catch (final Exception e)
1407    {
1408      Debug.debugException(e);
1409      throw new CertException(
1410           ERR_CERT_GEN_ISSUER_SIGNED_CANNOT_GENERATE_KEY_ID.get(
1411                StaticUtils.getExceptionMessage(e)),
1412           e);
1413    }
1414
1415
1416    // If the issuer certificate contains a subject key identifier, then
1417    // extract it to use as the authority key identifier.
1418    ASN1OctetString authorityKeyIdentifier = null;
1419    for (final X509CertificateExtension e : issuerCertificate.extensions)
1420    {
1421      if (e instanceof SubjectKeyIdentifierExtension)
1422      {
1423        authorityKeyIdentifier =
1424             ((SubjectKeyIdentifierExtension) e).getKeyIdentifier();
1425      }
1426    }
1427
1428
1429    // Construct the set of all extensions for the certificate.
1430    final ArrayList<X509CertificateExtension> extensionList =
1431         new ArrayList<>(10);
1432    extensionList.add(new SubjectKeyIdentifierExtension(false,
1433         new ASN1OctetString(subjectKeyIdentifier)));
1434
1435    if (authorityKeyIdentifier == null)
1436    {
1437      extensionList.add(new AuthorityKeyIdentifierExtension(false, null,
1438           new GeneralNamesBuilder().addDirectoryName(
1439                issuerCertificate.subjectDN).build(),
1440           issuerCertificate.serialNumber));
1441    }
1442    else
1443    {
1444      extensionList.add(new AuthorityKeyIdentifierExtension(false,
1445           authorityKeyIdentifier, null, null));
1446    }
1447
1448    if (extensions != null)
1449    {
1450      for (final X509CertificateExtension e : extensions)
1451      {
1452        if (e.getOID().equals(
1453             SubjectKeyIdentifierExtension.SUBJECT_KEY_IDENTIFIER_OID) ||
1454            e.getOID().equals(
1455                 AuthorityKeyIdentifierExtension.AUTHORITY_KEY_IDENTIFIER_OID))
1456        {
1457          continue;
1458        }
1459
1460        extensionList.add(e);
1461      }
1462    }
1463
1464    final X509CertificateExtension[] allExtensions =
1465         new X509CertificateExtension[extensionList.size()];
1466    extensionList.toArray(allExtensions);
1467
1468
1469    // Encode the tbsCertificate sequence for the certificate and use it to
1470    // generate the certificate's signature.
1471    final BigInteger serialNumber = generateSerialNumber();
1472    final ASN1BitString encodedSignature = generateSignature(signatureAlgorithm,
1473         issuerPrivateKey, serialNumber, issuerCertificate.subjectDN, notBefore,
1474         notAfter, subjectDN, publicKeyAlgorithmOID,
1475         publicKeyAlgorithmParameters, encodedPublicKey, allExtensions);
1476
1477
1478    // Construct and return the signed certificate.
1479    return new X509Certificate(X509CertificateVersion.V3, serialNumber,
1480         signatureAlgorithm.getOID(), null, encodedSignature,
1481         issuerCertificate.subjectDN, notBefore, notAfter, subjectDN,
1482         publicKeyAlgorithmOID, publicKeyAlgorithmParameters, encodedPublicKey,
1483         decodedPublicKey, null, null, allExtensions);
1484  }
1485
1486
1487
1488  /**
1489   * Generates a serial number for the certificate.
1490   *
1491   * @return  The generated serial number.
1492   */
1493  private static BigInteger generateSerialNumber()
1494  {
1495    final UUID uuid = UUID.randomUUID();
1496    final long msb = uuid.getMostSignificantBits() & 0x7FFF_FFFF_FFFF_FFFFL;
1497    final long lsb = uuid.getLeastSignificantBits() & 0x7FFF_FFFF_FFFF_FFFFL;
1498    return BigInteger.valueOf(msb).shiftLeft(64).add(BigInteger.valueOf(lsb));
1499  }
1500
1501
1502
1503  /**
1504   * Generates a signature for the certificate with the provided information.
1505   *
1506   * @param  signatureAlgorithm            The signature algorithm to use to
1507   *                                       generate the signature.  This must
1508   *                                       not be {@code null}.
1509   * @param  privateKey                    The private key to use to sign the
1510   *                                       certificate.  This must not be
1511   *                                       {@code null}.
1512   * @param  serialNumber                  The serial number for the
1513   *                                       certificate.  This must not be
1514   *                                       {@code null}.
1515   * @param  issuerDN                      The issuer DN for the certificate.
1516   *                                       This must not be {@code null}.
1517   * @param  notBefore                     The validity start time for the
1518   *                                       certificate.
1519   * @param  notAfter                      The validity end time for the
1520   *                                       certificate.
1521   * @param  subjectDN                     The subject DN for the certificate.
1522   *                                       This must not be {@code null}.
1523   * @param  publicKeyAlgorithmOID         The OID for the public key algorithm.
1524   *                                       This must not be {@code null}.
1525   * @param  publicKeyAlgorithmParameters  The encoded public key algorithm
1526   *                                       parameters.  This may be
1527   *                                       {@code null} if no parameters are
1528   *                                       needed.
1529   * @param  encodedPublicKey              The encoded representation of the
1530   *                                       public key.  This must not be
1531   *                                       {@code null}.
1532   * @param  extensions                    The set of extensions to include in
1533   *                                       the certificate.  This must not be
1534   *                                       {@code null} but may be empty.
1535   *
1536   * @return  An encoded representation of the generated signature.
1537   *
1538   * @throws  CertException  If a problem is encountered while generating the
1539   *                         certificate.
1540   */
1541  private static ASN1BitString generateSignature(
1542                      final SignatureAlgorithmIdentifier signatureAlgorithm,
1543                      final PrivateKey privateKey,
1544                      final BigInteger serialNumber,
1545                      final DN issuerDN, final long notBefore,
1546                      final long notAfter, final DN subjectDN,
1547                      final OID publicKeyAlgorithmOID,
1548                      final ASN1Element publicKeyAlgorithmParameters,
1549                      final ASN1BitString encodedPublicKey,
1550                      final X509CertificateExtension... extensions)
1551          throws CertException
1552  {
1553    // Get and initialize the signature generator.
1554    final Signature signature;
1555    try
1556    {
1557      signature = Signature.getInstance(signatureAlgorithm.getJavaName());
1558    }
1559    catch (final Exception e)
1560    {
1561      Debug.debugException(e);
1562      throw new CertException(
1563           ERR_CERT_GEN_SIGNATURE_CANNOT_GET_SIGNATURE_GENERATOR.get(
1564                signatureAlgorithm.getJavaName(),
1565                StaticUtils.getExceptionMessage(e)),
1566           e);
1567    }
1568
1569    try
1570    {
1571      signature.initSign(privateKey);
1572    }
1573    catch (final Exception e)
1574    {
1575      Debug.debugException(e);
1576      throw new CertException(
1577           ERR_CERT_GEN_SIGNATURE_CANNOT_INIT_SIGNATURE_GENERATOR.get(
1578                signatureAlgorithm.getJavaName(),
1579                StaticUtils.getExceptionMessage(e)),
1580           e);
1581    }
1582
1583
1584    // Construct the tbsCertificate element of the certificate and compute its
1585    // signature.
1586    try
1587    {
1588      final ArrayList<ASN1Element> tbsCertificateElements = new ArrayList<>(8);
1589      tbsCertificateElements.add(new ASN1Element(TYPE_EXPLICIT_VERSION,
1590           new ASN1Integer(X509CertificateVersion.V3.getIntValue()).encode()));
1591      tbsCertificateElements.add(new ASN1BigInteger(serialNumber));
1592      tbsCertificateElements.add(new ASN1Sequence(
1593           new ASN1ObjectIdentifier(signatureAlgorithm.getOID())));
1594      tbsCertificateElements.add(encodeName(issuerDN));
1595      tbsCertificateElements.add(encodeValiditySequence(notBefore, notAfter));
1596      tbsCertificateElements.add(encodeName(subjectDN));
1597
1598      if (publicKeyAlgorithmParameters == null)
1599      {
1600        tbsCertificateElements.add(new ASN1Sequence(
1601             new ASN1Sequence(
1602                  new ASN1ObjectIdentifier(publicKeyAlgorithmOID)),
1603             encodedPublicKey));
1604      }
1605      else
1606      {
1607        tbsCertificateElements.add(new ASN1Sequence(
1608             new ASN1Sequence(
1609                  new ASN1ObjectIdentifier(publicKeyAlgorithmOID),
1610                  publicKeyAlgorithmParameters),
1611             encodedPublicKey));
1612      }
1613
1614      final ArrayList<ASN1Element> extensionElements =
1615           new ArrayList<>(extensions.length);
1616      for (final X509CertificateExtension e : extensions)
1617      {
1618        extensionElements.add(e.encode());
1619      }
1620      tbsCertificateElements.add(new ASN1Element(TYPE_EXPLICIT_EXTENSIONS,
1621           new ASN1Sequence(extensionElements).encode()));
1622
1623      final byte[] tbsCertificateBytes =
1624           new ASN1Sequence(tbsCertificateElements).encode();
1625      signature.update(tbsCertificateBytes);
1626      final byte[] signatureBytes = signature.sign();
1627
1628      return new ASN1BitString(ASN1BitString.getBitsForBytes(signatureBytes));
1629    }
1630    catch (final Exception e)
1631    {
1632      Debug.debugException(e);
1633      throw new CertException(
1634           ERR_CERT_GEN_SIGNATURE_CANNOT_COMPUTE.get(
1635                signatureAlgorithm.getJavaName(),
1636                StaticUtils.getExceptionMessage(e)),
1637           e);
1638    }
1639  }
1640
1641
1642
1643  /**
1644   * Retrieves the bytes that comprise the encoded representation of this X.509
1645   * certificate.
1646   *
1647   * @return  The bytes that comprise the encoded representation of this X.509
1648   *          certificate.
1649   */
1650  public byte[] getX509CertificateBytes()
1651  {
1652    return x509CertificateBytes;
1653  }
1654
1655
1656
1657  /**
1658   * Retrieves the certificate version.
1659   *
1660   * @return  The certificate version.
1661   */
1662  public X509CertificateVersion getVersion()
1663  {
1664    return version;
1665  }
1666
1667
1668
1669  /**
1670   * Retrieves the certificate serial number.
1671   *
1672   * @return  The certificate serial number.
1673   */
1674  public BigInteger getSerialNumber()
1675  {
1676    return serialNumber;
1677  }
1678
1679
1680
1681  /**
1682   * Retrieves the certificate signature algorithm OID.
1683   *
1684   * @return  The certificate signature algorithm OID.
1685   */
1686  public OID getSignatureAlgorithmOID()
1687  {
1688    return signatureAlgorithmOID;
1689  }
1690
1691
1692
1693  /**
1694   * Retrieves the certificate signature algorithm name, if available.
1695   *
1696   * @return  The certificate signature algorithm name, or {@code null} if the
1697   *          signature algorithm OID does not correspond to any known algorithm
1698   *          name.
1699   */
1700  public String getSignatureAlgorithmName()
1701  {
1702    return signatureAlgorithmName;
1703  }
1704
1705
1706
1707  /**
1708   * Retrieves the signature algorithm name if it is available, or the string
1709   * representation of the signature algorithm OID if not.
1710   *
1711   * @return  The signature algorithm name or OID.
1712   */
1713  public String getSignatureAlgorithmNameOrOID()
1714  {
1715    if (signatureAlgorithmName != null)
1716    {
1717      return signatureAlgorithmName;
1718    }
1719    else
1720    {
1721      return signatureAlgorithmOID.toString();
1722    }
1723  }
1724
1725
1726
1727  /**
1728   * Retrieves the encoded signature algorithm parameters, if present.
1729   *
1730   * @return  The encoded signature algorithm parameters, or {@code null} if
1731   *          there are no signature algorithm parameters.
1732   */
1733  public ASN1Element getSignatureAlgorithmParameters()
1734  {
1735    return signatureAlgorithmParameters;
1736  }
1737
1738
1739
1740  /**
1741   * Retrieves the certificate issuer DN.
1742   *
1743   * @return  The certificate issuer DN.
1744   */
1745  public DN getIssuerDN()
1746  {
1747    return issuerDN;
1748  }
1749
1750
1751
1752  /**
1753   * Retrieves the certificate validity start time as the number of milliseconds
1754   * since the epoch (January 1, 1970 UTC).
1755   *
1756   * @return  The certificate validity start time as the number of milliseconds
1757   *          since the epoch.
1758   */
1759  public long getNotBeforeTime()
1760  {
1761    return notBefore;
1762  }
1763
1764
1765
1766  /**
1767   * Retrieves the certificate validity start time as a {@code Date}.
1768   *
1769   * @return  The certificate validity start time as a {@code Date}.
1770   */
1771  public Date getNotBeforeDate()
1772  {
1773    return new Date(notBefore);
1774  }
1775
1776
1777
1778  /**
1779   * Retrieves the certificate validity end time as the number of milliseconds
1780   * since the epoch (January 1, 1970 UTC).
1781   *
1782   * @return  The certificate validity end time as the number of milliseconds
1783   *          since the epoch.
1784   */
1785  public long getNotAfterTime()
1786  {
1787    return notAfter;
1788  }
1789
1790
1791
1792  /**
1793   * Retrieves the certificate validity end time as a {@code Date}.
1794   *
1795   * @return  The certificate validity end time as a {@code Date}.
1796   */
1797  public Date getNotAfterDate()
1798  {
1799    return new Date(notAfter);
1800  }
1801
1802
1803
1804  /**
1805   * Indicates whether the current time is within the certificate's validity
1806   * window.
1807   *
1808   * @return  {@code true} if the current time is within the certificate's
1809   *          validity window, or {@code false} if not.
1810   */
1811  public boolean isWithinValidityWindow()
1812  {
1813    return isWithinValidityWindow(System.currentTimeMillis());
1814  }
1815
1816
1817
1818  /**
1819   * Indicates whether the provided {@code Date} represents a time within the
1820   * certificate's validity window.
1821   *
1822   * @param  date  The {@code Date} for which to make the determination.  It
1823   *               must not be {@code null}.
1824   *
1825   * @return  {@code true} if the provided {@code Date} is within the
1826   *          certificate's validity window, or {@code false} if not.
1827   */
1828  public boolean isWithinValidityWindow(final Date date)
1829  {
1830    return isWithinValidityWindow(date.getTime());
1831  }
1832
1833
1834
1835  /**
1836   * Indicates whether the specified time is within the certificate's validity
1837   * window.
1838   *
1839   * @param  time  The time to for which to make the determination.
1840   *
1841   * @return  {@code true} if the specified time is within the certificate's
1842   *          validity window, or {@code false} if not.
1843   */
1844  public boolean isWithinValidityWindow(final long time)
1845  {
1846    return ((time >= notBefore) && (time <= notAfter));
1847  }
1848
1849
1850
1851  /**
1852   * Retrieves the certificate subject DN.
1853   *
1854   * @return  The certificate subject DN.
1855   */
1856  public DN getSubjectDN()
1857  {
1858    return subjectDN;
1859  }
1860
1861
1862
1863  /**
1864   * Retrieves the certificate public key algorithm OID.
1865   *
1866   * @return  The certificate public key algorithm OID.
1867   */
1868  public OID getPublicKeyAlgorithmOID()
1869  {
1870    return publicKeyAlgorithmOID;
1871  }
1872
1873
1874
1875  /**
1876   * Retrieves the certificate public key algorithm name, if available.
1877   *
1878   * @return  The certificate public key algorithm name, or {@code null} if the
1879   *          public key algorithm OID does not correspond to any known
1880   *          algorithm name.
1881   */
1882  public String getPublicKeyAlgorithmName()
1883  {
1884    return publicKeyAlgorithmName;
1885  }
1886
1887
1888
1889  /**
1890   * Retrieves the public key algorithm name if it is available, or the string
1891   * representation of the public key algorithm OID if not.
1892   *
1893   * @return  The signature algorithm name or OID.
1894   */
1895  public String getPublicKeyAlgorithmNameOrOID()
1896  {
1897    if (publicKeyAlgorithmName != null)
1898    {
1899      return publicKeyAlgorithmName;
1900    }
1901    else
1902    {
1903      return publicKeyAlgorithmOID.toString();
1904    }
1905  }
1906
1907
1908
1909  /**
1910   * Retrieves the encoded public key algorithm parameters, if present.
1911   *
1912   * @return  The encoded public key algorithm parameters, or {@code null} if
1913   *          there are no public key algorithm parameters.
1914   */
1915  public ASN1Element getPublicKeyAlgorithmParameters()
1916  {
1917    return publicKeyAlgorithmParameters;
1918  }
1919
1920
1921
1922  /**
1923   * Retrieves the encoded public key as a bit string.
1924   *
1925   * @return  The encoded public key as a bit string.
1926   */
1927  public ASN1BitString getEncodedPublicKey()
1928  {
1929    return encodedPublicKey;
1930  }
1931
1932
1933
1934  /**
1935   * Retrieves a decoded representation of the public key, if available.
1936   *
1937   * @return  A decoded representation of the public key, or {@code null} if the
1938   *          public key could not be decoded.
1939   */
1940  public DecodedPublicKey getDecodedPublicKey()
1941  {
1942    return decodedPublicKey;
1943  }
1944
1945
1946
1947  /**
1948   * Retrieves the issuer unique identifier for the certificate, if any.
1949   *
1950   * @return  The issuer unique identifier for the certificate, or {@code null}
1951   *          if there is none.
1952   */
1953  public ASN1BitString getIssuerUniqueID()
1954  {
1955    return issuerUniqueID;
1956  }
1957
1958
1959
1960  /**
1961   * Retrieves the subject unique identifier for the certificate, if any.
1962   *
1963   * @return  The subject unique identifier for the certificate, or {@code null}
1964   *          if there is none.
1965   */
1966  public ASN1BitString getSubjectUniqueID()
1967  {
1968    return subjectUniqueID;
1969  }
1970
1971
1972
1973  /**
1974   * Retrieves the list of certificate extensions.
1975   *
1976   * @return  The list of certificate extensions.
1977   */
1978  public List<X509CertificateExtension> getExtensions()
1979  {
1980    return extensions;
1981  }
1982
1983
1984
1985  /**
1986   * Retrieves the signature value for the certificate.
1987   *
1988   * @return  The signature value for the certificate.
1989   */
1990  public ASN1BitString getSignatureValue()
1991  {
1992    return signatureValue;
1993  }
1994
1995
1996
1997  /**
1998   * Verifies the signature for this certificate.
1999   *
2000   * @param  issuerCertificate  The issuer certificate for this certificate.  It
2001   *                            may be {@code null} if this is a self-signed
2002   *                            certificate.  It must not be {@code null} if it
2003   *                            is not a self-signed certificate.
2004   *
2005   * @throws  CertException  If the certificate signature could not be verified.
2006   */
2007  public void verifySignature(final X509Certificate issuerCertificate)
2008         throws CertException
2009  {
2010    // Get the issuer certificate.  If the certificate is self-signed, then it
2011    // might be the current certificate.
2012    final X509Certificate issuer;
2013    if (issuerCertificate == null)
2014    {
2015      if (isSelfSigned())
2016      {
2017        issuer = this;
2018      }
2019      else
2020      {
2021        throw new CertException(
2022             ERR_CERT_VERIFY_SIGNATURE_ISSUER_CERT_NOT_PROVIDED.get());
2023      }
2024    }
2025    else
2026    {
2027      issuer = issuerCertificate;
2028    }
2029
2030
2031    // Get the public key from the issuer certificate.
2032    final PublicKey publicKey;
2033    try
2034    {
2035      publicKey = issuer.toCertificate().getPublicKey();
2036    }
2037    catch (final Exception e)
2038    {
2039      Debug.debugException(e);
2040      throw new CertException(
2041           ERR_CERT_VERIFY_SIGNATURE_CANNOT_GET_PUBLIC_KEY.get(
2042                StaticUtils.getExceptionMessage(e)),
2043           e);
2044    }
2045
2046
2047    // Get and initialize the signature generator.
2048    final Signature signature;
2049    final SignatureAlgorithmIdentifier signatureAlgorithm;
2050    try
2051    {
2052      signatureAlgorithm =
2053           SignatureAlgorithmIdentifier.forOID(signatureAlgorithmOID);
2054      signature = Signature.getInstance(signatureAlgorithm.getJavaName());
2055    }
2056    catch (final Exception e)
2057    {
2058      Debug.debugException(e);
2059      throw new CertException(
2060           ERR_CERT_VERIFY_SIGNATURE_CANNOT_GET_SIGNATURE_VERIFIER.get(
2061                getSignatureAlgorithmNameOrOID(),
2062                StaticUtils.getExceptionMessage(e)),
2063           e);
2064    }
2065
2066    try
2067    {
2068      signature.initVerify(publicKey);
2069    }
2070    catch (final Exception e)
2071    {
2072      Debug.debugException(e);
2073      throw new CertException(
2074           ERR_CERT_VERIFY_SIGNATURE_CANNOT_INIT_SIGNATURE_VERIFIER.get(
2075                signatureAlgorithm.getJavaName(),
2076                StaticUtils.getExceptionMessage(e)),
2077           e);
2078    }
2079
2080
2081    // Construct the tbsCertificate element of the certificate and compute its
2082    // signature.
2083    try
2084    {
2085      final ASN1Element[] x509CertificateElements =
2086           ASN1Sequence.decodeAsSequence(x509CertificateBytes).elements();
2087      final byte[] tbsCertificateBytes = x509CertificateElements[0].encode();
2088      signature.update(tbsCertificateBytes);
2089    }
2090    catch (final Exception e)
2091    {
2092      Debug.debugException(e);
2093      throw new CertException(
2094           ERR_CERT_GEN_SIGNATURE_CANNOT_COMPUTE.get(
2095                signatureAlgorithm.getJavaName(),
2096                StaticUtils.getExceptionMessage(e)),
2097           e);
2098    }
2099
2100
2101    try
2102    {
2103      if (! signature.verify(signatureValue.getBytes()))
2104      {
2105        throw new CertException(
2106             ERR_CERT_VERIFY_SIGNATURE_NOT_VALID.get(subjectDN));
2107      }
2108    }
2109    catch (final CertException ce)
2110    {
2111      Debug.debugException(ce);
2112      throw ce;
2113    }
2114    catch (final Exception e)
2115    {
2116      Debug.debugException(e);
2117      throw new CertException(
2118           ERR_CERT_VERIFY_SIGNATURE_ERROR.get(subjectDN,
2119                StaticUtils.getExceptionMessage(e)),
2120           e);
2121    }
2122  }
2123
2124
2125
2126  /**
2127   * Retrieves the bytes that comprise a SHA-1 fingerprint of this certificate.
2128   *
2129   * @return  The bytes that comprise a SHA-1 fingerprint of this certificate.
2130   *
2131   * @throws  CertException  If a problem is encountered while computing the
2132   *                         fingerprint.
2133   */
2134  public byte[] getSHA1Fingerprint()
2135         throws CertException
2136  {
2137    return getFingerprint("SHA-1");
2138  }
2139
2140
2141
2142  /**
2143   * Retrieves the bytes that comprise a 256-bit SHA-2 fingerprint of this
2144   * certificate.
2145   *
2146   * @return  The bytes that comprise a 256-bit SHA-2 fingerprint of this
2147   *          certificate.
2148   *
2149   * @throws  CertException  If a problem is encountered while computing the
2150   *                         fingerprint.
2151   */
2152  public byte[] getSHA256Fingerprint()
2153         throws CertException
2154  {
2155    return getFingerprint("SHA-256");
2156  }
2157
2158
2159
2160  /**
2161   * Retrieves the bytes that comprise a fingerprint of this certificate.
2162   *
2163   * @param  digestAlgorithm  The digest algorithm to use to generate the
2164   *                          fingerprint.
2165   *
2166   * @return  The bytes that comprise a fingerprint of this certificate.
2167   *
2168   * @throws  CertException  If a problem is encountered while computing the
2169   *                         fingerprint.
2170   */
2171  private byte[] getFingerprint(final String digestAlgorithm)
2172          throws CertException
2173  {
2174    try
2175    {
2176      final MessageDigest digest = MessageDigest.getInstance(digestAlgorithm);
2177      return digest.digest(x509CertificateBytes);
2178    }
2179    catch (final Exception e)
2180    {
2181      // This should never happen.
2182      Debug.debugException(e);
2183      throw new CertException(
2184           ERR_CERT_CANNOT_COMPUTE_FINGERPRINT.get(digestAlgorithm,
2185                StaticUtils.getExceptionMessage(e)),
2186           e);
2187    }
2188  }
2189
2190
2191
2192  /**
2193   * Indicates whether this certificate is self-signed.  The following criteria
2194   * will be used to make the determination:
2195   * <OL>
2196   *   <LI>
2197   *     If the certificate has both subject key identifier and authority
2198   *     key identifier extensions, then it will be considered self-signed if
2199   *     and only if the subject key identifier matches the authority key
2200   *     identifier.
2201   *   </LI>
2202   *   <LI>
2203   *     If the certificate does not have both a subject key identifier and an
2204   *     authority key identifier, then it will be considered self-signed if and
2205   *     only if its subject DN matches its issuer DN.
2206   *   </LI>
2207   * </OL>
2208   *
2209   * @return  {@code true} if this certificate is self-signed, or {@code false}
2210   *          if it is not.
2211   */
2212  public boolean isSelfSigned()
2213  {
2214    AuthorityKeyIdentifierExtension akie = null;
2215    SubjectKeyIdentifierExtension skie = null;
2216    for (final X509CertificateExtension e : extensions)
2217    {
2218      if (e instanceof AuthorityKeyIdentifierExtension)
2219      {
2220        akie = (AuthorityKeyIdentifierExtension) e;
2221      }
2222      else if (e instanceof SubjectKeyIdentifierExtension)
2223      {
2224        skie = (SubjectKeyIdentifierExtension) e;
2225      }
2226    }
2227
2228    if ((akie != null) && (skie != null))
2229    {
2230      return ((akie.getKeyIdentifier() != null) &&
2231           Arrays.equals(akie.getKeyIdentifier().getValue(),
2232                skie.getKeyIdentifier().getValue()));
2233    }
2234    else
2235    {
2236      return subjectDN.equals(issuerDN);
2237    }
2238  }
2239
2240
2241
2242  /**
2243   * Indicates whether this certificate is the issuer for the provided
2244   * certificate.  In order for this to be true, the following conditions must
2245   * be met:
2246   * <OL>
2247   *   <LI>
2248   *     The subject DN of this certificate must match the issuer DN for the
2249   *     provided certificate.
2250   *   </LI>
2251   *   <LI>
2252   *     If the provided certificate has an authority key identifier extension,
2253   *     then this certificate must have a subject key identifier extension with
2254   *     a matching identifier value.
2255   *   </LI>
2256   * </OL>
2257   *
2258   * @param  c  The certificate for which to make the determination.  This must
2259   *            not be {@code null}.
2260   *
2261   * @return  {@code true} if this certificate is considered the issuer for the
2262   *          provided certificate, or {@code } false if not.
2263   */
2264  public boolean isIssuerFor(final X509Certificate c)
2265  {
2266    return isIssuerFor(c, null);
2267  }
2268
2269
2270
2271  /**
2272   * Indicates whether this certificate is the issuer for the provided
2273   * certificate.  In order for this to be true, the following conditions must
2274   * be met:
2275   * <OL>
2276   *   <LI>
2277   *     The subject DN of this certificate must match the issuer DN for the
2278   *     provided certificate.
2279   *   </LI>
2280   *   <LI>
2281   *     If the provided certificate has an authority key identifier extension,
2282   *     then this certificate must have a subject key identifier extension with
2283   *     a matching identifier value.
2284   *   </LI>
2285   * </OL>
2286   *
2287   * @param  c               The certificate for which to make the
2288   *                         determination.  This must not be {@code null}.
2289   * @param  nonMatchReason  An optional buffer that may be updated with the
2290   *                         reason that this certificate is not considered the
2291   *                         issuer for the provided certificate.  This may be
2292   *                         {@code null} if the caller does not require a
2293   *                         reason.
2294   *
2295   * @return  {@code true} if this certificate is considered the issuer for the
2296   *          provided certificate, or {@code } false if not.
2297   */
2298  public boolean isIssuerFor(final X509Certificate c,
2299                             final StringBuilder nonMatchReason)
2300  {
2301    if (! c.issuerDN.equals(subjectDN))
2302    {
2303      if (nonMatchReason != null)
2304      {
2305        nonMatchReason.append(INFO_CERT_IS_ISSUER_FOR_DN_MISMATCH.get(
2306             subjectDN, c.subjectDN, issuerDN));
2307      }
2308
2309      return false;
2310    }
2311
2312
2313    byte[] authorityKeyIdentifier = null;
2314    for (final X509CertificateExtension extension : c.extensions)
2315    {
2316      if (extension instanceof AuthorityKeyIdentifierExtension)
2317      {
2318        final AuthorityKeyIdentifierExtension akie =
2319             (AuthorityKeyIdentifierExtension) extension;
2320        if (akie.getKeyIdentifier() != null)
2321        {
2322          authorityKeyIdentifier = akie.getKeyIdentifier().getValue();
2323          break;
2324        }
2325      }
2326    }
2327
2328    if (authorityKeyIdentifier != null)
2329    {
2330      boolean matchFound = false;
2331      for (final X509CertificateExtension extension : extensions)
2332      {
2333        if (extension instanceof SubjectKeyIdentifierExtension)
2334        {
2335          final SubjectKeyIdentifierExtension skie =
2336               (SubjectKeyIdentifierExtension) extension;
2337          matchFound = Arrays.equals(authorityKeyIdentifier,
2338               skie.getKeyIdentifier().getValue());
2339          break;
2340        }
2341      }
2342
2343      if (! matchFound)
2344      {
2345        if (nonMatchReason != null)
2346        {
2347          nonMatchReason.append(INFO_CERT_IS_ISSUER_FOR_KEY_ID_MISMATCH.get(
2348               subjectDN, c.subjectDN));
2349        }
2350
2351        return false;
2352      }
2353    }
2354
2355
2356    return true;
2357  }
2358
2359
2360
2361  /**
2362   * Converts this X.509 certificate object to a Java {@code Certificate}
2363   * object.
2364   *
2365   * @return  The Java {@code Certificate} object that corresponds to this
2366   *          X.509 certificate.
2367   *
2368   * @throws  CertificateException  If a problem is encountered while performing
2369   *                                the conversion.
2370   */
2371  public Certificate toCertificate()
2372         throws CertificateException
2373  {
2374    return CertificateFactory.getInstance("X.509").generateCertificate(
2375         new ByteArrayInputStream(x509CertificateBytes));
2376  }
2377
2378
2379
2380  /**
2381   * Retrieves a string representation of the decoded X.509 certificate.
2382   *
2383   * @return  A string representation of the decoded X.509 certificate.
2384   */
2385  @Override()
2386  public String toString()
2387  {
2388    final StringBuilder buffer = new StringBuilder();
2389    toString(buffer);
2390    return buffer.toString();
2391  }
2392
2393
2394
2395  /**
2396   * Appends a string representation of the decoded X.509 certificate to the
2397   * provided buffer.
2398   *
2399   * @param  buffer  The buffer to which the information should be appended.
2400   */
2401  public void toString(final StringBuilder buffer)
2402  {
2403    buffer.append("X509Certificate(version='");
2404    buffer.append(version.getName());
2405    buffer.append("', serialNumber='");
2406    StaticUtils.toHex(serialNumber.toByteArray(), ":", buffer);
2407    buffer.append("', signatureAlgorithmOID='");
2408    buffer.append(signatureAlgorithmOID.toString());
2409    buffer.append('\'');
2410
2411    if (signatureAlgorithmName != null)
2412    {
2413      buffer.append(", signatureAlgorithmName='");
2414      buffer.append(signatureAlgorithmName);
2415      buffer.append('\'');
2416    }
2417
2418    buffer.append(", issuerDN='");
2419    buffer.append(issuerDN.toString());
2420    buffer.append("', notBefore='");
2421    buffer.append(StaticUtils.encodeGeneralizedTime(notBefore));
2422    buffer.append("', notAfter='");
2423    buffer.append(StaticUtils.encodeGeneralizedTime(notAfter));
2424    buffer.append("', subjectDN='");
2425    buffer.append(subjectDN.toString());
2426    buffer.append("', publicKeyAlgorithmOID='");
2427    buffer.append(publicKeyAlgorithmOID.toString());
2428    buffer.append('\'');
2429
2430    if (publicKeyAlgorithmName != null)
2431    {
2432      buffer.append(", publicKeyAlgorithmName='");
2433      buffer.append(publicKeyAlgorithmName);
2434      buffer.append('\'');
2435    }
2436
2437    buffer.append(", subjectPublicKey=");
2438    if (decodedPublicKey == null)
2439    {
2440      buffer.append('\'');
2441
2442      try
2443      {
2444        StaticUtils.toHex(encodedPublicKey.getBytes(), ":", buffer);
2445      }
2446      catch (final Exception e)
2447      {
2448        Debug.debugException(e);
2449        encodedPublicKey.toString(buffer);
2450      }
2451
2452      buffer.append('\'');
2453    }
2454    else
2455    {
2456      decodedPublicKey.toString(buffer);
2457
2458      if (decodedPublicKey instanceof EllipticCurvePublicKey)
2459      {
2460        try
2461        {
2462          final OID namedCurveOID =
2463               publicKeyAlgorithmParameters.decodeAsObjectIdentifier().getOID();
2464          buffer.append(", ellipticCurvePublicKeyParameters=namedCurve='");
2465          buffer.append(NamedCurve.getNameOrOID(namedCurveOID));
2466          buffer.append('\'');
2467        }
2468        catch (final Exception e)
2469        {
2470          Debug.debugException(e);
2471        }
2472      }
2473    }
2474
2475    if (issuerUniqueID != null)
2476    {
2477      buffer.append(", issuerUniqueID='");
2478      buffer.append(issuerUniqueID.toString());
2479      buffer.append('\'');
2480    }
2481
2482    if (subjectUniqueID != null)
2483    {
2484      buffer.append(", subjectUniqueID='");
2485      buffer.append(subjectUniqueID.toString());
2486      buffer.append('\'');
2487    }
2488
2489    if (! extensions.isEmpty())
2490    {
2491      buffer.append(", extensions={");
2492
2493      final Iterator<X509CertificateExtension> iterator = extensions.iterator();
2494      while (iterator.hasNext())
2495      {
2496        iterator.next().toString(buffer);
2497        if (iterator.hasNext())
2498        {
2499          buffer.append(", ");
2500        }
2501      }
2502
2503      buffer.append('}');
2504    }
2505
2506    buffer.append(", signatureValue='");
2507
2508    try
2509    {
2510      StaticUtils.toHex(signatureValue.getBytes(), ":", buffer);
2511    }
2512    catch (final Exception e)
2513    {
2514      Debug.debugException(e);
2515      buffer.append(signatureValue.toString());
2516    }
2517
2518    buffer.append("')");
2519  }
2520
2521
2522
2523  /**
2524   * Retrieves a list of the lines that comprise a PEM representation of this
2525   * X.509 certificate.
2526   *
2527   * @return  A list of the lines that comprise a PEM representation of this
2528   *          X.509 certificate.
2529   */
2530  public List<String> toPEM()
2531  {
2532    final ArrayList<String> lines = new ArrayList<>(10);
2533    lines.add("-----BEGIN CERTIFICATE-----");
2534
2535    final String certBase64 = Base64.encode(x509CertificateBytes);
2536    lines.addAll(StaticUtils.wrapLine(certBase64, 64));
2537
2538    lines.add("-----END CERTIFICATE-----");
2539
2540    return Collections.unmodifiableList(lines);
2541  }
2542
2543
2544
2545  /**
2546   * Retrieves a multi-line string containing a PEM representation of this X.509
2547   * certificate.
2548   *
2549   * @return  A multi-line string containing a PEM representation of this X.509
2550   *          certificate.
2551   */
2552  public String toPEMString()
2553  {
2554    final StringBuilder buffer = new StringBuilder();
2555    buffer.append("-----BEGIN CERTIFICATE-----");
2556    buffer.append(StaticUtils.EOL);
2557
2558    final String certBase64 = Base64.encode(x509CertificateBytes);
2559    for (final String line : StaticUtils.wrapLine(certBase64, 64))
2560    {
2561      buffer.append(line);
2562      buffer.append(StaticUtils.EOL);
2563    }
2564    buffer.append("-----END CERTIFICATE-----");
2565    buffer.append(StaticUtils.EOL);
2566
2567    return buffer.toString();
2568  }
2569}