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