Update spongycastle to open-keychain/spongycastle master

Current master (HEAD) is 2c744ebade816d2e4f65f3734db373e4c19c2e4f
This commit is contained in:
Daniel Martí 2015-04-01 11:08:29 +02:00
parent 893e68b3da
commit 274013ad68
732 changed files with 30122 additions and 16943 deletions

View File

@ -1,7 +1,7 @@
<html>
<body bgcolor=#ffffff>
Copyright (c) 2000-2013 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
<p>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,

View File

@ -9,5 +9,5 @@ subprojects {
sourceCompatibility = 1.5
targetCompatibility = 1.5
version = '1.50.0.0'
version = '1.51.0.0'
}

View File

@ -2,4 +2,4 @@ apply plugin: 'java'
sourceCompatibility = 1.5
targetCompatibility = 1.5
version = '1.50.0.0'
version = '1.51.0.0'

View File

@ -1460,12 +1460,12 @@ public class BigInteger
bitsCorrect <<= 1;
}
while (bitsCorrect < pow);
}
if (x.sign < 0)
{
x = x.add(m);
}
}
return x;
}

View File

@ -1,27 +1,260 @@
package org.spongycastle.asn1;
import java.io.IOException;
import java.util.Date;
import java.util.TimeZone;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings;
/**
* Generalized time object.
*/
public class ASN1GeneralizedTime
extends DERGeneralizedTime
extends ASN1Primitive
{
ASN1GeneralizedTime(byte[] bytes)
private byte[] time;
/**
* return a generalized time from the passed in object
*
* @exception IllegalArgumentException if the object cannot be converted.
*/
public static ASN1GeneralizedTime getInstance(
Object obj)
{
super(bytes);
if (obj == null || obj instanceof ASN1GeneralizedTime)
{
return (ASN1GeneralizedTime)obj;
}
public ASN1GeneralizedTime(Date date)
if (obj instanceof ASN1GeneralizedTime)
{
super(date);
return new ASN1GeneralizedTime(((ASN1GeneralizedTime)obj).time);
}
public ASN1GeneralizedTime(Date date, boolean includeMillis)
{
super(date, includeMillis);
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
public ASN1GeneralizedTime(String time)
/**
* return a Generalized Time object from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
public static ASN1GeneralizedTime getInstance(
ASN1TaggedObject obj,
boolean explicit)
{
super(time);
ASN1Primitive o = obj.getObject();
if (explicit || o instanceof ASN1GeneralizedTime)
{
return getInstance(o);
}
else
{
return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets());
}
}
/**
* 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
* time and UTC time. The fractional second amount f must consist of at
* least one number with trailing zeroes removed.
*
* @param time the time string.
* @exception IllegalArgumentException if String is an illegal format.
*/
public ASN1GeneralizedTime(
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 ASN1GeneralizedTime(
Date time)
{
this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(time, false));
}
protected ASN1GeneralizedTime(Date date, boolean includeMillis)
{
this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(date, true));
}
ASN1GeneralizedTime(
byte[] bytes)
{
this.time = bytes;
}
/**
* Return the time.
* @return The time string as it appeared in the encoded object.
*/
public String getTimeString()
{
return Strings.fromByteArray(time);
}
/**
* return the time - always in the form of
* YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm).
* <p>
* Normally in a certificate we would expect "Z" rather than "GMT",
* however adding the "GMT" means we can just use:
* <pre>
* dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
* </pre>
* To read in the time and get a date which is compatible with our local
* time zone.
*/
public String getTime()
{
String stime = Strings.fromByteArray(time);
//
// standardise the format.
//
if (stime.charAt(stime.length() - 1) == 'Z')
{
return stime.substring(0, stime.length() - 1) + "GMT+00:00";
}
else
{
int signPos = stime.length() - 5;
char sign = stime.charAt(signPos);
if (sign == '-' || sign == '+')
{
return stime.substring(0, signPos)
+ "GMT"
+ stime.substring(signPos, signPos + 3)
+ ":"
+ stime.substring(signPos + 3);
}
else
{
signPos = stime.length() - 3;
sign = stime.charAt(signPos);
if (sign == '-' || sign == '+')
{
return stime.substring(0, signPos)
+ "GMT"
+ stime.substring(signPos)
+ ":00";
}
}
}
return stime + calculateGMTOffset();
}
private String calculateGMTOffset()
{
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);
// 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);
}
private String convert(int time)
{
if (time < 10)
{
return "0" + time;
}
return Integer.toString(time);
}
public Date getDate()
{
return DateFormatter.fromGeneralizedTimeString(time);
}
private boolean hasFractionalSeconds()
{
for (int i = 0; i != time.length; i++)
{
if (time[i] == '.')
{
if (i == 14)
{
return true;
}
}
}
return false;
}
boolean isConstructed()
{
return false;
}
int encodedLength()
{
int length = time.length;
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.writeEncoded(BERTags.GENERALIZED_TIME, time);
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof ASN1GeneralizedTime))
{
return false;
}
return Arrays.areEqual(time, ((ASN1GeneralizedTime)o).time);
}
public int hashCode()
{
return Arrays.hashCode(time);
}
}

View File

@ -1,22 +1,259 @@
package org.spongycastle.asn1;
import java.io.IOException;
import java.util.Date;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings;
/**
* UTC time object.
*/
public class ASN1UTCTime
extends DERUTCTime
extends ASN1Primitive
{
ASN1UTCTime(byte[] bytes)
private byte[] time;
/**
* return an UTC Time from the passed in object.
*
* @exception IllegalArgumentException if the object cannot be converted.
*/
public static ASN1UTCTime getInstance(
Object obj)
{
super(bytes);
if (obj == null || obj instanceof ASN1UTCTime)
{
return (ASN1UTCTime)obj;
}
public ASN1UTCTime(Date date)
if (obj instanceof ASN1UTCTime)
{
super(date);
return new ASN1UTCTime(((ASN1UTCTime)obj).time);
}
public ASN1UTCTime(String time)
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return an UTC Time from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
public static ASN1UTCTime getInstance(
ASN1TaggedObject obj,
boolean explicit)
{
super(time);
ASN1Object o = obj.getObject();
if (explicit || o instanceof ASN1UTCTime)
{
return getInstance(o);
}
else
{
return new ASN1UTCTime(((ASN1OctetString)o).getOctets());
}
}
/**
* The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
* never encoded. When you're creating one of these objects from scratch, that's
* what you want to use, otherwise we'll try to deal with whatever gets read from
* the input stream... (this is why the input format is different from the getTime()
* method output).
* <p>
*
* @param time the time string.
*/
public ASN1UTCTime(
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 ASN1UTCTime(
Date time)
{
this.time = Strings.toByteArray(DateFormatter.toUTCDateString(time));
}
ASN1UTCTime(
byte[] time)
{
this.time = time;
}
/**
* 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>
* Normally in a certificate we would expect "Z" rather than "GMT",
* however adding the "GMT" means we can just use:
* <pre>
* dateF = new SimpleDateFormat("yyMMddHHmmssz");
* </pre>
* To read in the time and get a date which is compatible with our local
* time zone.
* <p>
* <b>Note:</b> In some cases, due to the local date processing, this
* may lead to unexpected results. If you want to stick the normal
* convention of 1950 to 2049 use the getAdjustedTime() method.
*/
public String getTime()
{
String stime = Strings.fromByteArray(time);
//
// standardise the format.
//
if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0)
{
if (stime.length() == 11)
{
return stime.substring(0, 10) + "00GMT+00:00";
}
else
{
return stime.substring(0, 12) + "GMT+00:00";
}
}
else
{
int index = stime.indexOf('-');
if (index < 0)
{
index = stime.indexOf('+');
}
String d = stime;
if (index == stime.length() - 3)
{
d += "00";
}
if (index == 10)
{
return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15);
}
else
{
return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17);
}
}
}
/**
* return a time string as an adjusted date with a 4 digit year. This goes
* in the range of 1950 - 2049.
*/
public String getAdjustedTime()
{
String d = this.getTime();
if (d.charAt(0) < '5')
{
return "20" + d;
}
else
{
return "19" + d;
}
}
/**
* 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;
}
int encodedLength()
{
int length = time.length;
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.write(BERTags.UTC_TIME);
int length = time.length;
out.writeLength(length);
for (int i = 0; i != length; i++)
{
out.write((byte)time[i]);
}
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof ASN1UTCTime))
{
return false;
}
return Arrays.areEqual(time, ((ASN1UTCTime)o).time);
}
public int hashCode()
{
return Arrays.hashCode(time);
}
public String toString()
{
return Strings.fromByteArray(time);
}
}

View File

@ -1,260 +1,27 @@
package org.spongycastle.asn1;
import java.io.IOException;
import java.util.Date;
import java.util.TimeZone;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings;
/**
* Generalized time object.
*/
public class DERGeneralizedTime
extends ASN1Primitive
extends ASN1GeneralizedTime
{
private byte[] time;
/**
* return a generalized time from the passed in object
*
* @exception IllegalArgumentException if the object cannot be converted.
*/
public static ASN1GeneralizedTime getInstance(
Object obj)
DERGeneralizedTime(byte[] bytes)
{
if (obj == null || obj instanceof ASN1GeneralizedTime)
{
return (ASN1GeneralizedTime)obj;
super(bytes);
}
if (obj instanceof DERGeneralizedTime)
public DERGeneralizedTime(Date date)
{
return new ASN1GeneralizedTime(((DERGeneralizedTime)obj).time);
super(date);
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
public DERGeneralizedTime(Date date, boolean includeMillis)
{
super(date, includeMillis);
}
/**
* return a Generalized Time object from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
public static ASN1GeneralizedTime getInstance(
ASN1TaggedObject obj,
boolean explicit)
public DERGeneralizedTime(String time)
{
ASN1Primitive o = obj.getObject();
if (explicit || o instanceof DERGeneralizedTime)
{
return getInstance(o);
}
else
{
return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets());
}
}
/**
* 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
* time and UTC time. The fractional second amount f must consist of at
* least one number with trailing zeroes removed.
*
* @param time the time string.
* @exception IllegalArgumentException if String is an illegal format.
*/
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)
{
this.time = bytes;
}
/**
* Return the time.
* @return The time string as it appeared in the encoded object.
*/
public String getTimeString()
{
return Strings.fromByteArray(time);
}
/**
* return the time - always in the form of
* YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm).
* <p>
* Normally in a certificate we would expect "Z" rather than "GMT",
* however adding the "GMT" means we can just use:
* <pre>
* dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
* </pre>
* To read in the time and get a date which is compatible with our local
* time zone.
*/
public String getTime()
{
String stime = Strings.fromByteArray(time);
//
// standardise the format.
//
if (stime.charAt(stime.length() - 1) == 'Z')
{
return stime.substring(0, stime.length() - 1) + "GMT+00:00";
}
else
{
int signPos = stime.length() - 5;
char sign = stime.charAt(signPos);
if (sign == '-' || sign == '+')
{
return stime.substring(0, signPos)
+ "GMT"
+ stime.substring(signPos, signPos + 3)
+ ":"
+ stime.substring(signPos + 3);
}
else
{
signPos = stime.length() - 3;
sign = stime.charAt(signPos);
if (sign == '-' || sign == '+')
{
return stime.substring(0, signPos)
+ "GMT"
+ stime.substring(signPos)
+ ":00";
}
}
}
return stime + calculateGMTOffset();
}
private String calculateGMTOffset()
{
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);
// 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);
}
private String convert(int time)
{
if (time < 10)
{
return "0" + time;
}
return Integer.toString(time);
}
public Date getDate()
{
return DateFormatter.fromGeneralizedTimeString(time);
}
private boolean hasFractionalSeconds()
{
for (int i = 0; i != time.length; i++)
{
if (time[i] == '.')
{
if (i == 14)
{
return true;
}
}
}
return false;
}
boolean isConstructed()
{
return false;
}
int encodedLength()
{
int length = time.length;
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.writeEncoded(BERTags.GENERALIZED_TIME, time);
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof DERGeneralizedTime))
{
return false;
}
return Arrays.areEqual(time, ((DERGeneralizedTime)o).time);
}
public int hashCode()
{
return Arrays.hashCode(time);
super(time);
}
}

View File

