Don't clobber existing entries in the AlgorithmId tables
When AlgorithmId is initialized, it inserts "well-known" values into the
table. However, any subsequent addition to the table could potentially
clobber the entries already in there.
Bug: 26922084
Change-Id: I7317f9c44e4628300bec0089ecb6d274e7dfa9c8
diff --git a/luni/src/test/java/libcore/java/security/ProviderTest.java b/luni/src/test/java/libcore/java/security/ProviderTest.java
index d3ccae1..1198bcb 100644
--- a/luni/src/test/java/libcore/java/security/ProviderTest.java
+++ b/luni/src/test/java/libcore/java/security/ProviderTest.java
@@ -38,6 +38,7 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -45,6 +46,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.crypto.Cipher;
+import javax.crypto.EncryptedPrivateKeyInfo;
import javax.crypto.NoSuchPaddingException;
import junit.framework.TestCase;
import libcore.javax.crypto.MockKey;
@@ -550,6 +552,39 @@
}
}
+ @SuppressWarnings("serial")
+ public void testProviderService_AliasDoesNotEraseCanonical_Success()
+ throws Exception {
+ // Make sure we start with a "known good" alias for this OID.
+ {
+ EncryptedPrivateKeyInfo epki1 = new EncryptedPrivateKeyInfo("OID.1.2.840.113549.1.1.5",
+ new byte[1]);
+ assertEquals("SHA1WITHRSA", epki1.getAlgName().toUpperCase(Locale.US));
+ }
+
+ Provider provider = new MockProvider("MockProvider") {
+ public void setup() {
+ put("Signature.FOO", MockSpi.class.getName());
+ put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", "FOO");
+ }
+ };
+
+ Security.addProvider(provider);
+ try {
+ // This triggers a re-indexing of the algorithm id data:
+ try {
+ new EncryptedPrivateKeyInfo("nonexistent", new byte[1]);
+ fail("Should not find 'nonexistent' algorithm");
+ } catch (NoSuchAlgorithmException expected) {
+ }
+
+ EncryptedPrivateKeyInfo epki2 = new EncryptedPrivateKeyInfo("OID.1.2.840.113549.1.1.5", new byte[1]);
+ assertEquals("SHA1WITHRSA", epki2.getAlgName().toUpperCase(Locale.US));
+ } finally {
+ Security.removeProvider(provider.getName());
+ }
+ }
+
public void testProvider_removeProvider_Success() throws Exception {
MockProvider provider = new MockProvider("MockProvider");
assertNull(Security.getProvider(provider.getName()));
diff --git a/ojluni/src/main/java/sun/security/x509/AlgorithmId.java b/ojluni/src/main/java/sun/security/x509/AlgorithmId.java
index 620a13d..136c357 100755
--- a/ojluni/src/main/java/sun/security/x509/AlgorithmId.java
+++ b/ojluni/src/main/java/sun/security/x509/AlgorithmId.java
@@ -571,13 +571,22 @@
String stdAlgName = provs[i].getProperty(alias);
if (stdAlgName != null) {
stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH);
- }
- if (stdAlgName != null &&
- oidTable.get(stdAlgName) == null) {
- ObjectIdentifier oid =
- new ObjectIdentifier(oidString);
- oidTable.put(stdAlgName, oid);
- nameTable.put(oid, stdAlgName);
+
+ ObjectIdentifier oid = null;
+ try {
+ oid = new ObjectIdentifier(oidString);
+ } catch (IOException e) {
+ // Not an OID.
+ }
+
+ if (oid != null) {
+ if (!oidTable.containsKey(stdAlgName)) {
+ oidTable.put(stdAlgName, oid);
+ }
+ if (!nameTable.containsKey(oid)) {
+ nameTable.put(oid, stdAlgName);
+ }
+ }
}
} else {
// Android-changed: If the alias isn't specified with an explicit
@@ -596,10 +605,12 @@
String stdAlgName = provs[i].getProperty(alias);
if (stdAlgName != null) {
stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH);
- }
- if (stdAlgName != null && oidTable.get(stdAlgName) == null) {
- oidTable.put(stdAlgName, oid);
- nameTable.put(oid, stdAlgName);
+ if (!oidTable.containsKey(stdAlgName)) {
+ oidTable.put(stdAlgName, oid);
+ }
+ if (!nameTable.containsKey(oid)) {
+ nameTable.put(oid, stdAlgName);
+ }
}
}
}