Update spongycastle to open-keychain/spongycastle master
Current master (HEAD) is 2c744ebade816d2e4f65f3734db373e4c19c2e4f
This commit is contained in:
parent
893e68b3da
commit
274013ad68
2
extern/spongycastle/LICENSE.html
vendored
2
extern/spongycastle/LICENSE.html
vendored
@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<body bgcolor=#ffffff>
|
||||
|
||||
Copyright (c) 2000-2013 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
|
||||
Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
|
||||
<p>
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
|
2
extern/spongycastle/build.gradle
vendored
2
extern/spongycastle/build.gradle
vendored
@ -9,5 +9,5 @@ subprojects {
|
||||
|
||||
sourceCompatibility = 1.5
|
||||
targetCompatibility = 1.5
|
||||
version = '1.50.0.0'
|
||||
version = '1.51.0.0'
|
||||
}
|
||||
|
2
extern/spongycastle/core/build.gradle
vendored
2
extern/spongycastle/core/build.gradle
vendored
@ -2,4 +2,4 @@ apply plugin: 'java'
|
||||
|
||||
sourceCompatibility = 1.5
|
||||
targetCompatibility = 1.5
|
||||
version = '1.50.0.0'
|
||||
version = '1.51.0.0'
|
||||
|
@ -1460,11 +1460,11 @@ public class BigInteger
|
||||
bitsCorrect <<= 1;
|
||||
}
|
||||
while (bitsCorrect < pow);
|
||||
}
|
||||
|
||||
if (x.sign < 0)
|
||||
{
|
||||
x = x.add(m);
|
||||
}
|
||||
if (x.sign < 0)
|
||||
{
|
||||
x = x.add(m);
|
||||
}
|
||||
|
||||
return x;
|
||||
|
@ -1,27 +1,260 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.Strings;
|
||||
|
||||
/**
|
||||
* Generalized time object.
|
||||
*/
|
||||
public class ASN1GeneralizedTime
|
||||
extends DERGeneralizedTime
|
||||
extends ASN1Primitive
|
||||
{
|
||||
ASN1GeneralizedTime(byte[] bytes)
|
||||
private byte[] time;
|
||||
|
||||
/**
|
||||
* return a generalized time from the passed in object
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static ASN1GeneralizedTime getInstance(
|
||||
Object obj)
|
||||
{
|
||||
super(bytes);
|
||||
if (obj == null || obj instanceof ASN1GeneralizedTime)
|
||||
{
|
||||
return (ASN1GeneralizedTime)obj;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,259 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.Strings;
|
||||
|
||||
/**
|
||||
* UTC time object.
|
||||
*/
|
||||
public class ASN1UTCTime
|
||||
extends DERUTCTime
|
||||
extends ASN1Primitive
|
||||
{
|
||||
ASN1UTCTime(byte[] bytes)
|
||||
private byte[] time;
|
||||
|
||||
/**
|
||||
* return an UTC Time from the passed in object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static ASN1UTCTime getInstance(
|
||||
Object obj)
|
||||
{
|
||||
super(bytes);
|
||||
if (obj == null || obj instanceof ASN1UTCTime)
|
||||
{
|
||||
return (ASN1UTCTime)obj;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -1,260 +1,27 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.Strings;
|
||||
|
||||
/**
|
||||
* Generalized time object.
|
||||
*/
|
||||
public class DERGeneralizedTime
|
||||
extends ASN1Primitive
|
||||
extends ASN1GeneralizedTime
|
||||
{
|
||||
private byte[] time;
|
||||
|
||||
/**
|
||||
* return a generalized time from the passed in object
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static ASN1GeneralizedTime getInstance(
|
||||
Object obj)
|
||||
DERGeneralizedTime(byte[] bytes)
|
||||
{
|
||||
if (obj == null || obj instanceof ASN1GeneralizedTime)
|
||||
{
|
||||
return (ASN1GeneralizedTime)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof DERGeneralizedTime)
|
||||
{
|
||||
return new ASN1GeneralizedTime(((DERGeneralizedTime)obj).time);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
super(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a Generalized Time object from a tagged object.
|
||||
*
|
||||
* @param obj the tagged object holding the object we want
|
||||
* @param explicit true if the object is meant to be explicitly
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
*/
|
||||
public static ASN1GeneralizedTime getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
public DERGeneralizedTime(Date date)
|
||||
{
|
||||
ASN1Primitive o = obj.getObject();
|
||||
|
||||
if (explicit || o instanceof DERGeneralizedTime)
|
||||
{
|
||||
return getInstance(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z
|
||||
* for local time, or Z|[+|-]HHMM on the end, for difference between local
|
||||
* time and UTC time. The fractional second amount f must consist of at
|
||||
* least one number with trailing zeroes removed.
|
||||
*
|
||||
* @param time the time string.
|
||||
* @exception IllegalArgumentException if String is an illegal format.
|
||||
*/
|
||||
public DERGeneralizedTime(
|
||||
String time)
|
||||
{
|
||||
char last = time.charAt(time.length() - 1);
|
||||
if (last != 'Z' && !(last >= 0 && last <= '9'))
|
||||
{
|
||||
if (time.indexOf('-') < 0 && time.indexOf('+') < 0)
|
||||
{
|
||||
throw new IllegalArgumentException("time needs to be in format YYYYMMDDHHMMSS[.f]Z or YYYYMMDDHHMMSS[.f][+-]HHMM");
|
||||
}
|
||||
}
|
||||
|
||||
this.time = Strings.toByteArray(time);
|
||||
super(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* base constructer from a java.util.date object
|
||||
*/
|
||||
public DERGeneralizedTime(
|
||||
Date time)
|
||||
public DERGeneralizedTime(Date date, boolean includeMillis)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
DERGeneralizedTime(
|
||||
byte[] bytes)
|
||||
{
|
||||
this.time = bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time.
|
||||
* @return The time string as it appeared in the encoded object.
|
||||
*/
|
||||
public String getTimeString()
|
||||
{
|
||||
return Strings.fromByteArray(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the time - always in the form of
|
||||
* YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm).
|
||||
* <p>
|
||||
* Normally in a certificate we would expect "Z" rather than "GMT",
|
||||
* however adding the "GMT" means we can just use:
|
||||
* <pre>
|
||||
* dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
|
||||
* </pre>
|
||||
* To read in the time and get a date which is compatible with our local
|
||||
* time zone.
|
||||
*/
|
||||
public String getTime()
|
||||
{
|
||||
String stime = Strings.fromByteArray(time);
|
||||
|
||||
//
|
||||
// standardise the format.
|
||||
//
|
||||
if (stime.charAt(stime.length() - 1) == 'Z')
|
||||
{
|
||||
return stime.substring(0, stime.length() - 1) + "GMT+00:00";
|
||||
}
|
||||
else
|
||||
{
|
||||
int signPos = stime.length() - 5;
|
||||
char sign = stime.charAt(signPos);
|
||||
if (sign == '-' || sign == '+')
|
||||
{
|
||||
return stime.substring(0, signPos)
|
||||
+ "GMT"
|
||||
+ stime.substring(signPos, signPos + 3)
|
||||
+ ":"
|
||||
+ stime.substring(signPos + 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
signPos = stime.length() - 3;
|
||||
sign = stime.charAt(signPos);
|
||||
if (sign == '-' || sign == '+')
|
||||
{
|
||||
return stime.substring(0, signPos)
|
||||
+ "GMT"
|
||||
+ stime.substring(signPos)
|
||||
+ ":00";
|
||||
}
|
||||
}
|
||||
}
|
||||
return stime + calculateGMTOffset();
|
||||
}
|
||||
|
||||
private String calculateGMTOffset()
|
||||
{
|
||||
String sign = "+";
|
||||
TimeZone timeZone = TimeZone.getDefault();
|
||||
int offset = timeZone.getRawOffset();
|
||||
if (offset < 0)
|
||||
{
|
||||
sign = "-";
|
||||
offset = -offset;
|
||||
}
|
||||
int hours = offset / (60 * 60 * 1000);
|
||||
int minutes = (offset - (hours * 60 * 60 * 1000)) / (60 * 1000);
|
||||
|
||||
// try
|
||||
// {
|
||||
// if (timeZone.useDaylightTime() && timeZone.inDaylightTime(this.getDate()))
|
||||
// {
|
||||
// hours += sign.equals("+") ? 1 : -1;
|
||||
// }
|
||||
// }
|
||||
// catch (ParseException e)
|
||||
// {
|
||||
// // we'll do our best and ignore daylight savings
|
||||
// }
|
||||
|
||||
return "GMT" + sign + convert(hours) + ":" + convert(minutes);
|
||||
}
|
||||
|
||||
private String convert(int time)
|
||||
{
|
||||
if (time < 10)
|
||||
{
|
||||
return "0" + time;
|
||||
}
|
||||
|
||||
return Integer.toString(time);
|
||||
}
|
||||
|
||||
public Date getDate()
|
||||
{
|
||||
return DateFormatter.fromGeneralizedTimeString(time);
|
||||
}
|
||||
|
||||
private boolean hasFractionalSeconds()
|
||||
{
|
||||
for (int i = 0; i != time.length; i++)
|
||||
{
|
||||
if (time[i] == '.')
|
||||
{
|
||||
if (i == 14)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isConstructed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int encodedLength()
|
||||
{
|
||||
int length = time.length;
|
||||
|
||||
return 1 + StreamUtil.calculateBodyLength(length) + length;
|
||||
}
|
||||
|
||||
void encode(
|
||||
ASN1OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(BERTags.GENERALIZED_TIME, time);
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
ASN1Primitive o)
|
||||
{
|
||||
if (!(o instanceof DERGeneralizedTime))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Arrays.areEqual(time, ((DERGeneralizedTime)o).time);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return Arrays.hashCode(time);
|
||||
super(time);
|
||||
}
|
||||
}
|
||||
|
@ -1,259 +1,22 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.Strings;
|
||||
|
||||
/**
|
||||
* UTC time object.
|
||||
*/
|
||||
public class DERUTCTime
|
||||
extends ASN1Primitive
|
||||
extends ASN1UTCTime
|
||||
{
|
||||
private byte[] time;
|
||||
|
||||
/**
|
||||
* return an UTC Time from the passed in object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static ASN1UTCTime getInstance(
|
||||
Object obj)
|
||||
DERUTCTime(byte[] bytes)
|
||||
{
|
||||
if (obj == null || obj instanceof ASN1UTCTime)
|
||||
{
|
||||
return (ASN1UTCTime)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof DERUTCTime)
|
||||
{
|
||||
return new ASN1UTCTime(((DERUTCTime)obj).time);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
super(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* return an UTC Time from a tagged object.
|
||||
*
|
||||
* @param obj the tagged object holding the object we want
|
||||
* @param explicit true if the object is meant to be explicitly
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
*/
|
||||
public static ASN1UTCTime getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
public DERUTCTime(Date 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 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);
|
||||
super(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* base constructor from a java.util.date object
|
||||
*/
|
||||
public DERUTCTime(
|
||||
Date time)
|
||||
public DERUTCTime(String time)
|
||||
{
|
||||
this.time = Strings.toByteArray(DateFormatter.toUTCDateString(time));
|
||||
}
|
||||
|
||||
DERUTCTime(
|
||||
byte[] time)
|
||||
{
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the time as a date based on whatever a 2 digit year will return. For
|
||||
* standardised processing use getAdjustedDate().
|
||||
*
|
||||
* @return the resulting date
|
||||
*/
|
||||
public Date getDate()
|
||||
{
|
||||
return DateFormatter.adjustedFromUTCDateString(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the time as an adjusted date
|
||||
* in the range of 1950 - 2049.
|
||||
*
|
||||
* @return a date in the range of 1950 to 2049.
|
||||
*/
|
||||
public Date getAdjustedDate()
|
||||
{
|
||||
return DateFormatter.adjustedFromUTCDateString(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the time - always in the form of
|
||||
* YYMMDDhhmmssGMT(+hh:mm|-hh:mm).
|
||||
* <p>
|
||||
* Normally in a certificate we would expect "Z" rather than "GMT",
|
||||
* however adding the "GMT" means we can just use:
|
||||
* <pre>
|
||||
* dateF = new SimpleDateFormat("yyMMddHHmmssz");
|
||||
* </pre>
|
||||
* To read in the time and get a date which is compatible with our local
|
||||
* time zone.
|
||||
* <p>
|
||||
* <b>Note:</b> In some cases, due to the local date processing, this
|
||||
* may lead to unexpected results. If you want to stick the normal
|
||||
* convention of 1950 to 2049 use the getAdjustedTime() method.
|
||||
*/
|
||||
public String getTime()
|
||||
{
|
||||
String stime = Strings.fromByteArray(time);
|
||||
|
||||
//
|
||||
// standardise the format.
|
||||
//
|
||||
if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0)
|
||||
{
|
||||
if (stime.length() == 11)
|
||||
{
|
||||
return stime.substring(0, 10) + "00GMT+00:00";
|
||||
}
|
||||
else
|
||||
{
|
||||
return stime.substring(0, 12) + "GMT+00:00";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = stime.indexOf('-');
|
||||
if (index < 0)
|
||||
{
|
||||
index = stime.indexOf('+');
|
||||
}
|
||||
String d = stime;
|
||||
|
||||
if (index == stime.length() - 3)
|
||||
{
|
||||
d += "00";
|
||||
}
|
||||
|
||||
if (index == 10)
|
||||
{
|
||||
return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15);
|
||||
}
|
||||
else
|
||||
{
|
||||
return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return a time string as an adjusted date with a 4 digit year. This goes
|
||||
* in the range of 1950 - 2049.
|
||||
*/
|
||||
public String getAdjustedTime()
|
||||
{
|
||||
String d = this.getTime();
|
||||
|
||||
if (d.charAt(0) < '5')
|
||||
{
|
||||
return "20" + d;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "19" + d;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time.
|
||||
* @return The time string as it appeared in the encoded object.
|
||||
*/
|
||||
public String getTimeString()
|
||||
{
|
||||
return Strings.fromByteArray(time);
|
||||
}
|
||||
|
||||
boolean isConstructed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int encodedLength()
|
||||
{
|
||||
int length = time.length;
|
||||
|
||||
return 1 + StreamUtil.calculateBodyLength(length) + length;
|
||||
}
|
||||
|
||||
void encode(
|
||||
ASN1OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.write(BERTags.UTC_TIME);
|
||||
|
||||
int length = time.length;
|
||||
|
||||
out.writeLength(length);
|
||||
|
||||
for (int i = 0; i != length; i++)
|
||||
{
|
||||
out.write((byte)time[i]);
|
||||
}
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
ASN1Primitive o)
|
||||
{
|
||||
if (!(o instanceof DERUTCTime))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Arrays.areEqual(time, ((DERUTCTime)o).time);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return Arrays.hashCode(time);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return Strings.fromByteArray(time);
|
||||
super(time);
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ import org.spongycastle.asn1.ASN1Choice;
|
||||
import org.spongycastle.asn1.ASN1Object;
|
||||
import org.spongycastle.asn1.ASN1Primitive;
|
||||
import org.spongycastle.asn1.ASN1TaggedObject;
|
||||
import org.spongycastle.asn1.DERGeneralizedTime;
|
||||
import org.spongycastle.asn1.DERUTCTime;
|
||||
import org.spongycastle.asn1.ASN1GeneralizedTime;
|
||||
import org.spongycastle.asn1.ASN1UTCTime;
|
||||
|
||||
public class Time
|
||||
extends ASN1Object
|
||||
@ -26,8 +26,8 @@ public class Time
|
||||
public Time(
|
||||
ASN1Primitive time)
|
||||
{
|
||||
if (!(time instanceof DERUTCTime)
|
||||
&& !(time instanceof DERGeneralizedTime))
|
||||
if (!(time instanceof ASN1UTCTime)
|
||||
&& !(time instanceof ASN1GeneralizedTime))
|
||||
{
|
||||
throw new IllegalArgumentException("unknown object passed to Time");
|
||||
}
|
||||
@ -51,11 +51,11 @@ public class Time
|
||||
|
||||
if (year < 1950 || year > 2049)
|
||||
{
|
||||
time = new DERGeneralizedTime(date);
|
||||
time = new ASN1GeneralizedTime(date);
|
||||
}
|
||||
else
|
||||
{
|
||||
time = new DERUTCTime(date);
|
||||
time = new ASN1UTCTime(date);
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,13 +66,13 @@ public class Time
|
||||
{
|
||||
return (Time)obj;
|
||||
}
|
||||
else if (obj instanceof DERUTCTime)
|
||||
else if (obj instanceof ASN1UTCTime)
|
||||
{
|
||||
return new Time((DERUTCTime)obj);
|
||||
return new Time((ASN1UTCTime)obj);
|
||||
}
|
||||
else if (obj instanceof DERGeneralizedTime)
|
||||
else if (obj instanceof ASN1GeneralizedTime)
|
||||
{
|
||||
return new Time((DERGeneralizedTime)obj);
|
||||
return new Time((ASN1GeneralizedTime)obj);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
|
||||
@ -80,25 +80,25 @@ public class Time
|
||||
|
||||
public String getTime()
|
||||
{
|
||||
if (time instanceof DERUTCTime)
|
||||
if (time instanceof ASN1UTCTime)
|
||||
{
|
||||
return ((DERUTCTime)time).getAdjustedTime();
|
||||
return ((ASN1UTCTime)time).getAdjustedTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((DERGeneralizedTime)time).getTime();
|
||||
return ((ASN1GeneralizedTime)time).getTime();
|
||||
}
|
||||
}
|
||||
|
||||
public Date getDate()
|
||||
{
|
||||
if (time instanceof DERUTCTime)
|
||||
if (time instanceof ASN1UTCTime)
|
||||
{
|
||||
return ((DERUTCTime)time).getAdjustedDate();
|
||||
return ((ASN1UTCTime)time).getAdjustedDate();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((DERGeneralizedTime)time).getDate();
|
||||
return ((ASN1GeneralizedTime)time).getDate();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,8 @@ import org.spongycastle.asn1.ASN1Choice;
|
||||
import org.spongycastle.asn1.ASN1Object;
|
||||
import org.spongycastle.asn1.ASN1Primitive;
|
||||
import org.spongycastle.asn1.ASN1TaggedObject;
|
||||
import org.spongycastle.asn1.DERGeneralizedTime;
|
||||
import org.spongycastle.asn1.DERUTCTime;
|
||||
import org.spongycastle.asn1.ASN1GeneralizedTime;
|
||||
import org.spongycastle.asn1.ASN1UTCTime;
|
||||
|
||||
public class Time
|
||||
extends ASN1Object
|
||||
@ -26,8 +26,8 @@ public class Time
|
||||
public Time(
|
||||
ASN1Primitive time)
|
||||
{
|
||||
if (!(time instanceof DERUTCTime)
|
||||
&& !(time instanceof DERGeneralizedTime))
|
||||
if (!(time instanceof ASN1UTCTime)
|
||||
&& !(time instanceof ASN1GeneralizedTime))
|
||||
{
|
||||
throw new IllegalArgumentException("unknown object passed to Time");
|
||||
}
|
||||
@ -51,11 +51,11 @@ public class Time
|
||||
|
||||
if (year < 1950 || year > 2049)
|
||||
{
|
||||
time = new DERGeneralizedTime(date);
|
||||
time = new ASN1GeneralizedTime(date);
|
||||
}
|
||||
else
|
||||
{
|
||||
time = new DERUTCTime(date);
|
||||
time = new ASN1UTCTime(date);
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,13 +66,13 @@ public class Time
|
||||
{
|
||||
return (Time)obj;
|
||||
}
|
||||
else if (obj instanceof DERUTCTime)
|
||||
else if (obj instanceof ASN1UTCTime)
|
||||
{
|
||||
return new Time((DERUTCTime)obj);
|
||||
return new Time((ASN1UTCTime)obj);
|
||||
}
|
||||
else if (obj instanceof DERGeneralizedTime)
|
||||
else if (obj instanceof ASN1GeneralizedTime)
|
||||
{
|
||||
return new Time((DERGeneralizedTime)obj);
|
||||
return new Time((ASN1GeneralizedTime)obj);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
|
||||
@ -80,25 +80,25 @@ public class Time
|
||||
|
||||
public String getTime()
|
||||
{
|
||||
if (time instanceof DERUTCTime)
|
||||
if (time instanceof ASN1UTCTime)
|
||||
{
|
||||
return ((DERUTCTime)time).getAdjustedTime();
|
||||
return ((ASN1UTCTime)time).getAdjustedTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((DERGeneralizedTime)time).getTime();
|
||||
return ((ASN1GeneralizedTime)time).getTime();
|
||||
}
|
||||
}
|
||||
|
||||
public Date getDate()
|
||||
{
|
||||
if (time instanceof DERUTCTime)
|
||||
if (time instanceof ASN1UTCTime)
|
||||
{
|
||||
return ((DERUTCTime)time).getAdjustedDate();
|
||||
return ((ASN1UTCTime)time).getAdjustedDate();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((DERGeneralizedTime)time).getDate();
|
||||
return ((ASN1GeneralizedTime)time).getDate();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
package org.spongycastle.crypto.encodings;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
import org.spongycastle.crypto.AsymmetricBlockCipher;
|
||||
import org.spongycastle.crypto.CipherParameters;
|
||||
import org.spongycastle.crypto.InvalidCipherTextException;
|
||||
import org.spongycastle.crypto.params.AsymmetricKeyParameter;
|
||||
import org.spongycastle.crypto.params.ParametersWithRandom;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
/**
|
||||
* this does your basic PKCS 1 v1.5 padding - whether or not you should be using this
|
||||
* depends on your application - see PKCS1 Version 2 for details.
|
||||
@ -32,6 +32,8 @@ public class PKCS1Encoding
|
||||
private boolean forEncryption;
|
||||
private boolean forPrivateKey;
|
||||
private boolean useStrictLength;
|
||||
private int pLen = -1;
|
||||
private byte[] fallback = null;
|
||||
|
||||
/**
|
||||
* Basic constructor.
|
||||
@ -44,11 +46,48 @@ public class PKCS1Encoding
|
||||
this.useStrictLength = useStrict();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for decryption with a fixed plaintext length.
|
||||
*
|
||||
* @param cipher The cipher to use for cryptographic operation.
|
||||
* @param pLen Length of the expected plaintext.
|
||||
*/
|
||||
public PKCS1Encoding(
|
||||
AsymmetricBlockCipher cipher,
|
||||
int pLen)
|
||||
{
|
||||
this.engine = cipher;
|
||||
this.useStrictLength = useStrict();
|
||||
this.pLen = pLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for decryption with a fixed plaintext length and a fallback
|
||||
* value that is returned, if the padding is incorrect.
|
||||
*
|
||||
* @param cipher
|
||||
* The cipher to use for cryptographic operation.
|
||||
* @param fallback
|
||||
* The fallback value, we don't to a arraycopy here.
|
||||
*/
|
||||
public PKCS1Encoding(
|
||||
AsymmetricBlockCipher cipher,
|
||||
byte[] fallback)
|
||||
{
|
||||
this.engine = cipher;
|
||||
this.useStrictLength = useStrict();
|
||||
this.fallback = fallback;
|
||||
this.pLen = fallback.length;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// for J2ME compatibility
|
||||
//
|
||||
private boolean useStrict()
|
||||
{
|
||||
// required if security manager has been installed.
|
||||
String strict = System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY);
|
||||
|
||||
return strict == null || strict.equals("true");
|
||||
@ -174,6 +213,121 @@ public class PKCS1Encoding
|
||||
|
||||
return engine.processBlock(block, 0, block.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the argument is a correctly PKCS#1.5 encoded Plaintext
|
||||
* for encryption.
|
||||
*
|
||||
* @param encoded The Plaintext.
|
||||
* @param pLen Expected length of the plaintext.
|
||||
* @return Either 0, if the encoding is correct, or -1, if it is incorrect.
|
||||
*/
|
||||
private static int checkPkcs1Encoding(byte[] encoded, int pLen) {
|
||||
int correct = 0;
|
||||
/*
|
||||
* Check if the first two bytes are 0 2
|
||||
*/
|
||||
correct |= (encoded[0] ^ 2);
|
||||
|
||||
/*
|
||||
* Now the padding check, check for no 0 byte in the padding
|
||||
*/
|
||||
int plen = encoded.length - (
|
||||
pLen /* Lenght of the PMS */
|
||||
+ 1 /* Final 0-byte before PMS */
|
||||
);
|
||||
|
||||
for (int i = 1; i < plen; i++) {
|
||||
int tmp = encoded[i];
|
||||
tmp |= tmp >> 1;
|
||||
tmp |= tmp >> 2;
|
||||
tmp |= tmp >> 4;
|
||||
correct |= (tmp & 1) - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure the padding ends with a 0 byte.
|
||||
*/
|
||||
correct |= encoded[encoded.length - (pLen +1)];
|
||||
|
||||
/*
|
||||
* Return 0 or 1, depending on the result.
|
||||
*/
|
||||
correct |= correct >> 1;
|
||||
correct |= correct >> 2;
|
||||
correct |= correct >> 4;
|
||||
return ~((correct & 1) - 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decode PKCS#1.5 encoding, and return a random value if the padding is not correct.
|
||||
*
|
||||
* @param in The encrypted block.
|
||||
* @param inOff Offset in the encrypted block.
|
||||
* @param inLen Length of the encrypted block.
|
||||
* //@param pLen Length of the desired output.
|
||||
* @return The plaintext without padding, or a random value if the padding was incorrect.
|
||||
*
|
||||
* @throws InvalidCipherTextException
|
||||
*/
|
||||
private byte[] decodeBlockOrRandom(byte[] in, int inOff, int inLen)
|
||||
throws InvalidCipherTextException
|
||||
{
|
||||
if (!forPrivateKey)
|
||||
{
|
||||
throw new InvalidCipherTextException("sorry, this method is only for decryption, not for signing");
|
||||
}
|
||||
|
||||
byte[] block = engine.processBlock(in, inOff, inLen);
|
||||
byte[] random = null;
|
||||
if (this.fallback == null)
|
||||
{
|
||||
random = new byte[this.pLen];
|
||||
this.random.nextBytes(random);
|
||||
}
|
||||
else
|
||||
{
|
||||
random = fallback;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: This is a potential dangerous side channel. However, you can
|
||||
* fix this by changing the RSA engine in a way, that it will always
|
||||
* return blocks of the same length and prepend them with 0 bytes if
|
||||
* needed.
|
||||
*/
|
||||
if (block.length < getOutputBlockSize())
|
||||
{
|
||||
throw new InvalidCipherTextException("block truncated");
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: Potential side channel. Fix it by making the engine always
|
||||
* return blocks of the correct length.
|
||||
*/
|
||||
if (useStrictLength && block.length != engine.getOutputBlockSize())
|
||||
{
|
||||
throw new InvalidCipherTextException("block incorrect size");
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the padding.
|
||||
*/
|
||||
int correct = PKCS1Encoding.checkPkcs1Encoding(block, this.pLen);
|
||||
|
||||
/*
|
||||
* Now, to a constant time constant memory copy of the decrypted value
|
||||
* or the random value, depending on the validity of the padding.
|
||||
*/
|
||||
byte[] result = new byte[this.pLen];
|
||||
for (int i = 0; i < this.pLen; i++)
|
||||
{
|
||||
result[i] = (byte)((block[i + (block.length - pLen)] & (~correct)) | (random[i] & correct));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @exception InvalidCipherTextException if the decrypted block is not in PKCS1 format.
|
||||
@ -184,7 +338,15 @@ public class PKCS1Encoding
|
||||
int inLen)
|
||||
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())
|
||||
{
|
||||
@ -192,10 +354,20 @@ public class PKCS1Encoding
|
||||
}
|
||||
|
||||
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())
|
||||
|
@ -90,11 +90,11 @@ public class OCSPStatusRequest
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a {@link OCSPStatusRequest} from an {@link InputStream}.
|
||||
* Parse an {@link OCSPStatusRequest} from an {@link InputStream}.
|
||||
*
|
||||
* @param input
|
||||
* the {@link InputStream} to parse from.
|
||||
* @return a {@link OCSPStatusRequest} object.
|
||||
* @return an {@link OCSPStatusRequest} object.
|
||||
* @throws IOException
|
||||
*/
|
||||
public static OCSPStatusRequest parse(InputStream input) throws IOException
|
||||
|
@ -371,6 +371,23 @@ class LongArray
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOne()
|
||||
{
|
||||
long[] a = m_ints;
|
||||
if (a[0] != 1L)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (int i = 1; i < a.length; ++i)
|
||||
{
|
||||
if (a[i] != 0L)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isZero()
|
||||
{
|
||||
long[] a = m_ints;
|
||||
@ -822,12 +839,12 @@ class LongArray
|
||||
add(c, cOff, b, 0, bLen);
|
||||
}
|
||||
int k = 1;
|
||||
while ((a >>>= 1) != 0)
|
||||
while ((a >>>= 1) != 0L)
|
||||
{
|
||||
if ((a & 1L) != 0L)
|
||||
{
|
||||
long carry = addShiftedUp(c, cOff, b, 0, bLen, k);
|
||||
if (carry != 0)
|
||||
if (carry != 0L)
|
||||
{
|
||||
c[cOff + bLen] ^= carry;
|
||||
}
|
||||
@ -871,8 +888,8 @@ class LongArray
|
||||
|
||||
if (aLen == 1)
|
||||
{
|
||||
long a = A.m_ints[0];
|
||||
if (a == 1L)
|
||||
long a0 = A.m_ints[0];
|
||||
if (a0 == 1L)
|
||||
{
|
||||
return B;
|
||||
}
|
||||
@ -880,13 +897,13 @@ class LongArray
|
||||
/*
|
||||
* Fast path for small A, with performance dependent only on the number of set bits
|
||||
*/
|
||||
long[] c = new long[cLen];
|
||||
multiplyWord(a, B.m_ints, bLen, c, 0);
|
||||
long[] c0 = new long[cLen];
|
||||
multiplyWord(a0, B.m_ints, bLen, c0, 0);
|
||||
|
||||
/*
|
||||
* Reduce the raw answer against the reduction coefficients
|
||||
*/
|
||||
return reduceResult(c, 0, cLen, m, ks);
|
||||
return reduceResult(c0, 0, cLen, m, ks);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1003,8 +1020,8 @@ class LongArray
|
||||
|
||||
if (aLen == 1)
|
||||
{
|
||||
long a = A.m_ints[0];
|
||||
if (a == 1L)
|
||||
long a0 = A.m_ints[0];
|
||||
if (a0 == 1L)
|
||||
{
|
||||
return B;
|
||||
}
|
||||
@ -1012,13 +1029,13 @@ class LongArray
|
||||
/*
|
||||
* Fast path for small A, with performance dependent only on the number of set bits
|
||||
*/
|
||||
long[] c = new long[cLen];
|
||||
multiplyWord(a, B.m_ints, bLen, c, 0);
|
||||
long[] c0 = new long[cLen];
|
||||
multiplyWord(a0, B.m_ints, bLen, c0, 0);
|
||||
|
||||
/*
|
||||
* Reduce the raw answer against the reduction coefficients
|
||||
*/
|
||||
return reduceResult(c, 0, cLen, m, ks);
|
||||
return reduceResult(c0, 0, cLen, m, ks);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1077,7 +1094,8 @@ class LongArray
|
||||
aVal >>>= 4;
|
||||
int v = (int)aVal & MASK;
|
||||
addBoth(c, cOff, T0, ti[u], T1, ti[v], bMax);
|
||||
if ((aVal >>>= 4) == 0L)
|
||||
aVal >>>= 4;
|
||||
if (aVal == 0L)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -1085,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)
|
||||
{
|
||||
long a = A.m_ints[0];
|
||||
if (a == 1L)
|
||||
long a0 = A.m_ints[0];
|
||||
if (a0 == 1L)
|
||||
{
|
||||
return B;
|
||||
}
|
||||
@ -1141,13 +1161,13 @@ class LongArray
|
||||
/*
|
||||
* Fast path for small A, with performance dependent only on the number of set bits
|
||||
*/
|
||||
long[] c = new long[cLen];
|
||||
multiplyWord(a, B.m_ints, bLen, c, 0);
|
||||
long[] c0 = new long[cLen];
|
||||
multiplyWord(a0, B.m_ints, bLen, c0, 0);
|
||||
|
||||
/*
|
||||
* Reduce the raw answer against the reduction coefficients
|
||||
*/
|
||||
return reduceResult(c, 0, cLen, m, ks);
|
||||
return reduceResult(c0, 0, cLen, m, ks);
|
||||
}
|
||||
|
||||
// NOTE: This works, but is slower than width 4 processing
|
||||
@ -1314,6 +1334,158 @@ class LongArray
|
||||
return reduceResult(c, ci[1], cLen, m, ks);
|
||||
}
|
||||
|
||||
public LongArray modReduce(int m, int[] ks)
|
||||
{
|
||||
long[] buf = Arrays.clone(m_ints);
|
||||
int rLen = reduceInPlace(buf, 0, buf.length, m, ks);
|
||||
return new LongArray(buf, 0, rLen);
|
||||
}
|
||||
|
||||
public LongArray multiply(LongArray other, int m, int[] ks)
|
||||
{
|
||||
/*
|
||||
* Find out the degree of each argument and handle the zero cases
|
||||
*/
|
||||
int aDeg = degree();
|
||||
if (aDeg == 0)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
int bDeg = other.degree();
|
||||
if (bDeg == 0)
|
||||
{
|
||||
return other;
|
||||
}
|
||||
|
||||
/*
|
||||
* Swap if necessary so that A is the smaller argument
|
||||
*/
|
||||
LongArray A = this, B = other;
|
||||
if (aDeg > bDeg)
|
||||
{
|
||||
A = other; B = this;
|
||||
int tmp = aDeg; aDeg = bDeg; bDeg = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Establish the word lengths of the arguments and result
|
||||
*/
|
||||
int aLen = (aDeg + 63) >>> 6;
|
||||
int bLen = (bDeg + 63) >>> 6;
|
||||
int cLen = (aDeg + bDeg + 62) >>> 6;
|
||||
|
||||
if (aLen == 1)
|
||||
{
|
||||
long a0 = A.m_ints[0];
|
||||
if (a0 == 1L)
|
||||
{
|
||||
return B;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fast path for small A, with performance dependent only on the number of set bits
|
||||
*/
|
||||
long[] c0 = new long[cLen];
|
||||
multiplyWord(a0, B.m_ints, bLen, c0, 0);
|
||||
|
||||
/*
|
||||
* Reduce the raw answer against the reduction coefficients
|
||||
*/
|
||||
// return reduceResult(c0, 0, cLen, m, ks);
|
||||
return new LongArray(c0, 0, cLen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if B will get bigger during shifting
|
||||
*/
|
||||
int bMax = (bDeg + 7 + 63) >>> 6;
|
||||
|
||||
/*
|
||||
* Lookup table for the offset of each B in the tables
|
||||
*/
|
||||
int[] ti = new int[16];
|
||||
|
||||
/*
|
||||
* Precompute table of all 4-bit products of B
|
||||
*/
|
||||
long[] T0 = new long[bMax << 4];
|
||||
int tOff = bMax;
|
||||
ti[1] = tOff;
|
||||
System.arraycopy(B.m_ints, 0, T0, tOff, bLen);
|
||||
for (int i = 2; i < 16; ++i)
|
||||
{
|
||||
ti[i] = (tOff += bMax);
|
||||
if ((i & 1) == 0)
|
||||
{
|
||||
shiftUp(T0, tOff >>> 1, T0, tOff, bMax, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
add(T0, bMax, T0, tOff - bMax, T0, tOff, bMax);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Second table with all 4-bit products of B shifted 4 bits
|
||||
*/
|
||||
long[] T1 = new long[T0.length];
|
||||
shiftUp(T0, 0, T1, 0, T0.length, 4);
|
||||
// shiftUp(T0, bMax, T1, bMax, tOff, 4);
|
||||
|
||||
long[] a = A.m_ints;
|
||||
long[] c = new long[cLen << 3];
|
||||
|
||||
int MASK = 0xF;
|
||||
|
||||
/*
|
||||
* Lopez-Dahab (Modified) algorithm
|
||||
*/
|
||||
|
||||
for (int aPos = 0; aPos < aLen; ++aPos)
|
||||
{
|
||||
long aVal = a[aPos];
|
||||
int cOff = aPos;
|
||||
for (;;)
|
||||
{
|
||||
int u = (int)aVal & MASK;
|
||||
aVal >>>= 4;
|
||||
int v = (int)aVal & MASK;
|
||||
addBoth(c, cOff, T0, ti[u], T1, ti[v], bMax);
|
||||
aVal >>>= 4;
|
||||
if (aVal == 0L)
|
||||
{
|
||||
break;
|
||||
}
|
||||
cOff += cLen;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int cOff = c.length;
|
||||
while ((cOff -= cLen) != 0)
|
||||
{
|
||||
addShiftedUp(c, cOff - cLen, c, cOff, cLen, 8);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally the raw answer is collected, reduce it against the reduction coefficients
|
||||
*/
|
||||
// return reduceResult(c, 0, cLen, m, ks);
|
||||
return new LongArray(c, 0, cLen);
|
||||
}
|
||||
|
||||
public void reduce(int m, int[] ks)
|
||||
{
|
||||
long[] buf = m_ints;
|
||||
int rLen = reduceInPlace(buf, 0, buf.length, m, ks);
|
||||
if (rLen < buf.length)
|
||||
{
|
||||
m_ints = new long[rLen];
|
||||
System.arraycopy(buf, 0, m_ints, 0, rLen);
|
||||
}
|
||||
}
|
||||
|
||||
private static LongArray reduceResult(long[] buf, int off, int len, int m, int[] ks)
|
||||
{
|
||||
int rLen = reduceInPlace(buf, off, len, m, ks);
|
||||
@ -1405,13 +1577,13 @@ class LongArray
|
||||
private static void reduceBit(long[] buf, int off, int bit, int m, int[] ks)
|
||||
{
|
||||
flipBit(buf, off, bit);
|
||||
int base = bit - m;
|
||||
int n = bit - m;
|
||||
int j = ks.length;
|
||||
while (--j >= 0)
|
||||
{
|
||||
flipBit(buf, off, ks[j] + base);
|
||||
flipBit(buf, off, ks[j] + n);
|
||||
}
|
||||
flipBit(buf, off, base);
|
||||
flipBit(buf, off, n);
|
||||
}
|
||||
|
||||
private static void reduceWordWise(long[] buf, int off, int len, int toBit, int m, int[] ks)
|
||||
@ -1428,12 +1600,14 @@ class LongArray
|
||||
}
|
||||
}
|
||||
|
||||
int partial = toBit & 0x3F;
|
||||
long word = buf[off + toPos] >>> partial;
|
||||
if (word != 0)
|
||||
{
|
||||
buf[off + toPos] ^= word << partial;
|
||||
reduceWord(buf, off, toBit, word, m, ks);
|
||||
int partial = toBit & 0x3F;
|
||||
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));
|
||||
}
|
||||
|
||||
// private LongArray modSquareN(int n, int m, int[] ks)
|
||||
// {
|
||||
// int len = getUsedLength();
|
||||
// if (len == 0)
|
||||
// {
|
||||
// return this;
|
||||
// }
|
||||
//
|
||||
// int mLen = (m + 63) >>> 6;
|
||||
// long[] r = new long[mLen << 1];
|
||||
// System.arraycopy(m_ints, 0, r, 0, len);
|
||||
//
|
||||
// while (--n >= 0)
|
||||
// {
|
||||
// squareInPlace(r, len, m, ks);
|
||||
// len = reduceInPlace(r, 0, r.length, m, ks);
|
||||
// }
|
||||
//
|
||||
// return new LongArray(r, 0, len);
|
||||
// }
|
||||
//
|
||||
// private static void squareInPlace(long[] x, int xLen, int m, int[] ks)
|
||||
// {
|
||||
// int pos = xLen << 1;
|
||||
// while (--xLen >= 0)
|
||||
// {
|
||||
// long xVal = x[xLen];
|
||||
// x[--pos] = interleave2_32to64((int)(xVal >>> 32));
|
||||
// x[--pos] = interleave2_32to64((int)xVal);
|
||||
// }
|
||||
// }
|
||||
public LongArray modSquareN(int n, int m, int[] ks)
|
||||
{
|
||||
int len = getUsedLength();
|
||||
if (len == 0)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
int mLen = (m + 63) >>> 6;
|
||||
long[] r = new long[mLen << 1];
|
||||
System.arraycopy(m_ints, 0, r, 0, len);
|
||||
|
||||
while (--n >= 0)
|
||||
{
|
||||
squareInPlace(r, len, m, ks);
|
||||
len = reduceInPlace(r, 0, r.length, m, ks);
|
||||
}
|
||||
|
||||
return new LongArray(r, 0, len);
|
||||
}
|
||||
|
||||
public LongArray square(int m, int[] ks)
|
||||
{
|
||||
int len = getUsedLength();
|
||||
if (len == 0)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
int _2len = len << 1;
|
||||
long[] r = new long[_2len];
|
||||
|
||||
int pos = 0;
|
||||
while (pos < _2len)
|
||||
{
|
||||
long mi = m_ints[pos >>> 1];
|
||||
r[pos++] = interleave2_32to64((int)mi);
|
||||
r[pos++] = interleave2_32to64((int)(mi >>> 32));
|
||||
}
|
||||
|
||||
return new LongArray(r, 0, r.length);
|
||||
}
|
||||
|
||||
private static void squareInPlace(long[] x, int xLen, int m, int[] ks)
|
||||
{
|
||||
int pos = xLen << 1;
|
||||
while (--xLen >= 0)
|
||||
{
|
||||
long xVal = x[xLen];
|
||||
x[--pos] = interleave2_32to64((int)(xVal >>> 32));
|
||||
x[--pos] = interleave2_32to64((int)xVal);
|
||||
}
|
||||
}
|
||||
|
||||
private static void interleave(long[] x, int xOff, long[] z, int zOff, int count, int width)
|
||||
{
|
||||
@ -1856,6 +2052,10 @@ class LongArray
|
||||
* Output: a(z)^(-1) mod f(z)
|
||||
*/
|
||||
int uzDegree = degree();
|
||||
if (uzDegree == 0)
|
||||
{
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (uzDegree == 1)
|
||||
{
|
||||
return this;
|
||||
|
@ -2,6 +2,16 @@ package org.spongycastle.util;
|
||||
|
||||
public class Integers
|
||||
{
|
||||
public static int rotateLeft(int i, int distance)
|
||||
{
|
||||
return (i << distance) ^ (i >>> -distance);
|
||||
}
|
||||
|
||||
public static int rotateRight(int i, int distance)
|
||||
{
|
||||
return (i >>> distance) ^ (i << -distance);
|
||||
}
|
||||
|
||||
public static Integer valueOf(int value)
|
||||
{
|
||||
return new Integer(value);
|
||||
|
11
extern/spongycastle/core/src/main/j2me/org/spongycastle/util/Times.java
vendored
Normal file
11
extern/spongycastle/core/src/main/j2me/org/spongycastle/util/Times.java
vendored
Normal 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();
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package org.spongycastle;
|
||||
/**
|
||||
* The Bouncy Castle License
|
||||
*
|
||||
* Copyright (c) 2000-2013 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
|
||||
* Copyright (c) 2000-2014 The Legion Of The Bouncy Castle Inc. (http://www.bouncycastle.org)
|
||||
* <p>
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
* and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||
@ -24,7 +24,7 @@ package org.spongycastle;
|
||||
public class LICENSE
|
||||
{
|
||||
public static String licenseText =
|
||||
"Copyright (c) 2000-2013 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) "
|
||||
"Copyright (c) 2000-2014 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) "
|
||||
+ System.getProperty("line.separator")
|
||||
+ System.getProperty("line.separator")
|
||||
+ "Permission is hereby granted, free of charge, to any person obtaining a copy of this software "
|
||||
|
@ -2,9 +2,18 @@ package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Interface to parse ASN.1 application specific objects.
|
||||
*/
|
||||
public interface ASN1ApplicationSpecificParser
|
||||
extends ASN1Encodable, InMemoryRepresentable
|
||||
{
|
||||
/**
|
||||
* Read the next object in the parser.
|
||||
*
|
||||
* @return an ASN1Encodable
|
||||
* @throws IOException on a parsing or decoding error.
|
||||
*/
|
||||
ASN1Encodable readObject()
|
||||
throws IOException;
|
||||
}
|
||||
|
@ -1,15 +1,204 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
|
||||
/**
|
||||
* Public facade of ASN.1 Boolean data.
|
||||
* <p>
|
||||
* Use following to place a new instance of ASN.1 Boolean in your dataset:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li> ASN1Boolean.TRUE literal</li>
|
||||
* <li> ASN1Boolean.FALSE literal</li>
|
||||
* <li> {@link ASN1Boolean#getInstance(boolean) ASN1Boolean.getInstance(boolean)}</li>
|
||||
* <li> {@link ASN1Boolean#getInstance(int) ASN1Boolean.getInstance(int)}</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*/
|
||||
public class ASN1Boolean
|
||||
extends DERBoolean
|
||||
extends ASN1Primitive
|
||||
{
|
||||
public ASN1Boolean(boolean value)
|
||||
private static final byte[] TRUE_VALUE = new byte[] { (byte)0xff };
|
||||
private static final byte[] FALSE_VALUE = new byte[] { 0 };
|
||||
|
||||
private byte[] value;
|
||||
|
||||
public static final ASN1Boolean FALSE = new ASN1Boolean(false);
|
||||
public static final ASN1Boolean TRUE = new ASN1Boolean(true);
|
||||
|
||||
/**
|
||||
* return a boolean from the passed in object.
|
||||
*
|
||||
* @param obj an ASN1Boolean or an object that can be converted into one.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return an ASN1Boolean instance.
|
||||
*/
|
||||
public static ASN1Boolean getInstance(
|
||||
Object obj)
|
||||
{
|
||||
super(value);
|
||||
if (obj == null || obj instanceof ASN1Boolean)
|
||||
{
|
||||
return (ASN1Boolean)obj;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,22 @@ package org.spongycastle.asn1;
|
||||
* own object any attempt to tag the object implicitly will convert the tag to
|
||||
* an explicit one as the encoding rules require.
|
||||
* <p>
|
||||
* If you use this interface your class should also implement the getInstance
|
||||
* pattern which takes a tag object and the tagging mode used.
|
||||
* If you use this interface your class should also implement the getInstance()
|
||||
* pattern which takes a tag object and the tagging mode used.
|
||||
* <p>
|
||||
* <hr>
|
||||
* <p><b>X.690</b></p>
|
||||
* <p><b>8: Basic encoding rules</b></p>
|
||||
* <p><b>8.13 Encoding of a choice value </b></p>
|
||||
* <p>
|
||||
* The encoding of a choice value shall be the same as the encoding of a value of the chosen type.
|
||||
* <blockquote>
|
||||
* NOTE 1 — The encoding may be primitive or constructed depending on the chosen type.
|
||||
* <p>
|
||||
* NOTE 2 — 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
|
||||
{
|
||||
|
@ -1,6 +1,13 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
/**
|
||||
* Basic interface to produce serialisers for ASN.1 encodings.
|
||||
*/
|
||||
public interface ASN1Encodable
|
||||
{
|
||||
/**
|
||||
* Return an object, possibly constructed, of ASN.1 primitives
|
||||
* @return an ASN.1 primitive.
|
||||
*/
|
||||
ASN1Primitive toASN1Primitive();
|
||||
}
|
||||
|
@ -3,19 +3,35 @@ package org.spongycastle.asn1;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* Mutable class for building ASN.1 constructed objects.
|
||||
*/
|
||||
public class ASN1EncodableVector
|
||||
{
|
||||
Vector v = new Vector();
|
||||
|
||||
/**
|
||||
* Base constructor.
|
||||
*/
|
||||
public ASN1EncodableVector()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an encodable to the vector.
|
||||
*
|
||||
* @param obj the encodable to add.
|
||||
*/
|
||||
public void add(ASN1Encodable obj)
|
||||
{
|
||||
v.addElement(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the contents of another vector.
|
||||
*
|
||||
* @param other the vector to add.
|
||||
*/
|
||||
public void addAll(ASN1EncodableVector other)
|
||||
{
|
||||
for (Enumeration en = other.v.elements(); en.hasMoreElements();)
|
||||
@ -24,11 +40,22 @@ public class ASN1EncodableVector
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the object at position i in this vector.
|
||||
*
|
||||
* @param i the index of the object of interest.
|
||||
* @return the object at position i.
|
||||
*/
|
||||
public ASN1Encodable get(int i)
|
||||
{
|
||||
return (ASN1Encodable)v.elementAt(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size of the vector.
|
||||
*
|
||||
* @return the object count in the vector.
|
||||
*/
|
||||
public int size()
|
||||
{
|
||||
return v.size();
|
||||
|
@ -1,8 +1,22 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
/**
|
||||
* Supported encoding formats.
|
||||
*/
|
||||
public interface ASN1Encoding
|
||||
{
|
||||
/**
|
||||
* DER - distinguished encoding rules.
|
||||
*/
|
||||
static final String DER = "DER";
|
||||
|
||||
/**
|
||||
* DL - definite length encoding.
|
||||
*/
|
||||
static final String DL = "DL";
|
||||
|
||||
/**
|
||||
* BER - basic encoding rules.
|
||||
*/
|
||||
static final String BER = "BER";
|
||||
}
|
||||
|
@ -1,22 +1,174 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
|
||||
/**
|
||||
* Class representing the ASN.1 ENUMERATED type.
|
||||
*/
|
||||
public class ASN1Enumerated
|
||||
extends DEREnumerated
|
||||
extends ASN1Primitive
|
||||
{
|
||||
ASN1Enumerated(byte[] bytes)
|
||||
byte[] bytes;
|
||||
|
||||
/**
|
||||
* return an enumerated from the passed in object
|
||||
*
|
||||
* @param obj an ASN1Enumerated or an object that can be converted into one.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return an ASN1Enumerated instance, or null.
|
||||
*/
|
||||
public static ASN1Enumerated getInstance(
|
||||
Object obj)
|
||||
{
|
||||
super(bytes);
|
||||
if (obj == null || obj instanceof ASN1Enumerated)
|
||||
{
|
||||
return (ASN1Enumerated)obj;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,373 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.Strings;
|
||||
|
||||
/**
|
||||
* Base class representing the ASN.1 GeneralizedTime type.
|
||||
* <p>
|
||||
* The main difference between these and UTC time is a 4 digit year.
|
||||
* </p>
|
||||
*/
|
||||
public class ASN1GeneralizedTime
|
||||
extends DERGeneralizedTime
|
||||
extends ASN1Primitive
|
||||
{
|
||||
ASN1GeneralizedTime(byte[] bytes)
|
||||
private byte[] time;
|
||||
|
||||
/**
|
||||
* return a generalized time from the passed in object
|
||||
*
|
||||
* @param obj an ASN1GeneralizedTime or an object that can be converted into one.
|
||||
* @return an ASN1GeneralizedTime instance, or null.
|
||||
* @throws IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static ASN1GeneralizedTime getInstance(
|
||||
Object obj)
|
||||
{
|
||||
super(bytes);
|
||||
if (obj == null || obj instanceof ASN1GeneralizedTime)
|
||||
{
|
||||
return (ASN1GeneralizedTime)obj;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -124,6 +124,12 @@ public class ASN1InputStream
|
||||
|
||||
/**
|
||||
* build an object given its tag and the number of bytes to construct it from.
|
||||
*
|
||||
* @param tag the full tag details.
|
||||
* @param tagNo the tagNo defined.
|
||||
* @param length the length of the object.
|
||||
* @return the resulting primitive.
|
||||
* @throws java.io.IOException on processing exception.
|
||||
*/
|
||||
protected ASN1Primitive buildObject(
|
||||
int tag,
|
||||
@ -438,7 +444,7 @@ public class ASN1InputStream
|
||||
case IA5_STRING:
|
||||
return new DERIA5String(defIn.toByteArray());
|
||||
case INTEGER:
|
||||
return new ASN1Integer(defIn.toByteArray());
|
||||
return new ASN1Integer(defIn.toByteArray(), false);
|
||||
case NULL:
|
||||
return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?)
|
||||
case NUMERIC_STRING:
|
||||
|
@ -1,22 +1,157 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
|
||||
/**
|
||||
* Class representing the ASN.1 INTEGER type.
|
||||
*/
|
||||
public class ASN1Integer
|
||||
extends DERInteger
|
||||
extends ASN1Primitive
|
||||
{
|
||||
ASN1Integer(byte[] bytes)
|
||||
byte[] bytes;
|
||||
|
||||
/**
|
||||
* return an integer from the passed in object
|
||||
*
|
||||
* @param obj an ASN1Integer or an object that can be converted into one.
|
||||
* @throws IllegalArgumentException if the object cannot be converted.
|
||||
* @return an ASN1Integer instance.
|
||||
*/
|
||||
public static ASN1Integer getInstance(
|
||||
Object obj)
|
||||
{
|
||||
super(bytes);
|
||||
if (obj == null || obj instanceof ASN1Integer)
|
||||
{
|
||||
return (ASN1Integer)obj;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,18 +3,26 @@ package org.spongycastle.asn1;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A NULL object.
|
||||
* A NULL object - use DERNull.INSTANCE for populating structures.
|
||||
*/
|
||||
public abstract class ASN1Null
|
||||
extends ASN1Primitive
|
||||
{
|
||||
/**
|
||||
* @deprecated use DERNull.INSTANCE
|
||||
* Return an instance of ASN.1 NULL from the passed in object.
|
||||
* <p>
|
||||
* Accepted inputs:
|
||||
* <ul>
|
||||
* <li> null → null
|
||||
* <li> {@link ASN1Null} object
|
||||
* <li> a byte[] containing ASN.1 NULL object
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* @param o object to be converted.
|
||||
* @return an instance of ASN1Null, or null.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public ASN1Null()
|
||||
{
|
||||
}
|
||||
|
||||
public static ASN1Null getInstance(Object o)
|
||||
{
|
||||
if (o instanceof ASN1Null)
|
||||
|
@ -3,6 +3,9 @@ package org.spongycastle.asn1;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Base class for defining an ASN.1 object.
|
||||
*/
|
||||
public abstract class ASN1Object
|
||||
implements ASN1Encodable
|
||||
{
|
||||
@ -88,10 +91,21 @@ public abstract class ASN1Object
|
||||
return this.toASN1Primitive();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if obj is a byte array and represents an object with the given tag value.
|
||||
*
|
||||
* @param obj object of interest.
|
||||
* @param tagValue tag value to check for.
|
||||
* @return true if obj is a byte encoding starting with the given tag value, false otherwise.
|
||||
*/
|
||||
protected static boolean hasEncodedTagValue(Object obj, int tagValue)
|
||||
{
|
||||
return (obj instanceof byte[]) && ((byte[])obj)[0] == tagValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method providing a primitive representation of this object suitable for encoding.
|
||||
* @return a primitive representation of this object.
|
||||
*/
|
||||
public abstract ASN1Primitive toASN1Primitive();
|
||||
}
|
||||
|
@ -1,21 +1,205 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
|
||||
/**
|
||||
* Class representing the ASN.1 OBJECT IDENTIFIER type.
|
||||
*/
|
||||
public class ASN1ObjectIdentifier
|
||||
extends DERObjectIdentifier
|
||||
extends ASN1Primitive
|
||||
{
|
||||
public ASN1ObjectIdentifier(String identifier)
|
||||
String identifier;
|
||||
|
||||
private byte[] body;
|
||||
|
||||
/**
|
||||
* return an OID from the passed in object
|
||||
* @param obj an ASN1ObjectIdentifier or an object that can be converted into one.
|
||||
* @throws IllegalArgumentException if the object cannot be converted.
|
||||
* @return an ASN1ObjectIdentifier instance, or null.
|
||||
*/
|
||||
public static ASN1ObjectIdentifier getInstance(
|
||||
Object obj)
|
||||
{
|
||||
super(identifier);
|
||||
if (obj == null || obj instanceof ASN1ObjectIdentifier)
|
||||
{
|
||||
return (ASN1ObjectIdentifier)obj;
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
String id = getId(), stemId = stem.getId();
|
||||
return id.length() > stemId.length() && id.charAt(stemId.length()) == '.' && id.startsWith(stemId);
|
||||
}
|
||||
|
||||
private void writeField(
|
||||
ByteArrayOutputStream out,
|
||||
long fieldValue)
|
||||
{
|
||||
byte[] result = new byte[9];
|
||||
int pos = 8;
|
||||
result[pos] = (byte)((int)fieldValue & 0x7f);
|
||||
while (fieldValue >= (1L << 7))
|
||||
{
|
||||
fieldValue >>= 7;
|
||||
result[--pos] = (byte)((int)fieldValue & 0x7f | 0x80);
|
||||
}
|
||||
out.write(result, pos, 9 - pos);
|
||||
}
|
||||
|
||||
private void writeField(
|
||||
ByteArrayOutputStream out,
|
||||
BigInteger fieldValue)
|
||||
{
|
||||
int byteCount = (fieldValue.bitLength() + 6) / 7;
|
||||
if (byteCount == 0)
|
||||
{
|
||||
out.write(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
BigInteger tmpValue = fieldValue;
|
||||
byte[] tmp = new byte[byteCount];
|
||||
for (int i = byteCount - 1; i >= 0; i--)
|
||||
{
|
||||
tmp[i] = (byte)((tmpValue.intValue() & 0x7f) | 0x80);
|
||||
tmpValue = tmpValue.shiftRight(7);
|
||||
}
|
||||
tmp[byteCount - 1] &= 0x7f;
|
||||
out.write(tmp, 0, tmp.length);
|
||||
}
|
||||
}
|
||||
|
||||
private void doOutput(ByteArrayOutputStream aOut)
|
||||
{
|
||||
OIDTokenizer tok = new OIDTokenizer(identifier);
|
||||
int first = Integer.parseInt(tok.nextToken()) * 40;
|
||||
|
||||
String secondToken = tok.nextToken();
|
||||
if (secondToken.length() <= 18)
|
||||
{
|
||||
writeField(aOut, first + Long.parseLong(secondToken));
|
||||
}
|
||||
else
|
||||
{
|
||||
writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first)));
|
||||
}
|
||||
|
||||
while (tok.hasMoreTokens())
|
||||
{
|
||||
String token = tok.nextToken();
|
||||
if (token.length() <= 18)
|
||||
{
|
||||
writeField(aOut, Long.parseLong(token));
|
||||
}
|
||||
else
|
||||
{
|
||||
writeField(aOut, new BigInteger(token));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized byte[] getBody()
|
||||
{
|
||||
if (body == null)
|
||||
{
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
|
||||
doOutput(bOut);
|
||||
|
||||
body = bOut.toByteArray();
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
boolean isConstructed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int encodedLength()
|
||||
throws IOException
|
||||
{
|
||||
int length = getBody().length;
|
||||
|
||||
return 1 + StreamUtil.calculateBodyLength(length) + length;
|
||||
}
|
||||
|
||||
void encode(
|
||||
ASN1OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
byte[] enc = getBody();
|
||||
|
||||
out.write(BERTags.OBJECT_IDENTIFIER);
|
||||
out.writeLength(enc.length);
|
||||
out.write(enc);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return identifier.hashCode();
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
ASN1Primitive o)
|
||||
{
|
||||
if (!(o instanceof ASN1ObjectIdentifier))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return identifier.equals(((ASN1ObjectIdentifier)o).identifier);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getId();
|
||||
}
|
||||
|
||||
private static boolean isValidBranchID(
|
||||
String branchID, int start)
|
||||
{
|
||||
boolean periodAllowed = false;
|
||||
|
||||
int pos = branchID.length();
|
||||
while (--pos >= start)
|
||||
{
|
||||
char ch = branchID.charAt(pos);
|
||||
|
||||
// TODO Leading zeroes?
|
||||
if ('0' <= ch && ch <= '9')
|
||||
{
|
||||
periodAllowed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '.')
|
||||
{
|
||||
if (!periodAllowed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
periodAllowed = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return periodAllowed;
|
||||
}
|
||||
|
||||
private static boolean isValidIdentifier(
|
||||
String identifier)
|
||||
{
|
||||
if (identifier.length() < 3 || identifier.charAt(1) != '.')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char first = identifier.charAt(0);
|
||||
if (first < '0' || first > '2')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return isValidBranchID(identifier, 2);
|
||||
}
|
||||
|
||||
private static ASN1ObjectIdentifier[][] cache = new ASN1ObjectIdentifier[256][];
|
||||
|
||||
static ASN1ObjectIdentifier fromOctetString(byte[] enc)
|
||||
{
|
||||
if (enc.length < 3)
|
||||
{
|
||||
return new ASN1ObjectIdentifier(enc);
|
||||
}
|
||||
|
||||
int idx1 = enc[enc.length - 2] & 0xff;
|
||||
// in this case top bit is always zero
|
||||
int idx2 = enc[enc.length - 1] & 0x7f;
|
||||
|
||||
ASN1ObjectIdentifier possibleMatch;
|
||||
|
||||
synchronized (cache)
|
||||
{
|
||||
ASN1ObjectIdentifier[] first = cache[idx1];
|
||||
if (first == null)
|
||||
{
|
||||
first = cache[idx1] = new ASN1ObjectIdentifier[128];
|
||||
}
|
||||
|
||||
possibleMatch = first[idx2];
|
||||
if (possibleMatch == null)
|
||||
{
|
||||
return first[idx2] = new ASN1ObjectIdentifier(enc);
|
||||
}
|
||||
|
||||
if (Arrays.areEqual(enc, possibleMatch.getBody()))
|
||||
{
|
||||
return possibleMatch;
|
||||
}
|
||||
|
||||
idx1 = (idx1 + 1) & 0xff;
|
||||
first = cache[idx1];
|
||||
if (first == null)
|
||||
{
|
||||
first = cache[idx1] = new ASN1ObjectIdentifier[128];
|
||||
}
|
||||
|
||||
possibleMatch = first[idx2];
|
||||
if (possibleMatch == null)
|
||||
{
|
||||
return first[idx2] = new ASN1ObjectIdentifier(enc);
|
||||
}
|
||||
|
||||
if (Arrays.areEqual(enc, possibleMatch.getBody()))
|
||||
{
|
||||
return possibleMatch;
|
||||
}
|
||||
|
||||
idx2 = (idx2 + 1) & 0x7f;
|
||||
possibleMatch = first[idx2];
|
||||
if (possibleMatch == null)
|
||||
{
|
||||
return first[idx2] = new ASN1ObjectIdentifier(enc);
|
||||
}
|
||||
}
|
||||
|
||||
if (Arrays.areEqual(enc, possibleMatch.getBody()))
|
||||
{
|
||||
return possibleMatch;
|
||||
}
|
||||
|
||||
return new ASN1ObjectIdentifier(enc);
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,96 @@ import java.io.InputStream;
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
/**
|
||||
* Abstract base for the ASN.1 OCTET STRING data type
|
||||
* <p>
|
||||
* This supports BER, and DER forms of the data.
|
||||
* </p><p>
|
||||
* DER form is always primitive single OCTET STRING, while
|
||||
* BER support includes the constructed forms.
|
||||
* </p>
|
||||
* <hr>
|
||||
* <p><b>X.690</b></p>
|
||||
* <p><b>8: Basic encoding rules</b></p>
|
||||
* <p><b>8.7 Encoding of an octetstring value</b></p>
|
||||
* <p>
|
||||
* <b>8.7.1</b> The encoding of an octetstring value shall be
|
||||
* either primitive or constructed at the option of the sender.
|
||||
* <blockquote>
|
||||
* NOTE — 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 — 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 — 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 — 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 — In particular, the tags in the contents octets are always universal class, number 4.
|
||||
* </blockquote>
|
||||
* </p>
|
||||
* <p><b>9: Canonical encoding rules</b></p>
|
||||
* <p><b>9.1 Length forms</b></p>
|
||||
* <p>
|
||||
* If the encoding is constructed, it shall employ the indefinite length form.
|
||||
* If the encoding is primitive, it shall include the fewest length octets necessary.
|
||||
* [Contrast with 8.1.3.2 b).]
|
||||
* </p>
|
||||
* <p><b>9.2 String encoding forms</b></p>
|
||||
* <p>
|
||||
* BIT STRING, OCTET STRING,and restricted character string
|
||||
* values shall be encoded with a primitive encoding if they would
|
||||
* require no more than 1000 contents octets, and as a constructed
|
||||
* encoding otherwise. The string fragments contained in
|
||||
* the constructed encoding shall be encoded with a primitive encoding.
|
||||
* The encoding of each fragment, except possibly
|
||||
* the last, shall have 1000 contents octets. (Contrast with 8.21.6.)
|
||||
* </p>
|
||||
* <b>10: Distinguished encoding rules</b>
|
||||
* </p><p>
|
||||
* <b>10.1 Length forms</b>
|
||||
* The definite form of length encoding shall be used,
|
||||
* encoded in the minimum number of octets.
|
||||
* [Contrast with 8.1.3.2 b).]
|
||||
* </p><p>
|
||||
* <b>10.2 String encoding forms</b>
|
||||
* For BIT STRING, OCTET STRING and restricted character string types,
|
||||
* the constructed form of encoding shall not be used.
|
||||
* (Contrast with 8.21.6.)
|
||||
* </p>
|
||||
*/
|
||||
public abstract class ASN1OctetString
|
||||
extends ASN1Primitive
|
||||
implements ASN1OctetStringParser
|
||||
@ -88,16 +178,31 @@ public abstract class ASN1OctetString
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the content of the OCTET STRING as an InputStream.
|
||||
*
|
||||
* @return an InputStream representing the OCTET STRING's content.
|
||||
*/
|
||||
public InputStream getOctetStream()
|
||||
{
|
||||
return new ByteArrayInputStream(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parser associated with this object.
|
||||
*
|
||||
* @return a parser based on this OCTET STRING
|
||||
*/
|
||||
public ASN1OctetStringParser parser()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the content of the OCTET STRING as a byte array.
|
||||
*
|
||||
* @return the byte[] representing the OCTET STRING's content.
|
||||
*/
|
||||
public byte[] getOctets()
|
||||
{
|
||||
return string;
|
||||
|
@ -2,8 +2,16 @@ package org.spongycastle.asn1;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* A basic parser for an OCTET STRING object
|
||||
*/
|
||||
public interface ASN1OctetStringParser
|
||||
extends ASN1Encodable, InMemoryRepresentable
|
||||
{
|
||||
/**
|
||||
* Return the content of the OCTET STRING as an InputStream.
|
||||
*
|
||||
* @return an InputStream representing the OCTET STRING's content.
|
||||
*/
|
||||
public InputStream getOctetStream();
|
||||
}
|
||||
|
@ -2,6 +2,9 @@ package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Base class for ASN.1 primitive objects. These are the actual objects used to generate byte encodings.
|
||||
*/
|
||||
public abstract class ASN1Primitive
|
||||
extends ASN1Object
|
||||
{
|
||||
@ -47,11 +50,21 @@ public abstract class ASN1Primitive
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current object as one which encodes using Distinguished Encoding Rules.
|
||||
*
|
||||
* @return a DER version of this.
|
||||
*/
|
||||
ASN1Primitive toDERObject()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current object as one which encodes using Definite Length encoding.
|
||||
*
|
||||
* @return a DL version of this.
|
||||
*/
|
||||
ASN1Primitive toDLObject()
|
||||
{
|
||||
return this;
|
||||
|
@ -4,16 +4,64 @@ import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* ASN.1 <code>SEQUENCE</code> and <code>SEQUENCE OF</code> constructs.
|
||||
* <p>
|
||||
* DER form is always definite form length fields, while
|
||||
* BER support uses indefinite form.
|
||||
* <hr>
|
||||
* <p><b>X.690</b></p>
|
||||
* <p><b>8: Basic encoding rules</b></p>
|
||||
* <p><b>8.9 Encoding of a sequence value </b></p>
|
||||
* 8.9.1 The encoding of a sequence value shall be constructed.
|
||||
* <p>
|
||||
* <b>8.9.2</b> The contents octets shall consist of the complete
|
||||
* encoding of one data value from each of the types listed in
|
||||
* the ASN.1 definition of the sequence type, in the order of
|
||||
* their appearance in the definition, unless the type was referenced
|
||||
* with the keyword <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
|
||||
* </p><p>
|
||||
* <b>8.9.3</b> The encoding of a data value may, but need not,
|
||||
* be present for a type which was referenced with the keyword
|
||||
* <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
|
||||
* If present, it shall appear in the encoding at the point
|
||||
* corresponding to the appearance of the type in the ASN.1 definition.
|
||||
* </p><p>
|
||||
* <b>8.10 Encoding of a sequence-of value </b>
|
||||
* </p><p>
|
||||
* <b>8.10.1</b> The encoding of a sequence-of value shall be constructed.
|
||||
* <p>
|
||||
* <b>8.10.2</b> The contents octets shall consist of zero,
|
||||
* one or more complete encodings of data values from the type listed in
|
||||
* the ASN.1 definition.
|
||||
* <p>
|
||||
* <b>8.10.3</b> The order of the encodings of the data values shall be
|
||||
* the same as the order of the data values in the sequence-of value to
|
||||
* be encoded.
|
||||
* </p>
|
||||
* <p><b>9: Canonical encoding rules</b></p>
|
||||
* <p><b>9.1 Length forms</b></p>
|
||||
* If the encoding is constructed, it shall employ the indefinite length form.
|
||||
* If the encoding is primitive, it shall include the fewest length octets necessary.
|
||||
* [Contrast with 8.1.3.2 b).]
|
||||
*
|
||||
* <p><b>11: Restrictions on BER employed by both CER and DER</b></p>
|
||||
* <p><b>11.5 Set and sequence components with default value</b></p>
|
||||
* The encoding of a set value or sequence value shall not include
|
||||
* an encoding for any component value which is equal to
|
||||
* its default value.
|
||||
*/
|
||||
public abstract class ASN1Sequence
|
||||
extends ASN1Primitive
|
||||
{
|
||||
protected Vector seq = new Vector();
|
||||
|
||||
/**
|
||||
* return an ASN1Sequence from the given object.
|
||||
* Return an ASN1Sequence from the given object.
|
||||
*
|
||||
* @param obj the object we want converted.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return an ASN1Sequence instance, or null.
|
||||
*/
|
||||
public static ASN1Sequence getInstance(
|
||||
Object obj)
|
||||
@ -65,6 +113,7 @@ public abstract class ASN1Sequence
|
||||
* false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
* @return an ASN1Sequence instance.
|
||||
*/
|
||||
public static ASN1Sequence getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
@ -110,14 +159,15 @@ public abstract class ASN1Sequence
|
||||
}
|
||||
|
||||
/**
|
||||
* create an empty sequence
|
||||
* Create an empty sequence
|
||||
*/
|
||||
protected ASN1Sequence()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* create a sequence containing one object
|
||||
* Create a sequence containing one object
|
||||
* @param obj the object to be put in the SEQUENCE.
|
||||
*/
|
||||
protected ASN1Sequence(
|
||||
ASN1Encodable obj)
|
||||
@ -126,7 +176,8 @@ public abstract class ASN1Sequence
|
||||
}
|
||||
|
||||
/**
|
||||
* create a sequence containing a vector of objects.
|
||||
* Create a sequence containing a vector of objects.
|
||||
* @param v the vector of objects to be put in the SEQUENCE
|
||||
*/
|
||||
protected ASN1Sequence(
|
||||
ASN1EncodableVector v)
|
||||
@ -138,7 +189,7 @@ public abstract class ASN1Sequence
|
||||
}
|
||||
|
||||
/**
|
||||
* create a sequence containing a vector of objects.
|
||||
* Create a sequence containing a vector of objects.
|
||||
*/
|
||||
protected ASN1Sequence(
|
||||
ASN1Encodable[] array)
|
||||
@ -209,7 +260,7 @@ public abstract class ASN1Sequence
|
||||
}
|
||||
|
||||
/**
|
||||
* return the object at the sequence position indicated by index.
|
||||
* Return the object at the sequence position indicated by index.
|
||||
*
|
||||
* @param index the sequence number (starting at zero) of the object
|
||||
* @return the object at the sequence position indicated by index.
|
||||
@ -221,7 +272,7 @@ public abstract class ASN1Sequence
|
||||
}
|
||||
|
||||
/**
|
||||
* return the number of objects in this sequence.
|
||||
* Return the number of objects in this sequence.
|
||||
*
|
||||
* @return the number of objects in this sequence.
|
||||
*/
|
||||
@ -290,6 +341,10 @@ public abstract class ASN1Sequence
|
||||
return encObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change current SEQUENCE object to be encoded as {@link DERSequence}.
|
||||
* This is part of Distinguished Encoding Rules form serialization.
|
||||
*/
|
||||
ASN1Primitive toDERObject()
|
||||
{
|
||||
ASN1Sequence derSeq = new DERSequence();
|
||||
@ -299,6 +354,10 @@ public abstract class ASN1Sequence
|
||||
return derSeq;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change current SEQUENCE object to be encoded as {@link DLSequence}.
|
||||
* This is part of Direct Length form serialization.
|
||||
*/
|
||||
ASN1Primitive toDLObject()
|
||||
{
|
||||
ASN1Sequence dlSeq = new DLSequence();
|
||||
|
@ -2,9 +2,18 @@ package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A basic parser for a SEQUENCE object
|
||||
*/
|
||||
public interface ASN1SequenceParser
|
||||
extends ASN1Encodable, InMemoryRepresentable
|
||||
{
|
||||
/**
|
||||
* Read the next object from the underlying object representing a SEQUENCE.
|
||||
*
|
||||
* @throws IOException for bad input stream.
|
||||
* @return the next object, null if we are at the end.
|
||||
*/
|
||||
ASN1Encodable readObject()
|
||||
throws IOException;
|
||||
}
|
||||
|
@ -5,7 +5,94 @@ import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
abstract public class ASN1Set
|
||||
/**
|
||||
* ASN.1 <code>SET</code> and <code>SET OF</code> constructs.
|
||||
* <p>
|
||||
* Note: This does not know which syntax the set is!
|
||||
* (The difference: ordering of SET elements or not ordering.)
|
||||
* <p>
|
||||
* DER form is always definite form length fields, while
|
||||
* BER support uses indefinite form.
|
||||
* <p>
|
||||
* The CER form support does not exist.
|
||||
* <p>
|
||||
* <hr>
|
||||
* <h2>X.690</h2>
|
||||
* <h3>8: Basic encoding rules</h3>
|
||||
* <h4>8.11 Encoding of a set value </h4>
|
||||
* <b>8.11.1</b> The encoding of a set value shall be constructed
|
||||
* <p>
|
||||
* <b>8.11.2</b> The contents octets shall consist of the complete
|
||||
* encoding of a data value from each of the types listed in the
|
||||
* ASN.1 definition of the set type, in an order chosen by the sender,
|
||||
* unless the type was referenced with the keyword
|
||||
* <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
|
||||
* <p>
|
||||
* <b>8.11.3</b> The encoding of a data value may, but need not,
|
||||
* be present for a type which was referenced with the keyword
|
||||
* <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
|
||||
* <blockquote>
|
||||
* NOTE — 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 — 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 — The padding octets are for comparison purposes only
|
||||
* and do not appear in the encodings.
|
||||
* </blockquote>
|
||||
*/
|
||||
public abstract class ASN1Set
|
||||
extends ASN1Primitive
|
||||
{
|
||||
private Vector set = new Vector();
|
||||
@ -16,6 +103,7 @@ abstract public class ASN1Set
|
||||
*
|
||||
* @param obj the object we want converted.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return an ASN1Set instance, or null.
|
||||
*/
|
||||
public static ASN1Set getInstance(
|
||||
Object obj)
|
||||
@ -67,6 +155,7 @@ abstract public class ASN1Set
|
||||
* false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
* @return an ASN1Set instance.
|
||||
*/
|
||||
public static ASN1Set getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
@ -135,6 +224,7 @@ abstract public class ASN1Set
|
||||
|
||||
/**
|
||||
* create a sequence containing one object
|
||||
* @param obj object to be added to the SET.
|
||||
*/
|
||||
protected ASN1Set(
|
||||
ASN1Encodable obj)
|
||||
@ -144,6 +234,8 @@ abstract public class ASN1Set
|
||||
|
||||
/**
|
||||
* create a sequence containing a vector of objects.
|
||||
* @param v a vector of objects to make up the SET.
|
||||
* @param doSort true if should be sorted DER style, false otherwise.
|
||||
*/
|
||||
protected ASN1Set(
|
||||
ASN1EncodableVector v,
|
||||
@ -275,6 +367,10 @@ abstract public class ASN1Set
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change current SET object to be encoded as {@link DERSet}.
|
||||
* This is part of Distinguished Encoding Rules form serialization.
|
||||
*/
|
||||
ASN1Primitive toDERObject()
|
||||
{
|
||||
if (isSorted)
|
||||
@ -304,6 +400,10 @@ abstract public class ASN1Set
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change current SET object to be encoded as {@link DLSet}.
|
||||
* This is part of Direct Length form serialization.
|
||||
*/
|
||||
ASN1Primitive toDLObject()
|
||||
{
|
||||
ASN1Set derSet = new DLSet();
|
||||
|
@ -2,9 +2,18 @@ package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A basic parser for a SET object
|
||||
*/
|
||||
public interface ASN1SetParser
|
||||
extends ASN1Encodable, InMemoryRepresentable
|
||||
{
|
||||
/**
|
||||
* Read the next object from the underlying object representing a SET.
|
||||
*
|
||||
* @throws IOException for bad input stream.
|
||||
* @return the next object, null if we are at the end.
|
||||
*/
|
||||
public ASN1Encodable readObject()
|
||||
throws IOException;
|
||||
}
|
||||
|
@ -4,6 +4,9 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* A parser for ASN.1 streams which also returns, where possible, parsers for the objects it encounters.
|
||||
*/
|
||||
public class ASN1StreamParser
|
||||
{
|
||||
private final InputStream _in;
|
||||
|
@ -1,22 +1,314 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.SimpleTimeZone;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.Strings;
|
||||
|
||||
/**
|
||||
- * UTC time object.
|
||||
* Internal facade of {@link ASN1UTCTime}.
|
||||
* <p>
|
||||
* This datatype is valid only from 1950-01-01 00:00:00 UTC until 2049-12-31 23:59:59 UTC.
|
||||
* <p>
|
||||
* <hr>
|
||||
* <p><b>X.690</b></p>
|
||||
* <p><b>11: Restrictions on BER employed by both CER and DER</b></p>
|
||||
* <p><b>11.8 UTCTime </b></p>
|
||||
* <b>11.8.1</b> The encoding shall terminate with "Z",
|
||||
* as described in the ITU-T X.680 | ISO/IEC 8824-1 clause on UTCTime.
|
||||
* <p>
|
||||
* <b>11.8.2</b> The seconds element shall always be present.
|
||||
* <p>
|
||||
* <b>11.8.3</b> Midnight (GMT) shall be represented in the form:
|
||||
* <blockquote>
|
||||
* "YYMMDD000000Z"
|
||||
* </blockquote>
|
||||
* where "YYMMDD" represents the day following the midnight in question.
|
||||
*/
|
||||
public class ASN1UTCTime
|
||||
extends DERUTCTime
|
||||
extends ASN1Primitive
|
||||
{
|
||||
ASN1UTCTime(byte[] bytes)
|
||||
private byte[] time;
|
||||
|
||||
/**
|
||||
* return an UTC Time from the passed in object.
|
||||
*
|
||||
* @param obj an ASN1UTCTime or an object that can be converted into one.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return an ASN1UTCTime instance, or null.
|
||||
*/
|
||||
public static ASN1UTCTime getInstance(
|
||||
Object obj)
|
||||
{
|
||||
super(bytes);
|
||||
if (obj == null || obj instanceof ASN1UTCTime)
|
||||
{
|
||||
return (ASN1UTCTime)obj;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -103,15 +103,6 @@ public class DERApplicationSpecific
|
||||
throw new IllegalArgumentException("failed to construct object from byte[]: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
else if (obj instanceof ASN1Encodable)
|
||||
{
|
||||
ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
|
||||
|
||||
if (primitive instanceof ASN1Sequence)
|
||||
{
|
||||
return (DERApplicationSpecific)primitive;
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ public class DERBMPString
|
||||
*
|
||||
* @param obj the object we want converted.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return a DERBMPString instance, or null.
|
||||
*/
|
||||
public static DERBMPString getInstance(
|
||||
Object obj)
|
||||
@ -50,6 +51,7 @@ public class DERBMPString
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
* @return a DERBMPString instance.
|
||||
*/
|
||||
public static DERBMPString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
@ -69,6 +71,7 @@ public class DERBMPString
|
||||
|
||||
/**
|
||||
* basic constructor - byte encoded string.
|
||||
* @param string the encoded BMP STRING to wrap.
|
||||
*/
|
||||
DERBMPString(
|
||||
byte[] string)
|
||||
@ -90,6 +93,7 @@ public class DERBMPString
|
||||
|
||||
/**
|
||||
* basic constructor
|
||||
* @param string a String to wrap as a BMP STRING.
|
||||
*/
|
||||
public DERBMPString(
|
||||
String string)
|
||||
|
@ -18,7 +18,8 @@ public class DERBitString
|
||||
protected int padBits;
|
||||
|
||||
/**
|
||||
* return the correct number of pad bits for a bit string defined in
|
||||
* @param bitString an int containing the BIT STRING
|
||||
* @return the correct number of pad bits for a bit string defined in
|
||||
* a 32 bit constant
|
||||
*/
|
||||
static protected int getPadBits(
|
||||
@ -66,7 +67,8 @@ public class DERBitString
|
||||
}
|
||||
|
||||
/**
|
||||
* return the correct number of bytes for a bit string defined in
|
||||
* @param bitString an int containing the BIT STRING
|
||||
* @return the correct number of bytes for a bit string defined in
|
||||
* a 32 bit constant
|
||||
*/
|
||||
static protected byte[] getBytes(int bitString)
|
||||
@ -93,7 +95,9 @@ public class DERBitString
|
||||
/**
|
||||
* return a Bit String from the passed in object
|
||||
*
|
||||
* @param obj a DERBitString or an object that can be converted into one.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return a DERBitString instance, or null.
|
||||
*/
|
||||
public static DERBitString getInstance(
|
||||
Object obj)
|
||||
@ -114,6 +118,7 @@ public class DERBitString
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
* @return a DERBitString instance, or null.
|
||||
*/
|
||||
public static DERBitString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
|
@ -1,179 +1,22 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
|
||||
/**
|
||||
* @deprecated use ASN1Boolean
|
||||
*/
|
||||
public class DERBoolean
|
||||
extends ASN1Primitive
|
||||
extends ASN1Boolean
|
||||
{
|
||||
private static final byte[] TRUE_VALUE = new byte[] { (byte)0xff };
|
||||
private static final byte[] FALSE_VALUE = new byte[] { 0 };
|
||||
|
||||
private byte[] value;
|
||||
|
||||
public static final ASN1Boolean FALSE = new ASN1Boolean(false);
|
||||
public static final ASN1Boolean TRUE = new ASN1Boolean(true);
|
||||
|
||||
|
||||
/**
|
||||
* return a boolean from the passed in object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static ASN1Boolean getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof ASN1Boolean)
|
||||
{
|
||||
return (ASN1Boolean)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof DERBoolean)
|
||||
{
|
||||
return ((DERBoolean)obj).isTrue() ? DERBoolean.TRUE : DERBoolean.FALSE;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return a ASN1Boolean from the passed in boolean.
|
||||
*/
|
||||
public static ASN1Boolean getInstance(
|
||||
boolean value)
|
||||
{
|
||||
return (value ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a ASN1Boolean from the passed in boolean.
|
||||
*/
|
||||
public static ASN1Boolean getInstance(
|
||||
int value)
|
||||
{
|
||||
return (value != 0 ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a Boolean from a tagged object.
|
||||
*
|
||||
* @param obj the tagged object holding the object we want
|
||||
* @param explicit true if the object is meant to be explicitly
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
*/
|
||||
public static ASN1Boolean getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
ASN1Primitive o = obj.getObject();
|
||||
|
||||
if (explicit || o instanceof DERBoolean)
|
||||
{
|
||||
return getInstance(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ASN1Boolean.fromOctetString(((ASN1OctetString)o).getOctets());
|
||||
}
|
||||
}
|
||||
|
||||
DERBoolean(
|
||||
byte[] value)
|
||||
{
|
||||
if (value.length != 1)
|
||||
{
|
||||
throw new IllegalArgumentException("byte value should have 1 byte in it");
|
||||
}
|
||||
|
||||
if (value[0] == 0)
|
||||
{
|
||||
this.value = FALSE_VALUE;
|
||||
}
|
||||
else if (value[0] == 0xff)
|
||||
{
|
||||
this.value = TRUE_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.value = Arrays.clone(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use getInstance(boolean) method.
|
||||
* @param value
|
||||
*/
|
||||
public DERBoolean(
|
||||
boolean value)
|
||||
public DERBoolean(boolean value)
|
||||
{
|
||||
this.value = (value) ? TRUE_VALUE : FALSE_VALUE;
|
||||
super(value);
|
||||
}
|
||||
|
||||
public boolean isTrue()
|
||||
DERBoolean(byte[] value)
|
||||
{
|
||||
return (value[0] != 0);
|
||||
}
|
||||
|
||||
boolean isConstructed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int encodedLength()
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
void encode(
|
||||
ASN1OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(BERTags.BOOLEAN, value);
|
||||
}
|
||||
|
||||
protected boolean asn1Equals(
|
||||
ASN1Primitive o)
|
||||
{
|
||||
if ((o == null) || !(o instanceof DERBoolean))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (value[0] == ((DERBoolean)o).value[0]);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return value[0];
|
||||
}
|
||||
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return (value[0] != 0) ? "TRUE" : "FALSE";
|
||||
}
|
||||
|
||||
static ASN1Boolean fromOctetString(byte[] value)
|
||||
{
|
||||
if (value.length != 1)
|
||||
{
|
||||
throw new IllegalArgumentException("BOOLEAN value should have 1 byte in it");
|
||||
}
|
||||
|
||||
if (value[0] == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
else if (value[0] == 0xff)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ASN1Boolean(value);
|
||||
}
|
||||
super(value);
|
||||
}
|
||||
}
|
||||
|
@ -1,170 +1,37 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
|
||||
/**
|
||||
* Use ASN1Enumerated instead of this.
|
||||
* @deprecated Use ASN1Enumerated instead of this.
|
||||
*/
|
||||
public class DEREnumerated
|
||||
extends ASN1Primitive
|
||||
extends ASN1Enumerated
|
||||
{
|
||||
byte[] bytes;
|
||||
|
||||
/**
|
||||
* return an integer from the passed in object
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static ASN1Enumerated getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof ASN1Enumerated)
|
||||
{
|
||||
return (ASN1Enumerated)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof DEREnumerated)
|
||||
{
|
||||
return new ASN1Enumerated(((DEREnumerated)obj).getValue());
|
||||
}
|
||||
|
||||
if (obj instanceof byte[])
|
||||
{
|
||||
try
|
||||
{
|
||||
return (ASN1Enumerated)fromByteArray((byte[])obj);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return an Enumerated from a tagged object.
|
||||
*
|
||||
* @param obj the tagged object holding the object we want
|
||||
* @param explicit true if the object is meant to be explicitly
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
*/
|
||||
public static ASN1Enumerated getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
ASN1Primitive o = obj.getObject();
|
||||
|
||||
if (explicit || o instanceof DEREnumerated)
|
||||
{
|
||||
return getInstance(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
return fromOctetString(((ASN1OctetString)o).getOctets());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bytes the value of this enumerated as an encoded BigInteger (signed).
|
||||
* @deprecated use ASN1Enumerated
|
||||
*/
|
||||
public DEREnumerated(
|
||||
int value)
|
||||
DEREnumerated(byte[] bytes)
|
||||
{
|
||||
bytes = BigInteger.valueOf(value).toByteArray();
|
||||
super(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value the value of this enumerated.
|
||||
* @deprecated use ASN1Enumerated
|
||||
*/
|
||||
public DEREnumerated(
|
||||
BigInteger value)
|
||||
public DEREnumerated(BigInteger value)
|
||||
{
|
||||
bytes = value.toByteArray();
|
||||
super(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param value the value of this enumerated.
|
||||
* @deprecated use ASN1Enumerated
|
||||
*/
|
||||
public DEREnumerated(
|
||||
byte[] bytes)
|
||||
public DEREnumerated(int value)
|
||||
{
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
public BigInteger getValue()
|
||||
{
|
||||
return new BigInteger(bytes);
|
||||
}
|
||||
|
||||
boolean isConstructed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int encodedLength()
|
||||
{
|
||||
return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
|
||||
}
|
||||
|
||||
void encode(
|
||||
ASN1OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(BERTags.ENUMERATED, bytes);
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
ASN1Primitive o)
|
||||
{
|
||||
if (!(o instanceof DEREnumerated))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DEREnumerated other = (DEREnumerated)o;
|
||||
|
||||
return Arrays.areEqual(this.bytes, other.bytes);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return Arrays.hashCode(bytes);
|
||||
}
|
||||
|
||||
private static ASN1Enumerated[] cache = new ASN1Enumerated[12];
|
||||
|
||||
static ASN1Enumerated fromOctetString(byte[] enc)
|
||||
{
|
||||
if (enc.length > 1)
|
||||
{
|
||||
return new ASN1Enumerated(Arrays.clone(enc));
|
||||
}
|
||||
|
||||
if (enc.length == 0)
|
||||
{
|
||||
throw new IllegalArgumentException("ENUMERATED has zero length");
|
||||
}
|
||||
int value = enc[0] & 0xff;
|
||||
|
||||
if (value >= cache.length)
|
||||
{
|
||||
return new ASN1Enumerated(Arrays.clone(enc));
|
||||
}
|
||||
|
||||
ASN1Enumerated possibleMatch = cache[value];
|
||||
|
||||
if (possibleMatch == null)
|
||||
{
|
||||
possibleMatch = cache[value] = new ASN1Enumerated(Arrays.clone(enc));
|
||||
}
|
||||
|
||||
return possibleMatch;
|
||||
super(value);
|
||||
}
|
||||
}
|
||||
|
@ -1,350 +1,28 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.SimpleTimeZone;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.Strings;
|
||||
|
||||
/**
|
||||
* Generalized time object.
|
||||
* DER Generalized time object.
|
||||
*/
|
||||
public class DERGeneralizedTime
|
||||
extends ASN1Primitive
|
||||
extends ASN1GeneralizedTime
|
||||
{
|
||||
private byte[] time;
|
||||
|
||||
/**
|
||||
* return a generalized time from the passed in object
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static ASN1GeneralizedTime getInstance(
|
||||
Object obj)
|
||||
DERGeneralizedTime(byte[] bytes)
|
||||
{
|
||||
if (obj == null || obj instanceof ASN1GeneralizedTime)
|
||||
{
|
||||
return (ASN1GeneralizedTime)obj;
|
||||
}
|
||||
|
||||
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());
|
||||
super(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* return a Generalized Time object from a tagged object.
|
||||
*
|
||||
* @param obj the tagged object holding the object we want
|
||||
* @param explicit true if the object is meant to be explicitly
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
*/
|
||||
public static ASN1GeneralizedTime getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
public DERGeneralizedTime(Date time)
|
||||
{
|
||||
ASN1Primitive o = obj.getObject();
|
||||
|
||||
if (explicit || o instanceof DERGeneralizedTime)
|
||||
{
|
||||
return getInstance(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z
|
||||
* for local time, or Z+-HHMM on the end, for difference between local
|
||||
* time and UTC time. The fractional second amount f must consist of at
|
||||
* least one number with trailing zeroes removed.
|
||||
*
|
||||
* @param time the time string.
|
||||
* @exception IllegalArgumentException if String is an illegal format.
|
||||
*/
|
||||
public DERGeneralizedTime(
|
||||
String time)
|
||||
{
|
||||
this.time = Strings.toByteArray(time);
|
||||
try
|
||||
{
|
||||
this.getDate();
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
throw new IllegalArgumentException("invalid date string: " + e.getMessage());
|
||||
}
|
||||
super(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* base constructor from a java.util.date object
|
||||
*/
|
||||
public DERGeneralizedTime(
|
||||
Date time)
|
||||
public DERGeneralizedTime(String time)
|
||||
{
|
||||
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
|
||||
|
||||
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
|
||||
|
||||
this.time = Strings.toByteArray(dateF.format(time));
|
||||
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()
|
||||
throws ParseException
|
||||
{
|
||||
SimpleDateFormat dateF;
|
||||
String stime = Strings.fromByteArray(time);
|
||||
String d = stime;
|
||||
|
||||
if (stime.endsWith("Z"))
|
||||
{
|
||||
if (hasFractionalSeconds())
|
||||
{
|
||||
dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'");
|
||||
}
|
||||
else
|
||||
{
|
||||
dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
|
||||
}
|
||||
|
||||
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
|
||||
}
|
||||
else if (stime.indexOf('-') > 0 || stime.indexOf('+') > 0)
|
||||
{
|
||||
d = this.getTime();
|
||||
if (hasFractionalSeconds())
|
||||
{
|
||||
dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSSz");
|
||||
}
|
||||
else
|
||||
{
|
||||
dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
|
||||
}
|
||||
|
||||
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasFractionalSeconds())
|
||||
{
|
||||
dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS");
|
||||
}
|
||||
else
|
||||
{
|
||||
dateF = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
}
|
||||
|
||||
dateF.setTimeZone(new SimpleTimeZone(0, TimeZone.getDefault().getID()));
|
||||
}
|
||||
|
||||
if (hasFractionalSeconds())
|
||||
{
|
||||
// java misinterprets extra digits as being milliseconds...
|
||||
String frac = d.substring(14);
|
||||
int index;
|
||||
for (index = 1; index < frac.length(); index++)
|
||||
{
|
||||
char ch = frac.charAt(index);
|
||||
if (!('0' <= ch && ch <= '9'))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index - 1 > 3)
|
||||
{
|
||||
frac = frac.substring(0, 4) + frac.substring(index);
|
||||
d = d.substring(0, 14) + frac;
|
||||
}
|
||||
else if (index - 1 == 1)
|
||||
{
|
||||
frac = frac.substring(0, index) + "00" + frac.substring(index);
|
||||
d = d.substring(0, 14) + frac;
|
||||
}
|
||||
else if (index - 1 == 2)
|
||||
{
|
||||
frac = frac.substring(0, index) + "0" + frac.substring(index);
|
||||
d = d.substring(0, 14) + frac;
|
||||
}
|
||||
}
|
||||
|
||||
return dateF.parse(d);
|
||||
}
|
||||
|
||||
private boolean hasFractionalSeconds()
|
||||
{
|
||||
for (int i = 0; i != time.length; i++)
|
||||
{
|
||||
if (time[i] == '.')
|
||||
{
|
||||
if (i == 14)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isConstructed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int encodedLength()
|
||||
{
|
||||
int length = time.length;
|
||||
|
||||
return 1 + StreamUtil.calculateBodyLength(length) + length;
|
||||
}
|
||||
|
||||
void encode(
|
||||
ASN1OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(BERTags.GENERALIZED_TIME, time);
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
ASN1Primitive o)
|
||||
{
|
||||
if (!(o instanceof DERGeneralizedTime))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Arrays.areEqual(time, ((DERGeneralizedTime)o).time);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return Arrays.hashCode(time);
|
||||
}
|
||||
// TODO: create proper DER encoding.
|
||||
}
|
||||
|
@ -17,7 +17,9 @@ public class DERIA5String
|
||||
/**
|
||||
* return a IA5 string from the passed in object
|
||||
*
|
||||
* @param obj a DERIA5String or an object that can be converted into one.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return a DERIA5String instance, or null.
|
||||
*/
|
||||
public static DERIA5String getInstance(
|
||||
Object obj)
|
||||
@ -50,6 +52,7 @@ public class DERIA5String
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
* @return a DERIA5String instance, or null.
|
||||
*/
|
||||
public static DERIA5String getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
@ -69,6 +72,7 @@ public class DERIA5String
|
||||
|
||||
/**
|
||||
* basic constructor - with bytes.
|
||||
* @param string the byte encoding of the characters making up the string.
|
||||
*/
|
||||
DERIA5String(
|
||||
byte[] string)
|
||||
@ -78,6 +82,7 @@ public class DERIA5String
|
||||
|
||||
/**
|
||||
* basic constructor - without validation.
|
||||
* @param string the base string to use..
|
||||
*/
|
||||
public DERIA5String(
|
||||
String string)
|
||||
@ -163,7 +168,8 @@ public class DERIA5String
|
||||
* return true if the passed in String can be represented without
|
||||
* loss as an IA5String, false otherwise.
|
||||
*
|
||||
* @return true if in printable set, false otherwise.
|
||||
* @param str the string to check.
|
||||
* @return true if character set in IA5String set, false otherwise.
|
||||
*/
|
||||
public static boolean isIA5String(
|
||||
String str)
|
||||
|
@ -1,160 +1,30 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
|
||||
/**
|
||||
* Use ASN1Integer instead of this,
|
||||
* @deprecated Use ASN1Integer instead of this,
|
||||
*/
|
||||
public class DERInteger
|
||||
extends ASN1Primitive
|
||||
extends ASN1Integer
|
||||
{
|
||||
byte[] bytes;
|
||||
|
||||
/**
|
||||
* return an integer from the passed in object
|
||||
* Constructor from a byte array containing a signed representation of the number.
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @param bytes a byte array containing the signed number.A copy is made of the byte array.
|
||||
*/
|
||||
public static ASN1Integer getInstance(
|
||||
Object obj)
|
||||
public DERInteger(byte[] bytes)
|
||||
{
|
||||
if (obj == null || obj instanceof ASN1Integer)
|
||||
{
|
||||
return (ASN1Integer)obj;
|
||||
}
|
||||
if (obj instanceof DERInteger)
|
||||
{
|
||||
return new ASN1Integer((((DERInteger)obj).getValue()));
|
||||
}
|
||||
|
||||
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());
|
||||
super(bytes, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* return an Integer from a tagged object.
|
||||
*
|
||||
* @param obj the tagged object holding the object we want
|
||||
* @param explicit true if the object is meant to be explicitly
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
*/
|
||||
public static ASN1Integer getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
public DERInteger(BigInteger value)
|
||||
{
|
||||
ASN1Primitive o = obj.getObject();
|
||||
|
||||
if (explicit || o instanceof DERInteger)
|
||||
{
|
||||
return getInstance(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ASN1Integer(ASN1OctetString.getInstance(obj.getObject()).getOctets());
|
||||
}
|
||||
super(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use ASN1Integer constructor
|
||||
*/
|
||||
public DERInteger(
|
||||
long value)
|
||||
public DERInteger(long value)
|
||||
{
|
||||
bytes = BigInteger.valueOf(value).toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use ASN1Integer constructor
|
||||
*/
|
||||
public DERInteger(
|
||||
BigInteger value)
|
||||
{
|
||||
bytes = value.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use ASN1Integer constructor
|
||||
*/
|
||||
public DERInteger(
|
||||
byte[] bytes)
|
||||
{
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
public BigInteger getValue()
|
||||
{
|
||||
return new BigInteger(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* in some cases positive values get crammed into a space,
|
||||
* that's not quite big enough...
|
||||
*/
|
||||
public BigInteger getPositiveValue()
|
||||
{
|
||||
return new BigInteger(1, bytes);
|
||||
}
|
||||
|
||||
boolean isConstructed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int encodedLength()
|
||||
{
|
||||
return 1 + StreamUtil.calculateBodyLength(bytes.length) + bytes.length;
|
||||
}
|
||||
|
||||
void encode(
|
||||
ASN1OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(BERTags.INTEGER, bytes);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
int value = 0;
|
||||
|
||||
for (int i = 0; i != bytes.length; i++)
|
||||
{
|
||||
value ^= (bytes[i] & 0xff) << (i % 4);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
ASN1Primitive o)
|
||||
{
|
||||
if (!(o instanceof DERInteger))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DERInteger other = (DERInteger)o;
|
||||
|
||||
return Arrays.areEqual(bytes, other.bytes);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getValue().toString();
|
||||
super(value);
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,9 @@ public class DERNumericString
|
||||
/**
|
||||
* return a Numeric string from the passed in object
|
||||
*
|
||||
* @param obj a DERNumericString or an object that can be converted into one.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return a DERNumericString instance, or null
|
||||
*/
|
||||
public static DERNumericString getInstance(
|
||||
Object obj)
|
||||
@ -50,6 +52,7 @@ public class DERNumericString
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
* @return a DERNumericString instance, or null.
|
||||
*/
|
||||
public static DERNumericString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
|
@ -1,446 +1,24 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
|
||||
/**
|
||||
* Use ASN1ObjectIdentifier instead of this,
|
||||
*
|
||||
* @deprecated Use ASN1ObjectIdentifier instead of this,
|
||||
*/
|
||||
public class DERObjectIdentifier
|
||||
extends ASN1Primitive
|
||||
extends ASN1ObjectIdentifier
|
||||
{
|
||||
String identifier;
|
||||
|
||||
private byte[] body;
|
||||
|
||||
/**
|
||||
* return an OID from the passed in object
|
||||
*
|
||||
* @throws IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static ASN1ObjectIdentifier getInstance(
|
||||
Object obj)
|
||||
public DERObjectIdentifier(String identifier)
|
||||
{
|
||||
if (obj == null || obj instanceof ASN1ObjectIdentifier)
|
||||
{
|
||||
return (ASN1ObjectIdentifier)obj;
|
||||
}
|
||||
|
||||
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());
|
||||
super(identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
DERObjectIdentifier(byte[] bytes)
|
||||
{
|
||||
ASN1Primitive o = obj.getObject();
|
||||
|
||||
if (explicit || o instanceof DERObjectIdentifier)
|
||||
{
|
||||
return getInstance(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ASN1ObjectIdentifier.fromOctetString(ASN1OctetString.getInstance(obj.getObject()).getOctets());
|
||||
}
|
||||
super(bytes);
|
||||
}
|
||||
|
||||
private static final long LONG_LIMIT = (Long.MAX_VALUE >> 7) - 0x7f;
|
||||
|
||||
DERObjectIdentifier(
|
||||
byte[] bytes)
|
||||
DERObjectIdentifier(ASN1ObjectIdentifier oid, String 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use ASN1ObjectIdentifier constructor.
|
||||
*/
|
||||
public DERObjectIdentifier(
|
||||
String identifier)
|
||||
{
|
||||
if (identifier == null)
|
||||
{
|
||||
throw new IllegalArgumentException("'identifier' cannot be null");
|
||||
}
|
||||
if (!isValidIdentifier(identifier))
|
||||
{
|
||||
throw new IllegalArgumentException("string " + identifier + " not an OID");
|
||||
}
|
||||
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
DERObjectIdentifier(DERObjectIdentifier oid, String branchID)
|
||||
{
|
||||
if (!isValidBranchID(branchID, 0))
|
||||
{
|
||||
throw new IllegalArgumentException("string " + branchID + " not a valid OID branch");
|
||||
}
|
||||
|
||||
this.identifier = oid.getId() + "." + branchID;
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
|
||||
private void writeField(
|
||||
ByteArrayOutputStream out,
|
||||
long fieldValue)
|
||||
{
|
||||
byte[] result = new byte[9];
|
||||
int pos = 8;
|
||||
result[pos] = (byte)((int)fieldValue & 0x7f);
|
||||
while (fieldValue >= (1L << 7))
|
||||
{
|
||||
fieldValue >>= 7;
|
||||
result[--pos] = (byte)((int)fieldValue & 0x7f | 0x80);
|
||||
}
|
||||
out.write(result, pos, 9 - pos);
|
||||
}
|
||||
|
||||
private void writeField(
|
||||
ByteArrayOutputStream out,
|
||||
BigInteger fieldValue)
|
||||
{
|
||||
int byteCount = (fieldValue.bitLength() + 6) / 7;
|
||||
if (byteCount == 0)
|
||||
{
|
||||
out.write(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
BigInteger tmpValue = fieldValue;
|
||||
byte[] tmp = new byte[byteCount];
|
||||
for (int i = byteCount - 1; i >= 0; i--)
|
||||
{
|
||||
tmp[i] = (byte)((tmpValue.intValue() & 0x7f) | 0x80);
|
||||
tmpValue = tmpValue.shiftRight(7);
|
||||
}
|
||||
tmp[byteCount - 1] &= 0x7f;
|
||||
out.write(tmp, 0, tmp.length);
|
||||
}
|
||||
}
|
||||
|
||||
private void doOutput(ByteArrayOutputStream aOut)
|
||||
{
|
||||
OIDTokenizer tok = new OIDTokenizer(identifier);
|
||||
int first = Integer.parseInt(tok.nextToken()) * 40;
|
||||
|
||||
String secondToken = tok.nextToken();
|
||||
if (secondToken.length() <= 18)
|
||||
{
|
||||
writeField(aOut, first + Long.parseLong(secondToken));
|
||||
}
|
||||
else
|
||||
{
|
||||
writeField(aOut, new BigInteger(secondToken).add(BigInteger.valueOf(first)));
|
||||
}
|
||||
|
||||
while (tok.hasMoreTokens())
|
||||
{
|
||||
String token = tok.nextToken();
|
||||
if (token.length() <= 18)
|
||||
{
|
||||
writeField(aOut, Long.parseLong(token));
|
||||
}
|
||||
else
|
||||
{
|
||||
writeField(aOut, new BigInteger(token));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected synchronized byte[] getBody()
|
||||
{
|
||||
if (body == null)
|
||||
{
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
|
||||
doOutput(bOut);
|
||||
|
||||
body = bOut.toByteArray();
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
boolean isConstructed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int encodedLength()
|
||||
throws IOException
|
||||
{
|
||||
int length = getBody().length;
|
||||
|
||||
return 1 + StreamUtil.calculateBodyLength(length) + length;
|
||||
}
|
||||
|
||||
void encode(
|
||||
ASN1OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
byte[] enc = getBody();
|
||||
|
||||
out.write(BERTags.OBJECT_IDENTIFIER);
|
||||
out.writeLength(enc.length);
|
||||
out.write(enc);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return identifier.hashCode();
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
ASN1Primitive o)
|
||||
{
|
||||
if (!(o instanceof DERObjectIdentifier))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return identifier.equals(((DERObjectIdentifier)o).identifier);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getId();
|
||||
}
|
||||
|
||||
private static boolean isValidBranchID(
|
||||
String branchID, int start)
|
||||
{
|
||||
boolean periodAllowed = false;
|
||||
|
||||
int pos = branchID.length();
|
||||
while (--pos >= start)
|
||||
{
|
||||
char ch = branchID.charAt(pos);
|
||||
|
||||
// TODO Leading zeroes?
|
||||
if ('0' <= ch && ch <= '9')
|
||||
{
|
||||
periodAllowed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '.')
|
||||
{
|
||||
if (!periodAllowed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
periodAllowed = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return periodAllowed;
|
||||
}
|
||||
|
||||
private static boolean isValidIdentifier(
|
||||
String identifier)
|
||||
{
|
||||
if (identifier.length() < 3 || identifier.charAt(1) != '.')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char first = identifier.charAt(0);
|
||||
if (first < '0' || first > '2')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return isValidBranchID(identifier, 2);
|
||||
}
|
||||
|
||||
private static ASN1ObjectIdentifier[][] cache = new ASN1ObjectIdentifier[256][];
|
||||
|
||||
static ASN1ObjectIdentifier fromOctetString(byte[] enc)
|
||||
{
|
||||
if (enc.length < 3)
|
||||
{
|
||||
return new ASN1ObjectIdentifier(enc);
|
||||
}
|
||||
|
||||
int idx1 = enc[enc.length - 2] & 0xff;
|
||||
// in this case top bit is always zero
|
||||
int idx2 = enc[enc.length - 1] & 0x7f;
|
||||
|
||||
ASN1ObjectIdentifier possibleMatch;
|
||||
|
||||
synchronized (cache)
|
||||
{
|
||||
ASN1ObjectIdentifier[] first = cache[idx1];
|
||||
if (first == null)
|
||||
{
|
||||
first = cache[idx1] = new ASN1ObjectIdentifier[128];
|
||||
}
|
||||
|
||||
possibleMatch = first[idx2];
|
||||
if (possibleMatch == null)
|
||||
{
|
||||
return first[idx2] = new ASN1ObjectIdentifier(enc);
|
||||
}
|
||||
|
||||
if (Arrays.areEqual(enc, possibleMatch.getBody()))
|
||||
{
|
||||
return possibleMatch;
|
||||
}
|
||||
|
||||
idx1 = (idx1 + 1) & 0xff;
|
||||
first = cache[idx1];
|
||||
if (first == null)
|
||||
{
|
||||
first = cache[idx1] = new ASN1ObjectIdentifier[128];
|
||||
}
|
||||
|
||||
possibleMatch = first[idx2];
|
||||
if (possibleMatch == null)
|
||||
{
|
||||
return first[idx2] = new ASN1ObjectIdentifier(enc);
|
||||
}
|
||||
|
||||
if (Arrays.areEqual(enc, possibleMatch.getBody()))
|
||||
{
|
||||
return possibleMatch;
|
||||
}
|
||||
|
||||
idx2 = (idx2 + 1) & 0x7f;
|
||||
possibleMatch = first[idx2];
|
||||
if (possibleMatch == null)
|
||||
{
|
||||
return first[idx2] = new ASN1ObjectIdentifier(enc);
|
||||
}
|
||||
}
|
||||
|
||||
if (Arrays.areEqual(enc, possibleMatch.getBody()))
|
||||
{
|
||||
return possibleMatch;
|
||||
}
|
||||
|
||||
return new ASN1ObjectIdentifier(enc);
|
||||
super(oid, branch);
|
||||
}
|
||||
}
|
||||
|
@ -16,8 +16,10 @@ public class DERPrintableString
|
||||
|
||||
/**
|
||||
* return a printable string from the passed in object.
|
||||
*
|
||||
*
|
||||
* @param obj a DERPrintableString or an object that can be converted into one.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return a DERPrintableString instance, or null.
|
||||
*/
|
||||
public static DERPrintableString getInstance(
|
||||
Object obj)
|
||||
@ -50,6 +52,7 @@ public class DERPrintableString
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
* @return a DERPrintableString instance, or null.
|
||||
*/
|
||||
public static DERPrintableString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
|
@ -18,7 +18,9 @@ public class DERT61String
|
||||
/**
|
||||
* return a T61 string from the passed in object.
|
||||
*
|
||||
* @param obj a DERT61String or an object that can be converted into one.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return a DERT61String instance, or null
|
||||
*/
|
||||
public static DERT61String getInstance(
|
||||
Object obj)
|
||||
@ -51,6 +53,7 @@ public class DERT61String
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
* @return a DERT61String instance, or null
|
||||
*/
|
||||
public static DERT61String getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
@ -70,6 +73,8 @@ public class DERT61String
|
||||
|
||||
/**
|
||||
* basic constructor - string encoded as a sequence of bytes.
|
||||
*
|
||||
* @param string the byte encoding of the string to be wrapped.
|
||||
*/
|
||||
public DERT61String(
|
||||
byte[] string)
|
||||
@ -79,6 +84,8 @@ public class DERT61String
|
||||
|
||||
/**
|
||||
* basic constructor - with string 8 bit assumed.
|
||||
*
|
||||
* @param string the string to be wrapped.
|
||||
*/
|
||||
public DERT61String(
|
||||
String string)
|
||||
|
@ -18,7 +18,9 @@ public class DERT61UTF8String
|
||||
/**
|
||||
* return a T61 string from the passed in object. UTF-8 Encoding is assumed in this case.
|
||||
*
|
||||
* @param obj a DERT61UTF8String or an object that can be converted into one.
|
||||
* @throws IllegalArgumentException if the object cannot be converted.
|
||||
* @return a DERT61UTF8String instance, or null
|
||||
*/
|
||||
public static DERT61UTF8String getInstance(
|
||||
Object obj)
|
||||
@ -56,6 +58,7 @@ public class DERT61UTF8String
|
||||
* tagged false otherwise.
|
||||
* @throws IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
* @return a DERT61UTF8String instance, or null
|
||||
*/
|
||||
public static DERT61UTF8String getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
|
@ -1,278 +1,27 @@
|
||||
package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.SimpleTimeZone;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.Strings;
|
||||
|
||||
/**
|
||||
* UTC time object.
|
||||
* DER UTC time object.
|
||||
*/
|
||||
public class DERUTCTime
|
||||
extends ASN1Primitive
|
||||
extends ASN1UTCTime
|
||||
{
|
||||
private byte[] time;
|
||||
|
||||
/**
|
||||
* return an UTC Time from the passed in object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static ASN1UTCTime getInstance(
|
||||
Object obj)
|
||||
DERUTCTime(byte[] bytes)
|
||||
{
|
||||
if (obj == null || obj instanceof ASN1UTCTime)
|
||||
{
|
||||
return (ASN1UTCTime)obj;
|
||||
}
|
||||
|
||||
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());
|
||||
super(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* return an UTC Time from a tagged object.
|
||||
*
|
||||
* @param obj the tagged object holding the object we want
|
||||
* @param explicit true if the object is meant to be explicitly
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
*/
|
||||
public static ASN1UTCTime getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
public DERUTCTime(Date time)
|
||||
{
|
||||
ASN1Object o = obj.getObject();
|
||||
|
||||
if (explicit || o instanceof ASN1UTCTime)
|
||||
{
|
||||
return getInstance(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ASN1UTCTime(((ASN1OctetString)o).getOctets());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
|
||||
* never encoded. When you're creating one of these objects from scratch, that's
|
||||
* what you want to use, otherwise we'll try to deal with whatever gets read from
|
||||
* the input stream... (this is why the input format is different from the getTime()
|
||||
* method output).
|
||||
* <p>
|
||||
*
|
||||
* @param time the time string.
|
||||
*/
|
||||
public DERUTCTime(
|
||||
String time)
|
||||
{
|
||||
this.time = Strings.toByteArray(time);
|
||||
try
|
||||
{
|
||||
this.getDate();
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
throw new IllegalArgumentException("invalid date string: " + e.getMessage());
|
||||
}
|
||||
super(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* base constructer from a java.util.date object
|
||||
*/
|
||||
public DERUTCTime(
|
||||
Date time)
|
||||
public DERUTCTime(String time)
|
||||
{
|
||||
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'");
|
||||
|
||||
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
|
||||
|
||||
this.time = Strings.toByteArray(dateF.format(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
|
||||
* @exception ParseException if the date string cannot be parsed.
|
||||
*/
|
||||
public Date getDate()
|
||||
throws ParseException
|
||||
{
|
||||
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmssz");
|
||||
|
||||
return dateF.parse(getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* return the time as an adjusted date
|
||||
* in the range of 1950 - 2049.
|
||||
*
|
||||
* @return a date in the range of 1950 to 2049.
|
||||
* @exception ParseException if the date string cannot be parsed.
|
||||
*/
|
||||
public Date getAdjustedDate()
|
||||
throws ParseException
|
||||
{
|
||||
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
|
||||
|
||||
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
|
||||
|
||||
return dateF.parse(getAdjustedTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* return the time - always in the form of
|
||||
* YYMMDDhhmmssGMT(+hh:mm|-hh:mm).
|
||||
* <p>
|
||||
* Normally in a certificate we would expect "Z" rather than "GMT",
|
||||
* however adding the "GMT" means we can just use:
|
||||
* <pre>
|
||||
* dateF = new SimpleDateFormat("yyMMddHHmmssz");
|
||||
* </pre>
|
||||
* To read in the time and get a date which is compatible with our local
|
||||
* time zone.
|
||||
* <p>
|
||||
* <b>Note:</b> In some cases, due to the local date processing, this
|
||||
* may lead to unexpected results. If you want to stick the normal
|
||||
* convention of 1950 to 2049 use the getAdjustedTime() method.
|
||||
*/
|
||||
public String getTime()
|
||||
{
|
||||
String stime = Strings.fromByteArray(time);
|
||||
|
||||
//
|
||||
// standardise the format.
|
||||
//
|
||||
if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0)
|
||||
{
|
||||
if (stime.length() == 11)
|
||||
{
|
||||
return stime.substring(0, 10) + "00GMT+00:00";
|
||||
}
|
||||
else
|
||||
{
|
||||
return stime.substring(0, 12) + "GMT+00:00";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = stime.indexOf('-');
|
||||
if (index < 0)
|
||||
{
|
||||
index = stime.indexOf('+');
|
||||
}
|
||||
String d = stime;
|
||||
|
||||
if (index == stime.length() - 3)
|
||||
{
|
||||
d += "00";
|
||||
}
|
||||
|
||||
if (index == 10)
|
||||
{
|
||||
return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15);
|
||||
}
|
||||
else
|
||||
{
|
||||
return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return a time string as an adjusted date with a 4 digit year. This goes
|
||||
* in the range of 1950 - 2049.
|
||||
*/
|
||||
public String getAdjustedTime()
|
||||
{
|
||||
String d = this.getTime();
|
||||
|
||||
if (d.charAt(0) < '5')
|
||||
{
|
||||
return "20" + d;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "19" + d;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isConstructed()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int encodedLength()
|
||||
{
|
||||
int length = time.length;
|
||||
|
||||
return 1 + StreamUtil.calculateBodyLength(length) + length;
|
||||
}
|
||||
|
||||
void encode(
|
||||
ASN1OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.write(BERTags.UTC_TIME);
|
||||
|
||||
int length = time.length;
|
||||
|
||||
out.writeLength(length);
|
||||
|
||||
for (int i = 0; i != length; i++)
|
||||
{
|
||||
out.write((byte)time[i]);
|
||||
}
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
ASN1Primitive o)
|
||||
{
|
||||
if (!(o instanceof DERUTCTime))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Arrays.areEqual(time, ((DERUTCTime)o).time);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return Arrays.hashCode(time);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return Strings.fromByteArray(time);
|
||||
}
|
||||
// TODO: create proper DER encoding.
|
||||
}
|
||||
|
@ -15,10 +15,12 @@ public class DERUTF8String
|
||||
private byte[] string;
|
||||
|
||||
/**
|
||||
* return an UTF8 string from the passed in object.
|
||||
*
|
||||
* Return an UTF8 string from the passed in object.
|
||||
*
|
||||
* @param obj a DERUTF8String or an object that can be converted into one.
|
||||
* @exception IllegalArgumentException
|
||||
* if the object cannot be converted.
|
||||
* @return a DERUTF8String instance, or null
|
||||
*/
|
||||
public static DERUTF8String getInstance(Object obj)
|
||||
{
|
||||
@ -44,7 +46,7 @@ public class DERUTF8String
|
||||
}
|
||||
|
||||
/**
|
||||
* return an UTF8 String from a tagged object.
|
||||
* Return an UTF8 String from a tagged object.
|
||||
*
|
||||
* @param obj
|
||||
* the tagged object holding the object we want
|
||||
@ -53,6 +55,7 @@ public class DERUTF8String
|
||||
* otherwise.
|
||||
* @exception IllegalArgumentException
|
||||
* if the tagged object cannot be converted.
|
||||
* @return a DERUTF8String instance, or null
|
||||
*/
|
||||
public static DERUTF8String getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
@ -71,7 +74,7 @@ public class DERUTF8String
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor - byte encoded string.
|
||||
* Basic constructor - byte encoded string.
|
||||
*/
|
||||
DERUTF8String(byte[] string)
|
||||
{
|
||||
@ -79,7 +82,7 @@ public class DERUTF8String
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor
|
||||
* Basic constructor
|
||||
*/
|
||||
public DERUTF8String(String string)
|
||||
{
|
||||
|
@ -18,7 +18,9 @@ public class DERUniversalString
|
||||
/**
|
||||
* return a Universal String from the passed in object.
|
||||
*
|
||||
* @param obj a DERUniversalString or an object that can be converted into one.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return a DERUniversalString instance, or null
|
||||
*/
|
||||
public static DERUniversalString getInstance(
|
||||
Object obj)
|
||||
@ -51,6 +53,7 @@ public class DERUniversalString
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
* @return a DERUniversalString instance, or null
|
||||
*/
|
||||
public static DERUniversalString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
|
@ -6,7 +6,10 @@ import org.spongycastle.util.Arrays;
|
||||
import org.spongycastle.util.Strings;
|
||||
|
||||
/**
|
||||
* DER VisibleString object.
|
||||
* DER VisibleString object encoding ISO 646 (ASCII) character code points 32 to 126.
|
||||
* <p>
|
||||
* Explicit character set escape sequences are not allowed.
|
||||
* </p>
|
||||
*/
|
||||
public class DERVisibleString
|
||||
extends ASN1Primitive
|
||||
@ -15,9 +18,11 @@ public class DERVisibleString
|
||||
private byte[] string;
|
||||
|
||||
/**
|
||||
* return a Visible String from the passed in object.
|
||||
* Return a Visible String from the passed in object.
|
||||
*
|
||||
* @param obj a DERVisibleString or an object that can be converted into one.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
* @return a DERVisibleString instance, or null
|
||||
*/
|
||||
public static DERVisibleString getInstance(
|
||||
Object obj)
|
||||
@ -43,13 +48,14 @@ public class DERVisibleString
|
||||
}
|
||||
|
||||
/**
|
||||
* return a Visible String from a tagged object.
|
||||
* Return a Visible String from a tagged object.
|
||||
*
|
||||
* @param obj the tagged object holding the object we want
|
||||
* @param explicit true if the object is meant to be explicitly
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
* @return a DERVisibleString instance, or null
|
||||
*/
|
||||
public static DERVisibleString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
@ -68,7 +74,7 @@ public class DERVisibleString
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor - byte encoded string.
|
||||
* Basic constructor - byte encoded string.
|
||||
*/
|
||||
DERVisibleString(
|
||||
byte[] string)
|
||||
@ -77,7 +83,7 @@ public class DERVisibleString
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor
|
||||
* Basic constructor
|
||||
*/
|
||||
public DERVisibleString(
|
||||
String string)
|
||||
|
@ -11,13 +11,13 @@ import java.util.Enumeration;
|
||||
* <h3>8: Basic encoding rules</h3>
|
||||
* <h4>8.11 Encoding of a set value </h4>
|
||||
* <b>8.11.1</b> The encoding of a set value shall be constructed
|
||||
* <p/>
|
||||
* <p>
|
||||
* <b>8.11.2</b> The contents octets shall consist of the complete
|
||||
* encoding of a data value from each of the types listed in the
|
||||
* ASN.1 definition of the set type, in an order chosen by the sender,
|
||||
* unless the type was referenced with the keyword
|
||||
* <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
|
||||
* <p/>
|
||||
* <p>
|
||||
* <b>8.11.3</b> The encoding of a data value may, but need not,
|
||||
* be present for a type which was referenced with the keyword
|
||||
* <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
|
||||
|
@ -2,8 +2,15 @@ package org.spongycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Interface implemented by objects that can be converted from streaming to in-memory objects.
|
||||
*/
|
||||
public interface InMemoryRepresentable
|
||||
{
|
||||
/**
|
||||
* Get the in-memory representation of the ASN.1 object.
|
||||
* @throws IOException for bad input data.
|
||||
*/
|
||||
ASN1Primitive getLoadedObject()
|
||||
throws IOException;
|
||||
}
|
||||
|
35
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/bsi/BSIObjectIdentifiers.java
vendored
Normal file
35
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/bsi/BSIObjectIdentifiers.java
vendored
Normal 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");
|
||||
}
|
@ -4,13 +4,13 @@ import java.util.Enumeration;
|
||||
|
||||
import org.spongycastle.asn1.ASN1Encodable;
|
||||
import org.spongycastle.asn1.ASN1EncodableVector;
|
||||
import org.spongycastle.asn1.ASN1GeneralizedTime;
|
||||
import org.spongycastle.asn1.ASN1Integer;
|
||||
import org.spongycastle.asn1.ASN1Object;
|
||||
import org.spongycastle.asn1.ASN1OctetString;
|
||||
import org.spongycastle.asn1.ASN1Primitive;
|
||||
import org.spongycastle.asn1.ASN1Sequence;
|
||||
import org.spongycastle.asn1.ASN1TaggedObject;
|
||||
import org.spongycastle.asn1.DERGeneralizedTime;
|
||||
import org.spongycastle.asn1.DERSequence;
|
||||
import org.spongycastle.asn1.DERTaggedObject;
|
||||
import org.spongycastle.asn1.x500.X500Name;
|
||||
@ -31,7 +31,7 @@ public class PKIHeader
|
||||
private ASN1Integer pvno;
|
||||
private GeneralName sender;
|
||||
private GeneralName recipient;
|
||||
private DERGeneralizedTime messageTime;
|
||||
private ASN1GeneralizedTime messageTime;
|
||||
private AlgorithmIdentifier protectionAlg;
|
||||
private ASN1OctetString senderKID; // KeyIdentifier
|
||||
private ASN1OctetString recipKID; // KeyIdentifier
|
||||
@ -56,7 +56,7 @@ public class PKIHeader
|
||||
switch (tObj.getTagNo())
|
||||
{
|
||||
case 0:
|
||||
messageTime = DERGeneralizedTime.getInstance(tObj, true);
|
||||
messageTime = ASN1GeneralizedTime.getInstance(tObj, true);
|
||||
break;
|
||||
case 1:
|
||||
protectionAlg = AlgorithmIdentifier.getInstance(tObj, true);
|
||||
@ -136,7 +136,7 @@ public class PKIHeader
|
||||
return recipient;
|
||||
}
|
||||
|
||||
public DERGeneralizedTime getMessageTime()
|
||||
public ASN1GeneralizedTime getMessageTime()
|
||||
{
|
||||
return messageTime;
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import org.spongycastle.asn1.ASN1GeneralizedTime;
|
||||
import org.spongycastle.asn1.ASN1Integer;
|
||||
import org.spongycastle.asn1.ASN1OctetString;
|
||||
import org.spongycastle.asn1.ASN1Sequence;
|
||||
import org.spongycastle.asn1.DERGeneralizedTime;
|
||||
import org.spongycastle.asn1.DEROctetString;
|
||||
import org.spongycastle.asn1.DERSequence;
|
||||
import org.spongycastle.asn1.DERTaggedObject;
|
||||
@ -46,16 +45,6 @@ public class PKIHeaderBuilder
|
||||
this.recipient = recipient;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use ASN1GeneralizedTime
|
||||
*/
|
||||
public PKIHeaderBuilder setMessageTime(DERGeneralizedTime time)
|
||||
{
|
||||
messageTime = ASN1GeneralizedTime.getInstance(time);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public PKIHeaderBuilder setMessageTime(ASN1GeneralizedTime time)
|
||||
{
|
||||
messageTime = time;
|
||||
|
@ -7,7 +7,6 @@ import org.spongycastle.asn1.ASN1ObjectIdentifier;
|
||||
import org.spongycastle.asn1.ASN1Primitive;
|
||||
import org.spongycastle.asn1.ASN1Sequence;
|
||||
import org.spongycastle.asn1.ASN1Set;
|
||||
import org.spongycastle.asn1.DERObjectIdentifier;
|
||||
import org.spongycastle.asn1.DERSequence;
|
||||
|
||||
/**
|
||||
@ -73,17 +72,6 @@ public class Attribute
|
||||
attrValues = (ASN1Set)seq.getObjectAt(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use ASN1ObjectIdentifier
|
||||
*/
|
||||
public Attribute(
|
||||
DERObjectIdentifier attrType,
|
||||
ASN1Set attrValues)
|
||||
{
|
||||
this.attrType = new ASN1ObjectIdentifier(attrType.getId());
|
||||
this.attrValues = attrValues;
|
||||
}
|
||||
|
||||
public Attribute(
|
||||
ASN1ObjectIdentifier attrType,
|
||||
ASN1Set attrValues)
|
||||
|
@ -8,7 +8,6 @@ import org.spongycastle.asn1.ASN1Encodable;
|
||||
import org.spongycastle.asn1.ASN1EncodableVector;
|
||||
import org.spongycastle.asn1.ASN1ObjectIdentifier;
|
||||
import org.spongycastle.asn1.ASN1Set;
|
||||
import org.spongycastle.asn1.DERObjectIdentifier;
|
||||
import org.spongycastle.asn1.DERSet;
|
||||
|
||||
/**
|
||||
@ -90,14 +89,6 @@ public class AttributeTable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use ASN1ObjectIdentifier
|
||||
*/
|
||||
public Attribute get(DERObjectIdentifier oid)
|
||||
{
|
||||
return get(new ASN1ObjectIdentifier(oid.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first attribute matching the OBJECT IDENTIFIER oid.
|
||||
*
|
||||
@ -117,14 +108,6 @@ public class AttributeTable
|
||||
return (Attribute)value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use ASN1ObjectIdentifier
|
||||
*/
|
||||
public ASN1EncodableVector getAll(DERObjectIdentifier oid)
|
||||
{
|
||||
return getAll(new ASN1ObjectIdentifier(oid.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the attributes matching the OBJECT IDENTIFIER oid. The vector will be
|
||||
* empty if there are no attributes of the required type present.
|
||||
|
@ -1,12 +1,12 @@
|
||||
package org.spongycastle.asn1.cms;
|
||||
|
||||
import org.spongycastle.asn1.ASN1EncodableVector;
|
||||
import org.spongycastle.asn1.ASN1GeneralizedTime;
|
||||
import org.spongycastle.asn1.ASN1Object;
|
||||
import org.spongycastle.asn1.ASN1OctetString;
|
||||
import org.spongycastle.asn1.ASN1Primitive;
|
||||
import org.spongycastle.asn1.ASN1Sequence;
|
||||
import org.spongycastle.asn1.ASN1TaggedObject;
|
||||
import org.spongycastle.asn1.DERGeneralizedTime;
|
||||
import org.spongycastle.asn1.DEROctetString;
|
||||
import org.spongycastle.asn1.DERSequence;
|
||||
|
||||
@ -28,12 +28,12 @@ public class RecipientKeyIdentifier
|
||||
extends ASN1Object
|
||||
{
|
||||
private ASN1OctetString subjectKeyIdentifier;
|
||||
private DERGeneralizedTime date;
|
||||
private ASN1GeneralizedTime date;
|
||||
private OtherKeyAttribute other;
|
||||
|
||||
public RecipientKeyIdentifier(
|
||||
ASN1OctetString subjectKeyIdentifier,
|
||||
DERGeneralizedTime date,
|
||||
ASN1GeneralizedTime date,
|
||||
OtherKeyAttribute other)
|
||||
{
|
||||
this.subjectKeyIdentifier = subjectKeyIdentifier;
|
||||
@ -43,7 +43,7 @@ public class RecipientKeyIdentifier
|
||||
|
||||
public RecipientKeyIdentifier(
|
||||
byte[] subjectKeyIdentifier,
|
||||
DERGeneralizedTime date,
|
||||
ASN1GeneralizedTime date,
|
||||
OtherKeyAttribute other)
|
||||
{
|
||||
this.subjectKeyIdentifier = new DEROctetString(subjectKeyIdentifier);
|
||||
@ -71,9 +71,9 @@ public class RecipientKeyIdentifier
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
if (seq.getObjectAt(1) instanceof DERGeneralizedTime)
|
||||
if (seq.getObjectAt(1) instanceof ASN1GeneralizedTime)
|
||||
{
|
||||
date = (DERGeneralizedTime)seq.getObjectAt(1);
|
||||
date = ASN1GeneralizedTime.getInstance(seq.getObjectAt(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -81,7 +81,7 @@ public class RecipientKeyIdentifier
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
date = (DERGeneralizedTime)seq.getObjectAt(1);
|
||||
date = ASN1GeneralizedTime.getInstance(seq.getObjectAt(1));
|
||||
other = OtherKeyAttribute.getInstance(seq.getObjectAt(2));
|
||||
break;
|
||||
default:
|
||||
@ -136,7 +136,7 @@ public class RecipientKeyIdentifier
|
||||
return subjectKeyIdentifier;
|
||||
}
|
||||
|
||||
public DERGeneralizedTime getDate()
|
||||
public ASN1GeneralizedTime getDate()
|
||||
{
|
||||
return date;
|
||||
}
|
||||
|
@ -3,12 +3,15 @@ package org.spongycastle.asn1.cms;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.SimpleTimeZone;
|
||||
|
||||
import org.spongycastle.asn1.ASN1Choice;
|
||||
import org.spongycastle.asn1.ASN1GeneralizedTime;
|
||||
import org.spongycastle.asn1.ASN1Object;
|
||||
import org.spongycastle.asn1.ASN1Primitive;
|
||||
import org.spongycastle.asn1.ASN1TaggedObject;
|
||||
import org.spongycastle.asn1.ASN1UTCTime;
|
||||
import org.spongycastle.asn1.DERGeneralizedTime;
|
||||
import org.spongycastle.asn1.DERUTCTime;
|
||||
|
||||
@ -47,8 +50,8 @@ public class Time
|
||||
public Time(
|
||||
ASN1Primitive time)
|
||||
{
|
||||
if (!(time instanceof DERUTCTime)
|
||||
&& !(time instanceof DERGeneralizedTime))
|
||||
if (!(time instanceof ASN1UTCTime)
|
||||
&& !(time instanceof ASN1GeneralizedTime))
|
||||
{
|
||||
throw new IllegalArgumentException("unknown object passed to Time");
|
||||
}
|
||||
@ -57,28 +60,61 @@ public class Time
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a time object from a given date - if the year is in between 1950
|
||||
* Creates a time object from a given date - if the date is between 1950
|
||||
* and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
|
||||
* is used.
|
||||
*
|
||||
* @param time a date object representing the time of interest.
|
||||
*/
|
||||
public Time(
|
||||
Date date)
|
||||
Date time)
|
||||
{
|
||||
SimpleTimeZone tz = new SimpleTimeZone(0, "Z");
|
||||
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
|
||||
dateF.setTimeZone(tz);
|
||||
|
||||
String d = dateF.format(date) + "Z";
|
||||
String d = dateF.format(time) + "Z";
|
||||
int year = Integer.parseInt(d.substring(0, 4));
|
||||
|
||||
if (year < 1950 || year > 2049)
|
||||
{
|
||||
time = new DERGeneralizedTime(d);
|
||||
this.time = new DERGeneralizedTime(d);
|
||||
}
|
||||
else
|
||||
{
|
||||
time = new DERUTCTime(d.substring(2));
|
||||
this.time = new DERUTCTime(d.substring(2));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a time object from a given date and locale - if the date is between 1950
|
||||
* and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
|
||||
* is used. You may need to use this constructor if the default locale
|
||||
* doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations.
|
||||
*
|
||||
* @param time a date object representing the time of interest.
|
||||
* @param locale an appropriate Locale for producing an ASN.1 GeneralizedTime value.
|
||||
*/
|
||||
public Time(
|
||||
Date time,
|
||||
Locale locale)
|
||||
{
|
||||
SimpleTimeZone tz = new SimpleTimeZone(0, "Z");
|
||||
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss", locale);
|
||||
|
||||
dateF.setTimeZone(tz);
|
||||
|
||||
String d = dateF.format(time) + "Z";
|
||||
int year = Integer.parseInt(d.substring(0, 4));
|
||||
|
||||
if (year < 1950 || year > 2049)
|
||||
{
|
||||
this.time = new DERGeneralizedTime(d);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.time = new DERUTCTime(d.substring(2));
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,13 +139,13 @@ public class Time
|
||||
{
|
||||
return (Time)obj;
|
||||
}
|
||||
else if (obj instanceof DERUTCTime)
|
||||
else if (obj instanceof ASN1UTCTime)
|
||||
{
|
||||
return new Time((DERUTCTime)obj);
|
||||
return new Time((ASN1UTCTime)obj);
|
||||
}
|
||||
else if (obj instanceof DERGeneralizedTime)
|
||||
else if (obj instanceof ASN1GeneralizedTime)
|
||||
{
|
||||
return new Time((DERGeneralizedTime)obj);
|
||||
return new Time((ASN1GeneralizedTime)obj);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
|
||||
@ -120,13 +156,13 @@ public class Time
|
||||
*/
|
||||
public String getTime()
|
||||
{
|
||||
if (time instanceof DERUTCTime)
|
||||
if (time instanceof ASN1UTCTime)
|
||||
{
|
||||
return ((DERUTCTime)time).getAdjustedTime();
|
||||
return ((ASN1UTCTime)time).getAdjustedTime();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((DERGeneralizedTime)time).getTime();
|
||||
return ((ASN1GeneralizedTime)time).getTime();
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,13 +173,13 @@ public class Time
|
||||
{
|
||||
try
|
||||
{
|
||||
if (time instanceof DERUTCTime)
|
||||
if (time instanceof ASN1UTCTime)
|
||||
{
|
||||
return ((DERUTCTime)time).getAdjustedDate();
|
||||
return ((ASN1UTCTime)time).getAdjustedDate();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((DERGeneralizedTime)time).getDate();
|
||||
return ((ASN1GeneralizedTime)time).getDate();
|
||||
}
|
||||
}
|
||||
catch (ParseException e)
|
||||
|
@ -6,8 +6,8 @@ import java.util.Hashtable;
|
||||
|
||||
import org.spongycastle.asn1.ASN1ObjectIdentifier;
|
||||
import org.spongycastle.crypto.params.ECDomainParameters;
|
||||
import org.spongycastle.math.ec.ECConstants;
|
||||
import org.spongycastle.math.ec.ECCurve;
|
||||
import org.spongycastle.math.ec.ECPoint;
|
||||
|
||||
/**
|
||||
* table of the available named parameters for GOST 3410-2001.
|
||||
@ -26,7 +26,9 @@ public class ECGOST3410NamedCurves
|
||||
ECCurve.Fp curve = new ECCurve.Fp(
|
||||
mod_p, // p
|
||||
new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"), // a
|
||||
new BigInteger("166")); // b
|
||||
new BigInteger("166"), // b
|
||||
mod_q,
|
||||
ECConstants.ONE);
|
||||
|
||||
ECDomainParameters ecParams = new ECDomainParameters(
|
||||
curve,
|
||||
@ -43,7 +45,9 @@ public class ECGOST3410NamedCurves
|
||||
curve = new ECCurve.Fp(
|
||||
mod_p, // p
|
||||
new BigInteger("115792089237316195423570985008687907853269984665640564039457584007913129639316"),
|
||||
new BigInteger("166"));
|
||||
new BigInteger("166"),
|
||||
mod_q,
|
||||
ECConstants.ONE);
|
||||
|
||||
ecParams = new ECDomainParameters(
|
||||
curve,
|
||||
@ -60,7 +64,9 @@ public class ECGOST3410NamedCurves
|
||||
curve = new ECCurve.Fp(
|
||||
mod_p, // p
|
||||
new BigInteger("57896044618658097711785492504343953926634992332820282019728792003956564823190"), // a
|
||||
new BigInteger("28091019353058090096996979000309560759124368558014865957655842872397301267595")); // b
|
||||
new BigInteger("28091019353058090096996979000309560759124368558014865957655842872397301267595"), // b
|
||||
mod_q,
|
||||
ECConstants.ONE);
|
||||
|
||||
ecParams = new ECDomainParameters(
|
||||
curve,
|
||||
@ -77,7 +83,9 @@ public class ECGOST3410NamedCurves
|
||||
curve = new ECCurve.Fp(
|
||||
mod_p, // p
|
||||
new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"),
|
||||
new BigInteger("32858"));
|
||||
new BigInteger("32858"),
|
||||
mod_q,
|
||||
ECConstants.ONE);
|
||||
|
||||
ecParams = new ECDomainParameters(
|
||||
curve,
|
||||
@ -93,7 +101,9 @@ public class ECGOST3410NamedCurves
|
||||
curve = new ECCurve.Fp(
|
||||
mod_p, // p
|
||||
new BigInteger("70390085352083305199547718019018437841079516630045180471284346843705633502616"), // a
|
||||
new BigInteger("32858")); // b
|
||||
new BigInteger("32858"), // b
|
||||
mod_q,
|
||||
ECConstants.ONE);
|
||||
|
||||
ecParams = new ECDomainParameters(
|
||||
curve,
|
||||
|
@ -15,7 +15,6 @@ import org.spongycastle.asn1.DEROctetString;
|
||||
|
||||
/**
|
||||
* an iso7816Certificate structure.
|
||||
* <p/>
|
||||
* <pre>
|
||||
* Certificate ::= SEQUENCE {
|
||||
* CertificateBody Iso7816CertificateBody,
|
||||
@ -85,7 +84,6 @@ public class CVCertificate
|
||||
* Create an iso7816Certificate structure from an ASN1InputStream.
|
||||
*
|
||||
* @param aIS the byte stream to parse.
|
||||
* @return the Iso7816CertificateStructure represented by the byte stream.
|
||||
* @throws IOException if there is a problem parsing the data.
|
||||
*/
|
||||
public CVCertificate(ASN1InputStream aIS)
|
||||
@ -129,7 +127,6 @@ public class CVCertificate
|
||||
*
|
||||
* @param body the Iso7816CertificateBody object containing the body.
|
||||
* @param signature the byte array containing the signature
|
||||
* @return the Iso7816CertificateStructure
|
||||
* @throws IOException if there is a problem parsing the data.
|
||||
*/
|
||||
public CVCertificate(CertificateBody body, byte[] signature)
|
||||
@ -147,7 +144,6 @@ public class CVCertificate
|
||||
*
|
||||
* @param obj the Object to extract the certificate from.
|
||||
* @return the Iso7816CertificateStructure represented by the byte stream.
|
||||
* @throws IOException if there is a problem parsing the data.
|
||||
*/
|
||||
public static CVCertificate getInstance(Object obj)
|
||||
{
|
||||
|
@ -13,7 +13,6 @@ import org.spongycastle.asn1.DEROctetString;
|
||||
|
||||
/**
|
||||
* an Iso7816CertificateBody structure.
|
||||
* <p/>
|
||||
* <pre>
|
||||
* CertificateBody ::= SEQUENCE {
|
||||
* // version of the certificate format. Must be 0 (version 1)
|
||||
@ -128,7 +127,6 @@ public class CertificateBody
|
||||
* @param certificateHolderAuthorization
|
||||
* @param certificateEffectiveDate
|
||||
* @param certificateExpirationDate
|
||||
* @throws IOException
|
||||
*/
|
||||
public CertificateBody(
|
||||
DERApplicationSpecific certificateProfileIdentifier,
|
||||
@ -276,7 +274,6 @@ public class CertificateBody
|
||||
* create a "request" or "profile" type Iso7816CertificateBody according to the variables sets.
|
||||
*
|
||||
* @return return the ASN1Primitive representing the "request" or "profile" type certificate body.
|
||||
* @throws IOException if the DERApplicationSpecific cannot be created or if data are missings to create a valid certificate.
|
||||
*/
|
||||
public ASN1Primitive toASN1Primitive()
|
||||
{
|
||||
|
@ -13,7 +13,6 @@ import org.spongycastle.util.Integers;
|
||||
|
||||
/**
|
||||
* an Iso7816CertificateHolderAuthorization structure.
|
||||
* <p/>
|
||||
* <pre>
|
||||
* Certificate Holder Authorization ::= SEQUENCE {
|
||||
* // specifies the format and the rules for the evaluation of the authorization
|
||||
|
@ -4,17 +4,17 @@ import org.spongycastle.asn1.ASN1ObjectIdentifier;
|
||||
|
||||
/**
|
||||
* German Federal Office for Information Security
|
||||
* (Bundesamt für Sicherheit in der Informationstechnik)
|
||||
* (Bundesamt für Sicherheit in der Informationstechnik)
|
||||
* <a href="http://www.bsi.bund.de/">http://www.bsi.bund.de/</a>
|
||||
* <p>
|
||||
* <a href="https://www.bsi.bund.de/EN/Publications/TechnicalGuidelines/TR03110/BSITR03110.html">BSI TR-03110</a>
|
||||
* Technical Guideline Advanced Security Mechanisms for Machine Readable Travel Documents
|
||||
* <p>
|
||||
* <a href="https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03110/TR-03110_v2.1_P3pdf.pdf?__blob=publicationFile">Technical Guideline TR-03110-3</a>
|
||||
* <a href="https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03110/TR-03110_v2.1_P3pdf.pdf">
|
||||
* Technical Guideline TR-03110-3</a>
|
||||
* Advanced Security Mechanisms for Machine Readable Travel Documents;
|
||||
* Part 3: Common Specifications.
|
||||
*/
|
||||
|
||||
public interface EACObjectIdentifiers
|
||||
{
|
||||
/**
|
||||
|
@ -15,7 +15,6 @@ import org.spongycastle.asn1.DERTaggedObject;
|
||||
|
||||
/**
|
||||
* an Iso7816ECDSAPublicKeyStructure structure.
|
||||
* <p/>
|
||||
* <pre>
|
||||
* Certificate Holder Authorization ::= SEQUENCE {
|
||||
* ASN1TaggedObject primeModulusP; // OPTIONAL
|
||||
|
@ -3,6 +3,7 @@ package org.spongycastle.asn1.eac;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.SimpleTimeZone;
|
||||
|
||||
import org.spongycastle.util.Arrays;
|
||||
@ -21,7 +22,9 @@ public class PackedDate
|
||||
}
|
||||
|
||||
/**
|
||||
* base constructer from a java.util.date object
|
||||
* Base constructor from a java.util.date object.
|
||||
*
|
||||
* @param time a date object representing the time of interest.
|
||||
*/
|
||||
public PackedDate(
|
||||
Date time)
|
||||
@ -33,6 +36,24 @@ public class PackedDate
|
||||
this.time = convert(dateF.format(time));
|
||||
}
|
||||
|
||||
/**
|
||||
* Base constructor from a java.util.date object. You may need to use this constructor if the default locale
|
||||
* doesn't use a Gregorian calender so that the PackedDate produced is compatible with other ASN.1 implementations.
|
||||
*
|
||||
* @param time a date object representing the time of interest.
|
||||
* @param locale an appropriate Locale for producing an ASN.1 GeneralizedTime value.
|
||||
*/
|
||||
public PackedDate(
|
||||
Date time,
|
||||
Locale locale)
|
||||
{
|
||||
SimpleDateFormat dateF = new SimpleDateFormat("yyMMdd'Z'", locale);
|
||||
|
||||
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
|
||||
|
||||
this.time = convert(dateF.format(time));
|
||||
}
|
||||
|
||||
private byte[] convert(String sTime)
|
||||
{
|
||||
char[] digs = sTime.toCharArray();
|
||||
|
@ -12,7 +12,6 @@ import org.spongycastle.asn1.DERSequence;
|
||||
|
||||
/**
|
||||
* an Iso7816RSAPublicKeyStructure structure.
|
||||
* <p/>
|
||||
* <pre>
|
||||
* Certificate Holder Authorization ::= SEQUENCE {
|
||||
* // modulus should be at least 1024bit and a multiple of 512.
|
||||
|
@ -6,7 +6,6 @@ import org.spongycastle.asn1.ASN1Object;
|
||||
import org.spongycastle.asn1.ASN1ObjectIdentifier;
|
||||
import org.spongycastle.asn1.ASN1Primitive;
|
||||
import org.spongycastle.asn1.ASN1Sequence;
|
||||
import org.spongycastle.asn1.DERObjectIdentifier;
|
||||
import org.spongycastle.asn1.DERSequence;
|
||||
import org.spongycastle.asn1.DERUTF8String;
|
||||
|
||||
@ -47,25 +46,6 @@ public class ContentHints
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use ASN1ObjectIdentifier
|
||||
*/
|
||||
public ContentHints(
|
||||
DERObjectIdentifier contentType)
|
||||
{
|
||||
this(new ASN1ObjectIdentifier(contentType.getId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use ASN1ObjectIdentifier
|
||||
*/
|
||||
public ContentHints(
|
||||
DERObjectIdentifier contentType,
|
||||
DERUTF8String contentDescription)
|
||||
{
|
||||
this(new ASN1ObjectIdentifier(contentType.getId()), contentDescription);
|
||||
}
|
||||
|
||||
public ContentHints(
|
||||
ASN1ObjectIdentifier contentType)
|
||||
{
|
||||
|
@ -13,7 +13,7 @@ import org.spongycastle.asn1.x509.Certificate;
|
||||
/**
|
||||
* The CscaMasterList object. This object can be wrapped in a
|
||||
* CMSSignedData to be published in LDAP.
|
||||
* <p/>
|
||||
*
|
||||
* <pre>
|
||||
* CscaMasterList ::= SEQUENCE {
|
||||
* version CscaMasterListVersion,
|
||||
|
@ -19,8 +19,6 @@ import org.spongycastle.asn1.x509.AlgorithmIdentifier;
|
||||
* the expiry of the corresponding certificate. Hence, clients MUST support this
|
||||
* extension. If a positive statement of availability is to be delivered, this
|
||||
* extension syntax and OID MUST be used.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <pre>
|
||||
* CertHash ::= SEQUENCE {
|
||||
* hashAlgorithm AlgorithmIdentifier,
|
||||
@ -102,9 +100,8 @@ public class CertHash
|
||||
|
||||
/**
|
||||
* Produce an object suitable for an ASN1OutputStream.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Returns:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* CertHash ::= SEQUENCE {
|
||||
* hashAlgorithm AlgorithmIdentifier,
|
||||
|
@ -16,7 +16,7 @@ import org.spongycastle.asn1.x509.Certificate;
|
||||
* ISIS-MTT-Optional: The certificate requested by the client by inserting the
|
||||
* RetrieveIfAllowed extension in the request, will be returned in this
|
||||
* extension.
|
||||
* <p/>
|
||||
* <p>
|
||||
* ISIS-MTT-SigG: The signature act allows publishing certificates only then,
|
||||
* when the certificate owner gives his explicit permission. Accordingly, there
|
||||
* may be <EFBFBD>nondownloadable<EFBFBD> certificates, about which the responder must provide
|
||||
@ -36,7 +36,6 @@ import org.spongycastle.asn1.x509.Certificate;
|
||||
* Clients requesting RetrieveIfAllowed MUST be able to handle these cases. If
|
||||
* any of the OCTET STRING options is used, it MUST contain the DER encoding of
|
||||
* the requested certificate.
|
||||
* <p/>
|
||||
* <pre>
|
||||
* RequestedCertificate ::= CHOICE {
|
||||
* Certificate Certificate,
|
||||
@ -105,7 +104,7 @@ public class RequestedCertificate
|
||||
|
||||
/**
|
||||
* Constructor from a given details.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Only one parameter can be given. All other must be <code>null</code>.
|
||||
*
|
||||
* @param certificate Given as Certificate
|
||||
@ -155,9 +154,8 @@ public class RequestedCertificate
|
||||
|
||||
/**
|
||||
* Produce an object suitable for an ASN1OutputStream.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Returns:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* RequestedCertificate ::= CHOICE {
|
||||
* Certificate Certificate,
|
||||
|
@ -54,9 +54,8 @@ public class AdditionalInformationSyntax
|
||||
|
||||
/**
|
||||
* Produce an object suitable for an ASN1OutputStream.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Returns:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* AdditionalInformationSyntax ::= DirectoryString (SIZE(1..2048))
|
||||
* </pre>
|
||||
|
@ -11,28 +11,28 @@ import org.spongycastle.asn1.x509.GeneralName;
|
||||
|
||||
/**
|
||||
* Attribute to indicate admissions to certain professions.
|
||||
* <p/>
|
||||
*
|
||||
* <pre>
|
||||
* AdmissionSyntax ::= SEQUENCE
|
||||
* {
|
||||
* admissionAuthority GeneralName OPTIONAL,
|
||||
* contentsOfAdmissions SEQUENCE OF Admissions
|
||||
* }
|
||||
* <p/>
|
||||
*
|
||||
* Admissions ::= SEQUENCE
|
||||
* {
|
||||
* admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
|
||||
* namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
|
||||
* professionInfos SEQUENCE OF ProfessionInfo
|
||||
* }
|
||||
* <p/>
|
||||
*
|
||||
* NamingAuthority ::= SEQUENCE
|
||||
* {
|
||||
* namingAuthorityId OBJECT IDENTIFIER OPTIONAL,
|
||||
* namingAuthorityUrl IA5String OPTIONAL,
|
||||
* namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
|
||||
* }
|
||||
* <p/>
|
||||
*
|
||||
* ProfessionInfo ::= SEQUENCE
|
||||
* {
|
||||
* namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
|
||||
@ -42,8 +42,7 @@ import org.spongycastle.asn1.x509.GeneralName;
|
||||
* addProfessionInfo OCTET STRING OPTIONAL
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <p>
|
||||
* ISIS-MTT PROFILE: The relatively complex structure of AdmissionSyntax
|
||||
* supports the following concepts and requirements:
|
||||
* <ul>
|
||||
@ -68,7 +67,7 @@ import org.spongycastle.asn1.x509.GeneralName;
|
||||
* component namingAuthorityId are grouped under the OID-branch
|
||||
* id-isis-at-namingAuthorities and must be applied for.
|
||||
* <li>See
|
||||
* http://www.teletrust.de/anwend.asp?Id=30200&Sprache=E_&HomePG=0 for
|
||||
* http://www.teletrust.de/anwend.asp?Id=30200&Sprache=E_&HomePG=0 for
|
||||
* an application form and http://www.teletrust.de/links.asp?id=30220,11
|
||||
* for an overview of registered naming authorities.
|
||||
* <li> By means of the data type ProfessionInfo certain professions,
|
||||
@ -80,7 +79,7 @@ import org.spongycastle.asn1.x509.GeneralName;
|
||||
* addProfessionInfo may contain additional applicationspecific information in
|
||||
* DER-encoded form.
|
||||
* </ul>
|
||||
* <p/>
|
||||
* <p>
|
||||
* By means of different namingAuthority-OIDs or profession OIDs hierarchies of
|
||||
* professions, specializations, disciplines, fields of activity, etc. can be
|
||||
* expressed. The issuing admission authority should always be indicated (field
|
||||
@ -89,9 +88,7 @@ import org.spongycastle.asn1.x509.GeneralName;
|
||||
* naming authority by the exclusive use of the component professionItems. In
|
||||
* this case the certification authority is responsible for the verification of
|
||||
* the admission information.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <p>
|
||||
* This attribute is single-valued. Still, several admissions can be captured in
|
||||
* the sequence structure of the component contentsOfAdmissions of
|
||||
* AdmissionSyntax or in the component professionInfos of Admissions. The
|
||||
@ -102,7 +99,7 @@ import org.spongycastle.asn1.x509.GeneralName;
|
||||
* value for the component namingAuthority of ProfessionInfo. Within the latter
|
||||
* component the default value can be overwritten, in case that another naming
|
||||
* authority needs to be recorded.
|
||||
* <p/>
|
||||
* <p>
|
||||
* The length of the string objects is limited to 128 characters. It is
|
||||
* recommended to indicate a namingAuthorityURL in all issued attribute
|
||||
* certificates. If a namingAuthorityURL is indicated, the field professionItems
|
||||
@ -209,30 +206,29 @@ public class AdmissionSyntax
|
||||
|
||||
/**
|
||||
* Produce an object suitable for an ASN1OutputStream.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Returns:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* AdmissionSyntax ::= SEQUENCE
|
||||
* {
|
||||
* admissionAuthority GeneralName OPTIONAL,
|
||||
* contentsOfAdmissions SEQUENCE OF Admissions
|
||||
* }
|
||||
* <p/>
|
||||
*
|
||||
* Admissions ::= SEQUENCE
|
||||
* {
|
||||
* admissionAuthority [0] EXPLICIT GeneralName OPTIONAL
|
||||
* namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
|
||||
* professionInfos SEQUENCE OF ProfessionInfo
|
||||
* }
|
||||
* <p/>
|
||||
*
|
||||
* NamingAuthority ::= SEQUENCE
|
||||
* {
|
||||
* namingAuthorityId OBJECT IDENTIFIER OPTIONAL,
|
||||
* namingAuthorityUrl IA5String OPTIONAL,
|
||||
* namingAuthorityText DirectoryString(SIZE(1..128)) OPTIONAL
|
||||
* }
|
||||
* <p/>
|
||||
*
|
||||
* ProfessionInfo ::= SEQUENCE
|
||||
* {
|
||||
* namingAuthority [0] EXPLICIT NamingAuthority OPTIONAL,
|
||||
|
@ -14,7 +14,6 @@ import org.spongycastle.asn1.x509.GeneralName;
|
||||
|
||||
/**
|
||||
* An Admissions structure.
|
||||
* <p/>
|
||||
* <pre>
|
||||
* Admissions ::= SEQUENCE
|
||||
* {
|
||||
@ -22,7 +21,6 @@ import org.spongycastle.asn1.x509.GeneralName;
|
||||
* namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
|
||||
* professionInfos SEQUENCE OF ProfessionInfo
|
||||
* }
|
||||
* <p/>
|
||||
* </pre>
|
||||
*
|
||||
* @see org.spongycastle.asn1.isismtt.x509.AdmissionSyntax
|
||||
@ -117,7 +115,7 @@ public class Admissions
|
||||
|
||||
/**
|
||||
* Constructor from a given details.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Parameter <code>professionInfos</code> is mandatory.
|
||||
*
|
||||
* @param admissionAuthority The admission authority.
|
||||
@ -155,9 +153,8 @@ public class Admissions
|
||||
|
||||
/**
|
||||
* Produce an object suitable for an ASN1OutputStream.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Returns:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* Admissions ::= SEQUENCE
|
||||
* {
|
||||
@ -165,7 +162,6 @@ public class Admissions
|
||||
* namingAuthority [1] EXPLICIT NamingAuthority OPTIONAL
|
||||
* professionInfos SEQUENCE OF ProfessionInfo
|
||||
* }
|
||||
* <p/>
|
||||
* </pre>
|
||||
*
|
||||
* @return an ASN1Primitive
|
||||
|
@ -15,7 +15,7 @@ import org.spongycastle.asn1.DERTaggedObject;
|
||||
|
||||
/**
|
||||
* A declaration of majority.
|
||||
* <p/>
|
||||
*
|
||||
* <pre>
|
||||
* DeclarationOfMajoritySyntax ::= CHOICE
|
||||
* {
|
||||
@ -28,7 +28,7 @@ import org.spongycastle.asn1.DERTaggedObject;
|
||||
* dateOfBirth [2] IMPLICIT GeneralizedTime
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* <p>
|
||||
* fullAgeAtCountry indicates the majority of the owner with respect to the laws
|
||||
* of a specific country.
|
||||
*/
|
||||
@ -101,9 +101,8 @@ public class DeclarationOfMajority
|
||||
|
||||
/**
|
||||
* Produce an object suitable for an ASN1OutputStream.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Returns:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* DeclarationOfMajoritySyntax ::= CHOICE
|
||||
* {
|
||||
|
@ -17,11 +17,10 @@ import org.spongycastle.asn1.DERSequence;
|
||||
* since January 1, 2004. For the sake of backward compatibility with
|
||||
* certificates already in use, components SHOULD support MonetaryLimit (as well
|
||||
* as QcEuLimitValue).
|
||||
* <p/>
|
||||
* <p>
|
||||
* Indicates a monetary limit within which the certificate holder is authorized
|
||||
* to act. (This value DOES NOT express a limit on the liability of the
|
||||
* certification authority).
|
||||
* <p/>
|
||||
* <pre>
|
||||
* MonetaryLimitSyntax ::= SEQUENCE
|
||||
* {
|
||||
@ -30,9 +29,9 @@ import org.spongycastle.asn1.DERSequence;
|
||||
* exponent INTEGER
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* <p>
|
||||
* currency must be the ISO code.
|
||||
* <p/>
|
||||
* <p>
|
||||
* value = amount<EFBFBD>10*exponent
|
||||
*/
|
||||
public class MonetaryLimit
|
||||
@ -72,8 +71,7 @@ public class MonetaryLimit
|
||||
|
||||
/**
|
||||
* Constructor from a given details.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <p>
|
||||
* value = amount<EFBFBD>10^exponent
|
||||
*
|
||||
* @param currency The currency. Must be the ISO code.
|
||||
@ -104,9 +102,8 @@ public class MonetaryLimit
|
||||
|
||||
/**
|
||||
* Produce an object suitable for an ASN1OutputStream.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Returns:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* MonetaryLimitSyntax ::= SEQUENCE
|
||||
* {
|
||||
|
@ -11,7 +11,6 @@ import org.spongycastle.asn1.ASN1Sequence;
|
||||
import org.spongycastle.asn1.ASN1String;
|
||||
import org.spongycastle.asn1.ASN1TaggedObject;
|
||||
import org.spongycastle.asn1.DERIA5String;
|
||||
import org.spongycastle.asn1.DERObjectIdentifier;
|
||||
import org.spongycastle.asn1.DERSequence;
|
||||
import org.spongycastle.asn1.isismtt.ISISMTTObjectIdentifiers;
|
||||
import org.spongycastle.asn1.x500.DirectoryString;
|
||||
@ -173,27 +172,9 @@ public class NamingAuthority
|
||||
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.
|
||||
* <p/>
|
||||
* <p>
|
||||
* All parameters can be combined.
|
||||
*
|
||||
* @param namingAuthorityId ObjectIdentifier for naming authority.
|
||||
@ -210,9 +191,8 @@ public class NamingAuthority
|
||||
|
||||
/**
|
||||
* Produce an object suitable for an ASN1OutputStream.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Returns:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* NamingAuthority ::= SEQUENCE
|
||||
* {
|
||||
|
@ -132,8 +132,7 @@ public class ProcurationSyntax
|
||||
|
||||
/**
|
||||
* Constructor from a given details.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <p>
|
||||
* Either <code>generalName</code> or <code>certRef</code> MUST be
|
||||
* <code>null</code>.
|
||||
*
|
||||
@ -154,8 +153,7 @@ public class ProcurationSyntax
|
||||
|
||||
/**
|
||||
* Constructor from a given details.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <p>
|
||||
* Either <code>generalName</code> or <code>certRef</code> MUST be
|
||||
* <code>null</code>.
|
||||
*
|
||||
@ -196,16 +194,15 @@ public class ProcurationSyntax
|
||||
|
||||
/**
|
||||
* Produce an object suitable for an ASN1OutputStream.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Returns:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* ProcurationSyntax ::= SEQUENCE {
|
||||
* country [1] EXPLICIT PrintableString(SIZE(2)) OPTIONAL,
|
||||
* typeOfSubstitution [2] EXPLICIT DirectoryString (SIZE(1..128)) OPTIONAL,
|
||||
* signingFor [3] EXPLICIT SigningFor
|
||||
* }
|
||||
* <p/>
|
||||
*
|
||||
* SigningFor ::= CHOICE
|
||||
* {
|
||||
* thirdPerson GeneralName,
|
||||
|
@ -274,7 +274,7 @@ public class ProfessionInfo
|
||||
|
||||
/**
|
||||
* Constructor from given details.
|
||||
* <p/>
|
||||
* <p>
|
||||
* <code>professionItems</code> is mandatory, all other parameters are
|
||||
* optional.
|
||||
*
|
||||
@ -311,9 +311,8 @@ public class ProfessionInfo
|
||||
|
||||
/**
|
||||
* Produce an object suitable for an ASN1OutputStream.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Returns:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* ProfessionInfo ::= SEQUENCE
|
||||
* {
|
||||
|
@ -6,7 +6,7 @@ import org.spongycastle.asn1.x500.DirectoryString;
|
||||
|
||||
/**
|
||||
* Some other restriction regarding the usage of this certificate.
|
||||
* <p/>
|
||||
*
|
||||
* <pre>
|
||||
* RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
|
||||
* </pre>
|
||||
@ -64,12 +64,10 @@ public class Restriction
|
||||
|
||||
/**
|
||||
* Produce an object suitable for an ASN1OutputStream.
|
||||
* <p/>
|
||||
* <p>
|
||||
* Returns:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* RestrictionSyntax ::= DirectoryString (SIZE(1..1024))
|
||||
* <p/>
|
||||
* </pre>
|
||||
*
|
||||
* @return a DERObject
|
||||
|
@ -36,7 +36,7 @@ public interface MiscObjectIdentifiers
|
||||
|
||||
/** Verisign CZAG (Country,Zip,Age,Gender) Extension OID: 2.16.840.1.113733.1.6.3 */
|
||||
static final ASN1ObjectIdentifier verisignCzagExtension = verisign.branch("6.3");
|
||||
/** Verisign D&B D-U-N-S number Extension OID: 2.16.840.1.113733.1.6.15 */
|
||||
/** Verisign D&B D-U-N-S number Extension OID: 2.16.840.1.113733.1.6.15 */
|
||||
static final ASN1ObjectIdentifier verisignDnbDunsNumber = verisign.branch("6.15");
|
||||
|
||||
//
|
||||
|
@ -9,7 +9,6 @@ import org.spongycastle.asn1.ASN1Object;
|
||||
import org.spongycastle.asn1.ASN1Primitive;
|
||||
import org.spongycastle.asn1.ASN1Sequence;
|
||||
import org.spongycastle.asn1.ASN1TaggedObject;
|
||||
import org.spongycastle.asn1.DERGeneralizedTime;
|
||||
import org.spongycastle.asn1.DERIA5String;
|
||||
import org.spongycastle.asn1.DERSequence;
|
||||
import org.spongycastle.asn1.DERTaggedObject;
|
||||
@ -39,7 +38,7 @@ public class CrlID
|
||||
crlNum = ASN1Integer.getInstance(o, true);
|
||||
break;
|
||||
case 2:
|
||||
crlTime = DERGeneralizedTime.getInstance(o, true);
|
||||
crlTime = ASN1GeneralizedTime.getInstance(o, true);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
|
@ -7,7 +7,6 @@ import org.spongycastle.asn1.ASN1Object;
|
||||
import org.spongycastle.asn1.ASN1Primitive;
|
||||
import org.spongycastle.asn1.ASN1Sequence;
|
||||
import org.spongycastle.asn1.ASN1TaggedObject;
|
||||
import org.spongycastle.asn1.DERGeneralizedTime;
|
||||
import org.spongycastle.asn1.DERSequence;
|
||||
import org.spongycastle.asn1.DERTaggedObject;
|
||||
import org.spongycastle.asn1.x509.Extensions;
|
||||
@ -49,7 +48,7 @@ public class ResponseData
|
||||
*/
|
||||
public ResponseData(
|
||||
ResponderID responderID,
|
||||
DERGeneralizedTime producedAt,
|
||||
ASN1GeneralizedTime producedAt,
|
||||
ASN1Sequence responses,
|
||||
X509Extensions responseExtensions)
|
||||
{
|
||||
|
@ -6,7 +6,6 @@ import org.spongycastle.asn1.ASN1Object;
|
||||
import org.spongycastle.asn1.ASN1Primitive;
|
||||
import org.spongycastle.asn1.ASN1Sequence;
|
||||
import org.spongycastle.asn1.ASN1TaggedObject;
|
||||
import org.spongycastle.asn1.DERGeneralizedTime;
|
||||
import org.spongycastle.asn1.DERSequence;
|
||||
import org.spongycastle.asn1.DERTaggedObject;
|
||||
import org.spongycastle.asn1.x509.Extensions;
|
||||
@ -32,31 +31,13 @@ public class SingleResponse
|
||||
public SingleResponse(
|
||||
CertID certID,
|
||||
CertStatus certStatus,
|
||||
DERGeneralizedTime thisUpdate,
|
||||
DERGeneralizedTime nextUpdate,
|
||||
ASN1GeneralizedTime thisUpdate,
|
||||
ASN1GeneralizedTime nextUpdate,
|
||||
X509Extensions singleExtensions)
|
||||
{
|
||||
this(certID, certStatus, thisUpdate, nextUpdate, Extensions.getInstance(singleExtensions));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use method taking ASN1GeneralizedTime and Extensions
|
||||
* @param certID
|
||||
* @param certStatus
|
||||
* @param thisUpdate
|
||||
* @param nextUpdate
|
||||
* @param singleExtensions
|
||||
*/
|
||||
public SingleResponse(
|
||||
CertID certID,
|
||||
CertStatus certStatus,
|
||||
DERGeneralizedTime thisUpdate,
|
||||
DERGeneralizedTime nextUpdate,
|
||||
Extensions singleExtensions)
|
||||
{
|
||||
this(certID, certStatus, ASN1GeneralizedTime.getInstance(thisUpdate), ASN1GeneralizedTime.getInstance(nextUpdate), Extensions.getInstance(singleExtensions));
|
||||
}
|
||||
|
||||
public SingleResponse(
|
||||
CertID certID,
|
||||
CertStatus certStatus,
|
||||
|
@ -23,7 +23,7 @@ public class ElGamalParameter
|
||||
this.g = new ASN1Integer(g);
|
||||
}
|
||||
|
||||
public ElGamalParameter(
|
||||
private ElGamalParameter(
|
||||
ASN1Sequence seq)
|
||||
{
|
||||
Enumeration e = seq.getObjects();
|
||||
@ -32,6 +32,20 @@ public class ElGamalParameter
|
||||
g = (ASN1Integer)e.nextElement();
|
||||
}
|
||||
|
||||
public static ElGamalParameter getInstance(Object o)
|
||||
{
|
||||
if (o instanceof ElGamalParameter)
|
||||
{
|
||||
return (ElGamalParameter)o;
|
||||
}
|
||||
else if (o != null)
|
||||
{
|
||||
return new ElGamalParameter(ASN1Sequence.getInstance(o));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public BigInteger getP()
|
||||
{
|
||||
return p.getPositiveValue();
|
||||
|
@ -56,19 +56,19 @@ public class CRLBag
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
CRLBag ::= SEQUENCE {
|
||||
crlId BAG-TYPE.&id ({CRLTypes}),
|
||||
crlValue [0] EXPLICIT BAG-TYPE.&Type ({CRLTypes}{@crlId})
|
||||
}
|
||||
|
||||
x509CRL BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1}
|
||||
-- DER-encoded X.509 CRL stored in OCTET STRING
|
||||
|
||||
CRLTypes BAG-TYPE ::= {
|
||||
x509CRL,
|
||||
... -- For future extensions
|
||||
}
|
||||
</pre>
|
||||
* CRLBag ::= SEQUENCE {
|
||||
* crlId BAG-TYPE.&id ({CRLTypes}),
|
||||
* crlValue [0] EXPLICIT BAG-TYPE.&Type ({CRLTypes}{@crlId})
|
||||
* }
|
||||
*
|
||||
* x509CRL BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {certTypes 1}
|
||||
* -- DER-encoded X.509 CRL stored in OCTET STRING
|
||||
*
|
||||
* CRLTypes BAG-TYPE ::= {
|
||||
* x509CRL,
|
||||
* ... -- For future extensions
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public ASN1Primitive toASN1Primitive()
|
||||
{
|
||||
|
@ -25,8 +25,8 @@ import org.spongycastle.asn1.x509.X509Name;
|
||||
* Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
|
||||
*
|
||||
* Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
|
||||
* type ATTRIBUTE.&id({IOSet}),
|
||||
* values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
|
||||
* type ATTRIBUTE.&id({IOSet}),
|
||||
* values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
|
@ -25,7 +25,7 @@ public class EncryptionScheme
|
||||
this.algId = AlgorithmIdentifier.getInstance(seq);
|
||||
}
|
||||
|
||||
public static final EncryptionScheme getInstance(Object obj)
|
||||
public static EncryptionScheme getInstance(Object obj)
|
||||
{
|
||||
if (obj instanceof EncryptionScheme)
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ public class KeyDerivationFunc
|
||||
this.algId = AlgorithmIdentifier.getInstance(seq);
|
||||
}
|
||||
|
||||
public static final KeyDerivationFunc getInstance(Object obj)
|
||||
public static KeyDerivationFunc getInstance(Object obj)
|
||||
{
|
||||
if (obj instanceof KeyDerivationFunc)
|
||||
{
|
||||
|
@ -68,7 +68,7 @@ public class PrivateKeyInfo
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprectaed use PrivateKeyInfo.getInstance()
|
||||
* @deprecated use PrivateKeyInfo.getInstance()
|
||||
* @param seq
|
||||
*/
|
||||
public PrivateKeyInfo(
|
||||
|
@ -10,6 +10,8 @@ import org.spongycastle.asn1.x9.X9ECParametersHolder;
|
||||
import org.spongycastle.math.ec.ECConstants;
|
||||
import org.spongycastle.math.ec.ECCurve;
|
||||
import org.spongycastle.math.ec.ECPoint;
|
||||
import org.spongycastle.math.ec.endo.GLVTypeBEndomorphism;
|
||||
import org.spongycastle.math.ec.endo.GLVTypeBParameters;
|
||||
import org.spongycastle.util.Strings;
|
||||
import org.spongycastle.util.encoders.Hex;
|
||||
|
||||
@ -17,19 +19,14 @@ public class SECNamedCurves
|
||||
{
|
||||
private static ECCurve configureCurve(ECCurve curve)
|
||||
{
|
||||
// int coord = ECCurve.COORD_JACOBIAN_MODIFIED;
|
||||
//
|
||||
// if (curve.getCoordinateSystem() != coord && curve.supportsCoordinateSystem(coord))
|
||||
// {
|
||||
// return curve.configure()
|
||||
// .setCoordinateSystem(coord)
|
||||
//// .setMultiplier(new WNafL2RMultiplier())
|
||||
// .create();
|
||||
// }
|
||||
|
||||
return curve;
|
||||
}
|
||||
|
||||
private static ECCurve configureCurveGLV(ECCurve c, GLVTypeBParameters p)
|
||||
{
|
||||
return c.configure().setEndomorphism(new GLVTypeBEndomorphism(c, p)).create();
|
||||
}
|
||||
|
||||
private static BigInteger fromHex(
|
||||
String hex)
|
||||
{
|
||||
@ -51,7 +48,7 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("DB7C2ABF62E35E7628DFAC6561C5");
|
||||
BigInteger h = BigInteger.valueOf(1);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("02"
|
||||
//+ "09487239995A5EE76B55F9C2F098"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -77,7 +74,7 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("36DF0AAFD8B8D7597CA10520D04B");
|
||||
BigInteger h = BigInteger.valueOf(4);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("03"
|
||||
//+ "4BA30AB5E892B4E1649DD0928643"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -103,7 +100,7 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("FFFFFFFE0000000075A30D1B9038A115");
|
||||
BigInteger h = BigInteger.valueOf(1);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("03"
|
||||
//+ "161FF7528B899B2D0C28607CA52C5B86"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -129,7 +126,7 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("3FFFFFFF7FFFFFFFBE0024720613B5A3");
|
||||
BigInteger h = BigInteger.valueOf(4);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("02"
|
||||
//+ "7B6AA5D85E572983E6FB32A7CDEBC140"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -155,7 +152,20 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("0100000000000000000001B8FA16DFAB9ACA16B6B3");
|
||||
BigInteger h = BigInteger.valueOf(1);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
GLVTypeBParameters glv = new GLVTypeBParameters(
|
||||
new BigInteger("9ba48cba5ebcb9b6bd33b92830b2a2e0e192f10a", 16),
|
||||
new BigInteger("c39c6c3b3a36d7701b9c71a1f5804ae5d0003f4", 16),
|
||||
new BigInteger[]{
|
||||
new BigInteger("9162fbe73984472a0a9e", 16),
|
||||
new BigInteger("-96341f1138933bc2f505", 16) },
|
||||
new BigInteger[]{
|
||||
new BigInteger("127971af8721782ecffa3", 16),
|
||||
new BigInteger("9162fbe73984472a0a9e", 16) },
|
||||
new BigInteger("9162fbe73984472a0a9d0590", 16),
|
||||
new BigInteger("96341f1138933bc2f503fd44", 16),
|
||||
176);
|
||||
|
||||
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
|
||||
// ECPoint G = curve.decodePoint(Hex.decode("02"
|
||||
// + "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -181,7 +191,7 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("0100000000000000000001F4C8F927AED3CA752257");
|
||||
BigInteger h = BigInteger.valueOf(1);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("02"
|
||||
//+ "4A96B5688EF573284664698968C38BB913CBFC82"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -207,7 +217,7 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("0100000000000000000000351EE786A818F3A1A16B");
|
||||
BigInteger h = BigInteger.valueOf(1);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("02"
|
||||
//+ "52DCB034293A117E1F4FF11B30F7199D3144CE6D"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -233,7 +243,20 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D");
|
||||
BigInteger h = BigInteger.valueOf(1);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
GLVTypeBParameters glv = new GLVTypeBParameters(
|
||||
new BigInteger("bb85691939b869c1d087f601554b96b80cb4f55b35f433c2", 16),
|
||||
new BigInteger("3d84f26c12238d7b4f3d516613c1759033b1a5800175d0b1", 16),
|
||||
new BigInteger[]{
|
||||
new BigInteger("71169be7330b3038edb025f1", 16),
|
||||
new BigInteger("-b3fb3400dec5c4adceb8655c", 16) },
|
||||
new BigInteger[]{
|
||||
new BigInteger("12511cfe811d0f4e6bc688b4d", 16),
|
||||
new BigInteger("71169be7330b3038edb025f1", 16) },
|
||||
new BigInteger("71169be7330b3038edb025f1d0f9", 16),
|
||||
new BigInteger("b3fb3400dec5c4adceb8655d4c94", 16),
|
||||
208);
|
||||
|
||||
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("03"
|
||||
//+ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -259,7 +282,7 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831");
|
||||
BigInteger h = BigInteger.valueOf(1);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("03"
|
||||
//+ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -285,7 +308,20 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
|
||||
BigInteger h = BigInteger.valueOf(1);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
GLVTypeBParameters glv = new GLVTypeBParameters(
|
||||
new BigInteger("fe0e87005b4e83761908c5131d552a850b3f58b749c37cf5b84d6768", 16),
|
||||
new BigInteger("60dcd2104c4cbc0be6eeefc2bdd610739ec34e317f9b33046c9e4788", 16),
|
||||
new BigInteger[]{
|
||||
new BigInteger("6b8cf07d4ca75c88957d9d670591", 16),
|
||||
new BigInteger("-b8adf1378a6eb73409fa6c9c637d", 16) },
|
||||
new BigInteger[]{
|
||||
new BigInteger("1243ae1b4d71613bc9f780a03690e", 16),
|
||||
new BigInteger("6b8cf07d4ca75c88957d9d670591", 16) },
|
||||
new BigInteger("6b8cf07d4ca75c88957d9d67059037a4", 16),
|
||||
new BigInteger("b8adf1378a6eb73409fa6c9c637ba7f5", 16),
|
||||
240);
|
||||
|
||||
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("03"
|
||||
//+ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -311,7 +347,7 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D");
|
||||
BigInteger h = BigInteger.valueOf(1);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("02"
|
||||
//+ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -337,7 +373,20 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
|
||||
BigInteger h = BigInteger.valueOf(1);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
GLVTypeBParameters glv = new GLVTypeBParameters(
|
||||
new BigInteger("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee", 16),
|
||||
new BigInteger("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72", 16),
|
||||
new BigInteger[]{
|
||||
new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16),
|
||||
new BigInteger("-e4437ed6010e88286f547fa90abfe4c3", 16) },
|
||||
new BigInteger[]{
|
||||
new BigInteger("114ca50f7a8e2f3f657c1108d9d44cfd8", 16),
|
||||
new BigInteger("3086d221a7d46bcde86c90e49284eb15", 16) },
|
||||
new BigInteger("3086d221a7d46bcde86c90e49284eb153dab", 16),
|
||||
new BigInteger("e4437ed6010e88286f547fa90abfe4c42212", 16),
|
||||
272);
|
||||
|
||||
ECCurve curve = configureCurveGLV(new ECCurve.Fp(p, a, b, n, h), glv);
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("02"
|
||||
//+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -363,7 +412,7 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551");
|
||||
BigInteger h = BigInteger.valueOf(1);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("03"
|
||||
//+ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -389,7 +438,7 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973");
|
||||
BigInteger h = BigInteger.valueOf(1);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("03"
|
||||
//+ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7"));
|
||||
ECPoint G = curve.decodePoint(Hex.decode("04"
|
||||
@ -415,7 +464,7 @@ public class SECNamedCurves
|
||||
BigInteger n = fromHex("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409");
|
||||
BigInteger h = BigInteger.valueOf(1);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b));
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(p, a, b, n, h));
|
||||
|
||||
//ECPoint G = curve.decodePoint(Hex.decode("02"
|
||||
//+ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66"));
|
||||
|
@ -26,16 +26,19 @@ public class TeleTrusTNamedCurves
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620F", 16), // q
|
||||
new BigInteger("340E7BE2A280EB74E2BE61BADA745D97E8F7C300", 16), // a
|
||||
new BigInteger("1E589A8595423412134FAA2DBDEC95C8D8675E58", 16))); // b
|
||||
new BigInteger("1E589A8595423412134FAA2DBDEC95C8D8675E58", 16), // b
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("04BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC31667CB477A1A8EC338F94741669C976316DA6321")), // G
|
||||
new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16), //n
|
||||
new BigInteger("01", 16)); // h
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
|
||||
@ -43,17 +46,20 @@ public class TeleTrusTNamedCurves
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
// new BigInteger("24DBFF5DEC9B986BBFE5295A29BFBAE45E0F5D0B", 16), // Z
|
||||
new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620F", 16), // q
|
||||
new BigInteger("E95E4A5F737059DC60DFC7AD95B3D8139515620C", 16), // a'
|
||||
new BigInteger("7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380", 16))); // b'
|
||||
new BigInteger("7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380", 16), // b'
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("04B199B13B9B34EFC1397E64BAEB05ACC265FF2378ADD6718B7C7C1961F0991B842443772152C9E0AD")), // G
|
||||
new BigInteger("E95E4A5F737059DC60DF5991D45029409E60FC09", 16), //n
|
||||
new BigInteger("01", 16)); // h
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
|
||||
@ -61,16 +67,19 @@ public class TeleTrusTNamedCurves
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", 16), // q
|
||||
new BigInteger("6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", 16), // a
|
||||
new BigInteger("469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", 16))); // b
|
||||
new BigInteger("469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", 16), // b
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("04C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD614B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F")), // G
|
||||
new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16), //n
|
||||
new BigInteger("01", 16)); // h
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
|
||||
@ -78,17 +87,20 @@ public class TeleTrusTNamedCurves
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
//new BigInteger("1B6F5CC8DB4DC7AF19458A9CB80DC2295E5EB9C3732104CB") //Z
|
||||
new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", 16), // q
|
||||
new BigInteger("C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294", 16), // a'
|
||||
new BigInteger("13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79", 16))); // b'
|
||||
new BigInteger("13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79", 16), // b'
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("043AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9")), // G'
|
||||
new BigInteger("C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1", 16), //n
|
||||
new BigInteger("01", 16)); // h
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
|
||||
@ -96,165 +108,195 @@ public class TeleTrusTNamedCurves
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", 16), // q
|
||||
new BigInteger("68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", 16), // a
|
||||
new BigInteger("2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", 16))); // b
|
||||
new BigInteger("2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", 16), // b
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("040D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD")), // G
|
||||
new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16), //n
|
||||
new BigInteger("01", 16)); // n
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
static X9ECParametersHolder brainpoolP224t1 = new X9ECParametersHolder()
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
//new BigInteger("2DF271E14427A346910CF7A2E6CFA7B3F484E5C2CCE1C8B730E28B3F") //Z
|
||||
new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", 16), // q
|
||||
new BigInteger("D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC", 16), // a'
|
||||
new BigInteger("4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D", 16))); // b'
|
||||
new BigInteger("4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D", 16), // b'
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("046AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D5800374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C")), // G'
|
||||
new BigInteger("D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F", 16), //n
|
||||
new BigInteger("01", 16)); // h
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
static X9ECParametersHolder brainpoolP256r1 = new X9ECParametersHolder()
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16), // q
|
||||
new BigInteger("7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", 16), // a
|
||||
new BigInteger("26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", 16))); // b
|
||||
new BigInteger("26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", 16), // b
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("048BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997")), // G
|
||||
new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16), //n
|
||||
new BigInteger("01", 16)); // h
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
static X9ECParametersHolder brainpoolP256t1 = new X9ECParametersHolder()
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
//new BigInteger("3E2D4BD9597B58639AE7AA669CAB9837CF5CF20A2C852D10F655668DFC150EF0") //Z
|
||||
new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", 16), // q
|
||||
new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374", 16), // a'
|
||||
new BigInteger("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", 16))); // b'
|
||||
new BigInteger("662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", 16), // b'
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("04A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F42D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE")), // G'
|
||||
new BigInteger("A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7", 16), //n
|
||||
new BigInteger("01", 16)); // h
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
static X9ECParametersHolder brainpoolP320r1 = new X9ECParametersHolder()
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", 16), // q
|
||||
new BigInteger("3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", 16), // a
|
||||
new BigInteger("520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", 16))); // b
|
||||
new BigInteger("520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", 16), // b
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("0443BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E2061114FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1")), // G
|
||||
new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16), //n
|
||||
new BigInteger("01", 16)); // h
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
static X9ECParametersHolder brainpoolP320t1 = new X9ECParametersHolder()
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
//new BigInteger("15F75CAF668077F7E85B42EB01F0A81FF56ECD6191D55CB82B7D861458A18FEFC3E5AB7496F3C7B1") //Z
|
||||
new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", 16), // q
|
||||
new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24", 16), // a'
|
||||
new BigInteger("A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353", 16))); // b'
|
||||
new BigInteger("A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353", 16), // b'
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("04925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED5263BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3")), // G'
|
||||
new BigInteger("D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311", 16), //n
|
||||
new BigInteger("01", 16)); // h
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
static X9ECParametersHolder brainpoolP384r1 = new X9ECParametersHolder()
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16), // q
|
||||
new BigInteger("7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", 16), // a
|
||||
new BigInteger("4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", 16))); // b
|
||||
new BigInteger("4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", 16), // b
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("041D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315")), // G
|
||||
new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16), //n
|
||||
new BigInteger("01", 16)); // h
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
static X9ECParametersHolder brainpoolP384t1 = new X9ECParametersHolder()
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
//new BigInteger("41DFE8DD399331F7166A66076734A89CD0D2BCDB7D068E44E1F378F41ECBAE97D2D63DBC87BCCDDCCC5DA39E8589291C") //Z
|
||||
new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", 16), // q
|
||||
new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50", 16), // a'
|
||||
new BigInteger("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", 16))); // b'
|
||||
new BigInteger("7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", 16), // b'
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("0418DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928")), // G'
|
||||
new BigInteger("8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565", 16), //n
|
||||
new BigInteger("01", 16)); // h
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
static X9ECParametersHolder brainpoolP512r1 = new X9ECParametersHolder()
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16), // q
|
||||
new BigInteger("7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", 16), // a
|
||||
new BigInteger("3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", 16))); // b
|
||||
new BigInteger("3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", 16), // b
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("0481AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F8227DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892")), // G
|
||||
new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16), //n
|
||||
new BigInteger("01", 16)); // h
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
static X9ECParametersHolder brainpoolP512t1 = new X9ECParametersHolder()
|
||||
{
|
||||
protected X9ECParameters createParameters()
|
||||
{
|
||||
BigInteger n = new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16);
|
||||
BigInteger h = new BigInteger("01", 16);
|
||||
|
||||
ECCurve curve = configureCurve(new ECCurve.Fp(
|
||||
//new BigInteger("12EE58E6764838B69782136F0F2D3BA06E27695716054092E60A80BEDB212B64E585D90BCE13761F85C3F1D2A64E3BE8FEA2220F01EBA5EEB0F35DBD29D922AB") //Z
|
||||
new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", 16), // q
|
||||
new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0", 16), // a'
|
||||
new BigInteger("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", 16))); // b'
|
||||
new BigInteger("7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", 16), // b'
|
||||
n, h));
|
||||
|
||||
return new X9ECParameters(
|
||||
curve,
|
||||
curve.decodePoint(Hex.decode("04640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332")), // G'
|
||||
new BigInteger("AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069", 16), //n
|
||||
new BigInteger("01", 16)); // h
|
||||
n, h);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -41,35 +41,35 @@ public interface TeleTrusTObjectIdentifiers
|
||||
static final ASN1ObjectIdentifier ecc_brainpool = teleTrusTAlgorithm.branch("3.2.8");
|
||||
/** 1.3.36.3.3.2.8.1 */
|
||||
static final ASN1ObjectIdentifier ellipticCurve = ecc_brainpool.branch("1");
|
||||
/** 1.3.36.3.3.2.8.1 */
|
||||
/** 1.3.36.3.3.2.8.1.1 */
|
||||
static final ASN1ObjectIdentifier versionOne = ellipticCurve.branch("1");
|
||||
|
||||
/** 1.3.36.3.3.2.8.1.1 */
|
||||
/** 1.3.36.3.3.2.8.1.1.1 */
|
||||
static final ASN1ObjectIdentifier brainpoolP160r1 = versionOne.branch("1");
|
||||
/** 1.3.36.3.3.2.8.1.2 */
|
||||
/** 1.3.36.3.3.2.8.1.1.2 */
|
||||
static final ASN1ObjectIdentifier brainpoolP160t1 = versionOne.branch("2");
|
||||
/** 1.3.36.3.3.2.8.1.3 */
|
||||
/** 1.3.36.3.3.2.8.1.1.3 */
|
||||
static final ASN1ObjectIdentifier brainpoolP192r1 = versionOne.branch("3");
|
||||
/** 1.3.36.3.3.2.8.1.4 */
|
||||
/** 1.3.36.3.3.2.8.1.1.4 */
|
||||
static final ASN1ObjectIdentifier brainpoolP192t1 = versionOne.branch("4");
|
||||
/** 1.3.36.3.3.2.8.1.5 */
|
||||
/** 1.3.36.3.3.2.8.1.1.5 */
|
||||
static final ASN1ObjectIdentifier brainpoolP224r1 = versionOne.branch("5");
|
||||
/** 1.3.36.3.3.2.8.1.6 */
|
||||
/** 1.3.36.3.3.2.8.1.1.6 */
|
||||
static final ASN1ObjectIdentifier brainpoolP224t1 = versionOne.branch("6");
|
||||
/** 1.3.36.3.3.2.8.1.7 */
|
||||
/** 1.3.36.3.3.2.8.1.1.7 */
|
||||
static final ASN1ObjectIdentifier brainpoolP256r1 = versionOne.branch("7");
|
||||
/** 1.3.36.3.3.2.8.1.8 */
|
||||
/** 1.3.36.3.3.2.8.1.1.8 */
|
||||
static final ASN1ObjectIdentifier brainpoolP256t1 = versionOne.branch("8");
|
||||
/** 1.3.36.3.3.2.8.1.9 */
|
||||
/** 1.3.36.3.3.2.8.1.1.9 */
|
||||
static final ASN1ObjectIdentifier brainpoolP320r1 = versionOne.branch("9");
|
||||
/** 1.3.36.3.3.2.8.1.10 */
|
||||
/** 1.3.36.3.3.2.8.1.1.10 */
|
||||
static final ASN1ObjectIdentifier brainpoolP320t1 = versionOne.branch("10");
|
||||
/** 1.3.36.3.3.2.8.1.11 */
|
||||
/** 1.3.36.3.3.2.8.1.1.11 */
|
||||
static final ASN1ObjectIdentifier brainpoolP384r1 = versionOne.branch("11");
|
||||
/** 1.3.36.3.3.2.8.1.12 */
|
||||
/** 1.3.36.3.3.2.8.1.1.12 */
|
||||
static final ASN1ObjectIdentifier brainpoolP384t1 = versionOne.branch("12");
|
||||
/** 1.3.36.3.3.2.8.1.13 */
|
||||
/** 1.3.36.3.3.2.8.1.1.13 */
|
||||
static final ASN1ObjectIdentifier brainpoolP512r1 = versionOne.branch("13");
|
||||
/** 1.3.36.3.3.2.8.1.14 */
|
||||
/** 1.3.36.3.3.2.8.1.1.14 */
|
||||
static final ASN1ObjectIdentifier brainpoolP512t1 = versionOne.branch("14");
|
||||
}
|
||||
|
@ -12,15 +12,15 @@ import org.spongycastle.asn1.ASN1TaggedObject;
|
||||
import org.spongycastle.asn1.DEROctetString;
|
||||
import org.spongycastle.asn1.DERSequence;
|
||||
import org.spongycastle.asn1.DERTaggedObject;
|
||||
import org.spongycastle.asn1.x9.X9IntegerConverter;
|
||||
import org.spongycastle.crypto.params.ECDomainParameters;
|
||||
import org.spongycastle.math.ec.ECAlgorithms;
|
||||
import org.spongycastle.math.ec.ECCurve;
|
||||
import org.spongycastle.math.field.PolynomialExtensionField;
|
||||
import org.spongycastle.util.Arrays;
|
||||
|
||||
public class DSTU4145ECBinary
|
||||
extends ASN1Object
|
||||
{
|
||||
|
||||
BigInteger version = BigInteger.valueOf(0);
|
||||
|
||||
DSTU4145BinaryField f;
|
||||
@ -31,17 +31,27 @@ public class DSTU4145ECBinary
|
||||
|
||||
public DSTU4145ECBinary(ECDomainParameters params)
|
||||
{
|
||||
if (!(params.getCurve() instanceof ECCurve.F2m))
|
||||
ECCurve curve = params.getCurve();
|
||||
if (!ECAlgorithms.isF2mCurve(curve))
|
||||
{
|
||||
throw new IllegalArgumentException("only binary domain is possible");
|
||||
}
|
||||
|
||||
// We always use big-endian in parameter encoding
|
||||
ECCurve.F2m curve = (ECCurve.F2m)params.getCurve();
|
||||
f = new DSTU4145BinaryField(curve.getM(), curve.getK1(), curve.getK2(), curve.getK3());
|
||||
|
||||
PolynomialExtensionField field = (PolynomialExtensionField)curve.getField();
|
||||
int[] exponents = field.getMinimalPolynomial().getExponentsPresent();
|
||||
if (exponents.length == 3)
|
||||
{
|
||||
f = new DSTU4145BinaryField(exponents[2], exponents[1]);
|
||||
}
|
||||
else if (exponents.length == 5)
|
||||
{
|
||||
f = new DSTU4145BinaryField(exponents[4], exponents[1], exponents[2], exponents[3]);
|
||||
}
|
||||
|
||||
a = new ASN1Integer(curve.getA().toBigInteger());
|
||||
X9IntegerConverter converter = new X9IntegerConverter();
|
||||
b = new DEROctetString(converter.integerToBytes(curve.getB().toBigInteger(), converter.getByteLength(curve)));
|
||||
b = new DEROctetString(curve.getB().getEncoded());
|
||||
n = new ASN1Integer(params.getN());
|
||||
bp = new DEROctetString(DSTU4145PointEncoder.encodePoint(params.getG()));
|
||||
}
|
||||
|
@ -21,17 +21,41 @@ public class DSTU4145NamedCurves
|
||||
|
||||
static
|
||||
{
|
||||
BigInteger[] n_s = new BigInteger[10];
|
||||
n_s[0] = new BigInteger("400000000000000000002BEC12BE2262D39BCF14D", 16);
|
||||
n_s[1] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFB12EBCC7D7F29FF7701F", 16);
|
||||
n_s[2] = new BigInteger("800000000000000000000189B4E67606E3825BB2831", 16);
|
||||
n_s[3] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFB981960435FE5AB64236EF", 16);
|
||||
n_s[4] = new BigInteger("40000000000000000000000069A779CAC1DABC6788F7474F", 16);
|
||||
n_s[5] = new BigInteger("1000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 16);
|
||||
n_s[6] = new BigInteger("800000000000000000000000000000006759213AF182E987D3E17714907D470D", 16);
|
||||
n_s[7] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC079C2F3825DA70D390FBBA588D4604022B7B7", 16);
|
||||
n_s[8] = new BigInteger("40000000000000000000000000000000000000000000009C300B75A3FA824F22428FD28CE8812245EF44049B2D49", 16);
|
||||
n_s[9] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA3175458009A8C0A724F02F81AA8A1FCBAF80D90C7A95110504CF", 16);
|
||||
|
||||
BigInteger[] h_s = new BigInteger[10];
|
||||
h_s[0] = BigInteger.valueOf(2);
|
||||
h_s[1] = BigInteger.valueOf(2);
|
||||
h_s[2] = BigInteger.valueOf(4);
|
||||
h_s[3] = BigInteger.valueOf(2);
|
||||
h_s[4] = BigInteger.valueOf(2);
|
||||
h_s[5] = BigInteger.valueOf(2);
|
||||
h_s[6] = BigInteger.valueOf(4);
|
||||
h_s[7] = BigInteger.valueOf(2);
|
||||
h_s[8] = BigInteger.valueOf(2);
|
||||
h_s[9] = BigInteger.valueOf(2);
|
||||
|
||||
ECCurve.F2m[] curves = new ECCurve.F2m[10];
|
||||
curves[0] = new ECCurve.F2m(163, 3, 6, 7, ONE, new BigInteger("5FF6108462A2DC8210AB403925E638A19C1455D21", 16));
|
||||
curves[1] = new ECCurve.F2m(167, 6, ONE, new BigInteger("6EE3CEEB230811759F20518A0930F1A4315A827DAC", 16));
|
||||
curves[2] = new ECCurve.F2m(173, 1, 2, 10, ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16));
|
||||
curves[3] = new ECCurve.F2m(179, 1, 2, 4, ONE, new BigInteger("4A6E0856526436F2F88DD07A341E32D04184572BEB710", 16));
|
||||
curves[4] = new ECCurve.F2m(191, 9, ONE, new BigInteger("7BC86E2102902EC4D5890E8B6B4981ff27E0482750FEFC03", 16));
|
||||
curves[5] = new ECCurve.F2m(233, 1, 4, 9, ONE, new BigInteger("06973B15095675534C7CF7E64A21BD54EF5DD3B8A0326AA936ECE454D2C", 16));
|
||||
curves[6] = new ECCurve.F2m(257, 12, ZERO, new BigInteger("1CEF494720115657E18F938D7A7942394FF9425C1458C57861F9EEA6ADBE3BE10", 16));
|
||||
curves[7] = new ECCurve.F2m(307, 2, 4, 8, ONE, new BigInteger("393C7F7D53666B5054B5E6C6D3DE94F4296C0C599E2E2E241050DF18B6090BDC90186904968BB", 16));
|
||||
curves[8] = new ECCurve.F2m(367, 21, ONE, new BigInteger("43FC8AD242B0B7A6F3D1627AD5654447556B47BF6AA4A64B0C2AFE42CADAB8F93D92394C79A79755437B56995136", 16));
|
||||
curves[9] = new ECCurve.F2m(431, 1, 3, 5, ONE, new BigInteger("03CE10490F6A708FC26DFE8C3D27C4F94E690134D5BFF988D8D28AAEAEDE975936C66BAC536B18AE2DC312CA493117DAA469C640CAF3", 16));
|
||||
curves[0] = new ECCurve.F2m(163, 3, 6, 7, ONE, new BigInteger("5FF6108462A2DC8210AB403925E638A19C1455D21", 16), n_s[0], h_s[0]);
|
||||
curves[1] = new ECCurve.F2m(167, 6, ONE, new BigInteger("6EE3CEEB230811759F20518A0930F1A4315A827DAC", 16), n_s[1], h_s[1]);
|
||||
curves[2] = new ECCurve.F2m(173, 1, 2, 10, ZERO, new BigInteger("108576C80499DB2FC16EDDF6853BBB278F6B6FB437D9", 16), n_s[2], h_s[2]);
|
||||
curves[3] = new ECCurve.F2m(179, 1, 2, 4, ONE, new BigInteger("4A6E0856526436F2F88DD07A341E32D04184572BEB710", 16), n_s[3], h_s[3]);
|
||||
curves[4] = new ECCurve.F2m(191, 9, ONE, new BigInteger("7BC86E2102902EC4D5890E8B6B4981ff27E0482750FEFC03", 16), n_s[4], h_s[4]);
|
||||
curves[5] = new ECCurve.F2m(233, 1, 4, 9, ONE, new BigInteger("06973B15095675534C7CF7E64A21BD54EF5DD3B8A0326AA936ECE454D2C", 16), n_s[5], h_s[5]);
|
||||
curves[6] = new ECCurve.F2m(257, 12, ZERO, new BigInteger("1CEF494720115657E18F938D7A7942394FF9425C1458C57861F9EEA6ADBE3BE10", 16), n_s[6], h_s[6]);
|
||||
curves[7] = new ECCurve.F2m(307, 2, 4, 8, ONE, new BigInteger("393C7F7D53666B5054B5E6C6D3DE94F4296C0C599E2E2E241050DF18B6090BDC90186904968BB", 16), n_s[7], h_s[7]);
|
||||
curves[8] = new ECCurve.F2m(367, 21, ONE, new BigInteger("43FC8AD242B0B7A6F3D1627AD5654447556B47BF6AA4A64B0C2AFE42CADAB8F93D92394C79A79755437B56995136", 16), n_s[8], h_s[8]);
|
||||
curves[9] = new ECCurve.F2m(431, 1, 3, 5, ONE, new BigInteger("03CE10490F6A708FC26DFE8C3D27C4F94E690134D5BFF988D8D28AAEAEDE975936C66BAC536B18AE2DC312CA493117DAA469C640CAF3", 16), n_s[9], h_s[9]);
|
||||
|
||||
ECPoint[] points = new ECPoint[10];
|
||||
points[0] = curves[0].createPoint(new BigInteger("2E2F85F5DD74CE983A5C4237229DAF8A3F35823BE", 16), new BigInteger("3826F008A8C51D7B95284D9D03FF0E00CE2CD723A", 16));
|
||||
@ -45,21 +69,9 @@ public class DSTU4145NamedCurves
|
||||
points[8] = curves[8].createPoint(new BigInteger("324A6EDDD512F08C49A99AE0D3F961197A76413E7BE81A400CA681E09639B5FE12E59A109F78BF4A373541B3B9A1", 16), new BigInteger("1AB597A5B4477F59E39539007C7F977D1A567B92B043A49C6B61984C3FE3481AAF454CD41BA1F051626442B3C10", 16));
|
||||
points[9] = curves[9].createPoint(new BigInteger("1A62BA79D98133A16BBAE7ED9A8E03C32E0824D57AEF72F88986874E5AAE49C27BED49A2A95058068426C2171E99FD3B43C5947C857D", 16), new BigInteger("70B5E1E14031C1F70BBEFE96BDDE66F451754B4CA5F48DA241F331AA396B8D1839A855C1769B1EA14BA53308B5E2723724E090E02DB9", 16));
|
||||
|
||||
BigInteger[] n_s = new BigInteger[10];
|
||||
n_s[0] = new BigInteger("400000000000000000002BEC12BE2262D39BCF14D", 16);
|
||||
n_s[1] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFB12EBCC7D7F29FF7701F", 16);
|
||||
n_s[2] = new BigInteger("800000000000000000000189B4E67606E3825BB2831", 16);
|
||||
n_s[3] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFB981960435FE5AB64236EF", 16);
|
||||
n_s[4] = new BigInteger("40000000000000000000000069A779CAC1DABC6788F7474F", 16);
|
||||
n_s[5] = new BigInteger("1000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", 16);
|
||||
n_s[6] = new BigInteger("800000000000000000000000000000006759213AF182E987D3E17714907D470D", 16);
|
||||
n_s[7] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC079C2F3825DA70D390FBBA588D4604022B7B7", 16);
|
||||
n_s[8] = new BigInteger("40000000000000000000000000000000000000000000009C300B75A3FA824F22428FD28CE8812245EF44049B2D49", 16);
|
||||
n_s[9] = new BigInteger("3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBA3175458009A8C0A724F02F81AA8A1FCBAF80D90C7A95110504CF", 16);
|
||||
|
||||
for (int i = 0; i < params.length; i++)
|
||||
{
|
||||
params[i] = new ECDomainParameters(curves[i], points[i], n_s[i]);
|
||||
params[i] = new ECDomainParameters(curves[i], points[i], n_s[i], h_s[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < oids.length; i++)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user