@ -1,259 +1,22 @@
package org.spongycastle.asn1;
import java.io.IOException;
import java.util.Date;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings;
/**
* UTC time object.
*/
public class DERUTCTime
extends ASN1Primitive
extends ASN1UTCTime
{
private byte[] time;
/**
* return an UTC Time from the passed in object.
*
* @exception IllegalArgumentException if the object cannot be converted.
*/
public static ASN1UTCTime getInstance(
Object obj)
DERUTCTime(byte[] bytes)
{
if (obj == null || obj instanceof ASN1UTCTime)
{
return (ASN1UTCTime)obj;
super(bytes);
}
if (obj instanceof DERUTCTime)
public DERUTCTime(Date date)
{
return new ASN1UTCTime(((DERUTCTime)obj).time);
super(date);
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return an UTC Time from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
public static ASN1UTCTime getInstance(
ASN1TaggedObject obj,
boolean explicit)
public DERUTCTime(String time)
{
ASN1Object o = obj.getObject();
if (explicit || o instanceof ASN1UTCTime)
{
return getInstance(o);
}
else
{
return new ASN1UTCTime(((ASN1OctetString)o).getOctets());
}
}
/**
* The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
* never encoded. When you're creating one of these objects from scratch, that's
* what you want to use, otherwise we'll try to deal with whatever gets read from
* the input stream... (this is why the input format is different from the getTime()
* method output).
* <p>
*
* @param time the time string.
*/
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)
{
this.time = time;
}
/**
* 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>
* Normally in a certificate we would expect "Z" rather than "GMT",
* however adding the "GMT" means we can just use:
* <pre>
* dateF = new SimpleDateFormat("yyMMddHHmmssz");
* </pre>
* To read in the time and get a date which is compatible with our local
* time zone.
* <p>
* <b>Note:</b> In some cases, due to the local date processing, this
* may lead to unexpected results. If you want to stick the normal
* convention of 1950 to 2049 use the getAdjustedTime() method.
*/
public String getTime()
{
String stime = Strings.fromByteArray(time);
//
// standardise the format.
//
if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0)
{
if (stime.length() == 11)
{
return stime.substring(0, 10) + "00GMT+00:00";
}
else
{
return stime.substring(0, 12) + "GMT+00:00";
}
}
else
{
int index = stime.indexOf('-');
if (index < 0)
{
index = stime.indexOf('+');
}
String d = stime;
if (index == stime.length() - 3)
{
d += "00";
}
if (index == 10)
{
return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15);
}
else
{
return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17);
}
}
}
/**
* return a time string as an adjusted date with a 4 digit year. This goes
* in the range of 1950 - 2049.
*/
public String getAdjustedTime()
{
String d = this.getTime();
if (d.charAt(0) < '5')
{
return "20" + d;
}
else
{
return "19" + d;
}
}
/**
* 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;
}
int encodedLength()
{
int length = time.length;
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.write(BERTags.UTC_TIME);
int length = time.length;
out.writeLength(length);
for (int i = 0; i != length; i++)
{
out.write((byte)time[i]);
}
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof DERUTCTime))
{
return false;
}
return Arrays.areEqual(time, ((DERUTCTime)o).time);
}
public int hashCode()
{
return Arrays.hashCode(time);
}
public String toString()
{
return Strings.fromByteArray(time);
super(time);
}
}

View File

@ -7,8 +7,8 @@ import org.spongycastle.asn1.ASN1Choice;
import org.spongycastle.asn1.ASN1Object;
import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.DERGeneralizedTime;
import org.spongycastle.asn1.DERUTCTime;
import org.spongycastle.asn1.ASN1GeneralizedTime;
import org.spongycastle.asn1.ASN1UTCTime;
public class Time
extends ASN1Object
@ -26,8 +26,8 @@ public class Time
public Time(
ASN1Primitive time)
{
if (!(time instanceof DERUTCTime)
&& !(time instanceof DERGeneralizedTime))
if (!(time instanceof ASN1UTCTime)
&& !(time instanceof ASN1GeneralizedTime))
{
throw new IllegalArgumentException("unknown object passed to Time");
}
@ -51,11 +51,11 @@ public class Time
if (year < 1950 || year > 2049)
{
time = new DERGeneralizedTime(date);
time = new ASN1GeneralizedTime(date);
}
else
{
time = new DERUTCTime(date);
time = new ASN1UTCTime(date);
}
}
@ -66,13 +66,13 @@ public class Time
{
return (Time)obj;
}
else if (obj instanceof DERUTCTime)
else if (obj instanceof ASN1UTCTime)
{
return new Time((DERUTCTime)obj);
return new Time((ASN1UTCTime)obj);
}
else if (obj instanceof DERGeneralizedTime)
else if (obj instanceof ASN1GeneralizedTime)
{
return new Time((DERGeneralizedTime)obj);
return new Time((ASN1GeneralizedTime)obj);
}
throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
@ -80,25 +80,25 @@ public class Time
public String getTime()
{
if (time instanceof DERUTCTime)
if (time instanceof ASN1UTCTime)
{
return ((DERUTCTime)time).getAdjustedTime();
return ((ASN1UTCTime)time).getAdjustedTime();
}
else
{
return ((DERGeneralizedTime)time).getTime();
return ((ASN1GeneralizedTime)time).getTime();
}
}
public Date getDate()
{
if (time instanceof DERUTCTime)
if (time instanceof ASN1UTCTime)
{
return ((DERUTCTime)time).getAdjustedDate();
return ((ASN1UTCTime)time).getAdjustedDate();
}
else
{
return ((DERGeneralizedTime)time).getDate();
return ((ASN1GeneralizedTime)time).getDate();
}
}

View File

@ -7,8 +7,8 @@ import org.spongycastle.asn1.ASN1Choice;
import org.spongycastle.asn1.ASN1Object;
import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.DERGeneralizedTime;
import org.spongycastle.asn1.DERUTCTime;
import org.spongycastle.asn1.ASN1GeneralizedTime;
import org.spongycastle.asn1.ASN1UTCTime;
public class Time
extends ASN1Object
@ -26,8 +26,8 @@ public class Time
public Time(
ASN1Primitive time)
{
if (!(time instanceof DERUTCTime)
&& !(time instanceof DERGeneralizedTime))
if (!(time instanceof ASN1UTCTime)
&& !(time instanceof ASN1GeneralizedTime))
{
throw new IllegalArgumentException("unknown object passed to Time");
}
@ -51,11 +51,11 @@ public class Time
if (year < 1950 || year > 2049)
{
time = new DERGeneralizedTime(date);
time = new ASN1GeneralizedTime(date);
}
else
{
time = new DERUTCTime(date);
time = new ASN1UTCTime(date);
}
}
@ -66,13 +66,13 @@ public class Time
{
return (Time)obj;
}
else if (obj instanceof DERUTCTime)
else if (obj instanceof ASN1UTCTime)
{
return new Time((DERUTCTime)obj);
return new Time((ASN1UTCTime)obj);
}
else if (obj instanceof DERGeneralizedTime)
else if (obj instanceof ASN1GeneralizedTime)
{
return new Time((DERGeneralizedTime)obj);
return new Time((ASN1GeneralizedTime)obj);
}
throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
@ -80,25 +80,25 @@ public class Time
public String getTime()
{
if (time instanceof DERUTCTime)
if (time instanceof ASN1UTCTime)
{
return ((DERUTCTime)time).getAdjustedTime();
return ((ASN1UTCTime)time).getAdjustedTime();
}
else
{
return ((DERGeneralizedTime)time).getTime();
return ((ASN1GeneralizedTime)time).getTime();
}
}
public Date getDate()
{
if (time instanceof DERUTCTime)
if (time instanceof ASN1UTCTime)
{
return ((DERUTCTime)time).getAdjustedDate();
return ((ASN1UTCTime)time).getAdjustedDate();
}
else
{
return ((DERGeneralizedTime)time).getDate();
return ((ASN1GeneralizedTime)time).getDate();
}
}

View File

@ -1,13 +1,13 @@
package org.spongycastle.crypto.encodings;
import java.security.SecureRandom;
import org.spongycastle.crypto.AsymmetricBlockCipher;
import org.spongycastle.crypto.CipherParameters;
import org.spongycastle.crypto.InvalidCipherTextException;
import org.spongycastle.crypto.params.AsymmetricKeyParameter;
import org.spongycastle.crypto.params.ParametersWithRandom;
import java.security.SecureRandom;
/**
* this does your basic PKCS 1 v1.5 padding - whether or not you should be using this
* depends on your application - see PKCS1 Version 2 for details.
@ -32,6 +32,8 @@ public class PKCS1Encoding
private boolean forEncryption;
private boolean forPrivateKey;
private boolean useStrictLength;
private int pLen = -1;
private byte[] fallback = null;
/**
* Basic constructor.
@ -44,11 +46,48 @@ public class PKCS1Encoding
this.useStrictLength = useStrict();
}
/**
* Constructor for decryption with a fixed plaintext length.
*
* @param cipher The cipher to use for cryptographic operation.
* @param pLen Length of the expected plaintext.
*/
public PKCS1Encoding(
AsymmetricBlockCipher cipher,
int pLen)
{
this.engine = cipher;
this.useStrictLength = useStrict();
this.pLen = pLen;
}
/**
* Constructor for decryption with a fixed plaintext length and a fallback
* value that is returned, if the padding is incorrect.
*
* @param cipher
* The cipher to use for cryptographic operation.
* @param fallback
* The fallback value, we don't to a arraycopy here.
*/
public PKCS1Encoding(
AsymmetricBlockCipher cipher,
byte[] fallback)
{
this.engine = cipher;
this.useStrictLength = useStrict();
this.fallback = fallback;
this.pLen = fallback.length;
}
//
// for J2ME compatibility
//
private boolean useStrict()
{
// required if security manager has been installed.
String strict = System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY);
return strict == null || strict.equals("true");
@ -175,6 +214,121 @@ public class PKCS1Encoding
return engine.processBlock(block, 0, block.length);
}
/**
* Checks if the argument is a correctly PKCS#1.5 encoded Plaintext
* for encryption.
*
* @param encoded The Plaintext.
* @param pLen Expected length of the plaintext.
* @return Either 0, if the encoding is correct, or -1, if it is incorrect.
*/
private static int checkPkcs1Encoding(byte[] encoded, int pLen) {
int correct = 0;
/*
* Check if the first two bytes are 0 2
*/
correct |= (encoded[0] ^ 2);
/*
* Now the padding check, check for no 0 byte in the padding
*/
int plen = encoded.length - (
pLen /* Lenght of the PMS */
+ 1 /* Final 0-byte before PMS */
);
for (int i = 1; i < plen; i++) {
int tmp = encoded[i];
tmp |= tmp >> 1;
tmp |= tmp >> 2;
tmp |= tmp >> 4;
correct |= (tmp & 1) - 1;
}
/*
* Make sure the padding ends with a 0 byte.
*/
correct |= encoded[encoded.length - (pLen +1)];
/*
* Return 0 or 1, depending on the result.
*/
correct |= correct >> 1;
correct |= correct >> 2;
correct |= correct >> 4;
return ~((correct & 1) - 1);
}
/**
* Decode PKCS#1.5 encoding, and return a random value if the padding is not correct.
*
* @param in The encrypted block.
* @param inOff Offset in the encrypted block.
* @param inLen Length of the encrypted block.
* //@param pLen Length of the desired output.
* @return The plaintext without padding, or a random value if the padding was incorrect.
*
* @throws InvalidCipherTextException
*/
private byte[] decodeBlockOrRandom(byte[] in, int inOff, int inLen)
throws InvalidCipherTextException
{
if (!forPrivateKey)
{
throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing");
}
byte[] block = engine.processBlock(in, inOff, inLen);
byte[] random = null;
if (this.fallback == null)
{
random = new byte[this.pLen];
this.random.nextBytes(random);
}
else
{
random = fallback;
}
/*
* TODO: This is a potential dangerous side channel. However, you can
* fix this by changing the RSA engine in a way, that it will always
* return blocks of the same length and prepend them with 0 bytes if
* needed.
*/
if (block.length < getOutputBlockSize())
{
throw new InvalidCipherTextException("block truncated");
}
/*
* TODO: Potential side channel. Fix it by making the engine always
* return blocks of the correct length.
*/
if (useStrictLength && block.length != engine.getOutputBlockSize())
{
throw new InvalidCipherTextException("block incorrect size");
}
/*
* Check the padding.
*/
int correct = PKCS1Encoding.checkPkcs1Encoding(block, this.pLen);
/*
* Now, to a constant time constant memory copy of the decrypted value
* or the random value, depending on the validity of the padding.
*/
byte[] result = new byte[this.pLen];
for (int i = 0; i < this.pLen; i++)
{
result[i] = (byte)((block[i + (block.length - pLen)] & (~correct)) | (random[i] & correct));
}
return result;
}
/**
* @exception InvalidCipherTextException if the decrypted block is not in PKCS1 format.
*/
@ -184,6 +338,14 @@ public class PKCS1Encoding
int inLen)
throws InvalidCipherTextException
{
/*
* If the length of the expected plaintext is known, we use a constant-time decryption.
* If the decryption fails, we return a random value.
*/
if (this.pLen != -1) {
return this.decodeBlockOrRandom(in, inOff, inLen);
}
byte[] block = engine.processBlock(in, inOff, inLen);
if (block.length < getOutputBlockSize())
@ -193,10 +355,20 @@ public class PKCS1Encoding
byte type = block[0];
if (type != 1 && type != 2)
if (forPrivateKey)
{
if (type != 2)
{
throw new InvalidCipherTextException("unknown block type");
}
}
else
{
if (type != 1)
{
throw new InvalidCipherTextException("unknown block type");
}
}
if (useStrictLength && block.length != engine.getOutputBlockSize())
{

View File

@ -90,11 +90,11 @@ public class OCSPStatusRequest
}
/**
* Parse a {@link OCSPStatusRequest} from an {@link InputStream}.
* Parse an {@link OCSPStatusRequest} from an {@link InputStream}.
*
* @param input
* the {@link InputStream} to parse from.
* @return a {@link OCSPStatusRequest} object.
* @return an {@link OCSPStatusRequest} object.
* @throws IOException
*/
public static OCSPStatusRequest parse(InputStream input) throws IOException

View File

@ -371,6 +371,23 @@ class LongArray
}
}
public boolean isOne()
{
long[] a = m_ints;
if (a[0] != 1L)
{
return false;
}
for (int i = 1; i < a.length; ++i)
{
if (a[i] != 0L)
{
return false;
}
}
return true;
}
public boolean isZero()
{
long[] a = m_ints;
@ -822,12 +839,12 @@ class LongArray
add(c, cOff, b, 0, bLen);
}
int k = 1;
while ((a >>>= 1) != 0)
while ((a >>>= 1) != 0L)
{
if ((a & 1L) != 0L)
{
long carry = addShiftedUp(c, cOff, b, 0, bLen, k);
if (carry != 0)
if (carry != 0L)
{
c[cOff + bLen] ^= carry;
}
@ -871,8 +888,8 @@ class LongArray
if (aLen == 1)
{
long a = A.m_ints[0];
if (a == 1L)
long a0 = A.m_ints[0];
if (a0 == 1L)
{
return B;
}
@ -880,13 +897,13 @@ class LongArray
/*
* Fast path for small A, with performance dependent only on the number of set bits
*/
long[] c = new long[cLen];
multiplyWord(a, B.m_ints, bLen, c, 0);
long[] c0 = new long[cLen];
multiplyWord(a0, B.m_ints, bLen, c0, 0);
/*
* Reduce the raw answer against the reduction coefficients
*/
return reduceResult(c, 0, cLen, m, ks);
return reduceResult(c0, 0, cLen, m, ks);
}
/*
@ -1003,8 +1020,8 @@ class LongArray
if (aLen == 1)
{
long a = A.m_ints[0];
if (a == 1L)
long a0 = A.m_ints[0];
if (a0 == 1L)
{
return B;
}
@ -1012,13 +1029,13 @@ class LongArray
/*
* Fast path for small A, with performance dependent only on the number of set bits
*/
long[] c = new long[cLen];
multiplyWord(a, B.m_ints, bLen, c, 0);
long[] c0 = new long[cLen];
multiplyWord(a0, B.m_ints, bLen, c0, 0);
/*
* Reduce the raw answer against the reduction coefficients
*/
return reduceResult(c, 0, cLen, m, ks);
return reduceResult(c0, 0, cLen, m, ks);
}
/*
@ -1077,7 +1094,8 @@ class LongArray
aVal >>>= 4;
int v = (int)aVal & MASK;
addBoth(c, cOff, T0, ti[u], T1, ti[v], bMax);
if ((aVal >>>= 4) == 0L)
aVal >>>= 4;
if (aVal == 0L)
{
break;
}
@ -1085,11 +1103,13 @@ class LongArray
}
}
{
int cOff = c.length;
while ((cOff -= cLen) != 0)
{
addShiftedUp(c, cOff - cLen, c, cOff, cLen, 8);
}
}
/*
* Finally the raw answer is collected, reduce it against the reduction coefficients
@ -1132,8 +1152,8 @@ class LongArray
if (aLen == 1)
{
long a = A.m_ints[0];
if (a == 1L)
long a0 = A.m_ints[0];
if (a0 == 1L)
{
return B;
}
@ -1141,13 +1161,13 @@ class LongArray
/*
* Fast path for small A, with performance dependent only on the number of set bits
*/
long[] c = new long[cLen];
multiplyWord(a, B.m_ints, bLen, c, 0);
long[] c0 = new long[cLen];
multiplyWord(a0, B.m_ints, bLen, c0, 0);
/*
* Reduce the raw answer against the reduction coefficients
*/
return reduceResult(c, 0, cLen, m, ks);
return reduceResult(c0, 0, cLen, m, ks);
}
// NOTE: This works, but is slower than width 4 processing
@ -1314,6 +1334,158 @@ class LongArray
return reduceResult(c, ci[1], cLen, m, ks);
}
public LongArray modReduce(int m, int[] ks)
{
long[] buf = Arrays.clone(m_ints);
int rLen = reduceInPlace(buf, 0, buf.length, m, ks);
return new LongArray(buf, 0, rLen);
}
public LongArray multiply(LongArray other, int m, int[] ks)
{
/*
* Find out the degree of each argument and handle the zero cases
*/
int aDeg = degree();
if (aDeg == 0)
{
return this;
}
int bDeg = other.degree();
if (bDeg == 0)
{
return other;
}
/*
* Swap if necessary so that A is the smaller argument
*/
LongArray A = this, B = other;
if (aDeg > bDeg)
{
A = other; B = this;
int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
}
/*
* Establish the word lengths of the arguments and result
*/
int aLen = (aDeg + 63) >>> 6;
int bLen = (bDeg + 63) >>> 6;
int cLen = (aDeg + bDeg + 62) >>> 6;
if (aLen == 1)
{
long a0 = A.m_ints[0];
if (a0 == 1L)
{
return B;
}
/*
* Fast path for small A, with performance dependent only on the number of set bits
*/
long[] c0 = new long[cLen];
multiplyWord(a0, B.m_ints, bLen, c0, 0);
/*
* Reduce the raw answer against the reduction coefficients
*/
// return reduceResult(c0, 0, cLen, m, ks);
return new LongArray(c0, 0, cLen);
}
/*
* Determine if B will get bigger during shifting
*/
int bMax = (bDeg + 7 + 63) >>> 6;
/*
* Lookup table for the offset of each B in the tables
*/
int[] ti = new int[16];
/*
* Precompute table of all 4-bit products of B
*/
long[] T0 = new long[bMax << 4];
int tOff = bMax;
ti[1] = tOff;
System.arraycopy(B.m_ints, 0, T0, tOff, bLen);
for (int i = 2; i < 16; ++i)
{
ti[i] = (tOff += bMax);
if ((i & 1) == 0)
{
shiftUp(T0, tOff >>> 1, T0, tOff, bMax, 1);
}
else
{
add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax);
}
}
/*
* Second table with all 4-bit products of B shifted 4 bits
*/
long[] T1 = new long[T0.length];
shiftUp(T0, 0, T1, 0, T0.length, 4);
// shiftUp(T0, bMax, T1, bMax, tOff, 4);
long[] a = A.m_ints;
long[] c = new long[cLen << 3];
int MASK = 0xF;
/*
* Lopez-Dahab (Modified) algorithm
*/
for (int aPos = 0; aPos < aLen; ++aPos)
{
long aVal = a[aPos];
int cOff = aPos;
for (;;)
{
int u = (int)aVal & MASK;
aVal >>>= 4;
int v = (int)aVal & MASK;
addBoth(c, cOff, T0, ti[u], T1, ti[v], bMax);
aVal >>>= 4;
if (aVal == 0L)
{
break;
}
cOff += cLen;
}
}
{
int cOff = c.length;
while ((cOff -= cLen) != 0)
{
addShiftedUp(c, cOff - cLen, c, cOff, cLen, 8);
}
}
/*
* Finally the raw answer is collected, reduce it against the reduction coefficients
*/
// return reduceResult(c, 0, cLen, m, ks);
return new LongArray(c, 0, cLen);
}
public void reduce(int m, int[] ks)
{
long[] buf = m_ints;
int rLen = reduceInPlace(buf, 0, buf.length, m, ks);
if (rLen < buf.length)
{
m_ints = new long[rLen];
System.arraycopy(buf, 0, m_ints, 0, rLen);
}
}
private static LongArray reduceResult(long[] buf, int off, int len, int m, int[] ks)
{
int rLen = reduceInPlace(buf, off, len, m, ks);
@ -1405,13 +1577,13 @@ class LongArray
private static void reduceBit(long[] buf, int off, int bit, int m, int[] ks)
{
flipBit(buf, off, bit);
int base = bit - m;
int n = bit - m;
int j = ks.length;
while (--j >= 0)
{
flipBit(buf, off, ks[j] + base);
flipBit(buf, off, ks[j] + n);
}
flipBit(buf, off, base);
flipBit(buf, off, n);
}
private static void reduceWordWise(long[] buf, int off, int len, int toBit, int m, int[] ks)
@ -1428,6 +1600,7 @@ class LongArray
}
}
{
int partial = toBit & 0x3F;
long word = buf[off + toPos] >>> partial;
if (word != 0)
@ -1436,6 +1609,7 @@ class LongArray
reduceWord(buf, off, toBit, word, m, ks);
}
}
}
private static void reduceWord(long[] buf, int off, int bit, long word, int m, int[] ks)
{
@ -1502,37 +1676,59 @@ class LongArray
return new LongArray(r, 0, reduceInPlace(r, 0, r.length, m, ks));
}
// private LongArray modSquareN(int n, int m, int[] ks)
// {
// int len = getUsedLength();
// if (len == 0)
// {
// return this;
// }
//
// int mLen = (m + 63) >>> 6;
// long[] r = new long[mLen << 1];
// System.arraycopy(m_ints, 0, r, 0, len);
//
// while (--n >= 0)
// {
// squareInPlace(r, len, m, ks);
// len = reduceInPlace(r, 0, r.length, m, ks);
// }
//
// return new LongArray(r, 0, len);
// }
//
// private static void squareInPlace(long[] x, int xLen, int m, int[] ks)
// {
// int pos = xLen << 1;
// while (--xLen >= 0)
// {
// long xVal = x[xLen];
// x[--pos] = interleave2_32to64((int)(xVal >>> 32));
// x[--pos] = interleave2_32to64((int)xVal);
// }
// }
public LongArray modSquareN(int n, int m, int[] ks)
{
int len = getUsedLength();
if (len == 0)
{
return this;
}
int mLen = (m + 63) >>> 6;
long[] r = new long[mLen << 1];
System.arraycopy(m_ints, 0, r, 0, len);
while (--n >= 0)
{
squareInPlace(r, len, m, ks);
len = reduceInPlace(r, 0, r.length, m, ks);
}
return new LongArray(r, 0, len);
}
public LongArray square(int m, int[] ks)
{
int len = getUsedLength();
if (len == 0)
{
return this;
}
int _2len = len << 1;
long[] r = new long[_2len];
int pos = 0;
while (pos < _2len)
{
long mi = m_ints[pos >>> 1];
r[pos++] = interleave2_32to64((int)mi);
r[pos++] = interleave2_32to64((int)(mi >>> 32));
}
return new LongArray(r, 0, r.length);
}
private static void squareInPlace(long[] x, int xLen, int m, int[] ks)
{
int pos = xLen << 1;
while (--xLen >= 0)
{
long xVal = x[xLen];
x[--pos] = interleave2_32to64((int)(xVal >>> 32));
x[--pos] = interleave2_32to64((int)xVal);
}
}
private static void interleave(long[] x, int xOff, long[] z, int zOff, int count, int width)
{
@ -1856,6 +2052,10 @@ class LongArray
* Output: a(z)^(-1) mod f(z)
*/
int uzDegree = degree();
if (uzDegree == 0)
{
throw new IllegalStateException();
}
if (uzDegree == 1)
{
return this;

View File

@ -2,6 +2,16 @@ package org.spongycastle.util;
public class Integers
{
public static int rotateLeft(int i, int distance)
{
return (i << distance) ^ (i >>> -distance);
}
public static int rotateRight(int i, int distance)
{
return (i >>> distance) ^ (i << -distance);
}
public static Integer valueOf(int value)
{
return new Integer(value);

View File

@ -0,0 +1,11 @@
package org.spongycastle.util;
public final class Times
{
private static long NANOS_PER_MILLI = 1000000L;
public static long nanoTime()
{
return NANOS_PER_MILLI * System.currentTimeMillis();
}
}

View File

@ -3,7 +3,7 @@ package org.spongycastle;
/**
* The Bouncy Castle License
*
* Copyright (c) 2000-2013 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
* Copyright (c) 2000-2014 The Legion Of The Bouncy Castle Inc. (http://www.bouncycastle.org)
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without restriction,
@ -24,7 +24,7 @@ package org.spongycastle;
public class LICENSE
{
public static String licenseText =
"Copyright (c) 2000-2013 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) "
"Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) "
+ System.getProperty("line.separator")
+ System.getProperty("line.separator")
+ "Permission is hereby granted, free of charge, to any person obtaining a copy of this software "

View File

@ -2,9 +2,18 @@ package org.spongycastle.asn1;
import java.io.IOException;
/**
* Interface to parse ASN.1 application specific objects.
*/
public interface ASN1ApplicationSpecificParser
extends ASN1Encodable, InMemoryRepresentable
{
/**
* Read the next object in the parser.
*
* @return an ASN1Encodable
* @throws IOException on a parsing or decoding error.
*/
ASN1Encodable readObject()
throws IOException;
}

View File

@ -1,15 +1,204 @@
package org.spongycastle.asn1;
import java.io.IOException;
import org.spongycastle.util.Arrays;
/**
* Public facade of ASN.1 Boolean data.
* <p>
* Use following to place a new instance of ASN.1 Boolean in your dataset:
* </p>
* <ul>
* <li> ASN1Boolean.TRUE literal</li>
* <li> ASN1Boolean.FALSE literal</li>
* <li> {@link ASN1Boolean#getInstance(boolean) ASN1Boolean.getInstance(boolean)}</li>
* <li> {@link ASN1Boolean#getInstance(int) ASN1Boolean.getInstance(int)}</li>
* </ul>
* </p>
*/
public class ASN1Boolean
extends DERBoolean
extends ASN1Primitive
{
public ASN1Boolean(boolean value)
private static final byte[] TRUE_VALUE = new byte[] { (byte)0xff };
private static final byte[] FALSE_VALUE = new byte[] { 0 };
private byte[] value;
public static final ASN1Boolean FALSE = new ASN1Boolean(false);
public static final ASN1Boolean TRUE = new ASN1Boolean(true);
/**
* return a boolean from the passed in object.
*
* @param obj an ASN1Boolean or an object that can be converted into one.
* @exception IllegalArgumentException if the object cannot be converted.
* @return an ASN1Boolean instance.
*/
public static ASN1Boolean getInstance(
Object obj)
{
super(value);
if (obj == null || obj instanceof ASN1Boolean)
{
return (ASN1Boolean)obj;
}
ASN1Boolean(byte[] value)
if (obj instanceof byte[])
{
super(value);
byte[] enc = (byte[])obj;
try
{
return (ASN1Boolean)fromByteArray(enc);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct boolean from byte[]: " + e.getMessage());
}
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return an ASN1Boolean from the passed in boolean.
* @return an ASN1Boolean instance.
*/
public static ASN1Boolean getInstance(
boolean value)
{
return (value ? TRUE : FALSE);
}
/**
* return an ASN1Boolean from the passed in value.
* @return an ASN1Boolean instance.
*/
public static ASN1Boolean getInstance(
int value)
{
return (value != 0 ? TRUE : FALSE);
}
/**
* return a Boolean from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return an ASN1Boolean instance.
*/
public static ASN1Boolean getInstance(
ASN1TaggedObject obj,
boolean explicit)
{
ASN1Primitive o = obj.getObject();
if (explicit || o instanceof ASN1Boolean)
{
return getInstance(o);
}
else
{
return ASN1Boolean.fromOctetString(((ASN1OctetString)o).getOctets());
}
}
ASN1Boolean(
byte[] value)
{
if (value.length != 1)
{
throw new IllegalArgumentException("byte value should have 1 byte in it");
}
if (value[0] == 0)
{
this.value = FALSE_VALUE;
}
else if ((value[0] & 0xff) == 0xff)
{
this.value = TRUE_VALUE;
}
else
{
this.value = Arrays.clone(value);
}
}
/**
* @deprecated use getInstance(boolean) method.
* @param value true or false.
*/
public ASN1Boolean(
boolean value)
{
this.value = (value) ? TRUE_VALUE : FALSE_VALUE;
}
public boolean isTrue()
{
return (value[0] != 0);
}
boolean isConstructed()
{
return false;
}
int encodedLength()
{
return 3;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.writeEncoded(BERTags.BOOLEAN, value);
}
protected boolean asn1Equals(
ASN1Primitive o)
{
if (o instanceof ASN1Boolean)
{
return (value[0] == ((ASN1Boolean)o).value[0]);
}
return false;
}
public int hashCode()
{
return value[0];
}
public String toString()
{
return (value[0] != 0) ? "TRUE" : "FALSE";
}
static ASN1Boolean fromOctetString(byte[] value)
{
if (value.length != 1)
{
throw new IllegalArgumentException("BOOLEAN value should have 1 byte in it");
}
if (value[0] == 0)
{
return FALSE;
}
else if ((value[0] & 0xff) == 0xff)
{
return TRUE;
}
else
{
return new ASN1Boolean(value);
}
}
}

View File

@ -5,8 +5,22 @@ package org.spongycastle.asn1;
* own object any attempt to tag the object implicitly will convert the tag to
* an explicit one as the encoding rules require.
* <p>
* If you use this interface your class should also implement the getInstance
* If you use this interface your class should also implement the getInstance()
* pattern which takes a tag object and the tagging mode used.
* <p>
* <hr>
* <p><b>X.690</b></p>
* <p><b>8: Basic encoding rules</b></p>
* <p><b>8.13 Encoding of a choice value </b></p>
* <p>
* The encoding of a choice value shall be the same as the encoding of a value of the chosen type.
* <blockquote>
* NOTE 1 &mdash; The encoding may be primitive or constructed depending on the chosen type.
* <p>
* NOTE 2 &mdash; The tag used in the identifier octets is the tag of the chosen type,
* as specified in the ASN.1 definition of the choice type.
* </blockquote>
* </p>
*/
public interface ASN1Choice
{

View File

@ -1,6 +1,13 @@
package org.spongycastle.asn1;
/**
* Basic interface to produce serialisers for ASN.1 encodings.
*/
public interface ASN1Encodable
{
/**
* Return an object, possibly constructed, of ASN.1 primitives
* @return an ASN.1 primitive.
*/
ASN1Primitive toASN1Primitive();
}

View File

@ -3,19 +3,35 @@ package org.spongycastle.asn1;
import java.util.Enumeration;
import java.util.Vector;
/**
* Mutable class for building ASN.1 constructed objects.
*/
public class ASN1EncodableVector
{
Vector v = new Vector();
/**
* Base constructor.
*/
public ASN1EncodableVector()
{
}
/**
* Add an encodable to the vector.
*
* @param obj the encodable to add.
*/
public void add(ASN1Encodable obj)
{
v.addElement(obj);
}
/**
* Add the contents of another vector.
*
* @param other the vector to add.
*/
public void addAll(ASN1EncodableVector other)
{
for (Enumeration en = other.v.elements(); en.hasMoreElements();)
@ -24,11 +40,22 @@ public class ASN1EncodableVector
}
}
/**
* Return the object at position i in this vector.
*
* @param i the index of the object of interest.
* @return the object at position i.
*/
public ASN1Encodable get(int i)
{
return (ASN1Encodable)v.elementAt(i);
}
/**
* Return the size of the vector.
*
* @return the object count in the vector.
*/
public int size()
{
return v.size();

View File

@ -1,8 +1,22 @@
package org.spongycastle.asn1;
/**
* Supported encoding formats.
*/
public interface ASN1Encoding
{
/**
* DER - distinguished encoding rules.
*/
static final String DER = "DER";
/**
* DL - definite length encoding.
*/
static final String DL = "DL";
/**
* BER - basic encoding rules.
*/
static final String BER = "BER";
}

View File

@ -1,22 +1,174 @@
package org.spongycastle.asn1;
import java.io.IOException;
import java.math.BigInteger;
import org.spongycastle.util.Arrays;
/**
* Class representing the ASN.1 ENUMERATED type.
*/
public class ASN1Enumerated
extends DEREnumerated
extends ASN1Primitive
{
ASN1Enumerated(byte[] bytes)
byte[] bytes;
/**
* return an enumerated from the passed in object
*
* @param obj an ASN1Enumerated or an object that can be converted into one.
* @exception IllegalArgumentException if the object cannot be converted.
* @return an ASN1Enumerated instance, or null.
*/
public static ASN1Enumerated getInstance(
Object obj)
{
super(bytes);
if (obj == null || obj instanceof ASN1Enumerated)
{
return (ASN1Enumerated)obj;
}
public ASN1Enumerated(BigInteger value)
if (obj instanceof byte[])
{
super(value);
try
{
return (ASN1Enumerated)fromByteArray((byte[])obj);
}
catch (Exception e)
{
throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
}
}
public ASN1Enumerated(int value)
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return an Enumerated from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return an ASN1Enumerated instance, or null.
*/
public static ASN1Enumerated getInstance(
ASN1TaggedObject obj,
boolean explicit)
{
super(value);
ASN1Primitive o = obj.getObject();
if (explicit || o instanceof ASN1Enumerated)
{
return getInstance(o);
}
else
{
return fromOctetString(((ASN1OctetString)o).getOctets());
}
}
/**
* Constructor from int.
*
* @param value the value of this enumerated.
*/
public ASN1Enumerated(
int value)
{
bytes = BigInteger.valueOf(value).toByteArray();
}
/**
* Constructor from BigInteger
*
* @param value the value of this enumerated.
*/
public ASN1Enumerated(
BigInteger value)
{
bytes = value.toByteArray();
}
/**
* Constructor from encoded BigInteger.
*
* @param bytes the value of this enumerated as an encoded BigInteger (signed).
*/
public ASN1Enumerated(
byte[] bytes)
{
this.bytes = bytes;
}
public BigInteger getValue()
{
return new BigInteger(bytes);
}
boolean isConstructed()
{
return false;
}
int encodedLength()
{
return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.writeEncoded(BERTags.ENUMERATED, bytes);
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof ASN1Enumerated))
{
return false;
}
ASN1Enumerated other = (ASN1Enumerated)o;
return Arrays.areEqual(this.bytes, other.bytes);
}
public int hashCode()
{
return Arrays.hashCode(bytes);
}
private static ASN1Enumerated[] cache = new ASN1Enumerated[12];
static ASN1Enumerated fromOctetString(byte[] enc)
{
if (enc.length > 1)
{
return new ASN1Enumerated(Arrays.clone(enc));
}
if (enc.length == 0)
{
throw new IllegalArgumentException("ENUMERATED has zero length");
}
int value = enc[0] & 0xff;
if (value >= cache.length)
{
return new ASN1Enumerated(Arrays.clone(enc));
}
ASN1Enumerated possibleMatch = cache[value];
if (possibleMatch == null)
{
possibleMatch = cache[value] = new ASN1Enumerated(Arrays.clone(enc));
}
return possibleMatch;
}
}

View File

@ -1,22 +1,373 @@
package org.spongycastle.asn1;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings;
/**
* Base class representing the ASN.1 GeneralizedTime type.
* <p>
* The main difference between these and UTC time is a 4 digit year.
* </p>
*/
public class ASN1GeneralizedTime
extends DERGeneralizedTime
extends ASN1Primitive
{
ASN1GeneralizedTime(byte[] bytes)
private byte[] time;
/**
* return a generalized time from the passed in object
*
* @param obj an ASN1GeneralizedTime or an object that can be converted into one.
* @return an ASN1GeneralizedTime instance, or null.
* @throws IllegalArgumentException if the object cannot be converted.
*/
public static ASN1GeneralizedTime getInstance(
Object obj)
{
super(bytes);
if (obj == null || obj instanceof ASN1GeneralizedTime)
{
return (ASN1GeneralizedTime)obj;
}
public ASN1GeneralizedTime(Date time)
if (obj instanceof byte[])
{
super(time);
try
{
return (ASN1GeneralizedTime)fromByteArray((byte[])obj);
}
catch (Exception e)
{
throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
}
}
public ASN1GeneralizedTime(String time)
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return a Generalized Time object from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @return an ASN1GeneralizedTime instance.
* @throws IllegalArgumentException if the tagged object cannot
* be converted.
*/
public static ASN1GeneralizedTime getInstance(
ASN1TaggedObject obj,
boolean explicit)
{
super(time);
ASN1Primitive o = obj.getObject();
if (explicit || o instanceof ASN1GeneralizedTime)
{
return getInstance(o);
}
else
{
return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets());
}
}
/**
* 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
* time and UTC time. The fractional second amount f must consist of at
* least one number with trailing zeroes removed.
*
* @param time the time string.
* @throws IllegalArgumentException if String is an illegal format.
*/
public ASN1GeneralizedTime(
String time)
{
this.time = Strings.toByteArray(time);
try
{
this.getDate();
}
catch (ParseException e)
{
throw new IllegalArgumentException("invalid date string: " + e.getMessage());
}
}
/**
* Base constructor from a java.util.date object
*
* @param time a date object representing the time of interest.
*/
public ASN1GeneralizedTime(
Date time)
{
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
this.time = Strings.toByteArray(dateF.format(time));
}
/**
* Base constructor from a java.util.date and Locale - you may need to use this if the default locale
* doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations.
*
* @param time a date object representing the time of interest.
* @param locale an appropriate Locale for producing an ASN.1 GeneralizedTime value.
*/
public ASN1GeneralizedTime(
Date time,
Locale locale)
{
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'", locale);
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
this.time = Strings.toByteArray(dateF.format(time));
}
ASN1GeneralizedTime(
byte[] bytes)
{
this.time = bytes;
}
/**
* Return the time.
*
* @return The time string as it appeared in the encoded object.
*/
public String getTimeString()
{
return Strings.fromByteArray(time);
}
/**
* return the time - always in the form of
* YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm).
* <p/>
* Normally in a certificate we would expect "Z" rather than "GMT",
* however adding the "GMT" means we can just use:
* <pre>
* dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
* </pre>
* To read in the time and get a date which is compatible with our local
* time zone.
*/
public String getTime()
{
String stime = Strings.fromByteArray(time);
//
// standardise the format.
//
if (stime.charAt(stime.length() - 1) == 'Z')
{
return stime.substring(0, stime.length() - 1) + "GMT+00:00";
}
else
{
int signPos = stime.length() - 5;
char sign = stime.charAt(signPos);
if (sign == '-' || sign == '+')
{
return stime.substring(0, signPos)
+ "GMT"
+ stime.substring(signPos, signPos + 3)
+ ":"
+ stime.substring(signPos + 3);
}
else
{
signPos = stime.length() - 3;
sign = stime.charAt(signPos);
if (sign == '-' || sign == '+')
{
return stime.substring(0, signPos)
+ "GMT"
+ stime.substring(signPos)
+ ":00";
}
}
}
return stime + calculateGMTOffset();
}
private String calculateGMTOffset()
{
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);
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);
}
private String convert(int time)
{
if (time < 10)
{
return "0" + time;
}
return Integer.toString(time);
}
public Date getDate()
throws ParseException
{
SimpleDateFormat dateF;
String stime = Strings.fromByteArray(time);
String d = stime;
if (stime.endsWith("Z"))
{
if (hasFractionalSeconds())
{
dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'");
}
else
{
dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
}
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
}
else if (stime.indexOf('-') > 0 || stime.indexOf('+') > 0)
{
d = this.getTime();
if (hasFractionalSeconds())
{
dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz");
}
else
{
dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
}
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
}
else
{
if (hasFractionalSeconds())
{
dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
}
else
{
dateF = new SimpleDateFormat("yyyyMMddHHmmss");
}
dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID()));
}
if (hasFractionalSeconds())
{
// java misinterprets extra digits as being milliseconds...
String frac = d.substring(14);
int index;
for (index = 1; index < frac.length(); index++)
{
char ch = frac.charAt(index);
if (!('0' <= ch && ch <= '9'))
{
break;
}
}
if (index - 1 > 3)
{
frac = frac.substring(0, 4) + frac.substring(index);
d = d.substring(0, 14) + frac;
}
else if (index - 1 == 1)
{
frac = frac.substring(0, index) + "00" + frac.substring(index);
d = d.substring(0, 14) + frac;
}
else if (index - 1 == 2)
{
frac = frac.substring(0, index) + "0" + frac.substring(index);
d = d.substring(0, 14) + frac;
}
}
return dateF.parse(d);
}
private boolean hasFractionalSeconds()
{
for (int i = 0; i != time.length; i++)
{
if (time[i] == '.')
{
if (i == 14)
{
return true;
}
}
}
return false;
}
boolean isConstructed()
{
return false;
}
int encodedLength()
{
int length = time.length;
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.writeEncoded(BERTags.GENERALIZED_TIME, time);
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof ASN1GeneralizedTime))
{
return false;
}
return Arrays.areEqual(time, ((ASN1GeneralizedTime)o).time);
}
public int hashCode()
{
return Arrays.hashCode(time);
}
}

View File

@ -124,6 +124,12 @@ public class ASN1InputStream
/**
* build an object given its tag and the number of bytes to construct it from.
*
* @param tag the full tag details.
* @param tagNo the tagNo defined.
* @param length the length of the object.
* @return the resulting primitive.
* @throws java.io.IOException on processing exception.
*/
protected ASN1Primitive buildObject(
int tag,
@ -438,7 +444,7 @@ public class ASN1InputStream
case IA5_STRING:
return new DERIA5String(defIn.toByteArray());
case INTEGER:
return new ASN1Integer(defIn.toByteArray());
return new ASN1Integer(defIn.toByteArray(), false);
case NULL:
return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?)
case NUMERIC_STRING:

View File

@ -1,22 +1,157 @@
package org.spongycastle.asn1;
import java.io.IOException;
import java.math.BigInteger;
import org.spongycastle.util.Arrays;
/**
* Class representing the ASN.1 INTEGER type.
*/
public class ASN1Integer
extends DERInteger
extends ASN1Primitive
{
ASN1Integer(byte[] bytes)
byte[] bytes;
/**
* return an integer from the passed in object
*
* @param obj an ASN1Integer or an object that can be converted into one.
* @throws IllegalArgumentException if the object cannot be converted.
* @return an ASN1Integer instance.
*/
public static ASN1Integer getInstance(
Object obj)
{
super(bytes);
if (obj == null || obj instanceof ASN1Integer)
{
return (ASN1Integer)obj;
}
public ASN1Integer(BigInteger value)
if (obj instanceof byte[])
{
super(value);
try
{
return (ASN1Integer)fromByteArray((byte[])obj);
}
catch (Exception e)
{
throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
}
}
public ASN1Integer(long value)
{
super(value);
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return an Integer from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @throws IllegalArgumentException if the tagged object cannot
* be converted.
* @return an ASN1Integer instance.
*/
public static ASN1Integer getInstance(
ASN1TaggedObject obj,
boolean explicit)
{
ASN1Primitive o = obj.getObject();
if (explicit || o instanceof ASN1Integer)
{
return getInstance(o);
}
else
{
return new ASN1Integer(ASN1OctetString.getInstance(obj.getObject()).getOctets());
}
}
public ASN1Integer(
long value)
{
bytes = BigInteger.valueOf(value).toByteArray();
}
public ASN1Integer(
BigInteger value)
{
bytes = value.toByteArray();
}
public ASN1Integer(
byte[] bytes)
{
this(bytes, true);
}
ASN1Integer(byte[] bytes, boolean clone)
{
this.bytes = (clone) ? Arrays.clone(bytes) : bytes;
}
public BigInteger getValue()
{
return new BigInteger(bytes);
}
/**
* in some cases positive values get crammed into a space,
* that's not quite big enough...
* @return the BigInteger that results from treating this ASN.1 INTEGER as unsigned.
*/
public BigInteger getPositiveValue()
{
return new BigInteger(1, bytes);
}
boolean isConstructed()
{
return false;
}
int encodedLength()
{
return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.writeEncoded(BERTags.INTEGER, bytes);
}
public int hashCode()
{
int value = 0;
for (int i = 0; i != bytes.length; i++)
{
value ^= (bytes[i] & 0xff) << (i % 4);
}
return value;
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof ASN1Integer))
{
return false;
}
ASN1Integer other = (ASN1Integer)o;
return Arrays.areEqual(bytes, other.bytes);
}
public String toString()
{
return getValue().toString();
}
}

View File

@ -3,18 +3,26 @@ package org.spongycastle.asn1;
import java.io.IOException;
/**
* A NULL object.
* A NULL object - use DERNull.INSTANCE for populating structures.
*/
public abstract class ASN1Null
extends ASN1Primitive
{
/**
* @deprecated use DERNull.INSTANCE
* Return an instance of ASN.1 NULL from the passed in object.
* <p>
* Accepted inputs:
* <ul>
* <li> null &rarr; null
* <li> {@link ASN1Null} object
* <li> a byte[] containing ASN.1 NULL object
* </ul>
* </p>
*
* @param o object to be converted.
* @return an instance of ASN1Null, or null.
* @exception IllegalArgumentException if the object cannot be converted.
*/
public ASN1Null()
{
}
public static ASN1Null getInstance(Object o)
{
if (o instanceof ASN1Null)

View File

@ -3,6 +3,9 @@ package org.spongycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* Base class for defining an ASN.1 object.
*/
public abstract class ASN1Object
implements ASN1Encodable
{
@ -88,10 +91,21 @@ public abstract class ASN1Object
return this.toASN1Primitive();
}
/**
* Return true if obj is a byte array and represents an object with the given tag value.
*
* @param obj object of interest.
* @param tagValue tag value to check for.
* @return true if obj is a byte encoding starting with the given tag value, false otherwise.
*/
protected static boolean hasEncodedTagValue(Object obj, int tagValue)
{
return (obj instanceof byte[]) && ((byte[])obj)[0] == tagValue;
}
/**
* Method providing a primitive representation of this object suitable for encoding.
* @return a primitive representation of this object.
*/
public abstract ASN1Primitive toASN1Primitive();
}

View File

@ -1,21 +1,205 @@
package org.spongycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import org.spongycastle.util.Arrays;
/**
* Class representing the ASN.1 OBJECT IDENTIFIER type.
*/
public class ASN1ObjectIdentifier
extends DERObjectIdentifier
extends ASN1Primitive
{
public ASN1ObjectIdentifier(String identifier)
String identifier;
private byte[] body;
/**
* return an OID from the passed in object
* @param obj an ASN1ObjectIdentifier or an object that can be converted into one.
* @throws IllegalArgumentException if the object cannot be converted.
* @return an ASN1ObjectIdentifier instance, or null.
*/
public static ASN1ObjectIdentifier getInstance(
Object obj)
{
super(identifier);
if (obj == null || obj instanceof ASN1ObjectIdentifier)
{
return (ASN1ObjectIdentifier)obj;
}
ASN1ObjectIdentifier(byte[] bytes)
if (obj instanceof ASN1Encodable && ((ASN1Encodable)obj).toASN1Primitive() instanceof ASN1ObjectIdentifier)
{
super(bytes);
return (ASN1ObjectIdentifier)((ASN1Encodable)obj).toASN1Primitive();
}
ASN1ObjectIdentifier(ASN1ObjectIdentifier oid, String branch)
if (obj instanceof byte[])
{
super(oid, branch);
byte[] enc = (byte[])obj;
try
{
return (ASN1ObjectIdentifier)fromByteArray(enc);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct object identifier from byte[]: " + e.getMessage());
}
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return an Object Identifier from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @throws IllegalArgumentException if the tagged object cannot
* be converted.
* @return an ASN1ObjectIdentifier instance, or null.
*/
public static ASN1ObjectIdentifier getInstance(
ASN1TaggedObject obj,
boolean explicit)
{
ASN1Primitive o = obj.getObject();
if (explicit || o instanceof ASN1ObjectIdentifier)
{
return getInstance(o);
}
else
{
return ASN1ObjectIdentifier.fromOctetString(ASN1OctetString.getInstance(obj.getObject()).getOctets());
}
}
private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7f;
ASN1ObjectIdentifier(
byte[] bytes)
{
StringBuffer objId = new StringBuffer();
long value = 0;
BigInteger bigValue = null;
boolean first = true;
for (int i = 0; i != bytes.length; i++)
{
int b = bytes[i] & 0xff;
if (value <= LONG_LIMIT)
{
value += (b & 0x7f);
if ((b & 0x80) == 0) // end of number reached
{
if (first)
{
if (value < 40)
{
objId.append('0');
}
else if (value < 80)
{
objId.append('1');
value -= 40;
}
else
{
objId.append('2');
value -= 80;
}
first = false;
}
objId.append('.');
objId.append(value);
value = 0;
}
else
{
value <<= 7;
}
}
else
{
if (bigValue == null)
{
bigValue = BigInteger.valueOf(value);
}
bigValue = bigValue.or(BigInteger.valueOf(b & 0x7f));
if ((b & 0x80) == 0)
{
if (first)
{
objId.append('2');
bigValue = bigValue.subtract(BigInteger.valueOf(80));
first = false;
}
objId.append('.');
objId.append(bigValue);
bigValue = null;
value = 0;
}
else
{
bigValue = bigValue.shiftLeft(7);
}
}
}
this.identifier = objId.toString();
this.body = Arrays.clone(bytes);
}
/**
* Create an OID based on the passed in String.
*
* @param identifier a string representation of an OID.
*/
public ASN1ObjectIdentifier(
String identifier)
{
if (identifier == null)
{
throw new IllegalArgumentException("'identifier' cannot be null");
}
if (!isValidIdentifier(identifier))
{
throw new IllegalArgumentException("string " + identifier + " not an OID");
}
this.identifier = identifier;
}
/**
* Create an OID that creates a branch under the current one.
*
* @param branchID node numbers for the new branch.
* @return the OID for the new created branch.
*/
ASN1ObjectIdentifier(ASN1ObjectIdentifier oid, String branchID)
{
if (!isValidBranchID(branchID, 0))
{
throw new IllegalArgumentException("string " + branchID + " not a valid OID branch");
}
this.identifier = oid.getId() + "." + branchID;
}
/**
* Return the OID as a string.
*
* @return the string representation of the OID carried by this object.
*/
public String getId()
{
return identifier;
}
/**
@ -31,6 +215,7 @@ public class ASN1ObjectIdentifier
/**
* Return true if this oid is an extension of the passed in branch, stem.
*
* @param stem the arc or branch that is a possible parent.
* @return true if the branch is on the passed in stem, false otherwise.
*/
@ -39,4 +224,249 @@ public class ASN1ObjectIdentifier
String id = getId(), stemId = stem.getId();
return id.length() > stemId.length() && id.charAt(stemId.length()) == '.' && id.startsWith(stemId);
}
private void writeField(
ByteArrayOutputStream out,
long fieldValue)
{
byte[] result = new byte[9];
int pos = 8;
result[pos] = (byte)((int)fieldValue & 0x7f);
while (fieldValue >= (1L << 7))
{
fieldValue >>= 7;
result[--pos] = (byte)((int)fieldValue & 0x7f | 0x80);
}
out.write(result, pos, 9 - pos);
}
private void writeField(
ByteArrayOutputStream out,
BigInteger fieldValue)
{
int byteCount = (fieldValue.bitLength() + 6) / 7;
if (byteCount == 0)
{
out.write(0);
}
else
{
BigInteger tmpValue = fieldValue;
byte[] tmp = new byte[byteCount];
for (int i = byteCount - 1; i >= 0; i--)
{
tmp[i] = (byte)((tmpValue.intValue() & 0x7f) | 0x80);
tmpValue = tmpValue.shiftRight(7);
}
tmp[byteCount - 1] &= 0x7f;
out.write(tmp, 0, tmp.length);
}
}
private void doOutput(ByteArrayOutputStream aOut)
{
OIDTokenizer tok = new OIDTokenizer(identifier);
int first = Integer.parseInt(tok.nextToken()) * 40;
String secondToken = tok.nextToken();
if (secondToken.length() <= 18)
{
writeField(aOut, first + Long.parseLong(secondToken));
}
else
{
writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first)));
}
while (tok.hasMoreTokens())
{
String token = tok.nextToken();
if (token.length() <= 18)
{
writeField(aOut, Long.parseLong(token));
}
else
{
writeField(aOut, new BigInteger(token));
}
}
}
protected synchronized byte[] getBody()
{
if (body == null)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
doOutput(bOut);
body = bOut.toByteArray();
}
return body;
}
boolean isConstructed()
{
return false;
}
int encodedLength()
throws IOException
{
int length = getBody().length;
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
byte[] enc = getBody();
out.write(BERTags.OBJECT_IDENTIFIER);
out.writeLength(enc.length);
out.write(enc);
}
public int hashCode()
{
return identifier.hashCode();
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof ASN1ObjectIdentifier))
{
return false;
}
return identifier.equals(((ASN1ObjectIdentifier)o).identifier);
}
public String toString()
{
return getId();
}
private static boolean isValidBranchID(
String branchID, int start)
{
boolean periodAllowed = false;
int pos = branchID.length();
while (--pos >= start)
{
char ch = branchID.charAt(pos);
// TODO Leading zeroes?
if ('0' <= ch && ch <= '9')
{
periodAllowed = true;
continue;
}
if (ch == '.')
{
if (!periodAllowed)
{
return false;
}
periodAllowed = false;
continue;
}
return false;
}
return periodAllowed;
}
private static boolean isValidIdentifier(
String identifier)
{
if (identifier.length() < 3 || identifier.charAt(1) != '.')
{
return false;
}
char first = identifier.charAt(0);
if (first < '0' || first > '2')
{
return false;
}
return isValidBranchID(identifier, 2);
}
private static ASN1ObjectIdentifier[][] cache = new ASN1ObjectIdentifier[256][];
static ASN1ObjectIdentifier fromOctetString(byte[] enc)
{
if (enc.length < 3)
{
return new ASN1ObjectIdentifier(enc);
}
int idx1 = enc[enc.length - 2] & 0xff;
// in this case top bit is always zero
int idx2 = enc[enc.length - 1] & 0x7f;
ASN1ObjectIdentifier possibleMatch;
synchronized (cache)
{
ASN1ObjectIdentifier[] first = cache[idx1];
if (first == null)
{
first = cache[idx1] = new ASN1ObjectIdentifier[128];
}
possibleMatch = first[idx2];
if (possibleMatch == null)
{
return first[idx2] = new ASN1ObjectIdentifier(enc);
}
if (Arrays.areEqual(enc, possibleMatch.getBody()))
{
return possibleMatch;
}
idx1 = (idx1 + 1) & 0xff;
first = cache[idx1];
if (first == null)
{
first = cache[idx1] = new ASN1ObjectIdentifier[128];
}
possibleMatch = first[idx2];
if (possibleMatch == null)
{
return first[idx2] = new ASN1ObjectIdentifier(enc);
}
if (Arrays.areEqual(enc, possibleMatch.getBody()))
{
return possibleMatch;
}
idx2 = (idx2 + 1) & 0x7f;
possibleMatch = first[idx2];
if (possibleMatch == null)
{
return first[idx2] = new ASN1ObjectIdentifier(enc);
}
}
if (Arrays.areEqual(enc, possibleMatch.getBody()))
{
return possibleMatch;
}
return new ASN1ObjectIdentifier(enc);
}
}

