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