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