View File

@ -7,6 +7,96 @@ import java.io.InputStream;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.encoders.Hex;
/**
* Abstract base for the ASN.1 OCTET STRING data type
* <p>
* This supports BER, and DER forms of the data.
* </p><p>
* DER form is always primitive single OCTET STRING, while
* BER support includes the constructed forms.
* </p>
* <hr>
* <p><b>X.690</b></p>
* <p><b>8: Basic encoding rules</b></p>
* <p><b>8.7 Encoding of an octetstring value</b></p>
* <p>
* <b>8.7.1</b> The encoding of an octetstring value shall be
* either primitive or constructed at the option of the sender.
* <blockquote>
* NOTE &mdash; Where it is necessary to transfer part of an octet string
* before the entire OCTET STRING is available, the constructed encoding
* is used.
* </blockquote>
* <p>
* <b>8.7.2</b> The primitive encoding contains zero,
* one or more contents octets equal in value to the octets
* in the data value, in the order they appear in the data value,
* and with the most significant bit of an octet of the data value
* aligned with the most significant bit of an octet of the contents octets.
* </p>
* <p>
* <b>8.7.3</b> The contents octets for the constructed encoding shall consist
* of zero, one, or more encodings.
* <blockquote>
* NOTE &mdash; Each such encoding includes identifier, length, and contents octets,
* and may include end-of-contents octets if it is constructed.
* </blockquote>
* </p>
* <p>
* <b>8.7.3.1</b> To encode an octetstring value in this way,
* it is segmented. Each segment shall consist of a series of
* consecutive octets of the value. There shall be no significance
* placed on the segment boundaries.
* <blockquote>
* NOTE &mdash; A segment may be of size zero, i.e. contain no octets.
* </blockquote>
* </p>
* <p>
* <b>8.7.3.2</b> Each encoding in the contents octets shall represent
* a segment of the overall octetstring, the encoding arising from
* a recursive application of this subclause.
* In this recursive application, each segment is treated as if it were
* a octetstring value. The encodings of the segments shall appear in the contents
* octets in the order in which their octets appear in the overall value.
* <blockquote>
* NOTE 1 &mdash; As a consequence of this recursion,
* each encoding in the contents octets may itself
* be primitive or constructed.
* However, such encodings will usually be primitive.
* </p><p>
* NOTE 2 &mdash; In particular, the tags in the contents octets are always universal class, number 4.
* </blockquote>
* </p>
* <p><b>9: Canonical encoding rules</b></p>
* <p><b>9.1 Length forms</b></p>
* <p>
* If the encoding is constructed, it shall employ the indefinite length form.
* If the encoding is primitive, it shall include the fewest length octets necessary.
* [Contrast with 8.1.3.2 b).]
* </p>
* <p><b>9.2 String encoding forms</b></p>
* <p>
* BIT STRING, OCTET STRING,and restricted character string
* values shall be encoded with a primitive encoding if they would
* require no more than 1000 contents octets, and as a constructed
* encoding otherwise. The string fragments contained in
* the constructed encoding shall be encoded with a primitive encoding.
* The encoding of each fragment, except possibly
* the last, shall have 1000 contents octets. (Contrast with 8.21.6.)
* </p>
* <b>10: Distinguished encoding rules</b>
* </p><p>
* <b>10.1 Length forms</b>
* The definite form of length encoding shall be used,
* encoded in the minimum number of octets.
* [Contrast with 8.1.3.2 b).]
* </p><p>
* <b>10.2 String encoding forms</b>
* For BIT STRING, OCTET STRING and restricted character string types,
* the constructed form of encoding shall not be used.
* (Contrast with 8.21.6.)
* </p>
*/
public abstract class ASN1OctetString
extends ASN1Primitive
implements ASN1OctetStringParser
@ -88,16 +178,31 @@ public abstract class ASN1OctetString
this.string = string;
}
/**
* Return the content of the OCTET STRING as an InputStream.
*
* @return an InputStream representing the OCTET STRING's content.
*/
public InputStream getOctetStream()
{
return new ByteArrayInputStream(string);
}
/**
* Return the parser associated with this object.
*
* @return a parser based on this OCTET STRING
*/
public ASN1OctetStringParser parser()
{
return this;
}
/**
* Return the content of the OCTET STRING as a byte array.
*
* @return the byte[] representing the OCTET STRING's content.
*/
public byte[] getOctets()
{
return string;

View File

@ -2,8 +2,16 @@ package org.spongycastle.asn1;
import java.io.InputStream;
/**
* A basic parser for an OCTET STRING object
*/
public interface ASN1OctetStringParser
extends ASN1Encodable, InMemoryRepresentable
{
/**
* Return the content of the OCTET STRING as an InputStream.
*
* @return an InputStream representing the OCTET STRING's content.
*/
public InputStream getOctetStream();
}

View File

@ -2,6 +2,9 @@ package org.spongycastle.asn1;
import java.io.IOException;
/**
* Base class for ASN.1 primitive objects. These are the actual objects used to generate byte encodings.
*/
public abstract class ASN1Primitive
extends ASN1Object
{
@ -47,11 +50,21 @@ public abstract class ASN1Primitive
return this;
}
/**
* Return the current object as one which encodes using Distinguished Encoding Rules.
*
* @return a DER version of this.
*/
ASN1Primitive toDERObject()
{
return this;
}
/**
* Return the current object as one which encodes using Definite Length encoding.
*
* @return a DL version of this.
*/
ASN1Primitive toDLObject()
{
return this;

View File

@ -4,16 +4,64 @@ import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
/**
* ASN.1 <code>SEQUENCE</code> and <code>SEQUENCE OF</code> constructs.
* <p>
* DER form is always definite form length fields, while
* BER support uses indefinite form.
* <hr>
* <p><b>X.690</b></p>
* <p><b>8: Basic encoding rules</b></p>
* <p><b>8.9 Encoding of a sequence value </b></p>
* 8.9.1 The encoding of a sequence value shall be constructed.
* <p>
* <b>8.9.2</b> The contents octets shall consist of the complete
* encoding of one data value from each of the types listed in
* the ASN.1 definition of the sequence type, in the order of
* their appearance in the definition, unless the type was referenced
* with the keyword <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
* </p><p>
* <b>8.9.3</b> The encoding of a data value may, but need not,
* be present for a type which was referenced with the keyword
* <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
* If present, it shall appear in the encoding at the point
* corresponding to the appearance of the type in the ASN.1 definition.
* </p><p>
* <b>8.10 Encoding of a sequence-of value </b>
* </p><p>
* <b>8.10.1</b> The encoding of a sequence-of value shall be constructed.
* <p>
* <b>8.10.2</b> The contents octets shall consist of zero,
* one or more complete encodings of data values from the type listed in
* the ASN.1 definition.
* <p>
* <b>8.10.3</b> The order of the encodings of the data values shall be
* the same as the order of the data values in the sequence-of value to
* be encoded.
* </p>
* <p><b>9: Canonical encoding rules</b></p>
* <p><b>9.1 Length forms</b></p>
* If the encoding is constructed, it shall employ the indefinite length form.
* If the encoding is primitive, it shall include the fewest length octets necessary.
* [Contrast with 8.1.3.2 b).]
*
* <p><b>11: Restrictions on BER employed by both CER and DER</b></p>
* <p><b>11.5 Set and sequence components with default value</b></p>
* The encoding of a set value or sequence value shall not include
* an encoding for any component value which is equal to
* its default value.
*/
public abstract class ASN1Sequence
extends ASN1Primitive
{
protected Vector seq = new Vector();
/**
* return an ASN1Sequence from the given object.
* Return an ASN1Sequence from the given object.
*
* @param obj the object we want converted.
* @exception IllegalArgumentException if the object cannot be converted.
* @return an ASN1Sequence instance, or null.
*/
public static ASN1Sequence getInstance(
Object obj)
@ -65,6 +113,7 @@ public abstract class ASN1Sequence
* false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return an ASN1Sequence instance.
*/
public static ASN1Sequence getInstance(
ASN1TaggedObject obj,
@ -110,14 +159,15 @@ public abstract class ASN1Sequence
}
/**
* create an empty sequence
* Create an empty sequence
*/
protected ASN1Sequence()
{
}
/**
* create a sequence containing one object
* Create a sequence containing one object
* @param obj the object to be put in the SEQUENCE.
*/
protected ASN1Sequence(
ASN1Encodable obj)
@ -126,7 +176,8 @@ public abstract class ASN1Sequence
}
/**
* create a sequence containing a vector of objects.
* Create a sequence containing a vector of objects.
* @param v the vector of objects to be put in the SEQUENCE
*/
protected ASN1Sequence(
ASN1EncodableVector v)
@ -138,7 +189,7 @@ public abstract class ASN1Sequence
}
/**
* create a sequence containing a vector of objects.
* Create a sequence containing a vector of objects.
*/
protected ASN1Sequence(
ASN1Encodable[] array)
@ -209,7 +260,7 @@ public abstract class ASN1Sequence
}
/**
* return the object at the sequence position indicated by index.
* Return the object at the sequence position indicated by index.
*
* @param index the sequence number (starting at zero) of the object
* @return the object at the sequence position indicated by index.
@ -221,7 +272,7 @@ public abstract class ASN1Sequence
}
/**
* return the number of objects in this sequence.
* Return the number of objects in this sequence.
*
* @return the number of objects in this sequence.
*/
@ -290,6 +341,10 @@ public abstract class ASN1Sequence
return encObj;
}
/**
* Change current SEQUENCE object to be encoded as {@link DERSequence}.
* This is part of Distinguished Encoding Rules form serialization.
*/
ASN1Primitive toDERObject()
{
ASN1Sequence derSeq = new DERSequence();
@ -299,6 +354,10 @@ public abstract class ASN1Sequence
return derSeq;
}
/**
* Change current SEQUENCE object to be encoded as {@link DLSequence}.
* This is part of Direct Length form serialization.
*/
ASN1Primitive toDLObject()
{
ASN1Sequence dlSeq = new DLSequence();

View File

@ -2,9 +2,18 @@ package org.spongycastle.asn1;
import java.io.IOException;
/**
* A basic parser for a SEQUENCE object
*/
public interface ASN1SequenceParser
extends ASN1Encodable, InMemoryRepresentable
{
/**
* Read the next object from the underlying object representing a SEQUENCE.
*
* @throws IOException for bad input stream.
* @return the next object, null if we are at the end.
*/
ASN1Encodable readObject()
throws IOException;
}

View File

@ -5,7 +5,94 @@ import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
abstract public class ASN1Set
/**
* ASN.1 <code>SET</code> and <code>SET OF</code> constructs.
* <p>
* Note: This does not know which syntax the set is!
* (The difference: ordering of SET elements or not ordering.)
* <p>
* DER form is always definite form length fields, while
* BER support uses indefinite form.
* <p>
* The CER form support does not exist.
* <p>
* <hr>
* <h2>X.690</h2>
* <h3>8: Basic encoding rules</h3>
* <h4>8.11 Encoding of a set value </h4>
* <b>8.11.1</b> The encoding of a set value shall be constructed
* <p>
* <b>8.11.2</b> The contents octets shall consist of the complete
* encoding of a data value from each of the types listed in the
* ASN.1 definition of the set type, in an order chosen by the sender,
* unless the type was referenced with the keyword
* <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
* <p>
* <b>8.11.3</b> The encoding of a data value may, but need not,
* be present for a type which was referenced with the keyword
* <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
* <blockquote>
* NOTE &mdash; The order of data values in a set value is not significant,
* and places no constraints on the order during transfer
* </blockquote>
* <h4>8.12 Encoding of a set-of value</h4>
* <b>8.12.1</b> The encoding of a set-of value shall be constructed.
* <p>
* <b>8.12.2</b> The text of 8.10.2 applies:
* <i>The contents octets shall consist of zero,
* one or more complete encodings of data values from the type listed in
* the ASN.1 definition.</i>
* <p>
* <b>8.12.3</b> The order of data values need not be preserved by
* the encoding and subsequent decoding.
*
* <h3>9: Canonical encoding rules</h3>
* <h4>9.1 Length forms</h4>
* If the encoding is constructed, it shall employ the indefinite length form.
* If the encoding is primitive, it shall include the fewest length octets necessary.
* [Contrast with 8.1.3.2 b).]
* <h4>9.3 Set components</h4>
* The encodings of the component values of a set value shall
* appear in an order determined by their tags as specified
* in 8.6 of ITU-T Rec. X.680 | ISO/IEC 8824-1.
* Additionally, for the purposes of determining the order in which
* components are encoded when one or more component is an untagged
* choice type, each untagged choice type is ordered as though it
* has a tag equal to that of the smallest tag in that choice type
* or any untagged choice types nested within.
*
* <h3>10: Distinguished encoding rules</h3>
* <h4>10.1 Length forms</h4>
* The definite form of length encoding shall be used,
* encoded in the minimum number of octets.
* [Contrast with 8.1.3.2 b).]
* <h4>10.3 Set components</h4>
* The encodings of the component values of a set value shall appear
* in an order determined by their tags as specified
* in 8.6 of ITU-T Rec. X.680 | ISO/IEC 8824-1.
* <blockquote>
* NOTE &mdash; Where a component of the set is an untagged choice type,
* the location of that component in the ordering will depend on
* the tag of the choice component being encoded.
* </blockquote>
*
* <h3>11: Restrictions on BER employed by both CER and DER</h3>
* <h4>11.5 Set and sequence components with default value </h4>
* The encoding of a set value or sequence value shall not include
* an encoding for any component value which is equal to
* its default value.
* <h4>11.6 Set-of components </h4>
* <p>
* The encodings of the component values of a set-of value
* shall appear in ascending order, the encodings being compared
* as octet strings with the shorter components being padded at
* their trailing end with 0-octets.
* <blockquote>
* NOTE &mdash; The padding octets are for comparison purposes only
* and do not appear in the encodings.
* </blockquote>
*/
public abstract class ASN1Set
extends ASN1Primitive
{
private Vector set = new Vector();
@ -16,6 +103,7 @@ abstract public class ASN1Set
*
* @param obj the object we want converted.
* @exception IllegalArgumentException if the object cannot be converted.
* @return an ASN1Set instance, or null.
*/
public static ASN1Set getInstance(
Object obj)
@ -67,6 +155,7 @@ abstract public class ASN1Set
* false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return an ASN1Set instance.
*/
public static ASN1Set getInstance(
ASN1TaggedObject obj,
@ -135,6 +224,7 @@ abstract public class ASN1Set
/**
* create a sequence containing one object
* @param obj object to be added to the SET.
*/
protected ASN1Set(
ASN1Encodable obj)
@ -144,6 +234,8 @@ abstract public class ASN1Set
/**
* create a sequence containing a vector of objects.
* @param v a vector of objects to make up the SET.
* @param doSort true if should be sorted DER style, false otherwise.
*/
protected ASN1Set(
ASN1EncodableVector v,
@ -275,6 +367,10 @@ abstract public class ASN1Set
return hashCode;
}
/**
* Change current SET object to be encoded as {@link DERSet}.
* This is part of Distinguished Encoding Rules form serialization.
*/
ASN1Primitive toDERObject()
{
if (isSorted)
@ -304,6 +400,10 @@ abstract public class ASN1Set
}
}
/**
* Change current SET object to be encoded as {@link DLSet}.
* This is part of Direct Length form serialization.
*/
ASN1Primitive toDLObject()
{
ASN1Set derSet = new DLSet();

View File

@ -2,9 +2,18 @@ package org.spongycastle.asn1;
import java.io.IOException;
/**
* A basic parser for a SET object
*/
public interface ASN1SetParser
extends ASN1Encodable, InMemoryRepresentable
{
/**
* Read the next object from the underlying object representing a SET.
*
* @throws IOException for bad input stream.
* @return the next object, null if we are at the end.
*/
public ASN1Encodable readObject()
throws IOException;
}

View File

@ -4,6 +4,9 @@ import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* A parser for ASN.1 streams which also returns, where possible, parsers for the objects it encounters.
*/
public class ASN1StreamParser
{
private final InputStream _in;

View File

@ -1,22 +1,314 @@
package org.spongycastle.asn1;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.SimpleTimeZone;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings;
/**
- * UTC time object.
* Internal facade of {@link ASN1UTCTime}.
* <p>
* This datatype is valid only from 1950-01-01 00:00:00 UTC until 2049-12-31 23:59:59 UTC.
* <p>
* <hr>
* <p><b>X.690</b></p>
* <p><b>11: Restrictions on BER employed by both CER and DER</b></p>
* <p><b>11.8 UTCTime </b></p>
* <b>11.8.1</b> The encoding shall terminate with "Z",
* as described in the ITU-T X.680 | ISO/IEC 8824-1 clause on UTCTime.
* <p>
* <b>11.8.2</b> The seconds element shall always be present.
* <p>
* <b>11.8.3</b> Midnight (GMT) shall be represented in the form:
* <blockquote>
* "YYMMDD000000Z"
* </blockquote>
* where "YYMMDD" represents the day following the midnight in question.
*/
public class ASN1UTCTime
extends DERUTCTime
extends ASN1Primitive
{
ASN1UTCTime(byte[] bytes)
private byte[] time;
/**
* return an UTC Time from the passed in object.
*
* @param obj an ASN1UTCTime or an object that can be converted into one.
* @exception IllegalArgumentException if the object cannot be converted.
* @return an ASN1UTCTime instance, or null.
*/
public static ASN1UTCTime getInstance(
Object obj)
{
super(bytes);
if (obj == null || obj instanceof ASN1UTCTime)
{
return (ASN1UTCTime)obj;
}
public ASN1UTCTime(Date time)
if (obj instanceof byte[])
{
super(time);
try
{
return (ASN1UTCTime)fromByteArray((byte[])obj);
}
catch (Exception e)
{
throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
}
}
public ASN1UTCTime(String time)
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return an UTC Time from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return an ASN1UTCTime instance, or null.
*/
public static ASN1UTCTime getInstance(
ASN1TaggedObject obj,
boolean explicit)
{
super(time);
ASN1Object o = obj.getObject();
if (explicit || o instanceof ASN1UTCTime)
{
return getInstance(o);
}
else
{
return new ASN1UTCTime(((ASN1OctetString)o).getOctets());
}
}
/**
* The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
* never encoded. When you're creating one of these objects from scratch, that's
* what you want to use, otherwise we'll try to deal with whatever gets read from
* the input stream... (this is why the input format is different from the getTime()
* method output).
* <p>
*
* @param time the time string.
*/
public ASN1UTCTime(
String time)
{
this.time = Strings.toByteArray(time);
try
{
this.getDate();
}
catch (ParseException e)
{
throw new IllegalArgumentException("invalid date string: " + e.getMessage());
}
}
/**
* base constructor from a java.util.date object
* @param time the Date to build the time from.
*/
public ASN1UTCTime(
Date time)
{
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'");
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
this.time = Strings.toByteArray(dateF.format(time));
}
/**
* Base constructor from a java.util.date and Locale - you may need to use this if the default locale
* doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations.
*
* @param time a date object representing the time of interest.
* @param locale an appropriate Locale for producing an ASN.1 UTCTime value.
*/
public ASN1UTCTime(
Date time,
Locale locale)
{
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'", locale);
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
this.time = Strings.toByteArray(dateF.format(time));
}
ASN1UTCTime(
byte[] time)
{
this.time = time;
}
/**
* return the time as a date based on whatever a 2 digit year will return. For
* standardised processing use getAdjustedDate().
*
* @return the resulting date
* @exception ParseException if the date string cannot be parsed.
*/
public Date getDate()
throws ParseException
{
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz");
return dateF.parse(getTime());
}
/**
* return the time as an adjusted date
* in the range of 1950 - 2049.
*
* @return a date in the range of 1950 to 2049.
* @exception ParseException if the date string cannot be parsed.
*/
public Date getAdjustedDate()
throws ParseException
{
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
return dateF.parse(getAdjustedTime());
}
/**
* return the time - always in the form of
* YYMMDDhhmmssGMT(+hh:mm|-hh:mm).
* <p>
* Normally in a certificate we would expect "Z" rather than "GMT",
* however adding the "GMT" means we can just use:
* <pre>
* dateF = new SimpleDateFormat("yyMMddHHmmssz");
* </pre>
* To read in the time and get a date which is compatible with our local
* time zone.
* <p>
* <b>Note:</b> In some cases, due to the local date processing, this
* may lead to unexpected results. If you want to stick the normal
* convention of 1950 to 2049 use the getAdjustedTime() method.
*/
public String getTime()
{
String stime = Strings.fromByteArray(time);
//
// standardise the format.
//
if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0)
{
if (stime.length() == 11)
{
return stime.substring(0, 10) + "00GMT+00:00";
}
else
{
return stime.substring(0, 12) + "GMT+00:00";
}
}
else
{
int index = stime.indexOf('-');
if (index < 0)
{
index = stime.indexOf('+');
}
String d = stime;
if (index == stime.length() - 3)
{
d += "00";
}
if (index == 10)
{
return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15);
}
else
{
return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17);
}
}
}
/**
* return a time string as an adjusted date with a 4 digit year. This goes
* in the range of 1950 - 2049.
*/
public String getAdjustedTime()
{
String d = this.getTime();
if (d.charAt(0) < '5')
{
return "20" + d;
}
else
{
return "19" + d;
}
}
boolean isConstructed()
{
return false;
}
int encodedLength()
{
int length = time.length;
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.write(BERTags.UTC_TIME);
int length = time.length;
out.writeLength(length);
for (int i = 0; i != length; i++)
{
out.write((byte)time[i]);
}
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof ASN1UTCTime))
{
return false;
}
return Arrays.areEqual(time, ((ASN1UTCTime)o).time);
}
public int hashCode()
{
return Arrays.hashCode(time);
}
public String toString()
{
return Strings.fromByteArray(time);
}
}

