mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-01-30 14:52:16 +00:00
Remove the built-in copy of Bouncy Castle. Instead, make it a dependency in the Maven POM. Also include the shade plugin so the final JARs won't cause conflicts on Android. Resolves issue 42. Patch by Jonny Heggheim.
This commit is contained in:
parent
67aa0ae4a3
commit
49d676160c
1
AUTHORS
1
AUTHORS
@ -8,3 +8,4 @@ Noa Resare <noa@resare.com>
|
||||
John Sample <jwsample@gmail.com>
|
||||
Jan Møller <jan.moller@gmail.com>
|
||||
Wolfgang Nagele <wolfgang.nagele@gmail.com>
|
||||
Jonny Heggheim <hegjon@gmail.com>
|
35
pom.xml
35
pom.xml
@ -187,6 +187,34 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Automatically downloads and renames Bouncy Castle to avoid conflicts on Android. -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.bouncycastle</pattern>
|
||||
<shadedPattern>com.google.bitcoin.bouncycastle</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<include>org.bouncycastle</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Execute FindBugs during verify phase
|
||||
Will fail the build if it finds a bug
|
||||
Enable when ready -->
|
||||
@ -235,6 +263,13 @@
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk15</artifactId>
|
||||
<version>1.46</version>
|
||||
<type>jar</type>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<!-- The reporting section is deprecated in Maven3,
|
||||
but can be read by site plugin (see MNG-4162) -->
|
||||
|
@ -1,63 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle;
|
||||
|
||||
/**
|
||||
* The Bouncy Castle License
|
||||
*
|
||||
* Copyright (c) 2000-2008 The Legion Of The Bouncy Castle (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,
|
||||
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
* <p>
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||
* portions of the Software.
|
||||
* <p>
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
public class LICENSE
|
||||
{
|
||||
public static String licenseText =
|
||||
"Copyright (c) 2000-2008 The Legion Of The Bouncy Castle (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 "
|
||||
+ System.getProperty("line.separator")
|
||||
+ "and associated documentation files (the \"Software\"), to deal in the Software without restriction, "
|
||||
+ System.getProperty("line.separator")
|
||||
+ "including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, "
|
||||
+ System.getProperty("line.separator")
|
||||
+ "and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,"
|
||||
+ System.getProperty("line.separator")
|
||||
+ "subject to the following conditions:"
|
||||
+ System.getProperty("line.separator")
|
||||
+ System.getProperty("line.separator")
|
||||
+ "The above copyright notice and this permission notice shall be included in all copies or substantial"
|
||||
+ System.getProperty("line.separator")
|
||||
+ "portions of the Software."
|
||||
+ System.getProperty("line.separator")
|
||||
+ System.getProperty("line.separator")
|
||||
+ "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,"
|
||||
+ System.getProperty("line.separator")
|
||||
+ "INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR"
|
||||
+ System.getProperty("line.separator")
|
||||
+ "PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE"
|
||||
+ System.getProperty("line.separator")
|
||||
+ "LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR"
|
||||
+ System.getProperty("line.separator")
|
||||
+ "OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER"
|
||||
+ System.getProperty("line.separator")
|
||||
+ "DEALINGS IN THE SOFTWARE.";
|
||||
|
||||
public static void main(
|
||||
String[] args)
|
||||
{
|
||||
System.out.println(licenseText);
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface ASN1ApplicationSpecificParser
|
||||
extends DEREncodable
|
||||
{
|
||||
DEREncodable readObject()
|
||||
throws IOException;
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
/**
|
||||
* Marker interface for CHOICE objects - if you implement this in a role your
|
||||
* 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.
|
||||
*/
|
||||
public interface ASN1Choice
|
||||
{
|
||||
// marker interface
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Base class for objects which can be written directly to ASN.1 output streams.
|
||||
*/
|
||||
public abstract class ASN1Encodable
|
||||
implements DEREncodable
|
||||
{
|
||||
public static final String DER = "DER";
|
||||
public static final String BER = "BER";
|
||||
|
||||
/**
|
||||
* Return the default BER or DER encoding for this object.
|
||||
*
|
||||
* @return BER/DER byte encoded object.
|
||||
* @throws IOException on encoding error.
|
||||
*/
|
||||
public byte[] getEncoded()
|
||||
throws IOException
|
||||
{
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ASN1OutputStream aOut = new ASN1OutputStream(bOut);
|
||||
|
||||
aOut.writeObject(this);
|
||||
|
||||
return bOut.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return either the default for "BER" or a DER encoding if "DER" is specified.
|
||||
*
|
||||
* @param encoding name of encoding to use.
|
||||
* @return byte encoded object.
|
||||
* @throws IOException on encoding error.
|
||||
*/
|
||||
public byte[] getEncoded(
|
||||
String encoding)
|
||||
throws IOException
|
||||
{
|
||||
if (encoding.equals(DER))
|
||||
{
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
DEROutputStream dOut = new DEROutputStream(bOut);
|
||||
|
||||
dOut.writeObject(this);
|
||||
|
||||
return bOut.toByteArray();
|
||||
}
|
||||
|
||||
return this.getEncoded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DER encoding of the object, null if the DER encoding can not be made.
|
||||
*
|
||||
* @return a DER byte array, null otherwise.
|
||||
*/
|
||||
public byte[] getDEREncoded()
|
||||
{
|
||||
try
|
||||
{
|
||||
return this.getEncoded(DER);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return this.toASN1Object().hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(
|
||||
Object o)
|
||||
{
|
||||
if (this == o)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof DEREncodable))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DEREncodable other = (DEREncodable)o;
|
||||
|
||||
return this.toASN1Object().equals(other.getDERObject());
|
||||
}
|
||||
|
||||
public DERObject getDERObject()
|
||||
{
|
||||
return this.toASN1Object();
|
||||
}
|
||||
|
||||
public abstract DERObject toASN1Object();
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
/**
|
||||
* the parent class for this will eventually disappear. Use this one!
|
||||
*/
|
||||
public class ASN1EncodableVector
|
||||
extends DEREncodableVector
|
||||
{
|
||||
// migrating from DEREncodeableVector
|
||||
public ASN1EncodableVector()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
public abstract class ASN1Generator
|
||||
{
|
||||
protected OutputStream _out;
|
||||
|
||||
public ASN1Generator(OutputStream out)
|
||||
{
|
||||
_out = out;
|
||||
}
|
||||
|
||||
public abstract OutputStream getRawOutputStream();
|
||||
}
|
@ -1,386 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.util.io.Streams;
|
||||
|
||||
/**
|
||||
* a general purpose ASN.1 decoder - note: this class differs from the
|
||||
* others in that it returns null after it has read the last object in
|
||||
* the stream. If an ASN.1 NULL is encountered a DER/BER Null object is
|
||||
* returned.
|
||||
*/
|
||||
public class ASN1InputStream
|
||||
extends FilterInputStream
|
||||
implements DERTags
|
||||
{
|
||||
private final int limit;
|
||||
private final boolean lazyEvaluate;
|
||||
|
||||
public ASN1InputStream(
|
||||
InputStream is)
|
||||
{
|
||||
this(is, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ASN1InputStream based on the input byte array. The length of DER objects in
|
||||
* the stream is automatically limited to the length of the input array.
|
||||
*
|
||||
* @param input array containing ASN.1 encoded data.
|
||||
*/
|
||||
public ASN1InputStream(
|
||||
byte[] input)
|
||||
{
|
||||
this(new ByteArrayInputStream(input), input.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ASN1InputStream based on the input byte array. The length of DER objects in
|
||||
* the stream is automatically limited to the length of the input array.
|
||||
*
|
||||
* @param input array containing ASN.1 encoded data.
|
||||
* @param lazyEvaluate true if parsing inside constructed objects can be delayed.
|
||||
*/
|
||||
public ASN1InputStream(
|
||||
byte[] input,
|
||||
boolean lazyEvaluate)
|
||||
{
|
||||
this(new ByteArrayInputStream(input), input.length, lazyEvaluate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ASN1InputStream where no DER object will be longer than limit.
|
||||
*
|
||||
* @param input stream containing ASN.1 encoded data.
|
||||
* @param limit maximum size of a DER encoded object.
|
||||
*/
|
||||
public ASN1InputStream(
|
||||
InputStream input,
|
||||
int limit)
|
||||
{
|
||||
this(input, limit, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an ASN1InputStream where no DER object will be longer than limit, and constructed
|
||||
* objects such as sequences will be parsed lazily.
|
||||
*
|
||||
* @param input stream containing ASN.1 encoded data.
|
||||
* @param limit maximum size of a DER encoded object.
|
||||
* @param lazyEvaluate true if parsing inside constructed objects can be delayed.
|
||||
*/
|
||||
public ASN1InputStream(
|
||||
InputStream input,
|
||||
int limit,
|
||||
boolean lazyEvaluate)
|
||||
{
|
||||
super(input);
|
||||
this.limit = limit;
|
||||
this.lazyEvaluate = lazyEvaluate;
|
||||
}
|
||||
|
||||
protected int readLength()
|
||||
throws IOException
|
||||
{
|
||||
return readLength(this, limit);
|
||||
}
|
||||
|
||||
protected void readFully(
|
||||
byte[] bytes)
|
||||
throws IOException
|
||||
{
|
||||
if (Streams.readFully(this, bytes) != bytes.length)
|
||||
{
|
||||
throw new EOFException("EOF encountered in middle of object");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* build an object given its tag and the number of bytes to construct it from.
|
||||
*/
|
||||
protected DERObject buildObject(
|
||||
int tag,
|
||||
int tagNo,
|
||||
int length)
|
||||
throws IOException
|
||||
{
|
||||
boolean isConstructed = (tag & CONSTRUCTED) != 0;
|
||||
|
||||
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(this, length);
|
||||
|
||||
if ((tag & APPLICATION) != 0)
|
||||
{
|
||||
return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
|
||||
}
|
||||
|
||||
if ((tag & TAGGED) != 0)
|
||||
{
|
||||
return new BERTaggedObjectParser(tag, tagNo, defIn).getDERObject();
|
||||
}
|
||||
|
||||
if (isConstructed)
|
||||
{
|
||||
// TODO There are other tags that may be constructed (e.g. BIT_STRING)
|
||||
switch (tagNo)
|
||||
{
|
||||
case OCTET_STRING:
|
||||
//
|
||||
// yes, people actually do this...
|
||||
//
|
||||
return new BERConstructedOctetString(buildDEREncodableVector(defIn).v);
|
||||
case SEQUENCE:
|
||||
if (lazyEvaluate)
|
||||
{
|
||||
return new LazyDERSequence(defIn.toByteArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
return DERFactory.createSequence(buildDEREncodableVector(defIn));
|
||||
}
|
||||
case SET:
|
||||
return DERFactory.createSet(buildDEREncodableVector(defIn), false);
|
||||
case EXTERNAL:
|
||||
return new DERExternal(buildDEREncodableVector(defIn));
|
||||
default:
|
||||
return new DERUnknownTag(true, tagNo, defIn.toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
return createPrimitiveDERObject(tagNo, defIn.toByteArray());
|
||||
}
|
||||
|
||||
ASN1EncodableVector buildEncodableVector()
|
||||
throws IOException
|
||||
{
|
||||
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||
DERObject o;
|
||||
|
||||
while ((o = readObject()) != null)
|
||||
{
|
||||
v.add(o);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
ASN1EncodableVector buildDEREncodableVector(
|
||||
DefiniteLengthInputStream dIn) throws IOException
|
||||
{
|
||||
return new ASN1InputStream(dIn).buildEncodableVector();
|
||||
}
|
||||
|
||||
public DERObject readObject()
|
||||
throws IOException
|
||||
{
|
||||
int tag = read();
|
||||
if (tag <= 0)
|
||||
{
|
||||
if (tag == 0)
|
||||
{
|
||||
throw new IOException("unexpected end-of-contents marker");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
// calculate tag number
|
||||
//
|
||||
int tagNo = readTagNumber(this, tag);
|
||||
|
||||
boolean isConstructed = (tag & CONSTRUCTED) != 0;
|
||||
|
||||
//
|
||||
// calculate length
|
||||
//
|
||||
int length = readLength();
|
||||
|
||||
if (length < 0) // indefinite length method
|
||||
{
|
||||
if (!isConstructed)
|
||||
{
|
||||
throw new IOException("indefinite length primitive encoding encountered");
|
||||
}
|
||||
|
||||
IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(this);
|
||||
|
||||
if ((tag & APPLICATION) != 0)
|
||||
{
|
||||
ASN1StreamParser sp = new ASN1StreamParser(indIn, limit);
|
||||
|
||||
return new BERApplicationSpecificParser(tagNo, sp).getDERObject();
|
||||
}
|
||||
if ((tag & TAGGED) != 0)
|
||||
{
|
||||
return new BERTaggedObjectParser(tag, tagNo, indIn).getDERObject();
|
||||
}
|
||||
|
||||
ASN1StreamParser sp = new ASN1StreamParser(indIn, limit);
|
||||
|
||||
// TODO There are other tags that may be constructed (e.g. BIT_STRING)
|
||||
switch (tagNo)
|
||||
{
|
||||
case OCTET_STRING:
|
||||
return new BEROctetStringParser(sp).getDERObject();
|
||||
case SEQUENCE:
|
||||
return new BERSequenceParser(sp).getDERObject();
|
||||
case SET:
|
||||
return new BERSetParser(sp).getDERObject();
|
||||
case EXTERNAL:
|
||||
return new DERExternalParser(sp).getDERObject();
|
||||
default:
|
||||
throw new IOException("unknown BER object encountered");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return buildObject(tag, tagNo, length);
|
||||
}
|
||||
}
|
||||
|
||||
static int readTagNumber(InputStream s, int tag)
|
||||
throws IOException
|
||||
{
|
||||
int tagNo = tag & 0x1f;
|
||||
|
||||
//
|
||||
// with tagged object tag number is bottom 5 bits, or stored at the start of the content
|
||||
//
|
||||
if (tagNo == 0x1f)
|
||||
{
|
||||
tagNo = 0;
|
||||
|
||||
int b = s.read();
|
||||
|
||||
// X.690-0207 8.1.2.4.2
|
||||
// "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
|
||||
if ((b & 0x7f) == 0) // Note: -1 will pass
|
||||
{
|
||||
throw new IOException("corrupted stream - invalid high tag number found");
|
||||
}
|
||||
|
||||
while ((b >= 0) && ((b & 0x80) != 0))
|
||||
{
|
||||
tagNo |= (b & 0x7f);
|
||||
tagNo <<= 7;
|
||||
b = s.read();
|
||||
}
|
||||
|
||||
if (b < 0)
|
||||
{
|
||||
throw new EOFException("EOF found inside tag value.");
|
||||
}
|
||||
|
||||
tagNo |= (b & 0x7f);
|
||||
}
|
||||
|
||||
return tagNo;
|
||||
}
|
||||
|
||||
static int readLength(InputStream s, int limit)
|
||||
throws IOException
|
||||
{
|
||||
int length = s.read();
|
||||
if (length < 0)
|
||||
{
|
||||
throw new EOFException("EOF found when length expected");
|
||||
}
|
||||
|
||||
if (length == 0x80)
|
||||
{
|
||||
return -1; // indefinite-length encoding
|
||||
}
|
||||
|
||||
if (length > 127)
|
||||
{
|
||||
int size = length & 0x7f;
|
||||
|
||||
if (size > 4)
|
||||
{
|
||||
throw new IOException("DER length more than 4 bytes: " + size);
|
||||
}
|
||||
|
||||
length = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
int next = s.read();
|
||||
|
||||
if (next < 0)
|
||||
{
|
||||
throw new EOFException("EOF found reading length");
|
||||
}
|
||||
|
||||
length = (length << 8) + next;
|
||||
}
|
||||
|
||||
if (length < 0)
|
||||
{
|
||||
throw new IOException("corrupted stream - negative length found");
|
||||
}
|
||||
|
||||
if (length >= limit) // after all we must have read at least 1 byte
|
||||
{
|
||||
throw new IOException("corrupted stream - out of bounds length found");
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static DERObject createPrimitiveDERObject(
|
||||
int tagNo,
|
||||
byte[] bytes)
|
||||
{
|
||||
switch (tagNo)
|
||||
{
|
||||
case BIT_STRING:
|
||||
{
|
||||
int padBits = bytes[0];
|
||||
byte[] data = new byte[bytes.length - 1];
|
||||
System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
|
||||
return new DERBitString(data, padBits);
|
||||
}
|
||||
case BMP_STRING:
|
||||
return new DERBMPString(bytes);
|
||||
case BOOLEAN:
|
||||
return new DERBoolean(bytes);
|
||||
case ENUMERATED:
|
||||
return new DEREnumerated(bytes);
|
||||
case GENERALIZED_TIME:
|
||||
return new DERGeneralizedTime(bytes);
|
||||
case GENERAL_STRING:
|
||||
return new DERGeneralString(bytes);
|
||||
case IA5_STRING:
|
||||
return new DERIA5String(bytes);
|
||||
case INTEGER:
|
||||
return new DERInteger(bytes);
|
||||
case NULL:
|
||||
return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?)
|
||||
case NUMERIC_STRING:
|
||||
return new DERNumericString(bytes);
|
||||
case OBJECT_IDENTIFIER:
|
||||
return new DERObjectIdentifier(bytes);
|
||||
case OCTET_STRING:
|
||||
return new DEROctetString(bytes);
|
||||
case PRINTABLE_STRING:
|
||||
return new DERPrintableString(bytes);
|
||||
case T61_STRING:
|
||||
return new DERT61String(bytes);
|
||||
case UNIVERSAL_STRING:
|
||||
return new DERUniversalString(bytes);
|
||||
case UTC_TIME:
|
||||
return new DERUTCTime(bytes);
|
||||
case UTF8_STRING:
|
||||
return new DERUTF8String(bytes);
|
||||
case VISIBLE_STRING:
|
||||
return new DERVisibleString(bytes);
|
||||
default:
|
||||
return new DERUnknownTag(false, tagNo, bytes);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A NULL object.
|
||||
*/
|
||||
public abstract class ASN1Null
|
||||
extends ASN1Object
|
||||
{
|
||||
public ASN1Null()
|
||||
{
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof ASN1Null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
abstract void encode(DEROutputStream out)
|
||||
throws IOException;
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "NULL";
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class ASN1Object
|
||||
extends DERObject
|
||||
{
|
||||
/**
|
||||
* Create a base ASN.1 object from a byte stream.
|
||||
*
|
||||
* @param data the byte stream to parse.
|
||||
* @return the base ASN.1 object represented by the byte stream.
|
||||
* @exception IOException if there is a problem parsing the data.
|
||||
*/
|
||||
public static ASN1Object fromByteArray(byte[] data)
|
||||
throws IOException
|
||||
{
|
||||
ASN1InputStream aIn = new ASN1InputStream(data);
|
||||
|
||||
return (ASN1Object)aIn.readObject();
|
||||
}
|
||||
|
||||
public final boolean equals(Object o)
|
||||
{
|
||||
if (this == o)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return (o instanceof DEREncodable) && asn1Equals(((DEREncodable)o).getDERObject());
|
||||
}
|
||||
|
||||
public abstract int hashCode();
|
||||
|
||||
abstract void encode(DEROutputStream out) throws IOException;
|
||||
|
||||
abstract boolean asn1Equals(DERObject o);
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @deprecated will be removed
|
||||
*/
|
||||
public class ASN1ObjectParser
|
||||
{
|
||||
ASN1StreamParser _aIn;
|
||||
|
||||
protected ASN1ObjectParser(
|
||||
int baseTag,
|
||||
int tagNumber,
|
||||
InputStream contentStream)
|
||||
{
|
||||
_aIn = new ASN1StreamParser(contentStream);
|
||||
}
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.util.Arrays;
|
||||
import com.google.bitcoin.bouncycastle.util.encoders.Hex;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
public abstract class ASN1OctetString
|
||||
extends ASN1Object
|
||||
implements ASN1OctetStringParser
|
||||
{
|
||||
byte[] string;
|
||||
|
||||
/**
|
||||
* return an Octet 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.
|
||||
*/
|
||||
public static ASN1OctetString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* return an Octet String from the given object.
|
||||
*
|
||||
* @param obj the object we want converted.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static ASN1OctetString getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof ASN1OctetString)
|
||||
{
|
||||
return (ASN1OctetString)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject)obj).getObject());
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1Sequence)
|
||||
{
|
||||
Vector v = new Vector();
|
||||
Enumeration e = ((ASN1Sequence)obj).getObjects();
|
||||
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
v.addElement(e.nextElement());
|
||||
}
|
||||
|
||||
return new BERConstructedOctetString(v);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string the octets making up the octet string.
|
||||
*/
|
||||
public ASN1OctetString(
|
||||
byte[] string)
|
||||
{
|
||||
if (string == null)
|
||||
{
|
||||
throw new NullPointerException("string cannot be null");
|
||||
}
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public ASN1OctetString(
|
||||
DEREncodable obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.string = obj.getDERObject().getEncoded(ASN1Encodable.DER);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Error processing object : " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public InputStream getOctetStream()
|
||||
{
|
||||
return new ByteArrayInputStream(string);
|
||||
}
|
||||
|
||||
public ASN1OctetStringParser parser()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public byte[] getOctets()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return Arrays.hashCode(this.getOctets());
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof ASN1OctetString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ASN1OctetString other = (ASN1OctetString)o;
|
||||
|
||||
return Arrays.areEqual(string, other.string);
|
||||
}
|
||||
|
||||
abstract void encode(DEROutputStream out)
|
||||
throws IOException;
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "#"+new String(Hex.encode(string));
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public interface ASN1OctetStringParser
|
||||
extends DEREncodable
|
||||
{
|
||||
public InputStream getOctetStream();
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class ASN1OutputStream
|
||||
extends DEROutputStream
|
||||
{
|
||||
public ASN1OutputStream(
|
||||
OutputStream os)
|
||||
{
|
||||
super(os);
|
||||
}
|
||||
|
||||
public void writeObject(
|
||||
Object obj)
|
||||
throws IOException
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
writeNull();
|
||||
}
|
||||
else if (obj instanceof DERObject)
|
||||
{
|
||||
((DERObject)obj).encode(this);
|
||||
}
|
||||
else if (obj instanceof DEREncodable)
|
||||
{
|
||||
((DEREncodable)obj).getDERObject().encode(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("object not ASN1Encodable");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
public class ASN1ParsingException
|
||||
extends IllegalStateException
|
||||
{
|
||||
private Throwable cause;
|
||||
|
||||
ASN1ParsingException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
|
||||
ASN1ParsingException(String message, Throwable cause)
|
||||
{
|
||||
super(message);
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
public Throwable getCause()
|
||||
{
|
||||
return cause;
|
||||
}
|
||||
}
|
@ -1,217 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
public abstract class ASN1Sequence
|
||||
extends ASN1Object
|
||||
{
|
||||
private Vector seq = new Vector();
|
||||
|
||||
/**
|
||||
* return an ASN1Sequence from the given object.
|
||||
*
|
||||
* @param obj the object we want converted.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static ASN1Sequence getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof ASN1Sequence)
|
||||
{
|
||||
return (ASN1Sequence)obj;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an ASN1 sequence from a tagged object. There is a special
|
||||
* case here, if an object appears to have been explicitly tagged on
|
||||
* reading but we were expecting it to be implicitly tagged in the
|
||||
* normal course of events it indicates that we lost the surrounding
|
||||
* sequence - so we need to add it back (this will happen if the tagged
|
||||
* object is a sequence that contains other sequences). If you are
|
||||
* dealing with implicitly tagged sequences you really <b>should</b>
|
||||
* be using this method.
|
||||
*
|
||||
* @param obj the tagged object.
|
||||
* @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 ASN1Sequence getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
if (explicit)
|
||||
{
|
||||
if (!obj.isExplicit())
|
||||
{
|
||||
throw new IllegalArgumentException("object implicit - explicit expected.");
|
||||
}
|
||||
|
||||
return (ASN1Sequence)obj.getObject();
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// constructed object which appears to be explicitly tagged
|
||||
// when it should be implicit means we have to add the
|
||||
// surrounding sequence.
|
||||
//
|
||||
if (obj.isExplicit())
|
||||
{
|
||||
if (obj instanceof BERTaggedObject)
|
||||
{
|
||||
return new BERSequence(obj.getObject());
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DERSequence(obj.getObject());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (obj.getObject() instanceof ASN1Sequence)
|
||||
{
|
||||
return (ASN1Sequence)obj.getObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
public Enumeration getObjects()
|
||||
{
|
||||
return seq.elements();
|
||||
}
|
||||
|
||||
public ASN1SequenceParser parser()
|
||||
{
|
||||
final ASN1Sequence outer = this;
|
||||
|
||||
return new ASN1SequenceParser()
|
||||
{
|
||||
private final int max = size();
|
||||
|
||||
private int index;
|
||||
|
||||
public DEREncodable readObject() throws IOException
|
||||
{
|
||||
if (index == max)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
DEREncodable obj = getObjectAt(index++);
|
||||
if (obj instanceof ASN1Sequence)
|
||||
{
|
||||
return ((ASN1Sequence)obj).parser();
|
||||
}
|
||||
if (obj instanceof ASN1Set)
|
||||
{
|
||||
return ((ASN1Set)obj).parser();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public DERObject getDERObject()
|
||||
{
|
||||
return outer;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public DEREncodable getObjectAt(
|
||||
int index)
|
||||
{
|
||||
return (DEREncodable)seq.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the number of objects in this sequence.
|
||||
*
|
||||
* @return the number of objects in this sequence.
|
||||
*/
|
||||
public int size()
|
||||
{
|
||||
return seq.size();
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
Enumeration e = this.getObjects();
|
||||
int hashCode = size();
|
||||
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
Object o = e.nextElement();
|
||||
hashCode *= 17;
|
||||
if (o != null)
|
||||
{
|
||||
hashCode ^= o.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof ASN1Sequence))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ASN1Sequence other = (ASN1Sequence)o;
|
||||
|
||||
if (this.size() != other.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Enumeration s1 = this.getObjects();
|
||||
Enumeration s2 = other.getObjects();
|
||||
|
||||
while (s1.hasMoreElements())
|
||||
{
|
||||
DERObject o1 = ((DEREncodable)s1.nextElement()).getDERObject();
|
||||
DERObject o2 = ((DEREncodable)s2.nextElement()).getDERObject();
|
||||
|
||||
if (o1 == o2 || (o1 != null && o1.equals(o2)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void addObject(
|
||||
DEREncodable obj)
|
||||
{
|
||||
seq.addElement(obj);
|
||||
}
|
||||
|
||||
abstract void encode(DEROutputStream out)
|
||||
throws IOException;
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return seq.toString();
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface ASN1SequenceParser
|
||||
extends DEREncodable
|
||||
{
|
||||
DEREncodable readObject()
|
||||
throws IOException;
|
||||
}
|
@ -1,343 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
abstract public class ASN1Set
|
||||
extends ASN1Object
|
||||
{
|
||||
protected Vector set = new Vector();
|
||||
|
||||
/**
|
||||
* return an ASN1Set from the given object.
|
||||
*
|
||||
* @param obj the object we want converted.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static ASN1Set getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof ASN1Set)
|
||||
{
|
||||
return (ASN1Set)obj;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an ASN1 set from a tagged object. There is a special
|
||||
* case here, if an object appears to have been explicitly tagged on
|
||||
* reading but we were expecting it to be implicitly tagged in the
|
||||
* normal course of events it indicates that we lost the surrounding
|
||||
* set - so we need to add it back (this will happen if the tagged
|
||||
* object is a sequence that contains other sequences). If you are
|
||||
* dealing with implicitly tagged sets you really <b>should</b>
|
||||
* be using this method.
|
||||
*
|
||||
* @param obj the tagged object.
|
||||
* @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 ASN1Set getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
if (explicit)
|
||||
{
|
||||
if (!obj.isExplicit())
|
||||
{
|
||||
throw new IllegalArgumentException("object implicit - explicit expected.");
|
||||
}
|
||||
|
||||
return (ASN1Set)obj.getObject();
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// constructed object which appears to be explicitly tagged
|
||||
// and it's really implicit means we have to add the
|
||||
// surrounding sequence.
|
||||
//
|
||||
if (obj.isExplicit())
|
||||
{
|
||||
ASN1Set set = new DERSet(obj.getObject());
|
||||
|
||||
return set;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (obj.getObject() instanceof ASN1Set)
|
||||
{
|
||||
return (ASN1Set)obj.getObject();
|
||||
}
|
||||
|
||||
//
|
||||
// in this case the parser returns a sequence, convert it
|
||||
// into a set.
|
||||
//
|
||||
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||
|
||||
if (obj.getObject() instanceof ASN1Sequence)
|
||||
{
|
||||
ASN1Sequence s = (ASN1Sequence)obj.getObject();
|
||||
Enumeration e = s.getObjects();
|
||||
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
v.add((DEREncodable)e.nextElement());
|
||||
}
|
||||
|
||||
return new DERSet(v, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
public ASN1Set()
|
||||
{
|
||||
}
|
||||
|
||||
public Enumeration getObjects()
|
||||
{
|
||||
return set.elements();
|
||||
}
|
||||
|
||||
/**
|
||||
* return the object at the set position indicated by index.
|
||||
*
|
||||
* @param index the set number (starting at zero) of the object
|
||||
* @return the object at the set position indicated by index.
|
||||
*/
|
||||
public DEREncodable getObjectAt(
|
||||
int index)
|
||||
{
|
||||
return (DEREncodable)set.elementAt(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the number of objects in this set.
|
||||
*
|
||||
* @return the number of objects in this set.
|
||||
*/
|
||||
public int size()
|
||||
{
|
||||
return set.size();
|
||||
}
|
||||
|
||||
public ASN1SetParser parser()
|
||||
{
|
||||
final ASN1Set outer = this;
|
||||
|
||||
return new ASN1SetParser()
|
||||
{
|
||||
private final int max = size();
|
||||
|
||||
private int index;
|
||||
|
||||
public DEREncodable readObject() throws IOException
|
||||
{
|
||||
if (index == max)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
DEREncodable obj = getObjectAt(index++);
|
||||
if (obj instanceof ASN1Sequence)
|
||||
{
|
||||
return ((ASN1Sequence)obj).parser();
|
||||
}
|
||||
if (obj instanceof ASN1Set)
|
||||
{
|
||||
return ((ASN1Set)obj).parser();
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public DERObject getDERObject()
|
||||
{
|
||||
return outer;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
Enumeration e = this.getObjects();
|
||||
int hashCode = size();
|
||||
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
Object o = e.nextElement();
|
||||
hashCode *= 17;
|
||||
if (o != null)
|
||||
{
|
||||
hashCode ^= o.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof ASN1Set))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ASN1Set other = (ASN1Set)o;
|
||||
|
||||
if (this.size() != other.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Enumeration s1 = this.getObjects();
|
||||
Enumeration s2 = other.getObjects();
|
||||
|
||||
while (s1.hasMoreElements())
|
||||
{
|
||||
DERObject o1 = ((DEREncodable)s1.nextElement()).getDERObject();
|
||||
DERObject o2 = ((DEREncodable)s2.nextElement()).getDERObject();
|
||||
|
||||
if (o1 == o2 || (o1 != null && o1.equals(o2)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* return true if a <= b (arrays are assumed padded with zeros).
|
||||
*/
|
||||
private boolean lessThanOrEqual(
|
||||
byte[] a,
|
||||
byte[] b)
|
||||
{
|
||||
if (a.length <= b.length)
|
||||
{
|
||||
for (int i = 0; i != a.length; i++)
|
||||
{
|
||||
int l = a[i] & 0xff;
|
||||
int r = b[i] & 0xff;
|
||||
|
||||
if (r > l)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (l > r)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i != b.length; i++)
|
||||
{
|
||||
int l = a[i] & 0xff;
|
||||
int r = b[i] & 0xff;
|
||||
|
||||
if (r > l)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (l > r)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] getEncoded(
|
||||
DEREncodable obj)
|
||||
{
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ASN1OutputStream aOut = new ASN1OutputStream(bOut);
|
||||
|
||||
try
|
||||
{
|
||||
aOut.writeObject(obj);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalArgumentException("cannot encode object added to SET");
|
||||
}
|
||||
|
||||
return bOut.toByteArray();
|
||||
}
|
||||
|
||||
protected void sort()
|
||||
{
|
||||
if (set.size() > 1)
|
||||
{
|
||||
boolean swapped = true;
|
||||
int lastSwap = set.size() - 1;
|
||||
|
||||
while (swapped)
|
||||
{
|
||||
int index = 0;
|
||||
int swapIndex = 0;
|
||||
byte[] a = getEncoded((DEREncodable)set.elementAt(0));
|
||||
|
||||
swapped = false;
|
||||
|
||||
while (index != lastSwap)
|
||||
{
|
||||
byte[] b = getEncoded((DEREncodable)set.elementAt(index + 1));
|
||||
|
||||
if (lessThanOrEqual(a, b))
|
||||
{
|
||||
a = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
Object o = set.elementAt(index);
|
||||
|
||||
set.setElementAt(set.elementAt(index + 1), index);
|
||||
set.setElementAt(o, index + 1);
|
||||
|
||||
swapped = true;
|
||||
swapIndex = index;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
lastSwap = swapIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void addObject(
|
||||
DEREncodable obj)
|
||||
{
|
||||
set.addElement(obj);
|
||||
}
|
||||
|
||||
abstract void encode(DEROutputStream out)
|
||||
throws IOException;
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return set.toString();
|
||||
}
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface ASN1SetParser
|
||||
extends DEREncodable
|
||||
{
|
||||
public DEREncodable readObject()
|
||||
throws IOException;
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class ASN1StreamParser
|
||||
{
|
||||
private final InputStream _in;
|
||||
private final int _limit;
|
||||
|
||||
private static int findLimit(InputStream in)
|
||||
{
|
||||
if (in instanceof DefiniteLengthInputStream)
|
||||
{
|
||||
return ((DefiniteLengthInputStream)in).getRemaining();
|
||||
}
|
||||
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public ASN1StreamParser(
|
||||
InputStream in)
|
||||
{
|
||||
this(in, findLimit(in));
|
||||
}
|
||||
|
||||
public ASN1StreamParser(
|
||||
InputStream in,
|
||||
int limit)
|
||||
{
|
||||
this._in = in;
|
||||
this._limit = limit;
|
||||
}
|
||||
|
||||
public ASN1StreamParser(
|
||||
byte[] encoding)
|
||||
{
|
||||
this(new ByteArrayInputStream(encoding), encoding.length);
|
||||
}
|
||||
|
||||
public DEREncodable readObject()
|
||||
throws IOException
|
||||
{
|
||||
int tag = _in.read();
|
||||
if (tag == -1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
// turn of looking for "00" while we resolve the tag
|
||||
//
|
||||
set00Check(false);
|
||||
|
||||
//
|
||||
// calculate tag number
|
||||
//
|
||||
int tagNo = ASN1InputStream.readTagNumber(_in, tag);
|
||||
|
||||
boolean isConstructed = (tag & DERTags.CONSTRUCTED) != 0;
|
||||
|
||||
//
|
||||
// calculate length
|
||||
//
|
||||
int length = ASN1InputStream.readLength(_in, _limit);
|
||||
|
||||
if (length < 0) // indefinite length method
|
||||
{
|
||||
if (!isConstructed)
|
||||
{
|
||||
throw new IOException("indefinite length primitive encoding encountered");
|
||||
}
|
||||
|
||||
IndefiniteLengthInputStream indIn = new IndefiniteLengthInputStream(_in);
|
||||
|
||||
if ((tag & DERTags.APPLICATION) != 0)
|
||||
{
|
||||
ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit);
|
||||
|
||||
return new BERApplicationSpecificParser(tagNo, sp);
|
||||
}
|
||||
|
||||
if ((tag & DERTags.TAGGED) != 0)
|
||||
{
|
||||
return new BERTaggedObjectParser(tag, tagNo, indIn);
|
||||
}
|
||||
|
||||
ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit);
|
||||
|
||||
// TODO There are other tags that may be constructed (e.g. BIT_STRING)
|
||||
switch (tagNo)
|
||||
{
|
||||
case DERTags.OCTET_STRING:
|
||||
return new BEROctetStringParser(sp);
|
||||
case DERTags.SEQUENCE:
|
||||
return new BERSequenceParser(sp);
|
||||
case DERTags.SET:
|
||||
return new BERSetParser(sp);
|
||||
case DERTags.EXTERNAL:{
|
||||
return new DERExternalParser(sp);
|
||||
}
|
||||
default:
|
||||
throw new IOException("unknown BER object encountered: 0x" + Integer.toHexString(tagNo));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length);
|
||||
|
||||
if ((tag & DERTags.APPLICATION) != 0)
|
||||
{
|
||||
return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
|
||||
}
|
||||
|
||||
if ((tag & DERTags.TAGGED) != 0)
|
||||
{
|
||||
return new BERTaggedObjectParser(tag, tagNo, defIn);
|
||||
}
|
||||
|
||||
if (isConstructed)
|
||||
{
|
||||
// TODO There are other tags that may be constructed (e.g. BIT_STRING)
|
||||
switch (tagNo)
|
||||
{
|
||||
case DERTags.OCTET_STRING:
|
||||
//
|
||||
// yes, people actually do this...
|
||||
//
|
||||
return new BEROctetStringParser(new ASN1StreamParser(defIn));
|
||||
case DERTags.SEQUENCE:
|
||||
return new DERSequenceParser(new ASN1StreamParser(defIn));
|
||||
case DERTags.SET:
|
||||
return new DERSetParser(new ASN1StreamParser(defIn));
|
||||
case DERTags.EXTERNAL:
|
||||
return new DERExternalParser(new ASN1StreamParser(defIn));
|
||||
default:
|
||||
// TODO Add DERUnknownTagParser class?
|
||||
return new DERUnknownTag(true, tagNo, defIn.toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
// Some primitive encodings can be handled by parsers too...
|
||||
switch (tagNo)
|
||||
{
|
||||
case DERTags.OCTET_STRING:
|
||||
return new DEROctetStringParser(defIn);
|
||||
}
|
||||
|
||||
return ASN1InputStream.createPrimitiveDERObject(tagNo, defIn.toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
private void set00Check(boolean enabled)
|
||||
{
|
||||
if (_in instanceof IndefiniteLengthInputStream)
|
||||
{
|
||||
((IndefiniteLengthInputStream)_in).setEofOn00(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
ASN1EncodableVector readVector() throws IOException
|
||||
{
|
||||
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||
|
||||
DEREncodable obj;
|
||||
while ((obj = readObject()) != null)
|
||||
{
|
||||
v.add(obj.getDERObject());
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
@ -1,210 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by
|
||||
* a [n] where n is some number - these are assumed to follow the construction
|
||||
* rules (as with sequences).
|
||||
*/
|
||||
public abstract class ASN1TaggedObject
|
||||
extends ASN1Object
|
||||
implements ASN1TaggedObjectParser
|
||||
{
|
||||
int tagNo;
|
||||
boolean empty = false;
|
||||
boolean explicit = true;
|
||||
DEREncodable obj = null;
|
||||
|
||||
static public ASN1TaggedObject getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
if (explicit)
|
||||
{
|
||||
return (ASN1TaggedObject)obj.getObject();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("implicitly tagged tagged object");
|
||||
}
|
||||
|
||||
static public ASN1TaggedObject getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return (ASN1TaggedObject)obj;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a tagged object in the explicit style.
|
||||
*
|
||||
* @param tagNo the tag number for this object.
|
||||
* @param obj the tagged object.
|
||||
*/
|
||||
public ASN1TaggedObject(
|
||||
int tagNo,
|
||||
DEREncodable obj)
|
||||
{
|
||||
this.explicit = true;
|
||||
this.tagNo = tagNo;
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a tagged object with the style given by the value of explicit.
|
||||
* <p>
|
||||
* If the object implements ASN1Choice the tag style will always be changed
|
||||
* to explicit in accordance with the ASN.1 encoding rules.
|
||||
* </p>
|
||||
* @param explicit true if the object is explicitly tagged.
|
||||
* @param tagNo the tag number for this object.
|
||||
* @param obj the tagged object.
|
||||
*/
|
||||
public ASN1TaggedObject(
|
||||
boolean explicit,
|
||||
int tagNo,
|
||||
DEREncodable obj)
|
||||
{
|
||||
if (obj instanceof ASN1Choice)
|
||||
{
|
||||
this.explicit = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.explicit = explicit;
|
||||
}
|
||||
|
||||
this.tagNo = tagNo;
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof ASN1TaggedObject))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ASN1TaggedObject other = (ASN1TaggedObject)o;
|
||||
|
||||
if (tagNo != other.tagNo || empty != other.empty || explicit != other.explicit)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(obj == null)
|
||||
{
|
||||
if (other.obj != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(obj.getDERObject().equals(other.obj.getDERObject())))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
int code = tagNo;
|
||||
|
||||
// TODO: actually this is wrong - the problem is that a re-encoded
|
||||
// object may end up with a different hashCode due to implicit
|
||||
// tagging. As implicit tagging is ambiguous if a sequence is involved
|
||||
// it seems the only correct method for both equals and hashCode is to
|
||||
// compare the encodings...
|
||||
if (obj != null)
|
||||
{
|
||||
code ^= obj.hashCode();
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
public int getTagNo()
|
||||
{
|
||||
return tagNo;
|
||||
}
|
||||
|
||||
/**
|
||||
* return whether or not the object may be explicitly tagged.
|
||||
* <p>
|
||||
* Note: if the object has been read from an input stream, the only
|
||||
* time you can be sure if isExplicit is returning the true state of
|
||||
* affairs is if it returns false. An implicitly tagged object may appear
|
||||
* to be explicitly tagged, so you need to understand the context under
|
||||
* which the reading was done as well, see getObject below.
|
||||
*/
|
||||
public boolean isExplicit()
|
||||
{
|
||||
return explicit;
|
||||
}
|
||||
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return empty;
|
||||
}
|
||||
|
||||
/**
|
||||
* return whatever was following the tag.
|
||||
* <p>
|
||||
* Note: tagged objects are generally context dependent if you're
|
||||
* trying to extract a tagged object you should be going via the
|
||||
* appropriate getInstance method.
|
||||
*/
|
||||
public DERObject getObject()
|
||||
{
|
||||
if (obj != null)
|
||||
{
|
||||
return obj.getDERObject();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the object held in this tagged object as a parser assuming it has
|
||||
* the type of the passed in tag. If the object doesn't have a parser
|
||||
* associated with it, the base object is returned.
|
||||
*/
|
||||
public DEREncodable getObjectParser(
|
||||
int tag,
|
||||
boolean isExplicit)
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
case DERTags.SET:
|
||||
return ASN1Set.getInstance(this, isExplicit).parser();
|
||||
case DERTags.SEQUENCE:
|
||||
return ASN1Sequence.getInstance(this, isExplicit).parser();
|
||||
case DERTags.OCTET_STRING:
|
||||
return ASN1OctetString.getInstance(this, isExplicit).parser();
|
||||
}
|
||||
|
||||
if (isExplicit)
|
||||
{
|
||||
return getObject();
|
||||
}
|
||||
|
||||
throw new RuntimeException("implicit tagging not implemented for tag: " + tag);
|
||||
}
|
||||
|
||||
abstract void encode(DEROutputStream out)
|
||||
throws IOException;
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return "[" + tagNo + "]" + obj;
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface ASN1TaggedObjectParser
|
||||
extends DEREncodable
|
||||
{
|
||||
public int getTagNo();
|
||||
|
||||
public DEREncodable getObjectParser(int tag, boolean isExplicit)
|
||||
throws IOException;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
public class BERApplicationSpecific
|
||||
extends DERApplicationSpecific
|
||||
{
|
||||
public BERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
|
||||
{
|
||||
super(tagNo, vec);
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class BERApplicationSpecificParser
|
||||
implements ASN1ApplicationSpecificParser
|
||||
{
|
||||
private final int tag;
|
||||
private final ASN1StreamParser parser;
|
||||
|
||||
BERApplicationSpecificParser(int tag, ASN1StreamParser parser)
|
||||
{
|
||||
this.tag = tag;
|
||||
this.parser = parser;
|
||||
}
|
||||
|
||||
public DEREncodable readObject()
|
||||
throws IOException
|
||||
{
|
||||
return parser.readObject();
|
||||
}
|
||||
|
||||
public DERObject getDERObject()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new BERApplicationSpecific(tag, parser.readVector());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ASN1ParsingException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Vector;
|
||||
|
||||
public class BERConstructedOctetString
|
||||
extends DEROctetString
|
||||
{
|
||||
private static final int MAX_LENGTH = 1000;
|
||||
|
||||
/**
|
||||
* convert a vector of octet strings into a single byte string
|
||||
*/
|
||||
static private byte[] toBytes(
|
||||
Vector octs)
|
||||
{
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
|
||||
for (int i = 0; i != octs.size(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
DEROctetString o = (DEROctetString)octs.elementAt(i);
|
||||
|
||||
bOut.write(o.getOctets());
|
||||
}
|
||||
catch (ClassCastException e)
|
||||
{
|
||||
throw new IllegalArgumentException(octs.elementAt(i).getClass().getName() + " found in input should only contain DEROctetString");
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalArgumentException("exception converting octets " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
return bOut.toByteArray();
|
||||
}
|
||||
|
||||
private Vector octs;
|
||||
|
||||
/**
|
||||
* @param string the octets making up the octet string.
|
||||
*/
|
||||
public BERConstructedOctetString(
|
||||
byte[] string)
|
||||
{
|
||||
super(string);
|
||||
}
|
||||
|
||||
public BERConstructedOctetString(
|
||||
Vector octs)
|
||||
{
|
||||
super(toBytes(octs));
|
||||
|
||||
this.octs = octs;
|
||||
}
|
||||
|
||||
public BERConstructedOctetString(
|
||||
DERObject obj)
|
||||
{
|
||||
super(obj);
|
||||
}
|
||||
|
||||
public BERConstructedOctetString(
|
||||
DEREncodable obj)
|
||||
{
|
||||
super(obj.getDERObject());
|
||||
}
|
||||
|
||||
public byte[] getOctets()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the DER octets that make up this string.
|
||||
*/
|
||||
public Enumeration getObjects()
|
||||
{
|
||||
if (octs == null)
|
||||
{
|
||||
return generateOcts().elements();
|
||||
}
|
||||
|
||||
return octs.elements();
|
||||
}
|
||||
|
||||
private Vector generateOcts()
|
||||
{
|
||||
Vector vec = new Vector();
|
||||
for (int i = 0; i < string.length; i += MAX_LENGTH)
|
||||
{
|
||||
int end;
|
||||
|
||||
if (i + MAX_LENGTH > string.length)
|
||||
{
|
||||
end = string.length;
|
||||
}
|
||||
else
|
||||
{
|
||||
end = i + MAX_LENGTH;
|
||||
}
|
||||
|
||||
byte[] nStr = new byte[end - i];
|
||||
|
||||
System.arraycopy(string, i, nStr, 0, nStr.length);
|
||||
|
||||
vec.addElement(new DEROctetString(nStr));
|
||||
}
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
public void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
|
||||
{
|
||||
out.write(CONSTRUCTED | OCTET_STRING);
|
||||
|
||||
out.write(0x80);
|
||||
|
||||
//
|
||||
// write out the octet array
|
||||
//
|
||||
Enumeration e = getObjects();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
out.writeObject(e.nextElement());
|
||||
}
|
||||
|
||||
out.write(0x00);
|
||||
out.write(0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.encode(out);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* @deprecated use BERSequence
|
||||
*/
|
||||
public class BERConstructedSequence
|
||||
extends DERConstructedSequence
|
||||
{
|
||||
/*
|
||||
*/
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
|
||||
{
|
||||
out.write(SEQUENCE | CONSTRUCTED);
|
||||
out.write(0x80);
|
||||
|
||||
Enumeration e = getObjects();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
out.writeObject(e.nextElement());
|
||||
}
|
||||
|
||||
out.write(0x00);
|
||||
out.write(0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.encode(out);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
class BERFactory
|
||||
{
|
||||
static final BERSequence EMPTY_SEQUENCE = new BERSequence();
|
||||
static final BERSet EMPTY_SET = new BERSet();
|
||||
|
||||
static BERSequence createSequence(ASN1EncodableVector v)
|
||||
{
|
||||
return v.size() < 1 ? EMPTY_SEQUENCE : new BERSequence(v);
|
||||
}
|
||||
|
||||
static BERSet createSet(ASN1EncodableVector v)
|
||||
{
|
||||
return v.size() < 1 ? EMPTY_SET : new BERSet(v);
|
||||
}
|
||||
|
||||
static BERSet createSet(ASN1EncodableVector v, boolean needsSorting)
|
||||
{
|
||||
return v.size() < 1 ? EMPTY_SET : new BERSet(v, needsSorting);
|
||||
}
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class BERGenerator
|
||||
extends ASN1Generator
|
||||
{
|
||||
private boolean _tagged = false;
|
||||
private boolean _isExplicit;
|
||||
private int _tagNo;
|
||||
|
||||
protected BERGenerator(
|
||||
OutputStream out)
|
||||
{
|
||||
super(out);
|
||||
}
|
||||
|
||||
public BERGenerator(
|
||||
OutputStream out,
|
||||
int tagNo,
|
||||
boolean isExplicit)
|
||||
{
|
||||
super(out);
|
||||
|
||||
_tagged = true;
|
||||
_isExplicit = isExplicit;
|
||||
_tagNo = tagNo;
|
||||
}
|
||||
|
||||
public OutputStream getRawOutputStream()
|
||||
{
|
||||
return _out;
|
||||
}
|
||||
|
||||
private void writeHdr(
|
||||
int tag)
|
||||
throws IOException
|
||||
{
|
||||
_out.write(tag);
|
||||
_out.write(0x80);
|
||||
}
|
||||
|
||||
protected void writeBERHeader(
|
||||
int tag)
|
||||
throws IOException
|
||||
{
|
||||
if (_tagged)
|
||||
{
|
||||
int tagNum = _tagNo | DERTags.TAGGED;
|
||||
|
||||
if (_isExplicit)
|
||||
{
|
||||
writeHdr(tagNum | DERTags.CONSTRUCTED);
|
||||
writeHdr(tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((tag & DERTags.CONSTRUCTED) != 0)
|
||||
{
|
||||
writeHdr(tagNum | DERTags.CONSTRUCTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeHdr(tagNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeHdr(tag);
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeBERBody(
|
||||
InputStream contentStream)
|
||||
throws IOException
|
||||
{
|
||||
int ch;
|
||||
|
||||
while ((ch = contentStream.read()) >= 0)
|
||||
{
|
||||
_out.write(ch);
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeBEREnd()
|
||||
throws IOException
|
||||
{
|
||||
_out.write(0x00);
|
||||
_out.write(0x00);
|
||||
|
||||
if (_tagged && _isExplicit) // write extra end for tag header
|
||||
{
|
||||
_out.write(0x00);
|
||||
_out.write(0x00);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,209 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* @deprecated use ASN1InputStream
|
||||
*/
|
||||
public class BERInputStream
|
||||
extends DERInputStream
|
||||
{
|
||||
private static final DERObject END_OF_STREAM = new DERObject()
|
||||
{
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
throw new IOException("Eeek!");
|
||||
}
|
||||
public int hashCode()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
public boolean equals(
|
||||
Object o)
|
||||
{
|
||||
return o == this;
|
||||
}
|
||||
};
|
||||
public BERInputStream(
|
||||
InputStream is)
|
||||
{
|
||||
super(is);
|
||||
}
|
||||
|
||||
/**
|
||||
* read a string of bytes representing an indefinite length object.
|
||||
*/
|
||||
private byte[] readIndefiniteLengthFully()
|
||||
throws IOException
|
||||
{
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
int b, b1;
|
||||
|
||||
b1 = read();
|
||||
|
||||
while ((b = read()) >= 0)
|
||||
{
|
||||
if (b1 == 0 && b == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
bOut.write(b1);
|
||||
b1 = b;
|
||||
}
|
||||
|
||||
return bOut.toByteArray();
|
||||
}
|
||||
|
||||
private BERConstructedOctetString buildConstructedOctetString()
|
||||
throws IOException
|
||||
{
|
||||
Vector octs = new Vector();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
DERObject o = readObject();
|
||||
|
||||
if (o == END_OF_STREAM)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
octs.addElement(o);
|
||||
}
|
||||
|
||||
return new BERConstructedOctetString(octs);
|
||||
}
|
||||
|
||||
public DERObject readObject()
|
||||
throws IOException
|
||||
{
|
||||
int tag = read();
|
||||
if (tag == -1)
|
||||
{
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
int length = readLength();
|
||||
|
||||
if (length < 0) // indefinite length method
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
case NULL:
|
||||
return null;
|
||||
case SEQUENCE | CONSTRUCTED:
|
||||
BERConstructedSequence seq = new BERConstructedSequence();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
DERObject obj = readObject();
|
||||
|
||||
if (obj == END_OF_STREAM)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
seq.addObject(obj);
|
||||
}
|
||||
return seq;
|
||||
case OCTET_STRING | CONSTRUCTED:
|
||||
return buildConstructedOctetString();
|
||||
case SET | CONSTRUCTED:
|
||||
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
DERObject obj = readObject();
|
||||
|
||||
if (obj == END_OF_STREAM)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
v.add(obj);
|
||||
}
|
||||
return new BERSet(v);
|
||||
default:
|
||||
//
|
||||
// with tagged object tag number is bottom 5 bits
|
||||
//
|
||||
if ((tag & TAGGED) != 0)
|
||||
{
|
||||
if ((tag & 0x1f) == 0x1f)
|
||||
{
|
||||
throw new IOException("unsupported high tag encountered");
|
||||
}
|
||||
|
||||
//
|
||||
// simple type - implicit... return an octet string
|
||||
//
|
||||
if ((tag & CONSTRUCTED) == 0)
|
||||
{
|
||||
byte[] bytes = readIndefiniteLengthFully();
|
||||
|
||||
return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes));
|
||||
}
|
||||
|
||||
//
|
||||
// either constructed or explicitly tagged
|
||||
//
|
||||
DERObject dObj = readObject();
|
||||
|
||||
if (dObj == END_OF_STREAM) // empty tag!
|
||||
{
|
||||
return new DERTaggedObject(tag & 0x1f);
|
||||
}
|
||||
|
||||
DERObject next = readObject();
|
||||
|
||||
//
|
||||
// explicitly tagged (probably!) - if it isn't we'd have to
|
||||
// tell from the context
|
||||
//
|
||||
if (next == END_OF_STREAM)
|
||||
{
|
||||
return new BERTaggedObject(tag & 0x1f, dObj);
|
||||
}
|
||||
|
||||
//
|
||||
// another implicit object, we'll create a sequence...
|
||||
//
|
||||
seq = new BERConstructedSequence();
|
||||
|
||||
seq.addObject(dObj);
|
||||
|
||||
do
|
||||
{
|
||||
seq.addObject(next);
|
||||
next = readObject();
|
||||
}
|
||||
while (next != END_OF_STREAM);
|
||||
|
||||
return new BERTaggedObject(false, tag & 0x1f, seq);
|
||||
}
|
||||
|
||||
throw new IOException("unknown BER object encountered");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tag == 0 && length == 0) // end of contents marker.
|
||||
{
|
||||
return END_OF_STREAM;
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[length];
|
||||
|
||||
readFully(bytes);
|
||||
|
||||
return buildObject(tag, bytes);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A BER NULL object.
|
||||
*/
|
||||
public class BERNull
|
||||
extends DERNull
|
||||
{
|
||||
public static final BERNull INSTANCE = new BERNull();
|
||||
|
||||
public BERNull()
|
||||
{
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
|
||||
{
|
||||
out.write(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.encode(out);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class BEROctetStringGenerator
|
||||
extends BERGenerator
|
||||
{
|
||||
public BEROctetStringGenerator(OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
super(out);
|
||||
|
||||
writeBERHeader(DERTags.CONSTRUCTED | DERTags.OCTET_STRING);
|
||||
}
|
||||
|
||||
public BEROctetStringGenerator(
|
||||
OutputStream out,
|
||||
int tagNo,
|
||||
boolean isExplicit)
|
||||
throws IOException
|
||||
{
|
||||
super(out, tagNo, isExplicit);
|
||||
|
||||
writeBERHeader(DERTags.CONSTRUCTED | DERTags.OCTET_STRING);
|
||||
}
|
||||
|
||||
public OutputStream getOctetOutputStream()
|
||||
{
|
||||
return getOctetOutputStream(new byte[1000]); // limit for CER encoding.
|
||||
}
|
||||
|
||||
public OutputStream getOctetOutputStream(
|
||||
byte[] buf)
|
||||
{
|
||||
return new BufferedBEROctetStream(buf);
|
||||
}
|
||||
|
||||
private class BufferedBEROctetStream
|
||||
extends OutputStream
|
||||
{
|
||||
private byte[] _buf;
|
||||
private int _off;
|
||||
private DEROutputStream _derOut;
|
||||
|
||||
BufferedBEROctetStream(
|
||||
byte[] buf)
|
||||
{
|
||||
_buf = buf;
|
||||
_off = 0;
|
||||
_derOut = new DEROutputStream(_out);
|
||||
}
|
||||
|
||||
public void write(
|
||||
int b)
|
||||
throws IOException
|
||||
{
|
||||
_buf[_off++] = (byte)b;
|
||||
|
||||
if (_off == _buf.length)
|
||||
{
|
||||
DEROctetString.encode(_derOut, _buf);
|
||||
_off = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException
|
||||
{
|
||||
while (len > 0)
|
||||
{
|
||||
int numToCopy = Math.min(len, _buf.length - _off);
|
||||
System.arraycopy(b, off, _buf, _off, numToCopy);
|
||||
|
||||
_off += numToCopy;
|
||||
if (_off < _buf.length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
DEROctetString.encode(_derOut, _buf);
|
||||
_off = 0;
|
||||
|
||||
off += numToCopy;
|
||||
len -= numToCopy;
|
||||
}
|
||||
}
|
||||
|
||||
public void close()
|
||||
throws IOException
|
||||
{
|
||||
if (_off != 0)
|
||||
{
|
||||
byte[] bytes = new byte[_off];
|
||||
System.arraycopy(_buf, 0, bytes, 0, _off);
|
||||
|
||||
DEROctetString.encode(_derOut, bytes);
|
||||
}
|
||||
|
||||
writeBEREnd();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.util.io.Streams;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class BEROctetStringParser
|
||||
implements ASN1OctetStringParser
|
||||
{
|
||||
private ASN1StreamParser _parser;
|
||||
|
||||
BEROctetStringParser(
|
||||
ASN1StreamParser parser)
|
||||
{
|
||||
_parser = parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated will be removed
|
||||
*/
|
||||
protected BEROctetStringParser(
|
||||
ASN1ObjectParser parser)
|
||||
{
|
||||
_parser = parser._aIn;
|
||||
}
|
||||
|
||||
public InputStream getOctetStream()
|
||||
{
|
||||
return new ConstructedOctetStream(_parser);
|
||||
}
|
||||
|
||||
public DERObject getDERObject()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new BERConstructedOctetString(Streams.readAll(getOctetStream()));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class BEROutputStream
|
||||
extends DEROutputStream
|
||||
{
|
||||
public BEROutputStream(
|
||||
OutputStream os)
|
||||
{
|
||||
super(os);
|
||||
}
|
||||
|
||||
public void writeObject(
|
||||
Object obj)
|
||||
throws IOException
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
writeNull();
|
||||
}
|
||||
else if (obj instanceof DERObject)
|
||||
{
|
||||
((DERObject)obj).encode(this);
|
||||
}
|
||||
else if (obj instanceof DEREncodable)
|
||||
{
|
||||
((DEREncodable)obj).getDERObject().encode(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("object not BEREncodable");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
public class BERSequence
|
||||
extends DERSequence
|
||||
{
|
||||
/**
|
||||
* create an empty sequence
|
||||
*/
|
||||
public BERSequence()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* create a sequence containing one object
|
||||
*/
|
||||
public BERSequence(
|
||||
DEREncodable obj)
|
||||
{
|
||||
super(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a sequence containing a vector of objects.
|
||||
*/
|
||||
public BERSequence(
|
||||
DEREncodableVector v)
|
||||
{
|
||||
super(v);
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
|
||||
{
|
||||
out.write(SEQUENCE | CONSTRUCTED);
|
||||
out.write(0x80);
|
||||
|
||||
Enumeration e = getObjects();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
out.writeObject(e.nextElement());
|
||||
}
|
||||
|
||||
out.write(0x00);
|
||||
out.write(0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.encode(out);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class BERSequenceGenerator
|
||||
extends BERGenerator
|
||||
{
|
||||
public BERSequenceGenerator(
|
||||
OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
super(out);
|
||||
|
||||
writeBERHeader(DERTags.CONSTRUCTED | DERTags.SEQUENCE);
|
||||
}
|
||||
|
||||
public BERSequenceGenerator(
|
||||
OutputStream out,
|
||||
int tagNo,
|
||||
boolean isExplicit)
|
||||
throws IOException
|
||||
{
|
||||
super(out, tagNo, isExplicit);
|
||||
|
||||
writeBERHeader(DERTags.CONSTRUCTED | DERTags.SEQUENCE);
|
||||
}
|
||||
|
||||
public void addObject(
|
||||
DEREncodable object)
|
||||
throws IOException
|
||||
{
|
||||
object.getDERObject().encode(new BEROutputStream(_out));
|
||||
}
|
||||
|
||||
public void close()
|
||||
throws IOException
|
||||
{
|
||||
writeBEREnd();
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class BERSequenceParser
|
||||
implements ASN1SequenceParser
|
||||
{
|
||||
private ASN1StreamParser _parser;
|
||||
|
||||
BERSequenceParser(ASN1StreamParser parser)
|
||||
{
|
||||
this._parser = parser;
|
||||
}
|
||||
|
||||
public DEREncodable readObject()
|
||||
throws IOException
|
||||
{
|
||||
return _parser.readObject();
|
||||
}
|
||||
|
||||
public DERObject getDERObject()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new BERSequence(_parser.readVector());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalStateException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
public class BERSet
|
||||
extends DERSet
|
||||
{
|
||||
/**
|
||||
* create an empty sequence
|
||||
*/
|
||||
public BERSet()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* create a set containing one object
|
||||
*/
|
||||
public BERSet(
|
||||
DEREncodable obj)
|
||||
{
|
||||
super(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param v - a vector of objects making up the set.
|
||||
*/
|
||||
public BERSet(
|
||||
DEREncodableVector v)
|
||||
{
|
||||
super(v, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param v - a vector of objects making up the set.
|
||||
*/
|
||||
BERSet(
|
||||
DEREncodableVector v,
|
||||
boolean needsSorting)
|
||||
{
|
||||
super(v, needsSorting);
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
|
||||
{
|
||||
out.write(SET | CONSTRUCTED);
|
||||
out.write(0x80);
|
||||
|
||||
Enumeration e = getObjects();
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
out.writeObject(e.nextElement());
|
||||
}
|
||||
|
||||
out.write(0x00);
|
||||
out.write(0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.encode(out);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class BERSetParser
|
||||
implements ASN1SetParser
|
||||
{
|
||||
private ASN1StreamParser _parser;
|
||||
|
||||
BERSetParser(ASN1StreamParser parser)
|
||||
{
|
||||
this._parser = parser;
|
||||
}
|
||||
|
||||
public DEREncodable readObject()
|
||||
throws IOException
|
||||
{
|
||||
return _parser.readObject();
|
||||
}
|
||||
|
||||
public DERObject getDERObject()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new BERSet(_parser.readVector(), false);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ASN1ParsingException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* BER TaggedObject - in ASN.1 notation this is any object preceded by
|
||||
* a [n] where n is some number - these are assumed to follow the construction
|
||||
* rules (as with sequences).
|
||||
*/
|
||||
public class BERTaggedObject
|
||||
extends DERTaggedObject
|
||||
{
|
||||
/**
|
||||
* @param tagNo the tag number for this object.
|
||||
* @param obj the tagged object.
|
||||
*/
|
||||
public BERTaggedObject(
|
||||
int tagNo,
|
||||
DEREncodable obj)
|
||||
{
|
||||
super(tagNo, obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param explicit true if an explicitly tagged object.
|
||||
* @param tagNo the tag number for this object.
|
||||
* @param obj the tagged object.
|
||||
*/
|
||||
public BERTaggedObject(
|
||||
boolean explicit,
|
||||
int tagNo,
|
||||
DEREncodable obj)
|
||||
{
|
||||
super(explicit, tagNo, obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* create an implicitly tagged object that contains a zero
|
||||
* length sequence.
|
||||
*/
|
||||
public BERTaggedObject(
|
||||
int tagNo)
|
||||
{
|
||||
super(false, tagNo, new BERSequence());
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
|
||||
{
|
||||
out.writeTag(CONSTRUCTED | TAGGED, tagNo);
|
||||
out.write(0x80);
|
||||
|
||||
if (!empty)
|
||||
{
|
||||
if (!explicit)
|
||||
{
|
||||
Enumeration e;
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
if (obj instanceof BERConstructedOctetString)
|
||||
{
|
||||
e = ((BERConstructedOctetString)obj).getObjects();
|
||||
}
|
||||
else
|
||||
{
|
||||
ASN1OctetString octs = (ASN1OctetString)obj;
|
||||
BERConstructedOctetString berO = new BERConstructedOctetString(octs.getOctets());
|
||||
e = berO.getObjects();
|
||||
}
|
||||
}
|
||||
else if (obj instanceof ASN1Sequence)
|
||||
{
|
||||
e = ((ASN1Sequence)obj).getObjects();
|
||||
}
|
||||
else if (obj instanceof ASN1Set)
|
||||
{
|
||||
e = ((ASN1Set)obj).getObjects();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException("not implemented: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
out.writeObject(e.nextElement());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out.writeObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
out.write(0x00);
|
||||
out.write(0x00);
|
||||
}
|
||||
else
|
||||
{
|
||||
super.encode(out);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class BERTaggedObjectParser
|
||||
implements ASN1TaggedObjectParser
|
||||
{
|
||||
private int _baseTag;
|
||||
private int _tagNumber;
|
||||
private InputStream _contentStream;
|
||||
|
||||
private boolean _indefiniteLength;
|
||||
|
||||
protected BERTaggedObjectParser(
|
||||
int baseTag,
|
||||
int tagNumber,
|
||||
InputStream contentStream)
|
||||
{
|
||||
_baseTag = baseTag;
|
||||
_tagNumber = tagNumber;
|
||||
_contentStream = contentStream;
|
||||
_indefiniteLength = contentStream instanceof IndefiniteLengthInputStream;
|
||||
}
|
||||
|
||||
public boolean isConstructed()
|
||||
{
|
||||
return (_baseTag & DERTags.CONSTRUCTED) != 0;
|
||||
}
|
||||
|
||||
public int getTagNo()
|
||||
{
|
||||
return _tagNumber;
|
||||
}
|
||||
|
||||
public DEREncodable getObjectParser(
|
||||
int tag,
|
||||
boolean isExplicit)
|
||||
throws IOException
|
||||
{
|
||||
if (isExplicit)
|
||||
{
|
||||
return new ASN1StreamParser(_contentStream).readObject();
|
||||
}
|
||||
|
||||
switch (tag)
|
||||
{
|
||||
case DERTags.SET:
|
||||
if (_indefiniteLength)
|
||||
{
|
||||
return new BERSetParser(new ASN1StreamParser(_contentStream));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DERSetParser(new ASN1StreamParser(_contentStream));
|
||||
}
|
||||
case DERTags.SEQUENCE:
|
||||
if (_indefiniteLength)
|
||||
{
|
||||
return new BERSequenceParser(new ASN1StreamParser(_contentStream));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DERSequenceParser(new ASN1StreamParser(_contentStream));
|
||||
}
|
||||
case DERTags.OCTET_STRING:
|
||||
// TODO Is the handling of definite length constructed encodings correct?
|
||||
if (_indefiniteLength || this.isConstructed())
|
||||
{
|
||||
return new BEROctetStringParser(new ASN1StreamParser(_contentStream));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DEROctetStringParser((DefiniteLengthInputStream)_contentStream);
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("implicit tagging not implemented");
|
||||
}
|
||||
|
||||
private ASN1EncodableVector rLoadVector(InputStream in)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new ASN1StreamParser(in).readVector();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ASN1ParsingException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public DERObject getDERObject()
|
||||
{
|
||||
if (_indefiniteLength)
|
||||
{
|
||||
ASN1EncodableVector v = rLoadVector(_contentStream);
|
||||
|
||||
return v.size() == 1
|
||||
? new BERTaggedObject(true, _tagNumber, v.get(0))
|
||||
: new BERTaggedObject(false, _tagNumber, BERFactory.createSequence(v));
|
||||
}
|
||||
|
||||
if (this.isConstructed())
|
||||
{
|
||||
ASN1EncodableVector v = rLoadVector(_contentStream);
|
||||
|
||||
return v.size() == 1
|
||||
? new DERTaggedObject(true, _tagNumber, v.get(0))
|
||||
: new DERTaggedObject(false, _tagNumber, DERFactory.createSequence(v));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_contentStream;
|
||||
return new DERTaggedObject(false, _tagNumber, new DEROctetString(defIn.toByteArray()));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalStateException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
class ConstructedOctetStream
|
||||
extends InputStream
|
||||
{
|
||||
private final ASN1StreamParser _parser;
|
||||
|
||||
private boolean _first = true;
|
||||
private InputStream _currentStream;
|
||||
|
||||
ConstructedOctetStream(
|
||||
ASN1StreamParser parser)
|
||||
{
|
||||
_parser = parser;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len) throws IOException
|
||||
{
|
||||
if (_currentStream == null)
|
||||
{
|
||||
if (!_first)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
|
||||
|
||||
if (s == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
_first = false;
|
||||
_currentStream = s.getOctetStream();
|
||||
}
|
||||
|
||||
int totalRead = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int numRead = _currentStream.read(b, off + totalRead, len - totalRead);
|
||||
|
||||
if (numRead >= 0)
|
||||
{
|
||||
totalRead += numRead;
|
||||
|
||||
if (totalRead == len)
|
||||
{
|
||||
return totalRead;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ASN1OctetStringParser aos = (ASN1OctetStringParser)_parser.readObject();
|
||||
|
||||
if (aos == null)
|
||||
{
|
||||
_currentStream = null;
|
||||
return totalRead < 1 ? -1 : totalRead;
|
||||
}
|
||||
|
||||
_currentStream = aos.getOctetStream();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int read()
|
||||
throws IOException
|
||||
{
|
||||
if (_currentStream == null)
|
||||
{
|
||||
if (!_first)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
|
||||
|
||||
if (s == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
_first = false;
|
||||
_currentStream = s.getOctetStream();
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
int b = _currentStream.read();
|
||||
|
||||
if (b >= 0)
|
||||
{
|
||||
return b;
|
||||
}
|
||||
|
||||
ASN1OctetStringParser s = (ASN1OctetStringParser)_parser.readObject();
|
||||
|
||||
if (s == null)
|
||||
{
|
||||
_currentStream = null;
|
||||
return -1;
|
||||
}
|
||||
|
||||
_currentStream = s.getOctetStream();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,225 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.util.Arrays;
|
||||
|
||||
/**
|
||||
* Base class for an application specific object
|
||||
*/
|
||||
public class DERApplicationSpecific
|
||||
extends ASN1Object
|
||||
{
|
||||
private final boolean isConstructed;
|
||||
private final int tag;
|
||||
private final byte[] octets;
|
||||
|
||||
DERApplicationSpecific(
|
||||
boolean isConstructed,
|
||||
int tag,
|
||||
byte[] octets)
|
||||
{
|
||||
this.isConstructed = isConstructed;
|
||||
this.tag = tag;
|
||||
this.octets = octets;
|
||||
}
|
||||
|
||||
public DERApplicationSpecific(
|
||||
int tag,
|
||||
byte[] octets)
|
||||
{
|
||||
this(false, tag, octets);
|
||||
}
|
||||
|
||||
public DERApplicationSpecific(
|
||||
int tag,
|
||||
DEREncodable object)
|
||||
throws IOException
|
||||
{
|
||||
this(true, tag, object);
|
||||
}
|
||||
|
||||
public DERApplicationSpecific(
|
||||
boolean explicit,
|
||||
int tag,
|
||||
DEREncodable object)
|
||||
throws IOException
|
||||
{
|
||||
byte[] data = object.getDERObject().getDEREncoded();
|
||||
|
||||
this.isConstructed = explicit;
|
||||
this.tag = tag;
|
||||
|
||||
if (explicit)
|
||||
{
|
||||
this.octets = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
int lenBytes = getLengthOfLength(data);
|
||||
byte[] tmp = new byte[data.length - lenBytes];
|
||||
System.arraycopy(data, lenBytes, tmp, 0, tmp.length);
|
||||
this.octets = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
public DERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
|
||||
{
|
||||
this.tag = tagNo;
|
||||
this.isConstructed = true;
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
|
||||
for (int i = 0; i != vec.size(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
bOut.write(((ASN1Encodable)vec.get(i)).getEncoded());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ASN1ParsingException("malformed object: " + e, e);
|
||||
}
|
||||
}
|
||||
this.octets = bOut.toByteArray();
|
||||
}
|
||||
|
||||
private int getLengthOfLength(byte[] data)
|
||||
{
|
||||
int count = 2; // TODO: assumes only a 1 byte tag number
|
||||
|
||||
while((data[count - 1] & 0x80) != 0)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public boolean isConstructed()
|
||||
{
|
||||
return isConstructed;
|
||||
}
|
||||
|
||||
public byte[] getContents()
|
||||
{
|
||||
return octets;
|
||||
}
|
||||
|
||||
public int getApplicationTag()
|
||||
{
|
||||
return tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the enclosed object assuming explicit tagging.
|
||||
*
|
||||
* @return the resulting object
|
||||
* @throws IOException if reconstruction fails.
|
||||
*/
|
||||
public DERObject getObject()
|
||||
throws IOException
|
||||
{
|
||||
return new ASN1InputStream(getContents()).readObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the enclosed object assuming implicit tagging.
|
||||
*
|
||||
* @param derTagNo the type tag that should be applied to the object's contents.
|
||||
* @return the resulting object
|
||||
* @throws IOException if reconstruction fails.
|
||||
*/
|
||||
public DERObject getObject(int derTagNo)
|
||||
throws IOException
|
||||
{
|
||||
if (derTagNo >= 0x1f)
|
||||
{
|
||||
throw new IOException("unsupported tag number");
|
||||
}
|
||||
|
||||
byte[] orig = this.getEncoded();
|
||||
byte[] tmp = replaceTagNumber(derTagNo, orig);
|
||||
|
||||
if ((orig[0] & DERTags.CONSTRUCTED) != 0)
|
||||
{
|
||||
tmp[0] |= DERTags.CONSTRUCTED;
|
||||
}
|
||||
|
||||
return new ASN1InputStream(tmp).readObject();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.bouncycastle.asn1.DERObject#encode(org.bouncycastle.asn1.DEROutputStream)
|
||||
*/
|
||||
void encode(DEROutputStream out) throws IOException
|
||||
{
|
||||
int classBits = DERTags.APPLICATION;
|
||||
if (isConstructed)
|
||||
{
|
||||
classBits |= DERTags.CONSTRUCTED;
|
||||
}
|
||||
|
||||
out.writeEncoded(classBits, tag, octets);
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERApplicationSpecific))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DERApplicationSpecific other = (DERApplicationSpecific)o;
|
||||
|
||||
return isConstructed == other.isConstructed
|
||||
&& tag == other.tag
|
||||
&& Arrays.areEqual(octets, other.octets);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return (isConstructed ? 1 : 0) ^ tag ^ Arrays.hashCode(octets);
|
||||
}
|
||||
|
||||
private byte[] replaceTagNumber(int newTag, byte[] input)
|
||||
throws IOException
|
||||
{
|
||||
int tagNo = input[0] & 0x1f;
|
||||
int index = 1;
|
||||
//
|
||||
// with tagged object tag number is bottom 5 bits, or stored at the start of the content
|
||||
//
|
||||
if (tagNo == 0x1f)
|
||||
{
|
||||
tagNo = 0;
|
||||
|
||||
int b = input[index++] & 0xff;
|
||||
|
||||
// X.690-0207 8.1.2.4.2
|
||||
// "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
|
||||
if ((b & 0x7f) == 0) // Note: -1 will pass
|
||||
{
|
||||
throw new ASN1ParsingException("corrupted stream - invalid high tag number found");
|
||||
}
|
||||
|
||||
while ((b >= 0) && ((b & 0x80) != 0))
|
||||
{
|
||||
tagNo |= (b & 0x7f);
|
||||
tagNo <<= 7;
|
||||
b = input[index++] & 0xff;
|
||||
}
|
||||
|
||||
tagNo |= (b & 0x7f);
|
||||
}
|
||||
|
||||
byte[] tmp = new byte[input.length - index + 1];
|
||||
|
||||
System.arraycopy(input, index, tmp, 1, tmp.length - 1);
|
||||
|
||||
tmp[0] = (byte)newTag;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* DER BMPString object.
|
||||
*/
|
||||
public class DERBMPString
|
||||
extends ASN1Object
|
||||
implements DERString
|
||||
{
|
||||
String string;
|
||||
|
||||
/**
|
||||
* return a BMP String from the given object.
|
||||
*
|
||||
* @param obj the object we want converted.
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DERBMPString getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERBMPString)
|
||||
{
|
||||
return (DERBMPString)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERBMPString(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject)obj).getObject());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return a BMP 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.
|
||||
*/
|
||||
public static DERBMPString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* basic constructor - byte encoded string.
|
||||
*/
|
||||
public DERBMPString(
|
||||
byte[] string)
|
||||
{
|
||||
char[] cs = new char[string.length / 2];
|
||||
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
cs[i] = (char)((string[2 * i] << 8) | (string[2 * i + 1] & 0xff));
|
||||
}
|
||||
|
||||
this.string = new String(cs);
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor
|
||||
*/
|
||||
public DERBMPString(
|
||||
String string)
|
||||
{
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public String getString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return this.getString().hashCode();
|
||||
}
|
||||
|
||||
protected boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERBMPString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DERBMPString s = (DERBMPString)o;
|
||||
|
||||
return this.getString().equals(s.getString());
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
char[] c = string.toCharArray();
|
||||
byte[] b = new byte[c.length * 2];
|
||||
|
||||
for (int i = 0; i != c.length; i++)
|
||||
{
|
||||
b[2 * i] = (byte)(c[i] >> 8);
|
||||
b[2 * i + 1] = (byte)c[i];
|
||||
}
|
||||
|
||||
out.writeEncoded(BMP_STRING, b);
|
||||
}
|
||||
}
|
@ -1,266 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.util.Arrays;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class DERBitString
|
||||
extends ASN1Object
|
||||
implements DERString
|
||||
{
|
||||
private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
|
||||
protected byte[] data;
|
||||
protected int padBits;
|
||||
|
||||
/**
|
||||
* return the correct number of pad bits for a bit string defined in
|
||||
* a 32 bit constant
|
||||
*/
|
||||
static protected int getPadBits(
|
||||
int bitString)
|
||||
{
|
||||
int val = 0;
|
||||
for (int i = 3; i >= 0; i--)
|
||||
{
|
||||
//
|
||||
// this may look a little odd, but if it isn't done like this pre jdk1.2
|
||||
// JVM's break!
|
||||
//
|
||||
if (i != 0)
|
||||
{
|
||||
if ((bitString >> (i * 8)) != 0)
|
||||
{
|
||||
val = (bitString >> (i * 8)) & 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bitString != 0)
|
||||
{
|
||||
val = bitString & 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
return 7;
|
||||
}
|
||||
|
||||
|
||||
int bits = 1;
|
||||
|
||||
while (((val <<= 1) & 0xFF) != 0)
|
||||
{
|
||||
bits++;
|
||||
}
|
||||
|
||||
return 8 - bits;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the correct number of bytes for a bit string defined in
|
||||
* a 32 bit constant
|
||||
*/
|
||||
static protected byte[] getBytes(int bitString)
|
||||
{
|
||||
int bytes = 4;
|
||||
for (int i = 3; i >= 1; i--)
|
||||
{
|
||||
if ((bitString & (0xFF << (i * 8))) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
bytes--;
|
||||
}
|
||||
|
||||
byte[] result = new byte[bytes];
|
||||
for (int i = 0; i < bytes; i++)
|
||||
{
|
||||
result[i] = (byte) ((bitString >> (i * 8)) & 0xFF);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* return a Bit String from the passed in object
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DERBitString getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERBitString)
|
||||
{
|
||||
return (DERBitString)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
byte[] bytes = ((ASN1OctetString)obj).getOctets();
|
||||
int padBits = bytes[0];
|
||||
byte[] data = new byte[bytes.length - 1];
|
||||
|
||||
System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
|
||||
|
||||
return new DERBitString(data, padBits);
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject)obj).getObject());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return a Bit 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.
|
||||
*/
|
||||
public static DERBitString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
protected DERBitString(
|
||||
byte data,
|
||||
int padBits)
|
||||
{
|
||||
this.data = new byte[1];
|
||||
this.data[0] = data;
|
||||
this.padBits = padBits;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data the octets making up the bit string.
|
||||
* @param padBits the number of extra bits at the end of the string.
|
||||
*/
|
||||
public DERBitString(
|
||||
byte[] data,
|
||||
int padBits)
|
||||
{
|
||||
this.data = data;
|
||||
this.padBits = padBits;
|
||||
}
|
||||
|
||||
public DERBitString(
|
||||
byte[] data)
|
||||
{
|
||||
this(data, 0);
|
||||
}
|
||||
|
||||
public DERBitString(
|
||||
DEREncodable obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.data = obj.getDERObject().getEncoded(ASN1Encodable.DER);
|
||||
this.padBits = 0;
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalArgumentException("Error processing object : " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getBytes()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
public int getPadBits()
|
||||
{
|
||||
return padBits;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the value of the bit string as an int (truncating if necessary)
|
||||
*/
|
||||
public int intValue()
|
||||
{
|
||||
int value = 0;
|
||||
|
||||
for (int i = 0; i != data.length && i != 4; i++)
|
||||
{
|
||||
value |= (data[i] & 0xff) << (8 * i);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
byte[] bytes = new byte[getBytes().length + 1];
|
||||
|
||||
bytes[0] = (byte)getPadBits();
|
||||
System.arraycopy(getBytes(), 0, bytes, 1, bytes.length - 1);
|
||||
|
||||
out.writeEncoded(BIT_STRING, bytes);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return padBits ^ Arrays.hashCode(data);
|
||||
}
|
||||
|
||||
protected boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERBitString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DERBitString other = (DERBitString)o;
|
||||
|
||||
return this.padBits == other.padBits
|
||||
&& Arrays.areEqual(this.data, other.data);
|
||||
}
|
||||
|
||||
public String getString()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("#");
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ASN1OutputStream aOut = new ASN1OutputStream(bOut);
|
||||
|
||||
try
|
||||
{
|
||||
aOut.writeObject(this);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException("internal error encoding BitString");
|
||||
}
|
||||
|
||||
byte[] string = bOut.toByteArray();
|
||||
|
||||
for (int i = 0; i != string.length; i++)
|
||||
{
|
||||
buf.append(table[(string[i] >>> 4) & 0xf]);
|
||||
buf.append(table[string[i] & 0xf]);
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getString();
|
||||
}
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DERBoolean
|
||||
extends ASN1Object
|
||||
{
|
||||
byte value;
|
||||
|
||||
public static final DERBoolean FALSE = new DERBoolean(false);
|
||||
public static final DERBoolean TRUE = new DERBoolean(true);
|
||||
|
||||
/**
|
||||
* return a boolean from the passed in object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DERBoolean getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERBoolean)
|
||||
{
|
||||
return (DERBoolean)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERBoolean(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject)obj).getObject());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return a DERBoolean from the passed in boolean.
|
||||
*/
|
||||
public static DERBoolean getInstance(
|
||||
boolean value)
|
||||
{
|
||||
return (value ? 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 DERBoolean getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
public DERBoolean(
|
||||
byte[] value)
|
||||
{
|
||||
this.value = value[0];
|
||||
}
|
||||
|
||||
public DERBoolean(
|
||||
boolean value)
|
||||
{
|
||||
this.value = (value) ? (byte)0xff : (byte)0;
|
||||
}
|
||||
|
||||
public boolean isTrue()
|
||||
{
|
||||
return (value != 0);
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
byte[] bytes = new byte[1];
|
||||
|
||||
bytes[0] = value;
|
||||
|
||||
out.writeEncoded(BOOLEAN, bytes);
|
||||
}
|
||||
|
||||
protected boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if ((o == null) || !(o instanceof DERBoolean))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (value == ((DERBoolean)o).value);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return (value != 0) ? "TRUE" : "FALSE";
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* @deprecated use DERSequence.
|
||||
*/
|
||||
public class DERConstructedSequence
|
||||
extends ASN1Sequence
|
||||
{
|
||||
public void addObject(
|
||||
DEREncodable obj)
|
||||
{
|
||||
super.addObject(obj);
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
/*
|
||||
* A note on the implementation:
|
||||
* <p>
|
||||
* As DER requires the constructed, definite-length model to
|
||||
* be used for structured types, this varies slightly from the
|
||||
* ASN.1 descriptions given. Rather than just outputing SEQUENCE,
|
||||
* we also have to specify CONSTRUCTED, and the objects length.
|
||||
*/
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
DEROutputStream dOut = new DEROutputStream(bOut);
|
||||
Enumeration e = this.getObjects();
|
||||
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
Object obj = e.nextElement();
|
||||
|
||||
dOut.writeObject(obj);
|
||||
}
|
||||
|
||||
dOut.close();
|
||||
|
||||
byte[] bytes = bOut.toByteArray();
|
||||
|
||||
out.writeEncoded(SEQUENCE | CONSTRUCTED, bytes);
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated use DERSet
|
||||
*/
|
||||
public class DERConstructedSet
|
||||
extends ASN1Set
|
||||
{
|
||||
public DERConstructedSet()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param obj - a single object that makes up the set.
|
||||
*/
|
||||
public DERConstructedSet(
|
||||
DEREncodable obj)
|
||||
{
|
||||
this.addObject(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param v - a vector of objects making up the set.
|
||||
*/
|
||||
public DERConstructedSet(
|
||||
DEREncodableVector v)
|
||||
{
|
||||
for (int i = 0; i != v.size(); i++)
|
||||
{
|
||||
this.addObject(v.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
public void addObject(
|
||||
DEREncodable obj)
|
||||
{
|
||||
super.addObject(obj);
|
||||
}
|
||||
|
||||
public int getSize()
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
/*
|
||||
* A note on the implementation:
|
||||
* <p>
|
||||
* As DER requires the constructed, definite-length model to
|
||||
* be used for structured types, this varies slightly from the
|
||||
* ASN.1 descriptions given. Rather than just outputing SET,
|
||||
* we also have to specify CONSTRUCTED, and the objects length.
|
||||
*/
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
DEROutputStream dOut = new DEROutputStream(bOut);
|
||||
Enumeration e = this.getObjects();
|
||||
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
Object obj = e.nextElement();
|
||||
|
||||
dOut.writeObject(obj);
|
||||
}
|
||||
|
||||
dOut.close();
|
||||
|
||||
byte[] bytes = bOut.toByteArray();
|
||||
|
||||
out.writeEncoded(SET | CONSTRUCTED, bytes);
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
public interface DEREncodable
|
||||
{
|
||||
public DERObject getDERObject();
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
/**
|
||||
* a general class for building up a vector of DER encodable objects -
|
||||
* this will eventually be superceded by ASN1EncodableVector so you should
|
||||
* use that class in preference.
|
||||
*/
|
||||
public class DEREncodableVector
|
||||
{
|
||||
Vector v = new Vector();
|
||||
|
||||
/**
|
||||
* @deprecated use ASN1EncodableVector instead.
|
||||
*/
|
||||
public DEREncodableVector()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void add(
|
||||
DEREncodable obj)
|
||||
{
|
||||
v.addElement(obj);
|
||||
}
|
||||
|
||||
public DEREncodable get(
|
||||
int i)
|
||||
{
|
||||
return (DEREncodable)v.elementAt(i);
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return v.size();
|
||||
}
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.util.Arrays;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class DEREnumerated
|
||||
extends ASN1Object
|
||||
{
|
||||
byte[] bytes;
|
||||
|
||||
/**
|
||||
* return an integer from the passed in object
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DEREnumerated getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DEREnumerated)
|
||||
{
|
||||
return (DEREnumerated)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DEREnumerated(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject)obj).getObject());
|
||||
}
|
||||
|
||||
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 DEREnumerated getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
public DEREnumerated(
|
||||
int value)
|
||||
{
|
||||
bytes = BigInteger.valueOf(value).toByteArray();
|
||||
}
|
||||
|
||||
public DEREnumerated(
|
||||
BigInteger value)
|
||||
{
|
||||
bytes = value.toByteArray();
|
||||
}
|
||||
|
||||
public DEREnumerated(
|
||||
byte[] bytes)
|
||||
{
|
||||
this.bytes = bytes;
|
||||
}
|
||||
|
||||
public BigInteger getValue()
|
||||
{
|
||||
return new BigInteger(bytes);
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(ENUMERATED, bytes);
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject 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);
|
||||
}
|
||||
}
|
@ -1,267 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Class representing the DER-type External
|
||||
*/
|
||||
public class DERExternal
|
||||
extends ASN1Object
|
||||
{
|
||||
private DERObjectIdentifier directReference;
|
||||
private DERInteger indirectReference;
|
||||
private ASN1Object dataValueDescriptor;
|
||||
private int encoding;
|
||||
private DERObject externalContent;
|
||||
|
||||
public DERExternal(ASN1EncodableVector vector)
|
||||
{
|
||||
int offset = 0;
|
||||
DERObject enc = vector.get(offset).getDERObject();
|
||||
if (enc instanceof DERObjectIdentifier)
|
||||
{
|
||||
directReference = (DERObjectIdentifier)enc;
|
||||
offset++;
|
||||
enc = vector.get(offset).getDERObject();
|
||||
}
|
||||
if (enc instanceof DERInteger)
|
||||
{
|
||||
indirectReference = (DERInteger) enc;
|
||||
offset++;
|
||||
enc = vector.get(offset).getDERObject();
|
||||
}
|
||||
if (!(enc instanceof DERTaggedObject))
|
||||
{
|
||||
dataValueDescriptor = (ASN1Object) enc;
|
||||
offset++;
|
||||
enc = vector.get(offset).getDERObject();
|
||||
}
|
||||
if (!(enc instanceof DERTaggedObject))
|
||||
{
|
||||
throw new IllegalArgumentException("No tagged object found in vector. Structure doesn't seem to be of type External");
|
||||
}
|
||||
DERTaggedObject obj = (DERTaggedObject)enc;
|
||||
setEncoding(obj.getTagNo());
|
||||
externalContent = obj.getObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of DERExternal
|
||||
* See X.690 for more informations about the meaning of these parameters
|
||||
* @param directReference The direct reference or <code>null</code> if not set.
|
||||
* @param indirectReference The indirect reference or <code>null</code> if not set.
|
||||
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
|
||||
* @param externalData The external data in its encoded form.
|
||||
*/
|
||||
public DERExternal(DERObjectIdentifier directReference, DERInteger indirectReference, ASN1Object dataValueDescriptor, DERTaggedObject externalData)
|
||||
{
|
||||
this(directReference, indirectReference, dataValueDescriptor, externalData.getTagNo(), externalData.getDERObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of DERExternal.
|
||||
* See X.690 for more informations about the meaning of these parameters
|
||||
* @param directReference The direct reference or <code>null</code> if not set.
|
||||
* @param indirectReference The indirect reference or <code>null</code> if not set.
|
||||
* @param dataValueDescriptor The data value descriptor or <code>null</code> if not set.
|
||||
* @param encoding The encoding to be used for the external data
|
||||
* @param externalData The external data
|
||||
*/
|
||||
public DERExternal(DERObjectIdentifier directReference, DERInteger indirectReference, ASN1Object dataValueDescriptor, int encoding, DERObject externalData)
|
||||
{
|
||||
setDirectReference(directReference);
|
||||
setIndirectReference(indirectReference);
|
||||
setDataValueDescriptor(dataValueDescriptor);
|
||||
setEncoding(encoding);
|
||||
setExternalContent(externalData.getDERObject());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode()
|
||||
{
|
||||
int ret = 0;
|
||||
if (directReference != null)
|
||||
{
|
||||
ret = directReference.hashCode();
|
||||
}
|
||||
if (indirectReference != null)
|
||||
{
|
||||
ret ^= indirectReference.hashCode();
|
||||
}
|
||||
if (dataValueDescriptor != null)
|
||||
{
|
||||
ret ^= dataValueDescriptor.hashCode();
|
||||
}
|
||||
ret ^= externalContent.hashCode();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.bouncycastle.asn1.DERObject#encode(org.bouncycastle.asn1.DEROutputStream)
|
||||
*/
|
||||
void encode(DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
if (directReference != null)
|
||||
{
|
||||
baos.write(directReference.getDEREncoded());
|
||||
}
|
||||
if (indirectReference != null)
|
||||
{
|
||||
baos.write(indirectReference.getDEREncoded());
|
||||
}
|
||||
if (dataValueDescriptor != null)
|
||||
{
|
||||
baos.write(dataValueDescriptor.getDEREncoded());
|
||||
}
|
||||
DERTaggedObject obj = new DERTaggedObject(encoding, externalContent);
|
||||
baos.write(obj.getDEREncoded());
|
||||
out.writeEncoded(DERTags.CONSTRUCTED, DERTags.EXTERNAL, baos.toByteArray());
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.bouncycastle.asn1.ASN1Object#asn1Equals(org.bouncycastle.asn1.DERObject)
|
||||
*/
|
||||
boolean asn1Equals(DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERExternal))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this == o)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
DERExternal other = (DERExternal)o;
|
||||
if (directReference != null)
|
||||
{
|
||||
if (other.directReference == null || !other.directReference.equals(directReference))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (indirectReference != null)
|
||||
{
|
||||
if (other.indirectReference == null || !other.indirectReference.equals(indirectReference))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (dataValueDescriptor != null)
|
||||
{
|
||||
if (other.dataValueDescriptor == null || !other.dataValueDescriptor.equals(dataValueDescriptor))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return externalContent.equals(other.externalContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data value descriptor
|
||||
* @return The descriptor
|
||||
*/
|
||||
public ASN1Object getDataValueDescriptor()
|
||||
{
|
||||
return dataValueDescriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the direct reference of the external element
|
||||
* @return The reference
|
||||
*/
|
||||
public DERObjectIdentifier getDirectReference()
|
||||
{
|
||||
return directReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encoding of the content. Valid values are
|
||||
* <ul>
|
||||
* <li><code>0</code> single-ASN1-type</li>
|
||||
* <li><code>1</code> OCTET STRING</li>
|
||||
* <li><code>2</code> BIT STRING</li>
|
||||
* </ul>
|
||||
* @return The encoding
|
||||
*/
|
||||
public int getEncoding()
|
||||
{
|
||||
return encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content of this element
|
||||
* @return The content
|
||||
*/
|
||||
public DERObject getExternalContent()
|
||||
{
|
||||
return externalContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the indirect reference of this element
|
||||
* @return The reference
|
||||
*/
|
||||
public DERInteger getIndirectReference()
|
||||
{
|
||||
return indirectReference;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the data value descriptor
|
||||
* @param dataValueDescriptor The descriptor
|
||||
*/
|
||||
private void setDataValueDescriptor(ASN1Object dataValueDescriptor)
|
||||
{
|
||||
this.dataValueDescriptor = dataValueDescriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the direct reference of the external element
|
||||
* @param directReferemce The reference
|
||||
*/
|
||||
private void setDirectReference(DERObjectIdentifier directReferemce)
|
||||
{
|
||||
this.directReference = directReferemce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the encoding of the content. Valid values are
|
||||
* <ul>
|
||||
* <li><code>0</code> single-ASN1-type</li>
|
||||
* <li><code>1</code> OCTET STRING</li>
|
||||
* <li><code>2</code> BIT STRING</li>
|
||||
* </ul>
|
||||
* @param encoding The encoding
|
||||
*/
|
||||
private void setEncoding(int encoding)
|
||||
{
|
||||
if (encoding < 0 || encoding > 2)
|
||||
{
|
||||
throw new IllegalArgumentException("invalid encoding value: " + encoding);
|
||||
}
|
||||
this.encoding = encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the content of this element
|
||||
* @param externalContent The content
|
||||
*/
|
||||
private void setExternalContent(DERObject externalContent)
|
||||
{
|
||||
this.externalContent = externalContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the indirect reference of this element
|
||||
* @param indirectReference The reference
|
||||
*/
|
||||
private void setIndirectReference(DERInteger indirectReference)
|
||||
{
|
||||
this.indirectReference = indirectReference;
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DERExternalParser
|
||||
implements DEREncodable
|
||||
{
|
||||
private ASN1StreamParser _parser;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public DERExternalParser(ASN1StreamParser parser)
|
||||
{
|
||||
this._parser = parser;
|
||||
}
|
||||
|
||||
public DEREncodable readObject()
|
||||
throws IOException
|
||||
{
|
||||
return _parser.readObject();
|
||||
}
|
||||
|
||||
public DERObject getDERObject()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new DERExternal(_parser.readVector());
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
throw new ASN1ParsingException("unable to get DER object", ioe);
|
||||
}
|
||||
catch (IllegalArgumentException ioe)
|
||||
{
|
||||
throw new ASN1ParsingException("unable to get DER object", ioe);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
class DERFactory
|
||||
{
|
||||
static final DERSequence EMPTY_SEQUENCE = new DERSequence();
|
||||
static final DERSet EMPTY_SET = new DERSet();
|
||||
|
||||
static DERSequence createSequence(ASN1EncodableVector v)
|
||||
{
|
||||
return v.size() < 1 ? EMPTY_SEQUENCE : new DERSequence(v);
|
||||
}
|
||||
|
||||
static DERSet createSet(ASN1EncodableVector v)
|
||||
{
|
||||
return v.size() < 1 ? EMPTY_SET : new DERSet(v);
|
||||
}
|
||||
|
||||
static DERSet createSet(ASN1EncodableVector v, boolean needsSorting)
|
||||
{
|
||||
return v.size() < 1 ? EMPTY_SET : new DERSet(v, needsSorting);
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DERGeneralString
|
||||
extends ASN1Object implements DERString
|
||||
{
|
||||
private String string;
|
||||
|
||||
public static DERGeneralString getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERGeneralString)
|
||||
{
|
||||
return (DERGeneralString) obj;
|
||||
}
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERGeneralString(((ASN1OctetString) obj).getOctets());
|
||||
}
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject) obj).getObject());
|
||||
}
|
||||
throw new IllegalArgumentException("illegal object in getInstance: "
|
||||
+ obj.getClass().getName());
|
||||
}
|
||||
|
||||
public static DERGeneralString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
public DERGeneralString(byte[] string)
|
||||
{
|
||||
char[] cs = new char[string.length];
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
cs[i] = (char)(string[i] & 0xff);
|
||||
}
|
||||
this.string = new String(cs);
|
||||
}
|
||||
|
||||
public DERGeneralString(String string)
|
||||
{
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public String getString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public byte[] getOctets()
|
||||
{
|
||||
char[] cs = string.toCharArray();
|
||||
byte[] bs = new byte[cs.length];
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
bs[i] = (byte) cs[i];
|
||||
}
|
||||
return bs;
|
||||
}
|
||||
|
||||
void encode(DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(GENERAL_STRING, this.getOctets());
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return this.getString().hashCode();
|
||||
}
|
||||
|
||||
boolean asn1Equals(DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERGeneralString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
DERGeneralString s = (DERGeneralString) o;
|
||||
return this.getString().equals(s.getString());
|
||||
}
|
||||
}
|
@ -1,314 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.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;
|
||||
|
||||
/**
|
||||
* Generalized time object.
|
||||
*/
|
||||
public class DERGeneralizedTime
|
||||
extends ASN1Object
|
||||
{
|
||||
String time;
|
||||
|
||||
/**
|
||||
* return a generalized time from the passed in object
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DERGeneralizedTime getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERGeneralizedTime)
|
||||
{
|
||||
return (DERGeneralizedTime)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERGeneralizedTime(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return a Generalized Time object from a tagged object.
|
||||
*
|
||||
* @param obj the tagged object holding the object we want
|
||||
* @param explicit true if the object is meant to be explicitly
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
*/
|
||||
public static DERGeneralizedTime getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = time;
|
||||
try
|
||||
{
|
||||
this.getDate();
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
throw new IllegalArgumentException("invalid date string: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* base constructer from a java.util.date object
|
||||
*/
|
||||
public DERGeneralizedTime(
|
||||
Date time)
|
||||
{
|
||||
SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
|
||||
|
||||
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
|
||||
|
||||
this.time = dateF.format(time);
|
||||
}
|
||||
|
||||
DERGeneralizedTime(
|
||||
byte[] bytes)
|
||||
{
|
||||
//
|
||||
// explicitly convert to characters
|
||||
//
|
||||
char[] dateC = new char[bytes.length];
|
||||
|
||||
for (int i = 0; i != dateC.length; i++)
|
||||
{
|
||||
dateC[i] = (char)(bytes[i] & 0xff);
|
||||
}
|
||||
|
||||
this.time = new String(dateC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time.
|
||||
* @return The time string as it appeared in the encoded object.
|
||||
*/
|
||||
public String getTimeString()
|
||||
{
|
||||
return 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()
|
||||
{
|
||||
//
|
||||
// standardise the format.
|
||||
//
|
||||
if (time.charAt(time.length() - 1) == 'Z')
|
||||
{
|
||||
return time.substring(0, time.length() - 1) + "GMT+00:00";
|
||||
}
|
||||
else
|
||||
{
|
||||
int signPos = time.length() - 5;
|
||||
char sign = time.charAt(signPos);
|
||||
if (sign == '-' || sign == '+')
|
||||
{
|
||||
return time.substring(0, signPos)
|
||||
+ "GMT"
|
||||
+ time.substring(signPos, signPos + 3)
|
||||
+ ":"
|
||||
+ time.substring(signPos + 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
signPos = time.length() - 3;
|
||||
sign = time.charAt(signPos);
|
||||
if (sign == '-' || sign == '+')
|
||||
{
|
||||
return time.substring(0, signPos)
|
||||
+ "GMT"
|
||||
+ time.substring(signPos)
|
||||
+ ":00";
|
||||
}
|
||||
}
|
||||
}
|
||||
return time + 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 d = time;
|
||||
|
||||
if (time.endsWith("Z"))
|
||||
{
|
||||
if (hasFractionalSeconds())
|
||||
{
|
||||
dateF = new SimpleDateFormat("yyyyMMddHHmmss.SSS'Z'");
|
||||
}
|
||||
else
|
||||
{
|
||||
dateF = new SimpleDateFormat("yyyyMMddHHmmss'Z'");
|
||||
}
|
||||
|
||||
dateF.setTimeZone(new SimpleTimeZone(0, "Z"));
|
||||
}
|
||||
else if (time.indexOf('-') > 0 || time.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;
|
||||
}
|
||||
}
|
||||
|
||||
return dateF.parse(d);
|
||||
}
|
||||
|
||||
private boolean hasFractionalSeconds()
|
||||
{
|
||||
return time.indexOf('.') == 14;
|
||||
}
|
||||
|
||||
private byte[] getOctets()
|
||||
{
|
||||
char[] cs = time.toCharArray();
|
||||
byte[] bs = new byte[cs.length];
|
||||
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
bs[i] = (byte)cs[i];
|
||||
}
|
||||
|
||||
return bs;
|
||||
}
|
||||
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(GENERALIZED_TIME, this.getOctets());
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERGeneralizedTime))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return time.equals(((DERGeneralizedTime)o).time);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return time.hashCode();
|
||||
}
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.util.io.Streams;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public abstract class DERGenerator
|
||||
extends ASN1Generator
|
||||
{
|
||||
private boolean _tagged = false;
|
||||
private boolean _isExplicit;
|
||||
private int _tagNo;
|
||||
|
||||
protected DERGenerator(
|
||||
OutputStream out)
|
||||
{
|
||||
super(out);
|
||||
}
|
||||
|
||||
public DERGenerator(
|
||||
OutputStream out,
|
||||
int tagNo,
|
||||
boolean isExplicit)
|
||||
{
|
||||
super(out);
|
||||
|
||||
_tagged = true;
|
||||
_isExplicit = isExplicit;
|
||||
_tagNo = tagNo;
|
||||
}
|
||||
|
||||
private void writeLength(
|
||||
OutputStream out,
|
||||
int length)
|
||||
throws IOException
|
||||
{
|
||||
if (length > 127)
|
||||
{
|
||||
int size = 1;
|
||||
int val = length;
|
||||
|
||||
while ((val >>>= 8) != 0)
|
||||
{
|
||||
size++;
|
||||
}
|
||||
|
||||
out.write((byte)(size | 0x80));
|
||||
|
||||
for (int i = (size - 1) * 8; i >= 0; i -= 8)
|
||||
{
|
||||
out.write((byte)(length >> i));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out.write((byte)length);
|
||||
}
|
||||
}
|
||||
|
||||
void writeDEREncoded(
|
||||
OutputStream out,
|
||||
int tag,
|
||||
byte[] bytes)
|
||||
throws IOException
|
||||
{
|
||||
out.write(tag);
|
||||
writeLength(out, bytes.length);
|
||||
out.write(bytes);
|
||||
}
|
||||
|
||||
void writeDEREncoded(
|
||||
int tag,
|
||||
byte[] bytes)
|
||||
throws IOException
|
||||
{
|
||||
if (_tagged)
|
||||
{
|
||||
int tagNum = _tagNo | DERTags.TAGGED;
|
||||
|
||||
if (_isExplicit)
|
||||
{
|
||||
int newTag = _tagNo | DERTags.CONSTRUCTED | DERTags.TAGGED;
|
||||
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
|
||||
writeDEREncoded(bOut, tag, bytes);
|
||||
|
||||
writeDEREncoded(_out, newTag, bOut.toByteArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((tag & DERTags.CONSTRUCTED) != 0)
|
||||
{
|
||||
writeDEREncoded(_out, tagNum | DERTags.CONSTRUCTED, bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeDEREncoded(_out, tagNum, bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeDEREncoded(_out, tag, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
void writeDEREncoded(
|
||||
OutputStream out,
|
||||
int tag,
|
||||
InputStream in)
|
||||
throws IOException
|
||||
{
|
||||
writeDEREncoded(out, tag, Streams.readAll(in));
|
||||
}
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* DER IA5String object - this is an ascii string.
|
||||
*/
|
||||
public class DERIA5String
|
||||
extends ASN1Object
|
||||
implements DERString
|
||||
{
|
||||
String string;
|
||||
|
||||
/**
|
||||
* return a IA5 string from the passed in object
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DERIA5String getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERIA5String)
|
||||
{
|
||||
return (DERIA5String)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERIA5String(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject)obj).getObject());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return an IA5 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.
|
||||
*/
|
||||
public static DERIA5String getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor - with bytes.
|
||||
*/
|
||||
public DERIA5String(
|
||||
byte[] string)
|
||||
{
|
||||
char[] cs = new char[string.length];
|
||||
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
cs[i] = (char)(string[i] & 0xff);
|
||||
}
|
||||
|
||||
this.string = new String(cs);
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor - without validation.
|
||||
*/
|
||||
public DERIA5String(
|
||||
String string)
|
||||
{
|
||||
this(string, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with optional validation.
|
||||
*
|
||||
* @param string the base string to wrap.
|
||||
* @param validate whether or not to check the string.
|
||||
* @throws IllegalArgumentException if validate is true and the string
|
||||
* contains characters that should not be in an IA5String.
|
||||
*/
|
||||
public DERIA5String(
|
||||
String string,
|
||||
boolean validate)
|
||||
{
|
||||
if (string == null)
|
||||
{
|
||||
throw new NullPointerException("string cannot be null");
|
||||
}
|
||||
if (validate && !isIA5String(string))
|
||||
{
|
||||
throw new IllegalArgumentException("string contains illegal characters");
|
||||
}
|
||||
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public String getString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public byte[] getOctets()
|
||||
{
|
||||
char[] cs = string.toCharArray();
|
||||
byte[] bs = new byte[cs.length];
|
||||
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
bs[i] = (byte)cs[i];
|
||||
}
|
||||
|
||||
return bs;
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(IA5_STRING, this.getOctets());
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return this.getString().hashCode();
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERIA5String))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DERIA5String s = (DERIA5String)o;
|
||||
|
||||
return this.getString().equals(s.getString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public static boolean isIA5String(
|
||||
String str)
|
||||
{
|
||||
for (int i = str.length() - 1; i >= 0; i--)
|
||||
{
|
||||
char ch = str.charAt(i);
|
||||
|
||||
if (ch > 0x007f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,272 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* Don't use this class. It will eventually disappear, use ASN1InputStream.
|
||||
* <br>
|
||||
* This class is scheduled for removal.
|
||||
* @deprecated use ASN1InputStream
|
||||
*/
|
||||
public class DERInputStream
|
||||
extends FilterInputStream implements DERTags
|
||||
{
|
||||
/**
|
||||
* @deprecated use ASN1InputStream
|
||||
*/
|
||||
public DERInputStream(
|
||||
InputStream is)
|
||||
{
|
||||
super(is);
|
||||
}
|
||||
|
||||
protected int readLength()
|
||||
throws IOException
|
||||
{
|
||||
int length = read();
|
||||
if (length < 0)
|
||||
{
|
||||
throw new IOException("EOF found when length expected");
|
||||
}
|
||||
|
||||
if (length == 0x80)
|
||||
{
|
||||
return -1; // indefinite-length encoding
|
||||
}
|
||||
|
||||
if (length > 127)
|
||||
{
|
||||
int size = length & 0x7f;
|
||||
|
||||
if (size > 4)
|
||||
{
|
||||
throw new IOException("DER length more than 4 bytes");
|
||||
}
|
||||
|
||||
length = 0;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
int next = read();
|
||||
|
||||
if (next < 0)
|
||||
{
|
||||
throw new IOException("EOF found reading length");
|
||||
}
|
||||
|
||||
length = (length << 8) + next;
|
||||
}
|
||||
|
||||
if (length < 0)
|
||||
{
|
||||
throw new IOException("corrupted stream - negative length found");
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
protected void readFully(
|
||||
byte[] bytes)
|
||||
throws IOException
|
||||
{
|
||||
int left = bytes.length;
|
||||
|
||||
if (left == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (left > 0)
|
||||
{
|
||||
int l = read(bytes, bytes.length - left, left);
|
||||
|
||||
if (l < 0)
|
||||
{
|
||||
throw new EOFException("unexpected end of stream");
|
||||
}
|
||||
|
||||
left -= l;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* build an object given its tag and a byte stream to construct it
|
||||
* from.
|
||||
*/
|
||||
protected DERObject buildObject(
|
||||
int tag,
|
||||
byte[] bytes)
|
||||
throws IOException
|
||||
{
|
||||
switch (tag)
|
||||
{
|
||||
case NULL:
|
||||
return null;
|
||||
case SEQUENCE | CONSTRUCTED:
|
||||
ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);
|
||||
BERInputStream dIn = new BERInputStream(bIn);
|
||||
DERConstructedSequence seq = new DERConstructedSequence();
|
||||
|
||||
try
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
DERObject obj = dIn.readObject();
|
||||
|
||||
seq.addObject(obj);
|
||||
}
|
||||
}
|
||||
catch (EOFException ex)
|
||||
{
|
||||
return seq;
|
||||
}
|
||||
case SET | CONSTRUCTED:
|
||||
bIn = new ByteArrayInputStream(bytes);
|
||||
dIn = new BERInputStream(bIn);
|
||||
|
||||
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||
|
||||
try
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
DERObject obj = dIn.readObject();
|
||||
|
||||
v.add(obj);
|
||||
}
|
||||
}
|
||||
catch (EOFException ex)
|
||||
{
|
||||
return new DERConstructedSet(v);
|
||||
}
|
||||
case BOOLEAN:
|
||||
return new DERBoolean(bytes);
|
||||
case INTEGER:
|
||||
return new DERInteger(bytes);
|
||||
case ENUMERATED:
|
||||
return new DEREnumerated(bytes);
|
||||
case OBJECT_IDENTIFIER:
|
||||
return new DERObjectIdentifier(bytes);
|
||||
case BIT_STRING:
|
||||
int padBits = bytes[0];
|
||||
byte[] data = new byte[bytes.length - 1];
|
||||
|
||||
System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
|
||||
|
||||
return new DERBitString(data, padBits);
|
||||
case UTF8_STRING:
|
||||
return new DERUTF8String(bytes);
|
||||
case PRINTABLE_STRING:
|
||||
return new DERPrintableString(bytes);
|
||||
case IA5_STRING:
|
||||
return new DERIA5String(bytes);
|
||||
case T61_STRING:
|
||||
return new DERT61String(bytes);
|
||||
case VISIBLE_STRING:
|
||||
return new DERVisibleString(bytes);
|
||||
case UNIVERSAL_STRING:
|
||||
return new DERUniversalString(bytes);
|
||||
case GENERAL_STRING:
|
||||
return new DERGeneralString(bytes);
|
||||
case BMP_STRING:
|
||||
return new DERBMPString(bytes);
|
||||
case OCTET_STRING:
|
||||
return new DEROctetString(bytes);
|
||||
case UTC_TIME:
|
||||
return new DERUTCTime(bytes);
|
||||
case GENERALIZED_TIME:
|
||||
return new DERGeneralizedTime(bytes);
|
||||
default:
|
||||
//
|
||||
// with tagged object tag number is bottom 5 bits
|
||||
//
|
||||
if ((tag & TAGGED) != 0)
|
||||
{
|
||||
if ((tag & 0x1f) == 0x1f)
|
||||
{
|
||||
throw new IOException("unsupported high tag encountered");
|
||||
}
|
||||
|
||||
if (bytes.length == 0) // empty tag!
|
||||
{
|
||||
if ((tag & CONSTRUCTED) == 0)
|
||||
{
|
||||
return new DERTaggedObject(false, tag & 0x1f, new DERNull());
|
||||
}
|
||||
else
|
||||
{
|
||||
return new DERTaggedObject(false, tag & 0x1f, new DERConstructedSequence());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// simple type - implicit... return an octet string
|
||||
//
|
||||
if ((tag & CONSTRUCTED) == 0)
|
||||
{
|
||||
return new DERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes));
|
||||
}
|
||||
|
||||
bIn = new ByteArrayInputStream(bytes);
|
||||
dIn = new BERInputStream(bIn);
|
||||
|
||||
DEREncodable dObj = dIn.readObject();
|
||||
|
||||
//
|
||||
// explicitly tagged (probably!) - if it isn't we'd have to
|
||||
// tell from the context
|
||||
//
|
||||
if (dIn.available() == 0)
|
||||
{
|
||||
return new DERTaggedObject(tag & 0x1f, dObj);
|
||||
}
|
||||
|
||||
//
|
||||
// another implicit object, we'll create a sequence...
|
||||
//
|
||||
seq = new DERConstructedSequence();
|
||||
|
||||
seq.addObject(dObj);
|
||||
|
||||
try
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
dObj = dIn.readObject();
|
||||
|
||||
seq.addObject(dObj);
|
||||
}
|
||||
}
|
||||
catch (EOFException ex)
|
||||
{
|
||||
// ignore --
|
||||
}
|
||||
|
||||
return new DERTaggedObject(false, tag & 0x1f, seq);
|
||||
}
|
||||
|
||||
return new DERUnknownTag(tag, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
public DERObject readObject()
|
||||
throws IOException
|
||||
{
|
||||
int tag = read();
|
||||
if (tag == -1)
|
||||
{
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
int length = readLength();
|
||||
byte[] bytes = new byte[length];
|
||||
|
||||
readFully(bytes);
|
||||
|
||||
return buildObject(tag, bytes);
|
||||
}
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.util.Arrays;
|
||||
|
||||
public class DERInteger
|
||||
extends ASN1Object
|
||||
{
|
||||
byte[] bytes;
|
||||
|
||||
/**
|
||||
* return an integer from the passed in object
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DERInteger getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERInteger)
|
||||
{
|
||||
return (DERInteger)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERInteger(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject)obj).getObject());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return an Integer from a tagged object.
|
||||
*
|
||||
* @param obj the tagged object holding the object we want
|
||||
* @param explicit true if the object is meant to be explicitly
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
*/
|
||||
public static DERInteger getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
public DERInteger(
|
||||
int value)
|
||||
{
|
||||
bytes = BigInteger.valueOf(value).toByteArray();
|
||||
}
|
||||
|
||||
public DERInteger(
|
||||
BigInteger value)
|
||||
{
|
||||
bytes = value.toByteArray();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(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(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERInteger))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DERInteger other = (DERInteger)o;
|
||||
|
||||
return Arrays.areEqual(bytes, other.bytes);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getValue().toString();
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A NULL object.
|
||||
*/
|
||||
public class DERNull
|
||||
extends ASN1Null
|
||||
{
|
||||
public static final DERNull INSTANCE = new DERNull();
|
||||
|
||||
byte[] zeroBytes = new byte[0];
|
||||
|
||||
public DERNull()
|
||||
{
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(NULL, zeroBytes);
|
||||
}
|
||||
}
|
@ -1,177 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* DER NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }.
|
||||
*/
|
||||
public class DERNumericString
|
||||
extends ASN1Object
|
||||
implements DERString
|
||||
{
|
||||
String string;
|
||||
|
||||
/**
|
||||
* return a Numeric string from the passed in object
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DERNumericString getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERNumericString)
|
||||
{
|
||||
return (DERNumericString)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERNumericString(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject)obj).getObject());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return an Numeric 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.
|
||||
*/
|
||||
public static DERNumericString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor - with bytes.
|
||||
*/
|
||||
public DERNumericString(
|
||||
byte[] string)
|
||||
{
|
||||
char[] cs = new char[string.length];
|
||||
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
cs[i] = (char)(string[i] & 0xff);
|
||||
}
|
||||
|
||||
this.string = new String(cs);
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor - without validation..
|
||||
*/
|
||||
public DERNumericString(
|
||||
String string)
|
||||
{
|
||||
this(string, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with optional validation.
|
||||
*
|
||||
* @param string the base string to wrap.
|
||||
* @param validate whether or not to check the string.
|
||||
* @throws IllegalArgumentException if validate is true and the string
|
||||
* contains characters that should not be in a NumericString.
|
||||
*/
|
||||
public DERNumericString(
|
||||
String string,
|
||||
boolean validate)
|
||||
{
|
||||
if (validate && !isNumericString(string))
|
||||
{
|
||||
throw new IllegalArgumentException("string contains illegal characters");
|
||||
}
|
||||
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public String getString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public byte[] getOctets()
|
||||
{
|
||||
char[] cs = string.toCharArray();
|
||||
byte[] bs = new byte[cs.length];
|
||||
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
bs[i] = (byte)cs[i];
|
||||
}
|
||||
|
||||
return bs;
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(NUMERIC_STRING, this.getOctets());
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return this.getString().hashCode();
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERNumericString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DERNumericString s = (DERNumericString)o;
|
||||
|
||||
return this.getString().equals(s.getString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the string can be represented as a NumericString ('0'..'9', ' ')
|
||||
*
|
||||
* @param str string to validate.
|
||||
* @return true if numeric, fale otherwise.
|
||||
*/
|
||||
public static boolean isNumericString(
|
||||
String str)
|
||||
{
|
||||
for (int i = str.length() - 1; i >= 0; i--)
|
||||
{
|
||||
char ch = str.charAt(i);
|
||||
|
||||
if (ch > 0x007f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (('0' <= ch && ch <= '9') || ch == ' ')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class DERObject
|
||||
extends ASN1Encodable
|
||||
implements DERTags
|
||||
{
|
||||
public DERObject toASN1Object()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public abstract int hashCode();
|
||||
|
||||
public abstract boolean equals(Object o);
|
||||
|
||||
abstract void encode(DEROutputStream out)
|
||||
throws IOException;
|
||||
}
|
@ -1,293 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
|
||||
public class DERObjectIdentifier
|
||||
extends ASN1Object
|
||||
{
|
||||
String identifier;
|
||||
|
||||
/**
|
||||
* return an OID from the passed in object
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DERObjectIdentifier getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERObjectIdentifier)
|
||||
{
|
||||
return (DERObjectIdentifier)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERObjectIdentifier(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject)obj).getObject());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return an Object Identifier from a tagged object.
|
||||
*
|
||||
* @param obj the tagged object holding the object we want
|
||||
* @param explicit true if the object is meant to be explicitly
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
*/
|
||||
public static DERObjectIdentifier getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
|
||||
DERObjectIdentifier(
|
||||
byte[] bytes)
|
||||
{
|
||||
StringBuffer objId = new StringBuffer();
|
||||
long value = 0;
|
||||
BigInteger bigValue = null;
|
||||
boolean first = true;
|
||||
|
||||
for (int i = 0; i != bytes.length; i++)
|
||||
{
|
||||
int b = bytes[i] & 0xff;
|
||||
|
||||
if (value < 0x80000000000000L)
|
||||
{
|
||||
value = value * 128 + (b & 0x7f);
|
||||
if ((b & 0x80) == 0) // end of number reached
|
||||
{
|
||||
if (first)
|
||||
{
|
||||
switch ((int)value / 40)
|
||||
{
|
||||
case 0:
|
||||
objId.append('0');
|
||||
break;
|
||||
case 1:
|
||||
objId.append('1');
|
||||
value -= 40;
|
||||
break;
|
||||
default:
|
||||
objId.append('2');
|
||||
value -= 80;
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
|
||||
objId.append('.');
|
||||
objId.append(value);
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bigValue == null)
|
||||
{
|
||||
bigValue = BigInteger.valueOf(value);
|
||||
}
|
||||
bigValue = bigValue.shiftLeft(7);
|
||||
bigValue = bigValue.or(BigInteger.valueOf(b & 0x7f));
|
||||
if ((b & 0x80) == 0)
|
||||
{
|
||||
objId.append('.');
|
||||
objId.append(bigValue);
|
||||
bigValue = null;
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.identifier = objId.toString();
|
||||
}
|
||||
|
||||
public DERObjectIdentifier(
|
||||
String identifier)
|
||||
{
|
||||
if (!isValidIdentifier(identifier))
|
||||
{
|
||||
throw new IllegalArgumentException("string " + identifier + " not an OID");
|
||||
}
|
||||
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return identifier;
|
||||
}
|
||||
|
||||
private void writeField(
|
||||
OutputStream out,
|
||||
long fieldValue)
|
||||
throws IOException
|
||||
{
|
||||
if (fieldValue >= (1L << 7))
|
||||
{
|
||||
if (fieldValue >= (1L << 14))
|
||||
{
|
||||
if (fieldValue >= (1L << 21))
|
||||
{
|
||||
if (fieldValue >= (1L << 28))
|
||||
{
|
||||
if (fieldValue >= (1L << 35))
|
||||
{
|
||||
if (fieldValue >= (1L << 42))
|
||||
{
|
||||
if (fieldValue >= (1L << 49))
|
||||
{
|
||||
if (fieldValue >= (1L << 56))
|
||||
{
|
||||
out.write((int)(fieldValue >> 56) | 0x80);
|
||||
}
|
||||
out.write((int)(fieldValue >> 49) | 0x80);
|
||||
}
|
||||
out.write((int)(fieldValue >> 42) | 0x80);
|
||||
}
|
||||
out.write((int)(fieldValue >> 35) | 0x80);
|
||||
}
|
||||
out.write((int)(fieldValue >> 28) | 0x80);
|
||||
}
|
||||
out.write((int)(fieldValue >> 21) | 0x80);
|
||||
}
|
||||
out.write((int)(fieldValue >> 14) | 0x80);
|
||||
}
|
||||
out.write((int)(fieldValue >> 7) | 0x80);
|
||||
}
|
||||
out.write((int)fieldValue & 0x7f);
|
||||
}
|
||||
|
||||
private void writeField(
|
||||
OutputStream out,
|
||||
BigInteger fieldValue)
|
||||
throws IOException
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
OIDTokenizer tok = new OIDTokenizer(identifier);
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
DEROutputStream dOut = new DEROutputStream(bOut);
|
||||
|
||||
writeField(bOut,
|
||||
Integer.parseInt(tok.nextToken()) * 40
|
||||
+ Integer.parseInt(tok.nextToken()));
|
||||
|
||||
while (tok.hasMoreTokens())
|
||||
{
|
||||
String token = tok.nextToken();
|
||||
if (token.length() < 18)
|
||||
{
|
||||
writeField(bOut, Long.parseLong(token));
|
||||
}
|
||||
else
|
||||
{
|
||||
writeField(bOut, new BigInteger(token));
|
||||
}
|
||||
}
|
||||
|
||||
dOut.close();
|
||||
|
||||
byte[] bytes = bOut.toByteArray();
|
||||
|
||||
out.writeEncoded(OBJECT_IDENTIFIER, bytes);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return identifier.hashCode();
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERObjectIdentifier))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return identifier.equals(((DERObjectIdentifier)o).identifier);
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getId();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
boolean periodAllowed = false;
|
||||
for (int i = identifier.length() - 1; i >= 2; i--)
|
||||
{
|
||||
char ch = identifier.charAt(i);
|
||||
|
||||
if ('0' <= ch && ch <= '9')
|
||||
{
|
||||
periodAllowed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == '.')
|
||||
{
|
||||
if (!periodAllowed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
periodAllowed = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return periodAllowed;
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DEROctetString
|
||||
extends ASN1OctetString
|
||||
{
|
||||
/**
|
||||
* @param string the octets making up the octet string.
|
||||
*/
|
||||
public DEROctetString(
|
||||
byte[] string)
|
||||
{
|
||||
super(string);
|
||||
}
|
||||
|
||||
public DEROctetString(
|
||||
DEREncodable obj)
|
||||
{
|
||||
super(obj);
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(OCTET_STRING, string);
|
||||
}
|
||||
|
||||
static void encode(
|
||||
DEROutputStream derOut,
|
||||
byte[] bytes)
|
||||
throws IOException
|
||||
{
|
||||
derOut.writeEncoded(DERTags.OCTET_STRING, bytes);
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class DEROctetStringParser
|
||||
implements ASN1OctetStringParser
|
||||
{
|
||||
private DefiniteLengthInputStream stream;
|
||||
|
||||
DEROctetStringParser(
|
||||
DefiniteLengthInputStream stream)
|
||||
{
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
public InputStream getOctetStream()
|
||||
{
|
||||
return stream;
|
||||
}
|
||||
|
||||
public DERObject getDERObject()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new DEROctetString(stream.toByteArray());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class DEROutputStream
|
||||
extends FilterOutputStream implements DERTags
|
||||
{
|
||||
public DEROutputStream(
|
||||
OutputStream os)
|
||||
{
|
||||
super(os);
|
||||
}
|
||||
|
||||
private void writeLength(
|
||||
int length)
|
||||
throws IOException
|
||||
{
|
||||
if (length > 127)
|
||||
{
|
||||
int size = 1;
|
||||
int val = length;
|
||||
|
||||
while ((val >>>= 8) != 0)
|
||||
{
|
||||
size++;
|
||||
}
|
||||
|
||||
write((byte)(size | 0x80));
|
||||
|
||||
for (int i = (size - 1) * 8; i >= 0; i -= 8)
|
||||
{
|
||||
write((byte)(length >> i));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
write((byte)length);
|
||||
}
|
||||
}
|
||||
|
||||
void writeEncoded(
|
||||
int tag,
|
||||
byte[] bytes)
|
||||
throws IOException
|
||||
{
|
||||
write(tag);
|
||||
writeLength(bytes.length);
|
||||
write(bytes);
|
||||
}
|
||||
|
||||
void writeTag(int flags, int tagNo)
|
||||
throws IOException
|
||||
{
|
||||
if (tagNo < 31)
|
||||
{
|
||||
write(flags | tagNo);
|
||||
}
|
||||
else
|
||||
{
|
||||
write(flags | 0x1f);
|
||||
if (tagNo < 128)
|
||||
{
|
||||
write(tagNo);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte[] stack = new byte[5];
|
||||
int pos = stack.length;
|
||||
|
||||
stack[--pos] = (byte)(tagNo & 0x7F);
|
||||
|
||||
do
|
||||
{
|
||||
tagNo >>= 7;
|
||||
stack[--pos] = (byte)(tagNo & 0x7F | 0x80);
|
||||
}
|
||||
while (tagNo > 127);
|
||||
|
||||
write(stack, pos, stack.length - pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void writeEncoded(int flags, int tagNo, byte[] bytes)
|
||||
throws IOException
|
||||
{
|
||||
writeTag(flags, tagNo);
|
||||
writeLength(bytes.length);
|
||||
write(bytes);
|
||||
}
|
||||
|
||||
protected void writeNull()
|
||||
throws IOException
|
||||
{
|
||||
write(NULL);
|
||||
write(0x00);
|
||||
}
|
||||
|
||||
public void write(byte[] buf)
|
||||
throws IOException
|
||||
{
|
||||
out.write(buf, 0, buf.length);
|
||||
}
|
||||
|
||||
public void write(byte[] buf, int offSet, int len)
|
||||
throws IOException
|
||||
{
|
||||
out.write(buf, offSet, len);
|
||||
}
|
||||
|
||||
public void writeObject(
|
||||
Object obj)
|
||||
throws IOException
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
writeNull();
|
||||
}
|
||||
else if (obj instanceof DERObject)
|
||||
{
|
||||
((DERObject)obj).encode(this);
|
||||
}
|
||||
else if (obj instanceof DEREncodable)
|
||||
{
|
||||
((DEREncodable)obj).getDERObject().encode(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IOException("object not DEREncodable");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* DER PrintableString object.
|
||||
*/
|
||||
public class DERPrintableString
|
||||
extends ASN1Object
|
||||
implements DERString
|
||||
{
|
||||
String string;
|
||||
|
||||
/**
|
||||
* return a printable string from the passed in object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DERPrintableString getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERPrintableString)
|
||||
{
|
||||
return (DERPrintableString)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERPrintableString(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject)obj).getObject());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return a Printable 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.
|
||||
*/
|
||||
public static DERPrintableString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor - byte encoded string.
|
||||
*/
|
||||
public DERPrintableString(
|
||||
byte[] string)
|
||||
{
|
||||
char[] cs = new char[string.length];
|
||||
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
cs[i] = (char)(string[i] & 0xff);
|
||||
}
|
||||
|
||||
this.string = new String(cs);
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor - this does not validate the string
|
||||
*/
|
||||
public DERPrintableString(
|
||||
String string)
|
||||
{
|
||||
this(string, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with optional validation.
|
||||
*
|
||||
* @param string the base string to wrap.
|
||||
* @param validate whether or not to check the string.
|
||||
* @throws IllegalArgumentException if validate is true and the string
|
||||
* contains characters that should not be in a PrintableString.
|
||||
*/
|
||||
public DERPrintableString(
|
||||
String string,
|
||||
boolean validate)
|
||||
{
|
||||
if (validate && !isPrintableString(string))
|
||||
{
|
||||
throw new IllegalArgumentException("string contains illegal characters");
|
||||
}
|
||||
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public String getString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public byte[] getOctets()
|
||||
{
|
||||
char[] cs = string.toCharArray();
|
||||
byte[] bs = new byte[cs.length];
|
||||
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
bs[i] = (byte)cs[i];
|
||||
}
|
||||
|
||||
return bs;
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(PRINTABLE_STRING, this.getOctets());
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return this.getString().hashCode();
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERPrintableString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DERPrintableString s = (DERPrintableString)o;
|
||||
|
||||
return this.getString().equals(s.getString());
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
/**
|
||||
* return true if the passed in String can be represented without
|
||||
* loss as a PrintableString, false otherwise.
|
||||
*
|
||||
* @return true if in printable set, false otherwise.
|
||||
*/
|
||||
public static boolean isPrintableString(
|
||||
String str)
|
||||
{
|
||||
for (int i = str.length() - 1; i >= 0; i--)
|
||||
{
|
||||
char ch = str.charAt(i);
|
||||
|
||||
if (ch > 0x007f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ('a' <= ch && ch <= 'z')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('A' <= ch && ch <= 'Z')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ('0' <= ch && ch <= '9')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case ' ':
|
||||
case '\'':
|
||||
case '(':
|
||||
case ')':
|
||||
case '+':
|
||||
case '-':
|
||||
case '.':
|
||||
case ':':
|
||||
case '=':
|
||||
case '?':
|
||||
case '/':
|
||||
case ',':
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
public class DERSequence
|
||||
extends ASN1Sequence
|
||||
{
|
||||
/**
|
||||
* create an empty sequence
|
||||
*/
|
||||
public DERSequence()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* create a sequence containing one object
|
||||
*/
|
||||
public DERSequence(
|
||||
DEREncodable obj)
|
||||
{
|
||||
this.addObject(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a sequence containing a vector of objects.
|
||||
*/
|
||||
public DERSequence(
|
||||
DEREncodableVector v)
|
||||
{
|
||||
for (int i = 0; i != v.size(); i++)
|
||||
{
|
||||
this.addObject(v.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create a sequence containing an array of objects.
|
||||
*/
|
||||
public DERSequence(
|
||||
ASN1Encodable[] a)
|
||||
{
|
||||
for (int i = 0; i != a.length; i++)
|
||||
{
|
||||
this.addObject(a[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A note on the implementation:
|
||||
* <p>
|
||||
* As DER requires the constructed, definite-length model to
|
||||
* be used for structured types, this varies slightly from the
|
||||
* ASN.1 descriptions given. Rather than just outputing SEQUENCE,
|
||||
* we also have to specify CONSTRUCTED, and the objects length.
|
||||
*/
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
// TODO Intermediate buffer could be avoided if we could calculate expected length
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
DEROutputStream dOut = new DEROutputStream(bOut);
|
||||
Enumeration e = this.getObjects();
|
||||
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
Object obj = e.nextElement();
|
||||
|
||||
dOut.writeObject(obj);
|
||||
}
|
||||
|
||||
dOut.close();
|
||||
|
||||
byte[] bytes = bOut.toByteArray();
|
||||
|
||||
out.writeEncoded(SEQUENCE | CONSTRUCTED, bytes);
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class DERSequenceGenerator
|
||||
extends DERGenerator
|
||||
{
|
||||
private final ByteArrayOutputStream _bOut = new ByteArrayOutputStream();
|
||||
|
||||
public DERSequenceGenerator(
|
||||
OutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
super(out);
|
||||
}
|
||||
|
||||
public DERSequenceGenerator(
|
||||
OutputStream out,
|
||||
int tagNo,
|
||||
boolean isExplicit)
|
||||
throws IOException
|
||||
{
|
||||
super(out, tagNo, isExplicit);
|
||||
}
|
||||
|
||||
public void addObject(
|
||||
DEREncodable object)
|
||||
throws IOException
|
||||
{
|
||||
object.getDERObject().encode(new DEROutputStream(_bOut));
|
||||
}
|
||||
|
||||
public OutputStream getRawOutputStream()
|
||||
{
|
||||
return _bOut;
|
||||
}
|
||||
|
||||
public void close()
|
||||
throws IOException
|
||||
{
|
||||
writeDEREncoded(DERTags.CONSTRUCTED | DERTags.SEQUENCE, _bOut.toByteArray());
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DERSequenceParser
|
||||
implements ASN1SequenceParser
|
||||
{
|
||||
private ASN1StreamParser _parser;
|
||||
|
||||
DERSequenceParser(ASN1StreamParser parser)
|
||||
{
|
||||
this._parser = parser;
|
||||
}
|
||||
|
||||
public DEREncodable readObject()
|
||||
throws IOException
|
||||
{
|
||||
return _parser.readObject();
|
||||
}
|
||||
|
||||
public DERObject getDERObject()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new DERSequence(_parser.readVector());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new IllegalStateException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* A DER encoded set object
|
||||
*/
|
||||
public class DERSet
|
||||
extends ASN1Set
|
||||
{
|
||||
/**
|
||||
* create an empty set
|
||||
*/
|
||||
public DERSet()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param obj - a single object that makes up the set.
|
||||
*/
|
||||
public DERSet(
|
||||
DEREncodable obj)
|
||||
{
|
||||
this.addObject(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param v - a vector of objects making up the set.
|
||||
*/
|
||||
public DERSet(
|
||||
DEREncodableVector v)
|
||||
{
|
||||
this(v, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a set from an array of objects.
|
||||
*/
|
||||
public DERSet(
|
||||
ASN1Encodable[] a)
|
||||
{
|
||||
for (int i = 0; i != a.length; i++)
|
||||
{
|
||||
this.addObject(a[i]);
|
||||
}
|
||||
|
||||
this.sort();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param v - a vector of objects making up the set.
|
||||
*/
|
||||
DERSet(
|
||||
DEREncodableVector v,
|
||||
boolean needsSorting)
|
||||
{
|
||||
for (int i = 0; i != v.size(); i++)
|
||||
{
|
||||
this.addObject(v.get(i));
|
||||
}
|
||||
|
||||
if (needsSorting)
|
||||
{
|
||||
this.sort();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A note on the implementation:
|
||||
* <p>
|
||||
* As DER requires the constructed, definite-length model to
|
||||
* be used for structured types, this varies slightly from the
|
||||
* ASN.1 descriptions given. Rather than just outputing SET,
|
||||
* we also have to specify CONSTRUCTED, and the objects length.
|
||||
*/
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
// TODO Intermediate buffer could be avoided if we could calculate expected length
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
DEROutputStream dOut = new DEROutputStream(bOut);
|
||||
Enumeration e = this.getObjects();
|
||||
|
||||
while (e.hasMoreElements())
|
||||
{
|
||||
Object obj = e.nextElement();
|
||||
|
||||
dOut.writeObject(obj);
|
||||
}
|
||||
|
||||
dOut.close();
|
||||
|
||||
byte[] bytes = bOut.toByteArray();
|
||||
|
||||
out.writeEncoded(SET | CONSTRUCTED, bytes);
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class DERSetParser
|
||||
implements ASN1SetParser
|
||||
{
|
||||
private ASN1StreamParser _parser;
|
||||
|
||||
DERSetParser(ASN1StreamParser parser)
|
||||
{
|
||||
this._parser = parser;
|
||||
}
|
||||
|
||||
public DEREncodable readObject()
|
||||
throws IOException
|
||||
{
|
||||
return _parser.readObject();
|
||||
}
|
||||
|
||||
public DERObject getDERObject()
|
||||
{
|
||||
try
|
||||
{
|
||||
return new DERSet(_parser.readVector(), false);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ASN1ParsingException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
/**
|
||||
* basic interface for DER string objects.
|
||||
*/
|
||||
public interface DERString
|
||||
{
|
||||
public String getString();
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* DER T61String (also the teletex string)
|
||||
*/
|
||||
public class DERT61String
|
||||
extends ASN1Object
|
||||
implements DERString
|
||||
{
|
||||
String string;
|
||||
|
||||
/**
|
||||
* return a T61 string from the passed in object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DERT61String getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERT61String)
|
||||
{
|
||||
return (DERT61String)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERT61String(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject)obj).getObject());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return an T61 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.
|
||||
*/
|
||||
public static DERT61String getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor - with bytes.
|
||||
*/
|
||||
public DERT61String(
|
||||
byte[] string)
|
||||
{
|
||||
char[] cs = new char[string.length];
|
||||
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
cs[i] = (char)(string[i] & 0xff);
|
||||
}
|
||||
|
||||
this.string = new String(cs);
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor - with string.
|
||||
*/
|
||||
public DERT61String(
|
||||
String string)
|
||||
{
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public String getString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(T61_STRING, this.getOctets());
|
||||
}
|
||||
|
||||
public byte[] getOctets()
|
||||
{
|
||||
char[] cs = string.toCharArray();
|
||||
byte[] bs = new byte[cs.length];
|
||||
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
bs[i] = (byte)cs[i];
|
||||
}
|
||||
|
||||
return bs;
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERT61String))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.getString().equals(((DERT61String)o).getString());
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return this.getString().hashCode();
|
||||
}
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* DER TaggedObject - in ASN.1 notation this is any object preceded by
|
||||
* a [n] where n is some number - these are assumed to follow the construction
|
||||
* rules (as with sequences).
|
||||
*/
|
||||
public class DERTaggedObject
|
||||
extends ASN1TaggedObject
|
||||
{
|
||||
private static final byte[] ZERO_BYTES = new byte[0];
|
||||
|
||||
/**
|
||||
* @param tagNo the tag number for this object.
|
||||
* @param obj the tagged object.
|
||||
*/
|
||||
public DERTaggedObject(
|
||||
int tagNo,
|
||||
DEREncodable obj)
|
||||
{
|
||||
super(tagNo, obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param explicit true if an explicitly tagged object.
|
||||
* @param tagNo the tag number for this object.
|
||||
* @param obj the tagged object.
|
||||
*/
|
||||
public DERTaggedObject(
|
||||
boolean explicit,
|
||||
int tagNo,
|
||||
DEREncodable obj)
|
||||
{
|
||||
super(explicit, tagNo, obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* create an implicitly tagged object that contains a zero
|
||||
* length sequence.
|
||||
*/
|
||||
public DERTaggedObject(
|
||||
int tagNo)
|
||||
{
|
||||
super(false, tagNo, new DERSequence());
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
if (!empty)
|
||||
{
|
||||
byte[] bytes = obj.getDERObject().getEncoded(DER);
|
||||
|
||||
if (explicit)
|
||||
{
|
||||
out.writeEncoded(CONSTRUCTED | TAGGED, tagNo, bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// need to mark constructed types...
|
||||
//
|
||||
int flags;
|
||||
if ((bytes[0] & CONSTRUCTED) != 0)
|
||||
{
|
||||
flags = CONSTRUCTED | TAGGED;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = TAGGED;
|
||||
}
|
||||
|
||||
out.writeTag(flags, tagNo);
|
||||
out.write(bytes, 1, bytes.length - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out.writeEncoded(CONSTRUCTED | TAGGED, tagNo, ZERO_BYTES);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
public interface DERTags
|
||||
{
|
||||
public static final int BOOLEAN = 0x01;
|
||||
public static final int INTEGER = 0x02;
|
||||
public static final int BIT_STRING = 0x03;
|
||||
public static final int OCTET_STRING = 0x04;
|
||||
public static final int NULL = 0x05;
|
||||
public static final int OBJECT_IDENTIFIER = 0x06;
|
||||
public static final int EXTERNAL = 0x08;
|
||||
public static final int ENUMERATED = 0x0a;
|
||||
public static final int SEQUENCE = 0x10;
|
||||
public static final int SEQUENCE_OF = 0x10; // for completeness
|
||||
public static final int SET = 0x11;
|
||||
public static final int SET_OF = 0x11; // for completeness
|
||||
|
||||
|
||||
public static final int NUMERIC_STRING = 0x12;
|
||||
public static final int PRINTABLE_STRING = 0x13;
|
||||
public static final int T61_STRING = 0x14;
|
||||
public static final int VIDEOTEX_STRING = 0x15;
|
||||
public static final int IA5_STRING = 0x16;
|
||||
public static final int UTC_TIME = 0x17;
|
||||
public static final int GENERALIZED_TIME = 0x18;
|
||||
public static final int GRAPHIC_STRING = 0x19;
|
||||
public static final int VISIBLE_STRING = 0x1a;
|
||||
public static final int GENERAL_STRING = 0x1b;
|
||||
public static final int UNIVERSAL_STRING = 0x1c;
|
||||
public static final int BMP_STRING = 0x1e;
|
||||
public static final int UTF8_STRING = 0x0c;
|
||||
|
||||
public static final int CONSTRUCTED = 0x20;
|
||||
public static final int APPLICATION = 0x40;
|
||||
public static final int TAGGED = 0x80;
|
||||
}
|
@ -1,254 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.SimpleTimeZone;
|
||||
|
||||
/**
|
||||
* UTC time object.
|
||||
*/
|
||||
public class DERUTCTime
|
||||
extends ASN1Object
|
||||
{
|
||||
String time;
|
||||
|
||||
/**
|
||||
* return an UTC Time from the passed in object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DERUTCTime getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERUTCTime)
|
||||
{
|
||||
return (DERUTCTime)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERUTCTime(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return an UTC Time from a tagged object.
|
||||
*
|
||||
* @param obj the tagged object holding the object we want
|
||||
* @param explicit true if the object is meant to be explicitly
|
||||
* tagged false otherwise.
|
||||
* @exception IllegalArgumentException if the tagged object cannot
|
||||
* be converted.
|
||||
*/
|
||||
public static DERUTCTime getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 = time;
|
||||
try
|
||||
{
|
||||
this.getDate();
|
||||
}
|
||||
catch (ParseException e)
|
||||
{
|
||||
throw new IllegalArgumentException("invalid date string: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* base constructer from a java.util.date object
|
||||
*/
|
||||
public DERUTCTime(
|
||||
Date time)
|
||||
{
|
||||
SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'");
|
||||
|
||||
dateF.setTimeZone(new SimpleTimeZone(0,"Z"));
|
||||
|
||||
this.time = dateF.format(time);
|
||||
}
|
||||
|
||||
DERUTCTime(
|
||||
byte[] bytes)
|
||||
{
|
||||
//
|
||||
// explicitly convert to characters
|
||||
//
|
||||
char[] dateC = new char[bytes.length];
|
||||
|
||||
for (int i = 0; i != dateC.length; i++)
|
||||
{
|
||||
dateC[i] = (char)(bytes[i] & 0xff);
|
||||
}
|
||||
|
||||
this.time = new String(dateC);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
//
|
||||
// standardise the format.
|
||||
//
|
||||
if (time.indexOf('-') < 0 && time.indexOf('+') < 0)
|
||||
{
|
||||
if (time.length() == 11)
|
||||
{
|
||||
return time.substring(0, 10) + "00GMT+00:00";
|
||||
}
|
||||
else
|
||||
{
|
||||
return time.substring(0, 12) + "GMT+00:00";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = time.indexOf('-');
|
||||
if (index < 0)
|
||||
{
|
||||
index = time.indexOf('+');
|
||||
}
|
||||
String d = time;
|
||||
|
||||
if (index == time.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;
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] getOctets()
|
||||
{
|
||||
char[] cs = time.toCharArray();
|
||||
byte[] bs = new byte[cs.length];
|
||||
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
bs[i] = (byte)cs[i];
|
||||
}
|
||||
|
||||
return bs;
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(UTC_TIME, this.getOctets());
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERUTCTime))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return time.equals(((DERUTCTime)o).time);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return time.hashCode();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return time;
|
||||
}
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.util.Strings;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* DER UTF8String object.
|
||||
*/
|
||||
public class DERUTF8String
|
||||
extends ASN1Object
|
||||
implements DERString
|
||||
{
|
||||
String string;
|
||||
|
||||
/**
|
||||
* return an UTF8 string from the passed in object.
|
||||
*
|
||||
* @exception IllegalArgumentException
|
||||
* if the object cannot be converted.
|
||||
*/
|
||||
public static DERUTF8String getInstance(Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERUTF8String)
|
||||
{
|
||||
return (DERUTF8String)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERUTF8String(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject)obj).getObject());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: "
|
||||
+ obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return an UTF8 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.
|
||||
*/
|
||||
public static DERUTF8String getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor - byte encoded string.
|
||||
*/
|
||||
DERUTF8String(byte[] string)
|
||||
{
|
||||
this.string = Strings.fromUTF8ByteArray(string);
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor
|
||||
*/
|
||||
public DERUTF8String(String string)
|
||||
{
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public String getString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return this.getString().hashCode();
|
||||
}
|
||||
|
||||
boolean asn1Equals(DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERUTF8String))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DERUTF8String s = (DERUTF8String)o;
|
||||
|
||||
return this.getString().equals(s.getString());
|
||||
}
|
||||
|
||||
void encode(DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(UTF8_STRING, Strings.toUTF8ByteArray(string));
|
||||
}
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* DER UniversalString object.
|
||||
*/
|
||||
public class DERUniversalString
|
||||
extends ASN1Object
|
||||
implements DERString
|
||||
{
|
||||
private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
private byte[] string;
|
||||
|
||||
/**
|
||||
* return a Universal String from the passed in object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DERUniversalString getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERUniversalString)
|
||||
{
|
||||
return (DERUniversalString)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERUniversalString(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* return a Universal 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.
|
||||
*/
|
||||
public static DERUniversalString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor - byte encoded string.
|
||||
*/
|
||||
public DERUniversalString(
|
||||
byte[] string)
|
||||
{
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public String getString()
|
||||
{
|
||||
StringBuffer buf = new StringBuffer("#");
|
||||
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||
ASN1OutputStream aOut = new ASN1OutputStream(bOut);
|
||||
|
||||
try
|
||||
{
|
||||
aOut.writeObject(this);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException("internal error encoding BitString");
|
||||
}
|
||||
|
||||
byte[] string = bOut.toByteArray();
|
||||
|
||||
for (int i = 0; i != string.length; i++)
|
||||
{
|
||||
buf.append(table[(string[i] >>> 4) & 0xf]);
|
||||
buf.append(table[string[i] & 0xf]);
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return getString();
|
||||
}
|
||||
|
||||
public byte[] getOctets()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(UNIVERSAL_STRING, this.getOctets());
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERUniversalString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.getString().equals(((DERUniversalString)o).getString());
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return this.getString().hashCode();
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.util.Arrays;
|
||||
|
||||
/**
|
||||
* We insert one of these when we find a tag we don't recognise.
|
||||
*/
|
||||
public class DERUnknownTag
|
||||
extends DERObject
|
||||
{
|
||||
private boolean isConstructed;
|
||||
private int tag;
|
||||
private byte[] data;
|
||||
|
||||
/**
|
||||
* @param tag the tag value.
|
||||
* @param data the contents octets.
|
||||
*/
|
||||
public DERUnknownTag(
|
||||
int tag,
|
||||
byte[] data)
|
||||
{
|
||||
this(false, tag, data);
|
||||
}
|
||||
|
||||
public DERUnknownTag(
|
||||
boolean isConstructed,
|
||||
int tag,
|
||||
byte[] data)
|
||||
{
|
||||
this.isConstructed = isConstructed;
|
||||
this.tag = tag;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public boolean isConstructed()
|
||||
{
|
||||
return isConstructed;
|
||||
}
|
||||
|
||||
public int getTag()
|
||||
{
|
||||
return tag;
|
||||
}
|
||||
|
||||
public byte[] getData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(isConstructed ? DERTags.CONSTRUCTED : 0, tag, data);
|
||||
}
|
||||
|
||||
public boolean equals(
|
||||
Object o)
|
||||
{
|
||||
if (!(o instanceof DERUnknownTag))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DERUnknownTag other = (DERUnknownTag)o;
|
||||
|
||||
return isConstructed == other.isConstructed
|
||||
&& tag == other.tag
|
||||
&& Arrays.areEqual(data, other.data);
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return (isConstructed ? ~0 : 0) ^ tag ^ Arrays.hashCode(data);
|
||||
}
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* DER VisibleString object.
|
||||
*/
|
||||
public class DERVisibleString
|
||||
extends ASN1Object
|
||||
implements DERString
|
||||
{
|
||||
String string;
|
||||
|
||||
/**
|
||||
* return a Visible String from the passed in object.
|
||||
*
|
||||
* @exception IllegalArgumentException if the object cannot be converted.
|
||||
*/
|
||||
public static DERVisibleString getInstance(
|
||||
Object obj)
|
||||
{
|
||||
if (obj == null || obj instanceof DERVisibleString)
|
||||
{
|
||||
return (DERVisibleString)obj;
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1OctetString)
|
||||
{
|
||||
return new DERVisibleString(((ASN1OctetString)obj).getOctets());
|
||||
}
|
||||
|
||||
if (obj instanceof ASN1TaggedObject)
|
||||
{
|
||||
return getInstance(((ASN1TaggedObject)obj).getObject());
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public static DERVisibleString getInstance(
|
||||
ASN1TaggedObject obj,
|
||||
boolean explicit)
|
||||
{
|
||||
return getInstance(obj.getObject());
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor - byte encoded string.
|
||||
*/
|
||||
public DERVisibleString(
|
||||
byte[] string)
|
||||
{
|
||||
char[] cs = new char[string.length];
|
||||
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
cs[i] = (char)(string[i] & 0xff);
|
||||
}
|
||||
|
||||
this.string = new String(cs);
|
||||
}
|
||||
|
||||
/**
|
||||
* basic constructor
|
||||
*/
|
||||
public DERVisibleString(
|
||||
String string)
|
||||
{
|
||||
this.string = string;
|
||||
}
|
||||
|
||||
public String getString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public String toString()
|
||||
{
|
||||
return string;
|
||||
}
|
||||
|
||||
public byte[] getOctets()
|
||||
{
|
||||
char[] cs = string.toCharArray();
|
||||
byte[] bs = new byte[cs.length];
|
||||
|
||||
for (int i = 0; i != cs.length; i++)
|
||||
{
|
||||
bs[i] = (byte)cs[i];
|
||||
}
|
||||
|
||||
return bs;
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(VISIBLE_STRING, this.getOctets());
|
||||
}
|
||||
|
||||
boolean asn1Equals(
|
||||
DERObject o)
|
||||
{
|
||||
if (!(o instanceof DERVisibleString))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.getString().equals(((DERVisibleString)o).getString());
|
||||
}
|
||||
|
||||
public int hashCode()
|
||||
{
|
||||
return this.getString().hashCode();
|
||||
}
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.util.io.Streams;
|
||||
|
||||
class DefiniteLengthInputStream
|
||||
extends LimitedInputStream
|
||||
{
|
||||
private static final byte[] EMPTY_BYTES = new byte[0];
|
||||
|
||||
private final int _originalLength;
|
||||
private int _remaining;
|
||||
|
||||
DefiniteLengthInputStream(
|
||||
InputStream in,
|
||||
int length)
|
||||
{
|
||||
super(in);
|
||||
|
||||
if (length < 0)
|
||||
{
|
||||
throw new IllegalArgumentException("negative lengths not allowed");
|
||||
}
|
||||
|
||||
this._originalLength = length;
|
||||
this._remaining = length;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
setParentEofDetect(true);
|
||||
}
|
||||
}
|
||||
|
||||
int getRemaining()
|
||||
{
|
||||
return _remaining;
|
||||
}
|
||||
|
||||
public int read()
|
||||
throws IOException
|
||||
{
|
||||
if (_remaining == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int b = _in.read();
|
||||
|
||||
if (b < 0)
|
||||
{
|
||||
throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
|
||||
}
|
||||
|
||||
if (--_remaining == 0)
|
||||
{
|
||||
setParentEofDetect(true);
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
public int read(byte[] buf, int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
if (_remaining == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int toRead = Math.min(len, _remaining);
|
||||
int numRead = _in.read(buf, off, toRead);
|
||||
|
||||
if (numRead < 0)
|
||||
{
|
||||
throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
|
||||
}
|
||||
|
||||
if ((_remaining -= numRead) == 0)
|
||||
{
|
||||
setParentEofDetect(true);
|
||||
}
|
||||
|
||||
return numRead;
|
||||
}
|
||||
|
||||
byte[] toByteArray()
|
||||
throws IOException
|
||||
{
|
||||
if (_remaining == 0)
|
||||
{
|
||||
return EMPTY_BYTES;
|
||||
}
|
||||
|
||||
byte[] bytes = new byte[_remaining];
|
||||
if ((_remaining -= Streams.readFully(_in, bytes)) != 0)
|
||||
{
|
||||
throw new EOFException("DEF length " + _originalLength + " object truncated by " + _remaining);
|
||||
}
|
||||
setParentEofDetect(true);
|
||||
return bytes;
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
class IndefiniteLengthInputStream
|
||||
extends LimitedInputStream
|
||||
{
|
||||
private int _b1;
|
||||
private int _b2;
|
||||
private boolean _eofReached = false;
|
||||
private boolean _eofOn00 = true;
|
||||
|
||||
IndefiniteLengthInputStream(
|
||||
InputStream in)
|
||||
throws IOException
|
||||
{
|
||||
super(in);
|
||||
|
||||
_b1 = in.read();
|
||||
_b2 = in.read();
|
||||
|
||||
if (_b2 < 0)
|
||||
{
|
||||
// Corrupted stream
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
checkForEof();
|
||||
}
|
||||
|
||||
void setEofOn00(
|
||||
boolean eofOn00)
|
||||
{
|
||||
_eofOn00 = eofOn00;
|
||||
checkForEof();
|
||||
}
|
||||
|
||||
private boolean checkForEof()
|
||||
{
|
||||
if (!_eofReached && _eofOn00 && (_b1 == 0x00 && _b2 == 0x00))
|
||||
{
|
||||
_eofReached = true;
|
||||
setParentEofDetect(true);
|
||||
}
|
||||
return _eofReached;
|
||||
}
|
||||
|
||||
public int read(byte[] b, int off, int len)
|
||||
throws IOException
|
||||
{
|
||||
// Only use this optimisation if we aren't checking for 00
|
||||
if (_eofOn00 || len < 3)
|
||||
{
|
||||
return super.read(b, off, len);
|
||||
}
|
||||
|
||||
if (_eofReached)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int numRead = _in.read(b, off + 2, len - 2);
|
||||
|
||||
if (numRead < 0)
|
||||
{
|
||||
// Corrupted stream
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
b[off] = (byte)_b1;
|
||||
b[off + 1] = (byte)_b2;
|
||||
|
||||
_b1 = _in.read();
|
||||
_b2 = _in.read();
|
||||
|
||||
if (_b2 < 0)
|
||||
{
|
||||
// Corrupted stream
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
return numRead + 2;
|
||||
}
|
||||
|
||||
public int read()
|
||||
throws IOException
|
||||
{
|
||||
if (checkForEof())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int b = _in.read();
|
||||
|
||||
if (b < 0)
|
||||
{
|
||||
// Corrupted stream
|
||||
throw new EOFException();
|
||||
}
|
||||
|
||||
int v = _b1;
|
||||
|
||||
_b1 = _b2;
|
||||
_b2 = b;
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.io.IOException;
|
||||
|
||||
class LazyDERConstructionEnumeration
|
||||
implements Enumeration
|
||||
{
|
||||
private ASN1InputStream aIn;
|
||||
private Object nextObj;
|
||||
|
||||
public LazyDERConstructionEnumeration(byte[] encoded)
|
||||
{
|
||||
aIn = new ASN1InputStream(encoded, true);
|
||||
nextObj = readObject();
|
||||
}
|
||||
|
||||
public boolean hasMoreElements()
|
||||
{
|
||||
return nextObj != null;
|
||||
}
|
||||
|
||||
public Object nextElement()
|
||||
{
|
||||
Object o = nextObj;
|
||||
|
||||
nextObj = readObject();
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
private Object readObject()
|
||||
{
|
||||
try
|
||||
{
|
||||
return aIn.readObject();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new ASN1ParsingException("malformed DER construction: " + e, e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
|
||||
public class LazyDERSequence
|
||||
extends DERSequence
|
||||
{
|
||||
private byte[] encoded;
|
||||
private boolean parsed = false;
|
||||
private int size = -1;
|
||||
|
||||
LazyDERSequence(
|
||||
byte[] encoded)
|
||||
throws IOException
|
||||
{
|
||||
this.encoded = encoded;
|
||||
}
|
||||
|
||||
private void parse()
|
||||
{
|
||||
Enumeration en = new LazyDERConstructionEnumeration(encoded);
|
||||
|
||||
while (en.hasMoreElements())
|
||||
{
|
||||
addObject((DEREncodable)en.nextElement());
|
||||
}
|
||||
|
||||
parsed = true;
|
||||
}
|
||||
|
||||
public DEREncodable getObjectAt(int index)
|
||||
{
|
||||
if (!parsed)
|
||||
{
|
||||
parse();
|
||||
}
|
||||
|
||||
return super.getObjectAt(index);
|
||||
}
|
||||
|
||||
public Enumeration getObjects()
|
||||
{
|
||||
if (parsed)
|
||||
{
|
||||
return super.getObjects();
|
||||
}
|
||||
|
||||
return new LazyDERConstructionEnumeration(encoded);
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
if (size < 0)
|
||||
{
|
||||
Enumeration en = new LazyDERConstructionEnumeration(encoded);
|
||||
|
||||
size = 0;
|
||||
while (en.hasMoreElements())
|
||||
{
|
||||
en.nextElement();
|
||||
size++;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void encode(
|
||||
DEROutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
out.writeEncoded(SEQUENCE | CONSTRUCTED, encoded);
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
abstract class LimitedInputStream
|
||||
extends InputStream
|
||||
{
|
||||
protected final InputStream _in;
|
||||
|
||||
LimitedInputStream(
|
||||
InputStream in)
|
||||
{
|
||||
this._in = in;
|
||||
}
|
||||
|
||||
protected void setParentEofDetect(boolean on)
|
||||
{
|
||||
if (_in instanceof IndefiniteLengthInputStream)
|
||||
{
|
||||
((IndefiniteLengthInputStream)_in).setEofOn00(on);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1;
|
||||
|
||||
/**
|
||||
* class for breaking up an OID into it's component tokens, ala
|
||||
* java.util.StringTokenizer. We need this class as some of the
|
||||
* lightweight Java environment don't support classes like
|
||||
* StringTokenizer.
|
||||
*/
|
||||
public class OIDTokenizer
|
||||
{
|
||||
private String oid;
|
||||
private int index;
|
||||
|
||||
public OIDTokenizer(
|
||||
String oid)
|
||||
{
|
||||
this.oid = oid;
|
||||
this.index = 0;
|
||||
}
|
||||
|
||||
public boolean hasMoreTokens()
|
||||
{
|
||||
return (index != -1);
|
||||
}
|
||||
|
||||
public String nextToken()
|
||||
{
|
||||
if (index == -1)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
String token;
|
||||
int end = oid.indexOf('.', index);
|
||||
|
||||
if (end == -1)
|
||||
{
|
||||
token = oid.substring(index);
|
||||
index = -1;
|
||||
return token;
|
||||
}
|
||||
|
||||
token = oid.substring(index, end);
|
||||
|
||||
index = end + 1;
|
||||
return token;
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1.bc;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERObjectIdentifier;
|
||||
|
||||
public interface BCObjectIdentifiers
|
||||
{
|
||||
/**
|
||||
* iso.org.dod.internet.private.enterprise.legion-of-the-bouncy-castle
|
||||
*
|
||||
* 1.3.6.1.4.1.22554
|
||||
*/
|
||||
public static final DERObjectIdentifier bc = new DERObjectIdentifier("1.3.6.1.4.1.22554");
|
||||
|
||||
/**
|
||||
* pbe(1) algorithms
|
||||
*/
|
||||
public static final DERObjectIdentifier bc_pbe = new DERObjectIdentifier(bc.getId() + ".1");
|
||||
|
||||
/**
|
||||
* SHA-1(1)
|
||||
*/
|
||||
public static final DERObjectIdentifier bc_pbe_sha1 = new DERObjectIdentifier(bc_pbe.getId() + ".1");
|
||||
|
||||
/**
|
||||
* SHA-2(2) . (SHA-256(1)|SHA-384(2)|SHA-512(3)|SHA-224(4))
|
||||
*/
|
||||
public static final DERObjectIdentifier bc_pbe_sha256 = new DERObjectIdentifier(bc_pbe.getId() + ".2.1");
|
||||
public static final DERObjectIdentifier bc_pbe_sha384 = new DERObjectIdentifier(bc_pbe.getId() + ".2.2");
|
||||
public static final DERObjectIdentifier bc_pbe_sha512 = new DERObjectIdentifier(bc_pbe.getId() + ".2.3");
|
||||
public static final DERObjectIdentifier bc_pbe_sha224 = new DERObjectIdentifier(bc_pbe.getId() + ".2.4");
|
||||
|
||||
/**
|
||||
* PKCS-5(1)|PKCS-12(2)
|
||||
*/
|
||||
public static final DERObjectIdentifier bc_pbe_sha1_pkcs5 = new DERObjectIdentifier(bc_pbe_sha1.getId() + ".1");
|
||||
public static final DERObjectIdentifier bc_pbe_sha1_pkcs12 = new DERObjectIdentifier(bc_pbe_sha1.getId() + ".2");
|
||||
|
||||
public static final DERObjectIdentifier bc_pbe_sha256_pkcs5 = new DERObjectIdentifier(bc_pbe_sha256.getId() + ".1");
|
||||
public static final DERObjectIdentifier bc_pbe_sha256_pkcs12 = new DERObjectIdentifier(bc_pbe_sha256.getId() + ".2");
|
||||
|
||||
/**
|
||||
* AES(1) . (CBC-128(2)|CBC-192(22)|CBC-256(42))
|
||||
*/
|
||||
public static final DERObjectIdentifier bc_pbe_sha1_pkcs12_aes128_cbc = new DERObjectIdentifier(bc_pbe_sha1_pkcs12.getId() + ".1.2");
|
||||
public static final DERObjectIdentifier bc_pbe_sha1_pkcs12_aes192_cbc = new DERObjectIdentifier(bc_pbe_sha1_pkcs12.getId() + ".1.22");
|
||||
public static final DERObjectIdentifier bc_pbe_sha1_pkcs12_aes256_cbc = new DERObjectIdentifier(bc_pbe_sha1_pkcs12.getId() + ".1.42");
|
||||
|
||||
public static final DERObjectIdentifier bc_pbe_sha256_pkcs12_aes128_cbc = new DERObjectIdentifier(bc_pbe_sha256_pkcs12.getId() + ".1.2");
|
||||
public static final DERObjectIdentifier bc_pbe_sha256_pkcs12_aes192_cbc = new DERObjectIdentifier(bc_pbe_sha256_pkcs12.getId() + ".1.22");
|
||||
public static final DERObjectIdentifier bc_pbe_sha256_pkcs12_aes256_cbc = new DERObjectIdentifier(bc_pbe_sha256_pkcs12.getId() + ".1.42");
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1.cmp;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Encodable;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1EncodableVector;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Sequence;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERSequence;
|
||||
|
||||
public class CAKeyUpdAnnContent
|
||||
extends ASN1Encodable
|
||||
{
|
||||
private CMPCertificate oldWithNew;
|
||||
private CMPCertificate newWithOld;
|
||||
private CMPCertificate newWithNew;
|
||||
|
||||
private CAKeyUpdAnnContent(ASN1Sequence seq)
|
||||
{
|
||||
oldWithNew = CMPCertificate.getInstance(seq.getObjectAt(0));
|
||||
newWithOld = CMPCertificate.getInstance(seq.getObjectAt(1));
|
||||
newWithNew = CMPCertificate.getInstance(seq.getObjectAt(2));
|
||||
}
|
||||
|
||||
public static CAKeyUpdAnnContent getInstance(Object o)
|
||||
{
|
||||
if (o instanceof CAKeyUpdAnnContent)
|
||||
{
|
||||
return (CAKeyUpdAnnContent)o;
|
||||
}
|
||||
|
||||
if (o instanceof ASN1Sequence)
|
||||
{
|
||||
return new CAKeyUpdAnnContent((ASN1Sequence)o);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
|
||||
}
|
||||
|
||||
public CMPCertificate getOldWithNew()
|
||||
{
|
||||
return oldWithNew;
|
||||
}
|
||||
|
||||
public CMPCertificate getNewWithOld()
|
||||
{
|
||||
return newWithOld;
|
||||
}
|
||||
|
||||
public CMPCertificate getNewWithNew()
|
||||
{
|
||||
return newWithNew;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* CAKeyUpdAnnContent ::= SEQUENCE {
|
||||
* oldWithNew CMPCertificate, -- old pub signed with new priv
|
||||
* newWithOld CMPCertificate, -- new pub signed with old priv
|
||||
* newWithNew CMPCertificate -- new pub signed with new priv
|
||||
* }
|
||||
* </pre>
|
||||
* @return a basic ASN.1 object representation.
|
||||
*/
|
||||
public DERObject toASN1Object()
|
||||
{
|
||||
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||
|
||||
v.add(oldWithNew);
|
||||
v.add(newWithOld);
|
||||
v.add(newWithNew);
|
||||
|
||||
return new DERSequence(v);
|
||||
}
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1.cmp;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Choice;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Encodable;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Sequence;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.x509.X509CertificateStructure;
|
||||
|
||||
public class CMPCertificate
|
||||
extends ASN1Encodable
|
||||
implements ASN1Choice
|
||||
{
|
||||
private X509CertificateStructure x509v3PKCert;
|
||||
|
||||
public CMPCertificate(X509CertificateStructure x509v3PKCert)
|
||||
{
|
||||
if (x509v3PKCert.getVersion() != 3)
|
||||
{
|
||||
throw new IllegalArgumentException("only version 3 certificates allowed");
|
||||
}
|
||||
|
||||
this.x509v3PKCert = x509v3PKCert;
|
||||
}
|
||||
|
||||
public static CMPCertificate getInstance(Object o)
|
||||
{
|
||||
if (o instanceof CMPCertificate)
|
||||
{
|
||||
return (CMPCertificate)o;
|
||||
}
|
||||
|
||||
if (o instanceof X509CertificateStructure)
|
||||
{
|
||||
return new CMPCertificate((X509CertificateStructure)o);
|
||||
}
|
||||
|
||||
if (o instanceof ASN1Sequence)
|
||||
{
|
||||
return new CMPCertificate(X509CertificateStructure.getInstance(o));
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
|
||||
}
|
||||
|
||||
public X509CertificateStructure getX509v3PKCert()
|
||||
{
|
||||
return x509v3PKCert;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* CMPCertificate ::= CHOICE {
|
||||
* x509v3PKCert Certificate
|
||||
* }
|
||||
* </pre>
|
||||
* @return a basic ASN.1 object representation.
|
||||
*/
|
||||
public DERObject toASN1Object()
|
||||
{
|
||||
return x509v3PKCert.toASN1Object();
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1.cmp;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Encodable;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Sequence;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.x509.CertificateList;
|
||||
|
||||
public class CRLAnnContent
|
||||
extends ASN1Encodable
|
||||
{
|
||||
private ASN1Sequence content;
|
||||
|
||||
private CRLAnnContent(ASN1Sequence seq)
|
||||
{
|
||||
content = seq;
|
||||
}
|
||||
|
||||
public static CRLAnnContent getInstance(Object o)
|
||||
{
|
||||
if (o instanceof CRLAnnContent)
|
||||
{
|
||||
return (CRLAnnContent)o;
|
||||
}
|
||||
|
||||
if (o instanceof ASN1Sequence)
|
||||
{
|
||||
return new CRLAnnContent((ASN1Sequence)o);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
|
||||
}
|
||||
|
||||
public CertificateList[] toCertificateListArray()
|
||||
{
|
||||
CertificateList[] result = new CertificateList[content.size()];
|
||||
|
||||
for (int i = 0; i != result.length; i++)
|
||||
{
|
||||
result[i] = CertificateList.getInstance(content.getObjectAt(i));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* CRLAnnContent ::= SEQUENCE OF CertificateList
|
||||
* </pre>
|
||||
* @return a basic ASN.1 object representation.
|
||||
*/
|
||||
public DERObject toASN1Object()
|
||||
{
|
||||
return content;
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1.cmp;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Encodable;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Sequence;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERObject;
|
||||
|
||||
public class CertConfirmContent
|
||||
extends ASN1Encodable
|
||||
{
|
||||
private ASN1Sequence content;
|
||||
|
||||
private CertConfirmContent(ASN1Sequence seq)
|
||||
{
|
||||
content = seq;
|
||||
}
|
||||
|
||||
public static CertConfirmContent getInstance(Object o)
|
||||
{
|
||||
if (o instanceof CertConfirmContent)
|
||||
{
|
||||
return (CertConfirmContent)o;
|
||||
}
|
||||
|
||||
if (o instanceof ASN1Sequence)
|
||||
{
|
||||
return new CertConfirmContent((ASN1Sequence)o);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
|
||||
}
|
||||
|
||||
public CertStatus[] toCertStatusArray()
|
||||
{
|
||||
CertStatus[] result = new CertStatus[content.size()];
|
||||
|
||||
for (int i = 0; i != result.length; i++)
|
||||
{
|
||||
result[i] = CertStatus.getInstance(content.getObjectAt(i));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* CertConfirmContent ::= SEQUENCE OF CertStatus
|
||||
* </pre>
|
||||
* @return a basic ASN.1 object representation.
|
||||
*/
|
||||
public DERObject toASN1Object()
|
||||
{
|
||||
return content;
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1.cmp;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Choice;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Encodable;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1TaggedObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERTaggedObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.crmf.EncryptedValue;
|
||||
|
||||
public class CertOrEncCert
|
||||
extends ASN1Encodable
|
||||
implements ASN1Choice
|
||||
{
|
||||
private CMPCertificate certificate;
|
||||
private EncryptedValue encryptedCert;
|
||||
|
||||
private CertOrEncCert(ASN1TaggedObject tagged)
|
||||
{
|
||||
if (tagged.getTagNo() == 0)
|
||||
{
|
||||
certificate = CMPCertificate.getInstance(tagged.getObject());
|
||||
}
|
||||
else if (tagged.getTagNo() == 1)
|
||||
{
|
||||
encryptedCert = EncryptedValue.getInstance(tagged.getObject());
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new IllegalArgumentException("unknown tag: " + tagged.getTagNo());
|
||||
}
|
||||
}
|
||||
|
||||
public static CertOrEncCert getInstance(Object o)
|
||||
{
|
||||
if (o instanceof CertOrEncCert)
|
||||
{
|
||||
return (CertOrEncCert)o;
|
||||
}
|
||||
|
||||
if (o instanceof ASN1TaggedObject)
|
||||
{
|
||||
return new CertOrEncCert((ASN1TaggedObject)o);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
|
||||
}
|
||||
|
||||
public CMPCertificate getCertificate()
|
||||
{
|
||||
return certificate;
|
||||
}
|
||||
|
||||
public EncryptedValue getEncryptedCert()
|
||||
{
|
||||
return encryptedCert;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* CertOrEncCert ::= CHOICE {
|
||||
* certificate [0] CMPCertificate,
|
||||
* encryptedCert [1] EncryptedValue
|
||||
* }
|
||||
* </pre>
|
||||
* @return a basic ASN.1 object representation.
|
||||
*/
|
||||
public DERObject toASN1Object()
|
||||
{
|
||||
if (certificate != null)
|
||||
{
|
||||
return new DERTaggedObject(true, 0, certificate);
|
||||
}
|
||||
|
||||
return new DERTaggedObject(true, 1, encryptedCert);
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1.cmp;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Encodable;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1EncodableVector;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Sequence;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1TaggedObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERSequence;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERTaggedObject;
|
||||
|
||||
public class CertRepMessage
|
||||
extends ASN1Encodable
|
||||
{
|
||||
private ASN1Sequence caPubs;
|
||||
private ASN1Sequence response;
|
||||
|
||||
private CertRepMessage(ASN1Sequence seq)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
if (seq.size() > 1)
|
||||
{
|
||||
caPubs = ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(index++), true);
|
||||
}
|
||||
|
||||
response = ASN1Sequence.getInstance(seq.getObjectAt(index));
|
||||
}
|
||||
|
||||
public static CertRepMessage getInstance(Object o)
|
||||
{
|
||||
if (o instanceof CertRepMessage)
|
||||
{
|
||||
return (CertRepMessage)o;
|
||||
}
|
||||
|
||||
if (o instanceof ASN1Sequence)
|
||||
{
|
||||
return new CertRepMessage((ASN1Sequence)o);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
|
||||
}
|
||||
|
||||
public CMPCertificate[] getCaPubs()
|
||||
{
|
||||
if (caPubs == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
CMPCertificate[] results = new CMPCertificate[caPubs.size()];
|
||||
|
||||
for (int i = 0; i != results.length; i++)
|
||||
{
|
||||
results[i] = CMPCertificate.getInstance(caPubs.getObjectAt(i));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
public CertResponse[] getResponse()
|
||||
{
|
||||
CertResponse[] results = new CertResponse[response.size()];
|
||||
|
||||
for (int i = 0; i != results.length; i++)
|
||||
{
|
||||
results[i] = CertResponse.getInstance(response.getObjectAt(i));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* CertRepMessage ::= SEQUENCE {
|
||||
* caPubs [1] SEQUENCE SIZE (1..MAX) OF CMPCertificate
|
||||
* OPTIONAL,
|
||||
* response SEQUENCE OF CertResponse
|
||||
* }
|
||||
* </pre>
|
||||
* @return a basic ASN.1 object representation.
|
||||
*/
|
||||
public DERObject toASN1Object()
|
||||
{
|
||||
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||
|
||||
if (caPubs != null)
|
||||
{
|
||||
v.add(new DERTaggedObject(true, 1, caPubs));
|
||||
}
|
||||
|
||||
v.add(response);
|
||||
|
||||
return new DERSequence(v);
|
||||
}
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1.cmp;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Encodable;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1EncodableVector;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1OctetString;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Sequence;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DEREncodable;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERInteger;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERSequence;
|
||||
|
||||
public class CertResponse
|
||||
extends ASN1Encodable
|
||||
{
|
||||
private DERInteger certReqId;
|
||||
private PKIStatusInfo status;
|
||||
private CertifiedKeyPair certifiedKeyPair;
|
||||
private ASN1OctetString rspInfo;
|
||||
|
||||
private CertResponse(ASN1Sequence seq)
|
||||
{
|
||||
certReqId = DERInteger.getInstance(seq.getObjectAt(0));
|
||||
status = PKIStatusInfo.getInstance(seq.getObjectAt(1));
|
||||
|
||||
if (seq.size() >= 3)
|
||||
{
|
||||
if (seq.size() == 3)
|
||||
{
|
||||
DEREncodable o = seq.getObjectAt(2);
|
||||
if (o instanceof ASN1OctetString)
|
||||
{
|
||||
rspInfo = ASN1OctetString.getInstance(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
certifiedKeyPair = CertifiedKeyPair.getInstance(o);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
certifiedKeyPair = CertifiedKeyPair.getInstance(seq.getObjectAt(2));
|
||||
rspInfo = ASN1OctetString.getInstance(seq.getObjectAt(3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static CertResponse getInstance(Object o)
|
||||
{
|
||||
if (o instanceof CertResponse)
|
||||
{
|
||||
return (CertResponse)o;
|
||||
}
|
||||
|
||||
if (o instanceof ASN1Sequence)
|
||||
{
|
||||
return new CertResponse((ASN1Sequence)o);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
|
||||
}
|
||||
|
||||
public DERInteger getCertReqId()
|
||||
{
|
||||
return certReqId;
|
||||
}
|
||||
|
||||
public PKIStatusInfo getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public CertifiedKeyPair getCertifiedKeyPair()
|
||||
{
|
||||
return certifiedKeyPair;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* CertResponse ::= SEQUENCE {
|
||||
* certReqId INTEGER,
|
||||
* -- to match this response with corresponding request (a value
|
||||
* -- of -1 is to be used if certReqId is not specified in the
|
||||
* -- corresponding request)
|
||||
* status PKIStatusInfo,
|
||||
* certifiedKeyPair CertifiedKeyPair OPTIONAL,
|
||||
* rspInfo OCTET STRING OPTIONAL
|
||||
* -- analogous to the id-regInfo-utf8Pairs string defined
|
||||
* -- for regInfo in CertReqMsg [CRMF]
|
||||
* }
|
||||
* </pre>
|
||||
* @return a basic ASN.1 object representation.
|
||||
*/
|
||||
public DERObject toASN1Object()
|
||||
{
|
||||
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||
|
||||
v.add(certReqId);
|
||||
v.add(status);
|
||||
|
||||
if (certifiedKeyPair != null)
|
||||
{
|
||||
v.add(certifiedKeyPair);
|
||||
}
|
||||
|
||||
if (rspInfo != null)
|
||||
{
|
||||
v.add(rspInfo);
|
||||
}
|
||||
|
||||
return new DERSequence(v);
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1.cmp;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Encodable;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1EncodableVector;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1OctetString;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Sequence;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERInteger;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERSequence;
|
||||
|
||||
public class CertStatus
|
||||
extends ASN1Encodable
|
||||
{
|
||||
private ASN1OctetString certHash;
|
||||
private DERInteger certReqId;
|
||||
private PKIStatusInfo statusInfo;
|
||||
|
||||
private CertStatus(ASN1Sequence seq)
|
||||
{
|
||||
certHash = ASN1OctetString.getInstance(seq.getObjectAt(0));
|
||||
certReqId = DERInteger.getInstance(seq.getObjectAt(1));
|
||||
|
||||
if (seq.size() > 2)
|
||||
{
|
||||
statusInfo = PKIStatusInfo.getInstance(seq.getObjectAt(2));
|
||||
}
|
||||
}
|
||||
|
||||
public static CertStatus getInstance(Object o)
|
||||
{
|
||||
if (o instanceof CertStatus)
|
||||
{
|
||||
return (CertStatus)o;
|
||||
}
|
||||
|
||||
if (o instanceof ASN1Sequence)
|
||||
{
|
||||
return new CertStatus((ASN1Sequence)o);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
|
||||
}
|
||||
|
||||
public DERInteger getCertReqId()
|
||||
{
|
||||
return certReqId;
|
||||
}
|
||||
|
||||
public PKIStatusInfo getStatusInfo()
|
||||
{
|
||||
return statusInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* CertStatus ::= SEQUENCE {
|
||||
* certHash OCTET STRING,
|
||||
* -- the hash of the certificate, using the same hash algorithm
|
||||
* -- as is used to create and verify the certificate signature
|
||||
* certReqId INTEGER,
|
||||
* -- to match this confirmation with the corresponding req/rep
|
||||
* statusInfo PKIStatusInfo OPTIONAL
|
||||
* }
|
||||
* </pre>
|
||||
* @return a basic ASN.1 object representation.
|
||||
*/
|
||||
public DERObject toASN1Object()
|
||||
{
|
||||
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||
|
||||
v.add(certHash);
|
||||
v.add(certReqId);
|
||||
|
||||
if (statusInfo != null)
|
||||
{
|
||||
v.add(statusInfo);
|
||||
}
|
||||
|
||||
return new DERSequence(v);
|
||||
}
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1.cmp;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Encodable;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1EncodableVector;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Sequence;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1TaggedObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERSequence;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERTaggedObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.crmf.EncryptedValue;
|
||||
import com.google.bitcoin.bouncycastle.asn1.crmf.PKIPublicationInfo;
|
||||
|
||||
public class CertifiedKeyPair
|
||||
extends ASN1Encodable
|
||||
{
|
||||
private CertOrEncCert certOrEncCert;
|
||||
private EncryptedValue privateKey;
|
||||
private PKIPublicationInfo publicationInfo;
|
||||
|
||||
private CertifiedKeyPair(ASN1Sequence seq)
|
||||
{
|
||||
certOrEncCert = CertOrEncCert.getInstance(seq.getObjectAt(0));
|
||||
|
||||
if (seq.size() >= 2)
|
||||
{
|
||||
if (seq.size() == 2)
|
||||
{
|
||||
ASN1TaggedObject tagged = ASN1TaggedObject.getInstance(seq.getObjectAt(1));
|
||||
if (tagged.getTagNo() == 0)
|
||||
{
|
||||
privateKey = EncryptedValue.getInstance(tagged.getObject());
|
||||
}
|
||||
else
|
||||
{
|
||||
publicationInfo = PKIPublicationInfo.getInstance(tagged.getObject());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
privateKey = EncryptedValue.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(1)));
|
||||
publicationInfo = PKIPublicationInfo.getInstance(ASN1TaggedObject.getInstance(seq.getObjectAt(2)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static CertifiedKeyPair getInstance(Object o)
|
||||
{
|
||||
if (o instanceof CertifiedKeyPair)
|
||||
{
|
||||
return (CertifiedKeyPair)o;
|
||||
}
|
||||
|
||||
if (o instanceof ASN1Sequence)
|
||||
{
|
||||
return new CertifiedKeyPair((ASN1Sequence)o);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
|
||||
}
|
||||
|
||||
public CertOrEncCert getCertOrEncCert()
|
||||
{
|
||||
return certOrEncCert;
|
||||
}
|
||||
|
||||
public EncryptedValue getPrivateKey()
|
||||
{
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
public PKIPublicationInfo getPublicationInfo()
|
||||
{
|
||||
return publicationInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* CertifiedKeyPair ::= SEQUENCE {
|
||||
* certOrEncCert CertOrEncCert,
|
||||
* privateKey [0] EncryptedValue OPTIONAL,
|
||||
* -- see [CRMF] for comment on encoding
|
||||
* publicationInfo [1] PKIPublicationInfo OPTIONAL
|
||||
* }
|
||||
* </pre>
|
||||
* @return a basic ASN.1 object representation.
|
||||
*/
|
||||
public DERObject toASN1Object()
|
||||
{
|
||||
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||
|
||||
v.add(certOrEncCert);
|
||||
|
||||
if (privateKey != null)
|
||||
{
|
||||
v.add(new DERTaggedObject(true, 0, privateKey));
|
||||
}
|
||||
|
||||
if (publicationInfo != null)
|
||||
{
|
||||
v.add(new DERTaggedObject(true, 1, publicationInfo));
|
||||
}
|
||||
|
||||
return new DERSequence(v);
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1.cmp;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Encodable;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1EncodableVector;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1OctetString;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Sequence;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERSequence;
|
||||
import com.google.bitcoin.bouncycastle.asn1.x509.AlgorithmIdentifier;
|
||||
|
||||
public class Challenge
|
||||
extends ASN1Encodable
|
||||
{
|
||||
private AlgorithmIdentifier owf;
|
||||
private ASN1OctetString witness;
|
||||
private ASN1OctetString challenge;
|
||||
|
||||
private Challenge(ASN1Sequence seq)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
if (seq.size() == 3)
|
||||
{
|
||||
owf = AlgorithmIdentifier.getInstance(seq.getObjectAt(index++));
|
||||
}
|
||||
|
||||
witness = ASN1OctetString.getInstance(seq.getObjectAt(index++));
|
||||
challenge = ASN1OctetString.getInstance(seq.getObjectAt(index));
|
||||
}
|
||||
|
||||
public static Challenge getInstance(Object o)
|
||||
{
|
||||
if (o instanceof Challenge)
|
||||
{
|
||||
return (Challenge)o;
|
||||
}
|
||||
|
||||
if (o instanceof ASN1Sequence)
|
||||
{
|
||||
return new Challenge((ASN1Sequence)o);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
|
||||
}
|
||||
|
||||
public AlgorithmIdentifier getOwf()
|
||||
{
|
||||
return owf;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Challenge ::= SEQUENCE {
|
||||
* owf AlgorithmIdentifier OPTIONAL,
|
||||
*
|
||||
* -- MUST be present in the first Challenge; MAY be omitted in
|
||||
* -- any subsequent Challenge in POPODecKeyChallContent (if
|
||||
* -- omitted, then the owf used in the immediately preceding
|
||||
* -- Challenge is to be used).
|
||||
*
|
||||
* witness OCTET STRING,
|
||||
* -- the result of applying the one-way function (owf) to a
|
||||
* -- randomly-generated INTEGER, A. [Note that a different
|
||||
* -- INTEGER MUST be used for each Challenge.]
|
||||
* challenge OCTET STRING
|
||||
* -- the encryption (under the public key for which the cert.
|
||||
* -- request is being made) of Rand, where Rand is specified as
|
||||
* -- Rand ::= SEQUENCE {
|
||||
* -- int INTEGER,
|
||||
* -- - the randomly-generated INTEGER A (above)
|
||||
* -- sender GeneralName
|
||||
* -- - the sender's name (as included in PKIHeader)
|
||||
* -- }
|
||||
* }
|
||||
* </pre>
|
||||
* @return a basic ASN.1 object representation.
|
||||
*/
|
||||
public DERObject toASN1Object()
|
||||
{
|
||||
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||
|
||||
addOptional(v, owf);
|
||||
v.add(witness);
|
||||
v.add(challenge);
|
||||
|
||||
return new DERSequence(v);
|
||||
}
|
||||
|
||||
private void addOptional(ASN1EncodableVector v, ASN1Encodable obj)
|
||||
{
|
||||
if (obj != null)
|
||||
{
|
||||
v.add(obj);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
package com.google.bitcoin.bouncycastle.asn1.cmp;
|
||||
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Encodable;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1EncodableVector;
|
||||
import com.google.bitcoin.bouncycastle.asn1.ASN1Sequence;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERInteger;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERObject;
|
||||
import com.google.bitcoin.bouncycastle.asn1.DERSequence;
|
||||
|
||||
import java.util.Enumeration;
|
||||
|
||||
public class ErrorMsgContent
|
||||
extends ASN1Encodable
|
||||
{
|
||||
private PKIStatusInfo pKIStatusInfo;
|
||||
private DERInteger errorCode;
|
||||
private PKIFreeText errorDetails;
|
||||
|
||||
private ErrorMsgContent(ASN1Sequence seq)
|
||||
{
|
||||
Enumeration en = seq.getObjects();
|
||||
|
||||
pKIStatusInfo = PKIStatusInfo.getInstance(en.nextElement());
|
||||
|
||||
while (en.hasMoreElements())
|
||||
{
|
||||
Object o = en.nextElement();
|
||||
|
||||
if (o instanceof DERInteger)
|
||||
{
|
||||
errorCode = DERInteger.getInstance(o);
|
||||
}
|
||||
else
|
||||
{
|
||||
errorDetails = PKIFreeText.getInstance(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static ErrorMsgContent getInstance(Object o)
|
||||
{
|
||||
if (o instanceof ErrorMsgContent)
|
||||
{
|
||||
return (ErrorMsgContent)o;
|
||||
}
|
||||
|
||||
if (o instanceof ASN1Sequence)
|
||||
{
|
||||
return new ErrorMsgContent((ASN1Sequence)o);
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Invalid object: " + o.getClass().getName());
|
||||
}
|
||||
|
||||
public PKIStatusInfo getPKIStatusInfo()
|
||||
{
|
||||
return pKIStatusInfo;
|
||||
}
|
||||
|
||||
public DERInteger getErrorCode()
|
||||
{
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
public PKIFreeText getErrorDetails()
|
||||
{
|
||||
return errorDetails;
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* ErrorMsgContent ::= SEQUENCE {
|
||||
* pKIStatusInfo PKIStatusInfo,
|
||||
* errorCode INTEGER OPTIONAL,
|
||||
* -- implementation-specific error codes
|
||||
* errorDetails PKIFreeText OPTIONAL
|
||||
* -- implementation-specific error details
|
||||
* }
|
||||
* </pre>
|
||||
* @return a basic ASN.1 object representation.
|
||||
*/
|
||||
public DERObject toASN1Object()
|
||||
{
|
||||
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||
|
||||
v.add(pKIStatusInfo);
|
||||
addOptional(v, errorCode);
|
||||
addOptional(v, errorDetails);
|
||||
|
||||
return new DERSequence(v);
|
||||
}
|
||||
|
||||
private void addOptional(ASN1EncodableVector v, ASN1Encodable obj)
|
||||
{
|
||||
if (obj != null)
|
||||
{
|
||||
v.add(obj);
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user