diff options
author | bouncy <bouncy> | 2012-03-22 04:12:38 +0000 |
---|---|---|
committer | bouncy <bouncy> | 2012-03-22 04:12:38 +0000 |
commit | 627fd07aea6b3c9c5001e3c6f7ca44fbfdd86ec6 (patch) | |
tree | d755a1f94c566d52dc0509954a1b43f3165825f7 | |
parent | 50304828965098734520b1cc56374ed1623eca06 (diff) | |
download | android_external_spongycastle-627fd07aea6b3c9c5001e3c6f7ca44fbfdd86ec6.tar.gz android_external_spongycastle-627fd07aea6b3c9c5001e3c6f7ca44fbfdd86ec6.tar.bz2 android_external_spongycastle-627fd07aea6b3c9c5001e3c6f7ca44fbfdd86ec6.zip |
core API updates.
15 files changed, 1167 insertions, 99 deletions
diff --git a/crypto/j2me/org/bouncycastle/asn1/ASN1GeneralizedTime.java b/crypto/j2me/org/bouncycastle/asn1/ASN1GeneralizedTime.java index 5a01826db..ea2cb3f27 100644 --- a/crypto/j2me/org/bouncycastle/asn1/ASN1GeneralizedTime.java +++ b/crypto/j2me/org/bouncycastle/asn1/ASN1GeneralizedTime.java @@ -10,6 +10,16 @@ public class ASN1GeneralizedTime super(bytes); } + public ASN1GeneralizedTime(Date date) + { + super(date); + } + + public ASN1GeneralizedTime(Date date, boolean includeMillis) + { + super(date, includeMillis); + } + public ASN1GeneralizedTime(String time) { super(time); diff --git a/crypto/j2me/org/bouncycastle/asn1/ASN1UTCTime.java b/crypto/j2me/org/bouncycastle/asn1/ASN1UTCTime.java index e74c5569b..aac76e101 100644 --- a/crypto/j2me/org/bouncycastle/asn1/ASN1UTCTime.java +++ b/crypto/j2me/org/bouncycastle/asn1/ASN1UTCTime.java @@ -10,6 +10,11 @@ public class ASN1UTCTime super(bytes); } + public ASN1UTCTime(Date date) + { + super(date); + } + public ASN1UTCTime(String time) { super(time); diff --git a/crypto/j2me/org/bouncycastle/asn1/DERGeneralizedTime.java b/crypto/j2me/org/bouncycastle/asn1/DERGeneralizedTime.java index 18863e0ae..2cb95b60c 100644 --- a/crypto/j2me/org/bouncycastle/asn1/DERGeneralizedTime.java +++ b/crypto/j2me/org/bouncycastle/asn1/DERGeneralizedTime.java @@ -1,6 +1,7 @@ package org.bouncycastle.asn1; import java.io.IOException; +import java.util.Date; import java.util.TimeZone; import org.bouncycastle.util.Arrays; @@ -62,7 +63,7 @@ public class DERGeneralizedTime /** * The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z - * for local time, or Z+-HHMM on the end, for difference between local + * for local time, or Z|[+|-]HHMM on the end, for difference between local * time and UTC time. The fractional second amount f must consist of at * least one number with trailing zeroes removed. * @@ -72,9 +73,32 @@ public class DERGeneralizedTime public DERGeneralizedTime( String time) { + char last = time.charAt(time.length() - 1); + if (last != 'Z' && !(last >= 0 && last <= '9')) + { + if (time.indexOf('-') < 0 && time.indexOf('+') < 0) + { + throw new IllegalArgumentException("time needs to be in format YYYYMMDDHHMMSS[.f]Z or YYYYMMDDHHMMSS[.f][+-]HHMM"); + } + } + this.time = Strings.toByteArray(time); } + /** + * base constructer from a java.util.date object + */ + public DERGeneralizedTime( + Date time) + { + this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(time, false)); + } + + protected DERGeneralizedTime(Date date, boolean includeMillis) + { + this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(date, true)); + } + DERGeneralizedTime( byte[] bytes) { @@ -153,19 +177,19 @@ public class DERGeneralizedTime } int hours = offset / (60 * 60 * 1000); int minutes = (offset - (hours * 60 * 60 * 1000)) / (60 * 1000); -/* - try - { - if (timeZone.useDaylightTime() && timeZone.inDaylightTime(this.getDate())) - { - hours += sign.equals("+") ? 1 : -1; - } - } - catch (ParseException e) - { - // we'll do our best and ignore daylight savings - } -*/ + +// try +// { +// if (timeZone.useDaylightTime() && timeZone.inDaylightTime(this.getDate())) +// { +// hours += sign.equals("+") ? 1 : -1; +// } +// } +// catch (ParseException e) +// { +// // we'll do our best and ignore daylight savings +// } + return "GMT" + sign + convert(hours) + ":" + convert(minutes); } @@ -179,6 +203,11 @@ public class DERGeneralizedTime return Integer.toString(time); } + public Date getDate() + { + return DateFormatter.fromGeneralizedTimeString(time); + } + private boolean hasFractionalSeconds() { for (int i = 0; i != time.length; i++) diff --git a/crypto/j2me/org/bouncycastle/asn1/DERUTCTime.java b/crypto/j2me/org/bouncycastle/asn1/DERUTCTime.java index 26716fde9..3e8010b4b 100644 --- a/crypto/j2me/org/bouncycastle/asn1/DERUTCTime.java +++ b/crypto/j2me/org/bouncycastle/asn1/DERUTCTime.java @@ -1,6 +1,7 @@ package org.bouncycastle.asn1; import java.io.IOException; +import java.util.Date; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Strings; @@ -72,9 +73,27 @@ public class DERUTCTime public DERUTCTime( String time) { + if (time.charAt(time.length() - 1) != 'Z') + { + // we accept this as a variation + if (time.indexOf('-') < 0 && time.indexOf('+') < 0) + { + throw new IllegalArgumentException("time needs to be in format YYMMDDHHMMSSZ"); + } + } + this.time = Strings.toByteArray(time); } + /** + * base constructor from a java.util.date object + */ + public DERUTCTime( + Date time) + { + this.time = Strings.toByteArray(DateFormatter.toUTCDateString(time)); + } + DERUTCTime( byte[] time) { @@ -82,6 +101,28 @@ public class DERUTCTime } /** + * return the time as a date based on whatever a 2 digit year will return. For + * standardised processing use getAdjustedDate(). + * + * @return the resulting date + */ + public Date getDate() + { + return DateFormatter.adjustedFromUTCDateString(time); + } + + /** + * return the time as an adjusted date + * in the range of 1950 - 2049. + * + * @return a date in the range of 1950 to 2049. + */ + public Date getAdjustedDate() + { + return DateFormatter.adjustedFromUTCDateString(time); + } + + /** * return the time - always in the form of * YYMMDDhhmmssGMT(+hh:mm|-hh:mm). * <p> @@ -158,6 +199,15 @@ public class DERUTCTime } } + /** + * Return the time. + * @return The time string as it appeared in the encoded object. + */ + public String getTimeString() + { + return Strings.fromByteArray(time); + } + boolean isConstructed() { return false; diff --git a/crypto/j2me/org/bouncycastle/asn1/DateFormatter.java b/crypto/j2me/org/bouncycastle/asn1/DateFormatter.java new file mode 100644 index 000000000..cd7077403 --- /dev/null +++ b/crypto/j2me/org/bouncycastle/asn1/DateFormatter.java @@ -0,0 +1,272 @@ +package org.bouncycastle.asn1; + +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +class DateFormatter +{ + // YYMMDDHHMMSSZ + static String toUTCDateString(Date date) + { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + + calendar.setTime(date); + + return format2Year(calendar.get(Calendar.YEAR)) + format2(calendar.get(Calendar.MONTH) + 1) + format2(calendar.get(Calendar.DAY_OF_MONTH)) + + format2(calendar.get(Calendar.HOUR_OF_DAY)) + format2(calendar.get(Calendar.MINUTE)) + format2(calendar.get(Calendar.SECOND)) + "Z"; + } + + static Date adjustedFromUTCDateString(byte[] date) + { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + + int year = toInt2(date, 0); + + if (year < 50) + { + year += 2000; + } + else + { + year += 1900; + } + + calendar.setTimeZone(TimeZone.getTimeZone("GMT")); + + calendar.set(Calendar.YEAR, year); + calendar.set(Calendar.MONTH, toInt2(date, 2) - 1); + calendar.set(Calendar.DAY_OF_MONTH, toInt2(date, 4)); + calendar.set(Calendar.HOUR_OF_DAY, toInt2(date, 6)); + calendar.set(Calendar.MINUTE, toInt2(date, 8)); + + int tzChar = 10; + + if (isNumber(date, tzChar)) + { + calendar.set(Calendar.SECOND, toInt2(date, 10)); + tzChar = 12; + } + else + { + calendar.set(Calendar.SECOND, 0); + } + + calendar.set(Calendar.MILLISECOND, 0); + + if (date[tzChar] != 'Z') + { + int hoursOff = 0; + int minutesOff = 0; + + hoursOff = toInt2(date, tzChar + 1) * 60 * 60 * 1000; + + if (date.length > tzChar + 3) + { + minutesOff = toInt2(date, tzChar + 3) * 60 * 1000; + } + + if (date[tzChar] == '-') + { + return new Date(calendar.getTime().getTime() + hoursOff + minutesOff); + } + else + { + return new Date(calendar.getTime().getTime() - (hoursOff + minutesOff)); + } + } + + return calendar.getTime(); + } + + static String getGeneralizedTimeDateString(Date date, boolean includeMillis) + { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + + calendar.setTime(date); + + String time = format4Year(calendar.get(Calendar.YEAR)) + format2(calendar.get(Calendar.MONTH) + 1) + format2(calendar.get(Calendar.DAY_OF_MONTH)) + + format2(calendar.get(Calendar.HOUR_OF_DAY)) + format2(calendar.get(Calendar.MINUTE)) + format2(calendar.get(Calendar.SECOND)); + + if (includeMillis) + { + time += "." + format3(calendar.get(Calendar.MILLISECOND)); + } + + return time + "Z"; + } + + static Date fromGeneralizedTimeString(byte[] date) + { + Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT")); + + int year = toInt4(date, 0); + + if (isLocalTime(date)) + { + calendar.setTimeZone(TimeZone.getTimeZone("GMT")); + } + + calendar.set(Calendar.YEAR, year); + calendar.set(Calendar.MONTH, toInt2(date, 4) - 1); + calendar.set(Calendar.DAY_OF_MONTH, toInt2(date, 6)); + calendar.set(Calendar.HOUR_OF_DAY, toInt2(date, 8)); + calendar.set(Calendar.MINUTE, toInt2(date, 10)); + + int tzChar = 12; + + if (isNumber(date, tzChar)) + { + calendar.set(Calendar.SECOND, toInt2(date, 12)); + tzChar = 14; + } + else + { + calendar.set(Calendar.SECOND, 0); + } + + if (tzChar != date.length && date[tzChar] == '.') + { + int millis = 0; + tzChar++; + if (isNumber(date, tzChar)) + { + millis = (date[tzChar] - '0') * 100; + tzChar++; + } + if (tzChar != date.length && isNumber(date, tzChar)) + { + millis += (date[tzChar] - '0') * 10; + tzChar++; + } + if (tzChar != date.length && isNumber(date, tzChar)) + { + millis += (date[tzChar] - '0'); + tzChar++; + } + calendar.set(Calendar.MILLISECOND, millis); + } + else + { + calendar.set(Calendar.MILLISECOND, 0); + } + + // skip nano-seconds + while (tzChar != date.length && isNumber(date, tzChar)) + { + tzChar++; + } + + if (tzChar != date.length && date[tzChar] != 'Z') + { + int hoursOff = 0; + int minutesOff = 0; + + hoursOff = toInt2(date, tzChar + 1) * 60 * 60 * 1000; + + if (date.length > tzChar + 3) + { + minutesOff = toInt2(date, tzChar + 3) * 60 * 1000; + } + + if (date[tzChar] == '-') + { + return new Date(calendar.getTime().getTime() + hoursOff + minutesOff); + } + else + { + return new Date(calendar.getTime().getTime() - (hoursOff + minutesOff)); + } + } + + return calendar.getTime(); + } + + private static String format2(int v) + { + if (v < 10) + { + return "0" + v; + } + + return Integer.toString(v); + } + + private static String format2Year(int v) + { + if (v > 2000) + { + v = v - 2000; + } + else + { + v = v - 1900; + } + + return format2(v); + } + + private static String format3(int v) + { + if (v < 10) + { + return "00" + v; + } + + if (v < 100) + { + return "0" + v; + } + + return Integer.toString(v); + } + + private static String format4Year(int v) + { + if (v < 10) + { + return "000" + v; + } + + if (v < 100) + { + return "00" + v; + } + + if (v < 1000) + { + return "0" + v; + } + + return Integer.toString(v); + } + + private static boolean isNumber(byte[] input, int off) + { + byte b = input[off]; + return (b >= '0') && (b <= '9'); + } + + private static boolean isLocalTime(byte[] date) + { + for (int i = date.length - 1; i > date.length - 6; i--) + { + if (date[i] == 'Z' || date[i] == '-' || date[i] == '+') + { + return false; + } + } + + return true; + } + + private static int toInt2(byte[] input, int off) + { + return (input[off] - '0') * 10 + (input[off + 1] - '0'); + } + + private static int toInt4(byte[] input, int off) + { + return toInt2(input, off) * 100 + toInt2(input, off + 2) ; + } +} diff --git a/crypto/j2me/org/bouncycastle/asn1/StreamUtil.java b/crypto/j2me/org/bouncycastle/asn1/StreamUtil.java index 6bc9914a0..67e3c2080 100644 --- a/crypto/j2me/org/bouncycastle/asn1/StreamUtil.java +++ b/crypto/j2me/org/bouncycastle/asn1/StreamUtil.java @@ -1,7 +1,6 @@ package org.bouncycastle.asn1; import java.io.ByteArrayInputStream; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; diff --git a/crypto/j2me/org/bouncycastle/asn1/cms/Time.java b/crypto/j2me/org/bouncycastle/asn1/cms/Time.java index 1668d78f0..5bbbd339e 100644 --- a/crypto/j2me/org/bouncycastle/asn1/cms/Time.java +++ b/crypto/j2me/org/bouncycastle/asn1/cms/Time.java @@ -1,21 +1,30 @@ package org.bouncycastle.asn1.cms; -import org.bouncycastle.asn1.*; +import java.util.Calendar; +import java.util.Date; + +import org.bouncycastle.asn1.ASN1Choice; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DERGeneralizedTime; +import org.bouncycastle.asn1.DERUTCTime; public class Time - implements DEREncodable, ASN1Choice + extends ASN1Object + implements ASN1Choice { - DERObject time; + ASN1Primitive time; public static Time getInstance( ASN1TaggedObject obj, boolean explicit) { - return getInstance(obj.getObject()); + return getInstance(obj.getObject()); // must be explicitly tagged } public Time( - DERObject time) + ASN1Primitive time) { if (!(time instanceof DERUTCTime) && !(time instanceof DERGeneralizedTime)) @@ -26,6 +35,30 @@ public class Time this.time = time; } + /** + * creates a time object from a given date - if the date is between 1950 + * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime + * is used. + */ + public Time( + Date date) + { + Calendar calendar = Calendar.getInstance(); + + calendar.setTime(date); + + int year = calendar.get(Calendar.YEAR); + + if (year < 1950 || year > 2049) + { + time = new DERGeneralizedTime(date); + } + else + { + time = new DERUTCTime(date); + } + } + public static Time getInstance( Object obj) { @@ -42,7 +75,7 @@ public class Time return new Time((DERGeneralizedTime)obj); } - throw new IllegalArgumentException("unknown object in factory"); + throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); } public String getTime() @@ -57,15 +90,33 @@ public class Time } } + public Date getDate() + { + if (time instanceof DERUTCTime) + { + return ((DERUTCTime)time).getAdjustedDate(); + } + else + { + return ((DERGeneralizedTime)time).getDate(); + } + } + /** + * Produce an object suitable for an ASN1OutputStream. * <pre> * Time ::= CHOICE { * utcTime UTCTime, * generalTime GeneralizedTime } * </pre> */ - public DERObject getDERObject() + public ASN1Primitive toASN1Primitive() { return time; } + + public String toString() + { + return getTime(); + } } diff --git a/crypto/j2me/org/bouncycastle/asn1/eac/PackedDate.java b/crypto/j2me/org/bouncycastle/asn1/eac/PackedDate.java new file mode 100644 index 000000000..2259eb894 --- /dev/null +++ b/crypto/j2me/org/bouncycastle/asn1/eac/PackedDate.java @@ -0,0 +1,70 @@ +package org.bouncycastle.asn1.eac; + +import org.bouncycastle.util.Arrays; + +/** + * EAC encoding date object + */ +public class PackedDate +{ + private byte[] time; + + public PackedDate( + String time) + { + this.time = convert(time); + } + + private byte[] convert(String sTime) + { + char[] digs = sTime.toCharArray(); + byte[] date = new byte[6]; + + for (int i = 0; i != 6; i++) + { + date[i] = (byte)(digs[i] - '0'); + } + + return date; + } + + PackedDate( + byte[] bytes) + { + this.time = bytes; + } + + public int hashCode() + { + return Arrays.hashCode(time); + } + + public boolean equals(Object o) + { + if (!(o instanceof PackedDate)) + { + return false; + } + + PackedDate other = (PackedDate)o; + + return Arrays.areEqual(time, other.time); + } + + public String toString() + { + char[] dateC = new char[time.length]; + + for (int i = 0; i != dateC.length; i++) + { + dateC[i] = (char)((time[i] & 0xff) + '0'); + } + + return new String(dateC); + } + + public byte[] getEncoding() + { + return time; + } +} diff --git a/crypto/j2me/org/bouncycastle/asn1/test/GeneralizedTimeTest.java b/crypto/j2me/org/bouncycastle/asn1/test/GeneralizedTimeTest.java new file mode 100644 index 000000000..22844c298 --- /dev/null +++ b/crypto/j2me/org/bouncycastle/asn1/test/GeneralizedTimeTest.java @@ -0,0 +1,189 @@ +package org.bouncycastle.asn1.test; + +import java.util.Date; +import java.util.TimeZone; + +import org.bouncycastle.asn1.ASN1GeneralizedTime; +import org.bouncycastle.asn1.DERGeneralizedTime; +import org.bouncycastle.util.test.SimpleTest; + +/** + * X.690 test example + */ +public class GeneralizedTimeTest + extends SimpleTest +{ + String[] input = + { + "20020122122220", + "20020122122220Z", + "20020122122220-1000", + "20020122122220+00", + "20020122122220.1", + "20020122122220.1Z", + "20020122122220.1-1000", + "20020122122220.1+00", + "20020122122220.01", + "20020122122220.01Z", + "20020122122220.01-1000", + "20020122122220.01+00", + "20020122122220.001", + "20020122122220.001Z", + "20020122122220.001-1000", + "20020122122220.001+00", + "20020122122220.0001", + "20020122122220.0001Z", + "20020122122220.0001-1000", + "20020122122220.0001+00", + "20020122122220.0001+1000" + }; + + String[] output = { + "20020122122220", + "20020122122220GMT+00:00", + "20020122122220GMT-10:00", + "20020122122220GMT+00:00", + "20020122122220.1", + "20020122122220.1GMT+00:00", + "20020122122220.1GMT-10:00", + "20020122122220.1GMT+00:00", + "20020122122220.01", + "20020122122220.01GMT+00:00", + "20020122122220.01GMT-10:00", + "20020122122220.01GMT+00:00", + "20020122122220.001", + "20020122122220.001GMT+00:00", + "20020122122220.001GMT-10:00", + "20020122122220.001GMT+00:00", + "20020122122220.0001", + "20020122122220.0001GMT+00:00", + "20020122122220.0001GMT-10:00", + "20020122122220.0001GMT+00:00", + "20020122122220.0001GMT+10:00" }; + + String[] zOutput = { + "20020122122220Z", + "20020122122220Z", + "20020122222220Z", + "20020122122220Z", + "20020122122220Z", + "20020122122220Z", + "20020122222220Z", + "20020122122220Z", + "20020122122220Z", + "20020122122220Z", + "20020122222220Z", + "20020122122220Z", + "20020122122220Z", + "20020122122220Z", + "20020122222220Z", + "20020122122220Z", + "20020122122220Z", + "20020122122220Z", + "20020122222220Z", + "20020122122220Z", + "20020122022220Z" + }; + + String[] mzOutput = { + "20020122122220.000Z", + "20020122122220.000Z", + "20020122222220.000Z", + "20020122122220.000Z", + "20020122122220.100Z", + "20020122122220.100Z", + "20020122222220.100Z", + "20020122122220.100Z", + "20020122122220.010Z", + "20020122122220.010Z", + "20020122222220.010Z", + "20020122122220.010Z", + "20020122122220.001Z", + "20020122122220.001Z", + "20020122222220.001Z", + "20020122122220.001Z", + "20020122122220.000Z", + "20020122122220.000Z", + "20020122222220.000Z", + "20020122122220.000Z", + "20020122022220.000Z" + }; + + public String getName() + { + return "GeneralizedTime"; + } + + public void performTest() + throws Exception + { + for (int i = 0; i != input.length; i++) + { + DERGeneralizedTime t = new DERGeneralizedTime(input[i]); + + if (output[i].indexOf('G') > 0) // don't check local time the same way + { + if (!t.getTime().equals(output[i])) + { + fail("failed conversion test"); + } + } + else + { + String offset = calculateGMTOffset(t.getDate()); + + if (!t.getTime().equals(output[i] + offset)) + { + fail("failed conversion test"); + } + } + } + + for (int i = 0; i != input.length; i++) + { + ASN1GeneralizedTime t = new ASN1GeneralizedTime(mzOutput[i]); + + if (!new ASN1GeneralizedTime(t.getDate(), true).getDate().equals(t.getDate())) + { + fail("failed equality test"); + } + } + } + + private String calculateGMTOffset(Date date) + { + String sign = "+"; + TimeZone timeZone = TimeZone.getDefault(); + int offset = timeZone.getRawOffset(); + if (offset < 0) + { + sign = "-"; + offset = -offset; + } + int hours = offset / (60 * 60 * 1000); + int minutes = (offset - (hours * 60 * 60 * 1000)) / (60 * 1000); + +// if (timeZone.useDaylightTime() && timeZone.inDaylightTime(date)) +// { +// hours += sign.equals("+") ? 1 : -1; +// } + + return "GMT" + sign + convert(hours) + ":" + convert(minutes); + } + + private String convert(int time) + { + if (time < 10) + { + return "0" + time; + } + + return Integer.toString(time); + } + + public static void main( + String[] args) + { + runTest(new GeneralizedTimeTest()); + } +} diff --git a/crypto/j2me/org/bouncycastle/asn1/test/RegressionTest.java b/crypto/j2me/org/bouncycastle/asn1/test/RegressionTest.java index dbaa5b348..e1a9f9bc4 100644 --- a/crypto/j2me/org/bouncycastle/asn1/test/RegressionTest.java +++ b/crypto/j2me/org/bouncycastle/asn1/test/RegressionTest.java @@ -6,17 +6,68 @@ import org.bouncycastle.util.test.TestResult; public class RegressionTest { public static Test[] tests = { + new EqualsAndHashCodeTest(), + new TagTest(), + new SetTest(), + new DERUTF8StringTest(), new CertificateTest(), + new GenerationTest(), new CMSTest(), new OCSPTest(), new OIDTest(), new PKCS10Test(), new PKCS12Test(), new X509NameTest(), + new X500NameTest(), + new X509ExtensionsTest(), + new GeneralizedTimeTest(), new BitStringTest(), new MiscTest(), + new SMIMETest(), new X9Test(), - new EncryptedPrivateKeyInfoTest() + new MonetaryValueUnitTest(), + new BiometricDataUnitTest(), + new Iso4217CurrencyCodeUnitTest(), + new SemanticsInformationUnitTest(), + new QCStatementUnitTest(), + new TypeOfBiometricDataUnitTest(), + new SignerLocationUnitTest(), + new CommitmentTypeQualifierUnitTest(), + new CommitmentTypeIndicationUnitTest(), + new EncryptedPrivateKeyInfoTest(), + new DataGroupHashUnitTest(), + new LDSSecurityObjectUnitTest(), + new AttributeTableUnitTest(), + new ReasonFlagsTest(), + new NetscapeCertTypeTest(), + new PKIFailureInfoTest(), + new KeyUsageTest(), + new StringTest(), + new UTCTimeTest(), + new RequestedCertificateUnitTest(), + new OtherCertIDUnitTest(), + new OtherSigningCertificateUnitTest(), + new ContentHintsUnitTest(), + new CertHashUnitTest(), + new AdditionalInformationSyntaxUnitTest(), + new AdmissionSyntaxUnitTest(), + new AdmissionsUnitTest(), + new DeclarationOfMajorityUnitTest(), + new ProcurationSyntaxUnitTest(), + new ProfessionInfoUnitTest(), + new RestrictionUnitTest(), + new NamingAuthorityUnitTest(), + new MonetaryLimitUnitTest(), + new NameOrPseudonymUnitTest(), + new PersonalDataUnitTest(), + new DERApplicationSpecificTest(), + new IssuingDistributionPointUnitTest(), + new TargetInformationTest(), + new SubjectKeyIdentifierTest(), + new ESSCertIDv2UnitTest(), + new ParsingTest(), + new GeneralNameTest(), + new RFC4519Test() }; public static void main( @@ -25,6 +76,12 @@ public class RegressionTest for (int i = 0; i != tests.length; i++) { TestResult result = tests[i].perform(); + + if (result.getException() != null) + { + result.getException().printStackTrace(); + } + System.out.println(result); } } diff --git a/crypto/j2me/org/bouncycastle/asn1/test/UTCTimeTest.java b/crypto/j2me/org/bouncycastle/asn1/test/UTCTimeTest.java new file mode 100644 index 000000000..e25bd9cd0 --- /dev/null +++ b/crypto/j2me/org/bouncycastle/asn1/test/UTCTimeTest.java @@ -0,0 +1,98 @@ +package org.bouncycastle.asn1.test; + +import org.bouncycastle.asn1.ASN1UTCTime; +import org.bouncycastle.asn1.DERUTCTime; +import org.bouncycastle.util.test.SimpleTest; + +/** + * X.690 test example + */ +public class UTCTimeTest + extends SimpleTest +{ + String[] input = + { + "020122122220Z", + "020122122220-1000", + "020122122220+1000", + "020122122220+00", + "0201221222Z", + "0201221222-1000", + "0201221222+1000", + "0201221222+00", + "550122122220Z", + "5501221222Z" + }; + + String[] output = { + "20020122122220GMT+00:00", + "20020122122220GMT-10:00", + "20020122122220GMT+10:00", + "20020122122220GMT+00:00", + "20020122122200GMT+00:00", + "20020122122200GMT-10:00", + "20020122122200GMT+10:00", + "20020122122200GMT+00:00", + "19550122122220GMT+00:00", + "19550122122200GMT+00:00" + }; + + String[] zOutput1 = { + "20020122122220Z", + "20020122222220Z", + "20020122022220Z", + "20020122122220Z", + "20020122122200Z", + "20020122222200Z", + "20020122022200Z", + "20020122122200Z", + "19550122122220Z", + "19550122122200Z" + }; + + String[] zOutput2 = { + "20020122122220Z", + "20020122222220Z", + "20020122022220Z", + "20020122122220Z", + "20020122122200Z", + "20020122222200Z", + "20020122022200Z", + "20020122122200Z", + "19550122122220Z", + "19550122122200Z" + }; + + public String getName() + { + return "UTCTime"; + } + + public void performTest() + throws Exception + { + + for (int i = 0; i != input.length; i++) + { + DERUTCTime t = new DERUTCTime(input[i]); + + if (!t.getAdjustedTime().equals(output[i])) + { + fail("failed conversion test " + i); + } + + t = new ASN1UTCTime(zOutput1[i].substring(2)); + + if (!new ASN1UTCTime(t.getAdjustedDate()).getAdjustedTime().equals(t.getAdjustedTime())) + { + fail("failed equality test"); + } + } + } + + public static void main( + String[] args) + { + runTest(new UTCTimeTest()); + } +} diff --git a/crypto/j2me/org/bouncycastle/asn1/x509/Time.java b/crypto/j2me/org/bouncycastle/asn1/x509/Time.java index 14da1dc5a..f8ca4e203 100644 --- a/crypto/j2me/org/bouncycastle/asn1/x509/Time.java +++ b/crypto/j2me/org/bouncycastle/asn1/x509/Time.java @@ -1,21 +1,30 @@ package org.bouncycastle.asn1.x509; -import org.bouncycastle.asn1.*; +import java.util.Calendar; +import java.util.Date; + +import org.bouncycastle.asn1.ASN1Choice; +import org.bouncycastle.asn1.ASN1Object; +import org.bouncycastle.asn1.ASN1Primitive; +import org.bouncycastle.asn1.ASN1TaggedObject; +import org.bouncycastle.asn1.DERGeneralizedTime; +import org.bouncycastle.asn1.DERUTCTime; public class Time - implements DEREncodable, ASN1Choice + extends ASN1Object + implements ASN1Choice { - DERObject time; + ASN1Primitive time; public static Time getInstance( ASN1TaggedObject obj, boolean explicit) { - return getInstance(obj.getObject()); + return getInstance(obj.getObject()); // must be explicitly tagged } public Time( - DERObject time) + ASN1Primitive time) { if (!(time instanceof DERUTCTime) && !(time instanceof DERGeneralizedTime)) @@ -26,6 +35,30 @@ public class Time this.time = time; } + /** + * creates a time object from a given date - if the date is between 1950 + * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime + * is used. + */ + public Time( + Date date) + { + Calendar calendar = Calendar.getInstance(); + + calendar.setTime(date); + + int year = calendar.get(Calendar.YEAR); + + if (year < 1950 || year > 2049) + { + time = new DERGeneralizedTime(date); + } + else + { + time = new DERUTCTime(date); + } + } + public static Time getInstance( Object obj) { @@ -42,7 +75,7 @@ public class Time return new Time((DERGeneralizedTime)obj); } - throw new IllegalArgumentException("unknown object in factory"); + throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName()); } public String getTime() @@ -57,15 +90,33 @@ public class Time } } + public Date getDate() + { + if (time instanceof DERUTCTime) + { + return ((DERUTCTime)time).getAdjustedDate(); + } + else + { + return ((DERGeneralizedTime)time).getDate(); + } + } + /** + * Produce an object suitable for an ASN1OutputStream. * <pre> * Time ::= CHOICE { * utcTime UTCTime, * generalTime GeneralizedTime } * </pre> */ - public DERObject getDERObject() + public ASN1Primitive toASN1Primitive() { return time; } + + public String toString() + { + return getTime(); + } } diff --git a/crypto/j2me/org/bouncycastle/crypto/test/RSATest.java b/crypto/j2me/org/bouncycastle/crypto/test/RSATest.java index b4b20fd01..2369d1c58 100644 --- a/crypto/j2me/org/bouncycastle/crypto/test/RSATest.java +++ b/crypto/j2me/org/bouncycastle/crypto/test/RSATest.java @@ -3,22 +3,23 @@ package org.bouncycastle.crypto.test; import java.math.BigInteger; import java.security.SecureRandom; -import org.bouncycastle.util.test.*; - import org.bouncycastle.crypto.AsymmetricBlockCipher; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; -import org.bouncycastle.crypto.params.RSAKeyParameters; -import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; -import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; -import org.bouncycastle.crypto.engines.RSAEngine; -import org.bouncycastle.crypto.encodings.PKCS1Encoding; +import org.bouncycastle.crypto.CipherParameters; +import org.bouncycastle.crypto.InvalidCipherTextException; import org.bouncycastle.crypto.encodings.OAEPEncoding; +import org.bouncycastle.crypto.encodings.PKCS1Encoding; +import org.bouncycastle.crypto.engines.RSAEngine; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; - +import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; +import org.bouncycastle.crypto.params.RSAKeyParameters; +import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; +import org.bouncycastle.util.Arrays; import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.test.SimpleTest; public class RSATest - implements Test + extends SimpleTest { static BigInteger mod = new BigInteger("b259d2d6e627a768c94be36164c2d9fc79d97aab9253140e5bf17751197731d6f7540d2509e7b9ffee0a70a6e26d56e92d2edd7f85aba85600b69089f35f6bdbf3c298e05842535d9f064e6b0391cb7d306e0a2d20c4dfb4e7b49a9640bdea26c10ad69c3f05007ce2513cee44cfe01998e62b6c3637d3fc0391079b26ee36d5", 16); static BigInteger pubExp = new BigInteger("11", 16); @@ -35,22 +36,117 @@ public class RSATest // to check that we handling byte extension by big number correctly. // static String edgeInput = "ff6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"; + + static byte[] oversizedSig = Hex.decode("01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); + static byte[] dudBlock = Hex.decode("000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); + static byte[] truncatedDataBlock = Hex.decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff004e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); + static byte[] incorrectPadding = Hex.decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e"); + static byte[] missingDataBlock = Hex.decode("0001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); public String getName() { return "RSA"; } - public TestResult perform() + private void testStrictPKCS1Length(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) { - RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod, pubExp); - RSAKeyParameters privParameters = new RSAPrivateCrtKeyParameters(mod, pubExp, privExp, p, q, pExp, qExp, crtCoef); - byte[] data = Hex.decode(edgeInput); + AsymmetricBlockCipher eng = new RSAEngine(); + eng.init(true, privParameters); + + byte[] data = null; + + try + { + data = eng.processBlock(oversizedSig, 0, oversizedSig.length); + } + catch (Exception e) + { + fail("RSA: failed - exception " + e.toString(), e); + } + + eng = new PKCS1Encoding(eng); + + eng.init(false, pubParameters); + + try + { + data = eng.processBlock(data, 0, data.length); + + fail("oversized signature block not recognised"); + } + catch (InvalidCipherTextException e) + { + if (!e.getMessage().equals("block incorrect size")) + { + fail("RSA: failed - exception " + e.toString(), e); + } + } + } + + private void testTruncatedPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) + { + checkForPKCS1Exception(pubParameters, privParameters, truncatedDataBlock, "block truncated"); + } + + private void testDudPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) + { + checkForPKCS1Exception(pubParameters, privParameters, dudBlock, "unknown block type"); + } + + private void testWrongPaddingPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) + { + checkForPKCS1Exception(pubParameters, privParameters, incorrectPadding, "block padding incorrect"); + } + + private void testMissingDataPKCS1Block(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) + { + checkForPKCS1Exception(pubParameters, privParameters, missingDataBlock, "no data in block"); + } + + private void checkForPKCS1Exception(RSAKeyParameters pubParameters, RSAKeyParameters privParameters, byte[] inputData, String expectedMessage) + { + AsymmetricBlockCipher eng = new RSAEngine(); + + eng.init(true, privParameters); + + byte[] data = null; + + try + { + data = eng.processBlock(inputData, 0, inputData.length); + } + catch (Exception e) + { + fail("RSA: failed - exception " + e.toString(), e); + } + + eng = new PKCS1Encoding(eng); + + eng.init(false, pubParameters); + + try + { + data = eng.processBlock(data, 0, data.length); + + fail("missing data block not recognised"); + } + catch (InvalidCipherTextException e) + { + if (!e.getMessage().equals(expectedMessage)) + { + fail("RSA: failed - exception " + e.toString(), e); + } + } + } + + private void testOAEP(RSAKeyParameters pubParameters, RSAKeyParameters privParameters) + { // - // RAW + // OAEP - public encrypt, private decrypt // - AsymmetricBlockCipher eng = new RSAEngine(); + AsymmetricBlockCipher eng = new OAEPEncoding(new RSAEngine()); + byte[] data = Hex.decode(input); eng.init(true, pubParameters); @@ -60,7 +156,7 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("failed - exception " + e.toString(), e); } eng.init(false, privParameters); @@ -71,15 +167,65 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("failed - exception " + e.toString(), e); } - if (!edgeInput.equals(new String(Hex.encode(data)))) + if (!input.equals(new String(Hex.encode(data)))) + { + fail("failed OAEP Test"); + } + } + + private void zeroBlockTest(CipherParameters encParameters, CipherParameters decParameters) + { + AsymmetricBlockCipher eng = new PKCS1Encoding(new RSAEngine()); + + eng.init(true, encParameters); + + if (eng.getOutputBlockSize() != ((PKCS1Encoding)eng).getUnderlyingCipher().getOutputBlockSize()) { - return new SimpleTestResult(false, "RSA: failed RAW edge Test"); + fail("PKCS1 output block size incorrect"); } - data = Hex.decode(input); + byte[] zero = new byte[0]; + byte[] data = null; + + try + { + data = eng.processBlock(zero, 0, zero.length); + } + catch (Exception e) + { + fail("failed - exception " + e.toString(), e); + } + + eng.init(false, decParameters); + + try + { + data = eng.processBlock(data, 0, data.length); + } + catch (Exception e) + { + fail("failed - exception " + e.toString(), e); + } + + if (!Arrays.areEqual(zero, data)) + { + fail("failed PKCS1 zero Test"); + } + } + + public void performTest() + { + RSAKeyParameters pubParameters = new RSAKeyParameters(false, mod, pubExp); + RSAKeyParameters privParameters = new RSAPrivateCrtKeyParameters(mod, pubExp, privExp, p, q, pExp, qExp, crtCoef); + byte[] data = Hex.decode(edgeInput); + + // + // RAW + // + AsymmetricBlockCipher eng = new RSAEngine(); eng.init(true, pubParameters); @@ -89,7 +235,7 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("RSA: failed - exception " + e.toString(), e); } eng.init(false, privParameters); @@ -100,18 +246,15 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("failed - exception " + e.toString(), e); } - if (!input.equals(new String(Hex.encode(data)))) + if (!edgeInput.equals(new String(Hex.encode(data)))) { - return new SimpleTestResult(false, "RSA: failed RAW Test"); + fail("failed RAW edge Test"); } - // - // PKCS1 - public encrypt, private decrypt - // - eng = new PKCS1Encoding(eng); + data = Hex.decode(input); eng.init(true, pubParameters); @@ -121,7 +264,7 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("failed - exception " + e.toString(), e); } eng.init(false, privParameters); @@ -132,20 +275,25 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { - return new SimpleTestResult(false, "RSA: failed PKCS1 public/private Test"); + fail("failed RAW Test"); } // - // PKCS1 - private encrypt, public decrypt + // PKCS1 - public encrypt, private decrypt // - eng = new PKCS1Encoding(((PKCS1Encoding)eng).getUnderlyingCipher()); + eng = new PKCS1Encoding(eng); - eng.init(true, privParameters); + eng.init(true, pubParameters); + + if (eng.getOutputBlockSize() != ((PKCS1Encoding)eng).getUnderlyingCipher().getOutputBlockSize()) + { + fail("PKCS1 output block size incorrect"); + } try { @@ -153,10 +301,10 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("failed - exception " + e.toString(), e); } - eng.init(false, pubParameters); + eng.init(false, privParameters); try { @@ -164,20 +312,20 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { - return new SimpleTestResult(false, "RSA: failed PKCS1 private/public Test"); + fail("failed PKCS1 public/private Test"); } // - // OAEP - public encrypt, private decrypt + // PKCS1 - private encrypt, public decrypt // - eng = new OAEPEncoding(((PKCS1Encoding)eng).getUnderlyingCipher()); + eng = new PKCS1Encoding(((PKCS1Encoding)eng).getUnderlyingCipher()); - eng.init(true, pubParameters); + eng.init(true, privParameters); try { @@ -185,10 +333,10 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("failed - exception " + e.toString(), e); } - eng.init(false, privParameters); + eng.init(false, pubParameters); try { @@ -196,14 +344,20 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { - return new SimpleTestResult(false, "RSA: failed OAEP Test"); + fail("failed PKCS1 private/public Test"); } + zeroBlockTest(pubParameters, privParameters); + zeroBlockTest(privParameters, pubParameters); + + // + // key generation test + // RSAKeyPairGenerator pGen = new RSAKeyPairGenerator(); RSAKeyGenerationParameters genParam = new RSAKeyGenerationParameters( BigInteger.valueOf(0x11), new SecureRandom(), 768, 25); @@ -214,9 +368,9 @@ public class RSATest eng = new RSAEngine(); - if (((RSAKeyParameters)pair.getPublic()).getModulus().bitLength() < 762) + if (((RSAKeyParameters)pair.getPublic()).getModulus().bitLength() < 768) { - return new SimpleTestResult(false, "RSA: failed key generation (768) length test"); + fail("failed key generation (768) length test"); } eng.init(true, pair.getPublic()); @@ -227,7 +381,7 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("failed - exception " + e.toString(), e); } eng.init(false, pair.getPrivate()); @@ -238,12 +392,12 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { - return new SimpleTestResult(false, "RSA: failed key generation (768) Test"); + fail("failed key generation (768) Test"); } genParam = new RSAKeyGenerationParameters(BigInteger.valueOf(0x11), new SecureRandom(), 1024, 25); @@ -253,9 +407,9 @@ public class RSATest eng.init(true, pair.getPublic()); - if (((RSAKeyParameters)pair.getPublic()).getModulus().bitLength() < 1018) + if (((RSAKeyParameters)pair.getPublic()).getModulus().bitLength() < 1024) { - return new SimpleTestResult(false, "RSA: failed key generation (1024) length test"); + fail("failed key generation (1024) length test"); } try @@ -264,7 +418,7 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("failed - exception " + e.toString(), e); } eng.init(false, pair.getPrivate()); @@ -275,23 +429,52 @@ public class RSATest } catch (Exception e) { - return new SimpleTestResult(false, "RSA: failed - exception " + e.toString()); + fail("failed - exception " + e.toString(), e); } if (!input.equals(new String(Hex.encode(data)))) { - return new SimpleTestResult(false, "RSA: failed key generation (1024) test"); + fail("failed key generation (1024) test"); } - return new SimpleTestResult(false, "RSA: Okay"); + genParam = new RSAKeyGenerationParameters( + BigInteger.valueOf(0x11), new SecureRandom(), 16, 25); + pGen.init(genParam); + + for (int i = 0; i < 100; ++i) + { + pair = pGen.generateKeyPair(); + RSAPrivateCrtKeyParameters privKey = (RSAPrivateCrtKeyParameters) pair.getPrivate(); + BigInteger pqDiff = privKey.getP().subtract(privKey.getQ()).abs(); + + if (pqDiff.bitLength() < 5) + { + fail("P and Q too close in RSA key pair"); + } + } + + testOAEP(pubParameters, privParameters); + testStrictPKCS1Length(pubParameters, privParameters); + testDudPKCS1Block(pubParameters, privParameters); + testMissingDataPKCS1Block(pubParameters, privParameters); + testTruncatedPKCS1Block(pubParameters, privParameters); + testWrongPaddingPKCS1Block(pubParameters, privParameters); + + try + { + new RSAEngine().processBlock(new byte[]{ 1 }, 0, 1); + fail("failed initialisation check"); + } + catch (IllegalStateException e) + { + // expected + } } + public static void main( String[] args) { - RSATest test = new RSATest(); - TestResult result = test.perform(); - - System.out.println(result); + runTest(new RSATest()); } } diff --git a/crypto/j2me/org/bouncycastle/crypto/test/RegressionTest.java b/crypto/j2me/org/bouncycastle/crypto/test/RegressionTest.java index d34638a8d..f8d37aaa1 100644 --- a/crypto/j2me/org/bouncycastle/crypto/test/RegressionTest.java +++ b/crypto/j2me/org/bouncycastle/crypto/test/RegressionTest.java @@ -1,15 +1,11 @@ package org.bouncycastle.crypto.test; -import org.bouncycastle.crypto.test.GOST28147Test; -import org.bouncycastle.crypto.test.GOST3410Test; -import org.bouncycastle.util.test.*; +import org.bouncycastle.util.test.Test; +import org.bouncycastle.util.test.TestResult; public final class RegressionTest { - private RegressionTest() - { }; - - private static Test[] _tests = { + public static Test[] tests = { new AESTest(), new DESTest(), new DESedeTest(), @@ -62,9 +58,9 @@ public final class RegressionTest public static void main( String[] args) { - for (int i = 0; i != _tests.length; i++) + for (int i = 0; i != tests.length; i++) { - TestResult result = _tests[i].perform(); + TestResult result = tests[i].perform(); System.out.println(result); } } diff --git a/crypto/j2me/org/bouncycastle/util/Selector.java b/crypto/j2me/org/bouncycastle/util/Selector.java new file mode 100644 index 000000000..79a1dd82a --- /dev/null +++ b/crypto/j2me/org/bouncycastle/util/Selector.java @@ -0,0 +1,8 @@ +package org.bouncycastle.util; + +public interface Selector +{ + boolean match(Object obj); + + Object clone(); +} |