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.Serializable;
026import java.security.KeyFactory;
027import java.security.KeyPair;
028import java.security.MessageDigest;
029import java.security.PrivateKey;
030import java.security.PublicKey;
031import java.security.Signature;
032import java.security.spec.X509EncodedKeySpec;
033import java.util.ArrayList;
034import java.util.Collections;
035import java.util.Iterator;
036import java.util.List;
037
038import com.unboundid.asn1.ASN1BitString;
039import com.unboundid.asn1.ASN1Element;
040import com.unboundid.asn1.ASN1Integer;
041import com.unboundid.asn1.ASN1ObjectIdentifier;
042import com.unboundid.asn1.ASN1OctetString;
043import com.unboundid.asn1.ASN1Sequence;
044import com.unboundid.asn1.ASN1Set;
045import com.unboundid.ldap.sdk.DN;
046import com.unboundid.util.Base64;
047import com.unboundid.util.Debug;
048import com.unboundid.util.NotMutable;
049import com.unboundid.util.ObjectPair;
050import com.unboundid.util.OID;
051import com.unboundid.util.StaticUtils;
052import com.unboundid.util.ThreadSafety;
053import com.unboundid.util.ThreadSafetyLevel;
054
055import static com.unboundid.util.ssl.cert.CertMessages.*;
056
057
058
059/**
060 * This class provides support for decoding a PKCS #10 certificate signing
061 * request (aka certification request or CSR) as defined in
062 * <A HREF="https://www.ietf.org/rfc/rfc2986.txt">RFC 2986</A>.  The certificate
063 * signing request is encoded using the ASN.1 Distinguished Encoding Rules
064 * (DER), which is a subset of BER, and is supported by the code in the
065 * {@code com.unboundid.asn1} package.  The ASN.1 specification is as follows:
066 * <PRE>
067 *   CertificationRequest ::= SEQUENCE {
068 *        certificationRequestInfo CertificationRequestInfo,
069 *        signatureAlgorithm AlgorithmIdentifier,
070 *        signature          BIT STRING
071 *   }
072 *
073 *   CertificationRequestInfo ::= SEQUENCE {
074 *        version       INTEGER { v1(0) } (v1,...),
075 *        subject       Name,
076 *        subjectPKInfo SubjectPublicKeyInfo,
077 *        attributes    [0] Attributes
078 *   }
079 *
080 *   SubjectPublicKeyInfo ::= SEQUENCE {
081 *        algorithm        AlgorithmIdentifier,
082 *        subjectPublicKey BIT STRING
083 *   }
084 *
085 *   PKInfoAlgorithms ALGORITHM ::= {
086 *        ...  -- add any locally defined algorithms here -- }
087 *
088 *   Attributes ::= SET OF Attribute
089 *
090 *   CRIAttributes  ATTRIBUTE  ::= {
091 *        ... -- add any locally defined attributes here -- }
092 *
093 *   Attribute ::= SEQUENCE {
094 *        type   OBJECT IDENTIFIER,
095 *        values SET SIZE(1..MAX)
096 *   }
097 *
098 *   AlgorithmIdentifier ::= SEQUENCE {
099 *        algorithm          OBJECT IDENTIFIER,
100 *        parameters         ANY OPTIONAL
101 *   }
102 *
103 *   SignatureAlgorithms ALGORITHM ::= {
104 *        ... -- add any locally defined algorithms here -- }
105 * </PRE>
106 */
107@NotMutable()
108@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
109public final class PKCS10CertificateSigningRequest
110       implements Serializable
111{
112  /**
113   * The DER type for the attributes element.
114   */
115  private static final byte TYPE_ATTRIBUTES = (byte) 0xA0;
116
117
118
119  /**
120   * The OID for the request attribute that holds the set of requested
121   * certificate extensions.
122   */
123  private static final OID  ATTRIBUTE_OID_EXTENSIONS =
124       new OID("1.2.840.113549.1.9.14");
125
126
127
128  /**
129   * The serial version UID for this serializable class.
130   */
131  private static final long serialVersionUID = -1665446530589389194L;
132
133
134
135  // The signature value for the request.
136  private final ASN1BitString signatureValue;
137
138  // The encoded public key for the request.
139  private final ASN1BitString encodedPublicKey;
140
141  // The ASN.1 element with the encoded public key algorithm parameters.
142  private final ASN1Element publicKeyAlgorithmParameters;
143
144  // The ASN.1 element with the encoded signature algorithm parameters.
145  private final ASN1Element signatureAlgorithmParameters;
146
147  // The bytes that comprise the encoded representation of the PKCS #10
148  // certificate signing request.
149  private final byte[] pkcs10CertificateSigningRequestBytes;
150
151  // The decoded public key for this request, if available.
152  private final DecodedPublicKey decodedPublicKey;
153
154  // The subject DN for the request.
155  private final DN subjectDN;
156
157  // The list of attributes for the request.
158  private final List<ObjectPair<OID,ASN1Set>> requestAttributes;
159
160  // The list of extensions for the request.
161  private final List<X509CertificateExtension> extensions;
162
163  // The OID for the public key algorithm.
164  private final OID publicKeyAlgorithmOID;
165
166  // The OID for the signature algorithm.
167  private final OID signatureAlgorithmOID;
168
169  // The PKCS #10 certificate signing request version.
170  private final PKCS10CertificateSigningRequestVersion version;
171
172  // The public key algorithm name that corresponds with the public key
173  // algorithm OID, if available.
174  private final String publicKeyAlgorithmName;
175
176  // The signature algorithm name that corresponds with the signature algorithm
177  // OID, if available.
178  private final String signatureAlgorithmName;
179
180
181
182  /**
183   * Creates a new PKCS #10 certificate signing request with the provided
184   * information.  This is primarily intended for unit testing and other
185   * internal use.
186   *
187   * @param  version                       The version number for the
188   *                                       certificate signing request.
189   * @param  signatureAlgorithmOID         The signature algorithm OID for the
190   *                                       request.  This must not be
191   *                                       {@code null}.
192   * @param  signatureAlgorithmParameters  The encoded signature algorithm
193   *                                       parameters for the request.  This
194   *                                       may be {@code null} if there are no
195   *                                       parameters.
196   * @param  signatureValue                The encoded signature for the
197   *                                       request.  This must not be
198   *                                       {@code null}.
199   * @param  subjectDN                     The subject DN for the request.  This
200   *                                       This must not be {@code null}.
201   * @param  publicKeyAlgorithmOID         The OID of the public key algorithm
202   *                                       for the request.  This must not be
203   *                                       {@code null}.
204   * @param  publicKeyAlgorithmParameters  The encoded public key algorithm
205   *                                       parameters for the request.  This may
206   *                                       be {@code null} if there are no
207   *                                       parameters.
208   * @param  encodedPublicKey              The encoded public key for the
209   *                                       request.  This must not be
210   *                                       {@code null}.
211   * @param  decodedPublicKey              The decoded public key for the
212   *                                       request.  This may be {@code null} if
213   *                                       it is not available.
214   * @param  nonExtensionAttributes        Any attributes to include in the
215   *                                       request other than the set of
216   *                                       extensions.  This may be {@code null}
217   *                                       or empty if no additional attributes
218   *                                       are needed.
219   * @param  extensions                    The set of extensions included in the
220   *                                       request.  This must not be
221   *                                       {@code null} but may be empty.
222   *
223   * @throws  CertException  If a problem is encountered while creating the
224   *                         certificate signing request.
225   */
226  PKCS10CertificateSigningRequest(
227       final PKCS10CertificateSigningRequestVersion version,
228       final OID signatureAlgorithmOID,
229       final ASN1Element signatureAlgorithmParameters,
230       final ASN1BitString signatureValue,
231       final DN subjectDN, final OID publicKeyAlgorithmOID,
232       final ASN1Element publicKeyAlgorithmParameters,
233       final ASN1BitString encodedPublicKey,
234       final DecodedPublicKey decodedPublicKey,
235       final List<ObjectPair<OID,ASN1Set>> nonExtensionAttributes,
236       final X509CertificateExtension... extensions)
237       throws CertException
238  {
239    this.version = version;
240    this.signatureAlgorithmOID = signatureAlgorithmOID;
241    this.signatureAlgorithmParameters = signatureAlgorithmParameters;
242    this.signatureValue = signatureValue;
243    this.subjectDN = subjectDN;
244    this.publicKeyAlgorithmOID = publicKeyAlgorithmOID;
245    this.publicKeyAlgorithmParameters = publicKeyAlgorithmParameters;
246    this.encodedPublicKey = encodedPublicKey;
247    this.decodedPublicKey = decodedPublicKey;
248    this.extensions = StaticUtils.toList(extensions);
249
250    final SignatureAlgorithmIdentifier signatureAlgorithmIdentifier =
251         SignatureAlgorithmIdentifier.forOID(signatureAlgorithmOID);
252    if (signatureAlgorithmIdentifier == null)
253    {
254      signatureAlgorithmName = null;
255    }
256    else
257    {
258      signatureAlgorithmName =
259           signatureAlgorithmIdentifier.getUserFriendlyName();
260    }
261
262    final PublicKeyAlgorithmIdentifier publicKeyAlgorithmIdentifier =
263         PublicKeyAlgorithmIdentifier.forOID(publicKeyAlgorithmOID);
264    if (publicKeyAlgorithmIdentifier == null)
265    {
266      publicKeyAlgorithmName = null;
267    }
268    else
269    {
270      publicKeyAlgorithmName = publicKeyAlgorithmIdentifier.getName();
271    }
272
273    final ArrayList<ObjectPair<OID, ASN1Set>> attrs = new ArrayList<>(10);
274    if (nonExtensionAttributes != null)
275    {
276      attrs.addAll(nonExtensionAttributes);
277    }
278
279    if (extensions.length > 0)
280    {
281      final ArrayList<ASN1Element> extensionElements =
282           new ArrayList<>(extensions.length);
283      for (final X509CertificateExtension e : extensions)
284      {
285        extensionElements.add(e.encode());
286      }
287
288      attrs.add(new ObjectPair<>(ATTRIBUTE_OID_EXTENSIONS,
289           new ASN1Set(new ASN1Sequence(extensionElements))));
290    }
291
292    requestAttributes = Collections.unmodifiableList(attrs);
293
294    pkcs10CertificateSigningRequestBytes = encode().encode();
295  }
296
297
298
299  /**
300   * Decodes the contents of the provided byte array as a PKCS #10 certificate
301   * signing request.
302   *
303   * @param  encodedRequest  The byte array containing the encoded PKCS #10
304   *                         certificate signing request.  This must not be
305   *                         {@code null}.
306   *
307   * @throws  CertException  If the contents of the provided byte array could
308   *                         not be decoded as a valid PKCS #10 certificate
309   *                         signing request.
310   */
311  public PKCS10CertificateSigningRequest(final byte[] encodedRequest)
312         throws CertException
313  {
314    pkcs10CertificateSigningRequestBytes = encodedRequest;
315
316    final ASN1Element[] requestElements;
317    try
318    {
319      requestElements =
320           ASN1Sequence.decodeAsSequence(encodedRequest).elements();
321    }
322    catch (final Exception e)
323    {
324      Debug.debugException(e);
325      throw new CertException(
326           ERR_CSR_DECODE_NOT_SEQUENCE.get(StaticUtils.getExceptionMessage(e)),
327           e);
328    }
329
330    if (requestElements.length != 3)
331    {
332      throw new CertException(
333           ERR_CSR_DECODE_UNEXPECTED_SEQUENCE_ELEMENT_COUNT.get(
334                requestElements.length));
335    }
336
337    final ASN1Element[] requestInfoElements;
338    try
339    {
340      requestInfoElements =
341           ASN1Sequence.decodeAsSequence(requestElements[0]).elements();
342    }
343    catch (final Exception e)
344    {
345      Debug.debugException(e);
346      throw new CertException(
347           ERR_CSR_DECODE_FIRST_ELEMENT_NOT_SEQUENCE.get(
348                StaticUtils.getExceptionMessage(e)),
349           e);
350    }
351
352    try
353    {
354      final int versionIntValue =
355           requestInfoElements[0].decodeAsInteger().intValue();
356      version = PKCS10CertificateSigningRequestVersion.valueOf(versionIntValue);
357      if (version == null)
358      {
359        throw new CertException(
360             ERR_CSR_DECODE_UNSUPPORTED_VERSION.get(version));
361      }
362    }
363    catch (final CertException e)
364    {
365      Debug.debugException(e);
366      throw e;
367    }
368    catch (final Exception e)
369    {
370      Debug.debugException(e);
371      throw new CertException(
372           ERR_CSR_DECODE_CANNOT_PARSE_VERSION.get(
373                StaticUtils.getExceptionMessage(e)),
374           e);
375    }
376
377    try
378    {
379      subjectDN = X509Certificate.decodeName(requestInfoElements[1]);
380    }
381    catch (final Exception e)
382    {
383      Debug.debugException(e);
384      throw new CertException(
385           ERR_CSR_DECODE_CANNOT_PARSE_SUBJECT_DN.get(
386                StaticUtils.getExceptionMessage(e)),
387           e);
388    }
389
390    try
391    {
392      final ASN1Element[] subjectPublicKeyInfoElements =
393           requestInfoElements[2].decodeAsSequence().elements();
394      final ASN1Element[] publicKeyAlgorithmElements =
395           subjectPublicKeyInfoElements[0].decodeAsSequence().elements();
396      publicKeyAlgorithmOID =
397           publicKeyAlgorithmElements[0].decodeAsObjectIdentifier().getOID();
398      if (publicKeyAlgorithmElements.length > 1)
399      {
400        publicKeyAlgorithmParameters = publicKeyAlgorithmElements[1];
401      }
402      else
403      {
404        publicKeyAlgorithmParameters = null;
405      }
406
407      encodedPublicKey = subjectPublicKeyInfoElements[1].decodeAsBitString();
408    }
409    catch (final Exception e)
410    {
411      Debug.debugException(e);
412      throw new CertException(
413           ERR_CSR_DECODE_CANNOT_PARSE_PUBLIC_KEY_INFO.get(
414                StaticUtils.getExceptionMessage(e)),
415           e);
416    }
417
418    final PublicKeyAlgorithmIdentifier publicKeyAlgorithmIdentifier =
419         PublicKeyAlgorithmIdentifier.forOID(publicKeyAlgorithmOID);
420    if (publicKeyAlgorithmIdentifier == null)
421    {
422      publicKeyAlgorithmName = null;
423      decodedPublicKey = null;
424    }
425    else
426    {
427      publicKeyAlgorithmName = publicKeyAlgorithmIdentifier.getName();
428
429      DecodedPublicKey pk = null;
430      switch (publicKeyAlgorithmIdentifier)
431      {
432        case RSA:
433          try
434          {
435            pk = new RSAPublicKey(encodedPublicKey);
436          }
437          catch (final Exception e)
438          {
439            Debug.debugException(e);
440          }
441          break;
442
443        case EC:
444          try
445          {
446            pk = new EllipticCurvePublicKey(encodedPublicKey);
447          }
448          catch (final Exception e)
449          {
450            Debug.debugException(e);
451          }
452          break;
453      }
454
455      decodedPublicKey = pk;
456    }
457
458    final ArrayList<ObjectPair<OID,ASN1Set>> attrList = new ArrayList<>(10);
459    final ArrayList<X509CertificateExtension> extList = new ArrayList<>(10);
460    if (requestInfoElements.length > 3)
461    {
462      for (int i=3; i < requestInfoElements.length; i++)
463      {
464        final ASN1Element element = requestInfoElements[i];
465        if (element.getType() == TYPE_ATTRIBUTES)
466        {
467          try
468          {
469            for (final ASN1Element attrSetElement :
470                 element.decodeAsSet().elements())
471            {
472              final ASN1Element[] attrElements =
473                   attrSetElement.decodeAsSequence().elements();
474              final OID attrOID =
475                   attrElements[0].decodeAsObjectIdentifier().getOID();
476              final ASN1Set attrValues = attrElements[1].decodeAsSet();
477              attrList.add(new ObjectPair<>(attrOID, attrValues));
478            }
479          }
480          catch (final Exception e)
481          {
482            Debug.debugException(e);
483            throw new CertException(
484                 ERR_CSR_DECODE_CANNOT_PARSE_ATTRS.get(
485                      StaticUtils.getExceptionMessage(e)),
486                 e);
487          }
488
489          for (final ObjectPair<OID,ASN1Set> p : attrList)
490          {
491            if (p.getFirst().equals(ATTRIBUTE_OID_EXTENSIONS))
492            {
493              try
494              {
495                for (final ASN1Element extElement :
496                     p.getSecond().elements()[0].decodeAsSequence().elements())
497                {
498                  extList.add(X509CertificateExtension.decode(extElement));
499                }
500              }
501              catch (final Exception e)
502              {
503                Debug.debugException(e);
504                throw new CertException(
505                     ERR_CSR_DECODE_CANNOT_PARSE_EXT_ATTR.get(
506                          p.getFirst(), StaticUtils.getExceptionMessage(e)),
507                     e);
508              }
509            }
510          }
511        }
512      }
513    }
514
515    requestAttributes = Collections.unmodifiableList(attrList);
516    extensions = Collections.unmodifiableList(extList);
517
518
519    try
520    {
521      final ASN1Element[] signatureAlgorithmElements =
522           requestElements[1].decodeAsSequence().elements();
523      signatureAlgorithmOID =
524           signatureAlgorithmElements[0].decodeAsObjectIdentifier().getOID();
525      if (signatureAlgorithmElements.length > 1)
526      {
527        signatureAlgorithmParameters = signatureAlgorithmElements[1];
528      }
529      else
530      {
531        signatureAlgorithmParameters = null;
532      }
533    }
534    catch (final Exception e)
535    {
536      Debug.debugException(e);
537      throw new CertException(
538           ERR_CSR_DECODE_CANNOT_PARSE_SIG_ALG.get(
539                StaticUtils.getExceptionMessage(e)),
540           e);
541    }
542
543    final SignatureAlgorithmIdentifier signatureAlgorithmIdentifier =
544         SignatureAlgorithmIdentifier.forOID(signatureAlgorithmOID);
545    if (signatureAlgorithmIdentifier == null)
546    {
547      signatureAlgorithmName = null;
548    }
549    else
550    {
551      signatureAlgorithmName =
552           signatureAlgorithmIdentifier.getUserFriendlyName();
553    }
554
555    try
556    {
557      signatureValue = requestElements[2].decodeAsBitString();
558    }
559    catch (final Exception e)
560    {
561      Debug.debugException(e);
562      throw new CertException(
563           ERR_CSR_DECODE_CANNOT_PARSE_SIG_VALUE.get(
564                StaticUtils.getExceptionMessage(e)),
565           e);
566    }
567  }
568
569
570
571  /**
572   * Encodes this PKCS #10 certificate signing request to an ASN.1 element.
573   *
574   * @return  The encoded PKCS #10 certificate signing request.
575   *
576   * @throws  CertException  If a problem is encountered while trying to encode
577   *                         the PKCS #10 certificate signing request.
578   */
579  private ASN1Element encode()
580          throws CertException
581  {
582    try
583    {
584      final ArrayList<ASN1Element> requestInfoElements = new ArrayList<>(4);
585      requestInfoElements.add(new ASN1Integer(version.getIntValue()));
586      requestInfoElements.add(X509Certificate.encodeName(subjectDN));
587
588      if (publicKeyAlgorithmParameters == null)
589      {
590        requestInfoElements.add(new ASN1Sequence(
591             new ASN1Sequence(
592                  new ASN1ObjectIdentifier(publicKeyAlgorithmOID)),
593             encodedPublicKey));
594      }
595      else
596      {
597        requestInfoElements.add(new ASN1Sequence(
598             new ASN1Sequence(
599                  new ASN1ObjectIdentifier(publicKeyAlgorithmOID),
600                  publicKeyAlgorithmParameters),
601             encodedPublicKey));
602      }
603
604      final ArrayList<ASN1Element> attrElements =
605           new ArrayList<>(requestAttributes.size());
606      for (final ObjectPair<OID,ASN1Set> attr : requestAttributes)
607      {
608        attrElements.add(
609             new ASN1Sequence(
610                  new ASN1ObjectIdentifier(attr.getFirst()),
611                  attr.getSecond()));
612      }
613
614      requestInfoElements.add(new ASN1Set(TYPE_ATTRIBUTES, attrElements));
615
616
617      final ArrayList<ASN1Element> certificationRequestElements =
618           new ArrayList<>(3);
619      certificationRequestElements.add(new ASN1Sequence(requestInfoElements));
620
621      if (signatureAlgorithmParameters == null)
622      {
623        certificationRequestElements.add(new ASN1Sequence(
624             new ASN1ObjectIdentifier(signatureAlgorithmOID)));
625      }
626      else
627      {
628        certificationRequestElements.add(new ASN1Sequence(
629             new ASN1ObjectIdentifier(signatureAlgorithmOID),
630             signatureAlgorithmParameters));
631      }
632
633      certificationRequestElements.add(signatureValue);
634
635      return new ASN1Sequence(certificationRequestElements);
636    }
637    catch (final Exception e)
638    {
639      Debug.debugException(e);
640      throw new CertException(
641           ERR_CSR_ENCODE_ERROR.get(toString(),
642                StaticUtils.getExceptionMessage(e)),
643           e);
644    }
645  }
646
647
648
649  /**
650   * Generates a PKCS #10 certificate signing request with the provided
651   * information.
652   *
653   * @param  signatureAlgorithm  The algorithm to use to generate the signature.
654   *                             This must not be {@code null}.
655   * @param  keyPair             The key pair to use for the certificate signing
656   *                             request.  This must not be {@code null}.
657   * @param  subjectDN           The subject DN for the certificate signing
658   *                             request.  This must not be {@code null}.
659   * @param  extensions          The set of extensions to include in the
660   *                             certificate signing request.  This may be
661   *                             {@code null} or empty if the request should not
662   *                             include any custom extensions.
663   *
664   * @return  The generated PKCS #10 certificate signing request.
665   *
666   * @throws  CertException  If a problem is encountered while creating the
667   *                         certificate signing request.
668   */
669  public static PKCS10CertificateSigningRequest
670              generateCertificateSigningRequest(
671                   final SignatureAlgorithmIdentifier signatureAlgorithm,
672                   final KeyPair keyPair, final DN subjectDN,
673                   final X509CertificateExtension... extensions)
674         throws CertException
675  {
676    // Extract the parameters and encoded public key from the generated key
677    // pair.  And while we're at it, generate a subject key identifier from
678    // the encoded public key.
679    DecodedPublicKey decodedPublicKey = null;
680    final ASN1BitString encodedPublicKey;
681    final ASN1Element publicKeyAlgorithmParameters;
682    final byte[] subjectKeyIdentifier;
683    final OID publicKeyAlgorithmOID;
684    try
685    {
686      final ASN1Element[] pkElements = ASN1Sequence.decodeAsSequence(
687           keyPair.getPublic().getEncoded()).elements();
688      final ASN1Element[] pkAlgIDElements = ASN1Sequence.decodeAsSequence(
689           pkElements[0]).elements();
690      publicKeyAlgorithmOID =
691           pkAlgIDElements[0].decodeAsObjectIdentifier().getOID();
692      if (pkAlgIDElements.length == 1)
693      {
694        publicKeyAlgorithmParameters = null;
695      }
696      else
697      {
698        publicKeyAlgorithmParameters = pkAlgIDElements[1];
699      }
700
701      encodedPublicKey = pkElements[1].decodeAsBitString();
702
703      try
704      {
705        if (publicKeyAlgorithmOID.equals(
706             PublicKeyAlgorithmIdentifier.RSA.getOID()))
707        {
708          decodedPublicKey = new RSAPublicKey(encodedPublicKey);
709        }
710        else if (publicKeyAlgorithmOID.equals(
711             PublicKeyAlgorithmIdentifier.EC.getOID()))
712        {
713          decodedPublicKey = new EllipticCurvePublicKey(encodedPublicKey);
714        }
715      }
716      catch (final Exception e)
717      {
718        Debug.debugException(e);
719      }
720
721      final MessageDigest sha256 = MessageDigest.getInstance(
722           SubjectKeyIdentifierExtension.
723                SUBJECT_KEY_IDENTIFIER_DIGEST_ALGORITHM);
724      subjectKeyIdentifier = sha256.digest(encodedPublicKey.getBytes());
725    }
726    catch (final Exception e)
727    {
728      Debug.debugException(e);
729      throw new CertException(
730           ERR_CSR_GEN_CANNOT_PARSE_KEY_PAIR.get(
731                StaticUtils.getExceptionMessage(e)),
732           e);
733    }
734
735
736    // Construct the set of all extensions for the certificate.
737    final ArrayList<X509CertificateExtension> extensionList =
738         new ArrayList<>(10);
739    extensionList.add(new SubjectKeyIdentifierExtension(false,
740         new ASN1OctetString(subjectKeyIdentifier)));
741    if (extensions != null)
742    {
743      for (final X509CertificateExtension e : extensions)
744      {
745        if (! e.getOID().equals(SubjectKeyIdentifierExtension.
746             SUBJECT_KEY_IDENTIFIER_OID))
747        {
748          extensionList.add(e);
749        }
750      }
751    }
752
753    final X509CertificateExtension[] allExtensions =
754         new X509CertificateExtension[extensionList.size()];
755    extensionList.toArray(allExtensions);
756
757
758    final ASN1BitString encodedSignature = generateSignature(signatureAlgorithm,
759         keyPair.getPrivate(), subjectDN, publicKeyAlgorithmOID,
760         publicKeyAlgorithmParameters, encodedPublicKey, allExtensions);
761
762    return new PKCS10CertificateSigningRequest(
763         PKCS10CertificateSigningRequestVersion.V1, signatureAlgorithm.getOID(),
764         null, encodedSignature, subjectDN, publicKeyAlgorithmOID,
765         publicKeyAlgorithmParameters, encodedPublicKey, decodedPublicKey,
766         null, allExtensions);
767  }
768
769
770
771  /**
772   * Generates a signature for the certificate signing request with the provided
773   * information.
774   *
775   * @param  signatureAlgorithm            The signature algorithm to use to
776   *                                       generate the signature.  This must
777   *                                       not be {@code null}.
778   * @param  privateKey                    The private key to use to sign the
779   *                                       certificate signing request.  This
780   *                                       must not be {@code null}.
781   * @param  subjectDN                     The subject DN for the certificate
782   *                                       signing request.  This must not be
783   *                                       {@code null}.
784   * @param  publicKeyAlgorithmOID         The OID for the public key algorithm.
785   *                                       This must not be {@code null}.
786   * @param  publicKeyAlgorithmParameters  The encoded public key algorithm
787   *                                       parameters.  This may be
788   *                                       {@code null} if no parameters are
789   *                                       needed.
790   * @param  encodedPublicKey              The encoded representation of the
791   *                                       public key.  This must not be
792   *                                       {@code null}.
793   * @param  extensions                    The set of extensions to include in
794   *                                       the certificate signing request.
795   *                                       This must not be {@code null} but
796   *                                       may be empty.
797   *
798   * @return  An encoded representation of the generated signature.
799   *
800   * @throws  CertException  If a problem is encountered while generating the
801   *                         certificate.
802   */
803  private static ASN1BitString generateSignature(
804                      final SignatureAlgorithmIdentifier signatureAlgorithm,
805                      final PrivateKey privateKey, final DN subjectDN,
806                      final OID publicKeyAlgorithmOID,
807                      final ASN1Element publicKeyAlgorithmParameters,
808                      final ASN1BitString encodedPublicKey,
809                      final X509CertificateExtension... extensions)
810          throws CertException
811  {
812    // Get and initialize the signature generator.
813    final Signature signature;
814    try
815    {
816      signature = Signature.getInstance(signatureAlgorithm.getJavaName());
817    }
818    catch (final Exception e)
819    {
820      Debug.debugException(e);
821      throw new CertException(
822           ERR_CSR_GEN_SIGNATURE_CANNOT_GET_SIGNATURE_GENERATOR.get(
823                signatureAlgorithm.getJavaName(),
824                StaticUtils.getExceptionMessage(e)),
825           e);
826    }
827
828    try
829    {
830      signature.initSign(privateKey);
831    }
832    catch (final Exception e)
833    {
834      Debug.debugException(e);
835      throw new CertException(
836           ERR_CSR_GEN_SIGNATURE_CANNOT_INIT_SIGNATURE_GENERATOR.get(
837                signatureAlgorithm.getJavaName(),
838                StaticUtils.getExceptionMessage(e)),
839           e);
840    }
841
842
843    // Construct the requestInfo element of the certificate signing request and
844    // compute its signature.
845    try
846    {
847      final ArrayList<ASN1Element> requestInfoElements = new ArrayList<>(4);
848      requestInfoElements.add(new ASN1Integer(
849           PKCS10CertificateSigningRequestVersion.V1.getIntValue()));
850      requestInfoElements.add(X509Certificate.encodeName(subjectDN));
851
852      if (publicKeyAlgorithmParameters == null)
853      {
854        requestInfoElements.add(new ASN1Sequence(
855             new ASN1Sequence(
856                  new ASN1ObjectIdentifier(publicKeyAlgorithmOID)),
857             encodedPublicKey));
858      }
859      else
860      {
861        requestInfoElements.add(new ASN1Sequence(
862             new ASN1Sequence(
863                  new ASN1ObjectIdentifier(publicKeyAlgorithmOID),
864                  publicKeyAlgorithmParameters),
865             encodedPublicKey));
866      }
867
868      final ArrayList<ASN1Element> attrElements = new ArrayList<>(1);
869      if ((extensions != null) && (extensions.length > 0))
870      {
871        final ArrayList<ASN1Element> extensionElements =
872             new ArrayList<>(extensions.length);
873        for (final X509CertificateExtension e : extensions)
874        {
875          extensionElements.add(e.encode());
876        }
877
878        attrElements.add(new ASN1Sequence(
879             new ASN1ObjectIdentifier(ATTRIBUTE_OID_EXTENSIONS),
880             new ASN1Set(new ASN1Sequence(extensionElements))));
881      }
882      requestInfoElements.add(new ASN1Set(TYPE_ATTRIBUTES, attrElements));
883
884      final byte[] certificationRequestInfoBytes =
885           new ASN1Sequence(requestInfoElements).encode();
886      signature.update(certificationRequestInfoBytes);
887      final byte[] signatureBytes = signature.sign();
888
889      return new ASN1BitString(ASN1BitString.getBitsForBytes(signatureBytes));
890    }
891    catch (final Exception e)
892    {
893      Debug.debugException(e);
894      throw new CertException(
895           ERR_CSR_GEN_SIGNATURE_CANNOT_COMPUTE.get(
896                signatureAlgorithm.getJavaName(),
897                StaticUtils.getExceptionMessage(e)),
898           e);
899    }
900  }
901
902
903
904  /**
905   * Retrieves the bytes that comprise the encoded representation of this
906   * PKCS #10 certificate signing request.
907   *
908   * @return  The bytes that comprise the encoded representation of this
909   *          PKCS #10 certificate signing request.
910   */
911  public byte[] getPKCS10CertificateSigningRequestBytes()
912  {
913    return pkcs10CertificateSigningRequestBytes;
914  }
915
916
917
918  /**
919   * Retrieves the certificate signing request version.
920   *
921   * @return  The certificate signing request version.
922   */
923  public PKCS10CertificateSigningRequestVersion getVersion()
924  {
925    return version;
926  }
927
928
929
930  /**
931   * Retrieves the certificate signing request signature algorithm OID.
932   *
933   * @return  The certificate signing request signature algorithm OID.
934   */
935  public OID getSignatureAlgorithmOID()
936  {
937    return signatureAlgorithmOID;
938  }
939
940
941
942  /**
943   * Retrieves the certificate signing request signature algorithm name, if
944   * available.
945   *
946   * @return  The certificate signing request signature algorithm name, or
947   *          {@code null} if the signature algorithm OID does not correspond to
948   *          any known algorithm name.
949   */
950  public String getSignatureAlgorithmName()
951  {
952    return signatureAlgorithmName;
953  }
954
955
956
957  /**
958   * Retrieves the signature algorithm name if it is available, or the string
959   * representation of the signature algorithm OID if not.
960   *
961   * @return  The signature algorithm name or OID.
962   */
963  public String getSignatureAlgorithmNameOrOID()
964  {
965    if (signatureAlgorithmName != null)
966    {
967      return signatureAlgorithmName;
968    }
969    else
970    {
971      return signatureAlgorithmOID.toString();
972    }
973  }
974
975
976
977  /**
978   * Retrieves the encoded signature algorithm parameters, if present.
979   *
980   * @return  The encoded signature algorithm parameters, or {@code null} if
981   *          there are no signature algorithm parameters.
982   */
983  public ASN1Element getSignatureAlgorithmParameters()
984  {
985    return signatureAlgorithmParameters;
986  }
987
988
989
990  /**
991   * Retrieves the certificate signing request subject DN.
992   *
993   * @return  The certificate signing request subject DN.
994   */
995  public DN getSubjectDN()
996  {
997    return subjectDN;
998  }
999
1000
1001
1002  /**
1003   * Retrieves the certificate signing request public key algorithm OID.
1004   *
1005   * @return  The certificate signing request public key algorithm OID.
1006   */
1007  public OID getPublicKeyAlgorithmOID()
1008  {
1009    return publicKeyAlgorithmOID;
1010  }
1011
1012
1013
1014  /**
1015   * Retrieves the certificate signing request public key algorithm name, if
1016   * available.
1017   *
1018   * @return  The certificate signing request public key algorithm name, or
1019   *          {@code null} if the public key algorithm OID does not correspond
1020   *          to any known algorithm name.
1021   */
1022  public String getPublicKeyAlgorithmName()
1023  {
1024    return publicKeyAlgorithmName;
1025  }
1026
1027
1028
1029  /**
1030   * Retrieves the public key algorithm name if it is available, or the string
1031   * representation of the public key algorithm OID if not.
1032   *
1033   * @return  The signature algorithm name or OID.
1034   */
1035  public String getPublicKeyAlgorithmNameOrOID()
1036  {
1037    if (publicKeyAlgorithmName != null)
1038    {
1039      return publicKeyAlgorithmName;
1040    }
1041    else
1042    {
1043      return publicKeyAlgorithmOID.toString();
1044    }
1045  }
1046
1047
1048
1049  /**
1050   * Retrieves the encoded public key algorithm parameters, if present.
1051   *
1052   * @return  The encoded public key algorithm parameters, or {@code null} if
1053   *          there are no public key algorithm parameters.
1054   */
1055  public ASN1Element getPublicKeyAlgorithmParameters()
1056  {
1057    return publicKeyAlgorithmParameters;
1058  }
1059
1060
1061
1062  /**
1063   * Retrieves the encoded public key as a bit string.
1064   *
1065   * @return  The encoded public key as a bit string.
1066   */
1067  public ASN1BitString getEncodedPublicKey()
1068  {
1069    return encodedPublicKey;
1070  }
1071
1072
1073
1074  /**
1075   * Retrieves a decoded representation of the public key, if available.
1076   *
1077   * @return  A decoded representation of the public key, or {@code null} if the
1078   *          public key could not be decoded.
1079   */
1080  public DecodedPublicKey getDecodedPublicKey()
1081  {
1082    return decodedPublicKey;
1083  }
1084
1085
1086
1087  /**
1088   * Retrieves the encoded request attributes included in the certificate
1089   * signing request.
1090   *
1091   * @return  The encoded request attributes included in the certificate signing
1092   *          request.
1093   */
1094  public List<ObjectPair<OID,ASN1Set>> getRequestAttributes()
1095  {
1096    return requestAttributes;
1097  }
1098
1099
1100
1101  /**
1102   * Retrieves the list of certificate extensions included in the certificate
1103   * signing request.
1104   *
1105   * @return  The list of certificate extensions included in the certificate
1106   *          signing request.
1107   */
1108  public List<X509CertificateExtension> getExtensions()
1109  {
1110    return extensions;
1111  }
1112
1113
1114
1115  /**
1116   * Retrieves the signature value for the certificate signing request.
1117   *
1118   * @return  The signature value for the certificate signing request.
1119   */
1120  public ASN1BitString getSignatureValue()
1121  {
1122    return signatureValue;
1123  }
1124
1125
1126
1127  /**
1128   * Verifies the signature for this certificate signing request.
1129   *
1130   * @throws  CertException  If the certificate signing request's signature
1131   *                         could not be verified.
1132   */
1133  public void verifySignature()
1134         throws CertException
1135  {
1136    // Generate the public key for this certificate signing request.
1137    final PublicKey publicKey;
1138    try
1139    {
1140      final byte[] encodedPublicKeyBytes;
1141      if (publicKeyAlgorithmParameters == null)
1142      {
1143        encodedPublicKeyBytes = new ASN1Sequence(
1144             new ASN1Sequence(
1145                  new ASN1ObjectIdentifier(publicKeyAlgorithmOID)),
1146             encodedPublicKey).encode();
1147      }
1148      else
1149      {
1150        encodedPublicKeyBytes = new ASN1Sequence(
1151             new ASN1Sequence(
1152                  new ASN1ObjectIdentifier(publicKeyAlgorithmOID),
1153                  publicKeyAlgorithmParameters),
1154             encodedPublicKey).encode();
1155      }
1156
1157      final KeyFactory keyFactory =
1158           KeyFactory.getInstance(getPublicKeyAlgorithmNameOrOID());
1159      publicKey = keyFactory.generatePublic(
1160           new X509EncodedKeySpec(encodedPublicKeyBytes));
1161    }
1162    catch (final Exception e)
1163    {
1164      Debug.debugException(e);
1165      throw new CertException(
1166           ERR_CSR_VERIFY_SIGNATURE_CANNOT_GET_PUBLIC_KEY.get(
1167                StaticUtils.getExceptionMessage(e)),
1168           e);
1169    }
1170
1171
1172    // Get and initialize the signature generator.
1173    final Signature signature;
1174    final SignatureAlgorithmIdentifier signatureAlgorithm;
1175    try
1176    {
1177      signatureAlgorithm =
1178           SignatureAlgorithmIdentifier.forOID(signatureAlgorithmOID);
1179      signature = Signature.getInstance(signatureAlgorithm.getJavaName());
1180    }
1181    catch (final Exception e)
1182    {
1183      Debug.debugException(e);
1184      throw new CertException(
1185           ERR_CSR_VERIFY_SIGNATURE_CANNOT_GET_SIGNATURE_VERIFIER.get(
1186                getSignatureAlgorithmNameOrOID(),
1187                StaticUtils.getExceptionMessage(e)),
1188           e);
1189    }
1190
1191    try
1192    {
1193      signature.initVerify(publicKey);
1194    }
1195    catch (final Exception e)
1196    {
1197      Debug.debugException(e);
1198      throw new CertException(
1199           ERR_CSR_VERIFY_SIGNATURE_CANNOT_INIT_SIGNATURE_VERIFIER.get(
1200                signatureAlgorithm.getJavaName(),
1201                StaticUtils.getExceptionMessage(e)),
1202           e);
1203    }
1204
1205
1206    // Construct the requestInfo element of the certificate signing request and
1207    // compute its signature.
1208    final boolean signatureIsValid;
1209    try
1210    {
1211      final ASN1Element[] requestInfoElements =
1212           ASN1Sequence.decodeAsSequence(
1213                pkcs10CertificateSigningRequestBytes).elements();
1214      final byte[] requestInfoBytes = requestInfoElements[0].encode();
1215      signature.update(requestInfoBytes);
1216      signatureIsValid = signature.verify(signatureValue.getBytes());
1217    }
1218    catch (final Exception e)
1219    {
1220      Debug.debugException(e);
1221      throw new CertException(
1222           ERR_CSR_VERIFY_SIGNATURE_ERROR.get(subjectDN,
1223                StaticUtils.getExceptionMessage(e)),
1224           e);
1225    }
1226
1227    if (! signatureIsValid)
1228    {
1229      throw new CertException(
1230           ERR_CSR_VERIFY_SIGNATURE_NOT_VALID.get(subjectDN));
1231    }
1232  }
1233
1234
1235
1236  /**
1237   * Retrieves a string representation of the decoded X.509 certificate.
1238   *
1239   * @return  A string representation of the decoded X.509 certificate.
1240   */
1241  @Override()
1242  public String toString()
1243  {
1244    final StringBuilder buffer = new StringBuilder();
1245    toString(buffer);
1246    return buffer.toString();
1247  }
1248
1249
1250
1251  /**
1252   * Appends a string representation of the decoded X.509 certificate to the
1253   * provided buffer.
1254   *
1255   * @param  buffer  The buffer to which the information should be appended.
1256   */
1257  public void toString(final StringBuilder buffer)
1258  {
1259    buffer.append("PKCS10CertificateSigningRequest(version='");
1260    buffer.append(version.getName());
1261    buffer.append("', subjectDN='");
1262    buffer.append(subjectDN);
1263    buffer.append("', publicKeyAlgorithmOID='");
1264    buffer.append(publicKeyAlgorithmOID.toString());
1265    buffer.append('\'');
1266
1267    if (publicKeyAlgorithmName != null)
1268    {
1269      buffer.append(", publicKeyAlgorithmName='");
1270      buffer.append(publicKeyAlgorithmName);
1271      buffer.append('\'');
1272    }
1273
1274    buffer.append(", subjectPublicKey=");
1275    if (decodedPublicKey == null)
1276    {
1277      buffer.append('\'');
1278
1279      try
1280      {
1281        StaticUtils.toHex(encodedPublicKey.getBytes(), ":", buffer);
1282      }
1283      catch (final Exception e)
1284      {
1285        Debug.debugException(e);
1286        encodedPublicKey.toString(buffer);
1287      }
1288
1289      buffer.append('\'');
1290    }
1291    else
1292    {
1293      decodedPublicKey.toString(buffer);
1294
1295      if (decodedPublicKey instanceof EllipticCurvePublicKey)
1296      {
1297        try
1298        {
1299          final OID namedCurveOID =
1300               publicKeyAlgorithmParameters.decodeAsObjectIdentifier().getOID();
1301          buffer.append(", ellipticCurvePublicKeyParameters=namedCurve='");
1302          buffer.append(NamedCurve.getNameOrOID(namedCurveOID));
1303          buffer.append('\'');
1304        }
1305        catch (final Exception e)
1306        {
1307          Debug.debugException(e);
1308        }
1309      }
1310    }
1311
1312    buffer.append(", signatureAlgorithmOID='");
1313    buffer.append(signatureAlgorithmOID.toString());
1314    buffer.append('\'');
1315
1316    if (signatureAlgorithmName != null)
1317    {
1318      buffer.append(", signatureAlgorithmName='");
1319      buffer.append(signatureAlgorithmName);
1320      buffer.append('\'');
1321    }
1322
1323    if (! extensions.isEmpty())
1324    {
1325      buffer.append(", extensions={");
1326
1327      final Iterator<X509CertificateExtension> iterator = extensions.iterator();
1328      while (iterator.hasNext())
1329      {
1330        iterator.next().toString(buffer);
1331        if (iterator.hasNext())
1332        {
1333          buffer.append(", ");
1334        }
1335      }
1336
1337      buffer.append('}');
1338    }
1339
1340    buffer.append(", signatureValue='");
1341
1342    try
1343    {
1344      StaticUtils.toHex(signatureValue.getBytes(), ":", buffer);
1345    }
1346    catch (final Exception e)
1347    {
1348      Debug.debugException(e);
1349      buffer.append(signatureValue.toString());
1350    }
1351
1352    buffer.append("')");
1353  }
1354
1355
1356
1357  /**
1358   * Retrieves a list of the lines that comprise a PEM representation of this
1359   * PKCS #10 certificate signing request.
1360   *
1361   * @return  A list of the lines that comprise a PEM representation of this
1362   *          PKCS #10 certificate signing request.
1363   */
1364  public List<String> toPEM()
1365  {
1366    final ArrayList<String> lines = new ArrayList<>(10);
1367    lines.add("-----BEGIN CERTIFICATE REQUEST-----");
1368
1369    final String csrBase64 =
1370         Base64.encode(pkcs10CertificateSigningRequestBytes);
1371    lines.addAll(StaticUtils.wrapLine(csrBase64, 64));
1372
1373    lines.add("-----END CERTIFICATE REQUEST-----");
1374
1375    return Collections.unmodifiableList(lines);
1376  }
1377
1378
1379
1380  /**
1381   * Retrieves a multi-line string containing a PEM representation of this
1382   * PKCS #10 certificate signing request.
1383   *
1384   * @return  A multi-line string containing a PEM representation of this
1385   *          PKCS #10 certificate signing request.
1386   */
1387  public String toPEMString()
1388  {
1389    final StringBuilder buffer = new StringBuilder();
1390    buffer.append("-----BEGIN CERTIFICATE REQUEST-----");
1391    buffer.append(StaticUtils.EOL);
1392
1393    final String csrBase64 =
1394         Base64.encode(pkcs10CertificateSigningRequestBytes);
1395    for (final String line : StaticUtils.wrapLine(csrBase64, 64))
1396    {
1397      buffer.append(line);
1398      buffer.append(StaticUtils.EOL);
1399    }
1400    buffer.append("-----END CERTIFICATE REQUEST-----");
1401    buffer.append(StaticUtils.EOL);
1402
1403    return buffer.toString();
1404  }
1405}