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> <html>
<body bgcolor=#ffffff> <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> <p>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software 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, and associated documentation files (the "Software"), to deal in the Software without restriction,

View File

@ -9,5 +9,5 @@ subprojects {
sourceCompatibility = 1.5 sourceCompatibility = 1.5
targetCompatibility = 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 sourceCompatibility = 1.5
targetCompatibility = 1.5 targetCompatibility = 1.5
version = '1.50.0.0' version = '1.51.0.0'

View File

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

View File

@ -1,27 +1,260 @@
package org.spongycastle.asn1; package org.spongycastle.asn1;
import java.io.IOException;
import java.util.Date; import java.util.Date;
import java.util.TimeZone;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings;
/**
* Generalized time object.
*/
public class ASN1GeneralizedTime 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;
}
if (obj instanceof ASN1GeneralizedTime)
{
return new ASN1GeneralizedTime(((ASN1GeneralizedTime)obj).time);
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
} }
public ASN1GeneralizedTime(Date date) /**
* 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(date); 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);
} }
public ASN1GeneralizedTime(Date date, boolean includeMillis) /**
* base constructer from a java.util.date object
*/
public ASN1GeneralizedTime(
Date time)
{ {
super(date, includeMillis); this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(time, false));
} }
public ASN1GeneralizedTime(String time) protected ASN1GeneralizedTime(Date date, boolean includeMillis)
{ {
super(time); 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; package org.spongycastle.asn1;
import java.io.IOException;
import java.util.Date; import java.util.Date;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings;
/**
* UTC time object.
*/
public class ASN1UTCTime 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;
}
if (obj instanceof ASN1UTCTime)
{
return new ASN1UTCTime(((ASN1UTCTime)obj).time);
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
} }
public ASN1UTCTime(Date date) /**
* 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(date); 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);
} }
public ASN1UTCTime(String time) /**
* base constructor from a java.util.date object
*/
public ASN1UTCTime(
Date time)
{ {
super(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; package org.spongycastle.asn1;
import java.io.IOException;
import java.util.Date; import java.util.Date;
import java.util.TimeZone;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings;
/**
* Generalized time object.
*/
public class DERGeneralizedTime public class DERGeneralizedTime
extends ASN1Primitive extends ASN1GeneralizedTime
{ {
private byte[] time; DERGeneralizedTime(byte[] bytes)
/**
* return a generalized time from the passed in object
*
* @exception IllegalArgumentException if the object cannot be converted.
*/
public static ASN1GeneralizedTime getInstance(
Object obj)
{ {
if (obj == null || obj instanceof ASN1GeneralizedTime) super(bytes);
{
return (ASN1GeneralizedTime)obj;
}
if (obj instanceof DERGeneralizedTime)
{
return new ASN1GeneralizedTime(((DERGeneralizedTime)obj).time);
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
} }
/** public DERGeneralizedTime(Date date)
* 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(); super(date);
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);
} }
/** public DERGeneralizedTime(Date date, boolean includeMillis)
* base constructer from a java.util.date object
*/
public DERGeneralizedTime(
Date time)
{ {
this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(time, false)); super(date, includeMillis);
} }
protected DERGeneralizedTime(Date date, boolean includeMillis) public DERGeneralizedTime(String time)
{ {
this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(date, true)); super(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()
{
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);
} }
} }

View File

@ -1,259 +1,22 @@
package org.spongycastle.asn1; package org.spongycastle.asn1;
import java.io.IOException;
import java.util.Date; import java.util.Date;
import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings;
/**
* UTC time object.
*/
public class DERUTCTime public class DERUTCTime
extends ASN1Primitive extends ASN1UTCTime
{ {
private byte[] time; DERUTCTime(byte[] bytes)
/**
* return an UTC Time from the passed in object.
*
* @exception IllegalArgumentException if the object cannot be converted.
*/
public static ASN1UTCTime getInstance(
Object obj)
{ {
if (obj == null || obj instanceof ASN1UTCTime) super(bytes);
{
return (ASN1UTCTime)obj;
}
if (obj instanceof DERUTCTime)
{
return new ASN1UTCTime(((DERUTCTime)obj).time);
}
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
} }
/** public DERUTCTime(Date date)
* 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(); super(date);
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);
} }
/** public DERUTCTime(String time)
* base constructor from a java.util.date object
*/
public DERUTCTime(
Date time)
{ {
this.time = Strings.toByteArray(DateFormatter.toUTCDateString(time)); super(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);
} }
} }

View File

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

View File

@ -1,13 +1,13 @@
package org.spongycastle.crypto.encodings; package org.spongycastle.crypto.encodings;
import java.security.SecureRandom;
import org.spongycastle.crypto.AsymmetricBlockCipher; import org.spongycastle.crypto.AsymmetricBlockCipher;
import org.spongycastle.crypto.CipherParameters; import org.spongycastle.crypto.CipherParameters;
import org.spongycastle.crypto.InvalidCipherTextException; import org.spongycastle.crypto.InvalidCipherTextException;
import org.spongycastle.crypto.params.AsymmetricKeyParameter; import org.spongycastle.crypto.params.AsymmetricKeyParameter;
import org.spongycastle.crypto.params.ParametersWithRandom; 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 * 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. * depends on your application - see PKCS1 Version 2 for details.
@ -32,6 +32,8 @@ public class PKCS1Encoding
private boolean forEncryption; private boolean forEncryption;
private boolean forPrivateKey; private boolean forPrivateKey;
private boolean useStrictLength; private boolean useStrictLength;
private int pLen = -1;
private byte[] fallback = null;
/** /**
* Basic constructor. * Basic constructor.
@ -44,11 +46,48 @@ public class PKCS1Encoding
this.useStrictLength = useStrict(); 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 // for J2ME compatibility
// //
private boolean useStrict() private boolean useStrict()
{ {
// required if security manager has been installed.
String strict = System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY); String strict = System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY);
return strict == null || strict.equals("true"); return strict == null || strict.equals("true");
@ -174,6 +213,121 @@ public class PKCS1Encoding
return engine.processBlock(block, 0, block.length); 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. * @exception InvalidCipherTextException if the decrypted block is not in PKCS1 format.
@ -184,7 +338,15 @@ public class PKCS1Encoding
int inLen) int inLen)
throws InvalidCipherTextException throws InvalidCipherTextException
{ {
byte[] block = engine.processBlock(in, inOff, inLen); /*
* 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()) if (block.length < getOutputBlockSize())
{ {
@ -192,10 +354,20 @@ public class PKCS1Encoding
} }
byte type = block[0]; byte type = block[0];
if (type != 1 && type != 2) if (forPrivateKey)
{ {
throw new InvalidCipherTextException("unknown block type"); 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()) 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 * @param input
* the {@link InputStream} to parse from. * the {@link InputStream} to parse from.
* @return a {@link OCSPStatusRequest} object. * @return an {@link OCSPStatusRequest} object.
* @throws IOException * @throws IOException
*/ */
public static OCSPStatusRequest parse(InputStream input) 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() public boolean isZero()
{ {
long[] a = m_ints; long[] a = m_ints;
@ -822,12 +839,12 @@ class LongArray
add(c, cOff, b, 0, bLen); add(c, cOff, b, 0, bLen);
} }
int k = 1; int k = 1;
while ((a >>>= 1) != 0) while ((a >>>= 1) != 0L)
{ {
if ((a & 1L) != 0L) if ((a & 1L) != 0L)
{ {
long carry = addShiftedUp(c, cOff, b, 0, bLen, k); long carry = addShiftedUp(c, cOff, b, 0, bLen, k);
if (carry != 0) if (carry != 0L)
{ {
c[cOff + bLen] ^= carry; c[cOff + bLen] ^= carry;
} }
@ -871,8 +888,8 @@ class LongArray
if (aLen == 1) if (aLen == 1)
{ {
long a = A.m_ints[0]; long a0 = A.m_ints[0];
if (a == 1L) if (a0 == 1L)
{ {
return B; return B;
} }
@ -880,13 +897,13 @@ class LongArray
/* /*
* Fast path for small A, with performance dependent only on the number of set bits * Fast path for small A, with performance dependent only on the number of set bits
*/ */
long[] c = new long[cLen]; long[] c0 = new long[cLen];
multiplyWord(a, B.m_ints, bLen, c, 0); multiplyWord(a0, B.m_ints, bLen, c0, 0);
/* /*
* Reduce the raw answer against the reduction coefficients * 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) if (aLen == 1)
{ {
long a = A.m_ints[0]; long a0 = A.m_ints[0];
if (a == 1L) if (a0 == 1L)
{ {
return B; return B;
} }
@ -1012,13 +1029,13 @@ class LongArray
/* /*
* Fast path for small A, with performance dependent only on the number of set bits * Fast path for small A, with performance dependent only on the number of set bits
*/ */
long[] c = new long[cLen]; long[] c0 = new long[cLen];
multiplyWord(a, B.m_ints, bLen, c, 0); multiplyWord(a0, B.m_ints, bLen, c0, 0);
/* /*
* Reduce the raw answer against the reduction coefficients * 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; aVal >>>= 4;
int v = (int)aVal & MASK; int v = (int)aVal & MASK;
addBoth(c, cOff, T0, ti[u], T1, ti[v], bMax); addBoth(c, cOff, T0, ti[u], T1, ti[v], bMax);
if ((aVal >>>= 4) == 0L) aVal >>>= 4;
if (aVal == 0L)
{ {
break; break;
} }
@ -1085,10 +1103,12 @@ class LongArray
} }
} }
int cOff = c.length;
while ((cOff -= cLen) != 0)
{ {
addShiftedUp(c, cOff - cLen, c, cOff, cLen, 8); int cOff = c.length;
while ((cOff -= cLen) != 0)
{
addShiftedUp(c, cOff - cLen, c, cOff, cLen, 8);
}
} }
/* /*
@ -1132,8 +1152,8 @@ class LongArray
if (aLen == 1) if (aLen == 1)
{ {
long a = A.m_ints[0]; long a0 = A.m_ints[0];
if (a == 1L) if (a0 == 1L)
{ {
return B; return B;
} }
@ -1141,13 +1161,13 @@ class LongArray
/* /*
* Fast path for small A, with performance dependent only on the number of set bits * Fast path for small A, with performance dependent only on the number of set bits
*/ */
long[] c = new long[cLen]; long[] c0 = new long[cLen];
multiplyWord(a, B.m_ints, bLen, c, 0); multiplyWord(a0, B.m_ints, bLen, c0, 0);
/* /*
* Reduce the raw answer against the reduction coefficients * 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 // NOTE: This works, but is slower than width 4 processing
@ -1314,6 +1334,158 @@ class LongArray
return reduceResult(c, ci[1], cLen, m, ks); 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) private static LongArray reduceResult(long[] buf, int off, int len, int m, int[] ks)
{ {
int rLen = reduceInPlace(buf, off, len, m, 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) private static void reduceBit(long[] buf, int off, int bit, int m, int[] ks)
{ {
flipBit(buf, off, bit); flipBit(buf, off, bit);
int base = bit - m; int n = bit - m;
int j = ks.length; int j = ks.length;
while (--j >= 0) 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) private static void reduceWordWise(long[] buf, int off, int len, int toBit, int m, int[] ks)
@ -1428,12 +1600,14 @@ class LongArray
} }
} }
int partial = toBit & 0x3F;
long word = buf[off + toPos] >>> partial;
if (word != 0)
{ {
buf[off + toPos] ^= word << partial; int partial = toBit & 0x3F;
reduceWord(buf, off, toBit, word, m, ks); long word = buf[off + toPos] >>> partial;
if (word != 0)
{
buf[off + toPos] ^= word << partial;
reduceWord(buf, off, toBit, word, m, ks);
}
} }
} }
@ -1502,37 +1676,59 @@ class LongArray
return new LongArray(r, 0, reduceInPlace(r, 0, r.length, m, ks)); return new LongArray(r, 0, reduceInPlace(r, 0, r.length, m, ks));
} }
// private LongArray modSquareN(int n, int m, int[] ks) public LongArray modSquareN(int n, int m, int[] ks)
// { {
// int len = getUsedLength(); int len = getUsedLength();
// if (len == 0) if (len == 0)
// { {
// return this; return this;
// } }
//
// int mLen = (m + 63) >>> 6; int mLen = (m + 63) >>> 6;
// long[] r = new long[mLen << 1]; long[] r = new long[mLen << 1];
// System.arraycopy(m_ints, 0, r, 0, len); System.arraycopy(m_ints, 0, r, 0, len);
//
// while (--n >= 0) while (--n >= 0)
// { {
// squareInPlace(r, len, m, ks); squareInPlace(r, len, m, ks);
// len = reduceInPlace(r, 0, r.length, m, ks); len = reduceInPlace(r, 0, r.length, m, ks);
// } }
//
// return new LongArray(r, 0, len); return new LongArray(r, 0, len);
// } }
//
// private static void squareInPlace(long[] x, int xLen, int m, int[] ks) public LongArray square(int m, int[] ks)
// { {
// int pos = xLen << 1; int len = getUsedLength();
// while (--xLen >= 0) if (len == 0)
// { {
// long xVal = x[xLen]; return this;
// x[--pos] = interleave2_32to64((int)(xVal >>> 32)); }
// x[--pos] = interleave2_32to64((int)xVal);
// } 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) 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) * Output: a(z)^(-1) mod f(z)
*/ */
int uzDegree = degree(); int uzDegree = degree();
if (uzDegree == 0)
{
throw new IllegalStateException();
}
if (uzDegree == 1) if (uzDegree == 1)
{ {
return this; return this;

View File

@ -2,6 +2,16 @@ package org.spongycastle.util;
public class Integers 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) public static Integer valueOf(int value)
{ {
return new Integer(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 * 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> * <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software * 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, * and associated documentation files (the "Software"), to deal in the Software without restriction,
@ -24,7 +24,7 @@ package org.spongycastle;
public class LICENSE public class LICENSE
{ {
public static String licenseText = 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")
+ System.getProperty("line.separator") + System.getProperty("line.separator")
+ "Permission is hereby granted, free of charge, to any person obtaining a copy of this software " + "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; import java.io.IOException;
/**
* Interface to parse ASN.1 application specific objects.
*/
public interface ASN1ApplicationSpecificParser public interface ASN1ApplicationSpecificParser
extends ASN1Encodable, InMemoryRepresentable extends ASN1Encodable, InMemoryRepresentable
{ {
/**
* Read the next object in the parser.
*
* @return an ASN1Encodable
* @throws IOException on a parsing or decoding error.
*/
ASN1Encodable readObject() ASN1Encodable readObject()
throws IOException; throws IOException;
} }

View File

@ -1,15 +1,204 @@
package org.spongycastle.asn1; 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 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;
}
if (obj instanceof byte[])
{
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());
} }
ASN1Boolean(byte[] value) /**
* return an ASN1Boolean from the passed in boolean.
* @return an ASN1Boolean instance.
*/
public static ASN1Boolean getInstance(
boolean value)
{ {
super(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 * own object any attempt to tag the object implicitly will convert the tag to
* an explicit one as the encoding rules require. * an explicit one as the encoding rules require.
* <p> * <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. * 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 public interface ASN1Choice
{ {

View File

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

View File

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

View File

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

View File

@ -1,22 +1,174 @@
package org.spongycastle.asn1; package org.spongycastle.asn1;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import org.spongycastle.util.Arrays;
/**
* Class representing the ASN.1 ENUMERATED type.
*/
public class ASN1Enumerated 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;
}
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());
} }
public ASN1Enumerated(BigInteger value) /**
* 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());
}
} }
public ASN1Enumerated(int value) /**
* Constructor from int.
*
* @param value the value of this enumerated.
*/
public ASN1Enumerated(
int value)
{ {
super(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; package org.spongycastle.asn1;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; 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 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;
}
if (obj instanceof byte[])
{
try
{
return (ASN1GeneralizedTime)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());
} }
public ASN1GeneralizedTime(Date 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.
* @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());
}
} }
public ASN1GeneralizedTime(String time) /**
* 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)
{ {
super(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. * 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( protected ASN1Primitive buildObject(
int tag, int tag,
@ -438,7 +444,7 @@ public class ASN1InputStream
case IA5_STRING: case IA5_STRING:
return new DERIA5String(defIn.toByteArray()); return new DERIA5String(defIn.toByteArray());
case INTEGER: case INTEGER:
return new ASN1Integer(defIn.toByteArray()); return new ASN1Integer(defIn.toByteArray(), false);
case NULL: case NULL:
return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?) return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?)
case NUMERIC_STRING: case NUMERIC_STRING:

View File

@ -1,22 +1,157 @@
package org.spongycastle.asn1; package org.spongycastle.asn1;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import org.spongycastle.util.Arrays;
/**
* Class representing the ASN.1 INTEGER type.
*/
public class ASN1Integer 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;
}
if (obj instanceof byte[])
{
try
{
return (ASN1Integer)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());
} }
public ASN1Integer(BigInteger value) /**
* 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)
{ {
super(value); 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) public ASN1Integer(
long value)
{ {
super(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; import java.io.IOException;
/** /**
* A NULL object. * A NULL object - use DERNull.INSTANCE for populating structures.
*/ */
public abstract class ASN1Null public abstract class ASN1Null
extends ASN1Primitive 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) public static ASN1Null getInstance(Object o)
{ {
if (o instanceof ASN1Null) if (o instanceof ASN1Null)

View File

@ -3,6 +3,9 @@ package org.spongycastle.asn1;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
/**
* Base class for defining an ASN.1 object.
*/
public abstract class ASN1Object public abstract class ASN1Object
implements ASN1Encodable implements ASN1Encodable
{ {
@ -88,10 +91,21 @@ public abstract class ASN1Object
return this.toASN1Primitive(); 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) protected static boolean hasEncodedTagValue(Object obj, int tagValue)
{ {
return (obj instanceof byte[]) && ((byte[])obj)[0] == 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(); public abstract ASN1Primitive toASN1Primitive();
} }

View File

@ -1,21 +1,205 @@
package org.spongycastle.asn1; 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 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;
}
if (obj instanceof ASN1Encodable && ((ASN1Encodable)obj).toASN1Primitive() instanceof ASN1ObjectIdentifier)
{
return (ASN1ObjectIdentifier)((ASN1Encodable)obj).toASN1Primitive();
}
if (obj instanceof byte[])
{
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());
} }
ASN1ObjectIdentifier(byte[] bytes) /**
* 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)
{ {
super(bytes); ASN1Primitive o = obj.getObject();
if (explicit || o instanceof ASN1ObjectIdentifier)
{
return getInstance(o);
}
else
{
return ASN1ObjectIdentifier.fromOctetString(ASN1OctetString.getInstance(obj.getObject()).getOctets());
}
} }
ASN1ObjectIdentifier(ASN1ObjectIdentifier oid, String branch) private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7f;
ASN1ObjectIdentifier(
byte[] bytes)
{ {
super(oid, branch); 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,12 +215,258 @@ public class ASN1ObjectIdentifier
/** /**
* Return true if this oid is an extension of the passed in branch, stem. * 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. * @param stem the arc or branch that is a possible parent.
* @return true if the branch is on the passed in stem, false otherwise. * @return true if the branch is on the passed in stem, false otherwise.
*/ */
public boolean on(ASN1ObjectIdentifier stem) public boolean on(ASN1ObjectIdentifier stem)
{ {
String id = getId(), stemId = stem.getId(); String id = getId(), stemId = stem.getId();
return id.length() > stemId.length() && id.charAt(stemId.length()) == '.' && id.startsWith(stemId); 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.Arrays;
import org.spongycastle.util.encoders.Hex; 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 public abstract class ASN1OctetString
extends ASN1Primitive extends ASN1Primitive
implements ASN1OctetStringParser implements ASN1OctetStringParser
@ -88,16 +178,31 @@ public abstract class ASN1OctetString
this.string = string; 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() public InputStream getOctetStream()
{ {
return new ByteArrayInputStream(string); return new ByteArrayInputStream(string);
} }
/**
* Return the parser associated with this object.
*
* @return a parser based on this OCTET STRING
*/
public ASN1OctetStringParser parser() public ASN1OctetStringParser parser()
{ {
return this; 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() public byte[] getOctets()
{ {
return string; return string;

View File

@ -2,8 +2,16 @@ package org.spongycastle.asn1;
import java.io.InputStream; import java.io.InputStream;
/**
* A basic parser for an OCTET STRING object
*/
public interface ASN1OctetStringParser public interface ASN1OctetStringParser
extends ASN1Encodable, InMemoryRepresentable 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(); public InputStream getOctetStream();
} }

View File

@ -2,6 +2,9 @@ package org.spongycastle.asn1;
import java.io.IOException; 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 public abstract class ASN1Primitive
extends ASN1Object extends ASN1Object
{ {
@ -47,11 +50,21 @@ public abstract class ASN1Primitive
return this; return this;
} }
/**
* Return the current object as one which encodes using Distinguished Encoding Rules.
*
* @return a DER version of this.
*/
ASN1Primitive toDERObject() ASN1Primitive toDERObject()
{ {
return this; return this;
} }
/**
* Return the current object as one which encodes using Definite Length encoding.
*
* @return a DL version of this.
*/
ASN1Primitive toDLObject() ASN1Primitive toDLObject()
{ {
return this; return this;

View File

@ -4,16 +4,64 @@ import java.io.IOException;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Vector; 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 public abstract class ASN1Sequence
extends ASN1Primitive extends ASN1Primitive
{ {
protected Vector seq = new Vector(); 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. * @param obj the object we want converted.
* @exception IllegalArgumentException if the object cannot be converted. * @exception IllegalArgumentException if the object cannot be converted.
* @return an ASN1Sequence instance, or null.
*/ */
public static ASN1Sequence getInstance( public static ASN1Sequence getInstance(
Object obj) Object obj)
@ -65,6 +113,7 @@ public abstract class ASN1Sequence
* false otherwise. * false otherwise.
* @exception IllegalArgumentException if the tagged object cannot * @exception IllegalArgumentException if the tagged object cannot
* be converted. * be converted.
* @return an ASN1Sequence instance.
*/ */
public static ASN1Sequence getInstance( public static ASN1Sequence getInstance(
ASN1TaggedObject obj, ASN1TaggedObject obj,
@ -110,14 +159,15 @@ public abstract class ASN1Sequence
} }
/** /**
* create an empty sequence * Create an empty sequence
*/ */
protected ASN1Sequence() 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( protected ASN1Sequence(
ASN1Encodable obj) 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( protected ASN1Sequence(
ASN1EncodableVector v) 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( protected ASN1Sequence(
ASN1Encodable[] array) 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 * @param index the sequence number (starting at zero) of the object
* @return the object at the sequence position indicated by index. * @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. * @return the number of objects in this sequence.
*/ */
@ -290,6 +341,10 @@ public abstract class ASN1Sequence
return encObj; return encObj;
} }
/**
* Change current SEQUENCE object to be encoded as {@link DERSequence}.
* This is part of Distinguished Encoding Rules form serialization.
*/
ASN1Primitive toDERObject() ASN1Primitive toDERObject()
{ {
ASN1Sequence derSeq = new DERSequence(); ASN1Sequence derSeq = new DERSequence();
@ -299,6 +354,10 @@ public abstract class ASN1Sequence
return derSeq; return derSeq;
} }
/**
* Change current SEQUENCE object to be encoded as {@link DLSequence}.
* This is part of Direct Length form serialization.
*/
ASN1Primitive toDLObject() ASN1Primitive toDLObject()
{ {
ASN1Sequence dlSeq = new DLSequence(); ASN1Sequence dlSeq = new DLSequence();

View File

@ -2,9 +2,18 @@ package org.spongycastle.asn1;
import java.io.IOException; import java.io.IOException;
/**
* A basic parser for a SEQUENCE object
*/
public interface ASN1SequenceParser public interface ASN1SequenceParser
extends ASN1Encodable, InMemoryRepresentable 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() ASN1Encodable readObject()
throws IOException; throws IOException;
} }

View File

@ -5,7 +5,94 @@ import java.io.IOException;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Vector; 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 extends ASN1Primitive
{ {
private Vector set = new Vector(); private Vector set = new Vector();
@ -16,6 +103,7 @@ abstract public class ASN1Set
* *
* @param obj the object we want converted. * @param obj the object we want converted.
* @exception IllegalArgumentException if the object cannot be converted. * @exception IllegalArgumentException if the object cannot be converted.
* @return an ASN1Set instance, or null.
*/ */
public static ASN1Set getInstance( public static ASN1Set getInstance(
Object obj) Object obj)
@ -67,6 +155,7 @@ abstract public class ASN1Set
* false otherwise. * false otherwise.
* @exception IllegalArgumentException if the tagged object cannot * @exception IllegalArgumentException if the tagged object cannot
* be converted. * be converted.
* @return an ASN1Set instance.
*/ */
public static ASN1Set getInstance( public static ASN1Set getInstance(
ASN1TaggedObject obj, ASN1TaggedObject obj,
@ -135,6 +224,7 @@ abstract public class ASN1Set
/** /**
* create a sequence containing one object * create a sequence containing one object
* @param obj object to be added to the SET.
*/ */
protected ASN1Set( protected ASN1Set(
ASN1Encodable obj) ASN1Encodable obj)
@ -144,6 +234,8 @@ abstract public class ASN1Set
/** /**
* create a sequence containing a vector of objects. * 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( protected ASN1Set(
ASN1EncodableVector v, ASN1EncodableVector v,
@ -275,6 +367,10 @@ abstract public class ASN1Set
return hashCode; return hashCode;
} }
/**
* Change current SET object to be encoded as {@link DERSet}.
* This is part of Distinguished Encoding Rules form serialization.
*/
ASN1Primitive toDERObject() ASN1Primitive toDERObject()
{ {
if (isSorted) 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() ASN1Primitive toDLObject()
{ {
ASN1Set derSet = new DLSet(); ASN1Set derSet = new DLSet();

View File

@ -2,9 +2,18 @@ package org.spongycastle.asn1;
import java.io.IOException; import java.io.IOException;
/**
* A basic parser for a SET object
*/
public interface ASN1SetParser public interface ASN1SetParser
extends ASN1Encodable, InMemoryRepresentable 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() public ASN1Encodable readObject()
throws IOException; throws IOException;
} }

View File

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

View File

@ -1,22 +1,314 @@
package org.spongycastle.asn1; package org.spongycastle.asn1;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; 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 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;
}
if (obj instanceof byte[])
{
try
{
return (ASN1UTCTime)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());
} }
public ASN1UTCTime(Date time) /**
* 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());
}
} }
public ASN1UTCTime(String time) /**
* 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)
{ {
super(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()); 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()); 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. * @param obj the object we want converted.
* @exception IllegalArgumentException if the object cannot be converted. * @exception IllegalArgumentException if the object cannot be converted.
* @return a DERBMPString instance, or null.
*/ */
public static DERBMPString getInstance( public static DERBMPString getInstance(
Object obj) Object obj)
@ -50,6 +51,7 @@ public class DERBMPString
* tagged false otherwise. * tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot * @exception IllegalArgumentException if the tagged object cannot
* be converted. * be converted.
* @return a DERBMPString instance.
*/ */
public static DERBMPString getInstance( public static DERBMPString getInstance(
ASN1TaggedObject obj, ASN1TaggedObject obj,
@ -69,6 +71,7 @@ public class DERBMPString
/** /**
* basic constructor - byte encoded string. * basic constructor - byte encoded string.
* @param string the encoded BMP STRING to wrap.
*/ */
DERBMPString( DERBMPString(
byte[] string) byte[] string)
@ -90,6 +93,7 @@ public class DERBMPString
/** /**
* basic constructor * basic constructor
* @param string a String to wrap as a BMP STRING.
*/ */
public DERBMPString( public DERBMPString(
String string) String string)

View File

@ -18,7 +18,8 @@ public class DERBitString
protected int padBits; 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 * a 32 bit constant
*/ */
static protected int getPadBits( 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 * a 32 bit constant
*/ */
static protected byte[] getBytes(int bitString) static protected byte[] getBytes(int bitString)
@ -93,7 +95,9 @@ public class DERBitString
/** /**
* return a Bit String from the passed in object * 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. * @exception IllegalArgumentException if the object cannot be converted.
* @return a DERBitString instance, or null.
*/ */
public static DERBitString getInstance( public static DERBitString getInstance(
Object obj) Object obj)
@ -114,6 +118,7 @@ public class DERBitString
* tagged false otherwise. * tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot * @exception IllegalArgumentException if the tagged object cannot
* be converted. * be converted.
* @return a DERBitString instance, or null.
*/ */
public static DERBitString getInstance( public static DERBitString getInstance(
ASN1TaggedObject obj, ASN1TaggedObject obj,

View File

@ -1,179 +1,22 @@
package org.spongycastle.asn1; package org.spongycastle.asn1;
import java.io.IOException; /**
* @deprecated use ASN1Boolean
import org.spongycastle.util.Arrays; */
public class DERBoolean 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. * @deprecated use getInstance(boolean) method.
* @param value * @param value
*/ */
public DERBoolean( public DERBoolean(boolean value)
boolean value)
{ {
this.value = (value) ? TRUE_VALUE : FALSE_VALUE; super(value);
} }
public boolean isTrue() DERBoolean(byte[] value)
{ {
return (value[0] != 0); super(value);
}
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);
}
} }
} }

View File

@ -1,170 +1,37 @@
package org.spongycastle.asn1; package org.spongycastle.asn1;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import org.spongycastle.util.Arrays;
/** /**
* Use ASN1Enumerated instead of this. * @deprecated Use ASN1Enumerated instead of this.
*/ */
public class DEREnumerated 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 * @deprecated use ASN1Enumerated
*/ */
public DEREnumerated( DEREnumerated(byte[] bytes)
int value)
{ {
bytes = BigInteger.valueOf(value).toByteArray(); super(bytes);
} }
/** /**
* @param value the value of this enumerated.
* @deprecated use ASN1Enumerated * @deprecated use ASN1Enumerated
*/ */
public DEREnumerated( public DEREnumerated(BigInteger value)
BigInteger value)
{ {
bytes = value.toByteArray(); super(value);
} }
/** /**
* @param value the value of this enumerated.
* @deprecated use ASN1Enumerated * @deprecated use ASN1Enumerated
*/ */
public DEREnumerated( public DEREnumerated(int value)
byte[] bytes)
{ {
this.bytes = bytes; super(value);
}
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;
} }
} }

View File

@ -1,350 +1,28 @@
package org.spongycastle.asn1; package org.spongycastle.asn1;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; 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 public class DERGeneralizedTime
extends ASN1Primitive extends ASN1GeneralizedTime
{ {
private byte[] time;
/** DERGeneralizedTime(byte[] bytes)
* return a generalized time from the passed in object
*
* @exception IllegalArgumentException if the object cannot be converted.
*/
public static ASN1GeneralizedTime getInstance(
Object obj)
{ {
if (obj == null || obj instanceof ASN1GeneralizedTime) super(bytes);
{
return (ASN1GeneralizedTime)obj;
}
if (obj instanceof DERGeneralizedTime)
{
return new ASN1GeneralizedTime(((DERGeneralizedTime)obj).time);
}
if (obj instanceof byte[])
{
try
{
return (ASN1GeneralizedTime)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());
} }
/** public DERGeneralizedTime(Date 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)
{ {
ASN1Primitive o = obj.getObject(); super(time);
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());
}
} }
/** public DERGeneralizedTime(String time)
* base constructor from a java.util.date object
*/
public DERGeneralizedTime(
Date time)
{ {
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'"); super(time);
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
this.time = Strings.toByteArray(dateF.format(time));
} }
DERGeneralizedTime( // TODO: create proper DER encoding.
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);
}
} }

View File

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

View File

@ -1,160 +1,30 @@
package org.spongycastle.asn1; package org.spongycastle.asn1;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import org.spongycastle.util.Arrays;
/** /**
* Use ASN1Integer instead of this, * @deprecated Use ASN1Integer instead of this,
*/ */
public class DERInteger 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( public DERInteger(byte[] bytes)
Object obj)
{ {
if (obj == null || obj instanceof ASN1Integer) super(bytes, true);
{
return (ASN1Integer)obj;
}
if (obj instanceof DERInteger)
{
return new ASN1Integer((((DERInteger)obj).getValue()));
}
if (obj instanceof byte[])
{
try
{
return (ASN1Integer)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());
} }
/** public DERInteger(BigInteger value)
* 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)
{ {
ASN1Primitive o = obj.getObject(); super(value);
if (explicit || o instanceof DERInteger)
{
return getInstance(o);
}
else
{
return new ASN1Integer(ASN1OctetString.getInstance(obj.getObject()).getOctets());
}
} }
/** public DERInteger(long value)
* @deprecated use ASN1Integer constructor
*/
public DERInteger(
long value)
{ {
bytes = BigInteger.valueOf(value).toByteArray(); super(value);
}
/**
* @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();
} }
} }

View File

@ -17,7 +17,9 @@ public class DERNumericString
/** /**
* return a Numeric string from the passed in object * 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. * @exception IllegalArgumentException if the object cannot be converted.
* @return a DERNumericString instance, or null
*/ */
public static DERNumericString getInstance( public static DERNumericString getInstance(
Object obj) Object obj)
@ -50,6 +52,7 @@ public class DERNumericString
* tagged false otherwise. * tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot * @exception IllegalArgumentException if the tagged object cannot
* be converted. * be converted.
* @return a DERNumericString instance, or null.
*/ */
public static DERNumericString getInstance( public static DERNumericString getInstance(
ASN1TaggedObject obj, ASN1TaggedObject obj,

View File

@ -1,446 +1,24 @@
package org.spongycastle.asn1; 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 public class DERObjectIdentifier
extends ASN1Primitive extends ASN1ObjectIdentifier
{ {
String identifier; public DERObjectIdentifier(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)
{ {
if (obj == null || obj instanceof ASN1ObjectIdentifier) super(identifier);
{
return (ASN1ObjectIdentifier)obj;
}
if (obj instanceof DERObjectIdentifier)
{
return new ASN1ObjectIdentifier(((DERObjectIdentifier)obj).getId());
}
if (obj instanceof ASN1Encodable && ((ASN1Encodable)obj).toASN1Primitive() instanceof ASN1ObjectIdentifier)
{
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());
} }
/** DERObjectIdentifier(byte[] bytes)
* 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(); super(bytes);
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(ASN1ObjectIdentifier oid, String branch)
DERObjectIdentifier(
byte[] bytes)
{ {
StringBuffer objId = new StringBuffer(); super(oid, branch);
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);
} }
} }

View File

@ -16,8 +16,10 @@ public class DERPrintableString
/** /**
* return a printable string from the passed in object. * 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. * @exception IllegalArgumentException if the object cannot be converted.
* @return a DERPrintableString instance, or null.
*/ */
public static DERPrintableString getInstance( public static DERPrintableString getInstance(
Object obj) Object obj)
@ -50,6 +52,7 @@ public class DERPrintableString
* tagged false otherwise. * tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot * @exception IllegalArgumentException if the tagged object cannot
* be converted. * be converted.
* @return a DERPrintableString instance, or null.
*/ */
public static DERPrintableString getInstance( public static DERPrintableString getInstance(
ASN1TaggedObject obj, ASN1TaggedObject obj,

View File

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

View File

@ -1,278 +1,27 @@
package org.spongycastle.asn1; package org.spongycastle.asn1;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date; 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 public class DERUTCTime
extends ASN1Primitive extends ASN1UTCTime
{ {
private byte[] time; DERUTCTime(byte[] bytes)
/**
* return an UTC Time from the passed in object.
*
* @exception IllegalArgumentException if the object cannot be converted.
*/
public static ASN1UTCTime getInstance(
Object obj)
{ {
if (obj == null || obj instanceof ASN1UTCTime) super(bytes);
{
return (ASN1UTCTime)obj;
}
if (obj instanceof DERUTCTime)
{
return new ASN1UTCTime(((DERUTCTime)obj).time);
}
if (obj instanceof byte[])
{
try
{
return (ASN1UTCTime)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());
} }
/** public DERUTCTime(Date time)
* 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(); super(time);
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());
}
} }
/** public DERUTCTime(String time)
* base constructer from a java.util.date object
*/
public DERUTCTime(
Date time)
{ {
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'"); super(time);
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
this.time = Strings.toByteArray(dateF.format(time));
} }
DERUTCTime( // TODO: create proper DER encoding.
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);
}
} }

View File

@ -15,10 +15,12 @@ public class DERUTF8String
private byte[] string; 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 * @exception IllegalArgumentException
* if the object cannot be converted. * if the object cannot be converted.
* @return a DERUTF8String instance, or null
*/ */
public static DERUTF8String getInstance(Object obj) 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 * @param obj
* the tagged object holding the object we want * the tagged object holding the object we want
@ -53,6 +55,7 @@ public class DERUTF8String
* otherwise. * otherwise.
* @exception IllegalArgumentException * @exception IllegalArgumentException
* if the tagged object cannot be converted. * if the tagged object cannot be converted.
* @return a DERUTF8String instance, or null
*/ */
public static DERUTF8String getInstance( public static DERUTF8String getInstance(
ASN1TaggedObject obj, ASN1TaggedObject obj,
@ -71,7 +74,7 @@ public class DERUTF8String
} }
/** /**
* basic constructor - byte encoded string. * Basic constructor - byte encoded string.
*/ */
DERUTF8String(byte[] string) DERUTF8String(byte[] string)
{ {
@ -79,7 +82,7 @@ public class DERUTF8String
} }
/** /**
* basic constructor * Basic constructor
*/ */
public DERUTF8String(String string) public DERUTF8String(String string)
{ {

View File

@ -18,7 +18,9 @@ public class DERUniversalString
/** /**
* return a Universal String from the passed in object. * 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. * @exception IllegalArgumentException if the object cannot be converted.
* @return a DERUniversalString instance, or null
*/ */
public static DERUniversalString getInstance( public static DERUniversalString getInstance(
Object obj) Object obj)
@ -51,6 +53,7 @@ public class DERUniversalString
* tagged false otherwise. * tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot * @exception IllegalArgumentException if the tagged object cannot
* be converted. * be converted.
* @return a DERUniversalString instance, or null
*/ */
public static DERUniversalString getInstance( public static DERUniversalString getInstance(
ASN1TaggedObject obj, ASN1TaggedObject obj,

View File

@ -6,7 +6,10 @@ import org.spongycastle.util.Arrays;
import org.spongycastle.util.Strings; 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 public class DERVisibleString
extends ASN1Primitive extends ASN1Primitive
@ -15,9 +18,11 @@ public class DERVisibleString
private byte[] string; 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. * @exception IllegalArgumentException if the object cannot be converted.
* @return a DERVisibleString instance, or null
*/ */
public static DERVisibleString getInstance( public static DERVisibleString getInstance(
Object obj) 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 obj the tagged object holding the object we want
* @param explicit true if the object is meant to be explicitly * @param explicit true if the object is meant to be explicitly
* tagged false otherwise. * tagged false otherwise.
* @exception IllegalArgumentException if the tagged object cannot * @exception IllegalArgumentException if the tagged object cannot
* be converted. * be converted.
* @return a DERVisibleString instance, or null
*/ */
public static DERVisibleString getInstance( public static DERVisibleString getInstance(
ASN1TaggedObject obj, ASN1TaggedObject obj,
@ -68,7 +74,7 @@ public class DERVisibleString
} }
/** /**
* basic constructor - byte encoded string. * Basic constructor - byte encoded string.
*/ */
DERVisibleString( DERVisibleString(
byte[] string) byte[] string)
@ -77,7 +83,7 @@ public class DERVisibleString
} }
/** /**
* basic constructor * Basic constructor
*/ */
public DERVisibleString( public DERVisibleString(
String string) String string)

View File

@ -11,13 +11,13 @@ import java.util.Enumeration;
* <h3>8: Basic encoding rules</h3> * <h3>8: Basic encoding rules</h3>
* <h4>8.11 Encoding of a set value </h4> * <h4>8.11 Encoding of a set value </h4>
* <b>8.11.1</b> The encoding of a set value shall be constructed * <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 * <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 * 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, * ASN.1 definition of the set type, in an order chosen by the sender,
* unless the type was referenced with the keyword * unless the type was referenced with the keyword
* <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>. * <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, * <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 * be present for a type which was referenced with the keyword
* <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>. * <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.

View File

@ -2,8 +2,15 @@ package org.spongycastle.asn1;
import java.io.IOException; import java.io.IOException;
/**
* Interface implemented by objects that can be converted from streaming to in-memory objects.
*/
public interface InMemoryRepresentable public interface InMemoryRepresentable
{ {
/**
* Get the in-memory representation of the ASN.1 object.
* @throws IOException for bad input data.
*/
ASN1Primitive getLoadedObject() ASN1Primitive getLoadedObject()
throws IOException; 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.ASN1Encodable;
import org.spongycastle.asn1.ASN1EncodableVector; import org.spongycastle.asn1.ASN1EncodableVector;
import org.spongycastle.asn1.ASN1GeneralizedTime;
import org.spongycastle.asn1.ASN1Integer; import org.spongycastle.asn1.ASN1Integer;
import org.spongycastle.asn1.ASN1Object; import org.spongycastle.asn1.ASN1Object;
import org.spongycastle.asn1.ASN1OctetString; import org.spongycastle.asn1.ASN1OctetString;
import org.spongycastle.asn1.ASN1Primitive; import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1Sequence; import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.ASN1TaggedObject; import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.DERGeneralizedTime;
import org.spongycastle.asn1.DERSequence; import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.DERTaggedObject; import org.spongycastle.asn1.DERTaggedObject;
import org.spongycastle.asn1.x500.X500Name; import org.spongycastle.asn1.x500.X500Name;
@ -31,7 +31,7 @@ public class PKIHeader
private ASN1Integer pvno; private ASN1Integer pvno;
private GeneralName sender; private GeneralName sender;
private GeneralName recipient; private GeneralName recipient;
private DERGeneralizedTime messageTime; private ASN1GeneralizedTime messageTime;
private AlgorithmIdentifier protectionAlg; private AlgorithmIdentifier protectionAlg;
private ASN1OctetString senderKID; // KeyIdentifier private ASN1OctetString senderKID; // KeyIdentifier
private ASN1OctetString recipKID; // KeyIdentifier private ASN1OctetString recipKID; // KeyIdentifier
@ -56,7 +56,7 @@ public class PKIHeader
switch (tObj.getTagNo()) switch (tObj.getTagNo())
{ {
case 0: case 0:
messageTime = DERGeneralizedTime.getInstance(tObj, true); messageTime = ASN1GeneralizedTime.getInstance(tObj, true);
break; break;
case 1: case 1:
protectionAlg = AlgorithmIdentifier.getInstance(tObj, true); protectionAlg = AlgorithmIdentifier.getInstance(tObj, true);
@ -136,7 +136,7 @@ public class PKIHeader
return recipient; return recipient;
} }
public DERGeneralizedTime getMessageTime() public ASN1GeneralizedTime getMessageTime()
{ {
return messageTime; return messageTime;
} }

View File

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

View File

@ -7,7 +7,6 @@ import org.spongycastle.asn1.ASN1ObjectIdentifier;
import org.spongycastle.asn1.ASN1Primitive; import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1Sequence; import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.ASN1Set; import org.spongycastle.asn1.ASN1Set;
import org.spongycastle.asn1.DERObjectIdentifier;
import org.spongycastle.asn1.DERSequence; import org.spongycastle.asn1.DERSequence;
/** /**
@ -73,17 +72,6 @@ public class Attribute
attrValues = (ASN1Set)seq.getObjectAt(1); 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( public Attribute(
ASN1ObjectIdentifier attrType, ASN1ObjectIdentifier attrType,
ASN1Set attrValues) ASN1Set attrValues)

View File

@ -8,7 +8,6 @@ import org.spongycastle.asn1.ASN1Encodable;
import org.spongycastle.asn1.ASN1EncodableVector; import org.spongycastle.asn1.ASN1EncodableVector;
import org.spongycastle.asn1.ASN1ObjectIdentifier; import org.spongycastle.asn1.ASN1ObjectIdentifier;
import org.spongycastle.asn1.ASN1Set; import org.spongycastle.asn1.ASN1Set;
import org.spongycastle.asn1.DERObjectIdentifier;
import org.spongycastle.asn1.DERSet; 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. * Return the first attribute matching the OBJECT IDENTIFIER oid.
* *
@ -117,14 +108,6 @@ public class AttributeTable
return (Attribute)value; 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 * Return all the attributes matching the OBJECT IDENTIFIER oid. The vector will be
* empty if there are no attributes of the required type present. * empty if there are no attributes of the required type present.

View File

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

View File

@ -3,12 +3,15 @@ package org.spongycastle.asn1.cms;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale;
import java.util.SimpleTimeZone; import java.util.SimpleTimeZone;
import org.spongycastle.asn1.ASN1Choice; import org.spongycastle.asn1.ASN1Choice;
import org.spongycastle.asn1.ASN1GeneralizedTime;
import org.spongycastle.asn1.ASN1Object; import org.spongycastle.asn1.ASN1Object;
import org.spongycastle.asn1.ASN1Primitive; import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1TaggedObject; import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.ASN1UTCTime;
import org.spongycastle.asn1.DERGeneralizedTime; import org.spongycastle.asn1.DERGeneralizedTime;
import org.spongycastle.asn1.DERUTCTime; import org.spongycastle.asn1.DERUTCTime;
@ -47,8 +50,8 @@ public class Time
public Time( public Time(
ASN1Primitive time) ASN1Primitive time)
{ {
if (!(time instanceof DERUTCTime) if (!(time instanceof ASN1UTCTime)
&& !(time instanceof DERGeneralizedTime)) && !(time instanceof ASN1GeneralizedTime))
{ {
throw new IllegalArgumentException("unknown object passed to Time"); 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 * and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
* is used. * is used.
*
* @param time a date object representing the time of interest.
*/ */
public Time( public Time(
Date date) Date time)
{ {
SimpleTimeZone tz = new SimpleTimeZone(0, "Z"); SimpleTimeZone tz = new SimpleTimeZone(0, "Z");
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss"); SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss");
dateF.setTimeZone(tz); dateF.setTimeZone(tz);
String d = dateF.format(date) + "Z"; String d = dateF.format(time) + "Z";
int year = Integer.parseInt(d.substring(0, 4)); int year = Integer.parseInt(d.substring(0, 4));
if (year < 1950 || year > 2049) if (year < 1950 || year > 2049)
{ {
time = new DERGeneralizedTime(d); this.time = new DERGeneralizedTime(d);
} }
else 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; 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()); throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
@ -120,13 +156,13 @@ public class Time
*/ */
public String getTime() public String getTime()
{ {
if (time instanceof DERUTCTime) if (time instanceof ASN1UTCTime)
{ {
return ((DERUTCTime)time).getAdjustedTime(); return ((ASN1UTCTime)time).getAdjustedTime();
} }
else else
{ {
return ((DERGeneralizedTime)time).getTime(); return ((ASN1GeneralizedTime)time).getTime();
} }
} }
@ -137,13 +173,13 @@ public class Time
{ {
try try
{ {
if (time instanceof DERUTCTime) if (time instanceof ASN1UTCTime)
{ {
return ((DERUTCTime)time).getAdjustedDate(); return ((ASN1UTCTime)time).getAdjustedDate();
} }
else else
{ {
return ((DERGeneralizedTime)time).getDate(); return ((ASN1GeneralizedTime)time).getDate();
} }
} }
catch (ParseException e) catch (ParseException e)

View File

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

View File

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

View File

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

View File

@ -13,7 +13,6 @@ import org.spongycastle.util.Integers;
/** /**
* an Iso7816CertificateHolderAuthorization structure. * an Iso7816CertificateHolderAuthorization structure.
* <p/>
* <pre> * <pre>
* Certificate Holder Authorization ::= SEQUENCE { * Certificate Holder Authorization ::= SEQUENCE {
* // specifies the format and the rules for the evaluation of the authorization * // 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 * 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> * <a href="http://www.bsi.bund.de/">http://www.bsi.bund.de/</a>
* <p> * <p>
* <a href="https://www.bsi.bund.de/EN/Publications/TechnicalGuidelines/TR03110/BSITR03110.html">BSI TR-03110</a> * <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 * Technical Guideline Advanced Security Mechanisms for Machine Readable Travel Documents
* <p> * <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; * Advanced Security Mechanisms for Machine Readable Travel Documents;
* Part 3: Common Specifications. * Part 3: Common Specifications.
*/ */
public interface EACObjectIdentifiers public interface EACObjectIdentifiers
{ {
/** /**

View File

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

View File

@ -3,6 +3,7 @@ package org.spongycastle.asn1.eac;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale;
import java.util.SimpleTimeZone; import java.util.SimpleTimeZone;
import org.spongycastle.util.Arrays; 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( public PackedDate(
Date time) Date time)
@ -33,6 +36,24 @@ public class PackedDate
this.time = convert(dateF.format(time)); 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) private byte[] convert(String sTime)
{ {
char[] digs = sTime.toCharArray(); char[] digs = sTime.toCharArray();

View File

@ -12,7 +12,6 @@ import org.spongycastle.asn1.DERSequence;
/** /**
* an Iso7816RSAPublicKeyStructure structure. * an Iso7816RSAPublicKeyStructure structure.
* <p/>
* <pre> * <pre>
* Certificate Holder Authorization ::= SEQUENCE { * Certificate Holder Authorization ::= SEQUENCE {
* // modulus should be at least 1024bit and a multiple of 512. * // 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.ASN1ObjectIdentifier;
import org.spongycastle.asn1.ASN1Primitive; import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1Sequence; import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.DERObjectIdentifier;
import org.spongycastle.asn1.DERSequence; import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.DERUTF8String; 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( public ContentHints(
ASN1ObjectIdentifier contentType) ASN1ObjectIdentifier contentType)
{ {

View File

@ -13,7 +13,7 @@ import org.spongycastle.asn1.x509.Certificate;
/** /**
* The CscaMasterList object. This object can be wrapped in a * The CscaMasterList object. This object can be wrapped in a
* CMSSignedData to be published in LDAP. * CMSSignedData to be published in LDAP.
* <p/> *
* <pre> * <pre>
* CscaMasterList ::= SEQUENCE { * CscaMasterList ::= SEQUENCE {
* version CscaMasterListVersion, * 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 * the expiry of the corresponding certificate. Hence, clients MUST support this
* extension. If a positive statement of availability is to be delivered, this * extension. If a positive statement of availability is to be delivered, this
* extension syntax and OID MUST be used. * extension syntax and OID MUST be used.
* <p/>
* <p/>
* <pre> * <pre>
* CertHash ::= SEQUENCE { * CertHash ::= SEQUENCE {
* hashAlgorithm AlgorithmIdentifier, * hashAlgorithm AlgorithmIdentifier,
@ -102,9 +100,8 @@ public class CertHash
/** /**
* Produce an object suitable for an ASN1OutputStream. * Produce an object suitable for an ASN1OutputStream.
* <p/> * <p>
* Returns: * Returns:
* <p/>
* <pre> * <pre>
* CertHash ::= SEQUENCE { * CertHash ::= SEQUENCE {
* hashAlgorithm AlgorithmIdentifier, * 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 * ISIS-MTT-Optional: The certificate requested by the client by inserting the
* RetrieveIfAllowed extension in the request, will be returned in this * RetrieveIfAllowed extension in the request, will be returned in this
* extension. * extension.
* <p/> * <p>
* ISIS-MTT-SigG: The signature act allows publishing certificates only then, * ISIS-MTT-SigG: The signature act allows publishing certificates only then,
* when the certificate owner gives his explicit permission. Accordingly, there * when the certificate owner gives his explicit permission. Accordingly, there
* may be <EFBFBD>nondownloadable<EFBFBD> certificates, about which the responder must provide * 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 * 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 * any of the OCTET STRING options is used, it MUST contain the DER encoding of
* the requested certificate. * the requested certificate.
* <p/>
* <pre> * <pre>
* RequestedCertificate ::= CHOICE { * RequestedCertificate ::= CHOICE {
* Certificate Certificate, * Certificate Certificate,
@ -105,7 +104,7 @@ public class RequestedCertificate
/** /**
* Constructor from a given details. * Constructor from a given details.
* <p/> * <p>
* Only one parameter can be given. All other must be <code>null</code>. * Only one parameter can be given. All other must be <code>null</code>.
* *
* @param certificate Given as Certificate * @param certificate Given as Certificate
@ -155,9 +154,8 @@ public class RequestedCertificate
/** /**
* Produce an object suitable for an ASN1OutputStream. * Produce an object suitable for an ASN1OutputStream.
* <p/> * <p>
* Returns: * Returns:
* <p/>
* <pre> * <pre>
* RequestedCertificate ::= CHOICE { * RequestedCertificate ::= CHOICE {
* Certificate Certificate, * Certificate Certificate,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -11,7 +11,6 @@ import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.ASN1String; import org.spongycastle.asn1.ASN1String;
import org.spongycastle.asn1.ASN1TaggedObject; import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.DERIA5String; import org.spongycastle.asn1.DERIA5String;
import org.spongycastle.asn1.DERObjectIdentifier;
import org.spongycastle.asn1.DERSequence; import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.isismtt.ISISMTTObjectIdentifiers; import org.spongycastle.asn1.isismtt.ISISMTTObjectIdentifiers;
import org.spongycastle.asn1.x500.DirectoryString; import org.spongycastle.asn1.x500.DirectoryString;
@ -173,27 +172,9 @@ public class NamingAuthority
return namingAuthorityUrl; return namingAuthorityUrl;
} }
/**
* 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. * Constructor from given details.
* <p/> * <p>
* All parameters can be combined. * All parameters can be combined.
* *
* @param namingAuthorityId ObjectIdentifier for naming authority. * @param namingAuthorityId ObjectIdentifier for naming authority.
@ -210,9 +191,8 @@ public class NamingAuthority
/** /**
* Produce an object suitable for an ASN1OutputStream. * Produce an object suitable for an ASN1OutputStream.
* <p/> * <p>
* Returns: * Returns:
* <p/>
* <pre> * <pre>
* NamingAuthority ::= SEQUENCE * NamingAuthority ::= SEQUENCE
* { * {

View File

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

View File

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

View File

@ -6,7 +6,7 @@ import org.spongycastle.asn1.x500.DirectoryString;
/** /**
* Some other restriction regarding the usage of this certificate. * Some other restriction regarding the usage of this certificate.
* <p/> *
* <pre> * <pre>
* RestrictionSyntax ::= DirectoryString (SIZE(1..1024)) * RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
* </pre> * </pre>
@ -64,12 +64,10 @@ public class Restriction
/** /**
* Produce an object suitable for an ASN1OutputStream. * Produce an object suitable for an ASN1OutputStream.
* <p/> * <p>
* Returns: * Returns:
* <p/>
* <pre> * <pre>
* RestrictionSyntax ::= DirectoryString (SIZE(1..1024)) * RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
* <p/>
* </pre> * </pre>
* *
* @return a DERObject * @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 */ /** Verisign CZAG (Country,Zip,Age,Gender) Extension OID: 2.16.840.1.113733.1.6.3 */
static final ASN1ObjectIdentifier verisignCzagExtension = verisign.branch("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"); 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.ASN1Primitive;
import org.spongycastle.asn1.ASN1Sequence; import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.ASN1TaggedObject; import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.DERGeneralizedTime;
import org.spongycastle.asn1.DERIA5String; import org.spongycastle.asn1.DERIA5String;
import org.spongycastle.asn1.DERSequence; import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.DERTaggedObject; import org.spongycastle.asn1.DERTaggedObject;
@ -39,7 +38,7 @@ public class CrlID
crlNum = ASN1Integer.getInstance(o, true); crlNum = ASN1Integer.getInstance(o, true);
break; break;
case 2: case 2:
crlTime = DERGeneralizedTime.getInstance(o, true); crlTime = ASN1GeneralizedTime.getInstance(o, true);
break; break;
default: default:
throw new IllegalArgumentException( throw new IllegalArgumentException(

View File

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

View File

@ -6,7 +6,6 @@ import org.spongycastle.asn1.ASN1Object;
import org.spongycastle.asn1.ASN1Primitive; import org.spongycastle.asn1.ASN1Primitive;
import org.spongycastle.asn1.ASN1Sequence; import org.spongycastle.asn1.ASN1Sequence;
import org.spongycastle.asn1.ASN1TaggedObject; import org.spongycastle.asn1.ASN1TaggedObject;
import org.spongycastle.asn1.DERGeneralizedTime;
import org.spongycastle.asn1.DERSequence; import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.DERTaggedObject; import org.spongycastle.asn1.DERTaggedObject;
import org.spongycastle.asn1.x509.Extensions; import org.spongycastle.asn1.x509.Extensions;
@ -32,31 +31,13 @@ public class SingleResponse
public SingleResponse( public SingleResponse(
CertID certID, CertID certID,
CertStatus certStatus, CertStatus certStatus,
DERGeneralizedTime thisUpdate, ASN1GeneralizedTime thisUpdate,
DERGeneralizedTime nextUpdate, ASN1GeneralizedTime nextUpdate,
X509Extensions singleExtensions) X509Extensions singleExtensions)
{ {
this(certID, certStatus, thisUpdate, nextUpdate, Extensions.getInstance(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( public SingleResponse(
CertID certID, CertID certID,
CertStatus certStatus, CertStatus certStatus,

View File

@ -23,7 +23,7 @@ public class ElGamalParameter
this.g = new ASN1Integer(g); this.g = new ASN1Integer(g);
} }
public ElGamalParameter( private ElGamalParameter(
ASN1Sequence seq) ASN1Sequence seq)
{ {
Enumeration e = seq.getObjects(); Enumeration e = seq.getObjects();
@ -32,6 +32,20 @@ public class ElGamalParameter
g = (ASN1Integer)e.nextElement(); 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() public BigInteger getP()
{ {
return p.getPositiveValue(); return p.getPositiveValue();

View File

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

View File

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

View File

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

View File

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

View File

@ -68,7 +68,7 @@ public class PrivateKeyInfo
} }
/** /**
* @deprectaed use PrivateKeyInfo.getInstance() * @deprecated use PrivateKeyInfo.getInstance()
* @param seq * @param seq
*/ */
public PrivateKeyInfo( 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.ECConstants;
import org.spongycastle.math.ec.ECCurve; import org.spongycastle.math.ec.ECCurve;
import org.spongycastle.math.ec.ECPoint; 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.Strings;
import org.spongycastle.util.encoders.Hex; import org.spongycastle.util.encoders.Hex;
@ -17,19 +19,14 @@ public class SECNamedCurves
{ {
private static ECCurve configureCurve(ECCurve curve) 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; return curve;
} }
private static ECCurve configureCurveGLV(ECCurve c, GLVTypeBParameters p)
{
return c.configure().setEndomorphism(new GLVTypeBEndomorphism(c, p)).create();
}
private static BigInteger fromHex( private static BigInteger fromHex(
String hex) String hex)
{ {
@ -51,7 +48,7 @@ public class SECNamedCurves
BigInteger n = fromHex("DB7C2ABF62E35E7628DFAC6561C5"); BigInteger n = fromHex("DB7C2ABF62E35E7628DFAC6561C5");
BigInteger h = BigInteger.valueOf(1); 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" //ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "09487239995A5EE76B55F9C2F098")); //+ "09487239995A5EE76B55F9C2F098"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -77,7 +74,7 @@ public class SECNamedCurves
BigInteger n = fromHex("36DF0AAFD8B8D7597CA10520D04B"); BigInteger n = fromHex("36DF0AAFD8B8D7597CA10520D04B");
BigInteger h = BigInteger.valueOf(4); 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" //ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "4BA30AB5E892B4E1649DD0928643")); //+ "4BA30AB5E892B4E1649DD0928643"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -103,7 +100,7 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFE0000000075A30D1B9038A115"); BigInteger n = fromHex("FFFFFFFE0000000075A30D1B9038A115");
BigInteger h = BigInteger.valueOf(1); 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" //ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "161FF7528B899B2D0C28607CA52C5B86")); //+ "161FF7528B899B2D0C28607CA52C5B86"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -129,7 +126,7 @@ public class SECNamedCurves
BigInteger n = fromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3"); BigInteger n = fromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3");
BigInteger h = BigInteger.valueOf(4); 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" //ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "7B6AA5D85E572983E6FB32A7CDEBC140")); //+ "7B6AA5D85E572983E6FB32A7CDEBC140"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -155,7 +152,20 @@ public class SECNamedCurves
BigInteger n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3"); BigInteger n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3");
BigInteger h = BigInteger.valueOf(1); 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" // ECPoint G = curve.decodePoint(Hex.decode("02"
// + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB")); // + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -181,7 +191,7 @@ public class SECNamedCurves
BigInteger n = fromHex("0100000000000000000001F4C8F927AED3CA752257"); BigInteger n = fromHex("0100000000000000000001F4C8F927AED3CA752257");
BigInteger h = BigInteger.valueOf(1); 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" //ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "4A96B5688EF573284664698968C38BB913CBFC82")); //+ "4A96B5688EF573284664698968C38BB913CBFC82"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -207,7 +217,7 @@ public class SECNamedCurves
BigInteger n = fromHex("0100000000000000000000351EE786A818F3A1A16B"); BigInteger n = fromHex("0100000000000000000000351EE786A818F3A1A16B");
BigInteger h = BigInteger.valueOf(1); 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" //ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "52DCB034293A117E1F4FF11B30F7199D3144CE6D")); //+ "52DCB034293A117E1F4FF11B30F7199D3144CE6D"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -233,7 +243,20 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D"); BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D");
BigInteger h = BigInteger.valueOf(1); 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" //ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D")); //+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -259,7 +282,7 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831"); BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831");
BigInteger h = BigInteger.valueOf(1); 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" //ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")); //+ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -285,7 +308,20 @@ public class SECNamedCurves
BigInteger n = fromHex("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7"); BigInteger n = fromHex("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
BigInteger h = BigInteger.valueOf(1); 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" //ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C")); //+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -311,7 +347,7 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D"); BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D");
BigInteger h = BigInteger.valueOf(1); 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" //ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")); //+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -337,7 +373,20 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
BigInteger h = BigInteger.valueOf(1); 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" //ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798")); //+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -363,7 +412,7 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"); BigInteger n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
BigInteger h = BigInteger.valueOf(1); 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" //ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")); //+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -389,7 +438,7 @@ public class SECNamedCurves
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"); BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973");
BigInteger h = BigInteger.valueOf(1); 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" //ECPoint G = curve.decodePoint(Hex.decode("03"
//+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7")); //+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"));
ECPoint G = curve.decodePoint(Hex.decode("04" ECPoint G = curve.decodePoint(Hex.decode("04"
@ -415,7 +464,7 @@ public class SECNamedCurves
BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"); BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409");
BigInteger h = BigInteger.valueOf(1); 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" //ECPoint G = curve.decodePoint(Hex.decode("02"
//+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66")); //+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"));

View File

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

View File

@ -41,35 +41,35 @@ public interface TeleTrusTObjectIdentifiers
static final ASN1ObjectIdentifier ecc_brainpool = teleTrusTAlgorithm.branch("3.2.8"); static final ASN1ObjectIdentifier ecc_brainpool = teleTrusTAlgorithm.branch("3.2.8");
/** 1.3.36.3.3.2.8.1 */ /** 1.3.36.3.3.2.8.1 */
static final ASN1ObjectIdentifier ellipticCurve = ecc_brainpool.branch("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"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); 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"); 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.DEROctetString;
import org.spongycastle.asn1.DERSequence; import org.spongycastle.asn1.DERSequence;
import org.spongycastle.asn1.DERTaggedObject; import org.spongycastle.asn1.DERTaggedObject;
import org.spongycastle.asn1.x9.X9IntegerConverter;
import org.spongycastle.crypto.params.ECDomainParameters; import org.spongycastle.crypto.params.ECDomainParameters;
import org.spongycastle.math.ec.ECAlgorithms;
import org.spongycastle.math.ec.ECCurve; import org.spongycastle.math.ec.ECCurve;
import org.spongycastle.math.field.PolynomialExtensionField;
import org.spongycastle.util.Arrays; import org.spongycastle.util.Arrays;
public class DSTU4145ECBinary public class DSTU4145ECBinary
extends ASN1Object extends ASN1Object
{ {
BigInteger version = BigInteger.valueOf(0); BigInteger version = BigInteger.valueOf(0);
DSTU4145BinaryField f; DSTU4145BinaryField f;
@ -31,17 +31,27 @@ public class DSTU4145ECBinary
public DSTU4145ECBinary(ECDomainParameters params) 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"); throw new IllegalArgumentException("only binary domain is possible");
} }
// We always use big-endian in parameter encoding // 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()); a = new ASN1Integer(curve.getA().toBigInteger());
X9IntegerConverter converter = new X9IntegerConverter(); b = new DEROctetString(curve.getB().getEncoded());
b = new DEROctetString(converter.integerToBytes(curve.getB().toBigInteger(), converter.getByteLength(curve)));
n = new ASN1Integer(params.getN()); n = new ASN1Integer(params.getN());
bp = new DEROctetString(DSTU4145PointEncoder.encodePoint(params.getG())); bp = new DEROctetString(DSTU4145PointEncoder.encodePoint(params.getG()));
} }

View File

@ -21,17 +21,41 @@ public class DSTU4145NamedCurves
static 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]; ECCurve.F2m[] curves = new ECCurve.F2m[10];
curves[0] = new ECCurve.F2m(163, 3, 6, 7, ONE, new BigInteger("5FF6108462A2DC8210AB403925E638A19C1455D21", 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)); 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)); 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)); 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)); 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)); 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)); 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)); 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)); 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)); 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]; ECPoint[] points = new ECPoint[10];
points[0] = curves[0].createPoint(new BigInteger("2E2F85F5DD74CE983A5C4237229DAF8A3F35823BE", 16), new BigInteger("3826F008A8C51D7B95284D9D03FF0E00CE2CD723A", 16)); 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[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)); 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++) 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++) for (int i = 0; i < oids.length; i++)

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