1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package sun.security.x509; 28 29 import java.io.*; 30 import java.util.*; 31 import java.security.*; 32 33 import sun.security.util.*; 34 35 36 /** 37 * This class identifies algorithms, such as cryptographic transforms, each 38 * of which may be associated with parameters. Instances of this base class 39 * are used when this runtime environment has no special knowledge of the 40 * algorithm type, and may also be used in other cases. Equivalence is 41 * defined according to OID and (where relevant) parameters. 42 * 43 * <P>Subclasses may be used, for example when when the algorithm ID has 44 * associated parameters which some code (e.g. code using public keys) needs 45 * to have parsed. Two examples of such algorithms are Diffie-Hellman key 46 * exchange, and the Digital Signature Standard Algorithm (DSS/DSA). 47 * 48 * <P>The OID constants defined in this class correspond to some widely 49 * used algorithms, for which conventional string names have been defined. 50 * This class is not a general repository for OIDs, or for such string names. 51 * Note that the mappings between algorithm IDs and algorithm names is 52 * not one-to-one. 53 * 54 * 55 * @author David Brownell 56 * @author Amit Kapoor 57 * @author Hemma Prafullchandra 58 */ 59 public class AlgorithmId implements Serializable, DerEncoder { 60 61 /** use serialVersionUID from JDK 1.1. for interoperability */ 62 private static final long serialVersionUID = 7205873507486557157L; 63 64 /** 65 * The object identitifer being used for this algorithm. 66 */ 67 private ObjectIdentifier algid; 68 69 // The (parsed) parameters 70 private AlgorithmParameters algParams; 71 private boolean constructedFromDer = true; 72 73 /** 74 * Parameters for this algorithm. These are stored in unparsed 75 * DER-encoded form; subclasses can be made to automaticaly parse 76 * them so there is fast access to these parameters. 77 */ 78 protected DerValue params; 79 80 81 /** 82 * Constructs an algorithm ID which will be initialized 83 * separately, for example by deserialization. 84 * @deprecated use one of the other constructors. 85 */ 86 @Deprecated AlgorithmId()87 public AlgorithmId() { } 88 89 /** 90 * Constructs a parameterless algorithm ID. 91 * 92 * @param oid the identifier for the algorithm 93 */ AlgorithmId(ObjectIdentifier oid)94 public AlgorithmId(ObjectIdentifier oid) { 95 algid = oid; 96 } 97 98 /** 99 * Constructs an algorithm ID with algorithm parameters. 100 * 101 * @param oid the identifier for the algorithm. 102 * @param algparams the associated algorithm parameters. 103 */ AlgorithmId(ObjectIdentifier oid, AlgorithmParameters algparams)104 public AlgorithmId(ObjectIdentifier oid, AlgorithmParameters algparams) { 105 algid = oid; 106 algParams = algparams; 107 constructedFromDer = false; 108 } 109 AlgorithmId(ObjectIdentifier oid, DerValue params)110 private AlgorithmId(ObjectIdentifier oid, DerValue params) 111 throws IOException { 112 this.algid = oid; 113 this.params = params; 114 if (this.params != null) { 115 decodeParams(); 116 } 117 } 118 decodeParams()119 protected void decodeParams() throws IOException { 120 String algidString = algid.toString(); 121 try { 122 algParams = AlgorithmParameters.getInstance(algidString); 123 } catch (NoSuchAlgorithmException e) { 124 /* 125 * This algorithm parameter type is not supported, so we cannot 126 * parse the parameters. 127 */ 128 algParams = null; 129 return; 130 } 131 132 // Decode (parse) the parameters 133 algParams.init(params.toByteArray()); 134 } 135 136 /** 137 * Marshal a DER-encoded "AlgorithmID" sequence on the DER stream. 138 */ encode(DerOutputStream out)139 public final void encode(DerOutputStream out) throws IOException { 140 derEncode(out); 141 } 142 143 /** 144 * DER encode this object onto an output stream. 145 * Implements the <code>DerEncoder</code> interface. 146 * 147 * @param out 148 * the output stream on which to write the DER encoding. 149 * 150 * @exception IOException on encoding error. 151 */ derEncode(OutputStream out)152 public void derEncode (OutputStream out) throws IOException { 153 DerOutputStream bytes = new DerOutputStream(); 154 DerOutputStream tmp = new DerOutputStream(); 155 156 bytes.putOID(algid); 157 // Setup params from algParams since no DER encoding is given 158 if (constructedFromDer == false) { 159 if (algParams != null) { 160 params = new DerValue(algParams.getEncoded()); 161 } else { 162 params = null; 163 } 164 } 165 if (params == null) { 166 // Changes backed out for compatibility with Solaris 167 168 // Several AlgorithmId should omit the whole parameter part when 169 // it's NULL. They are --- 170 // rfc3370 2.1: Implementations SHOULD generate SHA-1 171 // AlgorithmIdentifiers with absent parameters. 172 // rfc3447 C1: When id-sha1, id-sha224, id-sha256, id-sha384 and 173 // id-sha512 are used in an AlgorithmIdentifier the parameters 174 // (which are optional) SHOULD be omitted. 175 // rfc3279 2.3.2: The id-dsa algorithm syntax includes optional 176 // domain parameters... When omitted, the parameters component 177 // MUST be omitted entirely 178 // rfc3370 3.1: When the id-dsa-with-sha1 algorithm identifier 179 // is used, the AlgorithmIdentifier parameters field MUST be absent. 180 /*if ( 181 algid.equals((Object)SHA_oid) || 182 algid.equals((Object)SHA224_oid) || 183 algid.equals((Object)SHA256_oid) || 184 algid.equals((Object)SHA384_oid) || 185 algid.equals((Object)SHA512_oid) || 186 algid.equals((Object)DSA_oid) || 187 algid.equals((Object)sha1WithDSA_oid)) { 188 ; // no parameter part encoded 189 } else { 190 bytes.putNull(); 191 }*/ 192 bytes.putNull(); 193 } else { 194 bytes.putDerValue(params); 195 } 196 tmp.write(DerValue.tag_Sequence, bytes); 197 out.write(tmp.toByteArray()); 198 } 199 200 201 /** 202 * Returns the DER-encoded X.509 AlgorithmId as a byte array. 203 */ encode()204 public final byte[] encode() throws IOException { 205 DerOutputStream out = new DerOutputStream(); 206 derEncode(out); 207 return out.toByteArray(); 208 } 209 210 /** 211 * Returns the ISO OID for this algorithm. This is usually converted 212 * to a string and used as part of an algorithm name, for example 213 * "OID.1.3.14.3.2.13" style notation. Use the <code>getName</code> 214 * call when you do not need to ensure cross-system portability 215 * of algorithm names, or need a user friendly name. 216 */ getOID()217 public final ObjectIdentifier getOID () { 218 return algid; 219 } 220 221 /** 222 * Returns a name for the algorithm which may be more intelligible 223 * to humans than the algorithm's OID, but which won't necessarily 224 * be comprehensible on other systems. For example, this might 225 * return a name such as "MD5withRSA" for a signature algorithm on 226 * some systems. It also returns names like "OID.1.2.3.4", when 227 * no particular name for the algorithm is known. 228 */ getName()229 public String getName() { 230 String algName = nameTable.get(algid); 231 if (algName != null) { 232 return algName; 233 } 234 if ((params != null) && algid.equals((Object)specifiedWithECDSA_oid)) { 235 try { 236 AlgorithmId paramsId = 237 AlgorithmId.parse(new DerValue(getEncodedParams())); 238 String paramsName = paramsId.getName(); 239 algName = makeSigAlg(paramsName, "EC"); 240 } catch (IOException e) { 241 // ignore 242 } 243 } 244 245 // BEGIN Android-added: Update algorithm mapping tables for names when OID is used 246 // Try to update the name <-> OID mapping table. 247 synchronized (oidTable) { 248 reinitializeMappingTableLocked(); 249 algName = nameTable.get(algid); 250 } 251 // END Android-added: Update algorithm mapping tables for names when OID is used 252 253 return (algName == null) ? algid.toString() : algName; 254 } 255 getParameters()256 public AlgorithmParameters getParameters() { 257 return algParams; 258 } 259 260 /** 261 * Returns the DER encoded parameter, which can then be 262 * used to initialize java.security.AlgorithmParamters. 263 * 264 * @return DER encoded parameters, or null not present. 265 */ getEncodedParams()266 public byte[] getEncodedParams() throws IOException { 267 return (params == null) ? null : params.toByteArray(); 268 } 269 270 /** 271 * Returns true iff the argument indicates the same algorithm 272 * with the same parameters. 273 */ equals(AlgorithmId other)274 public boolean equals(AlgorithmId other) { 275 boolean paramsEqual = 276 (params == null ? other.params == null : params.equals(other.params)); 277 return (algid.equals((Object)other.algid) && paramsEqual); 278 } 279 280 /** 281 * Compares this AlgorithmID to another. If algorithm parameters are 282 * available, they are compared. Otherwise, just the object IDs 283 * for the algorithm are compared. 284 * 285 * @param other preferably an AlgorithmId, else an ObjectIdentifier 286 */ equals(Object other)287 public boolean equals(Object other) { 288 if (this == other) { 289 return true; 290 } 291 if (other instanceof AlgorithmId) { 292 return equals((AlgorithmId) other); 293 } else if (other instanceof ObjectIdentifier) { 294 return equals((ObjectIdentifier) other); 295 } else { 296 return false; 297 } 298 } 299 300 /** 301 * Compares two algorithm IDs for equality. Returns true iff 302 * they are the same algorithm, ignoring algorithm parameters. 303 */ equals(ObjectIdentifier id)304 public final boolean equals(ObjectIdentifier id) { 305 return algid.equals((Object)id); 306 } 307 308 /** 309 * Returns a hashcode for this AlgorithmId. 310 * 311 * @return a hashcode for this AlgorithmId. 312 */ hashCode()313 public int hashCode() { 314 StringBuilder sbuf = new StringBuilder(); 315 sbuf.append(algid.toString()); 316 sbuf.append(paramsToString()); 317 return sbuf.toString().hashCode(); 318 } 319 320 /** 321 * Provides a human-readable description of the algorithm parameters. 322 * This may be redefined by subclasses which parse those parameters. 323 */ paramsToString()324 protected String paramsToString() { 325 if (params == null) { 326 return ""; 327 } else if (algParams != null) { 328 return algParams.toString(); 329 } else { 330 return ", params unparsed"; 331 } 332 } 333 334 /** 335 * Returns a string describing the algorithm and its parameters. 336 */ toString()337 public String toString() { 338 return getName() + paramsToString(); 339 } 340 341 /** 342 * Parse (unmarshal) an ID from a DER sequence input value. This form 343 * parsing might be used when expanding a value which has already been 344 * partially unmarshaled as a set or sequence member. 345 * 346 * @exception IOException on error. 347 * @param val the input value, which contains the algid and, if 348 * there are any parameters, those parameters. 349 * @return an ID for the algorithm. If the system is configured 350 * appropriately, this may be an instance of a class 351 * with some kind of special support for this algorithm. 352 * In that case, you may "narrow" the type of the ID. 353 */ parse(DerValue val)354 public static AlgorithmId parse(DerValue val) throws IOException { 355 if (val.tag != DerValue.tag_Sequence) { 356 throw new IOException("algid parse error, not a sequence"); 357 } 358 359 /* 360 * Get the algorithm ID and any parameters. 361 */ 362 ObjectIdentifier algid; 363 DerValue params; 364 DerInputStream in = val.toDerInputStream(); 365 366 algid = in.getOID(); 367 if (in.available() == 0) { 368 params = null; 369 } else { 370 params = in.getDerValue(); 371 if (params.tag == DerValue.tag_Null) { 372 if (params.length() != 0) { 373 throw new IOException("invalid NULL"); 374 } 375 params = null; 376 } 377 if (in.available() != 0) { 378 throw new IOException("Invalid AlgorithmIdentifier: extra data"); 379 } 380 } 381 382 return new AlgorithmId(algid, params); 383 } 384 385 /** 386 * Returns one of the algorithm IDs most commonly associated 387 * with this algorithm name. 388 * 389 * @param algname the name being used 390 * @deprecated use the short get form of this method. 391 * @exception NoSuchAlgorithmException on error. 392 */ 393 @Deprecated getAlgorithmId(String algname)394 public static AlgorithmId getAlgorithmId(String algname) 395 throws NoSuchAlgorithmException { 396 return get(algname); 397 } 398 399 /** 400 * Returns one of the algorithm IDs most commonly associated 401 * with this algorithm name. 402 * 403 * @param algname the name being used 404 * @exception NoSuchAlgorithmException on error. 405 */ get(String algname)406 public static AlgorithmId get(String algname) 407 throws NoSuchAlgorithmException { 408 ObjectIdentifier oid; 409 try { 410 oid = algOID(algname); 411 } catch (IOException ioe) { 412 throw new NoSuchAlgorithmException 413 ("Invalid ObjectIdentifier " + algname); 414 } 415 416 if (oid == null) { 417 throw new NoSuchAlgorithmException 418 ("unrecognized algorithm name: " + algname); 419 } 420 return new AlgorithmId(oid); 421 } 422 423 /** 424 * Returns one of the algorithm IDs most commonly associated 425 * with this algorithm parameters. 426 * 427 * @param algparams the associated algorithm parameters. 428 * @exception NoSuchAlgorithmException on error. 429 */ get(AlgorithmParameters algparams)430 public static AlgorithmId get(AlgorithmParameters algparams) 431 throws NoSuchAlgorithmException { 432 ObjectIdentifier oid; 433 String algname = algparams.getAlgorithm(); 434 try { 435 oid = algOID(algname); 436 } catch (IOException ioe) { 437 throw new NoSuchAlgorithmException 438 ("Invalid ObjectIdentifier " + algname); 439 } 440 if (oid == null) { 441 throw new NoSuchAlgorithmException 442 ("unrecognized algorithm name: " + algname); 443 } 444 return new AlgorithmId(oid, algparams); 445 } 446 447 /* 448 * Translates from some common algorithm names to the 449 * OID with which they're usually associated ... this mapping 450 * is the reverse of the one below, except in those cases 451 * where synonyms are supported or where a given algorithm 452 * is commonly associated with multiple OIDs. 453 * 454 * XXX This method needs to be enhanced so that we can also pass the 455 * scope of the algorithm name to it, e.g., the algorithm name "DSA" 456 * may have a different OID when used as a "Signature" algorithm than when 457 * used as a "KeyPairGenerator" algorithm. 458 */ algOID(String name)459 private static ObjectIdentifier algOID(String name) throws IOException { 460 // See if algname is in printable OID ("dot-dot") notation 461 if (name.indexOf('.') != -1) { 462 if (name.startsWith("OID.")) { 463 return new ObjectIdentifier(name.substring("OID.".length())); 464 } else { 465 return new ObjectIdentifier(name); 466 } 467 } 468 469 // Digesting algorithms 470 if (name.equalsIgnoreCase("MD5")) { 471 return AlgorithmId.MD5_oid; 472 } 473 if (name.equalsIgnoreCase("MD2")) { 474 return AlgorithmId.MD2_oid; 475 } 476 if (name.equalsIgnoreCase("SHA") || name.equalsIgnoreCase("SHA1") 477 || name.equalsIgnoreCase("SHA-1")) { 478 return AlgorithmId.SHA_oid; 479 } 480 if (name.equalsIgnoreCase("SHA-256") || 481 name.equalsIgnoreCase("SHA256")) { 482 return AlgorithmId.SHA256_oid; 483 } 484 if (name.equalsIgnoreCase("SHA-384") || 485 name.equalsIgnoreCase("SHA384")) { 486 return AlgorithmId.SHA384_oid; 487 } 488 if (name.equalsIgnoreCase("SHA-512") || 489 name.equalsIgnoreCase("SHA512")) { 490 return AlgorithmId.SHA512_oid; 491 } 492 if (name.equalsIgnoreCase("SHA-224") || 493 name.equalsIgnoreCase("SHA224")) { 494 return AlgorithmId.SHA224_oid; 495 } 496 497 // Various public key algorithms 498 if (name.equalsIgnoreCase("RSA")) { 499 return AlgorithmId.RSAEncryption_oid; 500 } 501 if (name.equalsIgnoreCase("Diffie-Hellman") 502 || name.equalsIgnoreCase("DH")) { 503 return AlgorithmId.DH_oid; 504 } 505 if (name.equalsIgnoreCase("DSA")) { 506 return AlgorithmId.DSA_oid; 507 } 508 if (name.equalsIgnoreCase("EC")) { 509 return EC_oid; 510 } 511 if (name.equalsIgnoreCase("ECDH")) { 512 return AlgorithmId.ECDH_oid; 513 } 514 515 // Secret key algorithms 516 if (name.equalsIgnoreCase("AES")) { 517 return AlgorithmId.AES_oid; 518 } 519 520 // Common signature types 521 if (name.equalsIgnoreCase("MD5withRSA") 522 || name.equalsIgnoreCase("MD5/RSA")) { 523 return AlgorithmId.md5WithRSAEncryption_oid; 524 } 525 if (name.equalsIgnoreCase("MD2withRSA") 526 || name.equalsIgnoreCase("MD2/RSA")) { 527 return AlgorithmId.md2WithRSAEncryption_oid; 528 } 529 if (name.equalsIgnoreCase("SHAwithDSA") 530 || name.equalsIgnoreCase("SHA1withDSA") 531 || name.equalsIgnoreCase("SHA/DSA") 532 || name.equalsIgnoreCase("SHA1/DSA") 533 || name.equalsIgnoreCase("DSAWithSHA1") 534 || name.equalsIgnoreCase("DSS") 535 || name.equalsIgnoreCase("SHA-1/DSA")) { 536 return AlgorithmId.sha1WithDSA_oid; 537 } 538 if (name.equalsIgnoreCase("SHA224WithDSA")) { 539 return AlgorithmId.sha224WithDSA_oid; 540 } 541 if (name.equalsIgnoreCase("SHA256WithDSA")) { 542 return AlgorithmId.sha256WithDSA_oid; 543 } 544 if (name.equalsIgnoreCase("SHA1WithRSA") 545 || name.equalsIgnoreCase("SHA1/RSA")) { 546 return AlgorithmId.sha1WithRSAEncryption_oid; 547 } 548 if (name.equalsIgnoreCase("SHA1withECDSA") 549 || name.equalsIgnoreCase("ECDSA")) { 550 return AlgorithmId.sha1WithECDSA_oid; 551 } 552 if (name.equalsIgnoreCase("SHA224withECDSA")) { 553 return AlgorithmId.sha224WithECDSA_oid; 554 } 555 if (name.equalsIgnoreCase("SHA256withECDSA")) { 556 return AlgorithmId.sha256WithECDSA_oid; 557 } 558 if (name.equalsIgnoreCase("SHA384withECDSA")) { 559 return AlgorithmId.sha384WithECDSA_oid; 560 } 561 if (name.equalsIgnoreCase("SHA512withECDSA")) { 562 return AlgorithmId.sha512WithECDSA_oid; 563 } 564 565 // See if any of the installed providers supply a mapping from 566 // the given algorithm name to an OID string 567 // BEGIN Android-changed: Update algorithm mapping tables for names when OID is used 568 synchronized (oidTable) { 569 reinitializeMappingTableLocked(); 570 return oidTable.get(name.toUpperCase(Locale.ENGLISH)); 571 } 572 } 573 reinitializeMappingTableLocked()574 private static void reinitializeMappingTableLocked() { 575 // Android-changed: Update the table only if the OID changed. Also synchronize 576 // on oidTable for thread safety. 577 int currentVersion = Security.getVersion(); 578 if (initOidTableVersion != currentVersion) { 579 Provider[] provs = Security.getProviders(); 580 for (int i=0; i<provs.length; i++) { 581 for (Enumeration<Object> enum_ = provs[i].keys(); 582 enum_.hasMoreElements(); ) { 583 String alias = (String)enum_.nextElement(); 584 String upperCaseAlias = alias.toUpperCase(Locale.ENGLISH); 585 int index; 586 if (upperCaseAlias.startsWith("ALG.ALIAS")) { 587 if ((index=upperCaseAlias.indexOf("OID.", 0)) != -1) { 588 index += "OID.".length(); 589 if (index == alias.length()) { 590 // invalid alias entry 591 break; 592 } 593 String oidString = alias.substring(index); 594 String stdAlgName = provs[i].getProperty(alias); 595 if (stdAlgName != null) { 596 stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH); 597 598 ObjectIdentifier oid = null; 599 try { 600 oid = new ObjectIdentifier(oidString); 601 } catch (IOException e) { 602 // Not an OID. 603 } 604 605 if (oid != null) { 606 if (!oidTable.containsKey(stdAlgName)) { 607 oidTable.put(stdAlgName, oid); 608 } 609 if (!nameTable.containsKey(oid)) { 610 nameTable.put(oid, stdAlgName); 611 } 612 } 613 } 614 } else { 615 // Android-changed: If the alias isn't specified with an explicit 616 // "OID." in the name, we still attempt to parse it as one. 617 final int sep = alias.indexOf('.', "ALG.ALIAS.".length()); 618 String suffix = alias.substring(sep + 1); 619 620 ObjectIdentifier oid = null; 621 try { 622 oid = new ObjectIdentifier(suffix); 623 } catch (IOException e) { 624 // Not an OID. 625 } 626 627 if (oid != null) { 628 String stdAlgName = provs[i].getProperty(alias); 629 if (stdAlgName != null) { 630 stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH); 631 if (!oidTable.containsKey(stdAlgName)) { 632 oidTable.put(stdAlgName, oid); 633 } 634 if (!nameTable.containsKey(oid)) { 635 nameTable.put(oid, stdAlgName); 636 } 637 } 638 } 639 } 640 } 641 } 642 } 643 644 initOidTableVersion = currentVersion; 645 } 646 // END Android-changed: Update algorithm mapping tables for names when OID is used 647 } 648 oid(int ... values)649 private static ObjectIdentifier oid(int ... values) { 650 return ObjectIdentifier.newInternal(values); 651 } 652 653 // BEGIN Android-changed: Parsing mapping as OID even if "OID." prefix isn't specified 654 private static int initOidTableVersion = -1; 655 private static final Map<String,ObjectIdentifier> oidTable = 656 new HashMap<String,ObjectIdentifier>(1); 657 private static final Map<ObjectIdentifier,String> nameTable = 658 new HashMap<ObjectIdentifier,String>(); 659 // END Android-changed: Parsing mapping as OID even if "OID." prefix isn't specified 660 661 /*****************************************************************/ 662 663 /* 664 * HASHING ALGORITHMS 665 */ 666 667 /** 668 * Algorithm ID for the MD2 Message Digest Algorthm, from RFC 1319. 669 * OID = 1.2.840.113549.2.2 670 */ 671 public static final ObjectIdentifier MD2_oid = 672 ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 2, 2}); 673 674 /** 675 * Algorithm ID for the MD5 Message Digest Algorthm, from RFC 1321. 676 * OID = 1.2.840.113549.2.5 677 */ 678 public static final ObjectIdentifier MD5_oid = 679 ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 2, 5}); 680 681 /** 682 * Algorithm ID for the SHA1 Message Digest Algorithm, from FIPS 180-1. 683 * This is sometimes called "SHA", though that is often confusing since 684 * many people refer to FIPS 180 (which has an error) as defining SHA. 685 * OID = 1.3.14.3.2.26. Old SHA-0 OID: 1.3.14.3.2.18. 686 */ 687 public static final ObjectIdentifier SHA_oid = 688 ObjectIdentifier.newInternal(new int[] {1, 3, 14, 3, 2, 26}); 689 690 public static final ObjectIdentifier SHA224_oid = 691 ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 4}); 692 693 public static final ObjectIdentifier SHA256_oid = 694 ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 1}); 695 696 public static final ObjectIdentifier SHA384_oid = 697 ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 2}); 698 699 public static final ObjectIdentifier SHA512_oid = 700 ObjectIdentifier.newInternal(new int[] {2, 16, 840, 1, 101, 3, 4, 2, 3}); 701 702 /* 703 * COMMON PUBLIC KEY TYPES 704 */ 705 private static final int DH_data[] = { 1, 2, 840, 113549, 1, 3, 1 }; 706 private static final int DH_PKIX_data[] = { 1, 2, 840, 10046, 2, 1 }; 707 private static final int DSA_OIW_data[] = { 1, 3, 14, 3, 2, 12 }; 708 private static final int DSA_PKIX_data[] = { 1, 2, 840, 10040, 4, 1 }; 709 private static final int RSA_data[] = { 2, 5, 8, 1, 1 }; 710 private static final int RSAEncryption_data[] = 711 { 1, 2, 840, 113549, 1, 1, 1 }; 712 713 public static final ObjectIdentifier DH_oid; 714 public static final ObjectIdentifier DH_PKIX_oid; 715 public static final ObjectIdentifier DSA_oid; 716 public static final ObjectIdentifier DSA_OIW_oid; 717 public static final ObjectIdentifier EC_oid = oid(1, 2, 840, 10045, 2, 1); 718 public static final ObjectIdentifier ECDH_oid = oid(1, 3, 132, 1, 12); 719 public static final ObjectIdentifier RSA_oid; 720 public static final ObjectIdentifier RSAEncryption_oid; 721 722 /* 723 * COMMON SECRET KEY TYPES 724 */ 725 public static final ObjectIdentifier AES_oid = 726 oid(2, 16, 840, 1, 101, 3, 4, 1); 727 728 /* 729 * COMMON SIGNATURE ALGORITHMS 730 */ 731 private static final int md2WithRSAEncryption_data[] = 732 { 1, 2, 840, 113549, 1, 1, 2 }; 733 private static final int md5WithRSAEncryption_data[] = 734 { 1, 2, 840, 113549, 1, 1, 4 }; 735 private static final int sha1WithRSAEncryption_data[] = 736 { 1, 2, 840, 113549, 1, 1, 5 }; 737 private static final int sha1WithRSAEncryption_OIW_data[] = 738 { 1, 3, 14, 3, 2, 29 }; 739 private static final int sha224WithRSAEncryption_data[] = 740 { 1, 2, 840, 113549, 1, 1, 14 }; 741 private static final int sha256WithRSAEncryption_data[] = 742 { 1, 2, 840, 113549, 1, 1, 11 }; 743 private static final int sha384WithRSAEncryption_data[] = 744 { 1, 2, 840, 113549, 1, 1, 12 }; 745 private static final int sha512WithRSAEncryption_data[] = 746 { 1, 2, 840, 113549, 1, 1, 13 }; 747 private static final int shaWithDSA_OIW_data[] = 748 { 1, 3, 14, 3, 2, 13 }; 749 private static final int sha1WithDSA_OIW_data[] = 750 { 1, 3, 14, 3, 2, 27 }; 751 private static final int dsaWithSHA1_PKIX_data[] = 752 { 1, 2, 840, 10040, 4, 3 }; 753 754 public static final ObjectIdentifier md2WithRSAEncryption_oid; 755 public static final ObjectIdentifier md5WithRSAEncryption_oid; 756 public static final ObjectIdentifier sha1WithRSAEncryption_oid; 757 public static final ObjectIdentifier sha1WithRSAEncryption_OIW_oid; 758 public static final ObjectIdentifier sha224WithRSAEncryption_oid; 759 public static final ObjectIdentifier sha256WithRSAEncryption_oid; 760 public static final ObjectIdentifier sha384WithRSAEncryption_oid; 761 public static final ObjectIdentifier sha512WithRSAEncryption_oid; 762 public static final ObjectIdentifier shaWithDSA_OIW_oid; 763 public static final ObjectIdentifier sha1WithDSA_OIW_oid; 764 public static final ObjectIdentifier sha1WithDSA_oid; 765 public static final ObjectIdentifier sha224WithDSA_oid = 766 oid(2, 16, 840, 1, 101, 3, 4, 3, 1); 767 public static final ObjectIdentifier sha256WithDSA_oid = 768 oid(2, 16, 840, 1, 101, 3, 4, 3, 2); 769 770 public static final ObjectIdentifier sha1WithECDSA_oid = 771 oid(1, 2, 840, 10045, 4, 1); 772 public static final ObjectIdentifier sha224WithECDSA_oid = 773 oid(1, 2, 840, 10045, 4, 3, 1); 774 public static final ObjectIdentifier sha256WithECDSA_oid = 775 oid(1, 2, 840, 10045, 4, 3, 2); 776 public static final ObjectIdentifier sha384WithECDSA_oid = 777 oid(1, 2, 840, 10045, 4, 3, 3); 778 public static final ObjectIdentifier sha512WithECDSA_oid = 779 oid(1, 2, 840, 10045, 4, 3, 4); 780 public static final ObjectIdentifier specifiedWithECDSA_oid = 781 oid(1, 2, 840, 10045, 4, 3); 782 783 /** 784 * Algorithm ID for the PBE encryption algorithms from PKCS#5 and 785 * PKCS#12. 786 */ 787 public static final ObjectIdentifier pbeWithMD5AndDES_oid = 788 ObjectIdentifier.newInternal(new int[]{1, 2, 840, 113549, 1, 5, 3}); 789 public static final ObjectIdentifier pbeWithMD5AndRC2_oid = 790 ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 6}); 791 public static final ObjectIdentifier pbeWithSHA1AndDES_oid = 792 ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 10}); 793 public static final ObjectIdentifier pbeWithSHA1AndRC2_oid = 794 ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 5, 11}); 795 public static ObjectIdentifier pbeWithSHA1AndDESede_oid = 796 ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 3}); 797 public static ObjectIdentifier pbeWithSHA1AndRC2_40_oid = 798 ObjectIdentifier.newInternal(new int[] {1, 2, 840, 113549, 1, 12, 1, 6}); 799 800 static { 801 /* 802 * Note the preferred OIDs are named simply with no "OIW" or 803 * "PKIX" in them, even though they may point to data from these 804 * specs; e.g. SHA_oid, DH_oid, DSA_oid, SHA1WithDSA_oid... 805 */ 806 /** 807 * Algorithm ID for Diffie Hellman Key agreement, from PKCS #3. 808 * Parameters include public values P and G, and may optionally specify 809 * the length of the private key X. Alternatively, algorithm parameters 810 * may be derived from another source such as a Certificate Authority's 811 * certificate. 812 * OID = 1.2.840.113549.1.3.1 813 */ 814 DH_oid = ObjectIdentifier.newInternal(DH_data); 815 816 /** 817 * Algorithm ID for the Diffie Hellman Key Agreement (DH), from RFC 3279. 818 * Parameters may include public values P and G. 819 * OID = 1.2.840.10046.2.1 820 */ 821 DH_PKIX_oid = ObjectIdentifier.newInternal(DH_PKIX_data); 822 823 /** 824 * Algorithm ID for the Digital Signing Algorithm (DSA), from the 825 * NIST OIW Stable Agreements part 12. 826 * Parameters may include public values P, Q, and G; or these may be 827 * derived from 828 * another source such as a Certificate Authority's certificate. 829 * OID = 1.3.14.3.2.12 830 */ 831 DSA_OIW_oid = ObjectIdentifier.newInternal(DSA_OIW_data); 832 833 /** 834 * Algorithm ID for the Digital Signing Algorithm (DSA), from RFC 3279. 835 * Parameters may include public values P, Q, and G; or these may be 836 * derived from another source such as a Certificate Authority's 837 * certificate. 838 * OID = 1.2.840.10040.4.1 839 */ 840 DSA_oid = ObjectIdentifier.newInternal(DSA_PKIX_data); 841 842 /** 843 * Algorithm ID for RSA keys used for any purpose, as defined in X.509. 844 * The algorithm parameter is a single value, the number of bits in the 845 * public modulus. 846 * OID = 2.5.8.1.1 847 */ 848 RSA_oid = ObjectIdentifier.newInternal(RSA_data); 849 850 /** 851 * Algorithm ID for RSA keys used with RSA encryption, as defined 852 * in PKCS #1. There are no parameters associated with this algorithm. 853 * OID = 1.2.840.113549.1.1.1 854 */ 855 RSAEncryption_oid = ObjectIdentifier.newInternal(RSAEncryption_data); 856 857 /** 858 * Identifies a signing algorithm where an MD2 digest is encrypted 859 * using an RSA private key; defined in PKCS #1. Use of this 860 * signing algorithm is discouraged due to MD2 vulnerabilities. 861 * OID = 1.2.840.113549.1.1.2 862 */ 863 md2WithRSAEncryption_oid = 864 ObjectIdentifier.newInternal(md2WithRSAEncryption_data); 865 866 /** 867 * Identifies a signing algorithm where an MD5 digest is 868 * encrypted using an RSA private key; defined in PKCS #1. 869 * OID = 1.2.840.113549.1.1.4 870 */ 871 md5WithRSAEncryption_oid = 872 ObjectIdentifier.newInternal(md5WithRSAEncryption_data); 873 874 /** 875 * Identifies a signing algorithm where a SHA1 digest is 876 * encrypted using an RSA private key; defined by RSA DSI. 877 * OID = 1.2.840.113549.1.1.5 878 */ 879 sha1WithRSAEncryption_oid = 880 ObjectIdentifier.newInternal(sha1WithRSAEncryption_data); 881 882 /** 883 * Identifies a signing algorithm where a SHA1 digest is 884 * encrypted using an RSA private key; defined in NIST OIW. 885 * OID = 1.3.14.3.2.29 886 */ 887 sha1WithRSAEncryption_OIW_oid = 888 ObjectIdentifier.newInternal(sha1WithRSAEncryption_OIW_data); 889 890 /** 891 * Identifies a signing algorithm where a SHA224 digest is 892 * encrypted using an RSA private key; defined by PKCS #1. 893 * OID = 1.2.840.113549.1.1.14 894 */ 895 sha224WithRSAEncryption_oid = 896 ObjectIdentifier.newInternal(sha224WithRSAEncryption_data); 897 898 /** 899 * Identifies a signing algorithm where a SHA256 digest is 900 * encrypted using an RSA private key; defined by PKCS #1. 901 * OID = 1.2.840.113549.1.1.11 902 */ 903 sha256WithRSAEncryption_oid = 904 ObjectIdentifier.newInternal(sha256WithRSAEncryption_data); 905 906 /** 907 * Identifies a signing algorithm where a SHA384 digest is 908 * encrypted using an RSA private key; defined by PKCS #1. 909 * OID = 1.2.840.113549.1.1.12 910 */ 911 sha384WithRSAEncryption_oid = 912 ObjectIdentifier.newInternal(sha384WithRSAEncryption_data); 913 914 /** 915 * Identifies a signing algorithm where a SHA512 digest is 916 * encrypted using an RSA private key; defined by PKCS #1. 917 * OID = 1.2.840.113549.1.1.13 918 */ 919 sha512WithRSAEncryption_oid = 920 ObjectIdentifier.newInternal(sha512WithRSAEncryption_data); 921 922 /** 923 * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a 924 * SHA digest is signed using the Digital Signing Algorithm (DSA). 925 * This should not be used. 926 * OID = 1.3.14.3.2.13 927 */ 928 shaWithDSA_OIW_oid = ObjectIdentifier.newInternal(shaWithDSA_OIW_data); 929 930 /** 931 * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a 932 * SHA1 digest is signed using the Digital Signing Algorithm (DSA). 933 * OID = 1.3.14.3.2.27 934 */ 935 sha1WithDSA_OIW_oid = ObjectIdentifier.newInternal(sha1WithDSA_OIW_data); 936 937 /** 938 * Identifies the FIPS 186 "Digital Signature Standard" (DSS), where a 939 * SHA1 digest is signed using the Digital Signing Algorithm (DSA). 940 * OID = 1.2.840.10040.4.3 941 */ 942 sha1WithDSA_oid = ObjectIdentifier.newInternal(dsaWithSHA1_PKIX_data); 943 944 // Android-removed: Parsing mapping as OID even if "OID." prefix isn't specified 945 //nameTable = new HashMap<ObjectIdentifier,String>(); nameTable.put(MD5_oid, "MD5")946 nameTable.put(MD5_oid, "MD5"); nameTable.put(MD2_oid, "MD2")947 nameTable.put(MD2_oid, "MD2"); nameTable.put(SHA_oid, "SHA-1")948 nameTable.put(SHA_oid, "SHA-1"); nameTable.put(SHA224_oid, "SHA-224")949 nameTable.put(SHA224_oid, "SHA-224"); nameTable.put(SHA256_oid, "SHA-256")950 nameTable.put(SHA256_oid, "SHA-256"); nameTable.put(SHA384_oid, "SHA-384")951 nameTable.put(SHA384_oid, "SHA-384"); nameTable.put(SHA512_oid, "SHA-512")952 nameTable.put(SHA512_oid, "SHA-512"); nameTable.put(RSAEncryption_oid, "RSA")953 nameTable.put(RSAEncryption_oid, "RSA"); nameTable.put(RSA_oid, "RSA")954 nameTable.put(RSA_oid, "RSA"); nameTable.put(DH_oid, "Diffie-Hellman")955 nameTable.put(DH_oid, "Diffie-Hellman"); nameTable.put(DH_PKIX_oid, "Diffie-Hellman")956 nameTable.put(DH_PKIX_oid, "Diffie-Hellman"); nameTable.put(DSA_oid, "DSA")957 nameTable.put(DSA_oid, "DSA"); nameTable.put(DSA_OIW_oid, "DSA")958 nameTable.put(DSA_OIW_oid, "DSA"); nameTable.put(EC_oid, "EC")959 nameTable.put(EC_oid, "EC"); nameTable.put(ECDH_oid, "ECDH")960 nameTable.put(ECDH_oid, "ECDH"); 961 nameTable.put(AES_oid, "AES")962 nameTable.put(AES_oid, "AES"); 963 nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA")964 nameTable.put(sha1WithECDSA_oid, "SHA1withECDSA"); nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA")965 nameTable.put(sha224WithECDSA_oid, "SHA224withECDSA"); nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA")966 nameTable.put(sha256WithECDSA_oid, "SHA256withECDSA"); nameTable.put(sha384WithECDSA_oid, "SHA384withECDSA")967 nameTable.put(sha384WithECDSA_oid, "SHA384withECDSA"); nameTable.put(sha512WithECDSA_oid, "SHA512withECDSA")968 nameTable.put(sha512WithECDSA_oid, "SHA512withECDSA"); nameTable.put(md5WithRSAEncryption_oid, "MD5withRSA")969 nameTable.put(md5WithRSAEncryption_oid, "MD5withRSA"); nameTable.put(md2WithRSAEncryption_oid, "MD2withRSA")970 nameTable.put(md2WithRSAEncryption_oid, "MD2withRSA"); nameTable.put(sha1WithDSA_oid, "SHA1withDSA")971 nameTable.put(sha1WithDSA_oid, "SHA1withDSA"); nameTable.put(sha1WithDSA_OIW_oid, "SHA1withDSA")972 nameTable.put(sha1WithDSA_OIW_oid, "SHA1withDSA"); nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA")973 nameTable.put(shaWithDSA_OIW_oid, "SHA1withDSA"); nameTable.put(sha224WithDSA_oid, "SHA224withDSA")974 nameTable.put(sha224WithDSA_oid, "SHA224withDSA"); nameTable.put(sha256WithDSA_oid, "SHA256withDSA")975 nameTable.put(sha256WithDSA_oid, "SHA256withDSA"); nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA")976 nameTable.put(sha1WithRSAEncryption_oid, "SHA1withRSA"); nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA")977 nameTable.put(sha1WithRSAEncryption_OIW_oid, "SHA1withRSA"); nameTable.put(sha224WithRSAEncryption_oid, "SHA224withRSA")978 nameTable.put(sha224WithRSAEncryption_oid, "SHA224withRSA"); nameTable.put(sha256WithRSAEncryption_oid, "SHA256withRSA")979 nameTable.put(sha256WithRSAEncryption_oid, "SHA256withRSA"); nameTable.put(sha384WithRSAEncryption_oid, "SHA384withRSA")980 nameTable.put(sha384WithRSAEncryption_oid, "SHA384withRSA"); nameTable.put(sha512WithRSAEncryption_oid, "SHA512withRSA")981 nameTable.put(sha512WithRSAEncryption_oid, "SHA512withRSA"); nameTable.put(pbeWithMD5AndDES_oid, "PBEWithMD5AndDES")982 nameTable.put(pbeWithMD5AndDES_oid, "PBEWithMD5AndDES"); nameTable.put(pbeWithMD5AndRC2_oid, "PBEWithMD5AndRC2")983 nameTable.put(pbeWithMD5AndRC2_oid, "PBEWithMD5AndRC2"); nameTable.put(pbeWithSHA1AndDES_oid, "PBEWithSHA1AndDES")984 nameTable.put(pbeWithSHA1AndDES_oid, "PBEWithSHA1AndDES"); nameTable.put(pbeWithSHA1AndRC2_oid, "PBEWithSHA1AndRC2")985 nameTable.put(pbeWithSHA1AndRC2_oid, "PBEWithSHA1AndRC2"); nameTable.put(pbeWithSHA1AndDESede_oid, "PBEWithSHA1AndDESede")986 nameTable.put(pbeWithSHA1AndDESede_oid, "PBEWithSHA1AndDESede"); nameTable.put(pbeWithSHA1AndRC2_40_oid, "PBEWithSHA1AndRC2_40")987 nameTable.put(pbeWithSHA1AndRC2_40_oid, "PBEWithSHA1AndRC2_40"); 988 } 989 990 /** 991 * Creates a signature algorithm name from a digest algorithm 992 * name and a encryption algorithm name. 993 */ makeSigAlg(String digAlg, String encAlg)994 public static String makeSigAlg(String digAlg, String encAlg) { 995 digAlg = digAlg.replace("-", ""); 996 if (encAlg.equalsIgnoreCase("EC")) encAlg = "ECDSA"; 997 998 return digAlg + "with" + encAlg; 999 } 1000 1001 /** 1002 * Extracts the encryption algorithm name from a signature 1003 * algorithm name. 1004 */ getEncAlgFromSigAlg(String signatureAlgorithm)1005 public static String getEncAlgFromSigAlg(String signatureAlgorithm) { 1006 signatureAlgorithm = signatureAlgorithm.toUpperCase(Locale.ENGLISH); 1007 int with = signatureAlgorithm.indexOf("WITH"); 1008 String keyAlgorithm = null; 1009 if (with > 0) { 1010 int and = signatureAlgorithm.indexOf("AND", with + 4); 1011 if (and > 0) { 1012 keyAlgorithm = signatureAlgorithm.substring(with + 4, and); 1013 } else { 1014 keyAlgorithm = signatureAlgorithm.substring(with + 4); 1015 } 1016 if (keyAlgorithm.equalsIgnoreCase("ECDSA")) { 1017 keyAlgorithm = "EC"; 1018 } 1019 } 1020 return keyAlgorithm; 1021 } 1022 1023 /** 1024 * Extracts the digest algorithm name from a signature 1025 * algorithm name. 1026 */ getDigAlgFromSigAlg(String signatureAlgorithm)1027 public static String getDigAlgFromSigAlg(String signatureAlgorithm) { 1028 signatureAlgorithm = signatureAlgorithm.toUpperCase(Locale.ENGLISH); 1029 int with = signatureAlgorithm.indexOf("WITH"); 1030 if (with > 0) { 1031 return signatureAlgorithm.substring(0, with); 1032 } 1033 return null; 1034 } 1035 } 1036