View File

@ -103,15 +103,6 @@ public class DERApplicationSpecific
throw new IllegalArgumentException("failed to construct object from byte[]: " + e.getMessage());
}
}
else if (obj instanceof ASN1Encodable)
{
ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
if (primitive instanceof ASN1Sequence)
{
return (DERApplicationSpecific)primitive;
}
}
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
}

View File

@ -18,6 +18,7 @@ public class DERBMPString
*
* @param obj the object we want converted.
* @exception IllegalArgumentException if the object cannot be converted.
* @return a DERBMPString instance, or null.
*/
public static DERBMPString getInstance(
Object obj)
@ -50,6 +51,7 @@ public class DERBMPString
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return a DERBMPString instance.
*/
public static DERBMPString getInstance(
ASN1TaggedObject obj,
@ -69,6 +71,7 @@ public class DERBMPString
/**
* basic constructor - byte encoded string.
* @param string the encoded BMP STRING to wrap.
*/
DERBMPString(
byte[] string)
@ -90,6 +93,7 @@ public class DERBMPString
/**
* basic constructor
* @param string a String to wrap as a BMP STRING.
*/
public DERBMPString(
String string)

View File

@ -18,7 +18,8 @@ public class DERBitString
protected int padBits;
/**
* return the correct number of pad bits for a bit string defined in
* @param bitString an int containing the BIT STRING
* @return the correct number of pad bits for a bit string defined in
* a 32 bit constant
*/
static protected int getPadBits(
@ -66,7 +67,8 @@ public class DERBitString
}
/**
* return the correct number of bytes for a bit string defined in
* @param bitString an int containing the BIT STRING
* @return the correct number of bytes for a bit string defined in
* a 32 bit constant
*/
static protected byte[] getBytes(int bitString)
@ -93,7 +95,9 @@ public class DERBitString
/**
* return a Bit String from the passed in object
*
* @param obj a DERBitString or an object that can be converted into one.
* @exception IllegalArgumentException if the object cannot be converted.
* @return a DERBitString instance, or null.
*/
public static DERBitString getInstance(
Object obj)
@ -114,6 +118,7 @@ public class DERBitString
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return a DERBitString instance, or null.
*/
public static DERBitString getInstance(
ASN1TaggedObject obj,

View File

@ -1,179 +1,22 @@
package org.spongycastle.asn1;
import java.io.IOException;
import org.spongycastle.util.Arrays;
/**
* @deprecated use ASN1Boolean
*/
public class DERBoolean
extends ASN1Primitive
extends ASN1Boolean
{
private static final byte[] TRUE_VALUE = new byte[] { (byte)0xff };
private static final byte[] FALSE_VALUE = new byte[] { 0 };
private byte[] value;
public static final ASN1Boolean FALSE = new ASN1Boolean(false);
public static final ASN1Boolean TRUE = new ASN1Boolean(true);
/**
* return a boolean from the passed in object.
*
* @exception IllegalArgumentException if the object cannot be converted.
*/
public static ASN1Boolean getInstance(
Object obj)
{
if (obj == null || obj instanceof ASN1Boolean)
{
return (ASN1Boolean)obj;
}
if (obj instanceof DERBoolean)
{
return ((DERBoolean)obj).isTrue() ? DERBoolean.TRUE : DERBoolean.FALSE;
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return a ASN1Boolean from the passed in boolean.
*/
public static ASN1Boolean getInstance(
boolean value)
{
return (value ? TRUE : FALSE);
}
/**
* return a ASN1Boolean from the passed in boolean.
*/
public static ASN1Boolean getInstance(
int value)
{
return (value != 0 ? TRUE : FALSE);
}
/**
* return a Boolean from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
public static ASN1Boolean getInstance(
ASN1TaggedObject obj,
boolean explicit)
{
ASN1Primitive o = obj.getObject();
if (explicit || o instanceof DERBoolean)
{
return getInstance(o);
}
else
{
return ASN1Boolean.fromOctetString(((ASN1OctetString)o).getOctets());
}
}
DERBoolean(
byte[] value)
{
if (value.length != 1)
{
throw new IllegalArgumentException("byte value should have 1 byte in it");
}
if (value[0] == 0)
{
this.value = FALSE_VALUE;
}
else if (value[0] == 0xff)
{
this.value = TRUE_VALUE;
}
else
{
this.value = Arrays.clone(value);
}
}
/**
* @deprecated use getInstance(boolean) method.
* @param value
*/
public DERBoolean(
boolean value)
public DERBoolean(boolean value)
{
this.value = (value) ? TRUE_VALUE : FALSE_VALUE;
super(value);
}
public boolean isTrue()
DERBoolean(byte[] value)
{
return (value[0] != 0);
}
boolean isConstructed()
{
return false;
}
int encodedLength()
{
return 3;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.writeEncoded(BERTags.BOOLEAN, value);
}
protected boolean asn1Equals(
ASN1Primitive o)
{
if ((o == null) || !(o instanceof DERBoolean))
{
return false;
}
return (value[0] == ((DERBoolean)o).value[0]);
}
public int hashCode()
{
return value[0];
}
public String toString()
{
return (value[0] != 0) ? "TRUE" : "FALSE";
}
static ASN1Boolean fromOctetString(byte[] value)
{
if (value.length != 1)
{
throw new IllegalArgumentException("BOOLEAN value should have 1 byte in it");
}
if (value[0] == 0)
{
return FALSE;
}
else if (value[0] == 0xff)
{
return TRUE;
}
else
{
return new ASN1Boolean(value);
}
super(value);
}
}

View File

@ -1,170 +1,37 @@
package org.spongycastle.asn1;
import java.io.IOException;
import java.math.BigInteger;
import org.spongycastle.util.Arrays;
/**
* Use ASN1Enumerated instead of this.
* @deprecated Use ASN1Enumerated instead of this.
*/
public class DEREnumerated
extends ASN1Primitive
extends ASN1Enumerated
{
byte[] bytes;
/**
* return an integer from the passed in object
*
* @exception IllegalArgumentException if the object cannot be converted.
*/
public static ASN1Enumerated getInstance(
Object obj)
{
if (obj == null || obj instanceof ASN1Enumerated)
{
return (ASN1Enumerated)obj;
}
if (obj instanceof DEREnumerated)
{
return new ASN1Enumerated(((DEREnumerated)obj).getValue());
}
if (obj instanceof byte[])
{
try
{
return (ASN1Enumerated)fromByteArray((byte[])obj);
}
catch (Exception e)
{
throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
}
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return an Enumerated from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
public static ASN1Enumerated getInstance(
ASN1TaggedObject obj,
boolean explicit)
{
ASN1Primitive o = obj.getObject();
if (explicit || o instanceof DEREnumerated)
{
return getInstance(o);
}
else
{
return fromOctetString(((ASN1OctetString)o).getOctets());
}
}
/**
* @param bytes the value of this enumerated as an encoded BigInteger (signed).
* @deprecated use ASN1Enumerated
*/
public DEREnumerated(
int value)
DEREnumerated(byte[] bytes)
{
bytes = BigInteger.valueOf(value).toByteArray();
super(bytes);
}
/**
* @param value the value of this enumerated.
* @deprecated use ASN1Enumerated
*/
public DEREnumerated(
BigInteger value)
public DEREnumerated(BigInteger value)
{
bytes = value.toByteArray();
super(value);
}
/**
* @param value the value of this enumerated.
* @deprecated use ASN1Enumerated
*/
public DEREnumerated(
byte[] bytes)
public DEREnumerated(int value)
{
this.bytes = bytes;
}
public BigInteger getValue()
{
return new BigInteger(bytes);
}
boolean isConstructed()
{
return false;
}
int encodedLength()
{
return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.writeEncoded(BERTags.ENUMERATED, bytes);
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof DEREnumerated))
{
return false;
}
DEREnumerated other = (DEREnumerated)o;
return Arrays.areEqual(this.bytes, other.bytes);
}
public int hashCode()
{
return Arrays.hashCode(bytes);
}
private static ASN1Enumerated[] cache = new ASN1Enumerated[12];
static ASN1Enumerated fromOctetString(byte[] enc)
{
if (enc.length > 1)
{
return new ASN1Enumerated(Arrays.clone(enc));
}
if (enc.length == 0)
{
throw new IllegalArgumentException("ENUMERATED has zero length");
}
int value = enc[0] & 0xff;
if (value >= cache.length)
{
return new ASN1Enumerated(Arrays.clone(enc));
}
ASN1Enumerated possibleMatch = cache[value];
if (possibleMatch == null)
{
possibleMatch = cache[value] = new ASN1Enumerated(Arrays.clone(enc));
}
return possibleMatch;
super(value);
}
}

View File

@ -1,350 +1,28 @@
package org.spongycastle.asn1;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings;
/**
* Generalized time object.
* DER Generalized time object.
*/
public class DERGeneralizedTime
extends ASN1Primitive
extends ASN1GeneralizedTime
{
private byte[] time;
/**
* return a generalized time from the passed in object
*
* @exception IllegalArgumentException if the object cannot be converted.
*/
public static ASN1GeneralizedTime getInstance(
Object obj)
DERGeneralizedTime(byte[] bytes)
{
if (obj == null || obj instanceof ASN1GeneralizedTime)
{
return (ASN1GeneralizedTime)obj;
super(bytes);
}
if (obj instanceof DERGeneralizedTime)
public DERGeneralizedTime(Date time)
{
return new ASN1GeneralizedTime(((DERGeneralizedTime)obj).time);
super(time);
}
if (obj instanceof byte[])
public DERGeneralizedTime(String time)
{
try
{
return (ASN1GeneralizedTime)fromByteArray((byte[])obj);
}
catch (Exception e)
{
throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
}
super(time);
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return a Generalized Time object from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
public static ASN1GeneralizedTime getInstance(
ASN1TaggedObject obj,
boolean explicit)
{
ASN1Primitive o = obj.getObject();
if (explicit || o instanceof DERGeneralizedTime)
{
return getInstance(o);
}
else
{
return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets());
}
}
/**
* 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
* time and UTC time. The fractional second amount f must consist of at
* least one number with trailing zeroes removed.
*
* @param time the time string.
* @exception IllegalArgumentException if String is an illegal format.
*/
public DERGeneralizedTime(
String time)
{
this.time = Strings.toByteArray(time);
try
{
this.getDate();
}
catch (ParseException e)
{
throw new IllegalArgumentException("invalid date string: " + e.getMessage());
}
}
/**
* base constructor from a java.util.date object
*/
public DERGeneralizedTime(
Date time)
{
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
this.time = Strings.toByteArray(dateF.format(time));
}
DERGeneralizedTime(
byte[] bytes)
{
this.time = bytes;
}
/**
* Return the time.
* @return The time string as it appeared in the encoded object.
*/
public String getTimeString()
{
return Strings.fromByteArray(time);
}
/**
* return the time - always in the form of
* YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm).
* <p>
* Normally in a certificate we would expect "Z" rather than "GMT",
* however adding the "GMT" means we can just use:
* <pre>
* dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
* </pre>
* To read in the time and get a date which is compatible with our local
* time zone.
*/
public String getTime()
{
String stime = Strings.fromByteArray(time);
//
// standardise the format.
//
if (stime.charAt(stime.length() - 1) == 'Z')
{
return stime.substring(0, stime.length() - 1) + "GMT+00:00";
}
else
{
int signPos = stime.length() - 5;
char sign = stime.charAt(signPos);
if (sign == '-' || sign == '+')
{
return stime.substring(0, signPos)
+ "GMT"
+ stime.substring(signPos, signPos + 3)
+ ":"
+ stime.substring(signPos + 3);
}
else
{
signPos = stime.length() - 3;
sign = stime.charAt(signPos);
if (sign == '-' || sign == '+')
{
return stime.substring(0, signPos)
+ "GMT"
+ stime.substring(signPos)
+ ":00";
}
}
}
return stime + calculateGMTOffset();
}
private String calculateGMTOffset()
{
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);
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);
}
private String convert(int time)
{
if (time < 10)
{
return "0" + time;
}
return Integer.toString(time);
}
public Date getDate()
throws ParseException
{
SimpleDateFormat dateF;
String stime = Strings.fromByteArray(time);
String d = stime;
if (stime.endsWith("Z"))
{
if (hasFractionalSeconds())
{
dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'");
}
else
{
dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
}
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
}
else if (stime.indexOf('-') > 0 || stime.indexOf('+') > 0)
{
d = this.getTime();
if (hasFractionalSeconds())
{
dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz");
}
else
{
dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
}
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
}
else
{
if (hasFractionalSeconds())
{
dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
}
else
{
dateF = new SimpleDateFormat("yyyyMMddHHmmss");
}
dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID()));
}
if (hasFractionalSeconds())
{
// java misinterprets extra digits as being milliseconds...
String frac = d.substring(14);
int index;
for (index = 1; index < frac.length(); index++)
{
char ch = frac.charAt(index);
if (!('0' <= ch && ch <= '9'))
{
break;
}
}
if (index - 1 > 3)
{
frac = frac.substring(0, 4) + frac.substring(index);
d = d.substring(0, 14) + frac;
}
else if (index - 1 == 1)
{
frac = frac.substring(0, index) + "00" + frac.substring(index);
d = d.substring(0, 14) + frac;
}
else if (index - 1 == 2)
{
frac = frac.substring(0, index) + "0" + frac.substring(index);
d = d.substring(0, 14) + frac;
}
}
return dateF.parse(d);
}
private boolean hasFractionalSeconds()
{
for (int i = 0; i != time.length; i++)
{
if (time[i] == '.')
{
if (i == 14)
{
return true;
}
}
}
return false;
}
boolean isConstructed()
{
return false;
}
int encodedLength()
{
int length = time.length;
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.writeEncoded(BERTags.GENERALIZED_TIME, time);
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof DERGeneralizedTime))
{
return false;
}
return Arrays.areEqual(time, ((DERGeneralizedTime)o).time);
}
public int hashCode()
{
return Arrays.hashCode(time);
}
// TODO: create proper DER encoding.
}

