Index: modules/security/src/main/java/common/java/security/cert/X509CRLSelector.java =================================================================== --- modules/security/src/main/java/common/java/security/cert/X509CRLSelector.java (revision 410068) +++ modules/security/src/main/java/common/java/security/cert/X509CRLSelector.java (working copy) @@ -13,34 +13,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + /** -* @author Alexander Y. Kleymenov -* @version $Revision$ -*/ + * @author Alexander Y. Kleymenov + * @version $Revision$ + */ package java.security.cert; import java.io.IOException; import java.math.BigInteger; -import java.security.cert.CRLSelector; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; -import java.util.Iterator; import javax.security.auth.x500.X500Principal; import org.apache.harmony.security.asn1.ASN1Integer; import org.apache.harmony.security.asn1.ASN1OctetString; +import org.apache.harmony.security.x501.Name; - /** * @com.intel.drl.spec_ref */ public class X509CRLSelector implements CRLSelector { - // issuerNames criterion - private ArrayList issuerNames; + // issuerNames criterion: + // contains X.500 distinguished names in CANONICAL format + private ArrayList issuerNames; + // contains X500Principal objects corresponding to the names + // from issuerNames collection (above) + private ArrayList issuerPrincipals; // minCRLNumber criterion private BigInteger minCRL; // maxCRLNumber criterion @@ -49,11 +52,11 @@ private long dateAndTime = -1; // the certificate being checked private X509Certificate certificateChecking; - + /** * @com.intel.drl.spec_ref */ - public X509CRLSelector() {} + public X509CRLSelector() { } /** * @com.intel.drl.spec_ref @@ -61,29 +64,35 @@ public void setIssuers(Collection issuers) { if (issuers == null) { issuerNames = null; + issuerPrincipals = null; return; } - issuerNames = new ArrayList(issuers); + issuerNames = new ArrayList(issuers.size()); + issuerPrincipals = new ArrayList(issuers); + for (X500Principal issuer: issuers) { + issuerNames.add(issuer.getName(X500Principal.CANONICAL)); + } } - + /** * @com.intel.drl.spec_ref */ public void setIssuerNames(Collection names) throws IOException { if (names == null) { issuerNames = null; + issuerPrincipals = null; return; } - Iterator it = names.iterator(); - issuerNames = new ArrayList(names.size()); - while (it.hasNext()) { - Object princ = it.next(); - if (princ instanceof String) { - //addIssuer(new X500Principal((String) princ)); - issuerNames.add(new X500Principal((String) princ)); - } else if (princ instanceof byte[]) { - //addIssuer(new X500Principal((byte[]) princ)); - issuerNames.add(new X500Principal((byte[]) princ)); + issuerNames = new ArrayList(names.size()); + for (Object name: names) { + if (name instanceof String) { + issuerNames.add( + new Name((String) name).getName( + X500Principal.CANONICAL)); + } else if (name instanceof byte[]) { + issuerNames.add( + new Name((byte[]) name).getName( + X500Principal.CANONICAL)); } else { throw new IOException( "The name is not a String or byte array"); @@ -95,48 +104,70 @@ * @com.intel.drl.spec_ref */ public void addIssuer(X500Principal issuer) { + if (issuer == null) { + throw new NullPointerException("issuer"); + } if (issuerNames == null) { - issuerNames = new ArrayList(); + issuerNames = new ArrayList(); } - if (! issuerNames.contains(issuer)) { - issuerNames.add(issuer); + String name = issuer.getName(X500Principal.CANONICAL); + if (!issuerNames.contains(name)) { + issuerNames.add(name); } + if (issuerPrincipals == null) { + issuerPrincipals = new ArrayList(issuerNames.size()); + } + // extend the list of issuer Principals + int size = issuerNames.size() - 1; + for (int i=issuerPrincipals.size(); i(); } - addIssuer(new X500Principal(name)); + String name = new Name(iss_name).getName(X500Principal.CANONICAL); + if (!issuerNames.contains(name)) { + issuerNames.add(name); + } } - + /** * @com.intel.drl.spec_ref */ - public void addIssuerName(byte[] name) throws IOException { + public void addIssuerName(byte[] iss_name) throws IOException { + if (iss_name == null) { + throw new NullPointerException("Provided parameter is null"); + } if (issuerNames == null) { - issuerNames = new ArrayList(); + issuerNames = new ArrayList(); } - addIssuer(new X500Principal(name)); + String name = new Name(iss_name).getName(X500Principal.CANONICAL); + if (!issuerNames.contains(name)) { + issuerNames.add(name); + } } - + /** * @com.intel.drl.spec_ref */ public void setMinCRLNumber(BigInteger minCRL) { this.minCRL = minCRL; } - + /** * @com.intel.drl.spec_ref */ public void setMaxCRLNumber(BigInteger maxCRL) { this.maxCRL = maxCRL; } - + /** * @com.intel.drl.spec_ref */ @@ -147,7 +178,7 @@ } this.dateAndTime = dateAndTime.getTime(); } - + /** * @com.intel.drl.spec_ref */ @@ -162,9 +193,17 @@ if (issuerNames == null) { return null; } - return Collections.unmodifiableCollection(issuerNames); + if (issuerPrincipals == null) { + issuerPrincipals = new ArrayList(issuerNames.size()); + } + int size = issuerNames.size(); + // extend the list of issuer Principals + for (int i=issuerPrincipals.size(); i) issuerNames); } - + /** * @com.intel.drl.spec_ref */ public BigInteger getMinCRL() { return minCRL; } - + /** * @com.intel.drl.spec_ref */ public BigInteger getMaxCRL() { return maxCRL; } - + /** * @com.intel.drl.spec_ref */ @@ -203,14 +237,14 @@ } return new Date(dateAndTime); } - + /** * @com.intel.drl.spec_ref */ public X509Certificate getCertificateChecking() { return certificateChecking; } - + /** * @com.intel.drl.spec_ref */ @@ -221,8 +255,8 @@ result.append("\n IssuerNames:\n ["); int size = issuerNames.size(); for (int i=0; i nextUp.getTime())) { return false; } } return true; } - + /** * @com.intel.drl.spec_ref */ public Object clone() { X509CRLSelector result = new X509CRLSelector(); if (issuerNames != null) { - result.setIssuers(issuerNames); + result.issuerNames = new ArrayList(issuerNames); } result.minCRL = minCRL; result.maxCRL = maxCRL; Index: modules/security/src/test/impl/java.injected/java/security/cert/X509CRLSelectorTest.java =================================================================== --- modules/security/src/test/impl/java.injected/java/security/cert/X509CRLSelectorTest.java (revision 410068) +++ modules/security/src/test/impl/java.injected/java/security/cert/X509CRLSelectorTest.java (working copy) @@ -277,6 +277,19 @@ } /** + * @tests java.security.cert.X509CRLSelector#addIssuer(javax.security.auth.x500.X500Principal) + */ + public void test_addIssuerLjavax_security_auth_x500_X500Principal() throws Exception { + X509CRLSelector obj = new X509CRLSelector(); + try { + obj.addIssuer((X500Principal) null); + fail("NullPointerException expected"); + } catch (NullPointerException e) { + // expected + } + } + + /** * addIssuerName(String name) method testing. * Tests if CRLs with specified issuers match the selector, * and if not specified issuer does not match the selector. @@ -347,6 +360,45 @@ } /** + * @tests java.security.cert.X509CRLSelector#addIssuerName(java.lang.String) + */ + public void test_addIssuerNameLjava_lang_String() throws Exception { + X509CRLSelector obj = new X509CRLSelector(); + try { + obj.addIssuerName("234"); + fail("IOException expected"); + } catch (IOException e) { + // expected + } + } + + /** + * @tests java.security.cert.X509CRLSelector#addIssuerName(byte[]) + */ + public void test_addIssuerName$B_3() throws Exception { + X509CRLSelector obj = new X509CRLSelector(); + try { + obj.addIssuerName(new byte[]{(byte)2,(byte)3,(byte)4}); + fail("IOException expected"); + } catch (IOException e) { + // expected + } + } + + /** + * @tests java.security.cert.X509CRLSelector#addIssuerName(byte[]) + */ + public void test_addIssuerName$B_4() throws Exception { + X509CRLSelector obj = new X509CRLSelector(); + try { + obj.addIssuerName((byte[]) null); + fail("NullPointerException expected"); + } catch (NullPointerException e) { + // expected + } + } + + /** * setMinCRLNumber(BigInteger minCRL) method testing. * Tests if CRLs with any crl number value match the selector in the case of * null crlNumber criteria, if specified minCRL value matches the selector, @@ -425,23 +477,41 @@ * if the returned collection corresponds to the specified issuers and * this collection is unmodifiable. */ - public void testGetIssuers() { + public void testGetIssuers() throws Exception { X509CRLSelector selector = new X509CRLSelector(); X500Principal iss1 = new X500Principal("O=First Org."); X500Principal iss2 = new X500Principal("O=Second Org."); X500Principal iss3 = new X500Principal("O=Third Org."); + String iss_name_1 = "O=First String DN"; + String iss_name_2 = "O=Second String DN"; + String iss_name_3 = "O=Third String DN"; assertNull("The collection should be null.", selector.getIssuers()); + selector.addIssuerName(iss_name_1); selector.addIssuer(iss1); + selector.addIssuerName(iss_name_2); selector.addIssuer(iss2); + selector.addIssuerName(iss_name_3); + Collection result = selector.getIssuers(); + assertEquals("Size does not correspond to expacted", + 5, result.size()); try { result.add(iss3); fail("The returned collection should be unmodifiable."); } catch (UnsupportedOperationException e) { } assertTrue("The collection should contain the specified DN.", + result.contains(iss1)); + assertTrue("The collection should contain the specified DN.", result.contains(iss2)); + assertTrue("The collection should contain the specified DN.", + result.contains(new X500Principal(iss_name_1))); + assertTrue("The collection should contain the specified DN.", + result.contains(new X500Principal(iss_name_2))); + selector.addIssuer(iss3); + assertTrue("The collection should contain the specified DN.", + result.contains(iss3)); } /** Index: modules/security/src/main/java/common/org/apache/harmony/security/x509/DNParser.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x509/DNParser.java (revision 410068) +++ modules/security/src/main/java/common/org/apache/harmony/security/x509/DNParser.java (working copy) @@ -21,6 +21,7 @@ package org.apache.harmony.security.x509; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -63,13 +64,13 @@ * * @param dn - distinguished name string to be parsed */ - public DNParser(String dn) { + public DNParser(String dn) throws IOException { this.length = dn.length(); chars = dn.toCharArray(); } // gets next attribute type: (ALPHA 1*keychar) / oid - private String nextAT() { + private String nextAT() throws IOException { hasQE = false; // reset @@ -92,7 +93,7 @@ } if (pos >= length) { // unexpected end of DN - throw new IllegalArgumentException( + throw new IOException( "Invalid distinguished name string"); } @@ -107,7 +108,7 @@ if (chars[pos] != '=' || pos == length) { // unexpected end of DN - throw new IllegalArgumentException( + throw new IOException( "Invalid distinguished name string"); } } @@ -132,7 +133,7 @@ } // gets quoted attribute value: QUOTATION *( quotechar / pair ) QUOTATION - private String quotedAV() { + private String quotedAV() throws IOException { pos++; beg = pos; @@ -141,7 +142,7 @@ if (pos == length) { // unexpected end of DN - throw new IllegalArgumentException( + throw new IOException( "Invalid distinguished name string"); } @@ -168,11 +169,11 @@ } // gets hex string attribute value: "#" hexstring - private String hexAV() { + private String hexAV() throws IOException { if (pos + 4 >= length) { // encoded byte array must be not less then 4 c - throw new IllegalArgumentException( + throw new IOException( "Invalid distinguished name string"); } @@ -207,7 +208,7 @@ // encoded byte array must be not less then 4 and must be even number int hexLen = end - beg; // skip first '#' char if (hexLen < 5 || (hexLen & 1) == 0) { - throw new IllegalArgumentException( + throw new IOException( "Invalid distinguished name string"); } @@ -221,7 +222,7 @@ } // gets string attribute value: *( stringchar / pair ) - private String escapedAV() { + private String escapedAV() throws IOException { beg = pos; end = pos; @@ -268,11 +269,11 @@ } // returns escaped char - private char getEscaped() { + private char getEscaped() throws IOException { pos++; if (pos == length) { - throw new IllegalArgumentException( + throw new IOException( "Invalid distinguished name string"); } @@ -299,7 +300,7 @@ // decodes UTF-8 char // see http://www.unicode.org for UTF-8 bit distribution table - private char getUTF8() { + private char getUTF8() throws IOException { int res = getByte(pos); pos++; //FIXME tmp @@ -348,11 +349,11 @@ // According to BNF syntax: // hexchar = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" // / "a" / "b" / "c" / "d" / "e" / "f" - private int getByte(int position) { + private int getByte(int position) throws IOException { if ((position + 1) >= length) { // to avoid ArrayIndexOutOfBoundsException - throw new IllegalArgumentException( + throw new IOException( "Invalid distinguished name string"); } @@ -366,7 +367,7 @@ } else if (b1 >= 'A' && b1 <= 'F') { b1 = b1 - 55; // 55 = 'A' - 10 } else { - throw new IllegalArgumentException( + throw new IOException( "Invalid distinguished name string"); } @@ -378,7 +379,7 @@ } else if (b2 >= 'A' && b2 <= 'F') { b2 = b2 - 55; // 55 = 'A' - 10 } else { - throw new IllegalArgumentException( + throw new IOException( "Invalid distinguished name string"); } @@ -391,7 +392,7 @@ * @return a list of Relative Distinguished Names(RND), * each RDN is represented as a list of AttributeTypeAndValue objects */ - public List parse() { + public List parse() throws IOException { List list = new ArrayList(); @@ -448,16 +449,16 @@ list.add(0, atav); atav = new ArrayList(); } else if (chars[pos] != '+') { - throw new IllegalArgumentException( + throw new IOException( "Invalid distinguished name string"); } pos++; attType = nextAT(); if (attType == null) { - throw new IllegalArgumentException( + throw new IOException( "Invalid distinguished name string"); } } } -} \ No newline at end of file +} Index: modules/security/src/main/java/common/org/apache/harmony/security/x501/Name.java =================================================================== --- modules/security/src/main/java/common/org/apache/harmony/security/x501/Name.java (revision 410068) +++ modules/security/src/main/java/common/org/apache/harmony/security/x501/Name.java (working copy) @@ -34,6 +34,7 @@ import org.apache.harmony.security.asn1.ASN1SequenceOf; import org.apache.harmony.security.asn1.ASN1SetOf; import org.apache.harmony.security.asn1.BerInputStream; +import org.apache.harmony.security.asn1.DerInputStream; import org.apache.harmony.security.x509.DNParser; @@ -58,6 +59,25 @@ private List rdn; /** + * Creates new Name instance from its DER encoding + * + * @param encoding - ASN.1 DER encoding + * @throws IOException - if encoding is wrong + */ + public Name(byte[] encoding) throws IOException { + + DerInputStream in = new DerInputStream(encoding); + + if (in.getEndOffset() != encoding.length) { + throw new IOException("Wrong content length"); + } + + ASN1.decode(in); + + this.rdn = (List) in.content; + } + + /** * Creates new Name instance * * @param name - Name as String @@ -240,4 +260,4 @@ return ((Name) object).rdn; //FIXME what about get method? } }; -} \ No newline at end of file +} Index: modules/security/src/test/impl/java.injected/java/security/cert/X509CertSelectorTest.java =================================================================== --- modules/security/src/test/impl/java.injected/java/security/cert/X509CertSelectorTest.java (revision 410068) +++ modules/security/src/test/impl/java.injected/java/security/cert/X509CertSelectorTest.java (working copy) @@ -632,12 +632,15 @@ assertNull("Selector should return null", selector.getIssuerAsString()); selector.setIssuer(iss1); assertEquals("The returned issuer should be equal to specified", - name1, selector.getIssuerAsString()); + new X500Principal(name1), + new X500Principal(selector.getIssuerAsString())); assertFalse("The returned issuer should differ", - name2.equals(selector.getIssuerAsString())); + new X500Principal(name2).equals( + new X500Principal(selector.getIssuerAsString()))); selector.setIssuer(iss2); assertEquals("The returned issuer should be equal to specified", - name2, selector.getIssuerAsString()); + new X500Principal(name2), + new X500Principal(selector.getIssuerAsString())); } /** @@ -711,13 +714,16 @@ assertNull("Selector should return null", selector.getIssuerAsBytes()); selector.setIssuer(iss1); - assertTrue("The returned issuer should be equal to specified", - Arrays.equals(name1, selector.getIssuerAsBytes())); + assertEquals("The returned issuer should be equal to specified", + new X500Principal(name1), + new X500Principal(selector.getIssuerAsBytes())); assertFalse("The returned issuer should differ", - name2.equals(selector.getIssuerAsBytes())); + new X500Principal(name2).equals( + new X500Principal(selector.getIssuerAsBytes()))); selector.setIssuer(iss2); - assertTrue("The returned issuer should be equal to specified", - Arrays.equals(name2, selector.getIssuerAsBytes())); + assertEquals("The returned issuer should be equal to specified", + new X500Principal(name2), + new X500Principal(selector.getIssuerAsBytes())); } catch (IOException e) { e.printStackTrace(); fail("Unexpected IOException was thrown."); @@ -827,12 +833,15 @@ selector.getSubjectAsString()); selector.setSubject(sub1); assertEquals("The returned subject should be equal to specified", - name1, selector.getSubjectAsString()); + new X500Principal(name1), + new X500Principal(selector.getSubjectAsString())); assertFalse("The returned subject should differ", - name2.equals(selector.getSubjectAsString())); + new X500Principal(name2).equals( + new X500Principal(selector.getSubjectAsString()))); selector.setSubject(sub2); assertEquals("The returned subject should be equal to specified", - name2, selector.getSubjectAsString()); + new X500Principal(name2), + new X500Principal(selector.getSubjectAsString())); } /** @@ -906,13 +915,16 @@ assertNull("Selector should return null", selector.getSubjectAsBytes()); selector.setSubject(sub1); - assertTrue("The returned issuer should be equal to specified", - Arrays.equals(name1, selector.getSubjectAsBytes())); + assertEquals("The returned issuer should be equal to specified", + new X500Principal(name1), + new X500Principal(selector.getSubjectAsBytes())); assertFalse("The returned issuer should differ", - name2.equals(selector.getSubjectAsBytes())); + new X500Principal(name2).equals( + new X500Principal(selector.getSubjectAsBytes()))); selector.setSubject(sub2); - assertTrue("The returned issuer should be equal to specified", - Arrays.equals(name2, selector.getSubjectAsBytes())); + assertEquals("The returned issuer should be equal to specified", + new X500Principal(name2), + new X500Principal(selector.getSubjectAsBytes())); } catch (IOException e) { e.printStackTrace(); fail("Unexpected IOException was thrown."); @@ -1179,6 +1191,19 @@ } /** + * @tests java.security.cert.X509CertSelector#setSubjectPublicKeyAlgID(java.lang.String) + */ + public void test_setSubjectPublicKeyAlgIDLjava_lang_String() throws Exception { + X509CertSelector obj = new X509CertSelector(); + try { + obj.setSubjectPublicKeyAlgID("abc"); + fail("IOException expected"); + } catch (IOException e) { + // expected + } + } + + /** * getSubjectPublicKeyAlgID() method testing. * Tests if the method return null in the case of not specified criteria, * if the returned value [does not]corresponds to [not]specified Index: modules/security/src/main/java/common/java/security/cert/X509CertSelector.java =================================================================== --- modules/security/src/main/java/common/java/security/cert/X509CertSelector.java (revision 410068) +++ modules/security/src/main/java/common/java/security/cert/X509CertSelector.java (working copy) @@ -13,10 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + /** -* @author Alexander Y. Kleymenov -* @version $Revision$ -*/ + * @author Alexander Y. Kleymenov + * @version $Revision$ + */ package java.security.cert; @@ -360,6 +361,8 @@ if ((comp < 0) || (comp > 39)) { throw new IOException("The OID: \"" + oid + "\" is icorrect."); } + } catch (IndexOutOfBoundsException e) { + throw new IOException("The OID: \"" + oid + "\" is icorrect."); } catch (NumberFormatException e) { throw new IOException("The OID: \"" + oid + "\" is icorrect."); }