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