1 /* 2 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.x509; 27 28 import java.io.IOException; 29 import java.io.OutputStream; 30 import java.math.BigInteger; 31 import java.security.*; 32 import java.security.cert.*; 33 import java.security.cert.Certificate; 34 import java.util.*; 35 import java.util.concurrent.ConcurrentHashMap; 36 import javax.security.auth.x500.X500Principal; 37 38 import sun.misc.HexDumpEncoder; 39 import sun.security.util.*; 40 import sun.security.provider.X509Factory; 41 42 /** 43 * The X509CertImpl class represents an X.509 certificate. These certificates 44 * are widely used to support authentication and other functionality in 45 * Internet security systems. Common applications include Privacy Enhanced 46 * Mail (PEM), Transport Layer Security (SSL), code signing for trusted 47 * software distribution, and Secure Electronic Transactions (SET). There 48 * is a commercial infrastructure ready to manage large scale deployments 49 * of X.509 identity certificates. 50 * 51 * <P>These certificates are managed and vouched for by <em>Certificate 52 * Authorities</em> (CAs). CAs are services which create certificates by 53 * placing data in the X.509 standard format and then digitally signing 54 * that data. Such signatures are quite difficult to forge. CAs act as 55 * trusted third parties, making introductions between agents who have no 56 * direct knowledge of each other. CA certificates are either signed by 57 * themselves, or by some other CA such as a "root" CA. 58 * 59 * <P>RFC 1422 is very informative, though it does not describe much 60 * of the recent work being done with X.509 certificates. That includes 61 * a 1996 version (X.509v3) and a variety of enhancements being made to 62 * facilitate an explosion of personal certificates used as "Internet 63 * Drivers' Licences", or with SET for credit card transactions. 64 * 65 * <P>More recent work includes the IETF PKIX Working Group efforts, 66 * especially RFC2459. 67 * 68 * @author Dave Brownell 69 * @author Amit Kapoor 70 * @author Hemma Prafullchandra 71 * @see X509CertInfo 72 */ 73 public class X509CertImpl extends X509Certificate implements DerEncoder { 74 75 private static final long serialVersionUID = -3457612960190864406L; 76 77 private static final String DOT = "."; 78 /** 79 * Public attribute names. 80 */ 81 public static final String NAME = "x509"; 82 public static final String INFO = X509CertInfo.NAME; 83 public static final String ALG_ID = "algorithm"; 84 public static final String SIGNATURE = "signature"; 85 public static final String SIGNED_CERT = "signed_cert"; 86 87 /** 88 * The following are defined for ease-of-use. These 89 * are the most frequently retrieved attributes. 90 */ 91 // x509.info.subject.dname 92 public static final String SUBJECT_DN = NAME + DOT + INFO + DOT + 93 X509CertInfo.SUBJECT + DOT + X509CertInfo.DN_NAME; 94 // x509.info.issuer.dname 95 public static final String ISSUER_DN = NAME + DOT + INFO + DOT + 96 X509CertInfo.ISSUER + DOT + X509CertInfo.DN_NAME; 97 // x509.info.serialNumber.number 98 public static final String SERIAL_ID = NAME + DOT + INFO + DOT + 99 X509CertInfo.SERIAL_NUMBER + DOT + 100 CertificateSerialNumber.NUMBER; 101 // x509.info.key.value 102 public static final String PUBLIC_KEY = NAME + DOT + INFO + DOT + 103 X509CertInfo.KEY + DOT + 104 CertificateX509Key.KEY; 105 106 // x509.info.version.value 107 public static final String VERSION = NAME + DOT + INFO + DOT + 108 X509CertInfo.VERSION + DOT + 109 CertificateVersion.VERSION; 110 111 // x509.algorithm 112 public static final String SIG_ALG = NAME + DOT + ALG_ID; 113 114 // x509.signature 115 public static final String SIG = NAME + DOT + SIGNATURE; 116 117 // when we sign and decode we set this to true 118 // this is our means to make certificates immutable 119 private boolean readOnly = false; 120 121 // Certificate data, and its envelope 122 private byte[] signedCert = null; 123 protected X509CertInfo info = null; 124 protected AlgorithmId algId = null; 125 protected byte[] signature = null; 126 127 // recognized extension OIDS 128 private static final String KEY_USAGE_OID = "2.5.29.15"; 129 private static final String EXTENDED_KEY_USAGE_OID = "2.5.29.37"; 130 private static final String BASIC_CONSTRAINT_OID = "2.5.29.19"; 131 private static final String SUBJECT_ALT_NAME_OID = "2.5.29.17"; 132 private static final String ISSUER_ALT_NAME_OID = "2.5.29.18"; 133 private static final String AUTH_INFO_ACCESS_OID = "1.3.6.1.5.5.7.1.1"; 134 135 // number of standard key usage bits. 136 private static final int NUM_STANDARD_KEY_USAGE = 9; 137 138 // SubjectAlterntativeNames cache 139 private Collection<List<?>> subjectAlternativeNames; 140 141 // IssuerAlternativeNames cache 142 private Collection<List<?>> issuerAlternativeNames; 143 144 // ExtendedKeyUsage cache 145 private List<String> extKeyUsage; 146 147 // AuthorityInformationAccess cache 148 private Set<AccessDescription> authInfoAccess; 149 150 /** 151 * PublicKey that has previously been used to verify 152 * the signature of this certificate. Null if the certificate has not 153 * yet been verified. 154 */ 155 private PublicKey verifiedPublicKey; 156 /** 157 * If verifiedPublicKey is not null, name of the provider used to 158 * successfully verify the signature of this certificate, or the 159 * empty String if no provider was explicitly specified. 160 */ 161 private String verifiedProvider; 162 /** 163 * If verifiedPublicKey is not null, result of the verification using 164 * verifiedPublicKey and verifiedProvider. If true, verification was 165 * successful, if false, it failed. 166 */ 167 private boolean verificationResult; 168 169 /** 170 * Default constructor. 171 */ X509CertImpl()172 public X509CertImpl() { } 173 174 /** 175 * Unmarshals a certificate from its encoded form, parsing the 176 * encoded bytes. This form of constructor is used by agents which 177 * need to examine and use certificate contents. That is, this is 178 * one of the more commonly used constructors. Note that the buffer 179 * must include only a certificate, and no "garbage" may be left at 180 * the end. If you need to ignore data at the end of a certificate, 181 * use another constructor. 182 * 183 * @param certData the encoded bytes, with no trailing padding. 184 * @exception CertificateException on parsing and initialization errors. 185 */ X509CertImpl(byte[] certData)186 public X509CertImpl(byte[] certData) throws CertificateException { 187 try { 188 parse(new DerValue(certData)); 189 } catch (IOException e) { 190 signedCert = null; 191 throw new CertificateException("Unable to initialize, " + e, e); 192 } 193 } 194 195 // BEGIN Android-removed: unused code. 196 /* 197 /** 198 * unmarshals an X.509 certificate from an input stream. If the 199 * certificate is RFC1421 hex-encoded, then it must begin with 200 * the line X509Factory.BEGIN_CERT and end with the line 201 * X509Factory.END_CERT. 202 * 203 * @param in an input stream holding at least one certificate that may 204 * be either DER-encoded or RFC1421 hex-encoded version of the 205 * DER-encoded certificate. 206 * @exception CertificateException on parsing and initialization errors. 207 * 208 public X509CertImpl(InputStream in) throws CertificateException { 209 210 DerValue der = null; 211 212 BufferedInputStream inBuffered = new BufferedInputStream(in); 213 214 // First try reading stream as HEX-encoded DER-encoded bytes, 215 // since not mistakable for raw DER 216 try { 217 inBuffered.mark(Integer.MAX_VALUE); 218 der = readRFC1421Cert(inBuffered); 219 } catch (IOException ioe) { 220 try { 221 // Next, try reading stream as raw DER-encoded bytes 222 inBuffered.reset(); 223 der = new DerValue(inBuffered); 224 } catch (IOException ioe1) { 225 throw new CertificateException("Input stream must be " + 226 "either DER-encoded bytes " + 227 "or RFC1421 hex-encoded " + 228 "DER-encoded bytes: " + 229 ioe1.getMessage(), ioe1); 230 } 231 } 232 try { 233 parse(der); 234 } catch (IOException ioe) { 235 signedCert = null; 236 throw new CertificateException("Unable to parse DER value of " + 237 "certificate, " + ioe, ioe); 238 } 239 } 240 241 /** 242 * read input stream as HEX-encoded DER-encoded bytes 243 * 244 * @param in InputStream to read 245 * @returns DerValue corresponding to decoded HEX-encoded bytes 246 * @throws IOException if stream can not be interpreted as RFC1421 247 * encoded bytes 248 * 249 private DerValue readRFC1421Cert(InputStream in) throws IOException { 250 DerValue der = null; 251 String line = null; 252 BufferedReader certBufferedReader = 253 new BufferedReader(new InputStreamReader(in, "ASCII")); 254 try { 255 line = certBufferedReader.readLine(); 256 } catch (IOException ioe1) { 257 throw new IOException("Unable to read InputStream: " + 258 ioe1.getMessage()); 259 } 260 if (line.equals(X509Factory.BEGIN_CERT)) { 261 /* stream appears to be hex-encoded bytes * 262 ByteArrayOutputStream decstream = new ByteArrayOutputStream(); 263 try { 264 while ((line = certBufferedReader.readLine()) != null) { 265 if (line.equals(X509Factory.END_CERT)) { 266 der = new DerValue(decstream.toByteArray()); 267 break; 268 } else { 269 decstream.write(Pem.decode(line)); 270 } 271 } 272 } catch (IOException ioe2) { 273 throw new IOException("Unable to read InputStream: " 274 + ioe2.getMessage()); 275 } 276 } else { 277 throw new IOException("InputStream is not RFC1421 hex-encoded " + 278 "DER bytes"); 279 } 280 return der; 281 } 282 */ 283 // END Android-removed: unused code. 284 285 /** 286 * Construct an initialized X509 Certificate. The certificate is stored 287 * in raw form and has to be signed to be useful. 288 * 289 * @params info the X509CertificateInfo which the Certificate is to be 290 * created from. 291 */ X509CertImpl(X509CertInfo certInfo)292 public X509CertImpl(X509CertInfo certInfo) { 293 this.info = certInfo; 294 } 295 296 /** 297 * Unmarshal a certificate from its encoded form, parsing a DER value. 298 * This form of constructor is used by agents which need to examine 299 * and use certificate contents. 300 * 301 * @param derVal the der value containing the encoded cert. 302 * @exception CertificateException on parsing and initialization errors. 303 */ X509CertImpl(DerValue derVal)304 public X509CertImpl(DerValue derVal) throws CertificateException { 305 try { 306 parse(derVal); 307 } catch (IOException e) { 308 signedCert = null; 309 throw new CertificateException("Unable to initialize, " + e, e); 310 } 311 } 312 313 // BEGIN Android-added: Ctor to retain original encoded form for APKs parsing. 314 /** 315 * Unmarshal a certificate from its encoded form, parsing a DER value. 316 * This form of constructor is used by agents which need to examine 317 * and use certificate contents. 318 * 319 * @param derVal the der value containing the encoded cert. 320 * @exception CertificateException on parsing and initialization errors. 321 */ X509CertImpl(DerValue derVal, byte[] encoded)322 public X509CertImpl(DerValue derVal, byte[] encoded) 323 throws CertificateException { 324 try { 325 parse(derVal, encoded); 326 } catch (IOException e) { 327 signedCert = null; 328 throw new CertificateException("Unable to initialize, " + e, e); 329 } 330 } 331 // END Android-added: Ctor to retain original encoded form for APKs parsing. 332 333 /** 334 * Appends the certificate to an output stream. 335 * 336 * @param out an input stream to which the certificate is appended. 337 * @exception CertificateEncodingException on encoding errors. 338 */ encode(OutputStream out)339 public void encode(OutputStream out) 340 throws CertificateEncodingException { 341 if (signedCert == null) 342 throw new CertificateEncodingException( 343 "Null certificate to encode"); 344 try { 345 out.write(signedCert.clone()); 346 } catch (IOException e) { 347 throw new CertificateEncodingException(e.toString()); 348 } 349 } 350 351 /** 352 * DER encode this object onto an output stream. 353 * Implements the <code>DerEncoder</code> interface. 354 * 355 * @param out the output stream on which to write the DER encoding. 356 * 357 * @exception IOException on encoding error. 358 */ derEncode(OutputStream out)359 public void derEncode(OutputStream out) throws IOException { 360 if (signedCert == null) 361 throw new IOException("Null certificate to encode"); 362 out.write(signedCert.clone()); 363 } 364 365 /** 366 * Returns the encoded form of this certificate. It is 367 * assumed that each certificate type would have only a single 368 * form of encoding; for example, X.509 certificates would 369 * be encoded as ASN.1 DER. 370 * 371 * @exception CertificateEncodingException if an encoding error occurs. 372 */ getEncoded()373 public byte[] getEncoded() throws CertificateEncodingException { 374 return getEncodedInternal().clone(); 375 } 376 377 /** 378 * Returned the encoding as an uncloned byte array. Callers must 379 * guarantee that they neither modify it nor expose it to untrusted 380 * code. 381 */ getEncodedInternal()382 public byte[] getEncodedInternal() throws CertificateEncodingException { 383 if (signedCert == null) { 384 throw new CertificateEncodingException( 385 "Null certificate to encode"); 386 } 387 return signedCert; 388 } 389 390 /** 391 * Throws an exception if the certificate was not signed using the 392 * verification key provided. Successfully verifying a certificate 393 * does <em>not</em> indicate that one should trust the entity which 394 * it represents. 395 * 396 * @param key the public key used for verification. 397 * 398 * @exception InvalidKeyException on incorrect key. 399 * @exception NoSuchAlgorithmException on unsupported signature 400 * algorithms. 401 * @exception NoSuchProviderException if there's no default provider. 402 * @exception SignatureException on signature errors. 403 * @exception CertificateException on encoding errors. 404 */ verify(PublicKey key)405 public void verify(PublicKey key) 406 throws CertificateException, NoSuchAlgorithmException, 407 InvalidKeyException, NoSuchProviderException, SignatureException { 408 409 verify(key, ""); 410 } 411 412 /** 413 * Throws an exception if the certificate was not signed using the 414 * verification key provided. Successfully verifying a certificate 415 * does <em>not</em> indicate that one should trust the entity which 416 * it represents. 417 * 418 * @param key the public key used for verification. 419 * @param sigProvider the name of the provider. 420 * 421 * @exception NoSuchAlgorithmException on unsupported signature 422 * algorithms. 423 * @exception InvalidKeyException on incorrect key. 424 * @exception NoSuchProviderException on incorrect provider. 425 * @exception SignatureException on signature errors. 426 * @exception CertificateException on encoding errors. 427 */ verify(PublicKey key, String sigProvider)428 public synchronized void verify(PublicKey key, String sigProvider) 429 throws CertificateException, NoSuchAlgorithmException, 430 InvalidKeyException, NoSuchProviderException, SignatureException { 431 if (sigProvider == null) { 432 sigProvider = ""; 433 } 434 if ((verifiedPublicKey != null) && verifiedPublicKey.equals(key)) { 435 // this certificate has already been verified using 436 // this public key. Make sure providers match, too. 437 if (sigProvider.equals(verifiedProvider)) { 438 if (verificationResult) { 439 return; 440 } else { 441 throw new SignatureException("Signature does not match."); 442 } 443 } 444 } 445 if (signedCert == null) { 446 throw new CertificateEncodingException("Uninitialized certificate"); 447 } 448 // Verify the signature ... 449 Signature sigVerf = null; 450 if (sigProvider.length() == 0) { 451 sigVerf = Signature.getInstance(algId.getName()); 452 } else { 453 sigVerf = Signature.getInstance(algId.getName(), sigProvider); 454 } 455 sigVerf.initVerify(key); 456 457 byte[] rawCert = info.getEncodedInfo(); 458 sigVerf.update(rawCert, 0, rawCert.length); 459 460 // verify may throw SignatureException for invalid encodings, etc. 461 verificationResult = sigVerf.verify(signature); 462 verifiedPublicKey = key; 463 verifiedProvider = sigProvider; 464 465 if (verificationResult == false) { 466 throw new SignatureException("Signature does not match."); 467 } 468 } 469 470 /** 471 * Throws an exception if the certificate was not signed using the 472 * verification key provided. This method uses the signature verification 473 * engine supplied by the specified provider. Note that the specified 474 * Provider object does not have to be registered in the provider list. 475 * Successfully verifying a certificate does <em>not</em> indicate that one 476 * should trust the entity which it represents. 477 * 478 * @param key the public key used for verification. 479 * @param sigProvider the provider. 480 * 481 * @exception NoSuchAlgorithmException on unsupported signature 482 * algorithms. 483 * @exception InvalidKeyException on incorrect key. 484 * @exception SignatureException on signature errors. 485 * @exception CertificateException on encoding errors. 486 */ verify(PublicKey key, Provider sigProvider)487 public synchronized void verify(PublicKey key, Provider sigProvider) 488 throws CertificateException, NoSuchAlgorithmException, 489 InvalidKeyException, SignatureException { 490 if (signedCert == null) { 491 throw new CertificateEncodingException("Uninitialized certificate"); 492 } 493 // Verify the signature ... 494 Signature sigVerf = null; 495 if (sigProvider == null) { 496 sigVerf = Signature.getInstance(algId.getName()); 497 } else { 498 sigVerf = Signature.getInstance(algId.getName(), sigProvider); 499 } 500 sigVerf.initVerify(key); 501 502 byte[] rawCert = info.getEncodedInfo(); 503 sigVerf.update(rawCert, 0, rawCert.length); 504 505 // verify may throw SignatureException for invalid encodings, etc. 506 verificationResult = sigVerf.verify(signature); 507 verifiedPublicKey = key; 508 509 if (verificationResult == false) { 510 throw new SignatureException("Signature does not match."); 511 } 512 } 513 514 /** 515 * This static method is the default implementation of the 516 * verify(PublicKey key, Provider sigProvider) method in X509Certificate. 517 * Called from java.security.cert.X509Certificate.verify(PublicKey key, 518 * Provider sigProvider) 519 */ verify(X509Certificate cert, PublicKey key, Provider sigProvider)520 public static void verify(X509Certificate cert, PublicKey key, 521 Provider sigProvider) throws CertificateException, 522 NoSuchAlgorithmException, InvalidKeyException, SignatureException { 523 cert.verify(key, sigProvider); 524 } 525 526 /** 527 * Creates an X.509 certificate, and signs it using the given key 528 * (associating a signature algorithm and an X.500 name). 529 * This operation is used to implement the certificate generation 530 * functionality of a certificate authority. 531 * 532 * @param key the private key used for signing. 533 * @param algorithm the name of the signature algorithm used. 534 * 535 * @exception InvalidKeyException on incorrect key. 536 * @exception NoSuchAlgorithmException on unsupported signature 537 * algorithms. 538 * @exception NoSuchProviderException if there's no default provider. 539 * @exception SignatureException on signature errors. 540 * @exception CertificateException on encoding errors. 541 */ sign(PrivateKey key, String algorithm)542 public void sign(PrivateKey key, String algorithm) 543 throws CertificateException, NoSuchAlgorithmException, 544 InvalidKeyException, NoSuchProviderException, SignatureException { 545 sign(key, algorithm, null); 546 } 547 548 /** 549 * Creates an X.509 certificate, and signs it using the given key 550 * (associating a signature algorithm and an X.500 name). 551 * This operation is used to implement the certificate generation 552 * functionality of a certificate authority. 553 * 554 * @param key the private key used for signing. 555 * @param algorithm the name of the signature algorithm used. 556 * @param provider the name of the provider. 557 * 558 * @exception NoSuchAlgorithmException on unsupported signature 559 * algorithms. 560 * @exception InvalidKeyException on incorrect key. 561 * @exception NoSuchProviderException on incorrect provider. 562 * @exception SignatureException on signature errors. 563 * @exception CertificateException on encoding errors. 564 */ sign(PrivateKey key, String algorithm, String provider)565 public void sign(PrivateKey key, String algorithm, String provider) 566 throws CertificateException, NoSuchAlgorithmException, 567 InvalidKeyException, NoSuchProviderException, SignatureException { 568 try { 569 if (readOnly) 570 throw new CertificateEncodingException( 571 "cannot over-write existing certificate"); 572 Signature sigEngine = null; 573 if ((provider == null) || (provider.length() == 0)) 574 sigEngine = Signature.getInstance(algorithm); 575 else 576 sigEngine = Signature.getInstance(algorithm, provider); 577 578 sigEngine.initSign(key); 579 580 // in case the name is reset 581 algId = AlgorithmId.get(sigEngine.getAlgorithm()); 582 583 DerOutputStream out = new DerOutputStream(); 584 DerOutputStream tmp = new DerOutputStream(); 585 586 // encode certificate info 587 info.encode(tmp); 588 byte[] rawCert = tmp.toByteArray(); 589 590 // encode algorithm identifier 591 algId.encode(tmp); 592 593 // Create and encode the signature itself. 594 sigEngine.update(rawCert, 0, rawCert.length); 595 signature = sigEngine.sign(); 596 tmp.putBitString(signature); 597 598 // Wrap the signed data in a SEQUENCE { data, algorithm, sig } 599 out.write(DerValue.tag_Sequence, tmp); 600 signedCert = out.toByteArray(); 601 readOnly = true; 602 603 } catch (IOException e) { 604 throw new CertificateEncodingException(e.toString()); 605 } 606 } 607 608 /** 609 * Checks that the certificate is currently valid, i.e. the current 610 * time is within the specified validity period. 611 * 612 * @exception CertificateExpiredException if the certificate has expired. 613 * @exception CertificateNotYetValidException if the certificate is not 614 * yet valid. 615 */ checkValidity()616 public void checkValidity() 617 throws CertificateExpiredException, CertificateNotYetValidException { 618 Date date = new Date(); 619 checkValidity(date); 620 } 621 622 /** 623 * Checks that the specified date is within the certificate's 624 * validity period, or basically if the certificate would be 625 * valid at the specified date/time. 626 * 627 * @param date the Date to check against to see if this certificate 628 * is valid at that date/time. 629 * 630 * @exception CertificateExpiredException if the certificate has expired 631 * with respect to the <code>date</code> supplied. 632 * @exception CertificateNotYetValidException if the certificate is not 633 * yet valid with respect to the <code>date</code> supplied. 634 */ checkValidity(Date date)635 public void checkValidity(Date date) 636 throws CertificateExpiredException, CertificateNotYetValidException { 637 638 CertificateValidity interval = null; 639 try { 640 interval = (CertificateValidity)info.get(CertificateValidity.NAME); 641 } catch (Exception e) { 642 throw new CertificateNotYetValidException("Incorrect validity period"); 643 } 644 if (interval == null) 645 throw new CertificateNotYetValidException("Null validity period"); 646 interval.valid(date); 647 } 648 649 /** 650 * Return the requested attribute from the certificate. 651 * 652 * Note that the X509CertInfo is not cloned for performance reasons. 653 * Callers must ensure that they do not modify it. All other 654 * attributes are cloned. 655 * 656 * @param name the name of the attribute. 657 * @exception CertificateParsingException on invalid attribute identifier. 658 */ get(String name)659 public Object get(String name) 660 throws CertificateParsingException { 661 X509AttributeName attr = new X509AttributeName(name); 662 String id = attr.getPrefix(); 663 if (!(id.equalsIgnoreCase(NAME))) { 664 throw new CertificateParsingException("Invalid root of " 665 + "attribute name, expected [" + NAME + 666 "], received " + "[" + id + "]"); 667 } 668 attr = new X509AttributeName(attr.getSuffix()); 669 id = attr.getPrefix(); 670 671 if (id.equalsIgnoreCase(INFO)) { 672 if (info == null) { 673 return null; 674 } 675 if (attr.getSuffix() != null) { 676 try { 677 return info.get(attr.getSuffix()); 678 } catch (IOException e) { 679 throw new CertificateParsingException(e.toString()); 680 } catch (CertificateException e) { 681 throw new CertificateParsingException(e.toString()); 682 } 683 } else { 684 return info; 685 } 686 } else if (id.equalsIgnoreCase(ALG_ID)) { 687 return(algId); 688 } else if (id.equalsIgnoreCase(SIGNATURE)) { 689 if (signature != null) 690 return signature.clone(); 691 else 692 return null; 693 } else if (id.equalsIgnoreCase(SIGNED_CERT)) { 694 if (signedCert != null) 695 return signedCert.clone(); 696 else 697 return null; 698 } else { 699 throw new CertificateParsingException("Attribute name not " 700 + "recognized or get() not allowed for the same: " + id); 701 } 702 } 703 704 /** 705 * Set the requested attribute in the certificate. 706 * 707 * @param name the name of the attribute. 708 * @param obj the value of the attribute. 709 * @exception CertificateException on invalid attribute identifier. 710 * @exception IOException on encoding error of attribute. 711 */ set(String name, Object obj)712 public void set(String name, Object obj) 713 throws CertificateException, IOException { 714 // check if immutable 715 if (readOnly) 716 throw new CertificateException("cannot over-write existing" 717 + " certificate"); 718 719 X509AttributeName attr = new X509AttributeName(name); 720 String id = attr.getPrefix(); 721 if (!(id.equalsIgnoreCase(NAME))) { 722 throw new CertificateException("Invalid root of attribute name," 723 + " expected [" + NAME + "], received " + id); 724 } 725 attr = new X509AttributeName(attr.getSuffix()); 726 id = attr.getPrefix(); 727 728 if (id.equalsIgnoreCase(INFO)) { 729 if (attr.getSuffix() == null) { 730 if (!(obj instanceof X509CertInfo)) { 731 throw new CertificateException("Attribute value should" 732 + " be of type X509CertInfo."); 733 } 734 info = (X509CertInfo)obj; 735 signedCert = null; //reset this as certificate data has changed 736 } else { 737 info.set(attr.getSuffix(), obj); 738 signedCert = null; //reset this as certificate data has changed 739 } 740 } else { 741 throw new CertificateException("Attribute name not recognized or " + 742 "set() not allowed for the same: " + id); 743 } 744 } 745 746 /** 747 * Delete the requested attribute from the certificate. 748 * 749 * @param name the name of the attribute. 750 * @exception CertificateException on invalid attribute identifier. 751 * @exception IOException on other errors. 752 */ delete(String name)753 public void delete(String name) 754 throws CertificateException, IOException { 755 // check if immutable 756 if (readOnly) 757 throw new CertificateException("cannot over-write existing" 758 + " certificate"); 759 760 X509AttributeName attr = new X509AttributeName(name); 761 String id = attr.getPrefix(); 762 if (!(id.equalsIgnoreCase(NAME))) { 763 throw new CertificateException("Invalid root of attribute name," 764 + " expected [" 765 + NAME + "], received " + id); 766 } 767 attr = new X509AttributeName(attr.getSuffix()); 768 id = attr.getPrefix(); 769 770 if (id.equalsIgnoreCase(INFO)) { 771 if (attr.getSuffix() != null) { 772 info = null; 773 } else { 774 info.delete(attr.getSuffix()); 775 } 776 } else if (id.equalsIgnoreCase(ALG_ID)) { 777 algId = null; 778 } else if (id.equalsIgnoreCase(SIGNATURE)) { 779 signature = null; 780 } else if (id.equalsIgnoreCase(SIGNED_CERT)) { 781 signedCert = null; 782 } else { 783 throw new CertificateException("Attribute name not recognized or " + 784 "delete() not allowed for the same: " + id); 785 } 786 } 787 788 /** 789 * Return an enumeration of names of attributes existing within this 790 * attribute. 791 */ getElements()792 public Enumeration<String> getElements() { 793 AttributeNameEnumeration elements = new AttributeNameEnumeration(); 794 elements.addElement(NAME + DOT + INFO); 795 elements.addElement(NAME + DOT + ALG_ID); 796 elements.addElement(NAME + DOT + SIGNATURE); 797 elements.addElement(NAME + DOT + SIGNED_CERT); 798 799 return elements.elements(); 800 } 801 802 /** 803 * Return the name of this attribute. 804 */ getName()805 public String getName() { 806 return(NAME); 807 } 808 809 /** 810 * Returns a printable representation of the certificate. This does not 811 * contain all the information available to distinguish this from any 812 * other certificate. The certificate must be fully constructed 813 * before this function may be called. 814 */ toString()815 public String toString() { 816 if (info == null || algId == null || signature == null) 817 return ""; 818 819 StringBuilder sb = new StringBuilder(); 820 821 sb.append("[\n"); 822 sb.append(info.toString() + "\n"); 823 sb.append(" Algorithm: [" + algId.toString() + "]\n"); 824 825 HexDumpEncoder encoder = new HexDumpEncoder(); 826 sb.append(" Signature:\n" + encoder.encodeBuffer(signature)); 827 sb.append("\n]"); 828 829 return sb.toString(); 830 } 831 832 // the strongly typed gets, as per java.security.cert.X509Certificate 833 834 /** 835 * Gets the publickey from this certificate. 836 * 837 * @return the publickey. 838 */ getPublicKey()839 public PublicKey getPublicKey() { 840 if (info == null) 841 return null; 842 try { 843 PublicKey key = (PublicKey)info.get(CertificateX509Key.NAME 844 + DOT + CertificateX509Key.KEY); 845 return key; 846 } catch (Exception e) { 847 return null; 848 } 849 } 850 851 /** 852 * Gets the version number from the certificate. 853 * 854 * @return the version number, i.e. 1, 2 or 3. 855 */ getVersion()856 public int getVersion() { 857 if (info == null) 858 return -1; 859 try { 860 int vers = ((Integer)info.get(CertificateVersion.NAME 861 + DOT + CertificateVersion.VERSION)).intValue(); 862 return vers+1; 863 } catch (Exception e) { 864 return -1; 865 } 866 } 867 868 /** 869 * Gets the serial number from the certificate. 870 * 871 * @return the serial number. 872 */ getSerialNumber()873 public BigInteger getSerialNumber() { 874 SerialNumber ser = getSerialNumberObject(); 875 876 return ser != null ? ser.getNumber() : null; 877 } 878 879 /** 880 * Gets the serial number from the certificate as 881 * a SerialNumber object. 882 * 883 * @return the serial number. 884 */ getSerialNumberObject()885 public SerialNumber getSerialNumberObject() { 886 if (info == null) 887 return null; 888 try { 889 SerialNumber ser = (SerialNumber)info.get( 890 CertificateSerialNumber.NAME + DOT + 891 CertificateSerialNumber.NUMBER); 892 return ser; 893 } catch (Exception e) { 894 return null; 895 } 896 } 897 898 899 /** 900 * Gets the subject distinguished name from the certificate. 901 * 902 * @return the subject name. 903 */ getSubjectDN()904 public Principal getSubjectDN() { 905 if (info == null) 906 return null; 907 try { 908 Principal subject = (Principal)info.get(X509CertInfo.SUBJECT + DOT + 909 X509CertInfo.DN_NAME); 910 return subject; 911 } catch (Exception e) { 912 return null; 913 } 914 } 915 916 /** 917 * Get subject name as X500Principal. Overrides implementation in 918 * X509Certificate with a slightly more efficient version that is 919 * also aware of X509CertImpl mutability. 920 */ getSubjectX500Principal()921 public X500Principal getSubjectX500Principal() { 922 if (info == null) { 923 return null; 924 } 925 try { 926 X500Principal subject = (X500Principal)info.get( 927 X509CertInfo.SUBJECT + DOT + 928 "x500principal"); 929 return subject; 930 } catch (Exception e) { 931 return null; 932 } 933 } 934 935 /** 936 * Gets the issuer distinguished name from the certificate. 937 * 938 * @return the issuer name. 939 */ getIssuerDN()940 public Principal getIssuerDN() { 941 if (info == null) 942 return null; 943 try { 944 Principal issuer = (Principal)info.get(X509CertInfo.ISSUER + DOT + 945 X509CertInfo.DN_NAME); 946 return issuer; 947 } catch (Exception e) { 948 return null; 949 } 950 } 951 952 /** 953 * Get issuer name as X500Principal. Overrides implementation in 954 * X509Certificate with a slightly more efficient version that is 955 * also aware of X509CertImpl mutability. 956 */ getIssuerX500Principal()957 public X500Principal getIssuerX500Principal() { 958 if (info == null) { 959 return null; 960 } 961 try { 962 X500Principal issuer = (X500Principal)info.get( 963 X509CertInfo.ISSUER + DOT + 964 "x500principal"); 965 return issuer; 966 } catch (Exception e) { 967 return null; 968 } 969 } 970 971 /** 972 * Gets the notBefore date from the validity period of the certificate. 973 * 974 * @return the start date of the validity period. 975 */ getNotBefore()976 public Date getNotBefore() { 977 if (info == null) 978 return null; 979 try { 980 Date d = (Date) info.get(CertificateValidity.NAME + DOT + 981 CertificateValidity.NOT_BEFORE); 982 return d; 983 } catch (Exception e) { 984 return null; 985 } 986 } 987 988 /** 989 * Gets the notAfter date from the validity period of the certificate. 990 * 991 * @return the end date of the validity period. 992 */ getNotAfter()993 public Date getNotAfter() { 994 if (info == null) 995 return null; 996 try { 997 Date d = (Date) info.get(CertificateValidity.NAME + DOT + 998 CertificateValidity.NOT_AFTER); 999 return d; 1000 } catch (Exception e) { 1001 return null; 1002 } 1003 } 1004 1005 /** 1006 * Gets the DER encoded certificate informations, the 1007 * <code>tbsCertificate</code> from this certificate. 1008 * This can be used to verify the signature independently. 1009 * 1010 * @return the DER encoded certificate information. 1011 * @exception CertificateEncodingException if an encoding error occurs. 1012 */ getTBSCertificate()1013 public byte[] getTBSCertificate() throws CertificateEncodingException { 1014 if (info != null) { 1015 return info.getEncodedInfo(); 1016 } else 1017 throw new CertificateEncodingException("Uninitialized certificate"); 1018 } 1019 1020 /** 1021 * Gets the raw Signature bits from the certificate. 1022 * 1023 * @return the signature. 1024 */ getSignature()1025 public byte[] getSignature() { 1026 if (signature == null) 1027 return null; 1028 return signature.clone(); 1029 } 1030 1031 /** 1032 * Gets the signature algorithm name for the certificate 1033 * signature algorithm. 1034 * For example, the string "SHA-1/DSA" or "DSS". 1035 * 1036 * @return the signature algorithm name. 1037 */ getSigAlgName()1038 public String getSigAlgName() { 1039 if (algId == null) 1040 return null; 1041 return (algId.getName()); 1042 } 1043 1044 /** 1045 * Gets the signature algorithm OID string from the certificate. 1046 * For example, the string "1.2.840.10040.4.3" 1047 * 1048 * @return the signature algorithm oid string. 1049 */ getSigAlgOID()1050 public String getSigAlgOID() { 1051 if (algId == null) 1052 return null; 1053 ObjectIdentifier oid = algId.getOID(); 1054 return (oid.toString()); 1055 } 1056 1057 /** 1058 * Gets the DER encoded signature algorithm parameters from this 1059 * certificate's signature algorithm. 1060 * 1061 * @return the DER encoded signature algorithm parameters, or 1062 * null if no parameters are present. 1063 */ getSigAlgParams()1064 public byte[] getSigAlgParams() { 1065 if (algId == null) 1066 return null; 1067 try { 1068 return algId.getEncodedParams(); 1069 } catch (IOException e) { 1070 return null; 1071 } 1072 } 1073 1074 /** 1075 * Gets the Issuer Unique Identity from the certificate. 1076 * 1077 * @return the Issuer Unique Identity. 1078 */ getIssuerUniqueID()1079 public boolean[] getIssuerUniqueID() { 1080 if (info == null) 1081 return null; 1082 try { 1083 UniqueIdentity id = (UniqueIdentity)info.get( 1084 X509CertInfo.ISSUER_ID); 1085 if (id == null) 1086 return null; 1087 else 1088 return (id.getId()); 1089 } catch (Exception e) { 1090 return null; 1091 } 1092 } 1093 1094 /** 1095 * Gets the Subject Unique Identity from the certificate. 1096 * 1097 * @return the Subject Unique Identity. 1098 */ getSubjectUniqueID()1099 public boolean[] getSubjectUniqueID() { 1100 if (info == null) 1101 return null; 1102 try { 1103 UniqueIdentity id = (UniqueIdentity)info.get( 1104 X509CertInfo.SUBJECT_ID); 1105 if (id == null) 1106 return null; 1107 else 1108 return (id.getId()); 1109 } catch (Exception e) { 1110 return null; 1111 } 1112 } 1113 getAuthKeyId()1114 public KeyIdentifier getAuthKeyId() { 1115 AuthorityKeyIdentifierExtension aki 1116 = getAuthorityKeyIdentifierExtension(); 1117 if (aki != null) { 1118 try { 1119 return (KeyIdentifier)aki.get( 1120 AuthorityKeyIdentifierExtension.KEY_ID); 1121 } catch (IOException ioe) {} // not possible 1122 } 1123 return null; 1124 } 1125 1126 /** 1127 * Returns the subject's key identifier, or null 1128 */ getSubjectKeyId()1129 public KeyIdentifier getSubjectKeyId() { 1130 SubjectKeyIdentifierExtension ski = getSubjectKeyIdentifierExtension(); 1131 if (ski != null) { 1132 try { 1133 return (KeyIdentifier)ski.get( 1134 SubjectKeyIdentifierExtension.KEY_ID); 1135 } catch (IOException ioe) {} // not possible 1136 } 1137 return null; 1138 } 1139 1140 /** 1141 * Get AuthorityKeyIdentifier extension 1142 * @return AuthorityKeyIdentifier object or null (if no such object 1143 * in certificate) 1144 */ getAuthorityKeyIdentifierExtension()1145 public AuthorityKeyIdentifierExtension getAuthorityKeyIdentifierExtension() 1146 { 1147 return (AuthorityKeyIdentifierExtension) 1148 getExtension(PKIXExtensions.AuthorityKey_Id); 1149 } 1150 1151 /** 1152 * Get BasicConstraints extension 1153 * @return BasicConstraints object or null (if no such object in 1154 * certificate) 1155 */ getBasicConstraintsExtension()1156 public BasicConstraintsExtension getBasicConstraintsExtension() { 1157 return (BasicConstraintsExtension) 1158 getExtension(PKIXExtensions.BasicConstraints_Id); 1159 } 1160 1161 /** 1162 * Get CertificatePoliciesExtension 1163 * @return CertificatePoliciesExtension or null (if no such object in 1164 * certificate) 1165 */ getCertificatePoliciesExtension()1166 public CertificatePoliciesExtension getCertificatePoliciesExtension() { 1167 return (CertificatePoliciesExtension) 1168 getExtension(PKIXExtensions.CertificatePolicies_Id); 1169 } 1170 1171 /** 1172 * Get ExtendedKeyUsage extension 1173 * @return ExtendedKeyUsage extension object or null (if no such object 1174 * in certificate) 1175 */ getExtendedKeyUsageExtension()1176 public ExtendedKeyUsageExtension getExtendedKeyUsageExtension() { 1177 return (ExtendedKeyUsageExtension) 1178 getExtension(PKIXExtensions.ExtendedKeyUsage_Id); 1179 } 1180 1181 /** 1182 * Get IssuerAlternativeName extension 1183 * @return IssuerAlternativeName object or null (if no such object in 1184 * certificate) 1185 */ getIssuerAlternativeNameExtension()1186 public IssuerAlternativeNameExtension getIssuerAlternativeNameExtension() { 1187 return (IssuerAlternativeNameExtension) 1188 getExtension(PKIXExtensions.IssuerAlternativeName_Id); 1189 } 1190 1191 /** 1192 * Get NameConstraints extension 1193 * @return NameConstraints object or null (if no such object in certificate) 1194 */ getNameConstraintsExtension()1195 public NameConstraintsExtension getNameConstraintsExtension() { 1196 return (NameConstraintsExtension) 1197 getExtension(PKIXExtensions.NameConstraints_Id); 1198 } 1199 1200 /** 1201 * Get PolicyConstraints extension 1202 * @return PolicyConstraints object or null (if no such object in 1203 * certificate) 1204 */ getPolicyConstraintsExtension()1205 public PolicyConstraintsExtension getPolicyConstraintsExtension() { 1206 return (PolicyConstraintsExtension) 1207 getExtension(PKIXExtensions.PolicyConstraints_Id); 1208 } 1209 1210 /** 1211 * Get PolicyMappingsExtension extension 1212 * @return PolicyMappingsExtension object or null (if no such object 1213 * in certificate) 1214 */ getPolicyMappingsExtension()1215 public PolicyMappingsExtension getPolicyMappingsExtension() { 1216 return (PolicyMappingsExtension) 1217 getExtension(PKIXExtensions.PolicyMappings_Id); 1218 } 1219 1220 /** 1221 * Get PrivateKeyUsage extension 1222 * @return PrivateKeyUsage object or null (if no such object in certificate) 1223 */ getPrivateKeyUsageExtension()1224 public PrivateKeyUsageExtension getPrivateKeyUsageExtension() { 1225 return (PrivateKeyUsageExtension) 1226 getExtension(PKIXExtensions.PrivateKeyUsage_Id); 1227 } 1228 1229 /** 1230 * Get SubjectAlternativeName extension 1231 * @return SubjectAlternativeName object or null (if no such object in 1232 * certificate) 1233 */ getSubjectAlternativeNameExtension()1234 public SubjectAlternativeNameExtension getSubjectAlternativeNameExtension() 1235 { 1236 return (SubjectAlternativeNameExtension) 1237 getExtension(PKIXExtensions.SubjectAlternativeName_Id); 1238 } 1239 1240 /** 1241 * Get SubjectKeyIdentifier extension 1242 * @return SubjectKeyIdentifier object or null (if no such object in 1243 * certificate) 1244 */ getSubjectKeyIdentifierExtension()1245 public SubjectKeyIdentifierExtension getSubjectKeyIdentifierExtension() { 1246 return (SubjectKeyIdentifierExtension) 1247 getExtension(PKIXExtensions.SubjectKey_Id); 1248 } 1249 1250 /** 1251 * Get CRLDistributionPoints extension 1252 * @return CRLDistributionPoints object or null (if no such object in 1253 * certificate) 1254 */ getCRLDistributionPointsExtension()1255 public CRLDistributionPointsExtension getCRLDistributionPointsExtension() { 1256 return (CRLDistributionPointsExtension) 1257 getExtension(PKIXExtensions.CRLDistributionPoints_Id); 1258 } 1259 1260 /** 1261 * Return true if a critical extension is found that is 1262 * not supported, otherwise return false. 1263 */ hasUnsupportedCriticalExtension()1264 public boolean hasUnsupportedCriticalExtension() { 1265 if (info == null) 1266 return false; 1267 try { 1268 CertificateExtensions exts = (CertificateExtensions)info.get( 1269 CertificateExtensions.NAME); 1270 if (exts == null) 1271 return false; 1272 return exts.hasUnsupportedCriticalExtension(); 1273 } catch (Exception e) { 1274 return false; 1275 } 1276 } 1277 1278 /** 1279 * Gets a Set of the extension(s) marked CRITICAL in the 1280 * certificate. In the returned set, each extension is 1281 * represented by its OID string. 1282 * 1283 * @return a set of the extension oid strings in the 1284 * certificate that are marked critical. 1285 */ getCriticalExtensionOIDs()1286 public Set<String> getCriticalExtensionOIDs() { 1287 if (info == null) { 1288 return null; 1289 } 1290 try { 1291 CertificateExtensions exts = (CertificateExtensions)info.get( 1292 CertificateExtensions.NAME); 1293 if (exts == null) { 1294 return null; 1295 } 1296 Set<String> extSet = new TreeSet<>(); 1297 for (Extension ex : exts.getAllExtensions()) { 1298 if (ex.isCritical()) { 1299 extSet.add(ex.getExtensionId().toString()); 1300 } 1301 } 1302 return extSet; 1303 } catch (Exception e) { 1304 return null; 1305 } 1306 } 1307 1308 /** 1309 * Gets a Set of the extension(s) marked NON-CRITICAL in the 1310 * certificate. In the returned set, each extension is 1311 * represented by its OID string. 1312 * 1313 * @return a set of the extension oid strings in the 1314 * certificate that are NOT marked critical. 1315 */ getNonCriticalExtensionOIDs()1316 public Set<String> getNonCriticalExtensionOIDs() { 1317 if (info == null) { 1318 return null; 1319 } 1320 try { 1321 CertificateExtensions exts = (CertificateExtensions)info.get( 1322 CertificateExtensions.NAME); 1323 if (exts == null) { 1324 return null; 1325 } 1326 Set<String> extSet = new TreeSet<>(); 1327 for (Extension ex : exts.getAllExtensions()) { 1328 if (!ex.isCritical()) { 1329 extSet.add(ex.getExtensionId().toString()); 1330 } 1331 } 1332 extSet.addAll(exts.getUnparseableExtensions().keySet()); 1333 return extSet; 1334 } catch (Exception e) { 1335 return null; 1336 } 1337 } 1338 1339 /** 1340 * Gets the extension identified by the given ObjectIdentifier 1341 * 1342 * @param oid the Object Identifier value for the extension. 1343 * @return Extension or null if certificate does not contain this 1344 * extension 1345 */ getExtension(ObjectIdentifier oid)1346 public Extension getExtension(ObjectIdentifier oid) { 1347 if (info == null) { 1348 return null; 1349 } 1350 try { 1351 CertificateExtensions extensions; 1352 try { 1353 extensions = (CertificateExtensions)info.get(CertificateExtensions.NAME); 1354 } catch (CertificateException ce) { 1355 return null; 1356 } 1357 if (extensions == null) { 1358 return null; 1359 } else { 1360 Extension ex = extensions.getExtension(oid.toString()); 1361 if (ex != null) { 1362 return ex; 1363 } 1364 for (Extension ex2: extensions.getAllExtensions()) { 1365 if (ex2.getExtensionId().equals((Object)oid)) { 1366 //XXXX May want to consider cloning this 1367 return ex2; 1368 } 1369 } 1370 /* no such extension in this certificate */ 1371 return null; 1372 } 1373 } catch (IOException ioe) { 1374 return null; 1375 } 1376 } 1377 getUnparseableExtension(ObjectIdentifier oid)1378 public Extension getUnparseableExtension(ObjectIdentifier oid) { 1379 if (info == null) { 1380 return null; 1381 } 1382 try { 1383 CertificateExtensions extensions; 1384 try { 1385 extensions = (CertificateExtensions)info.get(CertificateExtensions.NAME); 1386 } catch (CertificateException ce) { 1387 return null; 1388 } 1389 if (extensions == null) { 1390 return null; 1391 } else { 1392 return extensions.getUnparseableExtensions().get(oid.toString()); 1393 } 1394 } catch (IOException ioe) { 1395 return null; 1396 } 1397 } 1398 1399 /** 1400 * Gets the DER encoded extension identified by the given 1401 * oid String. 1402 * 1403 * @param oid the Object Identifier value for the extension. 1404 */ getExtensionValue(String oid)1405 public byte[] getExtensionValue(String oid) { 1406 try { 1407 ObjectIdentifier findOID = new ObjectIdentifier(oid); 1408 String extAlias = OIDMap.getName(findOID); 1409 Extension certExt = null; 1410 CertificateExtensions exts = (CertificateExtensions)info.get( 1411 CertificateExtensions.NAME); 1412 1413 if (extAlias == null) { // may be unknown 1414 // get the extensions, search thru' for this oid 1415 if (exts == null) { 1416 return null; 1417 } 1418 1419 for (Extension ex : exts.getAllExtensions()) { 1420 ObjectIdentifier inCertOID = ex.getExtensionId(); 1421 if (inCertOID.equals((Object)findOID)) { 1422 certExt = ex; 1423 break; 1424 } 1425 } 1426 } else { // there's sub-class that can handle this extension 1427 try { 1428 certExt = (Extension)this.get(extAlias); 1429 } catch (CertificateException e) { 1430 // get() throws an Exception instead of returning null, ignore 1431 } 1432 } 1433 if (certExt == null) { 1434 if (exts != null) { 1435 certExt = exts.getUnparseableExtensions().get(oid); 1436 } 1437 if (certExt == null) { 1438 return null; 1439 } 1440 } 1441 byte[] extData = certExt.getExtensionValue(); 1442 if (extData == null) { 1443 return null; 1444 } 1445 DerOutputStream out = new DerOutputStream(); 1446 out.putOctetString(extData); 1447 return out.toByteArray(); 1448 } catch (Exception e) { 1449 return null; 1450 } 1451 } 1452 1453 /** 1454 * Get a boolean array representing the bits of the KeyUsage extension, 1455 * (oid = 2.5.29.15). 1456 * @return the bit values of this extension as an array of booleans. 1457 */ getKeyUsage()1458 public boolean[] getKeyUsage() { 1459 try { 1460 String extAlias = OIDMap.getName(PKIXExtensions.KeyUsage_Id); 1461 if (extAlias == null) 1462 return null; 1463 1464 KeyUsageExtension certExt = (KeyUsageExtension)this.get(extAlias); 1465 if (certExt == null) 1466 return null; 1467 1468 boolean[] ret = certExt.getBits(); 1469 if (ret.length < NUM_STANDARD_KEY_USAGE) { 1470 boolean[] usageBits = new boolean[NUM_STANDARD_KEY_USAGE]; 1471 System.arraycopy(ret, 0, usageBits, 0, ret.length); 1472 ret = usageBits; 1473 } 1474 return ret; 1475 } catch (Exception e) { 1476 return null; 1477 } 1478 } 1479 1480 /** 1481 * This method are the overridden implementation of 1482 * getExtendedKeyUsage method in X509Certificate in the Sun 1483 * provider. It is better performance-wise since it returns cached 1484 * values. 1485 */ getExtendedKeyUsage()1486 public synchronized List<String> getExtendedKeyUsage() 1487 throws CertificateParsingException { 1488 if (readOnly && extKeyUsage != null) { 1489 return extKeyUsage; 1490 } else { 1491 ExtendedKeyUsageExtension ext = getExtendedKeyUsageExtension(); 1492 if (ext == null) { 1493 return null; 1494 } 1495 extKeyUsage = 1496 Collections.unmodifiableList(ext.getExtendedKeyUsage()); 1497 return extKeyUsage; 1498 } 1499 } 1500 1501 /** 1502 * This static method is the default implementation of the 1503 * getExtendedKeyUsage method in X509Certificate. A 1504 * X509Certificate provider generally should overwrite this to 1505 * provide among other things caching for better performance. 1506 */ getExtendedKeyUsage(X509Certificate cert)1507 public static List<String> getExtendedKeyUsage(X509Certificate cert) 1508 throws CertificateParsingException { 1509 try { 1510 byte[] ext = cert.getExtensionValue(EXTENDED_KEY_USAGE_OID); 1511 if (ext == null) 1512 return null; 1513 DerValue val = new DerValue(ext); 1514 byte[] data = val.getOctetString(); 1515 1516 ExtendedKeyUsageExtension ekuExt = 1517 new ExtendedKeyUsageExtension(Boolean.FALSE, data); 1518 return Collections.unmodifiableList(ekuExt.getExtendedKeyUsage()); 1519 } catch (IOException ioe) { 1520 throw new CertificateParsingException(ioe); 1521 } 1522 } 1523 1524 /** 1525 * Get the certificate constraints path length from the 1526 * the critical BasicConstraints extension, (oid = 2.5.29.19). 1527 * @return the length of the constraint. 1528 */ getBasicConstraints()1529 public int getBasicConstraints() { 1530 try { 1531 String extAlias = OIDMap.getName(PKIXExtensions.BasicConstraints_Id); 1532 if (extAlias == null) 1533 return -1; 1534 BasicConstraintsExtension certExt = 1535 (BasicConstraintsExtension)this.get(extAlias); 1536 if (certExt == null) 1537 return -1; 1538 1539 if (((Boolean)certExt.get(BasicConstraintsExtension.IS_CA) 1540 ).booleanValue() == true) 1541 return ((Integer)certExt.get( 1542 BasicConstraintsExtension.PATH_LEN)).intValue(); 1543 else 1544 return -1; 1545 } catch (Exception e) { 1546 return -1; 1547 } 1548 } 1549 1550 /** 1551 * Converts a GeneralNames structure into an immutable Collection of 1552 * alternative names (subject or issuer) in the form required by 1553 * {@link #getSubjectAlternativeNames} or 1554 * {@link #getIssuerAlternativeNames}. 1555 * 1556 * @param names the GeneralNames to be converted 1557 * @return an immutable Collection of alternative names 1558 */ makeAltNames(GeneralNames names)1559 private static Collection<List<?>> makeAltNames(GeneralNames names) { 1560 if (names.isEmpty()) { 1561 return Collections.<List<?>>emptySet(); 1562 } 1563 List<List<?>> newNames = new ArrayList<>(); 1564 for (GeneralName gname : names.names()) { 1565 GeneralNameInterface name = gname.getName(); 1566 List<Object> nameEntry = new ArrayList<>(2); 1567 nameEntry.add(Integer.valueOf(name.getType())); 1568 switch (name.getType()) { 1569 case GeneralNameInterface.NAME_RFC822: 1570 nameEntry.add(((RFC822Name) name).getName()); 1571 break; 1572 case GeneralNameInterface.NAME_DNS: 1573 nameEntry.add(((DNSName) name).getName()); 1574 break; 1575 case GeneralNameInterface.NAME_DIRECTORY: 1576 nameEntry.add(((X500Name) name).getRFC2253Name()); 1577 break; 1578 case GeneralNameInterface.NAME_URI: 1579 nameEntry.add(((URIName) name).getName()); 1580 break; 1581 case GeneralNameInterface.NAME_IP: 1582 try { 1583 nameEntry.add(((IPAddressName) name).getName()); 1584 } catch (IOException ioe) { 1585 // IPAddressName in cert is bogus 1586 throw new RuntimeException("IPAddress cannot be parsed", 1587 ioe); 1588 } 1589 break; 1590 case GeneralNameInterface.NAME_OID: 1591 nameEntry.add(((OIDName) name).getOID().toString()); 1592 break; 1593 default: 1594 // add DER encoded form 1595 DerOutputStream derOut = new DerOutputStream(); 1596 try { 1597 name.encode(derOut); 1598 } catch (IOException ioe) { 1599 // should not occur since name has already been decoded 1600 // from cert (this would indicate a bug in our code) 1601 throw new RuntimeException("name cannot be encoded", ioe); 1602 } 1603 nameEntry.add(derOut.toByteArray()); 1604 break; 1605 } 1606 newNames.add(Collections.unmodifiableList(nameEntry)); 1607 } 1608 return Collections.unmodifiableCollection(newNames); 1609 } 1610 1611 /** 1612 * Checks a Collection of altNames and clones any name entries of type 1613 * byte []. 1614 */ // only partially generified due to javac bug cloneAltNames(Collection<List<?>> altNames)1615 private static Collection<List<?>> cloneAltNames(Collection<List<?>> altNames) { 1616 boolean mustClone = false; 1617 for (List<?> nameEntry : altNames) { 1618 if (nameEntry.get(1) instanceof byte[]) { 1619 // must clone names 1620 mustClone = true; 1621 } 1622 } 1623 if (mustClone) { 1624 List<List<?>> namesCopy = new ArrayList<>(); 1625 for (List<?> nameEntry : altNames) { 1626 Object nameObject = nameEntry.get(1); 1627 if (nameObject instanceof byte[]) { 1628 List<Object> nameEntryCopy = 1629 new ArrayList<>(nameEntry); 1630 nameEntryCopy.set(1, ((byte[])nameObject).clone()); 1631 namesCopy.add(Collections.unmodifiableList(nameEntryCopy)); 1632 } else { 1633 namesCopy.add(nameEntry); 1634 } 1635 } 1636 return Collections.unmodifiableCollection(namesCopy); 1637 } else { 1638 return altNames; 1639 } 1640 } 1641 1642 /** 1643 * This method are the overridden implementation of 1644 * getSubjectAlternativeNames method in X509Certificate in the Sun 1645 * provider. It is better performance-wise since it returns cached 1646 * values. 1647 */ getSubjectAlternativeNames()1648 public synchronized Collection<List<?>> getSubjectAlternativeNames() 1649 throws CertificateParsingException { 1650 // return cached value if we can 1651 if (readOnly && subjectAlternativeNames != null) { 1652 return cloneAltNames(subjectAlternativeNames); 1653 } 1654 SubjectAlternativeNameExtension subjectAltNameExt = 1655 getSubjectAlternativeNameExtension(); 1656 if (subjectAltNameExt == null) { 1657 return null; 1658 } 1659 GeneralNames names; 1660 try { 1661 names = subjectAltNameExt.get( 1662 SubjectAlternativeNameExtension.SUBJECT_NAME); 1663 } catch (IOException ioe) { 1664 // should not occur 1665 return Collections.<List<?>>emptySet(); 1666 } 1667 subjectAlternativeNames = makeAltNames(names); 1668 return subjectAlternativeNames; 1669 } 1670 1671 /** 1672 * This static method is the default implementation of the 1673 * getSubjectAlternaitveNames method in X509Certificate. A 1674 * X509Certificate provider generally should overwrite this to 1675 * provide among other things caching for better performance. 1676 */ getSubjectAlternativeNames(X509Certificate cert)1677 public static Collection<List<?>> getSubjectAlternativeNames(X509Certificate cert) 1678 throws CertificateParsingException { 1679 try { 1680 byte[] ext = cert.getExtensionValue(SUBJECT_ALT_NAME_OID); 1681 if (ext == null) { 1682 return null; 1683 } 1684 DerValue val = new DerValue(ext); 1685 byte[] data = val.getOctetString(); 1686 1687 SubjectAlternativeNameExtension subjectAltNameExt = 1688 new SubjectAlternativeNameExtension(Boolean.FALSE, 1689 data); 1690 1691 GeneralNames names; 1692 try { 1693 names = subjectAltNameExt.get( 1694 SubjectAlternativeNameExtension.SUBJECT_NAME); 1695 } catch (IOException ioe) { 1696 // should not occur 1697 return Collections.<List<?>>emptySet(); 1698 } 1699 return makeAltNames(names); 1700 } catch (IOException ioe) { 1701 throw new CertificateParsingException(ioe); 1702 } 1703 } 1704 1705 /** 1706 * This method are the overridden implementation of 1707 * getIssuerAlternativeNames method in X509Certificate in the Sun 1708 * provider. It is better performance-wise since it returns cached 1709 * values. 1710 */ getIssuerAlternativeNames()1711 public synchronized Collection<List<?>> getIssuerAlternativeNames() 1712 throws CertificateParsingException { 1713 // return cached value if we can 1714 if (readOnly && issuerAlternativeNames != null) { 1715 return cloneAltNames(issuerAlternativeNames); 1716 } 1717 IssuerAlternativeNameExtension issuerAltNameExt = 1718 getIssuerAlternativeNameExtension(); 1719 if (issuerAltNameExt == null) { 1720 return null; 1721 } 1722 GeneralNames names; 1723 try { 1724 names = issuerAltNameExt.get( 1725 IssuerAlternativeNameExtension.ISSUER_NAME); 1726 } catch (IOException ioe) { 1727 // should not occur 1728 return Collections.<List<?>>emptySet(); 1729 } 1730 issuerAlternativeNames = makeAltNames(names); 1731 return issuerAlternativeNames; 1732 } 1733 1734 /** 1735 * This static method is the default implementation of the 1736 * getIssuerAlternaitveNames method in X509Certificate. A 1737 * X509Certificate provider generally should overwrite this to 1738 * provide among other things caching for better performance. 1739 */ getIssuerAlternativeNames(X509Certificate cert)1740 public static Collection<List<?>> getIssuerAlternativeNames(X509Certificate cert) 1741 throws CertificateParsingException { 1742 try { 1743 byte[] ext = cert.getExtensionValue(ISSUER_ALT_NAME_OID); 1744 if (ext == null) { 1745 return null; 1746 } 1747 1748 DerValue val = new DerValue(ext); 1749 byte[] data = val.getOctetString(); 1750 1751 IssuerAlternativeNameExtension issuerAltNameExt = 1752 new IssuerAlternativeNameExtension(Boolean.FALSE, 1753 data); 1754 GeneralNames names; 1755 try { 1756 names = issuerAltNameExt.get( 1757 IssuerAlternativeNameExtension.ISSUER_NAME); 1758 } catch (IOException ioe) { 1759 // should not occur 1760 return Collections.<List<?>>emptySet(); 1761 } 1762 return makeAltNames(names); 1763 } catch (IOException ioe) { 1764 throw new CertificateParsingException(ioe); 1765 } 1766 } 1767 getAuthorityInfoAccessExtension()1768 public AuthorityInfoAccessExtension getAuthorityInfoAccessExtension() { 1769 return (AuthorityInfoAccessExtension) 1770 getExtension(PKIXExtensions.AuthInfoAccess_Id); 1771 } 1772 1773 /************************************************************/ 1774 1775 /* 1776 * Cert is a SIGNED ASN.1 macro, a three elment sequence: 1777 * 1778 * - Data to be signed (ToBeSigned) -- the "raw" cert 1779 * - Signature algorithm (SigAlgId) 1780 * - The signature bits 1781 * 1782 * This routine unmarshals the certificate, saving the signature 1783 * parts away for later verification. 1784 */ parse(DerValue val)1785 private void parse(DerValue val) 1786 throws CertificateException, IOException { 1787 // BEGIN Android-added: Use original encoded form of cert rather than regenerating. 1788 parse( 1789 val, 1790 null // use re-encoded form of val as the encoded form 1791 ); 1792 } 1793 1794 /* 1795 * Cert is a SIGNED ASN.1 macro, a three elment sequence: 1796 * 1797 * - Data to be signed (ToBeSigned) -- the "raw" cert 1798 * - Signature algorithm (SigAlgId) 1799 * - The signature bits 1800 * 1801 * This routine unmarshals the certificate, saving the signature 1802 * parts away for later verification. 1803 */ parse(DerValue val, byte[] originalEncodedForm)1804 private void parse(DerValue val, byte[] originalEncodedForm) 1805 throws CertificateException, IOException { 1806 // END Android-added: Use original encoded form of cert rather than regenerating. 1807 1808 // check if can over write the certificate 1809 if (readOnly) 1810 throw new CertificateParsingException( 1811 "cannot over-write existing certificate"); 1812 1813 if (val.data == null || val.tag != DerValue.tag_Sequence) 1814 throw new CertificateParsingException( 1815 "invalid DER-encoded certificate data"); 1816 1817 // Android-changed: Needed for providing encoded form of cert. 1818 // signedCert = val.toByteArray(); 1819 signedCert = 1820 (originalEncodedForm != null) 1821 ? originalEncodedForm : val.toByteArray(); 1822 DerValue[] seq = new DerValue[3]; 1823 1824 seq[0] = val.data.getDerValue(); 1825 seq[1] = val.data.getDerValue(); 1826 seq[2] = val.data.getDerValue(); 1827 1828 if (val.data.available() != 0) { 1829 throw new CertificateParsingException("signed overrun, bytes = " 1830 + val.data.available()); 1831 } 1832 if (seq[0].tag != DerValue.tag_Sequence) { 1833 throw new CertificateParsingException("signed fields invalid"); 1834 } 1835 1836 algId = AlgorithmId.parse(seq[1]); 1837 signature = seq[2].getBitString(); 1838 1839 if (seq[1].data.available() != 0) { 1840 throw new CertificateParsingException("algid field overrun"); 1841 } 1842 if (seq[2].data.available() != 0) 1843 throw new CertificateParsingException("signed fields overrun"); 1844 1845 // The CertificateInfo 1846 info = new X509CertInfo(seq[0]); 1847 1848 // the "inner" and "outer" signature algorithms must match 1849 AlgorithmId infoSigAlg = (AlgorithmId)info.get( 1850 CertificateAlgorithmId.NAME 1851 + DOT + 1852 CertificateAlgorithmId.ALGORITHM); 1853 if (! algId.equals(infoSigAlg)) 1854 throw new CertificateException("Signature algorithm mismatch"); 1855 readOnly = true; 1856 } 1857 1858 /** 1859 * Extract the subject or issuer X500Principal from an X509Certificate. 1860 * Parses the encoded form of the cert to preserve the principal's 1861 * ASN.1 encoding. 1862 */ getX500Principal(X509Certificate cert, boolean getIssuer)1863 private static X500Principal getX500Principal(X509Certificate cert, 1864 boolean getIssuer) throws Exception { 1865 byte[] encoded = cert.getEncoded(); 1866 DerInputStream derIn = new DerInputStream(encoded); 1867 DerValue tbsCert = derIn.getSequence(3)[0]; 1868 DerInputStream tbsIn = tbsCert.data; 1869 DerValue tmp; 1870 tmp = tbsIn.getDerValue(); 1871 // skip version number if present 1872 if (tmp.isContextSpecific((byte)0)) { 1873 tmp = tbsIn.getDerValue(); 1874 } 1875 // tmp always contains serial number now 1876 tmp = tbsIn.getDerValue(); // skip signature 1877 tmp = tbsIn.getDerValue(); // issuer 1878 if (getIssuer == false) { 1879 tmp = tbsIn.getDerValue(); // skip validity 1880 tmp = tbsIn.getDerValue(); // subject 1881 } 1882 byte[] principalBytes = tmp.toByteArray(); 1883 return new X500Principal(principalBytes); 1884 } 1885 1886 /** 1887 * Extract the subject X500Principal from an X509Certificate. 1888 * Called from java.security.cert.X509Certificate.getSubjectX500Principal(). 1889 */ getSubjectX500Principal(X509Certificate cert)1890 public static X500Principal getSubjectX500Principal(X509Certificate cert) { 1891 try { 1892 return getX500Principal(cert, false); 1893 } catch (Exception e) { 1894 throw new RuntimeException("Could not parse subject", e); 1895 } 1896 } 1897 1898 /** 1899 * Extract the issuer X500Principal from an X509Certificate. 1900 * Called from java.security.cert.X509Certificate.getIssuerX500Principal(). 1901 */ getIssuerX500Principal(X509Certificate cert)1902 public static X500Principal getIssuerX500Principal(X509Certificate cert) { 1903 try { 1904 return getX500Principal(cert, true); 1905 } catch (Exception e) { 1906 throw new RuntimeException("Could not parse issuer", e); 1907 } 1908 } 1909 1910 /** 1911 * Returned the encoding of the given certificate for internal use. 1912 * Callers must guarantee that they neither modify it nor expose it 1913 * to untrusted code. Uses getEncodedInternal() if the certificate 1914 * is instance of X509CertImpl, getEncoded() otherwise. 1915 */ getEncodedInternal(Certificate cert)1916 public static byte[] getEncodedInternal(Certificate cert) 1917 throws CertificateEncodingException { 1918 if (cert instanceof X509CertImpl) { 1919 return ((X509CertImpl)cert).getEncodedInternal(); 1920 } else { 1921 return cert.getEncoded(); 1922 } 1923 } 1924 1925 /** 1926 * Utility method to convert an arbitrary instance of X509Certificate 1927 * to a X509CertImpl. Does a cast if possible, otherwise reparses 1928 * the encoding. 1929 */ toImpl(X509Certificate cert)1930 public static X509CertImpl toImpl(X509Certificate cert) 1931 throws CertificateException { 1932 if (cert instanceof X509CertImpl) { 1933 return (X509CertImpl)cert; 1934 } else { 1935 return X509Factory.intern(cert); 1936 } 1937 } 1938 1939 /** 1940 * Utility method to test if a certificate is self-issued. This is 1941 * the case iff the subject and issuer X500Principals are equal. 1942 */ isSelfIssued(X509Certificate cert)1943 public static boolean isSelfIssued(X509Certificate cert) { 1944 X500Principal subject = cert.getSubjectX500Principal(); 1945 X500Principal issuer = cert.getIssuerX500Principal(); 1946 return subject.equals(issuer); 1947 } 1948 1949 /** 1950 * Utility method to test if a certificate is self-signed. This is 1951 * the case iff the subject and issuer X500Principals are equal 1952 * AND the certificate's subject public key can be used to verify 1953 * the certificate. In case of exception, returns false. 1954 */ isSelfSigned(X509Certificate cert, String sigProvider)1955 public static boolean isSelfSigned(X509Certificate cert, 1956 String sigProvider) { 1957 if (isSelfIssued(cert)) { 1958 try { 1959 if (sigProvider == null) { 1960 cert.verify(cert.getPublicKey()); 1961 } else { 1962 cert.verify(cert.getPublicKey(), sigProvider); 1963 } 1964 return true; 1965 } catch (Exception e) { 1966 // In case of exception, return false 1967 } 1968 } 1969 return false; 1970 } 1971 1972 private ConcurrentHashMap<String,String> fingerprints = 1973 new ConcurrentHashMap<>(2); 1974 1975 // BEGIN Android-removed: unused code. 1976 // public String getFingerprint(String algorithm) { 1977 // return fingerprints.computeIfAbsent(algorithm, 1978 // x -> getFingerprint(x, this)); 1979 // } 1980 // END Android-removed: unused code. 1981 1982 /** 1983 * Gets the requested finger print of the certificate. The result 1984 * only contains 0-9 and A-F. No small case, no colon. 1985 */ getFingerprint(String algorithm, X509Certificate cert)1986 public static String getFingerprint(String algorithm, 1987 X509Certificate cert) { 1988 String fingerPrint = ""; 1989 try { 1990 byte[] encCertInfo = cert.getEncoded(); 1991 MessageDigest md = MessageDigest.getInstance(algorithm); 1992 byte[] digest = md.digest(encCertInfo); 1993 StringBuffer buf = new StringBuffer(); 1994 for (int i = 0; i < digest.length; i++) { 1995 byte2hex(digest[i], buf); 1996 } 1997 fingerPrint = buf.toString(); 1998 } catch (NoSuchAlgorithmException | CertificateEncodingException e) { 1999 // ignored 2000 } 2001 return fingerPrint; 2002 } 2003 2004 // BEGIN Android-added: these methods are from OpenJDK 17. getFingerprint(String algorithm, Debug debug)2005 private String getFingerprint(String algorithm, Debug debug) { 2006 return fingerprints.computeIfAbsent(algorithm, 2007 x -> { 2008 try { 2009 return getFingerprintInternal(x, getEncodedInternal(), debug); 2010 } catch (CertificateEncodingException e) { 2011 if (debug != null) { 2012 debug.println("Cannot encode certificate: " + e); 2013 } 2014 return null; 2015 } 2016 }); 2017 } 2018 2019 private static String getFingerprintInternal(String algorithm, 2020 byte[] encodedCert, Debug debug) { 2021 try { 2022 MessageDigest md = MessageDigest.getInstance(algorithm); 2023 byte[] digest = md.digest(encodedCert); 2024 return HexFormat.of().withUpperCase().formatHex(digest); 2025 } catch (NoSuchAlgorithmException e) { 2026 if (debug != null) { 2027 debug.println("Cannot create " + algorithm 2028 + " MessageDigest: " + e); 2029 } 2030 return null; 2031 } 2032 } 2033 2034 /** 2035 * Gets the requested fingerprint of the certificate. The result 2036 * only contains 0-9 and A-F. No small case, no colon. 2037 * 2038 * @param algorithm the MessageDigest algorithm 2039 * @param cert the X509Certificate 2040 * @return the fingerprint, or null if it cannot be calculated because 2041 * of an exception 2042 */ 2043 public static String getFingerprint(String algorithm, 2044 X509Certificate cert, Debug debug) { 2045 if (cert instanceof X509CertImpl) { 2046 return ((X509CertImpl)cert).getFingerprint(algorithm, debug); 2047 } else { 2048 try { 2049 return getFingerprintInternal(algorithm, cert.getEncoded(), debug); 2050 } catch (CertificateEncodingException e) { 2051 if (debug != null) { 2052 debug.println("Cannot encode certificate: " + e); 2053 } 2054 return null; 2055 } 2056 } 2057 } 2058 // END Android-added: these methods are from OpenJDK 17. 2059 2060 /** 2061 * Converts a byte to hex digit and writes to the supplied buffer 2062 */ 2063 private static void byte2hex(byte b, StringBuffer buf) { 2064 char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', 2065 '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 2066 int high = ((b & 0xf0) >> 4); 2067 int low = (b & 0x0f); 2068 buf.append(hexChars[high]); 2069 buf.append(hexChars[low]); 2070 } 2071 } 2072