Replace spongycastle submodule with checked in code
This commit is contained in:
parent
4258ea1c40
commit
93c5bd4a95
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -10,10 +10,6 @@
|
|||||||
path = extern/Support
|
path = extern/Support
|
||||||
url = https://android.googlesource.com/platform/frameworks/support
|
url = https://android.googlesource.com/platform/frameworks/support
|
||||||
ignore = dirty
|
ignore = dirty
|
||||||
[submodule "extern/spongycastle"]
|
|
||||||
path = extern/spongycastle
|
|
||||||
url = https://github.com/open-keychain/spongycastle
|
|
||||||
ignore = dirty
|
|
||||||
[submodule "extern/nanohttpd"]
|
[submodule "extern/nanohttpd"]
|
||||||
path = extern/nanohttpd
|
path = extern/nanohttpd
|
||||||
url = https://github.com/eighthave/nanohttpd
|
url = https://github.com/eighthave/nanohttpd
|
||||||
|
1
extern/spongycastle
vendored
1
extern/spongycastle
vendored
@ -1 +0,0 @@
|
|||||||
Subproject commit 9e4fb80c4f8efb8a0f8fd0c1cc1e74a421d1eb7e
|
|
22
extern/spongycastle/LICENSE.html
vendored
Normal file
22
extern/spongycastle/LICENSE.html
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<html>
|
||||||
|
<body bgcolor=#ffffff>
|
||||||
|
|
||||||
|
Copyright (c) 2000-2013 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
|
||||||
|
<p>
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||||
|
and associated documentation files (the "Software"), to deal in the Software without restriction,
|
||||||
|
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.
|
||||||
|
</body>
|
||||||
|
</html>
|
100
extern/spongycastle/build.gradle
vendored
Normal file
100
extern/spongycastle/build.gradle
vendored
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
allprojects {
|
||||||
|
apply plugin: 'idea'
|
||||||
|
}
|
||||||
|
|
||||||
|
ext {
|
||||||
|
bcTestDataHome = file('core/src/test/data').absolutePath
|
||||||
|
}
|
||||||
|
|
||||||
|
subprojects {
|
||||||
|
apply plugin: 'eclipse'
|
||||||
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'maven'
|
||||||
|
apply plugin: 'signing'
|
||||||
|
|
||||||
|
group = 'com.madgag.spongycastle'
|
||||||
|
|
||||||
|
task javadocJar(type: Jar, dependsOn: javadoc) {
|
||||||
|
classifier = 'javadoc'
|
||||||
|
from 'build/docs/javadoc'
|
||||||
|
}
|
||||||
|
|
||||||
|
task sourcesJar(type: Jar) {
|
||||||
|
from sourceSets.main.allSource
|
||||||
|
classifier = 'sources'
|
||||||
|
}
|
||||||
|
|
||||||
|
artifacts {
|
||||||
|
archives jar
|
||||||
|
|
||||||
|
archives javadocJar
|
||||||
|
archives sourcesJar
|
||||||
|
}
|
||||||
|
|
||||||
|
if (project.hasProperty("signing.keyId")) {
|
||||||
|
signing {
|
||||||
|
sign configurations.archives
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (project.hasProperty("sonatypeUsername")) {
|
||||||
|
uploadArchives {
|
||||||
|
repositories {
|
||||||
|
mavenDeployer {
|
||||||
|
beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
|
||||||
|
|
||||||
|
repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
|
||||||
|
authentication(userName: sonatypeUsername, password: sonatypePassword)
|
||||||
|
}
|
||||||
|
|
||||||
|
pom.project {
|
||||||
|
name 'Spongy Castle'
|
||||||
|
packaging 'jar'
|
||||||
|
description 'Spongy Castle is a package-rename (org.bouncycastle.* to org.spongycastle.*) of Bouncy Castle\n' +
|
||||||
|
'intended for the Android platform. Android unfortunately ships with a stripped-down version of\n' +
|
||||||
|
'Bouncy Castle, which prevents easy upgrades - Spongy Castle overcomes this and provides a full,\n' +
|
||||||
|
'up-to-date version of the Bouncy Castle cryptographic libs.'
|
||||||
|
url 'http://rtyley.github.io/spongycastle/'
|
||||||
|
|
||||||
|
scm {
|
||||||
|
url 'scm:git@github.com:rtyley/spongycastle.git'
|
||||||
|
connection 'scm:git@github.com:rtyley/spongycastle.git'
|
||||||
|
developerConnection 'scm:git@github.com:rtyley/spongycastle.git'
|
||||||
|
}
|
||||||
|
|
||||||
|
licenses {
|
||||||
|
license {
|
||||||
|
name 'Bouncy Castle Licence'
|
||||||
|
url 'http://www.bouncycastle.org/licence.html'
|
||||||
|
distribution 'repo'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
developers {
|
||||||
|
developer {
|
||||||
|
id 'rtyley'
|
||||||
|
name 'Roberto Tyley'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testCompile group: 'junit', name: 'junit', version: '4.11'
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceCompatibility = 1.5
|
||||||
|
targetCompatibility = 1.5
|
||||||
|
version = '1.50.0.0'
|
||||||
|
|
||||||
|
test {
|
||||||
|
systemProperty 'bc.test.data.home', bcTestDataHome
|
||||||
|
}
|
||||||
|
}
|
9
extern/spongycastle/core/build.gradle
vendored
Normal file
9
extern/spongycastle/core/build.gradle
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
apply plugin: 'java'
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testCompile group: 'junit', name: 'junit', version: '4.11'
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceCompatibility = 1.5
|
||||||
|
targetCompatibility = 1.5
|
||||||
|
version = '1.50.0.0'
|
56
extern/spongycastle/core/src/main/j2me/java/io/FilterInputStream.java
vendored
Normal file
56
extern/spongycastle/core/src/main/j2me/java/io/FilterInputStream.java
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package java.io;
|
||||||
|
|
||||||
|
public class FilterInputStream extends InputStream
|
||||||
|
{
|
||||||
|
protected InputStream in;
|
||||||
|
|
||||||
|
protected FilterInputStream(InputStream underlying)
|
||||||
|
{
|
||||||
|
in = underlying;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read() throws IOException
|
||||||
|
{
|
||||||
|
return in.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read(byte[] b) throws IOException
|
||||||
|
{
|
||||||
|
return read(b, 0, b.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read(byte[] b, int offset, int length) throws IOException
|
||||||
|
{
|
||||||
|
return in.read(b, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long skip(long n) throws IOException
|
||||||
|
{
|
||||||
|
return in.skip(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int available() throws IOException
|
||||||
|
{
|
||||||
|
return in.available();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException
|
||||||
|
{
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mark(int readlimit)
|
||||||
|
{
|
||||||
|
in.mark(readlimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() throws IOException
|
||||||
|
{
|
||||||
|
in.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean markSupported()
|
||||||
|
{
|
||||||
|
return in.markSupported();
|
||||||
|
}
|
||||||
|
}
|
39
extern/spongycastle/core/src/main/j2me/java/io/FilterOutputStream.java
vendored
Normal file
39
extern/spongycastle/core/src/main/j2me/java/io/FilterOutputStream.java
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package java.io;
|
||||||
|
|
||||||
|
public class FilterOutputStream extends OutputStream
|
||||||
|
{
|
||||||
|
protected OutputStream out;
|
||||||
|
|
||||||
|
protected FilterOutputStream(OutputStream underlying)
|
||||||
|
{
|
||||||
|
out = underlying;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(int b) throws IOException
|
||||||
|
{
|
||||||
|
out.write(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(byte[] b) throws IOException
|
||||||
|
{
|
||||||
|
write(b, 0, b.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(byte[] b, int offset, int length) throws IOException
|
||||||
|
{
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
write(b[offset + i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush() throws IOException
|
||||||
|
{
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException
|
||||||
|
{
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
}
|
3272
extern/spongycastle/core/src/main/j2me/java/math/BigInteger.java
vendored
Normal file
3272
extern/spongycastle/core/src/main/j2me/java/math/BigInteger.java
vendored
Normal file
File diff suppressed because it is too large
Load Diff
141
extern/spongycastle/core/src/main/j2me/java/security/SecureRandom.java
vendored
Normal file
141
extern/spongycastle/core/src/main/j2me/java/security/SecureRandom.java
vendored
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
package java.security;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
import org.spongycastle.crypto.digests.SHA1Digest;
|
||||||
|
import org.spongycastle.crypto.digests.SHA256Digest;
|
||||||
|
import org.spongycastle.crypto.prng.RandomGenerator;
|
||||||
|
import org.spongycastle.crypto.prng.DigestRandomGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of SecureRandom specifically for the light-weight API, JDK
|
||||||
|
* 1.0, and the J2ME. Random generation is based on the traditional SHA1 with
|
||||||
|
* counter. Calling setSeed will always increase the entropy of the hash.
|
||||||
|
* <p>
|
||||||
|
* <b>Do not use this class without calling setSeed at least once</b>! There
|
||||||
|
* are some example seed generators in the org.spongycastle.prng package.
|
||||||
|
*/
|
||||||
|
public class SecureRandom extends java.util.Random
|
||||||
|
{
|
||||||
|
// Note: all objects of this class should be deriving their random data from
|
||||||
|
// a single generator appropriate to the digest being used.
|
||||||
|
private static final RandomGenerator sha1Generator = new DigestRandomGenerator(new SHA1Digest());
|
||||||
|
private static final RandomGenerator sha256Generator = new DigestRandomGenerator(new SHA256Digest());
|
||||||
|
|
||||||
|
protected RandomGenerator generator;
|
||||||
|
|
||||||
|
// public constructors
|
||||||
|
public SecureRandom()
|
||||||
|
{
|
||||||
|
this(sha1Generator);
|
||||||
|
setSeed(System.currentTimeMillis());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SecureRandom(byte[] inSeed)
|
||||||
|
{
|
||||||
|
this(sha1Generator);
|
||||||
|
setSeed(inSeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SecureRandom(
|
||||||
|
RandomGenerator generator)
|
||||||
|
{
|
||||||
|
super(0);
|
||||||
|
this.generator = generator;
|
||||||
|
}
|
||||||
|
|
||||||
|
// protected constructors
|
||||||
|
// protected SecureRandom(SecureRandomSpi srs, Provider provider);
|
||||||
|
|
||||||
|
// public class methods
|
||||||
|
public static SecureRandom getInstance(String algorithm)
|
||||||
|
{
|
||||||
|
if (algorithm.equals("SHA1PRNG"))
|
||||||
|
{
|
||||||
|
return new SecureRandom(sha1Generator);
|
||||||
|
}
|
||||||
|
if (algorithm.equals("SHA256PRNG"))
|
||||||
|
{
|
||||||
|
return new SecureRandom(sha256Generator);
|
||||||
|
}
|
||||||
|
return new SecureRandom(); // follow old behaviour
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SecureRandom getInstance(String algorithm, String provider)
|
||||||
|
{
|
||||||
|
return getInstance(algorithm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] getSeed(int numBytes)
|
||||||
|
{
|
||||||
|
byte[] rv = new byte[numBytes];
|
||||||
|
|
||||||
|
sha1Generator.addSeedMaterial(System.currentTimeMillis());
|
||||||
|
sha1Generator.nextBytes(rv);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public instance methods
|
||||||
|
public byte[] generateSeed(int numBytes)
|
||||||
|
{
|
||||||
|
byte[] rv = new byte[numBytes];
|
||||||
|
|
||||||
|
nextBytes(rv);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public final Provider getProvider();
|
||||||
|
public void setSeed(byte[] inSeed)
|
||||||
|
{
|
||||||
|
generator.addSeedMaterial(inSeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// public methods overriding random
|
||||||
|
public void nextBytes(byte[] bytes)
|
||||||
|
{
|
||||||
|
generator.nextBytes(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSeed(long rSeed)
|
||||||
|
{
|
||||||
|
if (rSeed != 0) // to avoid problems with Random calling setSeed in construction
|
||||||
|
{
|
||||||
|
generator.addSeedMaterial(rSeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int nextInt()
|
||||||
|
{
|
||||||
|
byte[] intBytes = new byte[4];
|
||||||
|
|
||||||
|
nextBytes(intBytes);
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
result = (result << 8) + (intBytes[i] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final int next(int numBits)
|
||||||
|
{
|
||||||
|
int size = (numBits + 7) / 8;
|
||||||
|
byte[] bytes = new byte[size];
|
||||||
|
|
||||||
|
nextBytes(bytes);
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
result = (result << 8) + (bytes[i] & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result & ((1 << numBits) - 1);
|
||||||
|
}
|
||||||
|
}
|
261
extern/spongycastle/core/src/main/j2me/java/util/AbstractCollection.java
vendored
Normal file
261
extern/spongycastle/core/src/main/j2me/java/util/AbstractCollection.java
vendored
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public abstract class AbstractCollection
|
||||||
|
implements Collection
|
||||||
|
{
|
||||||
|
protected AbstractCollection()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Iterator iterator();
|
||||||
|
|
||||||
|
public abstract int size();
|
||||||
|
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Object o)
|
||||||
|
{
|
||||||
|
Iterator it = iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
Object e = it.next();
|
||||||
|
if (o == null)
|
||||||
|
{
|
||||||
|
if (e == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (o.equals(e))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] toArray()
|
||||||
|
{
|
||||||
|
Object[] arObjects = new Object[size()];
|
||||||
|
Iterator it = iterator();
|
||||||
|
int i = 0;
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
arObjects[i++] = it.next();
|
||||||
|
}
|
||||||
|
return arObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] toArray(Object[] a)
|
||||||
|
throws NullPointerException, ArrayStoreException
|
||||||
|
//TODO: Check if this is realy compatible to SUN!!!
|
||||||
|
{
|
||||||
|
if (a == null)
|
||||||
|
{
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEmpty())
|
||||||
|
{
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
Object[] arObjects = null;
|
||||||
|
int size = size();
|
||||||
|
if (a.length < size)
|
||||||
|
{
|
||||||
|
Iterator it = iterator();
|
||||||
|
Object o = it.next();
|
||||||
|
if (o == null) //no object or object is null
|
||||||
|
{
|
||||||
|
throw new ArrayStoreException(); //correct ?
|
||||||
|
}
|
||||||
|
throw new ArrayStoreException("please pass array of correct size");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arObjects = a;
|
||||||
|
if (a.length > size)
|
||||||
|
{
|
||||||
|
arObjects[size] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator it = iterator();
|
||||||
|
int i = 0;
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
Object o = it.next();
|
||||||
|
arObjects[i++] = o;
|
||||||
|
}
|
||||||
|
return arObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean add(Object o)
|
||||||
|
throws RuntimeException, NullPointerException, ClassCastException, IllegalArgumentException
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean remove(Object o)
|
||||||
|
throws RuntimeException
|
||||||
|
{
|
||||||
|
Iterator it = iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
Object e = it.next();
|
||||||
|
if (o == null)
|
||||||
|
{
|
||||||
|
if (e == null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
catch (RuntimeException ue)
|
||||||
|
{
|
||||||
|
throw ue;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (o.equals(e))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
catch (RuntimeException ue)
|
||||||
|
{
|
||||||
|
throw ue;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsAll(Collection c)
|
||||||
|
{
|
||||||
|
Iterator it = c.iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
if (!contains(it.next()))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addAll(Collection c)
|
||||||
|
throws RuntimeException
|
||||||
|
{
|
||||||
|
Iterator it = c.iterator();
|
||||||
|
boolean ret = false;
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ret |= add(it.next());
|
||||||
|
}
|
||||||
|
catch (RuntimeException ue)
|
||||||
|
{
|
||||||
|
throw ue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removeAll(Collection c)
|
||||||
|
throws RuntimeException
|
||||||
|
{
|
||||||
|
Iterator it = iterator();
|
||||||
|
boolean ret = false;
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
if (c.contains(it.next()))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
catch (RuntimeException ue)
|
||||||
|
{
|
||||||
|
throw ue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean retainAll(Collection c)
|
||||||
|
throws RuntimeException
|
||||||
|
{
|
||||||
|
Iterator it = iterator();
|
||||||
|
boolean ret = false;
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
if (!c.contains(it.next()))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
it.remove();
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
catch (RuntimeException ue)
|
||||||
|
{
|
||||||
|
throw ue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
throws RuntimeException
|
||||||
|
{
|
||||||
|
Iterator it = iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
it.next();
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
catch (RuntimeException ue)
|
||||||
|
{
|
||||||
|
throw ue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuffer ret = new StringBuffer("[");
|
||||||
|
Iterator it = iterator();
|
||||||
|
if (it.hasNext())
|
||||||
|
{
|
||||||
|
ret.append(String.valueOf(it.next()));
|
||||||
|
}
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
ret.append(", ");
|
||||||
|
ret.append(String.valueOf(it.next()));
|
||||||
|
|
||||||
|
}
|
||||||
|
ret.append("]");
|
||||||
|
return ret.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
304
extern/spongycastle/core/src/main/j2me/java/util/AbstractList.java
vendored
Normal file
304
extern/spongycastle/core/src/main/j2me/java/util/AbstractList.java
vendored
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public abstract class AbstractList
|
||||||
|
extends AbstractCollection
|
||||||
|
implements List
|
||||||
|
{
|
||||||
|
protected AbstractList al = this;
|
||||||
|
|
||||||
|
|
||||||
|
protected AbstractList()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean add(Object o)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
add(size(), o);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (RuntimeException ue)
|
||||||
|
{
|
||||||
|
throw ue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Object get(int index)
|
||||||
|
throws IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
public Object set(int index, Object element)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(int index, Object element)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object remove(int index)
|
||||||
|
throws RuntimeException, IndexOutOfBoundsException
|
||||||
|
{
|
||||||
|
Object o = get(index);
|
||||||
|
|
||||||
|
removeRange(index, index + 1);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int indexOf(Object o)
|
||||||
|
{
|
||||||
|
ListIterator li = listIterator();
|
||||||
|
Object e;
|
||||||
|
while (li.hasNext())
|
||||||
|
{
|
||||||
|
int index = li.nextIndex();
|
||||||
|
e = li.next();
|
||||||
|
|
||||||
|
if (o == null)
|
||||||
|
{
|
||||||
|
if (e == null)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (o.equals(e))
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int lastIndexOf(Object o)
|
||||||
|
{
|
||||||
|
ListIterator li = listIterator(size());
|
||||||
|
while (li.hasPrevious())
|
||||||
|
{
|
||||||
|
int index = li.previousIndex();
|
||||||
|
Object e = li.previous();
|
||||||
|
if (o == null)
|
||||||
|
{
|
||||||
|
if (e == null)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (o.equals(e))
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
throws RuntimeException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
removeRange(0, size());
|
||||||
|
}
|
||||||
|
catch (RuntimeException ue)
|
||||||
|
{
|
||||||
|
throw ue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addAll(int index, Collection c)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException
|
||||||
|
{
|
||||||
|
Iterator it = c.iterator();
|
||||||
|
boolean ret = false;
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
add(index++, it.next());
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
catch (RuntimeException ue)
|
||||||
|
{
|
||||||
|
throw ue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator iterator()
|
||||||
|
{
|
||||||
|
return new AbstractListIterator(this, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListIterator listIterator()
|
||||||
|
{
|
||||||
|
return listIterator(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListIterator listIterator(int index)
|
||||||
|
throws IndexOutOfBoundsException
|
||||||
|
{
|
||||||
|
if (index < 0 || index > size())
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
return new AbstractListListIterator(this, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List subList(int fromIndex, int toIndex)
|
||||||
|
throws IndexOutOfBoundsException, IllegalArgumentException
|
||||||
|
{
|
||||||
|
if (fromIndex < 0 || toIndex > size())
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
if (fromIndex > toIndex)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
return (List)new Sublist(this, fromIndex, toIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
if (o == this)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(o instanceof List))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Iterator it1 = iterator();
|
||||||
|
Iterator it2 = ((List)o).iterator();
|
||||||
|
while (it1.hasNext())
|
||||||
|
{
|
||||||
|
if (!it2.hasNext())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Object e1 = it1.next();
|
||||||
|
Object e2 = it2.next();
|
||||||
|
if (e1 == null)
|
||||||
|
{
|
||||||
|
if (e2 != null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!e1.equals(e2))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
int hashCode = 1;
|
||||||
|
Iterator it = iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
Object o = it.next();
|
||||||
|
hashCode = 31 * hashCode + (o == null ? 0 : o.hashCode());
|
||||||
|
}
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void removeRange(int fromIndex, int toIndex)
|
||||||
|
{
|
||||||
|
if (fromIndex == toIndex)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ListIterator li = listIterator(fromIndex);
|
||||||
|
|
||||||
|
int i = fromIndex;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
li.next();
|
||||||
|
li.remove();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
while (li.hasNext() && i < toIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AbstractListIterator
|
||||||
|
implements Iterator
|
||||||
|
{
|
||||||
|
AbstractList m_al = null;
|
||||||
|
int m_nextIndex = 0;
|
||||||
|
|
||||||
|
public AbstractListIterator(AbstractList al, int index)
|
||||||
|
{
|
||||||
|
m_al = al;
|
||||||
|
m_nextIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNext()
|
||||||
|
{
|
||||||
|
return m_nextIndex < m_al.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object next()
|
||||||
|
{
|
||||||
|
return m_al.get(m_nextIndex++);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove()
|
||||||
|
{
|
||||||
|
m_al.remove(m_nextIndex - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class AbstractListListIterator
|
||||||
|
extends AbstractListIterator
|
||||||
|
implements ListIterator
|
||||||
|
{
|
||||||
|
public AbstractListListIterator(AbstractList al, int index)
|
||||||
|
{
|
||||||
|
super(al, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPrevious()
|
||||||
|
{
|
||||||
|
return m_nextIndex > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object previous()// throws NoSuchElementException;
|
||||||
|
{
|
||||||
|
return m_al.get(--m_nextIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int nextIndex()
|
||||||
|
{
|
||||||
|
return m_nextIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int previousIndex()
|
||||||
|
{
|
||||||
|
return m_nextIndex - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Object o) //throws RuntimeException, ClassCastException, IllegalArgumentException,IllegalStateException;
|
||||||
|
{
|
||||||
|
m_al.set(m_nextIndex - 1, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Object o)// throws RuntimeException, ClassCastException, IllegalArgumentException;
|
||||||
|
{
|
||||||
|
m_al.add(m_nextIndex - 1, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
173
extern/spongycastle/core/src/main/j2me/java/util/AbstractMap.java
vendored
Normal file
173
extern/spongycastle/core/src/main/j2me/java/util/AbstractMap.java
vendored
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public abstract class AbstractMap
|
||||||
|
implements Map
|
||||||
|
{
|
||||||
|
|
||||||
|
protected AbstractMap()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return entrySet().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsValue(Object value)
|
||||||
|
{
|
||||||
|
Iterator it = entrySet().iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
Map.Entry v = (Map.Entry)it.next();
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
if (v.getValue() == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (value.equals(v.getValue()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsKey(Object key)
|
||||||
|
throws ClassCastException, NullPointerException
|
||||||
|
{
|
||||||
|
Iterator it = entrySet().iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
Map.Entry v = (Map.Entry)it.next();
|
||||||
|
if (key == null)
|
||||||
|
{
|
||||||
|
if (v.getKey() == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (key.equals(v.getKey()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(Object key)
|
||||||
|
throws ClassCastException, NullPointerException
|
||||||
|
{
|
||||||
|
Iterator it = entrySet().iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
Map.Entry v = (Map.Entry)it.next();
|
||||||
|
if (key == null)
|
||||||
|
{
|
||||||
|
if (v.getKey() == null)
|
||||||
|
{
|
||||||
|
return v.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (key.equals(v.getKey()))
|
||||||
|
{
|
||||||
|
return v.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object put(Object key, Object value)
|
||||||
|
throws RuntimeException
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object remove(Object key)
|
||||||
|
{
|
||||||
|
Iterator it = entrySet().iterator();
|
||||||
|
Object o = null;
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
Map.Entry v = (Map.Entry)it.next();
|
||||||
|
if (key == null)
|
||||||
|
{
|
||||||
|
if (v.getKey() == null)
|
||||||
|
{
|
||||||
|
o = v.getValue();
|
||||||
|
it.remove();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (key.equals(v.getKey()))
|
||||||
|
{
|
||||||
|
o = v.getValue();
|
||||||
|
it.remove();
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putAll(Map t)
|
||||||
|
{
|
||||||
|
Iterator it = t.entrySet().iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
Map.Entry v = (Map.Entry)it.next();
|
||||||
|
put(v.getKey(), v.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
entrySet().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set keySet()
|
||||||
|
{
|
||||||
|
throw new RuntimeException("no keySet in AbstractMap()");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection values()
|
||||||
|
{
|
||||||
|
throw new RuntimeException("no values in AbstractMap()");
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Set entrySet();
|
||||||
|
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("no equals in AbstractMap()");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
throw new RuntimeException("no hashCode in AbstractMap()");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
throw new RuntimeException("no toString in AbstractMap()");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
46
extern/spongycastle/core/src/main/j2me/java/util/AbstractSet.java
vendored
Normal file
46
extern/spongycastle/core/src/main/j2me/java/util/AbstractSet.java
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public abstract class AbstractSet
|
||||||
|
extends AbstractCollection
|
||||||
|
implements Set
|
||||||
|
{
|
||||||
|
protected AbstractSet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
if (this == o)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(o instanceof Set))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (((Set)o).size() != size())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return containsAll((Collection)o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
int hashCode = 0;
|
||||||
|
Iterator it = iterator();
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
Object o = it.next();
|
||||||
|
if (o != null)
|
||||||
|
{
|
||||||
|
hashCode += o.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
}
|
107
extern/spongycastle/core/src/main/j2me/java/util/ArrayList.java
vendored
Normal file
107
extern/spongycastle/core/src/main/j2me/java/util/ArrayList.java
vendored
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public class ArrayList extends AbstractList
|
||||||
|
implements List
|
||||||
|
{
|
||||||
|
Vector m_Vector=null;
|
||||||
|
|
||||||
|
public ArrayList()
|
||||||
|
{
|
||||||
|
m_Vector=new Vector();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList(Collection c)
|
||||||
|
{
|
||||||
|
m_Vector=new Vector((int)(c.size()*1.1));
|
||||||
|
addAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList(int initialCapacity)
|
||||||
|
{
|
||||||
|
m_Vector=new Vector(initialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void trimToSize()
|
||||||
|
{
|
||||||
|
m_Vector.trimToSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ensureCapacity(int minCapacity)
|
||||||
|
{
|
||||||
|
m_Vector.ensureCapacity(minCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return m_Vector.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Object elem)
|
||||||
|
{
|
||||||
|
return m_Vector.contains(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int indexOf(Object elem)
|
||||||
|
{
|
||||||
|
return m_Vector.indexOf(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int lastIndexOf(Object elem)
|
||||||
|
{
|
||||||
|
return m_Vector.lastIndexOf(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone()
|
||||||
|
{
|
||||||
|
ArrayList al=new ArrayList(this);
|
||||||
|
|
||||||
|
return al;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] toArray()
|
||||||
|
{
|
||||||
|
Object[] o=new Object[m_Vector.size()];
|
||||||
|
m_Vector.copyInto(o);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(int index)
|
||||||
|
{
|
||||||
|
return m_Vector.elementAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object set(int index,Object elem)
|
||||||
|
{
|
||||||
|
Object o=m_Vector.elementAt(index);
|
||||||
|
m_Vector.setElementAt(elem,index);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean add(Object o)
|
||||||
|
{
|
||||||
|
m_Vector.addElement(o);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(int index,Object elem)
|
||||||
|
{
|
||||||
|
m_Vector.insertElementAt(elem,index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object remove(int index)
|
||||||
|
{
|
||||||
|
Object o=m_Vector.elementAt(index);
|
||||||
|
m_Vector.removeElementAt(index);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
m_Vector.removeAllElements();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
118
extern/spongycastle/core/src/main/j2me/java/util/Arrays.java
vendored
Normal file
118
extern/spongycastle/core/src/main/j2me/java/util/Arrays.java
vendored
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public class Arrays
|
||||||
|
{
|
||||||
|
|
||||||
|
private Arrays()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void fill(byte[] ret, byte v)
|
||||||
|
{
|
||||||
|
for (int i = 0; i != ret.length; i++)
|
||||||
|
{
|
||||||
|
ret[i] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean equals(byte[] a, byte[] a2)
|
||||||
|
{
|
||||||
|
if (a == a2)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (a == null || a2 == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = a.length;
|
||||||
|
if (a2.length != length)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
{
|
||||||
|
if (a[i] != a2[i])
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List asList(Object[] a)
|
||||||
|
{
|
||||||
|
return new ArrayList(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ArrayList
|
||||||
|
extends AbstractList
|
||||||
|
{
|
||||||
|
private Object[] a;
|
||||||
|
|
||||||
|
ArrayList(Object[] array)
|
||||||
|
{
|
||||||
|
a = array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return a.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] toArray()
|
||||||
|
{
|
||||||
|
Object[] tmp = new Object[a.length];
|
||||||
|
|
||||||
|
System.arraycopy(a, 0, tmp, 0, tmp.length);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(int index)
|
||||||
|
{
|
||||||
|
return a[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object set(int index, Object element)
|
||||||
|
{
|
||||||
|
Object oldValue = a[index];
|
||||||
|
a[index] = element;
|
||||||
|
return oldValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int indexOf(Object o)
|
||||||
|
{
|
||||||
|
if (o == null)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < a.length; i++)
|
||||||
|
{
|
||||||
|
if (a[i] == null)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < a.length; i++)
|
||||||
|
{
|
||||||
|
if (o.equals(a[i]))
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Object o)
|
||||||
|
{
|
||||||
|
return indexOf(o) != -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
21
extern/spongycastle/core/src/main/j2me/java/util/Collection.java
vendored
Normal file
21
extern/spongycastle/core/src/main/j2me/java/util/Collection.java
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
package java.util;
|
||||||
|
|
||||||
|
public interface Collection
|
||||||
|
{
|
||||||
|
public boolean add(Object o) throws RuntimeException,ClassCastException,IllegalArgumentException;
|
||||||
|
public boolean addAll(Collection c) throws RuntimeException,ClassCastException,IllegalArgumentException;
|
||||||
|
public void clear() throws RuntimeException;
|
||||||
|
public boolean contains(Object o);
|
||||||
|
public boolean containsAll(Collection c);
|
||||||
|
public boolean equals(Object o);
|
||||||
|
public int hashCode();
|
||||||
|
public boolean isEmpty();
|
||||||
|
public Iterator iterator();
|
||||||
|
public /*SK13*/boolean remove(Object o) throws RuntimeException;
|
||||||
|
public boolean removeAll(Collection c) throws RuntimeException;
|
||||||
|
public boolean retainAll(Collection c) throws RuntimeException;
|
||||||
|
public int size();
|
||||||
|
public Object[] toArray();
|
||||||
|
public Object[] toArray(Object[] a) throws ArrayStoreException;
|
||||||
|
}
|
365
extern/spongycastle/core/src/main/j2me/java/util/Collections.java
vendored
Normal file
365
extern/spongycastle/core/src/main/j2me/java/util/Collections.java
vendored
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public class Collections
|
||||||
|
{
|
||||||
|
public static List EMPTY_LIST = new ArrayList();
|
||||||
|
|
||||||
|
private Collections()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Collection unmodifiableCollection(Collection c)
|
||||||
|
{
|
||||||
|
return new UnmodifiableCollection(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class UnmodifiableCollection
|
||||||
|
implements Collection
|
||||||
|
{
|
||||||
|
Collection c;
|
||||||
|
|
||||||
|
UnmodifiableCollection(Collection c)
|
||||||
|
{
|
||||||
|
this.c = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return c.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return c.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Object o)
|
||||||
|
{
|
||||||
|
return c.contains(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] toArray()
|
||||||
|
{
|
||||||
|
return c.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object[] toArray(Object[] a)
|
||||||
|
{
|
||||||
|
return c.toArray(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator iterator()
|
||||||
|
{
|
||||||
|
return new Iterator()
|
||||||
|
{
|
||||||
|
Iterator i = c.iterator();
|
||||||
|
|
||||||
|
public boolean hasNext()
|
||||||
|
{
|
||||||
|
return i.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object next()
|
||||||
|
{
|
||||||
|
return i.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove()
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean add(Object o)
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean remove(Object o)
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsAll(Collection coll)
|
||||||
|
{
|
||||||
|
return c.containsAll(coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addAll(Collection coll)
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean removeAll(Collection coll)
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean retainAll(Collection coll)
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return c.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set unmodifiableSet(Set s)
|
||||||
|
{
|
||||||
|
return new UnmodifiableSet(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class UnmodifiableSet
|
||||||
|
extends UnmodifiableCollection
|
||||||
|
implements Set
|
||||||
|
{
|
||||||
|
UnmodifiableSet(Set s)
|
||||||
|
{
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
return c.equals(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return c.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map unmodifiableMap(Map map)
|
||||||
|
{
|
||||||
|
return new UnmodifiableMap(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class UnmodifiableMap
|
||||||
|
implements Map
|
||||||
|
{
|
||||||
|
private Map map;
|
||||||
|
|
||||||
|
UnmodifiableMap(Map map)
|
||||||
|
{
|
||||||
|
this.map = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return map.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return map.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsKey(Object key)
|
||||||
|
throws ClassCastException, NullPointerException
|
||||||
|
{
|
||||||
|
return map.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsValue(Object value)
|
||||||
|
{
|
||||||
|
return map.containsValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(Object key)
|
||||||
|
throws ClassCastException, NullPointerException
|
||||||
|
{
|
||||||
|
return map.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object put(Object key, Object value)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException, NullPointerException
|
||||||
|
{
|
||||||
|
throw new RuntimeException("unsupported operation - map unmodifiable");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object remove(Object key)
|
||||||
|
throws RuntimeException
|
||||||
|
{
|
||||||
|
throw new RuntimeException("unsupported operation - map unmodifiable");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putAll(Map t)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException, NullPointerException
|
||||||
|
{
|
||||||
|
throw new RuntimeException("unsupported operation - map unmodifiable");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
throws RuntimeException
|
||||||
|
{
|
||||||
|
throw new RuntimeException("unsupported operation - map unmodifiable");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set keySet()
|
||||||
|
{
|
||||||
|
return map.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection values()
|
||||||
|
{
|
||||||
|
return map.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set entrySet()
|
||||||
|
{
|
||||||
|
return map.entrySet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List unmodifiableList(List list)
|
||||||
|
{
|
||||||
|
return new UnmodifiableList(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class UnmodifiableList
|
||||||
|
extends UnmodifiableCollection
|
||||||
|
implements List
|
||||||
|
{
|
||||||
|
private List list;
|
||||||
|
|
||||||
|
UnmodifiableList(List list)
|
||||||
|
{
|
||||||
|
super(list);
|
||||||
|
this.list = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
return list.equals(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return list.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(int index)
|
||||||
|
{
|
||||||
|
return list.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object set(int index, Object element)
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(int index, Object element)
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object remove(int index)
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int indexOf(Object o)
|
||||||
|
{
|
||||||
|
return list.indexOf(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int lastIndexOf(Object o)
|
||||||
|
{
|
||||||
|
return list.lastIndexOf(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addAll(int index, Collection c)
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListIterator listIterator()
|
||||||
|
{
|
||||||
|
return listIterator(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListIterator listIterator(final int index)
|
||||||
|
{
|
||||||
|
return new ListIterator()
|
||||||
|
{
|
||||||
|
ListIterator i = list.listIterator(index);
|
||||||
|
|
||||||
|
public boolean hasNext()
|
||||||
|
{
|
||||||
|
return i.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object next()
|
||||||
|
{
|
||||||
|
return i.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPrevious()
|
||||||
|
{
|
||||||
|
return i.hasPrevious();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object previous()
|
||||||
|
{
|
||||||
|
return i.previous();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int nextIndex()
|
||||||
|
{
|
||||||
|
return i.nextIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int previousIndex()
|
||||||
|
{
|
||||||
|
return i.previousIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove()
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Object o)
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Object o)
|
||||||
|
{
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public List subList(int fromIndex, int toIndex)
|
||||||
|
{
|
||||||
|
return new UnmodifiableList(list.subList(fromIndex, toIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Enumeration enumeration(final Collection c)
|
||||||
|
{
|
||||||
|
return new Enumeration()
|
||||||
|
{
|
||||||
|
Iterator i = c.iterator();
|
||||||
|
|
||||||
|
public boolean hasMoreElements()
|
||||||
|
{
|
||||||
|
return i.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object nextElement()
|
||||||
|
{
|
||||||
|
return i.next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
279
extern/spongycastle/core/src/main/j2me/java/util/HashMap.java
vendored
Normal file
279
extern/spongycastle/core/src/main/j2me/java/util/HashMap.java
vendored
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
|
||||||
|
public class HashMap extends AbstractMap{
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
///// innere Klasse Null ////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
public class Null extends Object
|
||||||
|
{
|
||||||
|
public Null()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "Nullobject";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
///// innere Klasse innerSet ////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class ISet extends AbstractSet implements java.util.Set
|
||||||
|
{
|
||||||
|
|
||||||
|
Vector vec = null;
|
||||||
|
|
||||||
|
public ISet()
|
||||||
|
{
|
||||||
|
|
||||||
|
vec = new Vector();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean add(Object o)
|
||||||
|
{
|
||||||
|
vec.addElement(o);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return vec.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator iterator()
|
||||||
|
{
|
||||||
|
return new IIterator(vec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
///// innere Klasse Iterator ////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
class IIterator implements java.util.Iterator
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
Vector vec = null;
|
||||||
|
public IIterator(Vector ve)
|
||||||
|
{
|
||||||
|
vec = ve;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNext()
|
||||||
|
{
|
||||||
|
if (vec.size() > index) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object next()
|
||||||
|
{
|
||||||
|
Object o = vec.elementAt(index);
|
||||||
|
if (o==Nullobject) o=null;
|
||||||
|
index++;
|
||||||
|
return o;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove()
|
||||||
|
{
|
||||||
|
index--;
|
||||||
|
vec.removeElementAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
///// innere Klasse Entry ////////////////////////////////////
|
||||||
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
class Entry implements Map.Entry
|
||||||
|
{
|
||||||
|
public Object key=null;
|
||||||
|
public Object value=null;
|
||||||
|
|
||||||
|
public Entry(Object ke,Object valu)
|
||||||
|
{
|
||||||
|
key = ke;
|
||||||
|
value = valu;
|
||||||
|
}
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
if (value == ((Entry)o).value && key == ((Entry)o).key ) return true;
|
||||||
|
else return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValue()
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getKey()
|
||||||
|
{
|
||||||
|
return (Object)key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return value.hashCode() + key.hashCode();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object setValue(Object valu)
|
||||||
|
{
|
||||||
|
value = (String)valu;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
private Hashtable m_HashTable=null;
|
||||||
|
private Null Nullobject = null;
|
||||||
|
|
||||||
|
public HashMap()
|
||||||
|
{
|
||||||
|
Nullobject = new Null();
|
||||||
|
m_HashTable=new Hashtable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap(int initialCapacity)
|
||||||
|
{
|
||||||
|
Nullobject = new Null();
|
||||||
|
m_HashTable=new Hashtable(initialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap(Map t)
|
||||||
|
{
|
||||||
|
Nullobject = new Null();
|
||||||
|
m_HashTable=new Hashtable();
|
||||||
|
this.putAll(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
m_HashTable.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object clone()
|
||||||
|
{
|
||||||
|
HashMap hm=new HashMap(this);
|
||||||
|
|
||||||
|
return hm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsKey(Object key)
|
||||||
|
{
|
||||||
|
if (key == null) key = Nullobject;
|
||||||
|
boolean b = m_HashTable.containsKey(key);
|
||||||
|
return b;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsValue(Object value)
|
||||||
|
{
|
||||||
|
if (value == null ) value = Nullobject;
|
||||||
|
boolean b = m_HashTable.contains(value);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set entrySet()
|
||||||
|
{
|
||||||
|
|
||||||
|
Object Key = null;
|
||||||
|
ISet s = new ISet();
|
||||||
|
Enumeration en = m_HashTable.keys();
|
||||||
|
while (en.hasMoreElements())
|
||||||
|
{
|
||||||
|
Key = en.nextElement();
|
||||||
|
s.add(new Entry(Key,m_HashTable.get(Key)));
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(Object key)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (key==null) key= Nullobject;
|
||||||
|
|
||||||
|
Object o = m_HashTable.get(key);
|
||||||
|
|
||||||
|
if (o == Nullobject) o=null;
|
||||||
|
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return m_HashTable.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set keySet()
|
||||||
|
{
|
||||||
|
ISet s=new ISet();
|
||||||
|
Enumeration en = m_HashTable.keys();
|
||||||
|
|
||||||
|
while (en.hasMoreElements())
|
||||||
|
{
|
||||||
|
s.add(en.nextElement());
|
||||||
|
}
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object put(Object key, Object value)
|
||||||
|
{
|
||||||
|
if (key==null) key=Nullobject;
|
||||||
|
if (value==null) value = Nullobject;
|
||||||
|
return m_HashTable.put(key,value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putAll(Map m)
|
||||||
|
{
|
||||||
|
Iterator it = m.entrySet().iterator();
|
||||||
|
Object key=null;
|
||||||
|
Object value=null;
|
||||||
|
|
||||||
|
while (it.hasNext())
|
||||||
|
{
|
||||||
|
Map.Entry me = (Map.Entry)it.next();
|
||||||
|
if (me.getKey() == null) key = Nullobject;
|
||||||
|
else key= me.getKey();
|
||||||
|
if (me.getValue()==null) value = Nullobject;
|
||||||
|
else value = me.getValue();
|
||||||
|
m_HashTable.put(key,value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object remove(Object key)
|
||||||
|
{
|
||||||
|
return m_HashTable.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return m_HashTable.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection values()
|
||||||
|
{
|
||||||
|
|
||||||
|
ISet s=new ISet();
|
||||||
|
Enumeration en = m_HashTable.keys();
|
||||||
|
|
||||||
|
while (en.hasMoreElements())
|
||||||
|
{
|
||||||
|
Object Key = en.nextElement();
|
||||||
|
//s.add(((Map.Entry)m_HashTable.get(Key)).getValue());
|
||||||
|
s.add(m_HashTable.get(Key));
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
71
extern/spongycastle/core/src/main/j2me/java/util/HashSet.java
vendored
Normal file
71
extern/spongycastle/core/src/main/j2me/java/util/HashSet.java
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public class HashSet
|
||||||
|
extends AbstractSet
|
||||||
|
{
|
||||||
|
private HashMap m_HashMap = null;
|
||||||
|
|
||||||
|
public HashSet()
|
||||||
|
{
|
||||||
|
m_HashMap = new HashMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashSet(Collection c)
|
||||||
|
{
|
||||||
|
m_HashMap = new HashMap(Math.max(11, c.size() * 2));
|
||||||
|
addAll(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashSet(int initialCapacity)
|
||||||
|
{
|
||||||
|
m_HashMap = new HashMap(initialCapacity);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator iterator()
|
||||||
|
{
|
||||||
|
return (m_HashMap.keySet()).iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return m_HashMap.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(Object o)
|
||||||
|
{
|
||||||
|
return m_HashMap.containsKey(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean add(Object o)
|
||||||
|
{
|
||||||
|
if (!m_HashMap.containsValue(o))
|
||||||
|
{
|
||||||
|
m_HashMap.put((Object)o, (Object)o);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean remove(Object o)
|
||||||
|
{
|
||||||
|
return (m_HashMap.remove(o) != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
{
|
||||||
|
m_HashMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Object clone()
|
||||||
|
{
|
||||||
|
HashSet hs = new HashSet();
|
||||||
|
hs.m_HashMap = (HashMap)m_HashMap.clone();
|
||||||
|
return hs;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
9
extern/spongycastle/core/src/main/j2me/java/util/Iterator.java
vendored
Normal file
9
extern/spongycastle/core/src/main/j2me/java/util/Iterator.java
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
package java.util;
|
||||||
|
|
||||||
|
public interface Iterator
|
||||||
|
{
|
||||||
|
public abstract boolean hasNext();
|
||||||
|
public abstract Object next() throws NoSuchElementException;
|
||||||
|
public abstract void remove() throws RuntimeException,IllegalStateException;
|
||||||
|
}
|
32
extern/spongycastle/core/src/main/j2me/java/util/List.java
vendored
Normal file
32
extern/spongycastle/core/src/main/j2me/java/util/List.java
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public interface List
|
||||||
|
extends Collection
|
||||||
|
{
|
||||||
|
void add(int index, Object element)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
boolean addAll(int index, Collection c)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
Object get(int index)
|
||||||
|
throws IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
int indexOf(Object o);
|
||||||
|
|
||||||
|
int lastIndexOf(Object o);
|
||||||
|
|
||||||
|
ListIterator listIterator();
|
||||||
|
|
||||||
|
ListIterator listIterator(int index)
|
||||||
|
throws IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
Object remove(int index)
|
||||||
|
throws RuntimeException, IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
Object set(int index, Object element)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException, IndexOutOfBoundsException;
|
||||||
|
|
||||||
|
List subList(int fromIndex, int toIndex)
|
||||||
|
throws IndexOutOfBoundsException;
|
||||||
|
}
|
20
extern/spongycastle/core/src/main/j2me/java/util/ListIterator.java
vendored
Normal file
20
extern/spongycastle/core/src/main/j2me/java/util/ListIterator.java
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public interface ListIterator
|
||||||
|
extends Iterator
|
||||||
|
{
|
||||||
|
public boolean hasPrevious();
|
||||||
|
|
||||||
|
public Object previous()
|
||||||
|
throws NoSuchElementException;
|
||||||
|
|
||||||
|
public int nextIndex();
|
||||||
|
|
||||||
|
public int previousIndex();
|
||||||
|
|
||||||
|
public void set(Object o)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
public void add(Object o)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException;
|
||||||
|
}
|
54
extern/spongycastle/core/src/main/j2me/java/util/Map.java
vendored
Normal file
54
extern/spongycastle/core/src/main/j2me/java/util/Map.java
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public interface Map
|
||||||
|
{
|
||||||
|
|
||||||
|
public static interface Entry
|
||||||
|
{
|
||||||
|
public Object getKey();
|
||||||
|
|
||||||
|
public Object getValue();
|
||||||
|
|
||||||
|
public Object setValue(Object value)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException, NullPointerException;
|
||||||
|
|
||||||
|
public boolean equals(Object o);
|
||||||
|
|
||||||
|
public int hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size();
|
||||||
|
|
||||||
|
public boolean isEmpty();
|
||||||
|
|
||||||
|
public boolean containsKey(Object Key)
|
||||||
|
throws ClassCastException, NullPointerException;
|
||||||
|
|
||||||
|
public boolean containsValue(Object value);
|
||||||
|
|
||||||
|
public Object get(Object key)
|
||||||
|
throws ClassCastException, NullPointerException;
|
||||||
|
|
||||||
|
public Object put(Object key, Object value)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException, NullPointerException;
|
||||||
|
|
||||||
|
public Object remove(Object key)
|
||||||
|
throws RuntimeException;
|
||||||
|
|
||||||
|
public void putAll(Map t)
|
||||||
|
throws RuntimeException, ClassCastException, IllegalArgumentException, NullPointerException;
|
||||||
|
|
||||||
|
public void clear()
|
||||||
|
throws RuntimeException;
|
||||||
|
|
||||||
|
public Set keySet();
|
||||||
|
|
||||||
|
public Collection values();
|
||||||
|
|
||||||
|
public Set entrySet();
|
||||||
|
|
||||||
|
public boolean equals(Object o);
|
||||||
|
|
||||||
|
public int hashCode();
|
||||||
|
|
||||||
|
}
|
38
extern/spongycastle/core/src/main/j2me/java/util/Set.java
vendored
Normal file
38
extern/spongycastle/core/src/main/j2me/java/util/Set.java
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public interface Set
|
||||||
|
extends Collection
|
||||||
|
{
|
||||||
|
|
||||||
|
public int size();
|
||||||
|
|
||||||
|
public boolean isEmpty();
|
||||||
|
|
||||||
|
public boolean contains(Object o);
|
||||||
|
|
||||||
|
public Iterator iterator();
|
||||||
|
|
||||||
|
public Object[] toArray();
|
||||||
|
|
||||||
|
public Object[] toArray(Object[] a);
|
||||||
|
|
||||||
|
public boolean add(Object o);
|
||||||
|
|
||||||
|
public boolean remove(Object o);
|
||||||
|
|
||||||
|
public boolean containsAll(Collection c);
|
||||||
|
|
||||||
|
public boolean addAll(Collection c);
|
||||||
|
|
||||||
|
public boolean retainAll(Collection c);
|
||||||
|
|
||||||
|
public boolean removeAll(Collection c);
|
||||||
|
|
||||||
|
public void clear();
|
||||||
|
|
||||||
|
public boolean equals(Object o);
|
||||||
|
|
||||||
|
public int hashCode();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
115
extern/spongycastle/core/src/main/j2me/java/util/StringTokenizer.java
vendored
Normal file
115
extern/spongycastle/core/src/main/j2me/java/util/StringTokenizer.java
vendored
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
|
public class StringTokenizer
|
||||||
|
implements Enumeration
|
||||||
|
{
|
||||||
|
private String s;
|
||||||
|
private String delims;
|
||||||
|
private boolean retDelims;
|
||||||
|
private int maxPos;
|
||||||
|
|
||||||
|
private int pos;
|
||||||
|
|
||||||
|
public StringTokenizer(String s, String delims)
|
||||||
|
{
|
||||||
|
this(s, delims, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringTokenizer(String s, String delims, boolean retDelims)
|
||||||
|
{
|
||||||
|
this.s = s;
|
||||||
|
this.delims = delims;
|
||||||
|
this.retDelims = retDelims;
|
||||||
|
this.maxPos = s.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMoreTokens()
|
||||||
|
{
|
||||||
|
if (retDelims)
|
||||||
|
{
|
||||||
|
return pos < maxPos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int next = pos;
|
||||||
|
while (next < maxPos && isDelim(next))
|
||||||
|
{
|
||||||
|
next++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return next < maxPos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String nextToken()
|
||||||
|
{
|
||||||
|
String tok;
|
||||||
|
|
||||||
|
if (pos == maxPos)
|
||||||
|
{
|
||||||
|
throw new NoSuchElementException("no more tokens");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retDelims)
|
||||||
|
{
|
||||||
|
if (isDelim(pos))
|
||||||
|
{
|
||||||
|
tok = s.substring(pos, pos + 1);
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pos < maxPos && isDelim(pos))
|
||||||
|
{
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int start = pos;
|
||||||
|
|
||||||
|
while (pos < maxPos && !isDelim(pos))
|
||||||
|
{
|
||||||
|
pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pos < maxPos)
|
||||||
|
{
|
||||||
|
tok = s.substring(start, pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tok = s.substring(start);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMoreElements()
|
||||||
|
{
|
||||||
|
return hasMoreTokens();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object nextElement()
|
||||||
|
{
|
||||||
|
return nextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isDelim(int index)
|
||||||
|
{
|
||||||
|
char c = s.charAt(index);
|
||||||
|
|
||||||
|
for (int i = 0; i != delims.length(); i++)
|
||||||
|
{
|
||||||
|
if (delims.charAt(i) == c)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
142
extern/spongycastle/core/src/main/j2me/java/util/Sublist.java
vendored
Normal file
142
extern/spongycastle/core/src/main/j2me/java/util/Sublist.java
vendored
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public class Sublist
|
||||||
|
extends AbstractList
|
||||||
|
{
|
||||||
|
AbstractList m_al = null;
|
||||||
|
int m_fromIndex = 0;
|
||||||
|
int m_toIndex = 0;
|
||||||
|
int size = 0;
|
||||||
|
|
||||||
|
public Sublist(AbstractList ali, int fromIndex, int toIndex)
|
||||||
|
{
|
||||||
|
m_al = ali;
|
||||||
|
m_toIndex = toIndex;
|
||||||
|
m_fromIndex = fromIndex;
|
||||||
|
size = size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object set(int index, Object o)
|
||||||
|
{
|
||||||
|
if (index < size)
|
||||||
|
{
|
||||||
|
o = m_al.set(index + m_fromIndex, o);
|
||||||
|
if (o != null)
|
||||||
|
{
|
||||||
|
size++;
|
||||||
|
m_toIndex++;
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get(int index)
|
||||||
|
throws IndexOutOfBoundsException
|
||||||
|
{
|
||||||
|
if (index < size)
|
||||||
|
{
|
||||||
|
return m_al.get(index + m_fromIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(int index, Object o)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (index <= size)
|
||||||
|
{
|
||||||
|
m_al.add(index + m_fromIndex, o);
|
||||||
|
m_toIndex++;
|
||||||
|
size++;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object remove(int index, Object o)
|
||||||
|
{
|
||||||
|
if (index < size)
|
||||||
|
{
|
||||||
|
Object ob = m_al.remove(index + m_fromIndex);
|
||||||
|
if (ob != null)
|
||||||
|
{
|
||||||
|
m_toIndex--;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
return ob;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addAll(int index, Collection c)
|
||||||
|
{
|
||||||
|
if (index < size)
|
||||||
|
{
|
||||||
|
boolean bool = m_al.addAll(index + m_fromIndex, c);
|
||||||
|
if (bool)
|
||||||
|
{
|
||||||
|
int lange = c.size();
|
||||||
|
m_toIndex = m_toIndex + lange;
|
||||||
|
size = size + lange;
|
||||||
|
}
|
||||||
|
return bool;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addAll(Collection c)
|
||||||
|
{
|
||||||
|
boolean bool = m_al.addAll(m_toIndex, c);
|
||||||
|
if (bool)
|
||||||
|
{
|
||||||
|
int lange = c.size();
|
||||||
|
m_toIndex = m_toIndex + lange;
|
||||||
|
size = size + lange;
|
||||||
|
}
|
||||||
|
return bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeRange(int from, int to)
|
||||||
|
{
|
||||||
|
if ((from <= to) && (from <= size) && (to <= size))
|
||||||
|
{
|
||||||
|
m_al.removeRange(from, to);
|
||||||
|
int lange = to - from;
|
||||||
|
m_toIndex = m_toIndex - lange;
|
||||||
|
size = size - lange;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (from > to)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return (m_toIndex - m_fromIndex);
|
||||||
|
}
|
||||||
|
}
|
27
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/ASN1GeneralizedTime.java
vendored
Normal file
27
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/ASN1GeneralizedTime.java
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class ASN1GeneralizedTime
|
||||||
|
extends DERGeneralizedTime
|
||||||
|
{
|
||||||
|
ASN1GeneralizedTime(byte[] bytes)
|
||||||
|
{
|
||||||
|
super(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1GeneralizedTime(Date date)
|
||||||
|
{
|
||||||
|
super(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1GeneralizedTime(Date date, boolean includeMillis)
|
||||||
|
{
|
||||||
|
super(date, includeMillis);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1GeneralizedTime(String time)
|
||||||
|
{
|
||||||
|
super(time);
|
||||||
|
}
|
||||||
|
}
|
22
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/ASN1UTCTime.java
vendored
Normal file
22
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/ASN1UTCTime.java
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class ASN1UTCTime
|
||||||
|
extends DERUTCTime
|
||||||
|
{
|
||||||
|
ASN1UTCTime(byte[] bytes)
|
||||||
|
{
|
||||||
|
super(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1UTCTime(Date date)
|
||||||
|
{
|
||||||
|
super(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1UTCTime(String time)
|
||||||
|
{
|
||||||
|
super(time);
|
||||||
|
}
|
||||||
|
}
|
31
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/DERFactory.java
vendored
Normal file
31
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/DERFactory.java
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
class DERFactory
|
||||||
|
{
|
||||||
|
static final ASN1Sequence EMPTY_SEQUENCE = new DERSequence();
|
||||||
|
static final ASN1Set EMPTY_SET = new DERSet();
|
||||||
|
|
||||||
|
static ASN1Sequence createSequence(ASN1EncodableVector v)
|
||||||
|
{
|
||||||
|
if (v.size() < 1)
|
||||||
|
{
|
||||||
|
return EMPTY_SEQUENCE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new DLSequence(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ASN1Set createSet(ASN1EncodableVector v)
|
||||||
|
{
|
||||||
|
if (v.size() < 1)
|
||||||
|
{
|
||||||
|
return EMPTY_SET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new DLSet(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
260
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/DERGeneralizedTime.java
vendored
Normal file
260
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/DERGeneralizedTime.java
vendored
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.spongycastle.util.Arrays;
|
||||||
|
import org.spongycastle.util.Strings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generalized time object.
|
||||||
|
*/
|
||||||
|
public class DERGeneralizedTime
|
||||||
|
extends ASN1Primitive
|
||||||
|
{
|
||||||
|
private byte[] time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a generalized time from the passed in object
|
||||||
|
*
|
||||||
|
* @exception IllegalArgumentException if the object cannot be converted.
|
||||||
|
*/
|
||||||
|
public static ASN1GeneralizedTime getInstance(
|
||||||
|
Object obj)
|
||||||
|
{
|
||||||
|
if (obj == null || obj instanceof ASN1GeneralizedTime)
|
||||||
|
{
|
||||||
|
return (ASN1GeneralizedTime)obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj instanceof DERGeneralizedTime)
|
||||||
|
{
|
||||||
|
return new ASN1GeneralizedTime(((DERGeneralizedTime)obj).time);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a Generalized Time object from a tagged object.
|
||||||
|
*
|
||||||
|
* @param obj the tagged object holding the object we want
|
||||||
|
* @param explicit true if the object is meant to be explicitly
|
||||||
|
* tagged false otherwise.
|
||||||
|
* @exception IllegalArgumentException if the tagged object cannot
|
||||||
|
* be converted.
|
||||||
|
*/
|
||||||
|
public static ASN1GeneralizedTime getInstance(
|
||||||
|
ASN1TaggedObject obj,
|
||||||
|
boolean explicit)
|
||||||
|
{
|
||||||
|
ASN1Primitive o = obj.getObject();
|
||||||
|
|
||||||
|
if (explicit || o instanceof DERGeneralizedTime)
|
||||||
|
{
|
||||||
|
return getInstance(o);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new ASN1GeneralizedTime(((ASN1OctetString)o).getOctets());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The correct format for this is YYYYMMDDHHMMSS[.f]Z, or without the Z
|
||||||
|
* for local time, or Z|[+|-]HHMM on the end, for difference between local
|
||||||
|
* time and UTC time. The fractional second amount f must consist of at
|
||||||
|
* least one number with trailing zeroes removed.
|
||||||
|
*
|
||||||
|
* @param time the time string.
|
||||||
|
* @exception IllegalArgumentException if String is an illegal format.
|
||||||
|
*/
|
||||||
|
public DERGeneralizedTime(
|
||||||
|
String time)
|
||||||
|
{
|
||||||
|
char last = time.charAt(time.length() - 1);
|
||||||
|
if (last != 'Z' && !(last >= 0 && last <= '9'))
|
||||||
|
{
|
||||||
|
if (time.indexOf('-') < 0 && time.indexOf('+') < 0)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("time needs to be in format YYYYMMDDHHMMSS[.f]Z or YYYYMMDDHHMMSS[.f][+-]HHMM");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.time = Strings.toByteArray(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* base constructer from a java.util.date object
|
||||||
|
*/
|
||||||
|
public DERGeneralizedTime(
|
||||||
|
Date time)
|
||||||
|
{
|
||||||
|
this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(time, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected DERGeneralizedTime(Date date, boolean includeMillis)
|
||||||
|
{
|
||||||
|
this.time = Strings.toByteArray(DateFormatter.getGeneralizedTimeDateString(date, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
DERGeneralizedTime(
|
||||||
|
byte[] bytes)
|
||||||
|
{
|
||||||
|
this.time = bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the time.
|
||||||
|
* @return The time string as it appeared in the encoded object.
|
||||||
|
*/
|
||||||
|
public String getTimeString()
|
||||||
|
{
|
||||||
|
return Strings.fromByteArray(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the time - always in the form of
|
||||||
|
* YYYYMMDDhhmmssGMT(+hh:mm|-hh:mm).
|
||||||
|
* <p>
|
||||||
|
* Normally in a certificate we would expect "Z" rather than "GMT",
|
||||||
|
* however adding the "GMT" means we can just use:
|
||||||
|
* <pre>
|
||||||
|
* dateF = new SimpleDateFormat("yyyyMMddHHmmssz");
|
||||||
|
* </pre>
|
||||||
|
* To read in the time and get a date which is compatible with our local
|
||||||
|
* time zone.
|
||||||
|
*/
|
||||||
|
public String getTime()
|
||||||
|
{
|
||||||
|
String stime = Strings.fromByteArray(time);
|
||||||
|
|
||||||
|
//
|
||||||
|
// standardise the format.
|
||||||
|
//
|
||||||
|
if (stime.charAt(stime.length() - 1) == 'Z')
|
||||||
|
{
|
||||||
|
return stime.substring(0, stime.length() - 1) + "GMT+00:00";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int signPos = stime.length() - 5;
|
||||||
|
char sign = stime.charAt(signPos);
|
||||||
|
if (sign == '-' || sign == '+')
|
||||||
|
{
|
||||||
|
return stime.substring(0, signPos)
|
||||||
|
+ "GMT"
|
||||||
|
+ stime.substring(signPos, signPos + 3)
|
||||||
|
+ ":"
|
||||||
|
+ stime.substring(signPos + 3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
signPos = stime.length() - 3;
|
||||||
|
sign = stime.charAt(signPos);
|
||||||
|
if (sign == '-' || sign == '+')
|
||||||
|
{
|
||||||
|
return stime.substring(0, signPos)
|
||||||
|
+ "GMT"
|
||||||
|
+ stime.substring(signPos)
|
||||||
|
+ ":00";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stime + calculateGMTOffset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String calculateGMTOffset()
|
||||||
|
{
|
||||||
|
String sign = "+";
|
||||||
|
TimeZone timeZone = TimeZone.getDefault();
|
||||||
|
int offset = timeZone.getRawOffset();
|
||||||
|
if (offset < 0)
|
||||||
|
{
|
||||||
|
sign = "-";
|
||||||
|
offset = -offset;
|
||||||
|
}
|
||||||
|
int hours = offset / (60 * 60 * 1000);
|
||||||
|
int minutes = (offset - (hours * 60 * 60 * 1000)) / (60 * 1000);
|
||||||
|
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// if (timeZone.useDaylightTime() && timeZone.inDaylightTime(this.getDate()))
|
||||||
|
// {
|
||||||
|
// hours += sign.equals("+") ? 1 : -1;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (ParseException e)
|
||||||
|
// {
|
||||||
|
// // we'll do our best and ignore daylight savings
|
||||||
|
// }
|
||||||
|
|
||||||
|
return "GMT" + sign + convert(hours) + ":" + convert(minutes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convert(int time)
|
||||||
|
{
|
||||||
|
if (time < 10)
|
||||||
|
{
|
||||||
|
return "0" + time;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Integer.toString(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDate()
|
||||||
|
{
|
||||||
|
return DateFormatter.fromGeneralizedTimeString(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasFractionalSeconds()
|
||||||
|
{
|
||||||
|
for (int i = 0; i != time.length; i++)
|
||||||
|
{
|
||||||
|
if (time[i] == '.')
|
||||||
|
{
|
||||||
|
if (i == 14)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isConstructed()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int encodedLength()
|
||||||
|
{
|
||||||
|
int length = time.length;
|
||||||
|
|
||||||
|
return 1 + StreamUtil.calculateBodyLength(length) + length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void encode(
|
||||||
|
ASN1OutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
out.writeEncoded(BERTags.GENERALIZED_TIME, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean asn1Equals(
|
||||||
|
ASN1Primitive o)
|
||||||
|
{
|
||||||
|
if (!(o instanceof DERGeneralizedTime))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Arrays.areEqual(time, ((DERGeneralizedTime)o).time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return Arrays.hashCode(time);
|
||||||
|
}
|
||||||
|
}
|
259
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/DERUTCTime.java
vendored
Normal file
259
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/DERUTCTime.java
vendored
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.spongycastle.util.Arrays;
|
||||||
|
import org.spongycastle.util.Strings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UTC time object.
|
||||||
|
*/
|
||||||
|
public class DERUTCTime
|
||||||
|
extends ASN1Primitive
|
||||||
|
{
|
||||||
|
private byte[] time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an UTC Time from the passed in object.
|
||||||
|
*
|
||||||
|
* @exception IllegalArgumentException if the object cannot be converted.
|
||||||
|
*/
|
||||||
|
public static ASN1UTCTime getInstance(
|
||||||
|
Object obj)
|
||||||
|
{
|
||||||
|
if (obj == null || obj instanceof ASN1UTCTime)
|
||||||
|
{
|
||||||
|
return (ASN1UTCTime)obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj instanceof DERUTCTime)
|
||||||
|
{
|
||||||
|
return new ASN1UTCTime(((DERUTCTime)obj).time);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return an UTC Time from a tagged object.
|
||||||
|
*
|
||||||
|
* @param obj the tagged object holding the object we want
|
||||||
|
* @param explicit true if the object is meant to be explicitly
|
||||||
|
* tagged false otherwise.
|
||||||
|
* @exception IllegalArgumentException if the tagged object cannot
|
||||||
|
* be converted.
|
||||||
|
*/
|
||||||
|
public static ASN1UTCTime getInstance(
|
||||||
|
ASN1TaggedObject obj,
|
||||||
|
boolean explicit)
|
||||||
|
{
|
||||||
|
ASN1Object o = obj.getObject();
|
||||||
|
|
||||||
|
if (explicit || o instanceof ASN1UTCTime)
|
||||||
|
{
|
||||||
|
return getInstance(o);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new ASN1UTCTime(((ASN1OctetString)o).getOctets());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The correct format for this is YYMMDDHHMMSSZ (it used to be that seconds were
|
||||||
|
* never encoded. When you're creating one of these objects from scratch, that's
|
||||||
|
* what you want to use, otherwise we'll try to deal with whatever gets read from
|
||||||
|
* the input stream... (this is why the input format is different from the getTime()
|
||||||
|
* method output).
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* @param time the time string.
|
||||||
|
*/
|
||||||
|
public DERUTCTime(
|
||||||
|
String time)
|
||||||
|
{
|
||||||
|
if (time.charAt(time.length() - 1) != 'Z')
|
||||||
|
{
|
||||||
|
// we accept this as a variation
|
||||||
|
if (time.indexOf('-') < 0 && time.indexOf('+') < 0)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("time needs to be in format YYMMDDHHMMSSZ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.time = Strings.toByteArray(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* base constructor from a java.util.date object
|
||||||
|
*/
|
||||||
|
public DERUTCTime(
|
||||||
|
Date time)
|
||||||
|
{
|
||||||
|
this.time = Strings.toByteArray(DateFormatter.toUTCDateString(time));
|
||||||
|
}
|
||||||
|
|
||||||
|
DERUTCTime(
|
||||||
|
byte[] time)
|
||||||
|
{
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the time as a date based on whatever a 2 digit year will return. For
|
||||||
|
* standardised processing use getAdjustedDate().
|
||||||
|
*
|
||||||
|
* @return the resulting date
|
||||||
|
*/
|
||||||
|
public Date getDate()
|
||||||
|
{
|
||||||
|
return DateFormatter.adjustedFromUTCDateString(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the time as an adjusted date
|
||||||
|
* in the range of 1950 - 2049.
|
||||||
|
*
|
||||||
|
* @return a date in the range of 1950 to 2049.
|
||||||
|
*/
|
||||||
|
public Date getAdjustedDate()
|
||||||
|
{
|
||||||
|
return DateFormatter.adjustedFromUTCDateString(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the time - always in the form of
|
||||||
|
* YYMMDDhhmmssGMT(+hh:mm|-hh:mm).
|
||||||
|
* <p>
|
||||||
|
* Normally in a certificate we would expect "Z" rather than "GMT",
|
||||||
|
* however adding the "GMT" means we can just use:
|
||||||
|
* <pre>
|
||||||
|
* dateF = new SimpleDateFormat("yyMMddHHmmssz");
|
||||||
|
* </pre>
|
||||||
|
* To read in the time and get a date which is compatible with our local
|
||||||
|
* time zone.
|
||||||
|
* <p>
|
||||||
|
* <b>Note:</b> In some cases, due to the local date processing, this
|
||||||
|
* may lead to unexpected results. If you want to stick the normal
|
||||||
|
* convention of 1950 to 2049 use the getAdjustedTime() method.
|
||||||
|
*/
|
||||||
|
public String getTime()
|
||||||
|
{
|
||||||
|
String stime = Strings.fromByteArray(time);
|
||||||
|
|
||||||
|
//
|
||||||
|
// standardise the format.
|
||||||
|
//
|
||||||
|
if (stime.indexOf('-') < 0 && stime.indexOf('+') < 0)
|
||||||
|
{
|
||||||
|
if (stime.length() == 11)
|
||||||
|
{
|
||||||
|
return stime.substring(0, 10) + "00GMT+00:00";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return stime.substring(0, 12) + "GMT+00:00";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int index = stime.indexOf('-');
|
||||||
|
if (index < 0)
|
||||||
|
{
|
||||||
|
index = stime.indexOf('+');
|
||||||
|
}
|
||||||
|
String d = stime;
|
||||||
|
|
||||||
|
if (index == stime.length() - 3)
|
||||||
|
{
|
||||||
|
d += "00";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == 10)
|
||||||
|
{
|
||||||
|
return d.substring(0, 10) + "00GMT" + d.substring(10, 13) + ":" + d.substring(13, 15);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return d.substring(0, 12) + "GMT" + d.substring(12, 15) + ":" + d.substring(15, 17);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return a time string as an adjusted date with a 4 digit year. This goes
|
||||||
|
* in the range of 1950 - 2049.
|
||||||
|
*/
|
||||||
|
public String getAdjustedTime()
|
||||||
|
{
|
||||||
|
String d = this.getTime();
|
||||||
|
|
||||||
|
if (d.charAt(0) < '5')
|
||||||
|
{
|
||||||
|
return "20" + d;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "19" + d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the time.
|
||||||
|
* @return The time string as it appeared in the encoded object.
|
||||||
|
*/
|
||||||
|
public String getTimeString()
|
||||||
|
{
|
||||||
|
return Strings.fromByteArray(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isConstructed()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int encodedLength()
|
||||||
|
{
|
||||||
|
int length = time.length;
|
||||||
|
|
||||||
|
return 1 + StreamUtil.calculateBodyLength(length) + length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void encode(
|
||||||
|
ASN1OutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
out.write(BERTags.UTC_TIME);
|
||||||
|
|
||||||
|
int length = time.length;
|
||||||
|
|
||||||
|
out.writeLength(length);
|
||||||
|
|
||||||
|
for (int i = 0; i != length; i++)
|
||||||
|
{
|
||||||
|
out.write((byte)time[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean asn1Equals(
|
||||||
|
ASN1Primitive o)
|
||||||
|
{
|
||||||
|
if (!(o instanceof DERUTCTime))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Arrays.areEqual(time, ((DERUTCTime)o).time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return Arrays.hashCode(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return Strings.fromByteArray(time);
|
||||||
|
}
|
||||||
|
}
|
272
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/DateFormatter.java
vendored
Normal file
272
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/DateFormatter.java
vendored
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
class DateFormatter
|
||||||
|
{
|
||||||
|
// YYMMDDHHMMSSZ
|
||||||
|
static String toUTCDateString(Date date)
|
||||||
|
{
|
||||||
|
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||||
|
|
||||||
|
calendar.setTime(date);
|
||||||
|
|
||||||
|
return format2Year(calendar.get(Calendar.YEAR)) + format2(calendar.get(Calendar.MONTH) + 1) + format2(calendar.get(Calendar.DAY_OF_MONTH))
|
||||||
|
+ format2(calendar.get(Calendar.HOUR_OF_DAY)) + format2(calendar.get(Calendar.MINUTE)) + format2(calendar.get(Calendar.SECOND)) + "Z";
|
||||||
|
}
|
||||||
|
|
||||||
|
static Date adjustedFromUTCDateString(byte[] date)
|
||||||
|
{
|
||||||
|
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||||
|
|
||||||
|
int year = toInt2(date, 0);
|
||||||
|
|
||||||
|
if (year < 50)
|
||||||
|
{
|
||||||
|
year += 2000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
year += 1900;
|
||||||
|
}
|
||||||
|
|
||||||
|
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
|
||||||
|
calendar.set(Calendar.YEAR, year);
|
||||||
|
calendar.set(Calendar.MONTH, toInt2(date, 2) - 1);
|
||||||
|
calendar.set(Calendar.DAY_OF_MONTH, toInt2(date, 4));
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, toInt2(date, 6));
|
||||||
|
calendar.set(Calendar.MINUTE, toInt2(date, 8));
|
||||||
|
|
||||||
|
int tzChar = 10;
|
||||||
|
|
||||||
|
if (isNumber(date, tzChar))
|
||||||
|
{
|
||||||
|
calendar.set(Calendar.SECOND, toInt2(date, 10));
|
||||||
|
tzChar = 12;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
calendar.set(Calendar.SECOND, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
calendar.set(Calendar.MILLISECOND, 0);
|
||||||
|
|
||||||
|
if (date[tzChar] != 'Z')
|
||||||
|
{
|
||||||
|
int hoursOff = 0;
|
||||||
|
int minutesOff = 0;
|
||||||
|
|
||||||
|
hoursOff = toInt2(date, tzChar + 1) * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
if (date.length > tzChar + 3)
|
||||||
|
{
|
||||||
|
minutesOff = toInt2(date, tzChar + 3) * 60 * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (date[tzChar] == '-')
|
||||||
|
{
|
||||||
|
return new Date(calendar.getTime().getTime() + hoursOff + minutesOff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new Date(calendar.getTime().getTime() - (hoursOff + minutesOff));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return calendar.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
static String getGeneralizedTimeDateString(Date date, boolean includeMillis)
|
||||||
|
{
|
||||||
|
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||||
|
|
||||||
|
calendar.setTime(date);
|
||||||
|
|
||||||
|
String time = format4Year(calendar.get(Calendar.YEAR)) + format2(calendar.get(Calendar.MONTH) + 1) + format2(calendar.get(Calendar.DAY_OF_MONTH))
|
||||||
|
+ format2(calendar.get(Calendar.HOUR_OF_DAY)) + format2(calendar.get(Calendar.MINUTE)) + format2(calendar.get(Calendar.SECOND));
|
||||||
|
|
||||||
|
if (includeMillis)
|
||||||
|
{
|
||||||
|
time += "." + format3(calendar.get(Calendar.MILLISECOND));
|
||||||
|
}
|
||||||
|
|
||||||
|
return time + "Z";
|
||||||
|
}
|
||||||
|
|
||||||
|
static Date fromGeneralizedTimeString(byte[] date)
|
||||||
|
{
|
||||||
|
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||||
|
|
||||||
|
int year = toInt4(date, 0);
|
||||||
|
|
||||||
|
if (isLocalTime(date))
|
||||||
|
{
|
||||||
|
calendar.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
}
|
||||||
|
|
||||||
|
calendar.set(Calendar.YEAR, year);
|
||||||
|
calendar.set(Calendar.MONTH, toInt2(date, 4) - 1);
|
||||||
|
calendar.set(Calendar.DAY_OF_MONTH, toInt2(date, 6));
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, toInt2(date, 8));
|
||||||
|
calendar.set(Calendar.MINUTE, toInt2(date, 10));
|
||||||
|
|
||||||
|
int tzChar = 12;
|
||||||
|
|
||||||
|
if (isNumber(date, tzChar))
|
||||||
|
{
|
||||||
|
calendar.set(Calendar.SECOND, toInt2(date, 12));
|
||||||
|
tzChar = 14;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
calendar.set(Calendar.SECOND, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tzChar != date.length && date[tzChar] == '.')
|
||||||
|
{
|
||||||
|
int millis = 0;
|
||||||
|
tzChar++;
|
||||||
|
if (isNumber(date, tzChar))
|
||||||
|
{
|
||||||
|
millis = (date[tzChar] - '0') * 100;
|
||||||
|
tzChar++;
|
||||||
|
}
|
||||||
|
if (tzChar != date.length && isNumber(date, tzChar))
|
||||||
|
{
|
||||||
|
millis += (date[tzChar] - '0') * 10;
|
||||||
|
tzChar++;
|
||||||
|
}
|
||||||
|
if (tzChar != date.length && isNumber(date, tzChar))
|
||||||
|
{
|
||||||
|
millis += (date[tzChar] - '0');
|
||||||
|
tzChar++;
|
||||||
|
}
|
||||||
|
calendar.set(Calendar.MILLISECOND, millis);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
calendar.set(Calendar.MILLISECOND, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip nano-seconds
|
||||||
|
while (tzChar != date.length && isNumber(date, tzChar))
|
||||||
|
{
|
||||||
|
tzChar++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tzChar != date.length && date[tzChar] != 'Z')
|
||||||
|
{
|
||||||
|
int hoursOff = 0;
|
||||||
|
int minutesOff = 0;
|
||||||
|
|
||||||
|
hoursOff = toInt2(date, tzChar + 1) * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
if (date.length > tzChar + 3)
|
||||||
|
{
|
||||||
|
minutesOff = toInt2(date, tzChar + 3) * 60 * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (date[tzChar] == '-')
|
||||||
|
{
|
||||||
|
return new Date(calendar.getTime().getTime() + hoursOff + minutesOff);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new Date(calendar.getTime().getTime() - (hoursOff + minutesOff));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return calendar.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String format2(int v)
|
||||||
|
{
|
||||||
|
if (v < 10)
|
||||||
|
{
|
||||||
|
return "0" + v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Integer.toString(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String format2Year(int v)
|
||||||
|
{
|
||||||
|
if (v > 2000)
|
||||||
|
{
|
||||||
|
v = v - 2000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v = v - 1900;
|
||||||
|
}
|
||||||
|
|
||||||
|
return format2(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String format3(int v)
|
||||||
|
{
|
||||||
|
if (v < 10)
|
||||||
|
{
|
||||||
|
return "00" + v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v < 100)
|
||||||
|
{
|
||||||
|
return "0" + v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Integer.toString(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String format4Year(int v)
|
||||||
|
{
|
||||||
|
if (v < 10)
|
||||||
|
{
|
||||||
|
return "000" + v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v < 100)
|
||||||
|
{
|
||||||
|
return "00" + v;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v < 1000)
|
||||||
|
{
|
||||||
|
return "0" + v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Integer.toString(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isNumber(byte[] input, int off)
|
||||||
|
{
|
||||||
|
byte b = input[off];
|
||||||
|
return (b >= '0') && (b <= '9');
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isLocalTime(byte[] date)
|
||||||
|
{
|
||||||
|
for (int i = date.length - 1; i > date.length - 6; i--)
|
||||||
|
{
|
||||||
|
if (date[i] == 'Z' || date[i] == '-' || date[i] == '+')
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int toInt2(byte[] input, int off)
|
||||||
|
{
|
||||||
|
return (input[off] - '0') * 10 + (input[off + 1] - '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int toInt4(byte[] input, int off)
|
||||||
|
{
|
||||||
|
return toInt2(input, off) * 100 + toInt2(input, off + 2) ;
|
||||||
|
}
|
||||||
|
}
|
88
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/StreamUtil.java
vendored
Normal file
88
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/StreamUtil.java
vendored
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
class StreamUtil
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Find out possible longest length...
|
||||||
|
*
|
||||||
|
* @param in input stream of interest
|
||||||
|
* @return length calculation or MAX_VALUE.
|
||||||
|
*/
|
||||||
|
static int findLimit(InputStream in)
|
||||||
|
{
|
||||||
|
if (in instanceof LimitedInputStream)
|
||||||
|
{
|
||||||
|
return ((LimitedInputStream)in).getRemaining();
|
||||||
|
}
|
||||||
|
else if (in instanceof ASN1InputStream)
|
||||||
|
{
|
||||||
|
return ((ASN1InputStream)in).getLimit();
|
||||||
|
}
|
||||||
|
else if (in instanceof ByteArrayInputStream)
|
||||||
|
{
|
||||||
|
return ((ByteArrayInputStream)in).available();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int calculateBodyLength(
|
||||||
|
int length)
|
||||||
|
{
|
||||||
|
int count = 1;
|
||||||
|
|
||||||
|
if (length > 127)
|
||||||
|
{
|
||||||
|
int size = 1;
|
||||||
|
int val = length;
|
||||||
|
|
||||||
|
while ((val >>>= 8) != 0)
|
||||||
|
{
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = (size - 1) * 8; i >= 0; i -= 8)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int calculateTagLength(int tagNo)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
int length = 1;
|
||||||
|
|
||||||
|
if (tagNo >= 31)
|
||||||
|
{
|
||||||
|
if (tagNo < 128)
|
||||||
|
{
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
length += stack.length - pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
}
|
122
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/cms/Time.java
vendored
Normal file
122
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/cms/Time.java
vendored
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package org.spongycastle.asn1.cms;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.spongycastle.asn1.ASN1Choice;
|
||||||
|
import org.spongycastle.asn1.ASN1Object;
|
||||||
|
import org.spongycastle.asn1.ASN1Primitive;
|
||||||
|
import org.spongycastle.asn1.ASN1TaggedObject;
|
||||||
|
import org.spongycastle.asn1.DERGeneralizedTime;
|
||||||
|
import org.spongycastle.asn1.DERUTCTime;
|
||||||
|
|
||||||
|
public class Time
|
||||||
|
extends ASN1Object
|
||||||
|
implements ASN1Choice
|
||||||
|
{
|
||||||
|
ASN1Primitive time;
|
||||||
|
|
||||||
|
public static Time getInstance(
|
||||||
|
ASN1TaggedObject obj,
|
||||||
|
boolean explicit)
|
||||||
|
{
|
||||||
|
return getInstance(obj.getObject()); // must be explicitly tagged
|
||||||
|
}
|
||||||
|
|
||||||
|
public Time(
|
||||||
|
ASN1Primitive time)
|
||||||
|
{
|
||||||
|
if (!(time instanceof DERUTCTime)
|
||||||
|
&& !(time instanceof DERGeneralizedTime))
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("unknown object passed to Time");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a time object from a given date - if the date is between 1950
|
||||||
|
* and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
|
||||||
|
* is used.
|
||||||
|
*/
|
||||||
|
public Time(
|
||||||
|
Date date)
|
||||||
|
{
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
|
||||||
|
calendar.setTime(date);
|
||||||
|
|
||||||
|
int year = calendar.get(Calendar.YEAR);
|
||||||
|
|
||||||
|
if (year < 1950 || year > 2049)
|
||||||
|
{
|
||||||
|
time = new DERGeneralizedTime(date);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
time = new DERUTCTime(date);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Time getInstance(
|
||||||
|
Object obj)
|
||||||
|
{
|
||||||
|
if (obj == null || obj instanceof Time)
|
||||||
|
{
|
||||||
|
return (Time)obj;
|
||||||
|
}
|
||||||
|
else if (obj instanceof DERUTCTime)
|
||||||
|
{
|
||||||
|
return new Time((DERUTCTime)obj);
|
||||||
|
}
|
||||||
|
else if (obj instanceof DERGeneralizedTime)
|
||||||
|
{
|
||||||
|
return new Time((DERGeneralizedTime)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTime()
|
||||||
|
{
|
||||||
|
if (time instanceof DERUTCTime)
|
||||||
|
{
|
||||||
|
return ((DERUTCTime)time).getAdjustedTime();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ((DERGeneralizedTime)time).getTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDate()
|
||||||
|
{
|
||||||
|
if (time instanceof DERUTCTime)
|
||||||
|
{
|
||||||
|
return ((DERUTCTime)time).getAdjustedDate();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ((DERGeneralizedTime)time).getDate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produce an object suitable for an ASN1OutputStream.
|
||||||
|
* <pre>
|
||||||
|
* Time ::= CHOICE {
|
||||||
|
* utcTime UTCTime,
|
||||||
|
* generalTime GeneralizedTime }
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public ASN1Primitive toASN1Primitive()
|
||||||
|
{
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return getTime();
|
||||||
|
}
|
||||||
|
}
|
70
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/eac/PackedDate.java
vendored
Normal file
70
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/eac/PackedDate.java
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
package org.spongycastle.asn1.eac;
|
||||||
|
|
||||||
|
import org.spongycastle.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EAC encoding date object
|
||||||
|
*/
|
||||||
|
public class PackedDate
|
||||||
|
{
|
||||||
|
private byte[] time;
|
||||||
|
|
||||||
|
public PackedDate(
|
||||||
|
String time)
|
||||||
|
{
|
||||||
|
this.time = convert(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] convert(String sTime)
|
||||||
|
{
|
||||||
|
char[] digs = sTime.toCharArray();
|
||||||
|
byte[] date = new byte[6];
|
||||||
|
|
||||||
|
for (int i = 0; i != 6; i++)
|
||||||
|
{
|
||||||
|
date[i] = (byte)(digs[i] - '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackedDate(
|
||||||
|
byte[] bytes)
|
||||||
|
{
|
||||||
|
this.time = bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return Arrays.hashCode(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
if (!(o instanceof PackedDate))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackedDate other = (PackedDate)o;
|
||||||
|
|
||||||
|
return Arrays.areEqual(time, other.time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
char[] dateC = new char[time.length];
|
||||||
|
|
||||||
|
for (int i = 0; i != dateC.length; i++)
|
||||||
|
{
|
||||||
|
dateC[i] = (char)((time[i] & 0xff) + '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
return new String(dateC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getEncoding()
|
||||||
|
{
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
}
|
122
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/x509/Time.java
vendored
Normal file
122
extern/spongycastle/core/src/main/j2me/org/spongycastle/asn1/x509/Time.java
vendored
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package org.spongycastle.asn1.x509;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.spongycastle.asn1.ASN1Choice;
|
||||||
|
import org.spongycastle.asn1.ASN1Object;
|
||||||
|
import org.spongycastle.asn1.ASN1Primitive;
|
||||||
|
import org.spongycastle.asn1.ASN1TaggedObject;
|
||||||
|
import org.spongycastle.asn1.DERGeneralizedTime;
|
||||||
|
import org.spongycastle.asn1.DERUTCTime;
|
||||||
|
|
||||||
|
public class Time
|
||||||
|
extends ASN1Object
|
||||||
|
implements ASN1Choice
|
||||||
|
{
|
||||||
|
ASN1Primitive time;
|
||||||
|
|
||||||
|
public static Time getInstance(
|
||||||
|
ASN1TaggedObject obj,
|
||||||
|
boolean explicit)
|
||||||
|
{
|
||||||
|
return getInstance(obj.getObject()); // must be explicitly tagged
|
||||||
|
}
|
||||||
|
|
||||||
|
public Time(
|
||||||
|
ASN1Primitive time)
|
||||||
|
{
|
||||||
|
if (!(time instanceof DERUTCTime)
|
||||||
|
&& !(time instanceof DERGeneralizedTime))
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("unknown object passed to Time");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* creates a time object from a given date - if the date is between 1950
|
||||||
|
* and 2049 a UTCTime object is generated, otherwise a GeneralizedTime
|
||||||
|
* is used.
|
||||||
|
*/
|
||||||
|
public Time(
|
||||||
|
Date date)
|
||||||
|
{
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
|
||||||
|
calendar.setTime(date);
|
||||||
|
|
||||||
|
int year = calendar.get(Calendar.YEAR);
|
||||||
|
|
||||||
|
if (year < 1950 || year > 2049)
|
||||||
|
{
|
||||||
|
time = new DERGeneralizedTime(date);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
time = new DERUTCTime(date);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Time getInstance(
|
||||||
|
Object obj)
|
||||||
|
{
|
||||||
|
if (obj == null || obj instanceof Time)
|
||||||
|
{
|
||||||
|
return (Time)obj;
|
||||||
|
}
|
||||||
|
else if (obj instanceof DERUTCTime)
|
||||||
|
{
|
||||||
|
return new Time((DERUTCTime)obj);
|
||||||
|
}
|
||||||
|
else if (obj instanceof DERGeneralizedTime)
|
||||||
|
{
|
||||||
|
return new Time((DERGeneralizedTime)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("unknown object in factory: " + obj.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTime()
|
||||||
|
{
|
||||||
|
if (time instanceof DERUTCTime)
|
||||||
|
{
|
||||||
|
return ((DERUTCTime)time).getAdjustedTime();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ((DERGeneralizedTime)time).getTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDate()
|
||||||
|
{
|
||||||
|
if (time instanceof DERUTCTime)
|
||||||
|
{
|
||||||
|
return ((DERUTCTime)time).getAdjustedDate();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ((DERGeneralizedTime)time).getDate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produce an object suitable for an ASN1OutputStream.
|
||||||
|
* <pre>
|
||||||
|
* Time ::= CHOICE {
|
||||||
|
* utcTime UTCTime,
|
||||||
|
* generalTime GeneralizedTime }
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public ASN1Primitive toASN1Primitive()
|
||||||
|
{
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return getTime();
|
||||||
|
}
|
||||||
|
}
|
238
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/encodings/PKCS1Encoding.java
vendored
Normal file
238
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/encodings/PKCS1Encoding.java
vendored
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
package org.spongycastle.crypto.encodings;
|
||||||
|
|
||||||
|
import org.spongycastle.crypto.AsymmetricBlockCipher;
|
||||||
|
import org.spongycastle.crypto.CipherParameters;
|
||||||
|
import org.spongycastle.crypto.InvalidCipherTextException;
|
||||||
|
import org.spongycastle.crypto.params.AsymmetricKeyParameter;
|
||||||
|
import org.spongycastle.crypto.params.ParametersWithRandom;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this does your basic PKCS 1 v1.5 padding - whether or not you should be using this
|
||||||
|
* depends on your application - see PKCS1 Version 2 for details.
|
||||||
|
*/
|
||||||
|
public class PKCS1Encoding
|
||||||
|
implements AsymmetricBlockCipher
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* some providers fail to include the leading zero in PKCS1 encoded blocks. If you need to
|
||||||
|
* work with one of these set the system property org.spongycastle.pkcs1.strict to false.
|
||||||
|
* <p>
|
||||||
|
* The system property is checked during construction of the encoding object, it is set to
|
||||||
|
* true by default.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public static final String STRICT_LENGTH_ENABLED_PROPERTY = "org.spongycastle.pkcs1.strict";
|
||||||
|
|
||||||
|
private static final int HEADER_LENGTH = 10;
|
||||||
|
|
||||||
|
private SecureRandom random;
|
||||||
|
private AsymmetricBlockCipher engine;
|
||||||
|
private boolean forEncryption;
|
||||||
|
private boolean forPrivateKey;
|
||||||
|
private boolean useStrictLength;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic constructor.
|
||||||
|
* @param cipher
|
||||||
|
*/
|
||||||
|
public PKCS1Encoding(
|
||||||
|
AsymmetricBlockCipher cipher)
|
||||||
|
{
|
||||||
|
this.engine = cipher;
|
||||||
|
this.useStrictLength = useStrict();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// for J2ME compatibility
|
||||||
|
//
|
||||||
|
private boolean useStrict()
|
||||||
|
{
|
||||||
|
String strict = System.getProperty(STRICT_LENGTH_ENABLED_PROPERTY);
|
||||||
|
|
||||||
|
return strict == null || strict.equals("true");
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsymmetricBlockCipher getUnderlyingCipher()
|
||||||
|
{
|
||||||
|
return engine;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(
|
||||||
|
boolean forEncryption,
|
||||||
|
CipherParameters param)
|
||||||
|
{
|
||||||
|
AsymmetricKeyParameter kParam;
|
||||||
|
|
||||||
|
if (param instanceof ParametersWithRandom)
|
||||||
|
{
|
||||||
|
ParametersWithRandom rParam = (ParametersWithRandom)param;
|
||||||
|
|
||||||
|
this.random = rParam.getRandom();
|
||||||
|
kParam = (AsymmetricKeyParameter)rParam.getParameters();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.random = new SecureRandom();
|
||||||
|
kParam = (AsymmetricKeyParameter)param;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.init(forEncryption, param);
|
||||||
|
|
||||||
|
this.forPrivateKey = kParam.isPrivate();
|
||||||
|
this.forEncryption = forEncryption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getInputBlockSize()
|
||||||
|
{
|
||||||
|
int baseBlockSize = engine.getInputBlockSize();
|
||||||
|
|
||||||
|
if (forEncryption)
|
||||||
|
{
|
||||||
|
return baseBlockSize - HEADER_LENGTH;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return baseBlockSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOutputBlockSize()
|
||||||
|
{
|
||||||
|
int baseBlockSize = engine.getOutputBlockSize();
|
||||||
|
|
||||||
|
if (forEncryption)
|
||||||
|
{
|
||||||
|
return baseBlockSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return baseBlockSize - HEADER_LENGTH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] processBlock(
|
||||||
|
byte[] in,
|
||||||
|
int inOff,
|
||||||
|
int inLen)
|
||||||
|
throws InvalidCipherTextException
|
||||||
|
{
|
||||||
|
if (forEncryption)
|
||||||
|
{
|
||||||
|
return encodeBlock(in, inOff, inLen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return decodeBlock(in, inOff, inLen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] encodeBlock(
|
||||||
|
byte[] in,
|
||||||
|
int inOff,
|
||||||
|
int inLen)
|
||||||
|
throws InvalidCipherTextException
|
||||||
|
{
|
||||||
|
if (inLen > getInputBlockSize())
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("input data too large");
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] block = new byte[engine.getInputBlockSize()];
|
||||||
|
|
||||||
|
if (forPrivateKey)
|
||||||
|
{
|
||||||
|
block[0] = 0x01; // type code 1
|
||||||
|
|
||||||
|
for (int i = 1; i != block.length - inLen - 1; i++)
|
||||||
|
{
|
||||||
|
block[i] = (byte)0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
random.nextBytes(block); // random fill
|
||||||
|
|
||||||
|
block[0] = 0x02; // type code 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// a zero byte marks the end of the padding, so all
|
||||||
|
// the pad bytes must be non-zero.
|
||||||
|
//
|
||||||
|
for (int i = 1; i != block.length - inLen - 1; i++)
|
||||||
|
{
|
||||||
|
while (block[i] == 0)
|
||||||
|
{
|
||||||
|
block[i] = (byte)random.nextInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
block[block.length - inLen - 1] = 0x00; // mark the end of the padding
|
||||||
|
System.arraycopy(in, inOff, block, block.length - inLen, inLen);
|
||||||
|
|
||||||
|
return engine.processBlock(block, 0, block.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @exception InvalidCipherTextException if the decrypted block is not in PKCS1 format.
|
||||||
|
*/
|
||||||
|
private byte[] decodeBlock(
|
||||||
|
byte[] in,
|
||||||
|
int inOff,
|
||||||
|
int inLen)
|
||||||
|
throws InvalidCipherTextException
|
||||||
|
{
|
||||||
|
byte[] block = engine.processBlock(in, inOff, inLen);
|
||||||
|
|
||||||
|
if (block.length < getOutputBlockSize())
|
||||||
|
{
|
||||||
|
throw new InvalidCipherTextException("block truncated");
|
||||||
|
}
|
||||||
|
|
||||||
|
byte type = block[0];
|
||||||
|
|
||||||
|
if (type != 1 && type != 2)
|
||||||
|
{
|
||||||
|
throw new InvalidCipherTextException("unknown block type");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (useStrictLength && block.length != engine.getOutputBlockSize())
|
||||||
|
{
|
||||||
|
throw new InvalidCipherTextException("block incorrect size");
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// find and extract the message block.
|
||||||
|
//
|
||||||
|
int start;
|
||||||
|
|
||||||
|
for (start = 1; start != block.length; start++)
|
||||||
|
{
|
||||||
|
byte pad = block[start];
|
||||||
|
|
||||||
|
if (pad == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (type == 1 && pad != (byte)0xff)
|
||||||
|
{
|
||||||
|
throw new InvalidCipherTextException("block padding incorrect");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start++; // data should start at the next byte
|
||||||
|
|
||||||
|
if (start > block.length || start < HEADER_LENGTH)
|
||||||
|
{
|
||||||
|
throw new InvalidCipherTextException("no data in block");
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] result = new byte[block.length - start];
|
||||||
|
|
||||||
|
System.arraycopy(block, start, result, 0, result.length);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
177
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/examples/MIDPTest.java
vendored
Normal file
177
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/examples/MIDPTest.java
vendored
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
package org.spongycastle.crypto.examples;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.*;
|
||||||
|
|
||||||
|
import javax.microedition.midlet.MIDlet;
|
||||||
|
import javax.microedition.lcdui.*;
|
||||||
|
|
||||||
|
import org.spongycastle.util.test.*;
|
||||||
|
import org.spongycastle.util.encoders.*;
|
||||||
|
|
||||||
|
import org.spongycastle.crypto.*;
|
||||||
|
import org.spongycastle.crypto.paddings.*;
|
||||||
|
import org.spongycastle.crypto.engines.*;
|
||||||
|
import org.spongycastle.crypto.modes.*;
|
||||||
|
import org.spongycastle.crypto.params.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MIDP is a simple graphics application for the J2ME CLDC/MIDP.
|
||||||
|
*
|
||||||
|
* It has hardcoded values for the key and plain text. It also performs the
|
||||||
|
* standard testing for the chosen cipher, and displays the results.
|
||||||
|
*
|
||||||
|
* This example shows how to use the light-weight API and a symmetric cipher.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class MIDPTest extends MIDlet
|
||||||
|
{
|
||||||
|
private Display d = null;
|
||||||
|
|
||||||
|
private boolean doneEncrypt = false;
|
||||||
|
|
||||||
|
private String key = "0123456789abcdef0123456789abcdef";
|
||||||
|
private String plainText = "www.bouncycastle.org";
|
||||||
|
private byte[] keyBytes = null;
|
||||||
|
private byte[] cipherText = null;
|
||||||
|
private BufferedBlockCipher cipher = null;
|
||||||
|
|
||||||
|
private String[] cipherNames = {"DES", "DESede", "IDEA", "Rijndael", "Twofish"};
|
||||||
|
|
||||||
|
private Form output = null;
|
||||||
|
|
||||||
|
public void startApp()
|
||||||
|
{
|
||||||
|
Display.getDisplay(this).setCurrent(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void pauseApp()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroyApp(boolean unconditional)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public MIDPTest()
|
||||||
|
{
|
||||||
|
output = new Form("BouncyCastle");
|
||||||
|
output.append("Key: " + key.substring(0, 7) + "...\n");
|
||||||
|
output.append("In : " + plainText.substring(0, 7) + "...\n");
|
||||||
|
|
||||||
|
cipherText = performEncrypt(Hex.decode(key.getBytes()), plainText);
|
||||||
|
String ctS = new String(Hex.encode(cipherText));
|
||||||
|
|
||||||
|
output.append("\nCT : " + ctS.substring(0, 7) + "...\n");
|
||||||
|
|
||||||
|
String decryptText = performDecrypt(Hex.decode(key.getBytes()), cipherText);
|
||||||
|
|
||||||
|
output.append("PT : " + decryptText.substring(0, 7) + "...\n");
|
||||||
|
|
||||||
|
if (decryptText.compareTo(plainText) == 0)
|
||||||
|
{
|
||||||
|
output.append("Success");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
output.append("Failure");
|
||||||
|
message("[" + plainText + "]");
|
||||||
|
message("[" + decryptText + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] performEncrypt(byte[] key, String plainText)
|
||||||
|
{
|
||||||
|
byte[] ptBytes = plainText.getBytes();
|
||||||
|
|
||||||
|
cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(getEngineInstance()));
|
||||||
|
|
||||||
|
String name = cipher.getUnderlyingCipher().getAlgorithmName();
|
||||||
|
message("Using " + name);
|
||||||
|
|
||||||
|
cipher.init(true, new KeyParameter(key));
|
||||||
|
|
||||||
|
byte[] rv = new byte[cipher.getOutputSize(ptBytes.length)];
|
||||||
|
|
||||||
|
int oLen = cipher.processBytes(ptBytes, 0, ptBytes.length, rv, 0);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cipher.doFinal(rv, oLen);
|
||||||
|
}
|
||||||
|
catch (CryptoException ce)
|
||||||
|
{
|
||||||
|
message("Ooops, encrypt exception");
|
||||||
|
status(ce.toString());
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String performDecrypt(byte[] key, byte[] cipherText)
|
||||||
|
{
|
||||||
|
cipher.init(false, new KeyParameter(key));
|
||||||
|
|
||||||
|
byte[] rv = new byte[cipher.getOutputSize(cipherText.length)];
|
||||||
|
|
||||||
|
int oLen = cipher.processBytes(cipherText, 0, cipherText.length, rv, 0);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cipher.doFinal(rv, oLen);
|
||||||
|
}
|
||||||
|
catch (CryptoException ce)
|
||||||
|
{
|
||||||
|
message("Ooops, decrypt exception");
|
||||||
|
status(ce.toString());
|
||||||
|
}
|
||||||
|
return new String(rv).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int whichCipher()
|
||||||
|
{
|
||||||
|
return 4; // DES
|
||||||
|
}
|
||||||
|
|
||||||
|
private BlockCipher getEngineInstance()
|
||||||
|
{
|
||||||
|
// returns a block cipher according to the current
|
||||||
|
// state of the radio button lists. This is only
|
||||||
|
// done prior to encryption.
|
||||||
|
BlockCipher rv = null;
|
||||||
|
|
||||||
|
switch (whichCipher())
|
||||||
|
{
|
||||||
|
case 0 :
|
||||||
|
rv = new DESEngine();
|
||||||
|
break;
|
||||||
|
case 1 :
|
||||||
|
rv = new DESedeEngine();
|
||||||
|
break;
|
||||||
|
case 2 :
|
||||||
|
rv = new IDEAEngine();
|
||||||
|
break;
|
||||||
|
case 3 :
|
||||||
|
rv = new RijndaelEngine();
|
||||||
|
break;
|
||||||
|
case 4 :
|
||||||
|
rv = new TwofishEngine();
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
rv = new DESEngine();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void message(String s)
|
||||||
|
{
|
||||||
|
System.out.println("M:" + s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void status(String s)
|
||||||
|
{
|
||||||
|
System.out.println("S:" + s);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
6
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/examples/midp_test.jad
vendored
Normal file
6
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/examples/midp_test.jad
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
MIDlet-1: MIDPTest, , org.spongycastle.crypto.examples.MIDPTest
|
||||||
|
MIDlet-Name: MIDPTest
|
||||||
|
MIDlet-Jar-Size: 300000
|
||||||
|
MIDlet-Jar-URL: midp_test.jar
|
||||||
|
MIDlet-Vendor: The Legion of the Bouncy Castle
|
||||||
|
MIDlet-Version: 1.0.0
|
7
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/examples/midp_test.mf
vendored
Normal file
7
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/examples/midp_test.mf
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
MIDlet-1: MIDPTTest, , org.spongycastle.crypto.examples.MIDPTest
|
||||||
|
MIDlet-Name: MIDPTest
|
||||||
|
MIDlet-Version: 1.0.0
|
||||||
|
MIDlet-Vendor: Jon Eaves
|
||||||
|
Created-By: 1.3.1 (Sun Microsystems Inc.)
|
||||||
|
MicroEdition-Configuration: CLDC-1.0
|
||||||
|
MicroEdition-Profile: MIDP-1.0
|
258
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/params/SkeinParameters.java
vendored
Normal file
258
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/params/SkeinParameters.java
vendored
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
package org.spongycastle.crypto.params;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
|
||||||
|
import org.spongycastle.crypto.CipherParameters;
|
||||||
|
import org.spongycastle.crypto.digests.SkeinDigest;
|
||||||
|
import org.spongycastle.crypto.digests.SkeinEngine;
|
||||||
|
import org.spongycastle.crypto.macs.SkeinMac;
|
||||||
|
import org.spongycastle.util.Integers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters for the Skein hash function - a series of byte[] strings identified by integer tags.
|
||||||
|
* <p/>
|
||||||
|
* Parameterised Skein can be used for:
|
||||||
|
* <ul>
|
||||||
|
* <li>MAC generation, by providing a {@link SkeinParameters.Builder#setKey(byte[]) key}.</li>
|
||||||
|
* <li>Randomised hashing, by providing a {@link SkeinParameters.Builder#setNonce(byte[]) nonce}.</li>
|
||||||
|
* <li>A hash function for digital signatures, associating a
|
||||||
|
* {@link SkeinParameters.Builder#setPublicKey(byte[]) public key} with the message digest.</li>
|
||||||
|
* <li>A key derivation function, by providing a
|
||||||
|
* {@link SkeinParameters.Builder#setKeyIdentifier(byte[]) key identifier}.</li>
|
||||||
|
* <li>Personalised hashing, by providing a
|
||||||
|
* {@link SkeinParameters.Builder#setPersonalisation(Date, String, String) recommended format} or
|
||||||
|
* {@link SkeinParameters.Builder#setPersonalisation(byte[]) arbitrary} personalisation string.</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @see SkeinEngine
|
||||||
|
* @see SkeinDigest
|
||||||
|
* @see SkeinMac
|
||||||
|
*/
|
||||||
|
public class SkeinParameters
|
||||||
|
implements CipherParameters
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The parameter type for a secret key, supporting MAC or KDF functions: {@value
|
||||||
|
* #PARAM_TYPE_KEY}.
|
||||||
|
*/
|
||||||
|
public static final int PARAM_TYPE_KEY = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter type for the Skein configuration block: {@value #PARAM_TYPE_CONFIG}.
|
||||||
|
*/
|
||||||
|
public static final int PARAM_TYPE_CONFIG = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter type for a personalisation string: {@value #PARAM_TYPE_PERSONALISATION}.
|
||||||
|
*/
|
||||||
|
public static final int PARAM_TYPE_PERSONALISATION = 8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter type for a public key: {@value #PARAM_TYPE_PUBLIC_KEY}.
|
||||||
|
*/
|
||||||
|
public static final int PARAM_TYPE_PUBLIC_KEY = 12;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter type for a key identifier string: {@value #PARAM_TYPE_KEY_IDENTIFIER}.
|
||||||
|
*/
|
||||||
|
public static final int PARAM_TYPE_KEY_IDENTIFIER = 16;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter type for a nonce: {@value #PARAM_TYPE_NONCE}.
|
||||||
|
*/
|
||||||
|
public static final int PARAM_TYPE_NONCE = 20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter type for the message: {@value #PARAM_TYPE_MESSAGE}.
|
||||||
|
*/
|
||||||
|
public static final int PARAM_TYPE_MESSAGE = 48;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameter type for the output transformation: {@value #PARAM_TYPE_OUTPUT}.
|
||||||
|
*/
|
||||||
|
public static final int PARAM_TYPE_OUTPUT = 63;
|
||||||
|
|
||||||
|
private Hashtable parameters;
|
||||||
|
|
||||||
|
public SkeinParameters()
|
||||||
|
{
|
||||||
|
this(new Hashtable());
|
||||||
|
}
|
||||||
|
|
||||||
|
private SkeinParameters(final Hashtable parameters)
|
||||||
|
{
|
||||||
|
this.parameters = parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains a map of type (Integer) to value (byte[]) for the parameters tracked in this object.
|
||||||
|
*/
|
||||||
|
public Hashtable getParameters()
|
||||||
|
{
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains the value of the {@link #PARAM_TYPE_KEY key parameter}, or <code>null</code> if not
|
||||||
|
* set.
|
||||||
|
*/
|
||||||
|
public byte[] getKey()
|
||||||
|
{
|
||||||
|
return (byte[])parameters.get(Integers.valueOf(PARAM_TYPE_KEY));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains the value of the {@link #PARAM_TYPE_PERSONALISATION personalisation parameter}, or
|
||||||
|
* <code>null</code> if not set.
|
||||||
|
*/
|
||||||
|
public byte[] getPersonalisation()
|
||||||
|
{
|
||||||
|
return (byte[])parameters.get(Integers.valueOf(PARAM_TYPE_PERSONALISATION));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains the value of the {@link #PARAM_TYPE_PUBLIC_KEY public key parameter}, or
|
||||||
|
* <code>null</code> if not set.
|
||||||
|
*/
|
||||||
|
public byte[] getPublicKey()
|
||||||
|
{
|
||||||
|
return (byte[])parameters.get(Integers.valueOf(PARAM_TYPE_PUBLIC_KEY));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains the value of the {@link #PARAM_TYPE_KEY_IDENTIFIER key identifier parameter}, or
|
||||||
|
* <code>null</code> if not set.
|
||||||
|
*/
|
||||||
|
public byte[] getKeyIdentifier()
|
||||||
|
{
|
||||||
|
return (byte[])parameters.get(Integers.valueOf(PARAM_TYPE_KEY_IDENTIFIER));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains the value of the {@link #PARAM_TYPE_NONCE nonce parameter}, or <code>null</code> if
|
||||||
|
* not set.
|
||||||
|
*/
|
||||||
|
public byte[] getNonce()
|
||||||
|
{
|
||||||
|
return (byte[])parameters.get(Integers.valueOf(PARAM_TYPE_NONCE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder for {@link SkeinParameters}.
|
||||||
|
*/
|
||||||
|
public static class Builder
|
||||||
|
{
|
||||||
|
private Hashtable parameters = new Hashtable();
|
||||||
|
|
||||||
|
public Builder()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder(Hashtable paramsMap)
|
||||||
|
{
|
||||||
|
Enumeration keys = paramsMap.keys();
|
||||||
|
while (keys.hasMoreElements())
|
||||||
|
{
|
||||||
|
Integer key = (Integer)keys.nextElement();
|
||||||
|
parameters.put(key, paramsMap.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder(SkeinParameters params)
|
||||||
|
{
|
||||||
|
Enumeration keys = params.parameters.keys();
|
||||||
|
while (keys.hasMoreElements())
|
||||||
|
{
|
||||||
|
Integer key = (Integer)keys.nextElement();
|
||||||
|
parameters.put(key, params.parameters.get(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a parameters to apply to the Skein hash function.<br>
|
||||||
|
* Parameter types must be in the range 0,5..62, and cannot use the value {@value
|
||||||
|
* SkeinParameters#PARAM_TYPE_MESSAGE} (reserved for message body).
|
||||||
|
* <p/>
|
||||||
|
* Parameters with type < {@value SkeinParameters#PARAM_TYPE_MESSAGE} are processed before
|
||||||
|
* the message content, parameters with type > {@value SkeinParameters#PARAM_TYPE_MESSAGE}
|
||||||
|
* are processed after the message and prior to output.
|
||||||
|
*
|
||||||
|
* @param type the type of the parameter, in the range 5..62.
|
||||||
|
* @param value the byte sequence of the parameter.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Builder set(int type, byte[] value)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Parameter value must not be null.");
|
||||||
|
}
|
||||||
|
if ((type != PARAM_TYPE_KEY)
|
||||||
|
&& (type <= PARAM_TYPE_CONFIG || type >= PARAM_TYPE_OUTPUT || type == PARAM_TYPE_MESSAGE))
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Parameter types must be in the range 0,5..47,49..62.");
|
||||||
|
}
|
||||||
|
if (type == PARAM_TYPE_CONFIG)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Parameter type " + PARAM_TYPE_CONFIG
|
||||||
|
+ " is reserved for internal use.");
|
||||||
|
}
|
||||||
|
this.parameters.put(Integers.valueOf(type), value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link SkeinParameters#PARAM_TYPE_KEY} parameter.
|
||||||
|
*/
|
||||||
|
public Builder setKey(byte[] key)
|
||||||
|
{
|
||||||
|
return set(PARAM_TYPE_KEY, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link SkeinParameters#PARAM_TYPE_PERSONALISATION} parameter.
|
||||||
|
*/
|
||||||
|
public Builder setPersonalisation(byte[] personalisation)
|
||||||
|
{
|
||||||
|
return set(PARAM_TYPE_PERSONALISATION, personalisation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link SkeinParameters#PARAM_TYPE_KEY_IDENTIFIER} parameter.
|
||||||
|
*/
|
||||||
|
public Builder setPublicKey(byte[] publicKey)
|
||||||
|
{
|
||||||
|
return set(PARAM_TYPE_PUBLIC_KEY, publicKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link SkeinParameters#PARAM_TYPE_KEY_IDENTIFIER} parameter.
|
||||||
|
*/
|
||||||
|
public Builder setKeyIdentifier(byte[] keyIdentifier)
|
||||||
|
{
|
||||||
|
return set(PARAM_TYPE_KEY_IDENTIFIER, keyIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link SkeinParameters#PARAM_TYPE_NONCE} parameter.
|
||||||
|
*/
|
||||||
|
public Builder setNonce(byte[] nonce)
|
||||||
|
{
|
||||||
|
return set(PARAM_TYPE_NONCE, nonce);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link SkeinParameters} instance with the parameters provided to this
|
||||||
|
* builder.
|
||||||
|
*/
|
||||||
|
public SkeinParameters build()
|
||||||
|
{
|
||||||
|
return new SkeinParameters(parameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
131
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/tls/OCSPStatusRequest.java
vendored
Normal file
131
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/tls/OCSPStatusRequest.java
vendored
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
package org.spongycastle.crypto.tls;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.spongycastle.asn1.ASN1Encoding;
|
||||||
|
import org.spongycastle.asn1.ocsp.ResponderID;
|
||||||
|
import org.spongycastle.asn1.x509.Extensions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RFC 3546 3.6
|
||||||
|
*/
|
||||||
|
public class OCSPStatusRequest
|
||||||
|
{
|
||||||
|
protected Vector responderIDList;
|
||||||
|
protected Extensions requestExtensions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param responderIDList
|
||||||
|
* a {@link Vector} of {@link ResponderID}, specifying the list of trusted OCSP
|
||||||
|
* responders. An empty list has the special meaning that the responders are
|
||||||
|
* implicitly known to the server - e.g., by prior arrangement.
|
||||||
|
* @param requestExtensions
|
||||||
|
* OCSP request extensions. A null value means that there are no extensions.
|
||||||
|
*/
|
||||||
|
public OCSPStatusRequest(Vector responderIDList, Extensions requestExtensions)
|
||||||
|
{
|
||||||
|
this.responderIDList = responderIDList;
|
||||||
|
this.requestExtensions = requestExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a {@link Vector} of {@link ResponderID}
|
||||||
|
*/
|
||||||
|
public Vector getResponderIDList()
|
||||||
|
{
|
||||||
|
return responderIDList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return OCSP request extensions
|
||||||
|
*/
|
||||||
|
public Extensions getRequestExtensions()
|
||||||
|
{
|
||||||
|
return requestExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode this {@link OCSPStatusRequest} to an {@link OutputStream}.
|
||||||
|
*
|
||||||
|
* @param output
|
||||||
|
* the {@link OutputStream} to encode to.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void encode(OutputStream output) throws IOException
|
||||||
|
{
|
||||||
|
if (responderIDList == null || responderIDList.isEmpty())
|
||||||
|
{
|
||||||
|
TlsUtils.writeUint16(0, output);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||||
|
for (int i = 0; i < responderIDList.size(); ++i)
|
||||||
|
{
|
||||||
|
ResponderID responderID = (ResponderID) responderIDList.elementAt(i);
|
||||||
|
byte[] derEncoding = responderID.getEncoded(ASN1Encoding.DER);
|
||||||
|
TlsUtils.writeOpaque16(derEncoding, buf);
|
||||||
|
}
|
||||||
|
TlsUtils.checkUint16(buf.size());
|
||||||
|
TlsUtils.writeUint16(buf.size(), output);
|
||||||
|
output.write(buf.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestExtensions == null)
|
||||||
|
{
|
||||||
|
TlsUtils.writeUint16(0, output);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte[] derEncoding = requestExtensions.getEncoded(ASN1Encoding.DER);
|
||||||
|
TlsUtils.checkUint16(derEncoding.length);
|
||||||
|
TlsUtils.writeUint16(derEncoding.length, output);
|
||||||
|
output.write(derEncoding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a {@link OCSPStatusRequest} from an {@link InputStream}.
|
||||||
|
*
|
||||||
|
* @param input
|
||||||
|
* the {@link InputStream} to parse from.
|
||||||
|
* @return a {@link OCSPStatusRequest} object.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static OCSPStatusRequest parse(InputStream input) throws IOException
|
||||||
|
{
|
||||||
|
Vector responderIDList = new Vector();
|
||||||
|
{
|
||||||
|
int length = TlsUtils.readUint16(input);
|
||||||
|
if (length > 0)
|
||||||
|
{
|
||||||
|
byte[] data = TlsUtils.readFully(length, input);
|
||||||
|
ByteArrayInputStream buf = new ByteArrayInputStream(data);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
byte[] derEncoding = TlsUtils.readOpaque16(buf);
|
||||||
|
ResponderID responderID = ResponderID.getInstance(TlsUtils.readDERObject(derEncoding));
|
||||||
|
responderIDList.addElement(responderID);
|
||||||
|
}
|
||||||
|
while (buf.available() > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Extensions requestExtensions = null;
|
||||||
|
{
|
||||||
|
int length = TlsUtils.readUint16(input);
|
||||||
|
if (length > 0)
|
||||||
|
{
|
||||||
|
byte[] derEncoding = TlsUtils.readFully(length, input);
|
||||||
|
requestExtensions = Extensions.getInstance(TlsUtils.readDERObject(derEncoding));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OCSPStatusRequest(responderIDList, requestExtensions);
|
||||||
|
}
|
||||||
|
}
|
86
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/tls/ServerNameList.java
vendored
Normal file
86
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/tls/ServerNameList.java
vendored
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package org.spongycastle.crypto.tls;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
public class ServerNameList
|
||||||
|
{
|
||||||
|
protected Vector serverNameList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param serverNameList a {@link Vector} of {@link ServerName}.
|
||||||
|
*/
|
||||||
|
public ServerNameList(Vector serverNameList)
|
||||||
|
{
|
||||||
|
if (serverNameList == null || serverNameList.isEmpty())
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("'serverNameList' must not be null or empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.serverNameList = serverNameList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a {@link Vector} of {@link ServerName}.
|
||||||
|
*/
|
||||||
|
public Vector getServerNameList()
|
||||||
|
{
|
||||||
|
return serverNameList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode this {@link ServerNameList} to an {@link OutputStream}.
|
||||||
|
*
|
||||||
|
* @param output
|
||||||
|
* the {@link OutputStream} to encode to.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void encode(OutputStream output) throws IOException
|
||||||
|
{
|
||||||
|
ByteArrayOutputStream buf = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
for (int i = 0; i < serverNameList.size(); ++i)
|
||||||
|
{
|
||||||
|
ServerName entry = (ServerName)serverNameList.elementAt(i);
|
||||||
|
entry.encode(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
TlsUtils.checkUint16(buf.size());
|
||||||
|
TlsUtils.writeUint16(buf.size(), output);
|
||||||
|
output.write(buf.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a {@link ServerNameList} from an {@link InputStream}.
|
||||||
|
*
|
||||||
|
* @param input
|
||||||
|
* the {@link InputStream} to parse from.
|
||||||
|
* @return a {@link ServerNameList} object.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static ServerNameList parse(InputStream input) throws IOException
|
||||||
|
{
|
||||||
|
int length = TlsUtils.readUint16(input);
|
||||||
|
if (length < 1)
|
||||||
|
{
|
||||||
|
throw new TlsFatalAlert(AlertDescription.decode_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] data = TlsUtils.readFully(length, input);
|
||||||
|
|
||||||
|
ByteArrayInputStream buf = new ByteArrayInputStream(data);
|
||||||
|
|
||||||
|
Vector server_name_list = new Vector();
|
||||||
|
while (buf.available() > 0)
|
||||||
|
{
|
||||||
|
ServerName entry = ServerName.parse(buf);
|
||||||
|
server_name_list.addElement(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ServerNameList(server_name_list);
|
||||||
|
}
|
||||||
|
}
|
107
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/tls/UDPTransport.java
vendored
Normal file
107
extern/spongycastle/core/src/main/j2me/org/spongycastle/crypto/tls/UDPTransport.java
vendored
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package org.spongycastle.crypto.tls;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import javax.microedition.io.DatagramConnection;
|
||||||
|
import javax.microedition.io.Datagram;
|
||||||
|
|
||||||
|
public class UDPTransport
|
||||||
|
implements DatagramTransport
|
||||||
|
{
|
||||||
|
|
||||||
|
protected final static int MIN_IP_OVERHEAD = 20;
|
||||||
|
protected final static int MAX_IP_OVERHEAD = MIN_IP_OVERHEAD + 64;
|
||||||
|
protected final static int UDP_OVERHEAD = 8;
|
||||||
|
|
||||||
|
protected final DatagramConnection socket;
|
||||||
|
protected final int receiveLimit, sendLimit;
|
||||||
|
|
||||||
|
public UDPTransport(DatagramConnection socket, int mtu)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// In 1.3 and earlier sockets were bound and connected during creation
|
||||||
|
//
|
||||||
|
//if (!socket.isBound() || !socket.isConnected())
|
||||||
|
//{
|
||||||
|
// throw new IllegalArgumentException("'socket' must be bound and connected");
|
||||||
|
//}
|
||||||
|
|
||||||
|
this.socket = socket;
|
||||||
|
|
||||||
|
// NOTE: As of JDK 1.6, can use NetworkInterface.getMTU
|
||||||
|
|
||||||
|
this.receiveLimit = mtu - MIN_IP_OVERHEAD - UDP_OVERHEAD;
|
||||||
|
this.sendLimit = mtu - MAX_IP_OVERHEAD - UDP_OVERHEAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getReceiveLimit()
|
||||||
|
{
|
||||||
|
return receiveLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSendLimit()
|
||||||
|
{
|
||||||
|
// TODO[DTLS] Implement Path-MTU discovery?
|
||||||
|
return sendLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int receive(byte[] buf, int off, int len, int waitMillis)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
//socket.setSoTimeout(waitMillis); -- not applicable
|
||||||
|
|
||||||
|
if (off == 0)
|
||||||
|
{
|
||||||
|
Datagram packet = socket.newDatagram(buf, len);
|
||||||
|
socket.receive(packet);
|
||||||
|
|
||||||
|
return packet.getLength();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte[] rv = new byte[len];
|
||||||
|
|
||||||
|
Datagram packet = socket.newDatagram(rv, len);
|
||||||
|
socket.receive(packet);
|
||||||
|
|
||||||
|
System.arraycopy(rv, 0, buf, off, packet.getLength());
|
||||||
|
|
||||||
|
return packet.getLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(byte[] buf, int off, int len)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (len > getSendLimit())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* RFC 4347 4.1.1. "If the application attempts to send a record larger than the MTU,
|
||||||
|
* the DTLS implementation SHOULD generate an error, thus avoiding sending a packet
|
||||||
|
* which will be fragmented."
|
||||||
|
*/
|
||||||
|
// TODO Exception
|
||||||
|
}
|
||||||
|
|
||||||
|
if (off == 0)
|
||||||
|
{
|
||||||
|
Datagram packet = socket.newDatagram(buf, len);
|
||||||
|
socket.send(packet);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
byte[] data = new byte[len];
|
||||||
|
|
||||||
|
System.arraycopy(buf, off, data, 0, len);
|
||||||
|
|
||||||
|
Datagram packet = socket.newDatagram(data, len);
|
||||||
|
socket.send(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
}
|
1997
extern/spongycastle/core/src/main/j2me/org/spongycastle/math/ec/LongArray.java
vendored
Normal file
1997
extern/spongycastle/core/src/main/j2me/org/spongycastle/math/ec/LongArray.java
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9
extern/spongycastle/core/src/main/j2me/org/spongycastle/util/Integers.java
vendored
Normal file
9
extern/spongycastle/core/src/main/j2me/org/spongycastle/util/Integers.java
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package org.spongycastle.util;
|
||||||
|
|
||||||
|
public class Integers
|
||||||
|
{
|
||||||
|
public static Integer valueOf(int value)
|
||||||
|
{
|
||||||
|
return new Integer(value);
|
||||||
|
}
|
||||||
|
}
|
8
extern/spongycastle/core/src/main/j2me/org/spongycastle/util/Selector.java
vendored
Normal file
8
extern/spongycastle/core/src/main/j2me/org/spongycastle/util/Selector.java
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package org.spongycastle.util;
|
||||||
|
|
||||||
|
public interface Selector
|
||||||
|
{
|
||||||
|
boolean match(Object obj);
|
||||||
|
|
||||||
|
Object clone();
|
||||||
|
}
|
9
extern/spongycastle/core/src/main/j2me/org/spongycastle/util/Shorts.java
vendored
Normal file
9
extern/spongycastle/core/src/main/j2me/org/spongycastle/util/Shorts.java
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package org.spongycastle.util;
|
||||||
|
|
||||||
|
public class Shorts
|
||||||
|
{
|
||||||
|
public static Short valueOf(short value)
|
||||||
|
{
|
||||||
|
return new Short(value);
|
||||||
|
}
|
||||||
|
}
|
84
extern/spongycastle/core/src/main/j2me/org/spongycastle/util/test/SimpleTest.java
vendored
Normal file
84
extern/spongycastle/core/src/main/j2me/org/spongycastle/util/test/SimpleTest.java
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package org.spongycastle.util.test;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
import org.spongycastle.util.Arrays;
|
||||||
|
|
||||||
|
public abstract class SimpleTest
|
||||||
|
implements Test
|
||||||
|
{
|
||||||
|
public abstract String getName();
|
||||||
|
|
||||||
|
private TestResult success()
|
||||||
|
{
|
||||||
|
return SimpleTestResult.successful(this, "Okay");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fail(
|
||||||
|
String message)
|
||||||
|
{
|
||||||
|
throw new TestFailedException(SimpleTestResult.failed(this, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fail(
|
||||||
|
String message,
|
||||||
|
Throwable throwable)
|
||||||
|
{
|
||||||
|
throw new TestFailedException(SimpleTestResult.failed(this, message, throwable));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fail(
|
||||||
|
String message,
|
||||||
|
Object expected,
|
||||||
|
Object found)
|
||||||
|
{
|
||||||
|
throw new TestFailedException(SimpleTestResult.failed(this, message, expected, found));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean areEqual(
|
||||||
|
byte[] a,
|
||||||
|
byte[] b)
|
||||||
|
{
|
||||||
|
return Arrays.areEqual(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestResult perform()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
performTest();
|
||||||
|
|
||||||
|
return success();
|
||||||
|
}
|
||||||
|
catch (TestFailedException e)
|
||||||
|
{
|
||||||
|
return e.getResult();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return SimpleTestResult.failed(this, "Exception: " + e, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void runTest(
|
||||||
|
Test test)
|
||||||
|
{
|
||||||
|
runTest(test, System.out);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void runTest(
|
||||||
|
Test test,
|
||||||
|
PrintStream out)
|
||||||
|
{
|
||||||
|
TestResult result = test.perform();
|
||||||
|
|
||||||
|
out.println(result.toString());
|
||||||
|
if (result.getException() != null)
|
||||||
|
{
|
||||||
|
result.getException().printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void performTest()
|
||||||
|
throws Exception;
|
||||||
|
}
|
63
extern/spongycastle/core/src/main/java/org/spongycastle/LICENSE.java
vendored
Normal file
63
extern/spongycastle/core/src/main/java/org/spongycastle/LICENSE.java
vendored
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package org.spongycastle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Bouncy Castle License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2000-2013 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-2013 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org) "
|
||||||
|
+ System.getProperty("line.separator")
|
||||||
|
+ System.getProperty("line.separator")
|
||||||
|
+ "Permission is hereby granted, free of charge, to any person obtaining a copy of this software "
|
||||||
|
+ 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);
|
||||||
|
}
|
||||||
|
}
|
10
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1ApplicationSpecificParser.java
vendored
Normal file
10
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1ApplicationSpecificParser.java
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface ASN1ApplicationSpecificParser
|
||||||
|
extends ASN1Encodable, InMemoryRepresentable
|
||||||
|
{
|
||||||
|
ASN1Encodable readObject()
|
||||||
|
throws IOException;
|
||||||
|
}
|
15
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Boolean.java
vendored
Normal file
15
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Boolean.java
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
public class ASN1Boolean
|
||||||
|
extends DERBoolean
|
||||||
|
{
|
||||||
|
public ASN1Boolean(boolean value)
|
||||||
|
{
|
||||||
|
super(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Boolean(byte[] value)
|
||||||
|
{
|
||||||
|
super(value);
|
||||||
|
}
|
||||||
|
}
|
14
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Choice.java
vendored
Normal file
14
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Choice.java
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package org.spongycastle.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
|
||||||
|
}
|
6
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Encodable.java
vendored
Normal file
6
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Encodable.java
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
public interface ASN1Encodable
|
||||||
|
{
|
||||||
|
ASN1Primitive toASN1Primitive();
|
||||||
|
}
|
36
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1EncodableVector.java
vendored
Normal file
36
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1EncodableVector.java
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
public class ASN1EncodableVector
|
||||||
|
{
|
||||||
|
Vector v = new Vector();
|
||||||
|
|
||||||
|
public ASN1EncodableVector()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(ASN1Encodable obj)
|
||||||
|
{
|
||||||
|
v.addElement(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAll(ASN1EncodableVector other)
|
||||||
|
{
|
||||||
|
for (Enumeration en = other.v.elements(); en.hasMoreElements();)
|
||||||
|
{
|
||||||
|
v.addElement(en.nextElement());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Encodable get(int i)
|
||||||
|
{
|
||||||
|
return (ASN1Encodable)v.elementAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size()
|
||||||
|
{
|
||||||
|
return v.size();
|
||||||
|
}
|
||||||
|
}
|
8
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Encoding.java
vendored
Normal file
8
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Encoding.java
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
public interface ASN1Encoding
|
||||||
|
{
|
||||||
|
static final String DER = "DER";
|
||||||
|
static final String DL = "DL";
|
||||||
|
static final String BER = "BER";
|
||||||
|
}
|
22
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Enumerated.java
vendored
Normal file
22
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Enumerated.java
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
public class ASN1Enumerated
|
||||||
|
extends DEREnumerated
|
||||||
|
{
|
||||||
|
ASN1Enumerated(byte[] bytes)
|
||||||
|
{
|
||||||
|
super(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Enumerated(BigInteger value)
|
||||||
|
{
|
||||||
|
super(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Enumerated(int value)
|
||||||
|
{
|
||||||
|
super(value);
|
||||||
|
}
|
||||||
|
}
|
25
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Exception.java
vendored
Normal file
25
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Exception.java
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class ASN1Exception
|
||||||
|
extends IOException
|
||||||
|
{
|
||||||
|
private Throwable cause;
|
||||||
|
|
||||||
|
ASN1Exception(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Exception(String message, Throwable cause)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
this.cause = cause;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Throwable getCause()
|
||||||
|
{
|
||||||
|
return cause;
|
||||||
|
}
|
||||||
|
}
|
22
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1GeneralizedTime.java
vendored
Normal file
22
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1GeneralizedTime.java
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class ASN1GeneralizedTime
|
||||||
|
extends DERGeneralizedTime
|
||||||
|
{
|
||||||
|
ASN1GeneralizedTime(byte[] bytes)
|
||||||
|
{
|
||||||
|
super(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1GeneralizedTime(Date time)
|
||||||
|
{
|
||||||
|
super(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1GeneralizedTime(String time)
|
||||||
|
{
|
||||||
|
super(time);
|
||||||
|
}
|
||||||
|
}
|
15
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Generator.java
vendored
Normal file
15
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Generator.java
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public abstract class ASN1Generator
|
||||||
|
{
|
||||||
|
protected OutputStream _out;
|
||||||
|
|
||||||
|
public ASN1Generator(OutputStream out)
|
||||||
|
{
|
||||||
|
_out = out;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract OutputStream getRawOutputStream();
|
||||||
|
}
|
466
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1InputStream.java
vendored
Normal file
466
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1InputStream.java
vendored
Normal file
@ -0,0 +1,466 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.FilterInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.spongycastle.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 BERTags
|
||||||
|
{
|
||||||
|
private final int limit;
|
||||||
|
private final boolean lazyEvaluate;
|
||||||
|
|
||||||
|
private final byte[][] tmpBuffers;
|
||||||
|
|
||||||
|
public ASN1InputStream(
|
||||||
|
InputStream is)
|
||||||
|
{
|
||||||
|
this(is, StreamUtil.findLimit(is));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 lazyEvaluate true if parsing inside constructed objects can be delayed.
|
||||||
|
*/
|
||||||
|
public ASN1InputStream(
|
||||||
|
InputStream input,
|
||||||
|
boolean lazyEvaluate)
|
||||||
|
{
|
||||||
|
this(input, StreamUtil.findLimit(input), lazyEvaluate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
this.tmpBuffers = new byte[11][];
|
||||||
|
}
|
||||||
|
|
||||||
|
int getLimit()
|
||||||
|
{
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ASN1Primitive 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 ASN1StreamParser(defIn).readTaggedObject(isConstructed, tagNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
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...
|
||||||
|
//
|
||||||
|
ASN1EncodableVector v = buildDEREncodableVector(defIn);
|
||||||
|
ASN1OctetString[] strings = new ASN1OctetString[v.size()];
|
||||||
|
|
||||||
|
for (int i = 0; i != strings.length; i++)
|
||||||
|
{
|
||||||
|
strings[i] = (ASN1OctetString)v.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BEROctetString(strings);
|
||||||
|
case SEQUENCE:
|
||||||
|
if (lazyEvaluate)
|
||||||
|
{
|
||||||
|
return new LazyEncodedSequence(defIn.toByteArray());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return DERFactory.createSequence(buildDEREncodableVector(defIn));
|
||||||
|
}
|
||||||
|
case SET:
|
||||||
|
return DERFactory.createSet(buildDEREncodableVector(defIn));
|
||||||
|
case EXTERNAL:
|
||||||
|
return new DERExternal(buildDEREncodableVector(defIn));
|
||||||
|
default:
|
||||||
|
throw new IOException("unknown tag " + tagNo + " encountered");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1EncodableVector buildEncodableVector()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||||
|
ASN1Primitive o;
|
||||||
|
|
||||||
|
while ((o = readObject()) != null)
|
||||||
|
{
|
||||||
|
v.add(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1EncodableVector buildDEREncodableVector(
|
||||||
|
DefiniteLengthInputStream dIn) throws IOException
|
||||||
|
{
|
||||||
|
return new ASN1InputStream(dIn).buildEncodableVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive 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, limit);
|
||||||
|
ASN1StreamParser sp = new ASN1StreamParser(indIn, limit);
|
||||||
|
|
||||||
|
if ((tag & APPLICATION) != 0)
|
||||||
|
{
|
||||||
|
return new BERApplicationSpecificParser(tagNo, sp).getLoadedObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tag & TAGGED) != 0)
|
||||||
|
{
|
||||||
|
return new BERTaggedObjectParser(true, tagNo, sp).getLoadedObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO There are other tags that may be constructed (e.g. BIT_STRING)
|
||||||
|
switch (tagNo)
|
||||||
|
{
|
||||||
|
case OCTET_STRING:
|
||||||
|
return new BEROctetStringParser(sp).getLoadedObject();
|
||||||
|
case SEQUENCE:
|
||||||
|
return new BERSequenceParser(sp).getLoadedObject();
|
||||||
|
case SET:
|
||||||
|
return new BERSetParser(sp).getLoadedObject();
|
||||||
|
case EXTERNAL:
|
||||||
|
return new DERExternalParser(sp).getLoadedObject();
|
||||||
|
default:
|
||||||
|
throw new IOException("unknown BER object encountered");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return buildObject(tag, tagNo, length);
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e)
|
||||||
|
{
|
||||||
|
throw new ASN1Exception("corrupted stream detected", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] getBuffer(DefiniteLengthInputStream defIn, byte[][] tmpBuffers)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
int len = defIn.getRemaining();
|
||||||
|
if (defIn.getRemaining() < tmpBuffers.length)
|
||||||
|
{
|
||||||
|
byte[] buf = tmpBuffers[len];
|
||||||
|
|
||||||
|
if (buf == null)
|
||||||
|
{
|
||||||
|
buf = tmpBuffers[len] = new byte[len];
|
||||||
|
}
|
||||||
|
|
||||||
|
Streams.readFully(defIn, buf);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return defIn.toByteArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static char[] getBMPCharBuffer(DefiniteLengthInputStream defIn)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
int len = defIn.getRemaining() / 2;
|
||||||
|
char[] buf = new char[len];
|
||||||
|
int totalRead = 0;
|
||||||
|
while (totalRead < len)
|
||||||
|
{
|
||||||
|
int ch1 = defIn.read();
|
||||||
|
if (ch1 < 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int ch2 = defIn.read();
|
||||||
|
if (ch2 < 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buf[totalRead++] = (char)((ch1 << 8) | (ch2 & 0xff));
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ASN1Primitive createPrimitiveDERObject(
|
||||||
|
int tagNo,
|
||||||
|
DefiniteLengthInputStream defIn,
|
||||||
|
byte[][] tmpBuffers)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
switch (tagNo)
|
||||||
|
{
|
||||||
|
case BIT_STRING:
|
||||||
|
return DERBitString.fromInputStream(defIn.getRemaining(), defIn);
|
||||||
|
case BMP_STRING:
|
||||||
|
return new DERBMPString(getBMPCharBuffer(defIn));
|
||||||
|
case BOOLEAN:
|
||||||
|
return ASN1Boolean.fromOctetString(getBuffer(defIn, tmpBuffers));
|
||||||
|
case ENUMERATED:
|
||||||
|
return ASN1Enumerated.fromOctetString(getBuffer(defIn, tmpBuffers));
|
||||||
|
case GENERALIZED_TIME:
|
||||||
|
return new ASN1GeneralizedTime(defIn.toByteArray());
|
||||||
|
case GENERAL_STRING:
|
||||||
|
return new DERGeneralString(defIn.toByteArray());
|
||||||
|
case IA5_STRING:
|
||||||
|
return new DERIA5String(defIn.toByteArray());
|
||||||
|
case INTEGER:
|
||||||
|
return new ASN1Integer(defIn.toByteArray());
|
||||||
|
case NULL:
|
||||||
|
return DERNull.INSTANCE; // actual content is ignored (enforce 0 length?)
|
||||||
|
case NUMERIC_STRING:
|
||||||
|
return new DERNumericString(defIn.toByteArray());
|
||||||
|
case OBJECT_IDENTIFIER:
|
||||||
|
return ASN1ObjectIdentifier.fromOctetString(getBuffer(defIn, tmpBuffers));
|
||||||
|
case OCTET_STRING:
|
||||||
|
return new DEROctetString(defIn.toByteArray());
|
||||||
|
case PRINTABLE_STRING:
|
||||||
|
return new DERPrintableString(defIn.toByteArray());
|
||||||
|
case T61_STRING:
|
||||||
|
return new DERT61String(defIn.toByteArray());
|
||||||
|
case UNIVERSAL_STRING:
|
||||||
|
return new DERUniversalString(defIn.toByteArray());
|
||||||
|
case UTC_TIME:
|
||||||
|
return new ASN1UTCTime(defIn.toByteArray());
|
||||||
|
case UTF8_STRING:
|
||||||
|
return new DERUTF8String(defIn.toByteArray());
|
||||||
|
case VISIBLE_STRING:
|
||||||
|
return new DERVisibleString(defIn.toByteArray());
|
||||||
|
default:
|
||||||
|
throw new IOException("unknown tag " + tagNo + " encountered");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Integer.java
vendored
Normal file
22
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Integer.java
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
public class ASN1Integer
|
||||||
|
extends DERInteger
|
||||||
|
{
|
||||||
|
ASN1Integer(byte[] bytes)
|
||||||
|
{
|
||||||
|
super(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Integer(BigInteger value)
|
||||||
|
{
|
||||||
|
super(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Integer(long value)
|
||||||
|
{
|
||||||
|
super(value);
|
||||||
|
}
|
||||||
|
}
|
67
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Null.java
vendored
Normal file
67
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Null.java
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A NULL object.
|
||||||
|
*/
|
||||||
|
public abstract class ASN1Null
|
||||||
|
extends ASN1Primitive
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @deprecated use DERNull.INSTANCE
|
||||||
|
*/
|
||||||
|
public ASN1Null()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ASN1Null getInstance(Object o)
|
||||||
|
{
|
||||||
|
if (o instanceof ASN1Null)
|
||||||
|
{
|
||||||
|
return (ASN1Null)o;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return ASN1Null.getInstance(ASN1Primitive.fromByteArray((byte[])o));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("failed to construct NULL from byte[]: " + e.getMessage());
|
||||||
|
}
|
||||||
|
catch (ClassCastException e)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("unknown object in getInstance(): " + o.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean asn1Equals(
|
||||||
|
ASN1Primitive o)
|
||||||
|
{
|
||||||
|
if (!(o instanceof ASN1Null))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract void encode(ASN1OutputStream out)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "NULL";
|
||||||
|
}
|
||||||
|
}
|
97
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Object.java
vendored
Normal file
97
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Object.java
vendored
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public abstract class ASN1Object
|
||||||
|
implements ASN1Encodable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Return the default BER or DER encoding for this object.
|
||||||
|
*
|
||||||
|
* @return BER/DER byte encoded object.
|
||||||
|
* @throws java.io.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(ASN1Encoding.DER))
|
||||||
|
{
|
||||||
|
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||||
|
DEROutputStream dOut = new DEROutputStream(bOut);
|
||||||
|
|
||||||
|
dOut.writeObject(this);
|
||||||
|
|
||||||
|
return bOut.toByteArray();
|
||||||
|
}
|
||||||
|
else if (encoding.equals(ASN1Encoding.DL))
|
||||||
|
{
|
||||||
|
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||||
|
DLOutputStream dOut = new DLOutputStream(bOut);
|
||||||
|
|
||||||
|
dOut.writeObject(this);
|
||||||
|
|
||||||
|
return bOut.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.getEncoded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return this.toASN1Primitive().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(
|
||||||
|
Object o)
|
||||||
|
{
|
||||||
|
if (this == o)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(o instanceof ASN1Encodable))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Encodable other = (ASN1Encodable)o;
|
||||||
|
|
||||||
|
return this.toASN1Primitive().equals(other.toASN1Primitive());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use toASN1Primitive()
|
||||||
|
* @return the underlying primitive type.
|
||||||
|
*/
|
||||||
|
public ASN1Primitive toASN1Object()
|
||||||
|
{
|
||||||
|
return this.toASN1Primitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static boolean hasEncodedTagValue(Object obj, int tagValue)
|
||||||
|
{
|
||||||
|
return (obj instanceof byte[]) && ((byte[])obj)[0] == tagValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract ASN1Primitive toASN1Primitive();
|
||||||
|
}
|
42
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1ObjectIdentifier.java
vendored
Normal file
42
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1ObjectIdentifier.java
vendored
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
public class ASN1ObjectIdentifier
|
||||||
|
extends DERObjectIdentifier
|
||||||
|
{
|
||||||
|
public ASN1ObjectIdentifier(String identifier)
|
||||||
|
{
|
||||||
|
super(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1ObjectIdentifier(byte[] bytes)
|
||||||
|
{
|
||||||
|
super(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1ObjectIdentifier(ASN1ObjectIdentifier oid, String branch)
|
||||||
|
{
|
||||||
|
super(oid, branch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an OID that creates a branch under the current one.
|
||||||
|
*
|
||||||
|
* @param branchID node numbers for the new branch.
|
||||||
|
* @return the OID for the new created branch.
|
||||||
|
*/
|
||||||
|
public ASN1ObjectIdentifier branch(String branchID)
|
||||||
|
{
|
||||||
|
return new ASN1ObjectIdentifier(this, branchID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if this oid is an extension of the passed in branch, stem.
|
||||||
|
* @param stem the arc or branch that is a possible parent.
|
||||||
|
* @return true if the branch is on the passed in stem, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean on(ASN1ObjectIdentifier stem)
|
||||||
|
{
|
||||||
|
String id = getId(), stemId = stem.getId();
|
||||||
|
return id.length() > stemId.length() && id.charAt(stemId.length()) == '.' && id.startsWith(stemId);
|
||||||
|
}
|
||||||
|
}
|
146
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1OctetString.java
vendored
Normal file
146
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1OctetString.java
vendored
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.spongycastle.util.Arrays;
|
||||||
|
import org.spongycastle.util.encoders.Hex;
|
||||||
|
|
||||||
|
public abstract class ASN1OctetString
|
||||||
|
extends ASN1Primitive
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
ASN1Primitive o = obj.getObject();
|
||||||
|
|
||||||
|
if (explicit || o instanceof ASN1OctetString)
|
||||||
|
{
|
||||||
|
return getInstance(o);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return BEROctetString.fromSequence(ASN1Sequence.getInstance(o));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
else if (obj instanceof byte[])
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return ASN1OctetString.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("failed to construct OCTET STRING from byte[]: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (obj instanceof ASN1Encodable)
|
||||||
|
{
|
||||||
|
ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
|
||||||
|
|
||||||
|
if (primitive instanceof ASN1OctetString)
|
||||||
|
{
|
||||||
|
return (ASN1OctetString)primitive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 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(
|
||||||
|
ASN1Primitive o)
|
||||||
|
{
|
||||||
|
if (!(o instanceof ASN1OctetString))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1OctetString other = (ASN1OctetString)o;
|
||||||
|
|
||||||
|
return Arrays.areEqual(string, other.string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive getLoadedObject()
|
||||||
|
{
|
||||||
|
return this.toASN1Primitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Primitive toDERObject()
|
||||||
|
{
|
||||||
|
return new DEROctetString(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Primitive toDLObject()
|
||||||
|
{
|
||||||
|
return new DEROctetString(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract void encode(ASN1OutputStream out)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "#"+new String(Hex.encode(string));
|
||||||
|
}
|
||||||
|
}
|
9
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1OctetStringParser.java
vendored
Normal file
9
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1OctetStringParser.java
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public interface ASN1OctetStringParser
|
||||||
|
extends ASN1Encodable, InMemoryRepresentable
|
||||||
|
{
|
||||||
|
public InputStream getOctetStream();
|
||||||
|
}
|
194
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1OutputStream.java
vendored
Normal file
194
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1OutputStream.java
vendored
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stream that produces output based on the default encoding for the passed in objects.
|
||||||
|
*/
|
||||||
|
public class ASN1OutputStream
|
||||||
|
{
|
||||||
|
private OutputStream os;
|
||||||
|
|
||||||
|
public ASN1OutputStream(
|
||||||
|
OutputStream os)
|
||||||
|
{
|
||||||
|
this.os = os;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 write(int b)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
os.write(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(byte[] bytes)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
os.write(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void write(byte[] bytes, int off, int len)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
os.write(bytes, off, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
os.write(BERTags.NULL);
|
||||||
|
os.write(0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeObject(
|
||||||
|
ASN1Encodable obj)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (obj != null)
|
||||||
|
{
|
||||||
|
obj.toASN1Primitive().encode(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IOException("null object detected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeImplicitObject(ASN1Primitive obj)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (obj != null)
|
||||||
|
{
|
||||||
|
obj.encode(new ImplicitOutputStream(os));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IOException("null object detected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
os.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
os.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1OutputStream getDERSubStream()
|
||||||
|
{
|
||||||
|
return new DEROutputStream(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1OutputStream getDLSubStream()
|
||||||
|
{
|
||||||
|
return new DLOutputStream(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ImplicitOutputStream
|
||||||
|
extends ASN1OutputStream
|
||||||
|
{
|
||||||
|
private boolean first = true;
|
||||||
|
|
||||||
|
public ImplicitOutputStream(OutputStream os)
|
||||||
|
{
|
||||||
|
super(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(int b)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
super.write(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1ParsingException.java
vendored
Normal file
23
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1ParsingException.java
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
public class ASN1ParsingException
|
||||||
|
extends IllegalStateException
|
||||||
|
{
|
||||||
|
private Throwable cause;
|
||||||
|
|
||||||
|
public ASN1ParsingException(String message)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1ParsingException(String message, Throwable cause)
|
||||||
|
{
|
||||||
|
super(message);
|
||||||
|
this.cause = cause;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Throwable getCause()
|
||||||
|
{
|
||||||
|
return cause;
|
||||||
|
}
|
||||||
|
}
|
69
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Primitive.java
vendored
Normal file
69
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Primitive.java
vendored
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public abstract class ASN1Primitive
|
||||||
|
extends ASN1Object
|
||||||
|
{
|
||||||
|
ASN1Primitive()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 ASN1Primitive fromByteArray(byte[] data)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
ASN1InputStream aIn = new ASN1InputStream(data);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return aIn.readObject();
|
||||||
|
}
|
||||||
|
catch (ClassCastException e)
|
||||||
|
{
|
||||||
|
throw new IOException("cannot recognise object in stream");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final boolean equals(Object o)
|
||||||
|
{
|
||||||
|
if (this == o)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (o instanceof ASN1Encodable) && asn1Equals(((ASN1Encodable)o).toASN1Primitive());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive toASN1Primitive()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Primitive toDERObject()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Primitive toDLObject()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract int hashCode();
|
||||||
|
|
||||||
|
abstract boolean isConstructed();
|
||||||
|
|
||||||
|
abstract int encodedLength() throws IOException;
|
||||||
|
|
||||||
|
abstract void encode(ASN1OutputStream out) throws IOException;
|
||||||
|
|
||||||
|
abstract boolean asn1Equals(ASN1Primitive o);
|
||||||
|
}
|
323
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Sequence.java
vendored
Normal file
323
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Sequence.java
vendored
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
public abstract class ASN1Sequence
|
||||||
|
extends ASN1Primitive
|
||||||
|
{
|
||||||
|
protected 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;
|
||||||
|
}
|
||||||
|
else if (obj instanceof ASN1SequenceParser)
|
||||||
|
{
|
||||||
|
return ASN1Sequence.getInstance(((ASN1SequenceParser)obj).toASN1Primitive());
|
||||||
|
}
|
||||||
|
else if (obj instanceof byte[])
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return ASN1Sequence.getInstance(fromByteArray((byte[])obj));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("failed to construct sequence from byte[]: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (obj instanceof ASN1Encodable)
|
||||||
|
{
|
||||||
|
ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
|
||||||
|
|
||||||
|
if (primitive instanceof ASN1Sequence)
|
||||||
|
{
|
||||||
|
return (ASN1Sequence)primitive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.getInstance(obj.getObject().toASN1Primitive());
|
||||||
|
}
|
||||||
|
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 DLSequence(obj.getObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (obj.getObject() instanceof ASN1Sequence)
|
||||||
|
{
|
||||||
|
return (ASN1Sequence)obj.getObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create an empty sequence
|
||||||
|
*/
|
||||||
|
protected ASN1Sequence()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a sequence containing one object
|
||||||
|
*/
|
||||||
|
protected ASN1Sequence(
|
||||||
|
ASN1Encodable obj)
|
||||||
|
{
|
||||||
|
seq.addElement(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a sequence containing a vector of objects.
|
||||||
|
*/
|
||||||
|
protected ASN1Sequence(
|
||||||
|
ASN1EncodableVector v)
|
||||||
|
{
|
||||||
|
for (int i = 0; i != v.size(); i++)
|
||||||
|
{
|
||||||
|
seq.addElement(v.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a sequence containing a vector of objects.
|
||||||
|
*/
|
||||||
|
protected ASN1Sequence(
|
||||||
|
ASN1Encodable[] array)
|
||||||
|
{
|
||||||
|
for (int i = 0; i != array.length; i++)
|
||||||
|
{
|
||||||
|
seq.addElement(array[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Encodable[] toArray()
|
||||||
|
{
|
||||||
|
ASN1Encodable[] values = new ASN1Encodable[this.size()];
|
||||||
|
|
||||||
|
for (int i = 0; i != this.size(); i++)
|
||||||
|
{
|
||||||
|
values[i] = this.getObjectAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ASN1Encodable readObject() throws IOException
|
||||||
|
{
|
||||||
|
if (index == max)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Encodable obj = getObjectAt(index++);
|
||||||
|
if (obj instanceof ASN1Sequence)
|
||||||
|
{
|
||||||
|
return ((ASN1Sequence)obj).parser();
|
||||||
|
}
|
||||||
|
if (obj instanceof ASN1Set)
|
||||||
|
{
|
||||||
|
return ((ASN1Set)obj).parser();
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive getLoadedObject()
|
||||||
|
{
|
||||||
|
return outer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive toASN1Primitive()
|
||||||
|
{
|
||||||
|
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 ASN1Encodable getObjectAt(
|
||||||
|
int index)
|
||||||
|
{
|
||||||
|
return (ASN1Encodable)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 = getNext(e);
|
||||||
|
hashCode *= 17;
|
||||||
|
|
||||||
|
hashCode ^= o.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean asn1Equals(
|
||||||
|
ASN1Primitive 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())
|
||||||
|
{
|
||||||
|
ASN1Encodable obj1 = getNext(s1);
|
||||||
|
ASN1Encodable obj2 = getNext(s2);
|
||||||
|
|
||||||
|
ASN1Primitive o1 = obj1.toASN1Primitive();
|
||||||
|
ASN1Primitive o2 = obj2.toASN1Primitive();
|
||||||
|
|
||||||
|
if (o1 == o2 || o1.equals(o2))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ASN1Encodable getNext(Enumeration e)
|
||||||
|
{
|
||||||
|
ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
|
||||||
|
|
||||||
|
return encObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Primitive toDERObject()
|
||||||
|
{
|
||||||
|
ASN1Sequence derSeq = new DERSequence();
|
||||||
|
|
||||||
|
derSeq.seq = this.seq;
|
||||||
|
|
||||||
|
return derSeq;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Primitive toDLObject()
|
||||||
|
{
|
||||||
|
ASN1Sequence dlSeq = new DLSequence();
|
||||||
|
|
||||||
|
dlSeq.seq = this.seq;
|
||||||
|
|
||||||
|
return dlSeq;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isConstructed()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract void encode(ASN1OutputStream out)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return seq.toString();
|
||||||
|
}
|
||||||
|
}
|
10
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1SequenceParser.java
vendored
Normal file
10
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1SequenceParser.java
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface ASN1SequenceParser
|
||||||
|
extends ASN1Encodable, InMemoryRepresentable
|
||||||
|
{
|
||||||
|
ASN1Encodable readObject()
|
||||||
|
throws IOException;
|
||||||
|
}
|
460
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Set.java
vendored
Normal file
460
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1Set.java
vendored
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
abstract public class ASN1Set
|
||||||
|
extends ASN1Primitive
|
||||||
|
{
|
||||||
|
private Vector set = new Vector();
|
||||||
|
private boolean isSorted = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
else if (obj instanceof ASN1SetParser)
|
||||||
|
{
|
||||||
|
return ASN1Set.getInstance(((ASN1SetParser)obj).toASN1Primitive());
|
||||||
|
}
|
||||||
|
else if (obj instanceof byte[])
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return ASN1Set.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("failed to construct set from byte[]: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (obj instanceof ASN1Encodable)
|
||||||
|
{
|
||||||
|
ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
|
||||||
|
|
||||||
|
if (primitive instanceof ASN1Set)
|
||||||
|
{
|
||||||
|
return (ASN1Set)primitive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 set.
|
||||||
|
//
|
||||||
|
if (obj.isExplicit())
|
||||||
|
{
|
||||||
|
if (obj instanceof BERTaggedObject)
|
||||||
|
{
|
||||||
|
return new BERSet(obj.getObject());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new DLSet(obj.getObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (obj.getObject() instanceof ASN1Set)
|
||||||
|
{
|
||||||
|
return (ASN1Set)obj.getObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// in this case the parser returns a sequence, convert it
|
||||||
|
// into a set.
|
||||||
|
//
|
||||||
|
if (obj.getObject() instanceof ASN1Sequence)
|
||||||
|
{
|
||||||
|
ASN1Sequence s = (ASN1Sequence)obj.getObject();
|
||||||
|
|
||||||
|
if (obj instanceof BERTaggedObject)
|
||||||
|
{
|
||||||
|
return new BERSet(s.toArray());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new DLSet(s.toArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ASN1Set()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a sequence containing one object
|
||||||
|
*/
|
||||||
|
protected ASN1Set(
|
||||||
|
ASN1Encodable obj)
|
||||||
|
{
|
||||||
|
set.addElement(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a sequence containing a vector of objects.
|
||||||
|
*/
|
||||||
|
protected ASN1Set(
|
||||||
|
ASN1EncodableVector v,
|
||||||
|
boolean doSort)
|
||||||
|
{
|
||||||
|
for (int i = 0; i != v.size(); i++)
|
||||||
|
{
|
||||||
|
set.addElement(v.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doSort)
|
||||||
|
{
|
||||||
|
this.sort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a sequence containing a vector of objects.
|
||||||
|
*/
|
||||||
|
protected ASN1Set(
|
||||||
|
ASN1Encodable[] array,
|
||||||
|
boolean doSort)
|
||||||
|
{
|
||||||
|
for (int i = 0; i != array.length; i++)
|
||||||
|
{
|
||||||
|
set.addElement(array[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doSort)
|
||||||
|
{
|
||||||
|
this.sort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ASN1Encodable getObjectAt(
|
||||||
|
int index)
|
||||||
|
{
|
||||||
|
return (ASN1Encodable)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 ASN1Encodable[] toArray()
|
||||||
|
{
|
||||||
|
ASN1Encodable[] values = new ASN1Encodable[this.size()];
|
||||||
|
|
||||||
|
for (int i = 0; i != this.size(); i++)
|
||||||
|
{
|
||||||
|
values[i] = this.getObjectAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1SetParser parser()
|
||||||
|
{
|
||||||
|
final ASN1Set outer = this;
|
||||||
|
|
||||||
|
return new ASN1SetParser()
|
||||||
|
{
|
||||||
|
private final int max = size();
|
||||||
|
|
||||||
|
private int index;
|
||||||
|
|
||||||
|
public ASN1Encodable readObject() throws IOException
|
||||||
|
{
|
||||||
|
if (index == max)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Encodable obj = getObjectAt(index++);
|
||||||
|
if (obj instanceof ASN1Sequence)
|
||||||
|
{
|
||||||
|
return ((ASN1Sequence)obj).parser();
|
||||||
|
}
|
||||||
|
if (obj instanceof ASN1Set)
|
||||||
|
{
|
||||||
|
return ((ASN1Set)obj).parser();
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive getLoadedObject()
|
||||||
|
{
|
||||||
|
return outer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive toASN1Primitive()
|
||||||
|
{
|
||||||
|
return outer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
Enumeration e = this.getObjects();
|
||||||
|
int hashCode = size();
|
||||||
|
|
||||||
|
while (e.hasMoreElements())
|
||||||
|
{
|
||||||
|
Object o = getNext(e);
|
||||||
|
hashCode *= 17;
|
||||||
|
|
||||||
|
hashCode ^= o.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Primitive toDERObject()
|
||||||
|
{
|
||||||
|
if (isSorted)
|
||||||
|
{
|
||||||
|
ASN1Set derSet = new DERSet();
|
||||||
|
|
||||||
|
derSet.set = this.set;
|
||||||
|
|
||||||
|
return derSet;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Vector v = new Vector();
|
||||||
|
|
||||||
|
for (int i = 0; i != set.size(); i++)
|
||||||
|
{
|
||||||
|
v.addElement(set.elementAt(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Set derSet = new DERSet();
|
||||||
|
|
||||||
|
derSet.set = v;
|
||||||
|
|
||||||
|
derSet.sort();
|
||||||
|
|
||||||
|
return derSet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Primitive toDLObject()
|
||||||
|
{
|
||||||
|
ASN1Set derSet = new DLSet();
|
||||||
|
|
||||||
|
derSet.set = this.set;
|
||||||
|
|
||||||
|
return derSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean asn1Equals(
|
||||||
|
ASN1Primitive 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())
|
||||||
|
{
|
||||||
|
ASN1Encodable obj1 = getNext(s1);
|
||||||
|
ASN1Encodable obj2 = getNext(s2);
|
||||||
|
|
||||||
|
ASN1Primitive o1 = obj1.toASN1Primitive();
|
||||||
|
ASN1Primitive o2 = obj2.toASN1Primitive();
|
||||||
|
|
||||||
|
if (o1 == o2 || o1.equals(o2))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ASN1Encodable getNext(Enumeration e)
|
||||||
|
{
|
||||||
|
ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
|
||||||
|
|
||||||
|
// unfortunately null was allowed as a substitute for DER null
|
||||||
|
if (encObj == null)
|
||||||
|
{
|
||||||
|
return DERNull.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return encObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return true if a <= b (arrays are assumed padded with zeros).
|
||||||
|
*/
|
||||||
|
private boolean lessThanOrEqual(
|
||||||
|
byte[] a,
|
||||||
|
byte[] b)
|
||||||
|
{
|
||||||
|
int len = Math.min(a.length, b.length);
|
||||||
|
for (int i = 0; i != len; ++i)
|
||||||
|
{
|
||||||
|
if (a[i] != b[i])
|
||||||
|
{
|
||||||
|
return (a[i] & 0xff) < (b[i] & 0xff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len == a.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] getEncoded(
|
||||||
|
ASN1Encodable 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 (!isSorted)
|
||||||
|
{
|
||||||
|
isSorted = true;
|
||||||
|
if (set.size() > 1)
|
||||||
|
{
|
||||||
|
boolean swapped = true;
|
||||||
|
int lastSwap = set.size() - 1;
|
||||||
|
|
||||||
|
while (swapped)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
int swapIndex = 0;
|
||||||
|
byte[] a = getEncoded((ASN1Encodable)set.elementAt(0));
|
||||||
|
|
||||||
|
swapped = false;
|
||||||
|
|
||||||
|
while (index != lastSwap)
|
||||||
|
{
|
||||||
|
byte[] b = getEncoded((ASN1Encodable)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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isConstructed()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract void encode(ASN1OutputStream out)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return set.toString();
|
||||||
|
}
|
||||||
|
}
|
10
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1SetParser.java
vendored
Normal file
10
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1SetParser.java
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface ASN1SetParser
|
||||||
|
extends ASN1Encodable, InMemoryRepresentable
|
||||||
|
{
|
||||||
|
public ASN1Encodable readObject()
|
||||||
|
throws IOException;
|
||||||
|
}
|
247
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1StreamParser.java
vendored
Normal file
247
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1StreamParser.java
vendored
Normal file
@ -0,0 +1,247 @@
|
|||||||
|
package org.spongycastle.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 final byte[][] tmpBuffers;
|
||||||
|
|
||||||
|
public ASN1StreamParser(
|
||||||
|
InputStream in)
|
||||||
|
{
|
||||||
|
this(in, StreamUtil.findLimit(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1StreamParser(
|
||||||
|
InputStream in,
|
||||||
|
int limit)
|
||||||
|
{
|
||||||
|
this._in = in;
|
||||||
|
this._limit = limit;
|
||||||
|
|
||||||
|
this.tmpBuffers = new byte[11][];
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1StreamParser(
|
||||||
|
byte[] encoding)
|
||||||
|
{
|
||||||
|
this(new ByteArrayInputStream(encoding), encoding.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Encodable readIndef(int tagValue) throws IOException
|
||||||
|
{
|
||||||
|
// Note: INDEF => CONSTRUCTED
|
||||||
|
|
||||||
|
// TODO There are other tags that may be constructed (e.g. BIT_STRING)
|
||||||
|
switch (tagValue)
|
||||||
|
{
|
||||||
|
case BERTags.EXTERNAL:
|
||||||
|
return new DERExternalParser(this);
|
||||||
|
case BERTags.OCTET_STRING:
|
||||||
|
return new BEROctetStringParser(this);
|
||||||
|
case BERTags.SEQUENCE:
|
||||||
|
return new BERSequenceParser(this);
|
||||||
|
case BERTags.SET:
|
||||||
|
return new BERSetParser(this);
|
||||||
|
default:
|
||||||
|
throw new ASN1Exception("unknown BER object encountered: 0x" + Integer.toHexString(tagValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Encodable readImplicit(boolean constructed, int tag) throws IOException
|
||||||
|
{
|
||||||
|
if (_in instanceof IndefiniteLengthInputStream)
|
||||||
|
{
|
||||||
|
if (!constructed)
|
||||||
|
{
|
||||||
|
throw new IOException("indefinite length primitive encoding encountered");
|
||||||
|
}
|
||||||
|
|
||||||
|
return readIndef(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (constructed)
|
||||||
|
{
|
||||||
|
switch (tag)
|
||||||
|
{
|
||||||
|
case BERTags.SET:
|
||||||
|
return new DERSetParser(this);
|
||||||
|
case BERTags.SEQUENCE:
|
||||||
|
return new DERSequenceParser(this);
|
||||||
|
case BERTags.OCTET_STRING:
|
||||||
|
return new BEROctetStringParser(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (tag)
|
||||||
|
{
|
||||||
|
case BERTags.SET:
|
||||||
|
throw new ASN1Exception("sequences must use constructed encoding (see X.690 8.9.1/8.10.1)");
|
||||||
|
case BERTags.SEQUENCE:
|
||||||
|
throw new ASN1Exception("sets must use constructed encoding (see X.690 8.11.1/8.12.1)");
|
||||||
|
case BERTags.OCTET_STRING:
|
||||||
|
return new DEROctetStringParser((DefiniteLengthInputStream)_in);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO ASN1Exception
|
||||||
|
throw new RuntimeException("implicit tagging not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Primitive readTaggedObject(boolean constructed, int tag) throws IOException
|
||||||
|
{
|
||||||
|
if (!constructed)
|
||||||
|
{
|
||||||
|
// Note: !CONSTRUCTED => IMPLICIT
|
||||||
|
DefiniteLengthInputStream defIn = (DefiniteLengthInputStream)_in;
|
||||||
|
return new DERTaggedObject(false, tag, new DEROctetString(defIn.toByteArray()));
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1EncodableVector v = readVector();
|
||||||
|
|
||||||
|
if (_in instanceof IndefiniteLengthInputStream)
|
||||||
|
{
|
||||||
|
return v.size() == 1
|
||||||
|
? new BERTaggedObject(true, tag, v.get(0))
|
||||||
|
: new BERTaggedObject(false, tag, BERFactory.createSequence(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
return v.size() == 1
|
||||||
|
? new DERTaggedObject(true, tag, v.get(0))
|
||||||
|
: new DERTaggedObject(false, tag, DERFactory.createSequence(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Encodable 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 & BERTags.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, _limit);
|
||||||
|
ASN1StreamParser sp = new ASN1StreamParser(indIn, _limit);
|
||||||
|
|
||||||
|
if ((tag & BERTags.APPLICATION) != 0)
|
||||||
|
{
|
||||||
|
return new BERApplicationSpecificParser(tagNo, sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tag & BERTags.TAGGED) != 0)
|
||||||
|
{
|
||||||
|
return new BERTaggedObjectParser(true, tagNo, sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sp.readIndef(tagNo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DefiniteLengthInputStream defIn = new DefiniteLengthInputStream(_in, length);
|
||||||
|
|
||||||
|
if ((tag & BERTags.APPLICATION) != 0)
|
||||||
|
{
|
||||||
|
return new DERApplicationSpecific(isConstructed, tagNo, defIn.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tag & BERTags.TAGGED) != 0)
|
||||||
|
{
|
||||||
|
return new BERTaggedObjectParser(isConstructed, tagNo, new ASN1StreamParser(defIn));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isConstructed)
|
||||||
|
{
|
||||||
|
// TODO There are other tags that may be constructed (e.g. BIT_STRING)
|
||||||
|
switch (tagNo)
|
||||||
|
{
|
||||||
|
case BERTags.OCTET_STRING:
|
||||||
|
//
|
||||||
|
// yes, people actually do this...
|
||||||
|
//
|
||||||
|
return new BEROctetStringParser(new ASN1StreamParser(defIn));
|
||||||
|
case BERTags.SEQUENCE:
|
||||||
|
return new DERSequenceParser(new ASN1StreamParser(defIn));
|
||||||
|
case BERTags.SET:
|
||||||
|
return new DERSetParser(new ASN1StreamParser(defIn));
|
||||||
|
case BERTags.EXTERNAL:
|
||||||
|
return new DERExternalParser(new ASN1StreamParser(defIn));
|
||||||
|
default:
|
||||||
|
throw new IOException("unknown tag " + tagNo + " encountered");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some primitive encodings can be handled by parsers too...
|
||||||
|
switch (tagNo)
|
||||||
|
{
|
||||||
|
case BERTags.OCTET_STRING:
|
||||||
|
return new DEROctetStringParser(defIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return ASN1InputStream.createPrimitiveDERObject(tagNo, defIn, tmpBuffers);
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e)
|
||||||
|
{
|
||||||
|
throw new ASN1Exception("corrupted stream detected", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void set00Check(boolean enabled)
|
||||||
|
{
|
||||||
|
if (_in instanceof IndefiniteLengthInputStream)
|
||||||
|
{
|
||||||
|
((IndefiniteLengthInputStream)_in).setEofOn00(enabled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1EncodableVector readVector() throws IOException
|
||||||
|
{
|
||||||
|
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||||
|
|
||||||
|
ASN1Encodable obj;
|
||||||
|
while ((obj = readObject()) != null)
|
||||||
|
{
|
||||||
|
if (obj instanceof InMemoryRepresentable)
|
||||||
|
{
|
||||||
|
v.add(((InMemoryRepresentable)obj).getLoadedObject());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v.add(obj.toASN1Primitive());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
6
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1String.java
vendored
Normal file
6
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1String.java
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
public interface ASN1String
|
||||||
|
{
|
||||||
|
public String getString();
|
||||||
|
}
|
236
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1TaggedObject.java
vendored
Normal file
236
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1TaggedObject.java
vendored
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
package org.spongycastle.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 ASN1Primitive
|
||||||
|
implements ASN1TaggedObjectParser
|
||||||
|
{
|
||||||
|
int tagNo;
|
||||||
|
boolean empty = false;
|
||||||
|
boolean explicit = true;
|
||||||
|
ASN1Encodable 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;
|
||||||
|
}
|
||||||
|
else if (obj instanceof byte[])
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return ASN1TaggedObject.getInstance(fromByteArray((byte[])obj));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("failed to construct tagged object from byte[]: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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,
|
||||||
|
ASN1Encodable obj)
|
||||||
|
{
|
||||||
|
if (obj instanceof ASN1Choice)
|
||||||
|
{
|
||||||
|
this.explicit = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.explicit = explicit;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tagNo = tagNo;
|
||||||
|
|
||||||
|
if (this.explicit)
|
||||||
|
{
|
||||||
|
this.obj = obj;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASN1Primitive prim = obj.toASN1Primitive();
|
||||||
|
|
||||||
|
if (prim instanceof ASN1Set)
|
||||||
|
{
|
||||||
|
ASN1Set s = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.obj = obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean asn1Equals(
|
||||||
|
ASN1Primitive 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.toASN1Primitive().equals(other.obj.toASN1Primitive())))
|
||||||
|
{
|
||||||
|
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 ASN1Primitive getObject()
|
||||||
|
{
|
||||||
|
if (obj != null)
|
||||||
|
{
|
||||||
|
return obj.toASN1Primitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ASN1Encodable getObjectParser(
|
||||||
|
int tag,
|
||||||
|
boolean isExplicit)
|
||||||
|
{
|
||||||
|
switch (tag)
|
||||||
|
{
|
||||||
|
case BERTags.SET:
|
||||||
|
return ASN1Set.getInstance(this, isExplicit).parser();
|
||||||
|
case BERTags.SEQUENCE:
|
||||||
|
return ASN1Sequence.getInstance(this, isExplicit).parser();
|
||||||
|
case BERTags.OCTET_STRING:
|
||||||
|
return ASN1OctetString.getInstance(this, isExplicit).parser();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isExplicit)
|
||||||
|
{
|
||||||
|
return getObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("implicit tagging not implemented for tag: " + tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive getLoadedObject()
|
||||||
|
{
|
||||||
|
return this.toASN1Primitive();
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Primitive toDERObject()
|
||||||
|
{
|
||||||
|
return new DERTaggedObject(explicit, tagNo, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASN1Primitive toDLObject()
|
||||||
|
{
|
||||||
|
return new DLTaggedObject(explicit, tagNo, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract void encode(ASN1OutputStream out)
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "[" + tagNo + "]" + obj;
|
||||||
|
}
|
||||||
|
}
|
12
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1TaggedObjectParser.java
vendored
Normal file
12
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1TaggedObjectParser.java
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public interface ASN1TaggedObjectParser
|
||||||
|
extends ASN1Encodable, InMemoryRepresentable
|
||||||
|
{
|
||||||
|
public int getTagNo();
|
||||||
|
|
||||||
|
public ASN1Encodable getObjectParser(int tag, boolean isExplicit)
|
||||||
|
throws IOException;
|
||||||
|
}
|
22
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1UTCTime.java
vendored
Normal file
22
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ASN1UTCTime.java
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class ASN1UTCTime
|
||||||
|
extends DERUTCTime
|
||||||
|
{
|
||||||
|
ASN1UTCTime(byte[] bytes)
|
||||||
|
{
|
||||||
|
super(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1UTCTime(Date time)
|
||||||
|
{
|
||||||
|
super(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1UTCTime(String time)
|
||||||
|
{
|
||||||
|
super(time);
|
||||||
|
}
|
||||||
|
}
|
10
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERApplicationSpecific.java
vendored
Normal file
10
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERApplicationSpecific.java
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
public class BERApplicationSpecific
|
||||||
|
extends DERApplicationSpecific
|
||||||
|
{
|
||||||
|
public BERApplicationSpecific(int tagNo, ASN1EncodableVector vec)
|
||||||
|
{
|
||||||
|
super(tagNo, vec);
|
||||||
|
}
|
||||||
|
}
|
41
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERApplicationSpecificParser.java
vendored
Normal file
41
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERApplicationSpecificParser.java
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package org.spongycastle.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 ASN1Encodable readObject()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
return parser.readObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive getLoadedObject()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
return new BERApplicationSpecific(tag, parser.readVector());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive toASN1Primitive()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return getLoadedObject();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new ASN1ParsingException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
144
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERConstructedOctetString.java
vendored
Normal file
144
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERConstructedOctetString.java
vendored
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use BEROctetString
|
||||||
|
*/
|
||||||
|
public class BERConstructedOctetString
|
||||||
|
extends BEROctetString
|
||||||
|
{
|
||||||
|
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(
|
||||||
|
ASN1Primitive obj)
|
||||||
|
{
|
||||||
|
super(toByteArray(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] toByteArray(ASN1Primitive obj)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return obj.getEncoded();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Unable to encode object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BERConstructedOctetString(
|
||||||
|
ASN1Encodable obj)
|
||||||
|
{
|
||||||
|
this(obj.toASN1Primitive());
|
||||||
|
}
|
||||||
|
|
||||||
|
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 static BEROctetString fromSequence(ASN1Sequence seq)
|
||||||
|
{
|
||||||
|
Vector v = new Vector();
|
||||||
|
Enumeration e = seq.getObjects();
|
||||||
|
|
||||||
|
while (e.hasMoreElements())
|
||||||
|
{
|
||||||
|
v.addElement(e.nextElement());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BERConstructedOctetString(v);
|
||||||
|
}
|
||||||
|
}
|
17
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERFactory.java
vendored
Normal file
17
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERFactory.java
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package org.spongycastle.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);
|
||||||
|
}
|
||||||
|
}
|
100
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERGenerator.java
vendored
Normal file
100
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERGenerator.java
vendored
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
package org.spongycastle.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 | BERTags.TAGGED;
|
||||||
|
|
||||||
|
if (_isExplicit)
|
||||||
|
{
|
||||||
|
writeHdr(tagNum | BERTags.CONSTRUCTED);
|
||||||
|
writeHdr(tag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((tag & BERTags.CONSTRUCTED) != 0)
|
||||||
|
{
|
||||||
|
writeHdr(tagNum | BERTags.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
168
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BEROctetString.java
vendored
Normal file
168
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BEROctetString.java
vendored
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
public class BEROctetString
|
||||||
|
extends ASN1OctetString
|
||||||
|
{
|
||||||
|
private static final int MAX_LENGTH = 1000;
|
||||||
|
|
||||||
|
private ASN1OctetString[] octs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* convert a vector of octet strings into a single byte string
|
||||||
|
*/
|
||||||
|
static private byte[] toBytes(
|
||||||
|
ASN1OctetString[] octs)
|
||||||
|
{
|
||||||
|
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
for (int i = 0; i != octs.length; i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DEROctetString o = (DEROctetString)octs[i];
|
||||||
|
|
||||||
|
bOut.write(o.getOctets());
|
||||||
|
}
|
||||||
|
catch (ClassCastException e)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException(octs[i].getClass().getName() + " found in input should only contain DEROctetString");
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("exception converting octets " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bOut.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string the octets making up the octet string.
|
||||||
|
*/
|
||||||
|
public BEROctetString(
|
||||||
|
byte[] string)
|
||||||
|
{
|
||||||
|
super(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BEROctetString(
|
||||||
|
ASN1OctetString[] octs)
|
||||||
|
{
|
||||||
|
super(toBytes(octs));
|
||||||
|
|
||||||
|
this.octs = octs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getOctets()
|
||||||
|
{
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the DER octets that make up this string.
|
||||||
|
*/
|
||||||
|
public Enumeration getObjects()
|
||||||
|
{
|
||||||
|
if (octs == null)
|
||||||
|
{
|
||||||
|
return generateOcts().elements();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Enumeration()
|
||||||
|
{
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
public boolean hasMoreElements()
|
||||||
|
{
|
||||||
|
return counter < octs.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object nextElement()
|
||||||
|
{
|
||||||
|
return octs[counter++];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isConstructed()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int encodedLength()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
int length = 0;
|
||||||
|
for (Enumeration e = getObjects(); e.hasMoreElements();)
|
||||||
|
{
|
||||||
|
length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 2 + length + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void encode(
|
||||||
|
ASN1OutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
out.write(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
|
||||||
|
|
||||||
|
out.write(0x80);
|
||||||
|
|
||||||
|
//
|
||||||
|
// write out the octet array
|
||||||
|
//
|
||||||
|
for (Enumeration e = getObjects(); e.hasMoreElements();)
|
||||||
|
{
|
||||||
|
out.writeObject((ASN1Encodable)e.nextElement());
|
||||||
|
}
|
||||||
|
|
||||||
|
out.write(0x00);
|
||||||
|
out.write(0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BEROctetString fromSequence(ASN1Sequence seq)
|
||||||
|
{
|
||||||
|
ASN1OctetString[] v = new ASN1OctetString[seq.size()];
|
||||||
|
Enumeration e = seq.getObjects();
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
while (e.hasMoreElements())
|
||||||
|
{
|
||||||
|
v[index++] = (ASN1OctetString)e.nextElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BEROctetString(v);
|
||||||
|
}
|
||||||
|
}
|
102
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BEROctetStringGenerator.java
vendored
Normal file
102
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BEROctetStringGenerator.java
vendored
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class BEROctetStringGenerator
|
||||||
|
extends BERGenerator
|
||||||
|
{
|
||||||
|
public BEROctetStringGenerator(OutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
super(out);
|
||||||
|
|
||||||
|
writeBERHeader(BERTags.CONSTRUCTED | BERTags.OCTET_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BEROctetStringGenerator(
|
||||||
|
OutputStream out,
|
||||||
|
int tagNo,
|
||||||
|
boolean isExplicit)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
super(out, tagNo, isExplicit);
|
||||||
|
|
||||||
|
writeBERHeader(BERTags.CONSTRUCTED | BERTags.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
41
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BEROctetStringParser.java
vendored
Normal file
41
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BEROctetStringParser.java
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.spongycastle.util.io.Streams;
|
||||||
|
|
||||||
|
public class BEROctetStringParser
|
||||||
|
implements ASN1OctetStringParser
|
||||||
|
{
|
||||||
|
private ASN1StreamParser _parser;
|
||||||
|
|
||||||
|
BEROctetStringParser(
|
||||||
|
ASN1StreamParser parser)
|
||||||
|
{
|
||||||
|
_parser = parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getOctetStream()
|
||||||
|
{
|
||||||
|
return new ConstructedOctetStream(_parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive getLoadedObject()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
return new BEROctetString(Streams.readAll(getOctetStream()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive toASN1Primitive()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return getLoadedObject();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new ASN1ParsingException("IOException converting stream to byte array: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BEROutputStream.java
vendored
Normal file
36
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BEROutputStream.java
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package org.spongycastle.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 ASN1Primitive)
|
||||||
|
{
|
||||||
|
((ASN1Primitive)obj).encode(this);
|
||||||
|
}
|
||||||
|
else if (obj instanceof ASN1Encodable)
|
||||||
|
{
|
||||||
|
((ASN1Encodable)obj).toASN1Primitive().encode(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IOException("object not BEREncodable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
73
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERSequence.java
vendored
Normal file
73
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERSequence.java
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
|
||||||
|
public class BERSequence
|
||||||
|
extends ASN1Sequence
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* create an empty sequence
|
||||||
|
*/
|
||||||
|
public BERSequence()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a sequence containing one object
|
||||||
|
*/
|
||||||
|
public BERSequence(
|
||||||
|
ASN1Encodable obj)
|
||||||
|
{
|
||||||
|
super(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a sequence containing a vector of objects.
|
||||||
|
*/
|
||||||
|
public BERSequence(
|
||||||
|
ASN1EncodableVector v)
|
||||||
|
{
|
||||||
|
super(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a sequence containing an array of objects.
|
||||||
|
*/
|
||||||
|
public BERSequence(
|
||||||
|
ASN1Encodable[] array)
|
||||||
|
{
|
||||||
|
super(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
int encodedLength()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
int length = 0;
|
||||||
|
for (Enumeration e = getObjects(); e.hasMoreElements();)
|
||||||
|
{
|
||||||
|
length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 2 + length + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
void encode(
|
||||||
|
ASN1OutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
out.write(BERTags.SEQUENCE | BERTags.CONSTRUCTED);
|
||||||
|
out.write(0x80);
|
||||||
|
|
||||||
|
Enumeration e = getObjects();
|
||||||
|
while (e.hasMoreElements())
|
||||||
|
{
|
||||||
|
out.writeObject((ASN1Encodable)e.nextElement());
|
||||||
|
}
|
||||||
|
|
||||||
|
out.write(0x00);
|
||||||
|
out.write(0x00);
|
||||||
|
}
|
||||||
|
}
|
41
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERSequenceGenerator.java
vendored
Normal file
41
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERSequenceGenerator.java
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
public class BERSequenceGenerator
|
||||||
|
extends BERGenerator
|
||||||
|
{
|
||||||
|
public BERSequenceGenerator(
|
||||||
|
OutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
super(out);
|
||||||
|
|
||||||
|
writeBERHeader(BERTags.CONSTRUCTED | BERTags.SEQUENCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BERSequenceGenerator(
|
||||||
|
OutputStream out,
|
||||||
|
int tagNo,
|
||||||
|
boolean isExplicit)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
super(out, tagNo, isExplicit);
|
||||||
|
|
||||||
|
writeBERHeader(BERTags.CONSTRUCTED | BERTags.SEQUENCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addObject(
|
||||||
|
ASN1Encodable object)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
object.toASN1Primitive().encode(new BEROutputStream(_out));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
writeBEREnd();
|
||||||
|
}
|
||||||
|
}
|
38
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERSequenceParser.java
vendored
Normal file
38
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERSequenceParser.java
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class BERSequenceParser
|
||||||
|
implements ASN1SequenceParser
|
||||||
|
{
|
||||||
|
private ASN1StreamParser _parser;
|
||||||
|
|
||||||
|
BERSequenceParser(ASN1StreamParser parser)
|
||||||
|
{
|
||||||
|
this._parser = parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Encodable readObject()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
return _parser.readObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive getLoadedObject()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
return new BERSequence(_parser.readVector());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive toASN1Primitive()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return getLoadedObject();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
73
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERSet.java
vendored
Normal file
73
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERSet.java
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
|
||||||
|
public class BERSet
|
||||||
|
extends ASN1Set
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* create an empty sequence
|
||||||
|
*/
|
||||||
|
public BERSet()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param obj - a single object that makes up the set.
|
||||||
|
*/
|
||||||
|
public BERSet(
|
||||||
|
ASN1Encodable obj)
|
||||||
|
{
|
||||||
|
super(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param v - a vector of objects making up the set.
|
||||||
|
*/
|
||||||
|
public BERSet(
|
||||||
|
ASN1EncodableVector v)
|
||||||
|
{
|
||||||
|
super(v, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a set from an array of objects.
|
||||||
|
*/
|
||||||
|
public BERSet(
|
||||||
|
ASN1Encodable[] a)
|
||||||
|
{
|
||||||
|
super(a, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int encodedLength()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
int length = 0;
|
||||||
|
for (Enumeration e = getObjects(); e.hasMoreElements();)
|
||||||
|
{
|
||||||
|
length += ((ASN1Encodable)e.nextElement()).toASN1Primitive().encodedLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 2 + length + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
void encode(
|
||||||
|
ASN1OutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
out.write(BERTags.SET | BERTags.CONSTRUCTED);
|
||||||
|
out.write(0x80);
|
||||||
|
|
||||||
|
Enumeration e = getObjects();
|
||||||
|
while (e.hasMoreElements())
|
||||||
|
{
|
||||||
|
out.writeObject((ASN1Encodable)e.nextElement());
|
||||||
|
}
|
||||||
|
|
||||||
|
out.write(0x00);
|
||||||
|
out.write(0x00);
|
||||||
|
}
|
||||||
|
}
|
38
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERSetParser.java
vendored
Normal file
38
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERSetParser.java
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class BERSetParser
|
||||||
|
implements ASN1SetParser
|
||||||
|
{
|
||||||
|
private ASN1StreamParser _parser;
|
||||||
|
|
||||||
|
BERSetParser(ASN1StreamParser parser)
|
||||||
|
{
|
||||||
|
this._parser = parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Encodable readObject()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
return _parser.readObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive getLoadedObject()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
return new BERSet(_parser.readVector());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive toASN1Primitive()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return getLoadedObject();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new ASN1ParsingException(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
147
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERTaggedObject.java
vendored
Normal file
147
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERTaggedObject.java
vendored
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
package org.spongycastle.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 ASN1TaggedObject
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param tagNo the tag number for this object.
|
||||||
|
* @param obj the tagged object.
|
||||||
|
*/
|
||||||
|
public BERTaggedObject(
|
||||||
|
int tagNo,
|
||||||
|
ASN1Encodable obj)
|
||||||
|
{
|
||||||
|
super(true, 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,
|
||||||
|
ASN1Encodable 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isConstructed()
|
||||||
|
{
|
||||||
|
if (!empty)
|
||||||
|
{
|
||||||
|
if (explicit)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASN1Primitive primitive = obj.toASN1Primitive().toDERObject();
|
||||||
|
|
||||||
|
return primitive.isConstructed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int encodedLength()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (!empty)
|
||||||
|
{
|
||||||
|
ASN1Primitive primitive = obj.toASN1Primitive();
|
||||||
|
int length = primitive.encodedLength();
|
||||||
|
|
||||||
|
if (explicit)
|
||||||
|
{
|
||||||
|
return StreamUtil.calculateTagLength(tagNo) + StreamUtil.calculateBodyLength(length) + length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// header length already in calculation
|
||||||
|
length = length - 1;
|
||||||
|
|
||||||
|
return StreamUtil.calculateTagLength(tagNo) + length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return StreamUtil.calculateTagLength(tagNo) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void encode(
|
||||||
|
ASN1OutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
out.writeTag(BERTags.CONSTRUCTED | BERTags.TAGGED, tagNo);
|
||||||
|
out.write(0x80);
|
||||||
|
|
||||||
|
if (!empty)
|
||||||
|
{
|
||||||
|
if (!explicit)
|
||||||
|
{
|
||||||
|
Enumeration e;
|
||||||
|
if (obj instanceof ASN1OctetString)
|
||||||
|
{
|
||||||
|
if (obj instanceof BEROctetString)
|
||||||
|
{
|
||||||
|
e = ((BEROctetString)obj).getObjects();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ASN1OctetString octs = (ASN1OctetString)obj;
|
||||||
|
BEROctetString berO = new BEROctetString(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((ASN1Encodable)e.nextElement());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out.writeObject(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.write(0x00);
|
||||||
|
out.write(0x00);
|
||||||
|
}
|
||||||
|
}
|
66
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERTaggedObjectParser.java
vendored
Normal file
66
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERTaggedObjectParser.java
vendored
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class BERTaggedObjectParser
|
||||||
|
implements ASN1TaggedObjectParser
|
||||||
|
{
|
||||||
|
private boolean _constructed;
|
||||||
|
private int _tagNumber;
|
||||||
|
private ASN1StreamParser _parser;
|
||||||
|
|
||||||
|
BERTaggedObjectParser(
|
||||||
|
boolean constructed,
|
||||||
|
int tagNumber,
|
||||||
|
ASN1StreamParser parser)
|
||||||
|
{
|
||||||
|
_constructed = constructed;
|
||||||
|
_tagNumber = tagNumber;
|
||||||
|
_parser = parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConstructed()
|
||||||
|
{
|
||||||
|
return _constructed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTagNo()
|
||||||
|
{
|
||||||
|
return _tagNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Encodable getObjectParser(
|
||||||
|
int tag,
|
||||||
|
boolean isExplicit)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (isExplicit)
|
||||||
|
{
|
||||||
|
if (!_constructed)
|
||||||
|
{
|
||||||
|
throw new IOException("Explicit tags must be constructed (see X.690 8.14.2)");
|
||||||
|
}
|
||||||
|
return _parser.readObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _parser.readImplicit(_constructed, tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive getLoadedObject()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
return _parser.readTaggedObject(_constructed, _tagNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ASN1Primitive toASN1Primitive()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return this.getLoadedObject();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new ASN1ParsingException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERTags.java
vendored
Normal file
36
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/BERTags.java
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
public interface BERTags
|
||||||
|
{
|
||||||
|
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 - used to model a SEQUENCE of the same type.
|
||||||
|
public static final int SET = 0x11;
|
||||||
|
public static final int SET_OF = 0x11; // for completeness - used to model a SET of the same type.
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
111
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ConstructedOctetStream.java
vendored
Normal file
111
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/ConstructedOctetStream.java
vendored
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
276
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/DERApplicationSpecific.java
vendored
Normal file
276
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/DERApplicationSpecific.java
vendored
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.spongycastle.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for an application specific object
|
||||||
|
*/
|
||||||
|
public class DERApplicationSpecific
|
||||||
|
extends ASN1Primitive
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
ASN1Encodable object)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
this(true, tag, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DERApplicationSpecific(
|
||||||
|
boolean explicit,
|
||||||
|
int tag,
|
||||||
|
ASN1Encodable object)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
ASN1Primitive primitive = object.toASN1Primitive();
|
||||||
|
|
||||||
|
byte[] data = primitive.getEncoded(ASN1Encoding.DER);
|
||||||
|
|
||||||
|
this.isConstructed = explicit || (primitive instanceof ASN1Set || primitive instanceof ASN1Sequence);
|
||||||
|
this.tag = tag;
|
||||||
|
|
||||||
|
if (explicit)
|
||||||
|
{
|
||||||
|
this.octets = data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int lenBytes = getLengthOfHeader(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(((ASN1Object)vec.get(i)).getEncoded(ASN1Encoding.DER));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new ASN1ParsingException("malformed object: " + e, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.octets = bOut.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DERApplicationSpecific getInstance(Object obj)
|
||||||
|
{
|
||||||
|
if (obj == null || obj instanceof DERApplicationSpecific)
|
||||||
|
{
|
||||||
|
return (DERApplicationSpecific)obj;
|
||||||
|
}
|
||||||
|
else if (obj instanceof byte[])
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return DERApplicationSpecific.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("failed to construct object from byte[]: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (obj instanceof ASN1Encodable)
|
||||||
|
{
|
||||||
|
ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
|
||||||
|
|
||||||
|
if (primitive instanceof ASN1Sequence)
|
||||||
|
{
|
||||||
|
return (DERApplicationSpecific)primitive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getLengthOfHeader(byte[] data)
|
||||||
|
{
|
||||||
|
int length = data[1] & 0xff; // TODO: assumes 1 byte tag
|
||||||
|
|
||||||
|
if (length == 0x80)
|
||||||
|
{
|
||||||
|
return 2; // indefinite-length encoding
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length > 127)
|
||||||
|
{
|
||||||
|
int size = length & 0x7f;
|
||||||
|
|
||||||
|
// Note: The invalid long form "0xff" (see X.690 8.1.3.5c) will be caught here
|
||||||
|
if (size > 4)
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("DER length more than 4 bytes: " + size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return size + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ASN1Primitive 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 ASN1Primitive 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] & BERTags.CONSTRUCTED) != 0)
|
||||||
|
{
|
||||||
|
tmp[0] |= BERTags.CONSTRUCTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ASN1InputStream(tmp).readObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
int encodedLength()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
return StreamUtil.calculateTagLength(tag) + StreamUtil.calculateBodyLength(octets.length) + octets.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.spongycastle.asn1.ASN1Primitive#encode(org.spongycastle.asn1.DEROutputStream)
|
||||||
|
*/
|
||||||
|
void encode(ASN1OutputStream out) throws IOException
|
||||||
|
{
|
||||||
|
int classBits = BERTags.APPLICATION;
|
||||||
|
if (isConstructed)
|
||||||
|
{
|
||||||
|
classBits |= BERTags.CONSTRUCTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
out.writeEncoded(classBits, tag, octets);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean asn1Equals(
|
||||||
|
ASN1Primitive 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;
|
||||||
|
}
|
||||||
|
}
|
153
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/DERBMPString.java
vendored
Normal file
153
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/DERBMPString.java
vendored
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.spongycastle.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DER BMPString object.
|
||||||
|
*/
|
||||||
|
public class DERBMPString
|
||||||
|
extends ASN1Primitive
|
||||||
|
implements ASN1String
|
||||||
|
{
|
||||||
|
private char[] 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 byte[])
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return (DERBMPString)fromByteArray((byte[])obj);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return 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)
|
||||||
|
{
|
||||||
|
ASN1Primitive o = obj.getObject();
|
||||||
|
|
||||||
|
if (explicit || o instanceof DERBMPString)
|
||||||
|
{
|
||||||
|
return getInstance(o);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new DERBMPString(ASN1OctetString.getInstance(o).getOctets());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* basic constructor - byte encoded string.
|
||||||
|
*/
|
||||||
|
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 = cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
DERBMPString(char[] string)
|
||||||
|
{
|
||||||
|
this.string = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* basic constructor
|
||||||
|
*/
|
||||||
|
public DERBMPString(
|
||||||
|
String string)
|
||||||
|
{
|
||||||
|
this.string = string.toCharArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getString()
|
||||||
|
{
|
||||||
|
return new String(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return getString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return Arrays.hashCode(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean asn1Equals(
|
||||||
|
ASN1Primitive o)
|
||||||
|
{
|
||||||
|
if (!(o instanceof DERBMPString))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DERBMPString s = (DERBMPString)o;
|
||||||
|
|
||||||
|
return Arrays.areEqual(string, s.string);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isConstructed()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int encodedLength()
|
||||||
|
{
|
||||||
|
return 1 + StreamUtil.calculateBodyLength(string.length * 2) + (string.length * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void encode(
|
||||||
|
ASN1OutputStream out)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
out.write(BERTags.BMP_STRING);
|
||||||
|
out.writeLength(string.length * 2);
|
||||||
|
|
||||||
|
for (int i = 0; i != string.length; i++)
|
||||||
|
{
|
||||||
|
char c = string[i];
|
||||||
|
|
||||||
|
out.write((byte)(c >> 8));
|
||||||
|
out.write((byte)c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
313
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/DERBitString.java
vendored
Normal file
313
extern/spongycastle/core/src/main/java/org/spongycastle/asn1/DERBitString.java
vendored
Normal file
@ -0,0 +1,313 @@
|
|||||||
|
package org.spongycastle.asn1;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.EOFException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.spongycastle.util.Arrays;
|
||||||
|
import org.spongycastle.util.io.Streams;
|
||||||
|
|
||||||
|
public class DERBitString
|
||||||
|
extends ASN1Primitive
|
||||||
|
implements ASN1String
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
ASN1Primitive o = obj.getObject();
|
||||||
|
|
||||||
|
if (explicit || o instanceof DERBitString)
|
||||||
|
{
|
||||||
|
return getInstance(o);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return fromOctetString(((ASN1OctetString)o).getOctets());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(
|
||||||
|
int value)
|
||||||
|
{
|
||||||
|
this.data = getBytes(value);
|
||||||
|
this.padBits = getPadBits(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DERBitString(
|
||||||
|
ASN1Encodable obj)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
this.data = obj.toASN1Primitive().getEncoded(ASN1Encoding.DER);
|
||||||
|
this.padBits = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isConstructed()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int encodedLength()
|
||||||
|
{
|
||||||
|
return 1 + StreamUtil.calculateBodyLength(data.length + 1) + data.length + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void encode(
|
||||||
|
ASN1OutputStream 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(BERTags.BIT_STRING, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return padBits ^ Arrays.hashCode(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean asn1Equals(
|
||||||
|
ASN1Primitive 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
static DERBitString fromOctetString(byte[] bytes)
|
||||||
|
{
|
||||||
|
if (bytes.length < 1)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("truncated BIT STRING detected");
|
||||||
|
}
|
||||||
|
|
||||||
|
int padBits = bytes[0];
|
||||||
|
byte[] data = new byte[bytes.length - 1];
|
||||||
|
|
||||||
|
if (data.length != 0)
|
||||||
|
{
|
||||||
|
System.arraycopy(bytes, 1, data, 0, bytes.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DERBitString(data, padBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DERBitString fromInputStream(int length, InputStream stream)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (length < 1)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("truncated BIT STRING detected");
|
||||||
|
}
|
||||||
|
|
||||||
|
int padBits = stream.read();
|
||||||
|
byte[] data = new byte[length - 1];
|
||||||
|
|
||||||
|
if (data.length != 0)
|
||||||
|
{
|
||||||
|
if (Streams.readFully(stream, data) != data.length)
|
||||||
|
{
|
||||||
|
throw new EOFException("EOF encountered in middle of BIT STRING");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DERBitString(data, padBits);
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user