View File

@ -17,7 +17,9 @@ public class DERIA5String
/**
* return a IA5 string from the passed in object
*
* @param obj a DERIA5String or an object that can be converted into one.
* @exception IllegalArgumentException if the object cannot be converted.
* @return a DERIA5String instance, or null.
*/
public static DERIA5String getInstance(
Object obj)
@ -50,6 +52,7 @@ public class DERIA5String
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return a DERIA5String instance, or null.
*/
public static DERIA5String getInstance(
ASN1TaggedObject obj,
@ -69,6 +72,7 @@ public class DERIA5String
/**
* basic constructor - with bytes.
* @param string the byte encoding of the characters making up the string.
*/
DERIA5String(
byte[] string)
@ -78,6 +82,7 @@ public class DERIA5String
/**
* basic constructor - without validation.
* @param string the base string to use..
*/
public DERIA5String(
String string)
@ -163,7 +168,8 @@ public class DERIA5String
* return true if the passed in String can be represented without
* loss as an IA5String, false otherwise.
*
* @return true if in printable set, false otherwise.
* @param str the string to check.
* @return true if character set in IA5String set, false otherwise.
*/
public static boolean isIA5String(
String str)

View File

@ -1,160 +1,30 @@
package org.spongycastle.asn1;
import java.io.IOException;
import java.math.BigInteger;
import org.spongycastle.util.Arrays;
/**
* Use ASN1Integer instead of this,
* @deprecated Use ASN1Integer instead of this,
*/
public class DERInteger
extends ASN1Primitive
extends ASN1Integer
{
byte[] bytes;
/**
* return an integer from the passed in object
* Constructor from a byte array containing a signed representation of the number.
*
* @exception IllegalArgumentException if the object cannot be converted.
* @param bytes a byte array containing the signed number.A copy is made of the byte array.
*/
public static ASN1Integer getInstance(
Object obj)
public DERInteger(byte[] bytes)
{
if (obj == null || obj instanceof ASN1Integer)
{
return (ASN1Integer)obj;
}
if (obj instanceof DERInteger)
{
return new ASN1Integer((((DERInteger)obj).getValue()));
super(bytes, true);
}
if (obj instanceof byte[])
public DERInteger(BigInteger value)
{
try
{
return (ASN1Integer)fromByteArray((byte[])obj);
}
catch (Exception e)
{
throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
}
super(value);
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return an Integer from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
public static ASN1Integer getInstance(
ASN1TaggedObject obj,
boolean explicit)
public DERInteger(long value)
{
ASN1Primitive o = obj.getObject();
if (explicit || o instanceof DERInteger)
{
return getInstance(o);
}
else
{
return new ASN1Integer(ASN1OctetString.getInstance(obj.getObject()).getOctets());
}
}
/**
* @deprecated use ASN1Integer constructor
*/
public DERInteger(
long value)
{
bytes = BigInteger.valueOf(value).toByteArray();
}
/**
* @deprecated use ASN1Integer constructor
*/
public DERInteger(
BigInteger value)
{
bytes = value.toByteArray();
}
/**
* @deprecated use ASN1Integer constructor
*/
public DERInteger(
byte[] bytes)
{
this.bytes = bytes;
}
public BigInteger getValue()
{
return new BigInteger(bytes);
}
/**
* in some cases positive values get crammed into a space,
* that's not quite big enough...
*/
public BigInteger getPositiveValue()
{
return new BigInteger(1, bytes);
}
boolean isConstructed()
{
return false;
}
int encodedLength()
{
return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.writeEncoded(BERTags.INTEGER, bytes);
}
public int hashCode()
{
int value = 0;
for (int i = 0; i != bytes.length; i++)
{
value ^= (bytes[i] & 0xff) << (i % 4);
}
return value;
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof DERInteger))
{
return false;
}
DERInteger other = (DERInteger)o;
return Arrays.areEqual(bytes, other.bytes);
}
public String toString()
{
return getValue().toString();
super(value);
}
}

View File

@ -17,7 +17,9 @@ public class DERNumericString
/**
* return a Numeric string from the passed in object
*
* @param obj a DERNumericString or an object that can be converted into one.
* @exception IllegalArgumentException if the object cannot be converted.
* @return a DERNumericString instance, or null
*/
public static DERNumericString getInstance(
Object obj)
@ -50,6 +52,7 @@ public class DERNumericString
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return a DERNumericString instance, or null.
*/
public static DERNumericString getInstance(
ASN1TaggedObject obj,

View File

@ -1,446 +1,24 @@
package org.spongycastle.asn1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import org.spongycastle.util.Arrays;
/**
* Use ASN1ObjectIdentifier instead of this,
*
* @deprecated Use ASN1ObjectIdentifier instead of this,
*/
public class DERObjectIdentifier
extends ASN1Primitive
extends ASN1ObjectIdentifier
{
String identifier;
private byte[] body;
/**
* return an OID from the passed in object
*
* @throws IllegalArgumentException if the object cannot be converted.
*/
public static ASN1ObjectIdentifier getInstance(
Object obj)
public DERObjectIdentifier(String identifier)
{
if (obj == null || obj instanceof ASN1ObjectIdentifier)
{
return (ASN1ObjectIdentifier)obj;
super(identifier);
}
if (obj instanceof DERObjectIdentifier)
DERObjectIdentifier(byte[] bytes)
{
return new ASN1ObjectIdentifier(((DERObjectIdentifier)obj).getId());
super(bytes);
}
if (obj instanceof ASN1Encodable && ((ASN1Encodable)obj).toASN1Primitive() instanceof ASN1ObjectIdentifier)
DERObjectIdentifier(ASN1ObjectIdentifier oid, String branch)
{
return (ASN1ObjectIdentifier)((ASN1Encodable)obj).toASN1Primitive();
}
if (obj instanceof byte[])
{
byte[] enc = (byte[])obj;
if (enc[0] == BERTags.OBJECT_IDENTIFIER)
{
try
{
return (ASN1ObjectIdentifier)fromByteArray(enc);
}
catch (IOException e)
{
throw new IllegalArgumentException("failed to construct sequence from byte[]: " + e.getMessage());
}
}
else
{ // TODO: this really shouldn't be supported here...
return ASN1ObjectIdentifier.fromOctetString((byte[])obj);
}
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return an Object Identifier from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @throws IllegalArgumentException if the tagged object cannot
* be converted.
*/
public static ASN1ObjectIdentifier getInstance(
ASN1TaggedObject obj,
boolean explicit)
{
ASN1Primitive o = obj.getObject();
if (explicit || o instanceof DERObjectIdentifier)
{
return getInstance(o);
}
else
{
return ASN1ObjectIdentifier.fromOctetString(ASN1OctetString.getInstance(obj.getObject()).getOctets());
}
}
private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7f;
DERObjectIdentifier(
byte[] bytes)
{
StringBuffer objId = new StringBuffer();
long value = 0;
BigInteger bigValue = null;
boolean first = true;
for (int i = 0; i != bytes.length; i++)
{
int b = bytes[i] & 0xff;
if (value <= LONG_LIMIT)
{
value += (b & 0x7f);
if ((b & 0x80) == 0) // end of number reached
{
if (first)
{
if (value < 40)
{
objId.append('0');
}
else if (value < 80)
{
objId.append('1');
value -= 40;
}
else
{
objId.append('2');
value -= 80;
}
first = false;
}
objId.append('.');
objId.append(value);
value = 0;
}
else
{
value <<= 7;
}
}
else
{
if (bigValue == null)
{
bigValue = BigInteger.valueOf(value);
}
bigValue = bigValue.or(BigInteger.valueOf(b & 0x7f));
if ((b & 0x80) == 0)
{
if (first)
{
objId.append('2');
bigValue = bigValue.subtract(BigInteger.valueOf(80));
first = false;
}
objId.append('.');
objId.append(bigValue);
bigValue = null;
value = 0;
}
else
{
bigValue = bigValue.shiftLeft(7);
}
}
}
this.identifier = objId.toString();
this.body = Arrays.clone(bytes);
}
/**
* @deprecated use ASN1ObjectIdentifier constructor.
*/
public DERObjectIdentifier(
String identifier)
{
if (identifier == null)
{
throw new IllegalArgumentException("'identifier' cannot be null");
}
if (!isValidIdentifier(identifier))
{
throw new IllegalArgumentException("string " + identifier + " not an OID");
}
this.identifier = identifier;
}
DERObjectIdentifier(DERObjectIdentifier oid, String branchID)
{
if (!isValidBranchID(branchID, 0))
{
throw new IllegalArgumentException("string " + branchID + " not a valid OID branch");
}
this.identifier = oid.getId() + "." + branchID;
}
public String getId()
{
return identifier;
}
private void writeField(
ByteArrayOutputStream out,
long fieldValue)
{
byte[] result = new byte[9];
int pos = 8;
result[pos] = (byte)((int)fieldValue & 0x7f);
while (fieldValue >= (1L << 7))
{
fieldValue >>= 7;
result[--pos] = (byte)((int)fieldValue & 0x7f | 0x80);
}
out.write(result, pos, 9 - pos);
}
private void writeField(
ByteArrayOutputStream out,
BigInteger fieldValue)
{
int byteCount = (fieldValue.bitLength() + 6) / 7;
if (byteCount == 0)
{
out.write(0);
}
else
{
BigInteger tmpValue = fieldValue;
byte[] tmp = new byte[byteCount];
for (int i = byteCount - 1; i >= 0; i--)
{
tmp[i] = (byte)((tmpValue.intValue() & 0x7f) | 0x80);
tmpValue = tmpValue.shiftRight(7);
}
tmp[byteCount - 1] &= 0x7f;
out.write(tmp, 0, tmp.length);
}
}
private void doOutput(ByteArrayOutputStream aOut)
{
OIDTokenizer tok = new OIDTokenizer(identifier);
int first = Integer.parseInt(tok.nextToken()) * 40;
String secondToken = tok.nextToken();
if (secondToken.length() <= 18)
{
writeField(aOut, first + Long.parseLong(secondToken));
}
else
{
writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first)));
}
while (tok.hasMoreTokens())
{
String token = tok.nextToken();
if (token.length() <= 18)
{
writeField(aOut, Long.parseLong(token));
}
else
{
writeField(aOut, new BigInteger(token));
}
}
}
protected synchronized byte[] getBody()
{
if (body == null)
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
doOutput(bOut);
body = bOut.toByteArray();
}
return body;
}
boolean isConstructed()
{
return false;
}
int encodedLength()
throws IOException
{
int length = getBody().length;
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
byte[] enc = getBody();
out.write(BERTags.OBJECT_IDENTIFIER);
out.writeLength(enc.length);
out.write(enc);
}
public int hashCode()
{
return identifier.hashCode();
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof DERObjectIdentifier))
{
return false;
}
return identifier.equals(((DERObjectIdentifier)o).identifier);
}
public String toString()
{
return getId();
}
private static boolean isValidBranchID(
String branchID, int start)
{
boolean periodAllowed = false;
int pos = branchID.length();
while (--pos >= start)
{
char ch = branchID.charAt(pos);
// TODO Leading zeroes?
if ('0' <= ch && ch <= '9')
{
periodAllowed = true;
continue;
}
if (ch == '.')
{
if (!periodAllowed)
{
return false;
}
periodAllowed = false;
continue;
}
return false;
}
return periodAllowed;
}
private static boolean isValidIdentifier(
String identifier)
{
if (identifier.length() < 3 || identifier.charAt(1) != '.')
{
return false;
}
char first = identifier.charAt(0);
if (first < '0' || first > '2')
{
return false;
}
return isValidBranchID(identifier, 2);
}
private static ASN1ObjectIdentifier[][] cache = new ASN1ObjectIdentifier[256][];
static ASN1ObjectIdentifier fromOctetString(byte[] enc)
{
if (enc.length < 3)
{
return new ASN1ObjectIdentifier(enc);
}
int idx1 = enc[enc.length - 2] & 0xff;
// in this case top bit is always zero
int idx2 = enc[enc.length - 1] & 0x7f;
ASN1ObjectIdentifier possibleMatch;
synchronized (cache)
{
ASN1ObjectIdentifier[] first = cache[idx1];
if (first == null)
{
first = cache[idx1] = new ASN1ObjectIdentifier[128];
}
possibleMatch = first[idx2];
if (possibleMatch == null)
{
return first[idx2] = new ASN1ObjectIdentifier(enc);
}
if (Arrays.areEqual(enc, possibleMatch.getBody()))
{
return possibleMatch;
}
idx1 = (idx1 + 1) & 0xff;
first = cache[idx1];
if (first == null)
{
first = cache[idx1] = new ASN1ObjectIdentifier[128];
}
possibleMatch = first[idx2];
if (possibleMatch == null)
{
return first[idx2] = new ASN1ObjectIdentifier(enc);
}
if (Arrays.areEqual(enc, possibleMatch.getBody()))
{
return possibleMatch;
}
idx2 = (idx2 + 1) & 0x7f;
possibleMatch = first[idx2];
if (possibleMatch == null)
{
return first[idx2] = new ASN1ObjectIdentifier(enc);
}
}
if (Arrays.areEqual(enc, possibleMatch.getBody()))
{
return possibleMatch;
}
return new ASN1ObjectIdentifier(enc);
super(oid, branch);
}
}

View File

@ -17,7 +17,9 @@ public class DERPrintableString
/**
* return a printable string from the passed in object.
*
* @param obj a DERPrintableString or an object that can be converted into one.
* @exception IllegalArgumentException if the object cannot be converted.
* @return a DERPrintableString instance, or null.
*/
public static DERPrintableString getInstance(
Object obj)
@ -50,6 +52,7 @@ public class DERPrintableString
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return a DERPrintableString instance, or null.
*/
public static DERPrintableString getInstance(
ASN1TaggedObject obj,

View File

@ -18,7 +18,9 @@ public class DERT61String
/**
* return a T61 string from the passed in object.
*
* @param obj a DERT61String or an object that can be converted into one.
* @exception IllegalArgumentException if the object cannot be converted.
* @return a DERT61String instance, or null
*/
public static DERT61String getInstance(
Object obj)
@ -51,6 +53,7 @@ public class DERT61String
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return a DERT61String instance, or null
*/
public static DERT61String getInstance(
ASN1TaggedObject obj,
@ -70,6 +73,8 @@ public class DERT61String
/**
* basic constructor - string encoded as a sequence of bytes.
*
* @param string the byte encoding of the string to be wrapped.
*/
public DERT61String(
byte[] string)
@ -79,6 +84,8 @@ public class DERT61String
/**
* basic constructor - with string 8 bit assumed.
*
* @param string the string to be wrapped.
*/
public DERT61String(
String string)

View File

@ -18,7 +18,9 @@ public class DERT61UTF8String
/**
* return a T61 string from the passed in object. UTF-8 Encoding is assumed in this case.
*
* @param obj a DERT61UTF8String or an object that can be converted into one.
* @throws IllegalArgumentException if the object cannot be converted.
* @return a DERT61UTF8String instance, or null
*/
public static DERT61UTF8String getInstance(
Object obj)
@ -56,6 +58,7 @@ public class DERT61UTF8String
* tagged false otherwise.
* @throws IllegalArgumentException if the tagged object cannot
* be converted.
* @return a DERT61UTF8String instance, or null
*/
public static DERT61UTF8String getInstance(
ASN1TaggedObject obj,

View File

@ -1,278 +1,27 @@
package org.spongycastle.asn1;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SimpleTimeZone;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings;
/**
* UTC time object.
* DER UTC time object.
*/
public class DERUTCTime
extends ASN1Primitive
extends ASN1UTCTime
{
private byte[] time;
/**
* return an UTC Time from the passed in object.
*
* @exception IllegalArgumentException if the object cannot be converted.
*/
public static ASN1UTCTime getInstance(
Object obj)
DERUTCTime(byte[] bytes)
{
if (obj == null || obj instanceof ASN1UTCTime)
{
return (ASN1UTCTime)obj;
super(bytes);
}
if (obj instanceof DERUTCTime)
public DERUTCTime(Date time)
{
return new ASN1UTCTime(((DERUTCTime)obj).time);
super(time);
}
if (obj instanceof byte[])
public DERUTCTime(String time)
{
try
{
return (ASN1UTCTime)fromByteArray((byte[])obj);
}
catch (Exception e)
{
throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
}
super(time);
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
}
/**
* return an UTC Time from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
*/
public static ASN1UTCTime getInstance(
ASN1TaggedObject obj,
boolean explicit)
{
ASN1Object o = obj.getObject();
if (explicit || o instanceof ASN1UTCTime)
{
return getInstance(o);
}
else
{
return new ASN1UTCTime(((ASN1OctetString)o).getOctets());
}
}
/**
* The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
* never encoded. When you're creating one of these objects from scratch, that's
* what you want to use, otherwise we'll try to deal with whatever gets read from
* the input stream... (this is why the input format is different from the getTime()
* method output).
* <p>
*
* @param time the time string.
*/
public DERUTCTime(
String time)
{
this.time = Strings.toByteArray(time);
try
{
this.getDate();
}
catch (ParseException e)
{
throw new IllegalArgumentException("invalid date string: " + e.getMessage());
}
}
/**
* base constructer from a java.util.date object
*/
public DERUTCTime(
Date time)
{
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'");
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
this.time = Strings.toByteArray(dateF.format(time));
}
DERUTCTime(
byte[] time)
{
this.time = time;
}
/**
* return the time as a date based on whatever a 2 digit year will return. For
* standardised processing use getAdjustedDate().
*
* @return the resulting date
* @exception ParseException if the date string cannot be parsed.
*/
public Date getDate()
throws ParseException
{
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz");
return dateF.parse(getTime());
}
/**
* return the time as an adjusted date
* in the range of 1950 - 2049.
*
* @return a date in the range of 1950 to 2049.
* @exception ParseException if the date string cannot be parsed.
*/
public Date getAdjustedDate()
throws ParseException
{
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
return dateF.parse(getAdjustedTime());
}
/**
* return the time - always in the form of
* YYMMDDhhmmssGMT(+hh:mm|-hh:mm).
* <p>
* Normally in a certificate we would expect "Z" rather than "GMT",
* however adding the "GMT" means we can just use:
* <pre>
* dateF = new SimpleDateFormat("yyMMddHHmmssz");
* </pre>
* To read in the time and get a date which is compatible with our local
* time zone.
* <p>
* <b>Note:</b> In some cases, due to the local date processing, this
* may lead to unexpected results. If you want to stick the normal
* convention of 1950 to 2049 use the getAdjustedTime() method.
*/
public String getTime()
{
String stime = Strings.fromByteArray(time);
//
// standardise the format.
//
if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0)
{
if (stime.length() == 11)
{
return stime.substring(0, 10) + "00GMT+00:00";
}
else
{
return stime.substring(0, 12) + "GMT+00:00";
}
}
else
{
int index = stime.indexOf('-');
if (index < 0)
{
index = stime.indexOf('+');
}
String d = stime;
if (index == stime.length() - 3)
{
d += "00";
}
if (index == 10)
{
return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15);
}
else
{
return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17);
}
}
}
/**
* return a time string as an adjusted date with a 4 digit year. This goes
* in the range of 1950 - 2049.
*/
public String getAdjustedTime()
{
String d = this.getTime();
if (d.charAt(0) < '5')
{
return "20" + d;
}
else
{
return "19" + d;
}
}
boolean isConstructed()
{
return false;
}
int encodedLength()
{
int length = time.length;
return 1 + StreamUtil.calculateBodyLength(length) + length;
}
void encode(
ASN1OutputStream out)
throws IOException
{
out.write(BERTags.UTC_TIME);
int length = time.length;
out.writeLength(length);
for (int i = 0; i != length; i++)
{
out.write((byte)time[i]);
}
}
boolean asn1Equals(
ASN1Primitive o)
{
if (!(o instanceof DERUTCTime))
{
return false;
}
return Arrays.areEqual(time, ((DERUTCTime)o).time);
}
public int hashCode()
{
return Arrays.hashCode(time);
}
public String toString()
{
return Strings.fromByteArray(time);
}
// TODO: create proper DER encoding.
}

View File

@ -15,10 +15,12 @@ public class DERUTF8String
private byte[] string;
/**
* return an UTF8 string from the passed in object.
* Return an UTF8 string from the passed in object.
*
* @param obj a DERUTF8String or an object that can be converted into one.
* @exception IllegalArgumentException
* if the object cannot be converted.
* @return a DERUTF8String instance, or null
*/
public static DERUTF8String getInstance(Object obj)
{
@ -44,7 +46,7 @@ public class DERUTF8String
}
/**
* return an UTF8 String from a tagged object.
* Return an UTF8 String from a tagged object.
*
* @param obj
* the tagged object holding the object we want
@ -53,6 +55,7 @@ public class DERUTF8String
* otherwise.
* @exception IllegalArgumentException
* if the tagged object cannot be converted.
* @return a DERUTF8String instance, or null
*/
public static DERUTF8String getInstance(
ASN1TaggedObject obj,
@ -71,7 +74,7 @@ public class DERUTF8String
}
/**
* basic constructor - byte encoded string.
* Basic constructor - byte encoded string.
*/
DERUTF8String(byte[] string)
{
@ -79,7 +82,7 @@ public class DERUTF8String
}
/**
* basic constructor
* Basic constructor
*/
public DERUTF8String(String string)
{

View File

@ -18,7 +18,9 @@ public class DERUniversalString
/**
* return a Universal String from the passed in object.
*
* @param obj a DERUniversalString or an object that can be converted into one.
* @exception IllegalArgumentException if the object cannot be converted.
* @return a DERUniversalString instance, or null
*/
public static DERUniversalString getInstance(
Object obj)
@ -51,6 +53,7 @@ public class DERUniversalString
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return a DERUniversalString instance, or null
*/
public static DERUniversalString getInstance(
ASN1TaggedObject obj,

View File

@ -6,7 +6,10 @@ import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings;
/**
* DER VisibleString object.
* DER VisibleString object encoding ISO 646 (ASCII) character code points 32 to 126.
* <p>
* Explicit character set escape sequences are not allowed.
* </p>
*/
public class DERVisibleString
extends ASN1Primitive
@ -15,9 +18,11 @@ public class DERVisibleString
private byte[] string;
/**
* return a Visible String from the passed in object.
* Return a Visible String from the passed in object.
*
* @param obj a DERVisibleString or an object that can be converted into one.
* @exception IllegalArgumentException if the object cannot be converted.
* @return a DERVisibleString instance, or null
*/
public static DERVisibleString getInstance(
Object obj)
@ -43,13 +48,14 @@ public class DERVisibleString
}
/**
* return a Visible String from a tagged object.
* Return a Visible String from a tagged object.
*
* @param obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly
* tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot
* be converted.
* @return a DERVisibleString instance, or null
*/
public static DERVisibleString getInstance(
ASN1TaggedObject obj,
@ -68,7 +74,7 @@ public class DERVisibleString
}
/**
* basic constructor - byte encoded string.
* Basic constructor - byte encoded string.
*/
DERVisibleString(
byte[] string)
@ -77,7 +83,7 @@ public class DERVisibleString
}
/**
* basic constructor
* Basic constructor
*/
public DERVisibleString(
String string)

View File

@ -11,13 +11,13 @@ import java.util.Enumeration;
* <h3>8: Basic encoding rules</h3>
* <h4>8.11 Encoding of a set value </h4>
* <b>8.11.1</b> The encoding of a set value shall be constructed
* <p/>
* <p>
* <b>8.11.2</b> The contents octets shall consist of the complete
* encoding of a data value from each of the types listed in the
* ASN.1 definition of the set type, in an order chosen by the sender,
* unless the type was referenced with the keyword
* <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
* <p/>
* <p>
* <b>8.11.3</b> The encoding of a data value may, but need not,
* be present for a type which was referenced with the keyword
* <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.

View File

@ -2,8 +2,15 @@ package org.spongycastle.asn1;
import java.io.IOException;
/**
* Interface implemented by objects that can be converted from streaming to in-memory objects.
*/
public interface InMemoryRepresentable
{
/**
* Get the in-memory representation of the ASN.1 object.
* @throws IOException for bad input data.
*/
ASN1Primitive getLoadedObject()
throws IOException;
}

View File

@ -0,0 +1,35 @@
package org.spongycastle.asn1.bsi;
import org.spongycastle.asn1.ASN1ObjectIdentifier;
/**
* See https://www.bsi.bund.de/cae/servlet/contentblob/471398/publicationFile/30615/BSI-TR-03111_pdf.pdf
*/
public interface BSIObjectIdentifiers
{
static final ASN1ObjectIdentifier bsi_de = new ASN1ObjectIdentifier("0.4.0.127.0.7");
/* 0.4.0.127.0.7.1.1 */
static final ASN1ObjectIdentifier id_ecc = bsi_de.branch("1.1");
/* 0.4.0.127.0.7.1.1.4.1 */
static final ASN1ObjectIdentifier ecdsa_plain_signatures = id_ecc.branch("4.1");
/* 0.4.0.127.0.7.1.1.4.1.1 */
static final ASN1ObjectIdentifier ecdsa_plain_SHA1 = ecdsa_plain_signatures.branch("1");
/* 0.4.0.127.0.7.1.1.4.1.2 */
static final ASN1ObjectIdentifier ecdsa_plain_SHA224 = ecdsa_plain_signatures.branch("2");
/* 0.4.0.127.0.7.1.1.4.1.3 */
static final ASN1ObjectIdentifier ecdsa_plain_SHA256 = ecdsa_plain_signatures.branch("3");
/* 0.4.0.127.0.7.1.1.4.1.4 */
static final ASN1ObjectIdentifier ecdsa_plain_SHA384 = ecdsa_plain_signatures.branch("4");
/* 0.4.0.127.0.7.1.1.4.1.5 */
static final ASN1ObjectIdentifier ecdsa_plain_SHA512 = ecdsa_plain_signatures.branch("5");
/* 0.4.0.127.0.7.1.1.4.1.6 */
static final ASN1ObjectIdentifier ecdsa_plain_RIPEMD160 = ecdsa_plain_signatures.branch("6");
}

View File

@ -4,13 +4,13 @@ import java.util.Enumeration;
import org.spongycastle.asn1.ASN1Encodable;
import org.spongycastle.asn1.ASN1EncodableVector;
import org.spongycastle.asn1.ASN1GeneralizedTime;
import org.spongycastle.asn1.ASN1Integer;
import org.spongycastle.asn1.ASN1Object;
import org.spongycastle.asn1.ASN1OctetString;
import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.DERGeneralizedTime;
import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.DERTaggedObject;
import org.spongycastle.asn1.x500.X500Name;
@ -31,7 +31,7 @@ public class PKIHeader
private ASN1Integer pvno;
private GeneralName sender;
private GeneralName recipient;
private DERGeneralizedTime messageTime;
private ASN1GeneralizedTime messageTime;
private AlgorithmIdentifier protectionAlg;
private ASN1OctetString senderKID; // KeyIdentifier
private ASN1OctetString recipKID; // KeyIdentifier
@ -56,7 +56,7 @@ public class PKIHeader
switch (tObj.getTagNo())
{
case 0:
messageTime = DERGeneralizedTime.getInstance(tObj, true);
messageTime = ASN1GeneralizedTime.getInstance(tObj, true);
break;
case 1:
protectionAlg = AlgorithmIdentifier.getInstance(tObj, true);
@ -136,7 +136,7 @@ public class PKIHeader
return recipient;
}
public DERGeneralizedTime getMessageTime()
public ASN1GeneralizedTime getMessageTime()
{
return messageTime;
}

View File

@ -6,7 +6,6 @@ import org.spongycastle.asn1.ASN1GeneralizedTime;
import org.spongycastle.asn1.ASN1Integer;
import org.spongycastle.asn1.ASN1OctetString;
import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.DERGeneralizedTime;
import org.spongycastle.asn1.DEROctetString;
import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.DERTaggedObject;
@ -46,16 +45,6 @@ public class PKIHeaderBuilder
this.recipient = recipient;
}
/**
* @deprecated use ASN1GeneralizedTime
*/
public PKIHeaderBuilder setMessageTime(DERGeneralizedTime time)
{
messageTime = ASN1GeneralizedTime.getInstance(time);
return this;
}
public PKIHeaderBuilder setMessageTime(ASN1GeneralizedTime time)
{
messageTime = time;

View File

@ -7,7 +7,6 @@ import org.spongycastle.asn1.ASN1ObjectIdentifier;
import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.ASN1Set;
import org.spongycastle.asn1.DERObjectIdentifier;
import org.spongycastle.asn1.DERSequence;
/**
@ -73,17 +72,6 @@ public class Attribute
attrValues = (ASN1Set)seq.getObjectAt(1);
}
/**
* @deprecated use ASN1ObjectIdentifier
*/
public Attribute(
DERObjectIdentifier attrType,
ASN1Set attrValues)
{
this.attrType = new ASN1ObjectIdentifier(attrType.getId());
this.attrValues = attrValues;
}
public Attribute(
ASN1ObjectIdentifier attrType,
ASN1Set attrValues)

View File

@ -8,7 +8,6 @@ import org.spongycastle.asn1.ASN1Encodable;
import org.spongycastle.asn1.ASN1EncodableVector;
import org.spongycastle.asn1.ASN1ObjectIdentifier;
import org.spongycastle.asn1.ASN1Set;
import org.spongycastle.asn1.DERObjectIdentifier;
import org.spongycastle.asn1.DERSet;
/**
@ -90,14 +89,6 @@ public class AttributeTable
}
}
/**
* @deprecated use ASN1ObjectIdentifier
*/
public Attribute get(DERObjectIdentifier oid)
{
return get(new ASN1ObjectIdentifier(oid.getId()));
}
/**
* Return the first attribute matching the OBJECT IDENTIFIER oid.
*
@ -117,14 +108,6 @@ public class AttributeTable
return (Attribute)value;
}
/**
* @deprecated use ASN1ObjectIdentifier
*/
public ASN1EncodableVector getAll(DERObjectIdentifier oid)
{
return getAll(new ASN1ObjectIdentifier(oid.getId()));
}
/**
* Return all the attributes matching the OBJECT IDENTIFIER oid. The vector will be
* empty if there are no attributes of the required type present.

View File

@ -1,12 +1,12 @@
package org.spongycastle.asn1.cms;
import org.spongycastle.asn1.ASN1EncodableVector;
import org.spongycastle.asn1.ASN1GeneralizedTime;
import org.spongycastle.asn1.ASN1Object;
import org.spongycastle.asn1.ASN1OctetString;
import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.DERGeneralizedTime;
import org.spongycastle.asn1.DEROctetString;
import org.spongycastle.asn1.DERSequence;
@ -28,12 +28,12 @@ public class RecipientKeyIdentifier
extends ASN1Object
{
private ASN1OctetString subjectKeyIdentifier;
private DERGeneralizedTime date;
private ASN1GeneralizedTime date;
private OtherKeyAttribute other;
public RecipientKeyIdentifier(
ASN1OctetString subjectKeyIdentifier,
DERGeneralizedTime date,
ASN1GeneralizedTime date,
OtherKeyAttribute other)
{
this.subjectKeyIdentifier = subjectKeyIdentifier;
@ -43,7 +43,7 @@ public class RecipientKeyIdentifier
public RecipientKeyIdentifier(
byte[] subjectKeyIdentifier,
DERGeneralizedTime date,
ASN1GeneralizedTime date,
OtherKeyAttribute other)
{
this.subjectKeyIdentifier = new DEROctetString(subjectKeyIdentifier);
@ -71,9 +71,9 @@ public class RecipientKeyIdentifier
case 1:
break;
case 2:
if (seq.getObjectAt(1) instanceof DERGeneralizedTime)
if (seq.getObjectAt(1) instanceof ASN1GeneralizedTime)
{
date = (DERGeneralizedTime)seq.getObjectAt(1);
date = ASN1GeneralizedTime.getInstance(seq.getObjectAt(1));
}
else
{
@ -81,7 +81,7 @@ public class RecipientKeyIdentifier
}
break;
case 3:
date = (DERGeneralizedTime)seq.getObjectAt(1);
date = ASN1GeneralizedTime.getInstance(seq.getObjectAt(1));
other = OtherKeyAttribute.getInstance(seq.getObjectAt(2));
break;
default:
@ -136,7 +136,7 @@ public class RecipientKeyIdentifier
return subjectKeyIdentifier;
}
public DERGeneralizedTime getDate()
public ASN1GeneralizedTime getDate()
{
return date;
}

View File

@ -3,12 +3,15 @@ package org.spongycastle.asn1.cms;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.SimpleTimeZone;
import org.spongycastle.asn1.ASN1Choice;
import org.spongycastle.asn1.ASN1GeneralizedTime;
import org.spongycastle.asn1.ASN1Object;
import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.ASN1UTCTime;
import org.spongycastle.asn1.DERGeneralizedTime;
import org.spongycastle.asn1.DERUTCTime;
@ -47,8 +50,8 @@ public class Time
public Time(
ASN1Primitive time)
{
if (!(time instanceof DERUTCTime)
&& !(time instanceof DERGeneralizedTime))
if (!(time instanceof ASN1UTCTime)
&& !(time instanceof ASN1GeneralizedTime))
{
throw new IllegalArgumentException("unknown object passed to Time");
}
@ -57,28 +60,61 @@ public class Time
}
/**
* Create a time object from a given date - if the year is in between 1950
* 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.
*
* @param time a date object representing the time of interest.
*/
public Time(
Date date)
Date time)
{
SimpleTimeZone tz = new SimpleTimeZone(0, "Z");
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss");
dateF.setTimeZone(tz);
String d = dateF.format(date) + "Z";
String d = dateF.format(time) + "Z";
int year = Integer.parseInt(d.substring(0, 4));
if (year < 1950 || year > 2049)
{
time = new DERGeneralizedTime(d);
this.time = new DERGeneralizedTime(d);
}
else
{
time = new DERUTCTime(d.substring(2));
this.time = new DERUTCTime(d.substring(2));
}
}
/**
* Creates a time object from a given date and locale - if the date is between 1950
* and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
* is used. You may need to use this constructor if the default locale
* doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations.
*
* @param time a date object representing the time of interest.
* @param locale an appropriate Locale for producing an ASN.1 GeneralizedTime value.
*/
public Time(
Date time,
Locale locale)
{
SimpleTimeZone tz = new SimpleTimeZone(0, "Z");
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss", locale);
dateF.setTimeZone(tz);
String d = dateF.format(time) + "Z";
int year = Integer.parseInt(d.substring(0, 4));
if (year < 1950 || year > 2049)
{
this.time = new DERGeneralizedTime(d);
}
else
{
this.time = new DERUTCTime(d.substring(2));
}
}
@ -103,13 +139,13 @@ public class Time
{
return (Time)obj;
}
else if (obj instanceof DERUTCTime)
else if (obj instanceof ASN1UTCTime)
{
return new Time((DERUTCTime)obj);
return new Time((ASN1UTCTime)obj);
}
else if (obj instanceof DERGeneralizedTime)
else if (obj instanceof ASN1GeneralizedTime)
{
return new Time((DERGeneralizedTime)obj);
return new Time((ASN1GeneralizedTime)obj);
}
throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
@ -120,13 +156,13 @@ public class Time
*/
public String getTime()
{
if (time instanceof DERUTCTime)
if (time instanceof ASN1UTCTime)
{
return ((DERUTCTime)time).getAdjustedTime();
return ((ASN1UTCTime)time).getAdjustedTime();
}
else
{
return ((DERGeneralizedTime)time).getTime();
return ((ASN1GeneralizedTime)time).getTime();
}
}
@ -137,13 +173,13 @@ public class Time
{
try
{
if (time instanceof DERUTCTime)
if (time instanceof ASN1UTCTime)
{
return ((DERUTCTime)time).getAdjustedDate();
return ((ASN1UTCTime)time).getAdjustedDate();
}
else
{
return ((DERGeneralizedTime)time).getDate();
return ((ASN1GeneralizedTime)time).getDate();
}
}
catch (ParseException e)

View File

@ -6,8 +6,8 @@ import java.util.Hashtable;
import org.spongycastle.asn1.ASN1ObjectIdentifier;
import org.spongycastle.crypto.params.ECDomainParameters;
import org.spongycastle.math.ec.ECConstants;
import org.spongycastle.math.ec.ECCurve;
import org.spongycastle.math.ec.ECPoint;
/**
* table of the available named parameters for GOST 3410-2001.
@ -26,7 +26,9 @@ public class ECGOST3410NamedCurves
ECCurve.Fp curve = new ECCurve.Fp(
mod_p, // p
new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), // a
new BigInteger("166")); // b
new BigInteger("166"), // b
mod_q,
ECConstants.ONE);
ECDomainParameters ecParams = new ECDomainParameters(
curve,
@ -43,7 +45,9 @@ public class ECGOST3410NamedCurves
curve = new ECCurve.Fp(
mod_p, // p
new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"),
new BigInteger("166"));
new BigInteger("166"),
mod_q,
ECConstants.ONE);
ecParams = new ECDomainParameters(
curve,
@ -60,7 +64,9 @@ public class ECGOST3410NamedCurves
curve = new ECCurve.Fp(
mod_p, // p
new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823190"), // a
new BigInteger("28091019353058090096996979000309560759124368558014865957655842872397301267595")); // b
new BigInteger("28091019353058090096996979000309560759124368558014865957655842872397301267595"), // b
mod_q,
ECConstants.ONE);
ecParams = new ECDomainParameters(
curve,
@ -77,7 +83,9 @@ public class ECGOST3410NamedCurves
curve = new ECCurve.Fp(
mod_p, // p
new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"),
new BigInteger("32858"));
new BigInteger("32858"),
mod_q,
ECConstants.ONE);
ecParams = new ECDomainParameters(
curve,
@ -93,7 +101,9 @@ public class ECGOST3410NamedCurves
curve = new ECCurve.Fp(
mod_p, // p
new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), // a
new BigInteger("32858")); // b
new BigInteger("32858"), // b
mod_q,
ECConstants.ONE);
ecParams = new ECDomainParameters(
curve,

View File

@ -15,7 +15,6 @@ import org.spongycastle.asn1.DEROctetString;
/**
* an iso7816Certificate structure.
* <p/>
* <pre>
* Certificate ::= SEQUENCE {
* CertificateBody Iso7816CertificateBody,
@ -85,7 +84,6 @@ public class CVCertificate
* Create an iso7816Certificate structure from an ASN1InputStream.
*
* @param aIS the byte stream to parse.
* @return the Iso7816CertificateStructure represented by the byte stream.
* @throws IOException if there is a problem parsing the data.
*/
public CVCertificate(ASN1InputStream aIS)
@ -129,7 +127,6 @@ public class CVCertificate
*
* @param body the Iso7816CertificateBody object containing the body.
* @param signature the byte array containing the signature
* @return the Iso7816CertificateStructure
* @throws IOException if there is a problem parsing the data.
*/
public CVCertificate(CertificateBody body, byte[] signature)
@ -147,7 +144,6 @@ public class CVCertificate
*
* @param obj the Object to extract the certificate from.
* @return the Iso7816CertificateStructure represented by the byte stream.
* @throws IOException if there is a problem parsing the data.
*/
public static CVCertificate getInstance(Object obj)
{

View File

@ -13,7 +13,6 @@ import org.spongycastle.asn1.DEROctetString;
/**
* an Iso7816CertificateBody structure.
* <p/>
* <pre>
* CertificateBody ::= SEQUENCE {
* // version of the certificate format. Must be 0 (version 1)
@ -128,7 +127,6 @@ public class CertificateBody
* @param certificateHolderAuthorization
* @param certificateEffectiveDate
* @param certificateExpirationDate
* @throws IOException
*/
public CertificateBody(
DERApplicationSpecific certificateProfileIdentifier,
@ -276,7 +274,6 @@ public class CertificateBody
* create a "request" or "profile" type Iso7816CertificateBody according to the variables sets.
*
* @return return the ASN1Primitive representing the "request" or "profile" type certificate body.
* @throws IOException if the DERApplicationSpecific cannot be created or if data are missings to create a valid certificate.
*/
public ASN1Primitive toASN1Primitive()
{

View File

@ -13,7 +13,6 @@ import org.spongycastle.util.Integers;
/**
* an Iso7816CertificateHolderAuthorization structure.
* <p/>
* <pre>
* Certificate Holder Authorization ::= SEQUENCE {
* // specifies the format and the rules for the evaluation of the authorization

View File

@ -4,17 +4,17 @@ import org.spongycastle.asn1.ASN1ObjectIdentifier;
/**
* German Federal Office for Information Security
* (Bundesamt für Sicherheit in der Informationstechnik)
* (Bundesamt f&uuml;r Sicherheit in der Informationstechnik)
* <a href="http://www.bsi.bund.de/">http://www.bsi.bund.de/</a>
* <p>
* <a href="https://www.bsi.bund.de/EN/Publications/TechnicalGuidelines/TR03110/BSITR03110.html">BSI TR-03110</a>
* Technical Guideline Advanced Security Mechanisms for Machine Readable Travel Documents
* <p>
* <a href="https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03110/TR-03110_v2.1_P3pdf.pdf?__blob=publicationFile">Technical Guideline TR-03110-3</a>
* <a href="https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03110/TR-03110_v2.1_P3pdf.pdf">
* Technical Guideline TR-03110-3</a>
* Advanced Security Mechanisms for Machine Readable Travel Documents;
* Part 3: Common Specifications.
*/
public interface EACObjectIdentifiers
{
/**

View File

@ -15,7 +15,6 @@ import org.spongycastle.asn1.DERTaggedObject;
/**
* an Iso7816ECDSAPublicKeyStructure structure.
* <p/>
* <pre>
* Certificate Holder Authorization ::= SEQUENCE {
* ASN1TaggedObject primeModulusP; // OPTIONAL

View File

@ -3,6 +3,7 @@ package org.spongycastle.asn1.eac;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.SimpleTimeZone;
import org.spongycastle.util.Arrays;
@ -21,7 +22,9 @@ public class PackedDate
}
/**
* base constructer from a java.util.date object
* Base constructor from a java.util.date object.
*
* @param time a date object representing the time of interest.
*/
public PackedDate(
Date time)
@ -33,6 +36,24 @@ public class PackedDate
this.time = convert(dateF.format(time));
}
/**
* Base constructor from a java.util.date object. You may need to use this constructor if the default locale
* doesn't use a Gregorian calender so that the PackedDate produced is compatible with other ASN.1 implementations.
*
* @param time a date object representing the time of interest.
* @param locale an appropriate Locale for producing an ASN.1 GeneralizedTime value.
*/
public PackedDate(
Date time,
Locale locale)
{
SimpleDateFormat dateF = new SimpleDateFormat("yyMMdd'Z'", locale);
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
this.time = convert(dateF.format(time));
}
private byte[] convert(String sTime)
{
char[] digs = sTime.toCharArray();

View File

@ -12,7 +12,6 @@ import org.spongycastle.asn1.DERSequence;
/**
* an Iso7816RSAPublicKeyStructure structure.
* <p/>
* <pre>
* Certificate Holder Authorization ::= SEQUENCE {
* // modulus should be at least 1024bit and a multiple of 512.

View File

@ -6,7 +6,6 @@ import org.spongycastle.asn1.ASN1Object;
import org.spongycastle.asn1.ASN1ObjectIdentifier;
import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.DERObjectIdentifier;
import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.DERUTF8String;
@ -47,25 +46,6 @@ public class ContentHints
}
}
/**
* @deprecated use ASN1ObjectIdentifier
*/
public ContentHints(
DERObjectIdentifier contentType)
{
this(new ASN1ObjectIdentifier(contentType.getId()));
}
/**
* @deprecated use ASN1ObjectIdentifier
*/
public ContentHints(
DERObjectIdentifier contentType,
DERUTF8String contentDescription)
{
this(new ASN1ObjectIdentifier(contentType.getId()), contentDescription);
}
public ContentHints(
ASN1ObjectIdentifier contentType)
{

View File

@ -13,7 +13,7 @@ import org.spongycastle.asn1.x509.Certificate;
/**
* The CscaMasterList object. This object can be wrapped in a
* CMSSignedData to be published in LDAP.
* <p/>
*
* <pre>
* CscaMasterList ::= SEQUENCE {
* version CscaMasterListVersion,

View File

@ -19,8 +19,6 @@ import org.spongycastle.asn1.x509.AlgorithmIdentifier;
* the expiry of the corresponding certificate. Hence, clients MUST support this
* extension. If a positive statement of availability is to be delivered, this
* extension syntax and OID MUST be used.
* <p/>
* <p/>
* <pre>
* CertHash ::= SEQUENCE {
* hashAlgorithm AlgorithmIdentifier,
@ -102,9 +100,8 @@ public class CertHash
/**
* Produce an object suitable for an ASN1OutputStream.
* <p/>
* <p>
* Returns:
* <p/>
* <pre>
* CertHash ::= SEQUENCE {
* hashAlgorithm AlgorithmIdentifier,

View File

@ -16,7 +16,7 @@ import org.spongycastle.asn1.x509.Certificate;
* ISIS-MTT-Optional: The certificate requested by the client by inserting the
* RetrieveIfAllowed extension in the request, will be returned in this
* extension.
* <p/>
* <p>
* ISIS-MTT-SigG: The signature act allows publishing certificates only then,
* when the certificate owner gives his explicit permission. Accordingly, there
* may be <EFBFBD>nondownloadable<EFBFBD> certificates, about which the responder must provide
@ -36,7 +36,6 @@ import org.spongycastle.asn1.x509.Certificate;
* Clients requesting RetrieveIfAllowed MUST be able to handle these cases. If
* any of the OCTET STRING options is used, it MUST contain the DER encoding of
* the requested certificate.
* <p/>
* <pre>
* RequestedCertificate ::= CHOICE {
* Certificate Certificate,
@ -105,7 +104,7 @@ public class RequestedCertificate
/**
* Constructor from a given details.
* <p/>
* <p>
* Only one parameter can be given. All other must be <code>null</code>.
*
* @param certificate Given as Certificate
@ -155,9 +154,8 @@ public class RequestedCertificate
/**
* Produce an object suitable for an ASN1OutputStream.
* <p/>
* <p>
* Returns:
* <p/>
* <pre>
* RequestedCertificate ::= CHOICE {
* Certificate Certificate,

View File

@ -54,9 +54,8 @@ public class AdditionalInformationSyntax
/**
* Produce an object suitable for an ASN1OutputStream.
* <p/>
* <p>
* Returns:
* <p/>
* <pre>
* AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
* </pre>

View File

@ -11,28 +11,28 @@ import org.spongycastle.asn1.x509.GeneralName;
/**
* Attribute to indicate admissions to certain professions.
* <p/>
*
* <pre>
* AdmissionSyntax ::= SEQUENCE
* {
* admissionAuthority GeneralName OPTIONAL,
* contentsOfAdmissions SEQUENCE OF Admissions
* }
* <p/>
*
* Admissions ::= SEQUENCE
* {
* admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
* namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
* professionInfos SEQUENCE OF ProfessionInfo
* }
* <p/>
*
* NamingAuthority ::= SEQUENCE
* {
* namingAuthorityId OBJECT IDENTIFIER OPTIONAL,
* namingAuthorityUrl IA5String OPTIONAL,
* namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
* }
* <p/>
*
* ProfessionInfo ::= SEQUENCE
* {
* namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
@ -42,8 +42,7 @@ import org.spongycastle.asn1.x509.GeneralName;
* addProfessionInfo OCTET STRING OPTIONAL
* }
* </pre>
* <p/>
* <p/>
* <p>
* ISIS-MTT PROFILE: The relatively complex structure of AdmissionSyntax
* supports the following concepts and requirements:
* <ul>
@ -68,7 +67,7 @@ import org.spongycastle.asn1.x509.GeneralName;
* component namingAuthorityId are grouped under the OID-branch
* id-isis-at-namingAuthorities and must be applied for.
* <li>See
* http://www.teletrust.de/anwend.asp?Id=30200&Sprache=E_&HomePG=0 for
* http://www.teletrust.de/anwend.asp?Id=30200&amp;Sprache=E_&amp;HomePG=0 for
* an application form and http://www.teletrust.de/links.asp?id=30220,11
* for an overview of registered naming authorities.
* <li> By means of the data type ProfessionInfo certain professions,
@ -80,7 +79,7 @@ import org.spongycastle.asn1.x509.GeneralName;
* addProfessionInfo may contain additional applicationspecific information in
* DER-encoded form.
* </ul>
* <p/>
* <p>
* By means of different namingAuthority-OIDs or profession OIDs hierarchies of
* professions, specializations, disciplines, fields of activity, etc. can be
* expressed. The issuing admission authority should always be indicated (field
@ -89,9 +88,7 @@ import org.spongycastle.asn1.x509.GeneralName;
* naming authority by the exclusive use of the component professionItems. In
* this case the certification authority is responsible for the verification of
* the admission information.
* <p/>
* <p/>
* <p/>
* <p>
* This attribute is single-valued. Still, several admissions can be captured in
* the sequence structure of the component contentsOfAdmissions of
* AdmissionSyntax or in the component professionInfos of Admissions. The
@ -102,7 +99,7 @@ import org.spongycastle.asn1.x509.GeneralName;
* value for the component namingAuthority of ProfessionInfo. Within the latter
* component the default value can be overwritten, in case that another naming
* authority needs to be recorded.
* <p/>
* <p>
* The length of the string objects is limited to 128 characters. It is
* recommended to indicate a namingAuthorityURL in all issued attribute
* certificates. If a namingAuthorityURL is indicated, the field professionItems
@ -209,30 +206,29 @@ public class AdmissionSyntax
/**
* Produce an object suitable for an ASN1OutputStream.
* <p/>
* <p>
* Returns:
* <p/>
* <pre>
* AdmissionSyntax ::= SEQUENCE
* {
* admissionAuthority GeneralName OPTIONAL,
* contentsOfAdmissions SEQUENCE OF Admissions
* }
* <p/>
*
* Admissions ::= SEQUENCE
* {
* admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
* namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
* professionInfos SEQUENCE OF ProfessionInfo
* }
* <p/>
*
* NamingAuthority ::= SEQUENCE
* {
* namingAuthorityId OBJECT IDENTIFIER OPTIONAL,
* namingAuthorityUrl IA5String OPTIONAL,
* namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
* }
* <p/>
*
* ProfessionInfo ::= SEQUENCE
* {
* namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,

View File

@ -14,7 +14,6 @@ import org.spongycastle.asn1.x509.GeneralName;
/**
* An Admissions structure.
* <p/>
* <pre>
* Admissions ::= SEQUENCE
* {
@ -22,7 +21,6 @@ import org.spongycastle.asn1.x509.GeneralName;
* namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
* professionInfos SEQUENCE OF ProfessionInfo
* }
* <p/>
* </pre>
*
* @see org.spongycastle.asn1.isismtt.x509.AdmissionSyntax
@ -117,7 +115,7 @@ public class Admissions
/**
* Constructor from a given details.
* <p/>
* <p>
* Parameter <code>professionInfos</code> is mandatory.
*
* @param admissionAuthority The admission authority.
@ -155,9 +153,8 @@ public class Admissions
/**
* Produce an object suitable for an ASN1OutputStream.
* <p/>
* <p>
* Returns:
* <p/>
* <pre>
* Admissions ::= SEQUENCE
* {
@ -165,7 +162,6 @@ public class Admissions
* namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
* professionInfos SEQUENCE OF ProfessionInfo
* }
* <p/>
* </pre>
*
* @return an ASN1Primitive

View File

@ -15,7 +15,7 @@ import org.spongycastle.asn1.DERTaggedObject;
/**
* A declaration of majority.
* <p/>
*
* <pre>
* DeclarationOfMajoritySyntax ::= CHOICE
* {
@ -28,7 +28,7 @@ import org.spongycastle.asn1.DERTaggedObject;
* dateOfBirth [2] IMPLICIT GeneralizedTime
* }
* </pre>
* <p/>
* <p>
* fullAgeAtCountry indicates the majority of the owner with respect to the laws
* of a specific country.
*/
@ -101,9 +101,8 @@ public class DeclarationOfMajority
/**
* Produce an object suitable for an ASN1OutputStream.
* <p/>
* <p>
* Returns:
* <p/>
* <pre>
* DeclarationOfMajoritySyntax ::= CHOICE
* {

View File

@ -17,11 +17,10 @@ import org.spongycastle.asn1.DERSequence;
* since January 1, 2004. For the sake of backward compatibility with
* certificates already in use, components SHOULD support MonetaryLimit (as well
* as QcEuLimitValue).
* <p/>
* <p>
* Indicates a monetary limit within which the certificate holder is authorized
* to act. (This value DOES NOT express a limit on the liability of the
* certification authority).
* <p/>
* <pre>
* MonetaryLimitSyntax ::= SEQUENCE
* {
@ -30,9 +29,9 @@ import org.spongycastle.asn1.DERSequence;
* exponent INTEGER
* }
* </pre>
* <p/>
* <p>
* currency must be the ISO code.
* <p/>
* <p>
* value = amount<EFBFBD>10*exponent
*/
public class MonetaryLimit
@ -72,8 +71,7 @@ public class MonetaryLimit
/**
* Constructor from a given details.
* <p/>
* <p/>
* <p>
* value = amount<EFBFBD>10^exponent
*
* @param currency The currency. Must be the ISO code.
@ -104,9 +102,8 @@ public class MonetaryLimit
/**
* Produce an object suitable for an ASN1OutputStream.
* <p/>
* <p>
* Returns:
* <p/>
* <pre>
* MonetaryLimitSyntax ::= SEQUENCE
* {

View File

@ -11,7 +11,6 @@ import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.ASN1String;
import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.DERIA5String;
import org.spongycastle.asn1.DERObjectIdentifier;
import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.isismtt.ISISMTTObjectIdentifiers;
import org.spongycastle.asn1.x500.DirectoryString;
@ -175,25 +174,7 @@ public class NamingAuthority
/**
* Constructor from given details.
* <p/>
* All parameters can be combined.
*
* @param namingAuthorityId ObjectIdentifier for naming authority.
* @param namingAuthorityUrl URL for naming authority.
* @param namingAuthorityText Textual representation of naming authority.
* @deprecated use ASN1ObjectIdentifier method
*/
public NamingAuthority(DERObjectIdentifier namingAuthorityId,
String namingAuthorityUrl, DirectoryString namingAuthorityText)
{
this.namingAuthorityId = new ASN1ObjectIdentifier(namingAuthorityId.getId());
this.namingAuthorityUrl = namingAuthorityUrl;
this.namingAuthorityText = namingAuthorityText;
}
/**
* Constructor from given details.
* <p/>
* <p>
* All parameters can be combined.
*
* @param namingAuthorityId ObjectIdentifier for naming authority.
@ -210,9 +191,8 @@ public class NamingAuthority
/**
* Produce an object suitable for an ASN1OutputStream.
* <p/>
* <p>
* Returns:
* <p/>
* <pre>
* NamingAuthority ::= SEQUENCE
* {

View File

@ -132,8 +132,7 @@ public class ProcurationSyntax
/**
* Constructor from a given details.
* <p/>
* <p/>
* <p>
* Either <code>generalName</code> or <code>certRef</code> MUST be
* <code>null</code>.
*
@ -154,8 +153,7 @@ public class ProcurationSyntax
/**
* Constructor from a given details.
* <p/>
* <p/>
* <p>
* Either <code>generalName</code> or <code>certRef</code> MUST be
* <code>null</code>.
*
@ -196,16 +194,15 @@ public class ProcurationSyntax
/**
* Produce an object suitable for an ASN1OutputStream.
* <p/>
* <p>
* Returns:
* <p/>
* <pre>
* ProcurationSyntax ::= SEQUENCE {
* country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
* typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
* signingFor [3] EXPLICIT SigningFor
* }
* <p/>
*
* SigningFor ::= CHOICE
* {
* thirdPerson GeneralName,

View File

@ -274,7 +274,7 @@ public class ProfessionInfo
/**
* Constructor from given details.
* <p/>
* <p>
* <code>professionItems</code> is mandatory, all other parameters are
* optional.
*
@ -311,9 +311,8 @@ public class ProfessionInfo
/**
* Produce an object suitable for an ASN1OutputStream.
* <p/>
* <p>
* Returns:
* <p/>
* <pre>
* ProfessionInfo ::= SEQUENCE
* {

View File

@ -6,7 +6,7 @@ import org.spongycastle.asn1.x500.DirectoryString;
/**
* Some other restriction regarding the usage of this certificate.
* <p/>
*
* <pre>
* RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
* </pre>
@ -64,12 +64,10 @@ public class Restriction
/**
* Produce an object suitable for an ASN1OutputStream.
* <p/>
* <p>
* Returns:
* <p/>
* <pre>
* RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
* <p/>
* </pre>
*
* @return a DERObject

View File

@ -36,7 +36,7 @@ public interface MiscObjectIdentifiers
/** Verisign CZAG (Country,Zip,Age,Gender) Extension OID: 2.16.840.1.113733.1.6.3 */
static final ASN1ObjectIdentifier verisignCzagExtension = verisign.branch("6.3");
/** Verisign D&B D-U-N-S number Extension OID: 2.16.840.1.113733.1.6.15 */
/** Verisign D&amp;B D-U-N-S number Extension OID: 2.16.840.1.113733.1.6.15 */
static final ASN1ObjectIdentifier verisignDnbDunsNumber = verisign.branch("6.15");
//

View File

@ -9,7 +9,6 @@ import org.spongycastle.asn1.ASN1Object;
import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.DERGeneralizedTime;
import org.spongycastle.asn1.DERIA5String;
import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.DERTaggedObject;
@ -39,7 +38,7 @@ public class CrlID
crlNum = ASN1Integer.getInstance(o, true);
break;
case 2:
crlTime = DERGeneralizedTime.getInstance(o, true);
crlTime = ASN1GeneralizedTime.getInstance(o, true);
break;
default:
throw new IllegalArgumentException(

View File

@ -7,7 +7,6 @@ import org.spongycastle.asn1.ASN1Object;
import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.DERGeneralizedTime;
import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.DERTaggedObject;
import org.spongycastle.asn1.x509.Extensions;
@ -49,7 +48,7 @@ public class ResponseData
*/
public ResponseData(
ResponderID responderID,
DERGeneralizedTime producedAt,
ASN1GeneralizedTime producedAt,
ASN1Sequence responses,
X509Extensions responseExtensions)
{

View File

@ -6,7 +6,6 @@ import org.spongycastle.asn1.ASN1Object;
import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.DERGeneralizedTime;
import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.DERTaggedObject;
import org.spongycastle.asn1.x509.Extensions;
@ -32,31 +31,13 @@ public class SingleResponse
public SingleResponse(
CertID certID,
CertStatus certStatus,
DERGeneralizedTime thisUpdate,
DERGeneralizedTime nextUpdate,
ASN1GeneralizedTime thisUpdate,
ASN1GeneralizedTime nextUpdate,
X509Extensions singleExtensions)
{
this(certID, certStatus, thisUpdate, nextUpdate, Extensions.getInstance(singleExtensions));
}
/**
* @deprecated use method taking ASN1GeneralizedTime and Extensions
* @param certID
* @param certStatus
* @param thisUpdate
* @param nextUpdate
* @param singleExtensions
*/
public SingleResponse(
CertID certID,
CertStatus certStatus,
DERGeneralizedTime thisUpdate,
DERGeneralizedTime nextUpdate,
Extensions singleExtensions)
{
this(certID, certStatus, ASN1GeneralizedTime.getInstance(thisUpdate), ASN1GeneralizedTime.getInstance(nextUpdate), Extensions.getInstance(singleExtensions));
}
public SingleResponse(
CertID certID,
CertStatus certStatus,

View File

@ -23,7 +23,7 @@ public class ElGamalParameter
this.g = new ASN1Integer(g);
}
public ElGamalParameter(
private ElGamalParameter(
ASN1Sequence seq)
{
Enumeration e = seq.getObjects();
@ -32,6 +32,20 @@ public class ElGamalParameter
g = (ASN1Integer)e.nextElement();
}
public static ElGamalParameter getInstance(Object o)
{
if (o instanceof ElGamalParameter)
{
return (ElGamalParameter)o;
}
else if (o != null)
{
return new ElGamalParameter(ASN1Sequence.getInstance(o));
}
return null;
}
public BigInteger getP()
{
return p.getPositiveValue();

View File

@ -56,19 +56,19 @@ public class CRLBag
/**
* <pre>
CRLBag ::= SEQUENCE {
crlId BAG-TYPE.&id ({CRLTypes}),
crlValue [0] EXPLICIT BAG-TYPE.&Type ({CRLTypes}{@crlId})
}
x509CRL BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1}
-- DER-encoded X.509 CRL stored in OCTET STRING
CRLTypes BAG-TYPE ::= {
x509CRL,
... -- For future extensions
}
</pre>
* CRLBag ::= SEQUENCE {
* crlId BAG-TYPE.&amp;id ({CRLTypes}),
* crlValue [0] EXPLICIT BAG-TYPE.&amp;Type ({CRLTypes}{@crlId})
* }
*
* x509CRL BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1}
* -- DER-encoded X.509 CRL stored in OCTET STRING
*
* CRLTypes BAG-TYPE ::= {
* x509CRL,
* ... -- For future extensions
* }
* </pre>
*/
public ASN1Primitive toASN1Primitive()
{

View File

@ -25,8 +25,8 @@ import org.spongycastle.asn1.x509.X509Name;
* Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
*
* Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
* type ATTRIBUTE.&id({IOSet}),
* values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
* type ATTRIBUTE.&amp;id({IOSet}),
* values SET SIZE(1..MAX) OF ATTRIBUTE.&amp;Type({IOSet}{\@type})
* }
* </pre>
*/

View File

@ -25,7 +25,7 @@ public class EncryptionScheme
this.algId = AlgorithmIdentifier.getInstance(seq);
}
public static final EncryptionScheme getInstance(Object obj)
public static EncryptionScheme getInstance(Object obj)
{
if (obj instanceof EncryptionScheme)
{

View File

@ -25,7 +25,7 @@ public class KeyDerivationFunc
this.algId = AlgorithmIdentifier.getInstance(seq);
}
public static final KeyDerivationFunc getInstance(Object obj)
public static KeyDerivationFunc getInstance(Object obj)
{
if (obj instanceof KeyDerivationFunc)
{

View File

@ -68,7 +68,7 @@ public class PrivateKeyInfo
}
/**
* @deprectaed use PrivateKeyInfo.getInstance()
* @deprecated use PrivateKeyInfo.getInstance()
* @param seq
*/
public PrivateKeyInfo(

View File

@ -10,6 +10,8 @@ import org.spongycastle.asn1.x9.X9ECParametersHolder;
import org.spongycastle.math.ec.ECConstants;
import org.spongycastle.math.ec.ECCurve;
import org.spongycastle.math.ec.ECPoint;
import org.spongycastle.math.ec.endo.GLVTypeBEndomorphism;
import org.spongycastle.math.ec.endo.GLVTypeBParameters;
import org.spongycastle.util.Strings;
import org.spongycastle.util.encoders.Hex;
@ -17,19 +19,14 @@ public class SECNamedCurves
{
private static ECCurve configureCurve(ECCurve curve)
{
// int coord = ECCurve.COORD_JACOBIAN_MODIFIED;
//
// if (curve.getCoordinateSystem() != coord && curve.supportsCoordinateSystem(coord))
// {
// return curve.configure()
// .setCoordinateSystem(coord)
//// .setMultiplier(new WNafL2RMultiplier())
// .create();
// }
return curve;
}
private static ECCurve configureCurveGLV(ECCurve c, GLVTypeBParameters p)
{
return c.configure().setEndomorphism(new GLVTypeBEndomorphism(c, p)).create();
}
private static BigInteger fromHex(
String hex)
{
@ -51,7 +48,7 @@ public class SECNamedCurves
BigInteger n = fromHex("DB7C2ABF62E35E7628DFAC6561C5");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "09487239995A5EE76B55F9C2F098"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -77,7 +74,7 @@ public class SECNamedCurves
BigInteger n = fromHex("36DF0AAFD8B8D7597CA10520D04B");
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "4BA30AB5E892B4E1649DD0928643"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -103,7 +100,7 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFE0000000075A30D1B9038A115");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "161FF7528B899B2D0C28607CA52C5B86"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -129,7 +126,7 @@ public class SECNamedCurves
BigInteger n = fromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3");
BigInteger h = BigInteger.valueOf(4);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "7B6AA5D85E572983E6FB32A7CDEBC140"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -155,7 +152,20 @@ public class SECNamedCurves
BigInteger n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16),
new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16),
new BigInteger[]{
new BigInteger("9162fbe73984472a0a9e", 16),
new BigInteger("-96341f1138933bc2f505", 16) },
new BigInteger[]{
new BigInteger("127971af8721782ecffa3", 16),
new BigInteger("9162fbe73984472a0a9e", 16) },
new BigInteger("9162fbe73984472a0a9d0590", 16),
new BigInteger("96341f1138933bc2f503fd44", 16),
176);
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
// ECPoint G = curve.decodePoint(Hex.decode("02"
// + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -181,7 +191,7 @@ public class SECNamedCurves
BigInteger n = fromHex("0100000000000000000001F4C8F927AED3CA752257");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "4A96B5688EF573284664698968C38BB913CBFC82"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -207,7 +217,7 @@ public class SECNamedCurves
BigInteger n = fromHex("0100000000000000000000351EE786A818F3A1A16B");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "52DCB034293A117E1F4FF11B30F7199D3144CE6D"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -233,7 +243,20 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16),
new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16),
new BigInteger[]{
new BigInteger("71169be7330b3038edb025f1", 16),
new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
new BigInteger[]{
new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
new BigInteger("71169be7330b3038edb025f1", 16) },
new BigInteger("71169be7330b3038edb025f1d0f9", 16),
new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
208);
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -259,7 +282,7 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -285,7 +308,20 @@ public class SECNamedCurves
BigInteger n = fromHex("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16),
new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16),
new BigInteger[]{
new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
new BigInteger[]{
new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
240);
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -311,7 +347,7 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -337,7 +373,20 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
GLVTypeBParameters glv = new GLVTypeBParameters(
new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16),
new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16),
new BigInteger[]{
new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
new BigInteger[]{
new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
272);
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -363,7 +412,7 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -389,7 +438,7 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"));
ECPoint G = curve.decodePoint(Hex.decode("04"
@ -415,7 +464,7 @@ public class SECNamedCurves
BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409");
BigInteger h = BigInteger.valueOf(1);
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
//ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"));

View File

@ -26,16 +26,19 @@ public class TeleTrusTNamedCurves
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620F", 16), // q
new BigInteger("340E7BE2A280EB74E2BE61BADA745D97E8F7C300", 16), // a
new BigInteger("1E589A8595423412134FAA2DBDEC95C8D8675E58", 16))); // b
new BigInteger("1E589A8595423412134FAA2DBDEC95C8D8675E58", 16), // b
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321")), // G
new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16), //n
new BigInteger("01", 16)); // h
n, h);
}
};
@ -43,17 +46,20 @@ public class TeleTrusTNamedCurves
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
// new BigInteger("24DBFF5DEC9B986BBFE5295A29BFBAE45E0F5D0B", 16), // Z
new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620F", 16), // q
new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620C", 16), // a'
new BigInteger("7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380", 16))); // b'
new BigInteger("7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380", 16), // b'
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("04B199B13B9B34EFC1397E64BAEB05ACC265FF2378ADD6718B7C7C1961F0991B842443772152C9E0AD")), // G
new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16), //n
new BigInteger("01", 16)); // h
n, h);
}
};
@ -61,16 +67,19 @@ public class TeleTrusTNamedCurves
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", 16), // q
new BigInteger("6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", 16), // a
new BigInteger("469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", 16))); // b
new BigInteger("469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", 16), // b
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F")), // G
new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16), //n
new BigInteger("01", 16)); // h
n, h);
}
};
@ -78,17 +87,20 @@ public class TeleTrusTNamedCurves
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
//new BigInteger("1B6F5CC8DB4DC7AF19458A9CB80DC2295E5EB9C3732104CB") //Z
new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", 16), // q
new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294", 16), // a'
new BigInteger("13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79", 16))); // b'
new BigInteger("13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79", 16), // b'
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("043AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9")), // G'
new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16), //n
new BigInteger("01", 16)); // h
n, h);
}
};
@ -96,165 +108,195 @@ public class TeleTrusTNamedCurves
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", 16), // q
new BigInteger("68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", 16), // a
new BigInteger("2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", 16))); // b
new BigInteger("2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", 16), // b
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD")), // G
new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16), //n
new BigInteger("01", 16)); // n
n, h);
}
};
static X9ECParametersHolder brainpoolP224t1 = new X9ECParametersHolder()
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
//new BigInteger("2DF271E14427A346910CF7A2E6CFA7B3F484E5C2CCE1C8B730E28B3F") //Z
new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", 16), // q
new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC", 16), // a'
new BigInteger("4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D", 16))); // b'
new BigInteger("4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D", 16), // b'
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("046AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D5800374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C")), // G'
new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16), //n
new BigInteger("01", 16)); // h
n, h);
}
};
static X9ECParametersHolder brainpoolP256r1 = new X9ECParametersHolder()
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16), // q
new BigInteger("7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", 16), // a
new BigInteger("26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", 16))); // b
new BigInteger("26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", 16), // b
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997")), // G
new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16), //n
new BigInteger("01", 16)); // h
n, h);
}
};
static X9ECParametersHolder brainpoolP256t1 = new X9ECParametersHolder()
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
//new BigInteger("3E2D4BD9597B58639AE7AA669CAB9837CF5CF20A2C852D10F655668DFC150EF0") //Z
new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16), // q
new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374", 16), // a'
new BigInteger("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", 16))); // b'
new BigInteger("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", 16), // b'
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("04A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F42D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE")), // G'
new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16), //n
new BigInteger("01", 16)); // h
n, h);
}
};
static X9ECParametersHolder brainpoolP320r1 = new X9ECParametersHolder()
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", 16), // q
new BigInteger("3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", 16), // a
new BigInteger("520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", 16))); // b
new BigInteger("520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", 16), // b
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("0443BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E2061114FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1")), // G
new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16), //n
new BigInteger("01", 16)); // h
n, h);
}
};
static X9ECParametersHolder brainpoolP320t1 = new X9ECParametersHolder()
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
//new BigInteger("15F75CAF668077F7E85B42EB01F0A81FF56ECD6191D55CB82B7D861458A18FEFC3E5AB7496F3C7B1") //Z
new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", 16), // q
new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24", 16), // a'
new BigInteger("A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353", 16))); // b'
new BigInteger("A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353", 16), // b'
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("04925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED5263BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3")), // G'
new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16), //n
new BigInteger("01", 16)); // h
n, h);
}
};
static X9ECParametersHolder brainpoolP384r1 = new X9ECParametersHolder()
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16), // q
new BigInteger("7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", 16), // a
new BigInteger("4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", 16))); // b
new BigInteger("4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", 16), // b
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315")), // G
new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16), //n
new BigInteger("01", 16)); // h
n, h);
}
};
static X9ECParametersHolder brainpoolP384t1 = new X9ECParametersHolder()
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
//new BigInteger("41DFE8DD399331F7166A66076734A89CD0D2BCDB7D068E44E1F378F41ECBAE97D2D63DBC87BCCDDCCC5DA39E8589291C") //Z
new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16), // q
new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50", 16), // a'
new BigInteger("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", 16))); // b'
new BigInteger("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", 16), // b'
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("0418DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928")), // G'
new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16), //n
new BigInteger("01", 16)); // h
n, h);
}
};
static X9ECParametersHolder brainpoolP512r1 = new X9ECParametersHolder()
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16), // q
new BigInteger("7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", 16), // a
new BigInteger("3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", 16))); // b
new BigInteger("3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", 16), // b
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892")), // G
new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16), //n
new BigInteger("01", 16)); // h
n, h);
}
};
static X9ECParametersHolder brainpoolP512t1 = new X9ECParametersHolder()
{
protected X9ECParameters createParameters()
{
BigInteger n = new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16);
BigInteger h = new BigInteger("01", 16);
ECCurve curve = configureCurve(new ECCurve.Fp(
//new BigInteger("12EE58E6764838B69782136F0F2D3BA06E27695716054092E60A80BEDB212B64E585D90BCE13761F85C3F1D2A64E3BE8FEA2220F01EBA5EEB0F35DBD29D922AB") //Z
new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16), // q
new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0", 16), // a'
new BigInteger("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", 16))); // b'
new BigInteger("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", 16), // b'
n, h));
return new X9ECParameters(
curve,
curve.decodePoint(Hex.decode("04640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332")), // G'
new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16), //n
new BigInteger("01", 16)); // h
n, h);
}
};

View File

@ -41,35 +41,35 @@ public interface TeleTrusTObjectIdentifiers
static final ASN1ObjectIdentifier ecc_brainpool = teleTrusTAlgorithm.branch("3.2.8");
/** 1.3.36.3.3.2.8.1 */
static final ASN1ObjectIdentifier ellipticCurve = ecc_brainpool.branch("1");
/** 1.3.36.3.3.2.8.1 */
/** 1.3.36.3.3.2.8.1.1 */
static final ASN1ObjectIdentifier versionOne = ellipticCurve.branch("1");
/** 1.3.36.3.3.2.8.1.1 */
/** 1.3.36.3.3.2.8.1.1.1 */
static final ASN1ObjectIdentifier brainpoolP160r1 = versionOne.branch("1");
/** 1.3.36.3.3.2.8.1.2 */
/** 1.3.36.3.3.2.8.1.1.2 */
static final ASN1ObjectIdentifier brainpoolP160t1 = versionOne.branch("2");
/** 1.3.36.3.3.2.8.1.3 */
/** 1.3.36.3.3.2.8.1.1.3 */
static final ASN1ObjectIdentifier brainpoolP192r1 = versionOne.branch("3");
/** 1.3.36.3.3.2.8.1.4 */
/** 1.3.36.3.3.2.8.1.1.4 */
static final ASN1ObjectIdentifier brainpoolP192t1 = versionOne.branch("4");
/** 1.3.36.3.3.2.8.1.5 */
/** 1.3.36.3.3.2.8.1.1.5 */
static final ASN1ObjectIdentifier brainpoolP224r1 = versionOne.branch("5");
/** 1.3.36.3.3.2.8.1.6 */
/** 1.3.36.3.3.2.8.1.1.6 */
static final ASN1ObjectIdentifier brainpoolP224t1 = versionOne.branch("6");
/** 1.3.36.3.3.2.8.1.7 */
/** 1.3.36.3.3.2.8.1.1.7 */
static final ASN1ObjectIdentifier brainpoolP256r1 = versionOne.branch("7");
/** 1.3.36.3.3.2.8.1.8 */
/** 1.3.36.3.3.2.8.1.1.8 */
static final ASN1ObjectIdentifier brainpoolP256t1 = versionOne.branch("8");
/** 1.3.36.3.3.2.8.1.9 */
/** 1.3.36.3.3.2.8.1.1.9 */
static final ASN1ObjectIdentifier brainpoolP320r1 = versionOne.branch("9");
/** 1.3.36.3.3.2.8.1.10 */
/** 1.3.36.3.3.2.8.1.1.10 */
static final ASN1ObjectIdentifier brainpoolP320t1 = versionOne.branch("10");
/** 1.3.36.3.3.2.8.1.11 */
/** 1.3.36.3.3.2.8.1.1.11 */
static final ASN1ObjectIdentifier brainpoolP384r1 = versionOne.branch("11");
/** 1.3.36.3.3.2.8.1.12 */
/** 1.3.36.3.3.2.8.1.1.12 */
static final ASN1ObjectIdentifier brainpoolP384t1 = versionOne.branch("12");
/** 1.3.36.3.3.2.8.1.13 */
/** 1.3.36.3.3.2.8.1.1.13 */
static final ASN1ObjectIdentifier brainpoolP512r1 = versionOne.branch("13");
/** 1.3.36.3.3.2.8.1.14 */
/** 1.3.36.3.3.2.8.1.1.14 */
static final ASN1ObjectIdentifier brainpoolP512t1 = versionOne.branch("14");
}

View File

@ -12,15 +12,15 @@ import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.DEROctetString;
import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.DERTaggedObject;
import org.spongycastle.asn1.x9.X9IntegerConverter;
import org.spongycastle.crypto.params.ECDomainParameters;
import org.spongycastle.math.ec.ECAlgorithms;
import org.spongycastle.math.ec.ECCurve;
import org.spongycastle.math.field.PolynomialExtensionField;
import org.spongycastle.util.Arrays;
public class DSTU4145ECBinary
extends ASN1Object
{
BigInteger version = BigInteger.valueOf(0);
DSTU4145BinaryField f;
@ -31,17 +31,27 @@ public class DSTU4145ECBinary
public DSTU4145ECBinary(ECDomainParameters params)
{
if (!(params.getCurve() instanceof ECCurve.F2m))
ECCurve curve = params.getCurve();
if (!ECAlgorithms.isF2mCurve(curve))
{
throw new IllegalArgumentException("only binary domain is possible");
}
// We always use big-endian in parameter encoding
ECCurve.F2m curve = (ECCurve.F2m)params.getCurve();
f = new DSTU4145BinaryField(curve.getM(), curve.getK1(), curve.getK2(), curve.getK3());
PolynomialExtensionField field = (PolynomialExtensionField)curve.getField();
int[] exponents = field.getMinimalPolynomial().getExponentsPresent();
if (exponents.length == 3)
{
f = new DSTU4145BinaryField(exponents[2], exponents[1]);
}
else if (exponents.length == 5)
{
f = new DSTU4145BinaryField(exponents[4], exponents[1], exponents[2], exponents[3]);
}
a = new ASN1Integer(curve.getA().toBigInteger());
X9IntegerConverter converter = new X9IntegerConverter();
b = new DEROctetString(converter.integerToBytes(curve.getB().toBigInteger(), converter.getByteLength(curve)));
b = new DEROctetString(curve.getB().getEncoded());
n = new ASN1Integer(params.getN());
bp = new DEROctetString(DSTU4145PointEncoder.encodePoint(params.getG()));
}

View File

@ -21,17 +21,41 @@ public class DSTU4145NamedCurves
static
{
BigInteger[] n_s = new BigInteger[10];
n_s[0] = new BigInteger("400000000000000000002BEC12BE2262D39BCF14D", 16);
n_s[1] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFB12EBCC7D7F29FF7701F", 16);
n_s[2] = new BigInteger("800000000000000000000189B4E67606E3825BB2831", 16);
n_s[3] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFB981960435FE5AB64236EF", 16);
n_s[4] = new BigInteger("40000000000000000000000069A779CAC1DABC6788F7474F", 16);
n_s[5] = new BigInteger("1000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 16);
n_s[6] = new BigInteger("800000000000000000000000000000006759213AF182E987D3E17714907D470D", 16);
n_s[7] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC079C2F3825DA70D390FBBA588D4604022B7B7", 16);
n_s[8] = new BigInteger("40000000000000000000000000000000000000000000009C300B75A3FA824F22428FD28CE8812245EF44049B2D49", 16);
n_s[9] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA3175458009A8C0A724F02F81AA8A1FCBAF80D90C7A95110504CF", 16);
BigInteger[] h_s = new BigInteger[10];
h_s[0] = BigInteger.valueOf(2);
h_s[1] = BigInteger.valueOf(2);
h_s[2] = BigInteger.valueOf(4);
h_s[3] = BigInteger.valueOf(2);
h_s[4] = BigInteger.valueOf(2);
h_s[5] = BigInteger.valueOf(2);
h_s[6] = BigInteger.valueOf(4);
h_s[7] = BigInteger.valueOf(2);
h_s[8] = BigInteger.valueOf(2);
h_s[9] = BigInteger.valueOf(2);
ECCurve.F2m[] curves = new ECCurve.F2m[10];
curves[0] = new ECCurve.F2m(163, 3, 6, 7, ONE, new BigInteger("5FF6108462A2DC8210AB403925E638A19C1455D21", 16));
curves[1] = new ECCurve.F2m(167, 6, ONE, new BigInteger("6EE3CEEB230811759F20518A0930F1A4315A827DAC", 16));
curves[2] = new ECCurve.F2m(173, 1, 2, 10, ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16));
curves[3] = new ECCurve.F2m(179, 1, 2, 4, ONE, new BigInteger("4A6E0856526436F2F88DD07A341E32D04184572BEB710", 16));
curves[4] = new ECCurve.F2m(191, 9, ONE, new BigInteger("7BC86E2102902EC4D5890E8B6B4981ff27E0482750FEFC03", 16));
curves[5] = new ECCurve.F2m(233, 1, 4, 9, ONE, new BigInteger("06973B15095675534C7CF7E64A21BD54EF5DD3B8A0326AA936ECE454D2C", 16));
curves[6] = new ECCurve.F2m(257, 12, ZERO, new BigInteger("1CEF494720115657E18F938D7A7942394FF9425C1458C57861F9EEA6ADBE3BE10", 16));
curves[7] = new ECCurve.F2m(307, 2, 4, 8, ONE, new BigInteger("393C7F7D53666B5054B5E6C6D3DE94F4296C0C599E2E2E241050DF18B6090BDC90186904968BB", 16));
curves[8] = new ECCurve.F2m(367, 21, ONE, new BigInteger("43FC8AD242B0B7A6F3D1627AD5654447556B47BF6AA4A64B0C2AFE42CADAB8F93D92394C79A79755437B56995136", 16));
curves[9] = new ECCurve.F2m(431, 1, 3, 5, ONE, new BigInteger("03CE10490F6A708FC26DFE8C3D27C4F94E690134D5BFF988D8D28AAEAEDE975936C66BAC536B18AE2DC312CA493117DAA469C640CAF3", 16));
curves[0] = new ECCurve.F2m(163, 3, 6, 7, ONE, new BigInteger("5FF6108462A2DC8210AB403925E638A19C1455D21", 16), n_s[0], h_s[0]);
curves[1] = new ECCurve.F2m(167, 6, ONE, new BigInteger("6EE3CEEB230811759F20518A0930F1A4315A827DAC", 16), n_s[1], h_s[1]);
curves[2] = new ECCurve.F2m(173, 1, 2, 10, ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16), n_s[2], h_s[2]);
curves[3] = new ECCurve.F2m(179, 1, 2, 4, ONE, new BigInteger("4A6E0856526436F2F88DD07A341E32D04184572BEB710", 16), n_s[3], h_s[3]);
curves[4] = new ECCurve.F2m(191, 9, ONE, new BigInteger("7BC86E2102902EC4D5890E8B6B4981ff27E0482750FEFC03", 16), n_s[4], h_s[4]);
curves[5] = new ECCurve.F2m(233, 1, 4, 9, ONE, new BigInteger("06973B15095675534C7CF7E64A21BD54EF5DD3B8A0326AA936ECE454D2C", 16), n_s[5], h_s[5]);
curves[6] = new ECCurve.F2m(257, 12, ZERO, new BigInteger("1CEF494720115657E18F938D7A7942394FF9425C1458C57861F9EEA6ADBE3BE10", 16), n_s[6], h_s[6]);
curves[7] = new ECCurve.F2m(307, 2, 4, 8, ONE, new BigInteger("393C7F7D53666B5054B5E6C6D3DE94F4296C0C599E2E2E241050DF18B6090BDC90186904968BB", 16), n_s[7], h_s[7]);
curves[8] = new ECCurve.F2m(367, 21, ONE, new BigInteger("43FC8AD242B0B7A6F3D1627AD5654447556B47BF6AA4A64B0C2AFE42CADAB8F93D92394C79A79755437B56995136", 16), n_s[8], h_s[8]);
curves[9] = new ECCurve.F2m(431, 1, 3, 5, ONE, new BigInteger("03CE10490F6A708FC26DFE8C3D27C4F94E690134D5BFF988D8D28AAEAEDE975936C66BAC536B18AE2DC312CA493117DAA469C640CAF3", 16), n_s[9], h_s[9]);
ECPoint[] points = new ECPoint[10];
points[0] = curves[0].createPoint(new BigInteger("2E2F85F5DD74CE983A5C4237229DAF8A3F35823BE", 16), new BigInteger("3826F008A8C51D7B95284D9D03FF0E00CE2CD723A", 16));
@ -45,21 +69,9 @@ public class DSTU4145NamedCurves
points[8] = curves[8].createPoint(new BigInteger("324A6EDDD512F08C49A99AE0D3F961197A76413E7BE81A400CA681E09639B5FE12E59A109F78BF4A373541B3B9A1", 16), new BigInteger("1AB597A5B4477F59E39539007C7F977D1A567B92B043A49C6B61984C3FE3481AAF454CD41BA1F051626442B3C10", 16));
points[9] = curves[9].createPoint(new BigInteger("1A62BA79D98133A16BBAE7ED9A8E03C32E0824D57AEF72F88986874E5AAE49C27BED49A2A95058068426C2171E99FD3B43C5947C857D", 16), new BigInteger("70B5E1E14031C1F70BBEFE96BDDE66F451754B4CA5F48DA241F331AA396B8D1839A855C1769B1EA14BA53308B5E2723724E090E02DB9", 16));
BigInteger[] n_s = new BigInteger[10];
n_s[0] = new BigInteger("400000000000000000002BEC12BE2262D39BCF14D", 16);
n_s[1] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFB12EBCC7D7F29FF7701F", 16);
n_s[2] = new BigInteger("800000000000000000000189B4E67606E3825BB2831", 16);
n_s[3] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFB981960435FE5AB64236EF", 16);
n_s[4] = new BigInteger("40000000000000000000000069A779CAC1DABC6788F7474F", 16);
n_s[5] = new BigInteger("1000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 16);
n_s[6] = new BigInteger("800000000000000000000000000000006759213AF182E987D3E17714907D470D", 16);
n_s[7] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC079C2F3825DA70D390FBBA588D4604022B7B7", 16);
n_s[8] = new BigInteger("40000000000000000000000000000000000000000000009C300B75A3FA824F22428FD28CE8812245EF44049B2D49", 16);
n_s[9] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA3175458009A8C0A724F02F81AA8A1FCBAF80D90C7A95110504CF", 16);
for (int i = 0; i < params.length; i++)
{
params[i] = new ECDomainParameters(curves[i], points[i], n_s[i]);
params[i] = new ECDomainParameters(curves[i], points[i], n_s[i], h_s[i]);
}
for (int i = 0; i < oids.length; i++)

Some files were not shown because too many files have changed in this diff Show More