Replace NtruSign with GMSS which uses smaller public keys and inspires more confidence security-wise
This commit is contained in:
@@ -63,7 +63,7 @@
|
||||
<div class="main">
|
||||
<h2><ib:message key="Please wait..."/></h2>
|
||||
<img src="images/wait.gif"/>
|
||||
<ib:message key="The Email Identity is being generated."/>
|
||||
<ib:message key="The Email Identity is being generated. This can take several minutes."/>
|
||||
</div>
|
||||
</c:when>
|
||||
<%-- This is where the actual identity generation takes place --%>
|
||||
|
||||
21
build.xml
21
build.xml
@@ -124,6 +124,7 @@
|
||||
<lib file="${lib}/i2pbote.jar"/>
|
||||
<lib file="${lib}/mailapi.jar"/>
|
||||
<lib file="${lib}/bcprov-ecc-jdk16-145.jar"/>
|
||||
<lib file="ant_build/lib/flexi-gmss-1.7p1.jar"/>
|
||||
<zipfileset dir="WebContent/images" prefix="images"/>
|
||||
</war>
|
||||
|
||||
@@ -133,10 +134,17 @@
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="jar" depends="compile,precompilejsp,bundle">
|
||||
<target name="flexijar" depends="compile">
|
||||
<mkdir dir="ant_build/lib"/>
|
||||
<jar destfile="ant_build/lib/flexi-gmss-1.7p1.jar">
|
||||
<fileset dir="ant_build/classes" includes="de/flexiprovider/** codec/**"/>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="jar" depends="compile,flexijar,precompilejsp,bundle">
|
||||
<mkdir dir="ant_build" />
|
||||
<jar destfile="${lib}/i2pbote.jar">
|
||||
<fileset dir="ant_build/classes" excludes="i2p/bote/web/** i2p/bote/jsp/** org/apache/jsp/** **/*Test.class"/>
|
||||
<fileset dir="ant_build/classes" excludes="i2p/bote/web/** i2p/bote/jsp/** org/apache/jsp/** de/flexiprovider/** codec/** **/*Test.class"/>
|
||||
<fileset dir="src" includes="i2p/bote/network/built-in-peers.txt"/>
|
||||
</jar>
|
||||
</target>
|
||||
@@ -177,6 +185,13 @@
|
||||
<arg value="plugin/plugin.tmp/lib/bcprov-ecc-jdk16-145.jar.pack"/>
|
||||
<arg value="${lib}/bcprov-ecc-jdk16-145.jar"/>
|
||||
</exec>
|
||||
<exec executable="pack200" failonerror="true">
|
||||
<arg value="--no-gzip"/>
|
||||
<arg value="--effort=9"/>
|
||||
<arg value="--modification-time=latest"/>
|
||||
<arg value="plugin/plugin.tmp/lib/flexi-gmss-1.7p1.jar.pack"/>
|
||||
<arg value="ant_build/lib/flexi-gmss-1.7p1.jar"/>
|
||||
</exec>
|
||||
|
||||
<copy file="WebContent/WEB-INF/lib/encrypt.sh" todir="plugin/plugin.tmp/lib"/>
|
||||
<copy file="WebContent/WEB-INF/lib/decrypt.sh" todir="plugin/plugin.tmp/lib"/>
|
||||
@@ -220,7 +235,7 @@
|
||||
</target>
|
||||
|
||||
<!-- same as war but without the library jars -->
|
||||
<target name="pluginwar" depends="compile,precompilejsp,bundle">
|
||||
<target name="pluginwar" depends="compile,flexijar,precompilejsp,bundle">
|
||||
<mkdir dir="ant_build" />
|
||||
<war destfile="i2pbote-plugin.war" webxml="ant_build/web.xml">
|
||||
<classes dir="ant_build/classes" includes="i2p/bote/web/** i2p/bote/jsp/** org/apache/jsp/**" />
|
||||
|
||||
@@ -607,6 +607,11 @@ The file format is:
|
||||
mailapi.jar Part of JavaMail
|
||||
src/SevenZip/ An LZMA implementation from http://www.7-zip.org/sdk.html
|
||||
src/net/sf/ntru An NTRU implementation from http://sf.net/projects/ntru/
|
||||
de/flexiprovider and codec/ A stripped down and patched version of the FlexiProvider
|
||||
sources (http://www.flexiprovider.de/), containing only the
|
||||
classes needed for GMSS.
|
||||
The patch consists of a modified de.flexiprovider.core.CoreRegistry
|
||||
so there are no dependencies on classes not related to GMSS.
|
||||
src/com/lambdaworks/crypto/ An scrypt implementation from https://github.com/wg/scrypt/
|
||||
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
webapps.i2pbote.classpath=$I2P/lib/jstl.jar,$I2P/lib/standard.jar,$PLUGIN/lib/i2pbote.jar,$PLUGIN/lib/mailapi.jar,$PLUGIN/lib/bcprov-ecc-jdk16-145.jar
|
||||
webapps.i2pbote.classpath=$I2P/lib/jstl.jar,$I2P/lib/standard.jar,$PLUGIN/lib/i2pbote.jar,$PLUGIN/lib/mailapi.jar,$PLUGIN/lib/bcprov-ecc-jdk16-145.jar,$PLUGIN/lib/flexi-gmss-1.7p1.jar
|
||||
|
||||
106
src/codec/CorruptedCodeException.java
Normal file
106
src/codec/CorruptedCodeException.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec;
|
||||
|
||||
/**
|
||||
* Thrown if a code is recognized as being corrupted for instance due to
|
||||
* transmission errors.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version $Id: CorruptedCodeException.java,v 1.3 2005/04/06 09:24:51 flautens
|
||||
* Exp $
|
||||
* @see Base64
|
||||
*/
|
||||
public class CorruptedCodeException extends Exception {
|
||||
/**
|
||||
* Creates an exception instance with no particular message.
|
||||
*/
|
||||
public CorruptedCodeException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an exception instance with the given message.
|
||||
*
|
||||
* @param message
|
||||
* The message string describing the reason for this
|
||||
* exception.
|
||||
*/
|
||||
public CorruptedCodeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
162
src/codec/InconsistentStateException.java
Normal file
162
src/codec/InconsistentStateException.java
Normal file
@@ -0,0 +1,162 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec;
|
||||
|
||||
/**
|
||||
* Signals an inconsistent object state. Objects can enter inconsistent states
|
||||
* for instance if an exception is caught that shouldn't happen. Such exceptions
|
||||
* can occur due to unexpected exceptions from other code or internal errors.
|
||||
* <p>
|
||||
* A typical example is when an application knows that a specific error
|
||||
* condition cannot occur because the preconditions required for a successful
|
||||
* completion of a method call are met, but an exception is thrown nevertheless.
|
||||
* In this case, the exception can be caught and wrapped into an exception of
|
||||
* this class in order to pass on the original cause of the exception to code
|
||||
* further up the calling stack.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: InconsistentStateException.java,v 1.3 2005/04/06 09:33:26
|
||||
* flautens Exp $"
|
||||
*/
|
||||
public class InconsistentStateException extends RuntimeException {
|
||||
/**
|
||||
* The wrapped exception
|
||||
*/
|
||||
private Exception e_;
|
||||
|
||||
/**
|
||||
* Creates an instance.
|
||||
*/
|
||||
public InconsistentStateException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given message.
|
||||
*
|
||||
* @param message
|
||||
* The message.
|
||||
*/
|
||||
public InconsistentStateException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an exception that wraps around the given exception. The message
|
||||
* of this exception is set to the one of the given exception. The given
|
||||
* exception must not be <code>null</code>.
|
||||
*
|
||||
* @param e
|
||||
* The exception that shall be wrapped in this one.
|
||||
* @throws NullPointerException
|
||||
* if the given exception is <code>null</code>.
|
||||
*/
|
||||
public InconsistentStateException(Exception e) {
|
||||
super(e.getMessage());
|
||||
e_ = e;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wrapped exception or <code>this</code> if no exception is
|
||||
* wrapped in this one.
|
||||
*
|
||||
* @return The wrapped exception or <code>this</code> if there is no
|
||||
* exception wrapped by this one.
|
||||
*/
|
||||
public Exception getException() {
|
||||
if (e_ == null) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return e_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the stack trace of this exception. If this exception has a wrapped
|
||||
* exception then the stack trace of the wrapped exception is printed
|
||||
* instead of the one of this exception. Since this exception was created in
|
||||
* the course of catching the wrapped exception, the location where this
|
||||
* exception was thrown is included in the stack trace of the wrapped
|
||||
* exception.
|
||||
*/
|
||||
public void printStackTrace() {
|
||||
if (e_ == null) {
|
||||
super.printStackTrace();
|
||||
} else {
|
||||
e_.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
369
src/codec/asn1/ASN1.java
Normal file
369
src/codec/asn1/ASN1.java
Normal file
@@ -0,0 +1,369 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* Defines various constants used with ASN.1 such as the tag and type class
|
||||
* identifiers. The classes in this package are modelled along the lines of
|
||||
* ITU-T Recommendations X.680, X.681, X.682, X.690, and X.691. From now on we
|
||||
* assume the reader is familiar with ASN.1, BER, and DER.
|
||||
* <p>
|
||||
*
|
||||
* This package defines a number of primitive types as specified by the basic
|
||||
* syntax in X.680. Based on these primitive types more complex types can be
|
||||
* created. We refer to these types as <i>compound types</i> or <i> structures</i>.
|
||||
* Below, we discuss how such types are constructed, encoded and decoded using
|
||||
* the classes in this package.
|
||||
* <p>
|
||||
*
|
||||
* For instance the type <tt>PrivateKeyInfo</tt> is defined in PKCS#8 as
|
||||
* follows using ASN.1: <blockquote>
|
||||
*
|
||||
* <pre>
|
||||
* PrivateKeyInfo ::= SEQUENCE (
|
||||
* version Version,
|
||||
* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
|
||||
* privateKey PrivateKey,
|
||||
* attributes [0] IMPLICIT Attributes OPTIONAL
|
||||
* }
|
||||
* Version ::= INTEGER
|
||||
* PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
* PrivateKey ::= OCTET STRING
|
||||
* Attributes ::= SET OF Attribute
|
||||
* </pre>
|
||||
*
|
||||
* </blockquote>
|
||||
*
|
||||
* This type can be created as follows based on the classes in this package:
|
||||
* <blockquote>
|
||||
*
|
||||
* <pre>
|
||||
* public class PrivateKeyInfo extends ASN1Sequence
|
||||
* {
|
||||
* public PrivateKeyInfo()
|
||||
* {
|
||||
* add(new ASN1Integer());
|
||||
* add(new AlgorithmIdentifier()); // Detailed below
|
||||
* add(new ASN1OctetString());
|
||||
* add(new ASN1TaggedType(
|
||||
* 0, new ASN1SetOf(Attribute.class), false, true);
|
||||
* }
|
||||
* ...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* </blockquote> The {@link ASN1TaggedType tagged type} allows to define types
|
||||
* of the ASN.1 tag class UNIVERSAL, CONTEXT SPECIFIC, APPLICATION, and PRIVATE.
|
||||
* The constructor shown above is a convenience constructor that assumes the
|
||||
* class is CONTEXT SPECIFIC. The third parameter specifies that the tagging is
|
||||
* not EXPLICIT (hence IMPLICIT as required by the definition above), and the
|
||||
* fourth parameter specifies that <tt>attributes</tt> is OPTIONAL.
|
||||
* <p>
|
||||
*
|
||||
* The interface {@link ASN1Type ASN1Type} specifies a number of methods to
|
||||
* declare types as OPTIONAL, IMPLICIT or EXPLICIT. In principle, ASN.1
|
||||
* structures can be modelled almost one to one using the classes in this
|
||||
* package.
|
||||
* <p>
|
||||
*
|
||||
* Individual types also offer setter methods and constructors that allow to
|
||||
* preset certain values as the values of the ASN.1 types from native Java types
|
||||
* such as String, int, byte[] etc.
|
||||
* <p>
|
||||
*
|
||||
* Once, a primitive type or a compound type <tt>x</tt> has been defined and
|
||||
* initialized it can be encoded in a number of ways. The first step is to
|
||||
* choose an {@link Encoder encoder}. One example encoder is the
|
||||
* {@link DEREncoder DEREncoder}. This encoder encodes types according to the
|
||||
* Distinguished Encoding Rules, a subset of the Basic Encoding Rules defined in
|
||||
* the ITU-T Recommendations. Encoding to a file is simple, the following code
|
||||
* snippet shows how to do it: <blockquote>
|
||||
*
|
||||
* <pre>
|
||||
* DEREncoder enc;
|
||||
* enc = new DEREncoder(new FileOutputStream("code.der"));
|
||||
* enc.writeType(x);
|
||||
* enc.close();
|
||||
* </pre>
|
||||
*
|
||||
* </blockquote> There is nothing more to it. However, only types not declared
|
||||
* as OPTIONAL are written to the stream. Hence, the type <tt>
|
||||
* attributes</tt>
|
||||
* mentioned above is not written.
|
||||
* <p>
|
||||
*
|
||||
* Why then is it declared as OPTIONAL? Answer, by convention in this package
|
||||
* (and by reason) the default constructor is meant to initialize a type for
|
||||
* decoding. In a code the <tt>
|
||||
* attributes</tt> type can be encountered. The
|
||||
* decoder clears the OPTIONAL flag of types it encounters during decoding so it
|
||||
* is clear which types were present and which were not. If a type is only used
|
||||
* for encoding and not for decoding then the OPTIONAL types not required can be
|
||||
* omitted.
|
||||
*
|
||||
* <pre>
|
||||
* AlgorithmIdentifier ::= SEQUENCE{
|
||||
* algorithm OBJECT IDENTIFIER,
|
||||
* parameters ANY DEFINED BY algorithm OPTIONAL
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1.java,v 1.4 2005/03/22 16:04:37 flautens Exp $"
|
||||
*/
|
||||
public final class ASN1 extends Object {
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_EOC = 0;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_BOOLEAN = 1;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_INTEGER = 2;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_BITSTRING = 3;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_OCTETSTRING = 4;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_NULL = 5;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_OID = 6;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_REAL = 9;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_ENUMERATED = 10;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_UTF8STRING = 12;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_SEQUENCE = 16;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_SET = 17;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_NUMERICSTRING = 18;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_PRINTABLESTRING = 19;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_T61STRING = 20;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_VIDEOTEXTSTRING = 21;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_IA5STRING = 22;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_UTCTIME = 23;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_GENERALIZEDTIME = 24;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_GRAPHICSTRING = 25;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_VISIBLESTRING = 26;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_GENERALSTRING = 27;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_UNIVERSALSTRING = 28;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_BMPSTRING = 30;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_MASK = 0x1f;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int TAG_LONGFORM = 0x1f;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int CLASS_UNIVERSAL = 0x00;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int CLASS_APPLICATION = 0x40;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int CLASS_CONTEXT = 0x80;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int CLASS_PRIVATE = 0xc0;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int CLASS_MASK = 0xc0;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int PRIMITIVE = 0x00;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int CONSTRUCTED = 0x20;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int LENGTH_LONGFORM = 0x80;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public static final int LENGTH_MASK = 0x7f;
|
||||
|
||||
/**
|
||||
* No-one can instantiate this class.
|
||||
*/
|
||||
private ASN1() {
|
||||
}
|
||||
}
|
||||
412
src/codec/asn1/ASN1AbstractCollection.java
Normal file
412
src/codec/asn1/ASN1AbstractCollection.java
Normal file
@@ -0,0 +1,412 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutput;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Represents an abstract collection of ASN.1 types such as a SEQUENCE or a SET.
|
||||
* Since this class inherits from the Collection framework class ArrayList,
|
||||
* ASN.1 types may be added conveniently just as object instances are added to a
|
||||
* list.
|
||||
* <p>
|
||||
*
|
||||
* Please note that constraints of collections are validated before encoding and
|
||||
* after decoding. Invalid modification of a collection type can be detected on
|
||||
* importing and exporting abstract collections. On DER encoding a collection
|
||||
* its constraint is validated twice since the DER encoding is a two-pass
|
||||
* process.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1AbstractCollection.java,v 1.5 2005/03/22 16:12:45 flautens
|
||||
* Exp $"
|
||||
*/
|
||||
public abstract class ASN1AbstractCollection extends ArrayList implements
|
||||
ASN1Collection, Cloneable, Externalizable {
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
private boolean optional_ = false;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
private boolean explicit_ = true;
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
private Constraint constraint_;
|
||||
|
||||
/**
|
||||
* Abstract method declarations.
|
||||
*
|
||||
* @return corresponding ASN1 tag
|
||||
*/
|
||||
public abstract int getTag();
|
||||
|
||||
/**
|
||||
* Method declarations with default implementation.
|
||||
*/
|
||||
public ASN1AbstractCollection() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given capacity.
|
||||
*
|
||||
* @param capacity
|
||||
* The capacity.
|
||||
*/
|
||||
public ASN1AbstractCollection(int capacity) {
|
||||
super(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java type that corresponds to this ASN.1 type.
|
||||
*
|
||||
* @return The collection used internally for storing the elements in this
|
||||
* constructed ASN.1 type.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java type that corresponds to this ASN.1 type.
|
||||
*
|
||||
* @return The collection used internally for storing the elements in this
|
||||
* constructed ASN.1 type.
|
||||
*/
|
||||
public Collection getCollection() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional types may be present in an encoding but they need not be.
|
||||
*
|
||||
* @param optional
|
||||
* <code>true</code> iff this type is optional.
|
||||
*/
|
||||
public void setOptional(boolean optional) {
|
||||
optional_ = optional;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> iff this type is optional.
|
||||
*/
|
||||
public boolean isOptional() {
|
||||
return optional_;
|
||||
}
|
||||
|
||||
/**
|
||||
* This default implementation returns {@link ASN1#CLASS_UNIVERSAL
|
||||
* UNIVERSAL}.
|
||||
*
|
||||
* @return The class of the ASN.1 tag.
|
||||
*/
|
||||
public int getTagClass() {
|
||||
return ASN1.CLASS_UNIVERSAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tagging of this type as either EXPLICIT or IMPLICIT. The default
|
||||
* is EXPLICIT. Encoders skip the encoding of identifier octets for types
|
||||
* that are declared as IMPLICIT.
|
||||
*
|
||||
* @param explicit
|
||||
* <code>true</code> if this type shall be tagged EXPLICIT
|
||||
* and <code>false</code> if it shall be encoded IMPLICIT.
|
||||
*/
|
||||
public void setExplicit(boolean explicit) {
|
||||
explicit_ = explicit;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return <code>true</code> if this type is tagged EXPLICIT and
|
||||
* <code>false</code> if it is tagged IMPLICIT.
|
||||
*/
|
||||
public boolean isExplicit() {
|
||||
return explicit_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Constraint Constraint} of this type. For instance an
|
||||
* ASN.1 INTEGER might be constrained to a certain range such as INTEGER
|
||||
* (0..99). <code>null</code> can be passed as a constraint which disables
|
||||
* constraint checking.
|
||||
*
|
||||
* @param constraint
|
||||
* The {@link Constraint Constraint} of this type.
|
||||
*/
|
||||
public void setConstraint(Constraint constraint) {
|
||||
constraint_ = constraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Constraint Constraint} of this type or
|
||||
* <code>null</code> if there is none.
|
||||
*
|
||||
* @return The Constraint or <code>null</code>.
|
||||
*/
|
||||
public Constraint getConstraint() {
|
||||
return constraint_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the constraint on this type if it is set. Otherwise this method
|
||||
* returns silently.
|
||||
*
|
||||
* @throws ConstraintException
|
||||
* if this type is not in the appropriate range of values.
|
||||
*/
|
||||
public void checkConstraints() throws ConstraintException {
|
||||
if (constraint_ != null) {
|
||||
constraint_.constrain(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the given tag and tag class matches the
|
||||
* tag and tag class of this instance. This method is used primarily by
|
||||
* decoders and variable types such as {@link ASN1Choice ASN1Choice} and
|
||||
* {@link ASN1OpenType ASN1OpenType}. It enables decoders to query a
|
||||
* variable type whether a decoded type is accepted.
|
||||
* <p>
|
||||
*
|
||||
* This method provides a default implementation that matches the given tag
|
||||
* and tag class against the values returned by {@link #getTag getTag} and
|
||||
* {@link #getTagClass getTagClass} respectively.
|
||||
*
|
||||
* @param tag
|
||||
* The tag to compare with.
|
||||
* @param tagclass
|
||||
* The tag class to compare with.
|
||||
* @return <code>true</code> if the given tag and tag class matches this
|
||||
* type and <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isType(int tag, int tagclass) {
|
||||
if ((getTag() == tag) && (getTagClass() == tagclass)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes this collection to the given {@link Encoder encoder}.
|
||||
*
|
||||
* @param enc
|
||||
* The encoder to write this type to.
|
||||
*/
|
||||
public void encode(Encoder enc) throws ASN1Exception, IOException {
|
||||
checkConstraints();
|
||||
enc.writeCollection(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads this collection from the given {@link Decoder Decoder}. This type
|
||||
* is initialized with the decoded data. The components of the decoded
|
||||
* collection must match the components of this collection. If they do then
|
||||
* the components are also initialized with the decoded values. Otherwise an
|
||||
* exception is thrown.
|
||||
*
|
||||
* @param dec
|
||||
* The decoder to read from.
|
||||
*/
|
||||
public void decode(Decoder dec) throws ASN1Exception, IOException {
|
||||
dec.readCollection(this);
|
||||
checkConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints this collection. This default implementation derives a descriptive
|
||||
* name from the name of the fully qualified name of this class (or that of
|
||||
* the respective subclass). The last component of the class name is
|
||||
* extracted and a prefix of "ASN1" is removed from it. Then the
|
||||
* elements contained in this collection are printed.
|
||||
*
|
||||
* @return The string representation of this ASN.1 collection.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer buf;
|
||||
Iterator i;
|
||||
String s;
|
||||
|
||||
s = removePackageName(getClass());
|
||||
|
||||
buf = new StringBuffer();
|
||||
buf.append(s);
|
||||
|
||||
if (isOptional()) {
|
||||
buf.append(" OPTIONAL");
|
||||
}
|
||||
|
||||
if (this instanceof ASN1CollectionOf) {
|
||||
buf.append(" SEQUENCE OF "
|
||||
+ removePackageName(((ASN1CollectionOf) this)
|
||||
.getElementType()));
|
||||
} else {
|
||||
buf.append(" SEQUENCE ");
|
||||
}
|
||||
buf.append(" {\n");
|
||||
|
||||
for (i = iterator(); i.hasNext();) {
|
||||
buf.append(i.next().toString());
|
||||
buf.append("\n");
|
||||
}
|
||||
buf.append("}");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method removes the package information from the qualified class
|
||||
* name. If the remaining class name starts with 'ASN1' then this prefix is
|
||||
* also removed.
|
||||
*
|
||||
* @param clazz
|
||||
* The class to handle
|
||||
* @return the shortened class name
|
||||
*/
|
||||
private String removePackageName(Class clazz) {
|
||||
String s = clazz.getName();
|
||||
int n = s.lastIndexOf('.');
|
||||
|
||||
if (n < 0) {
|
||||
n = -1;
|
||||
}
|
||||
|
||||
s = s.substring(n + 1);
|
||||
if (s.startsWith("ASN1")) {
|
||||
s = s.substring(4);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* The writeExternal and readExternal methods of the Externalizable
|
||||
* interface are implemented by a class to give the serializable class
|
||||
* complete control over the format and contents of the stream for an object
|
||||
* and its supertypes.
|
||||
*
|
||||
* @param out -
|
||||
* the stream to write the object to
|
||||
* @see java.io.Externalizable
|
||||
*/
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
byte[] res = null;
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
try {
|
||||
encode(new DEREncoder(baos));
|
||||
res = baos.toByteArray();
|
||||
baos.close();
|
||||
out.write(res);
|
||||
} catch (ASN1Exception e) {
|
||||
throw new RuntimeException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The writeExternal and readExternal methods of the Externalizable
|
||||
* interface are implemented by a class to give the serializable class
|
||||
* complete control over the format and contents of the stream for an object
|
||||
* and its supertypes.
|
||||
*
|
||||
* @param in -
|
||||
* the stream to read data from in order to restore the
|
||||
* object
|
||||
* @see java.io.Externalizable
|
||||
*/
|
||||
public void readExternal(ObjectInput in) throws IOException {
|
||||
try {
|
||||
decode(new DERDecoder((ObjectInputStream) in));
|
||||
} catch (ASN1Exception e) {
|
||||
throw new RuntimeException(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
298
src/codec/asn1/ASN1AbstractString.java
Normal file
298
src/codec/asn1/ASN1AbstractString.java
Normal file
@@ -0,0 +1,298 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* The root class of all ASN.1 string types including but not limited to
|
||||
* IA5String, VisibleString, PrintableString, UTCTime, and GeneralizedTime.
|
||||
* <p>
|
||||
*
|
||||
* Each string type is encoded as if it is declared as <tt>[UNIVERSAL </tt><i>x</i><tt>] IMPLICIT OCTET STRING</tt>
|
||||
* where <i>x</i> is the tag number of the respective string type (see ITU-T
|
||||
* Rec. X.690, paragraph 8.20.3).
|
||||
* <p>
|
||||
*
|
||||
* There are 8 restructed string types of which 4 do not allow escape sequences,
|
||||
* namely NumericString, PrintableString, VisibleString (ISO646String) and
|
||||
* IA5String. TeletexString (T61String), VideotextString, GraphicString, and
|
||||
* GeneralString allow the use of escape sequences. However, the srings must be
|
||||
* encoded such as to use the minimum number of octets possible. All these
|
||||
* strings use 1-octet representations; IA5String uses 2-octet representations
|
||||
* for special characters.
|
||||
* <p>
|
||||
*
|
||||
* Two unrestricted string types are defined in X.680, namely BMPString and
|
||||
* UniversalString. BMPString uses a 2-octet representation per character and
|
||||
* UniversalString uses a 4-octet representation.
|
||||
* <p>
|
||||
*
|
||||
* Each string type represented in this package handles octets to character and
|
||||
* character to octets conversion according to the general coding scheme of the
|
||||
* particular string, but not neccessarily restriction to a particular character
|
||||
* set. This is to be implemented through {@link Constraint constraints} that
|
||||
* are added to the respective types on creation (in the constructors).
|
||||
* Restriction of character sets is thus done on the Unicode character set used
|
||||
* by Java.
|
||||
* <p>
|
||||
*
|
||||
* This class implements plain 1-octet to character conversion by default. Class
|
||||
* {@link ASN1BMPString ASN1BMPString} handles 2-octet conversion and class
|
||||
* {@link ASN1UniversalString ASN1UniversalString} handles 4-octets conversion.
|
||||
* Without reference to ISO defined character encodings these implementations
|
||||
* assume that the <i>n</i>-octet tuples represent the least significant bits
|
||||
* of the Unicode characters with the corresponding bits set to zero.
|
||||
*
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1AbstractString.java,v 1.4 2004/08/26 15:08:21 pebinger Exp $"
|
||||
*/
|
||||
public abstract class ASN1AbstractString extends ASN1AbstractType implements
|
||||
ASN1String {
|
||||
|
||||
private static final String DEFAULT_VALUE = "";
|
||||
|
||||
private String value_ = DEFAULT_VALUE;
|
||||
|
||||
public ASN1AbstractString() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given string value.
|
||||
*
|
||||
* This constructor calls {@link #setString setString} to set the string
|
||||
* value.
|
||||
*
|
||||
* @param s
|
||||
* The string value.
|
||||
*/
|
||||
public ASN1AbstractString(String s) {
|
||||
setString0(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the represented string value.
|
||||
*
|
||||
* @return The string value of this type.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return value_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the represented string value.
|
||||
*
|
||||
* @return The string value of this type.
|
||||
*/
|
||||
public String getString() {
|
||||
return value_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the string value.
|
||||
*
|
||||
* @param s
|
||||
* The string value.
|
||||
* @throws ConstraintException
|
||||
* if the given string does not match the constraint set for
|
||||
* this instance.
|
||||
*/
|
||||
public void setString(String s) throws ConstraintException {
|
||||
setString0(s);
|
||||
checkConstraints();
|
||||
}
|
||||
|
||||
protected void setString0(String s) {
|
||||
if (s == null)
|
||||
throw new NullPointerException("Need a string!");
|
||||
|
||||
value_ = s;
|
||||
}
|
||||
|
||||
public void encode(Encoder enc) throws ASN1Exception, IOException {
|
||||
enc.writeString(this);
|
||||
}
|
||||
|
||||
public void decode(Decoder enc) throws ASN1Exception, IOException {
|
||||
enc.readString(this);
|
||||
checkConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given byte array to a string by filling up each consecutive
|
||||
* byte with 0's to the size of the Unicode characters.
|
||||
*
|
||||
* @param b
|
||||
* The byte array to convert.
|
||||
* @throws ASN1Exception
|
||||
* never, only for compliance with the {@link ASN1String}
|
||||
* interface.
|
||||
*/
|
||||
public String convert(byte[] b) throws ASN1Exception {
|
||||
if (b == null)
|
||||
throw new NullPointerException("Cannot convert null array!");
|
||||
|
||||
char[] c = new char[b.length];
|
||||
for (int i = 0; i < b.length; i++)
|
||||
c[i] = (char) (b[i] & 0xff);
|
||||
|
||||
return String.valueOf(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given string to a byte array by chopping away all but the
|
||||
* least significant byte of each character.
|
||||
*
|
||||
* @param s
|
||||
* The string to convert.
|
||||
* @throws ASN1Exception
|
||||
* never, only for compliance with the {@link ASN1String}
|
||||
* interface.
|
||||
*/
|
||||
public byte[] convert(String s) throws ASN1Exception {
|
||||
if (s == null)
|
||||
throw new NullPointerException("Cannot convert null string!");
|
||||
|
||||
char[] c = s.toCharArray();
|
||||
byte[] b = new byte[c.length];
|
||||
|
||||
for (int i = 0; i < c.length; i++)
|
||||
b[i] = (byte) (c[i] & 0xff);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes required to store the converted string.
|
||||
*
|
||||
* @param s
|
||||
* The string.
|
||||
* @throws ASN1Exception
|
||||
* never, only for compliance with the {@link ASN1String}
|
||||
* interface.
|
||||
*/
|
||||
public int convertedLength(String s) throws ASN1Exception {
|
||||
return s.length();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String s;
|
||||
int n;
|
||||
|
||||
s = getClass().getName();
|
||||
n = s.lastIndexOf('.');
|
||||
|
||||
if (n < 0)
|
||||
n = -1;
|
||||
|
||||
s = s.substring(n + 1);
|
||||
if (s.startsWith("ASN1"))
|
||||
s = s.substring(4);
|
||||
|
||||
return s + " \"" + value_ + "\"";
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether some other ASN.1 string is "equal to" this one.
|
||||
*
|
||||
* @param s
|
||||
* the reference string with which to compare.
|
||||
* @return true if this string is the same as the s argument; false
|
||||
* otherwise.
|
||||
* @see java.lang.Object#equals(java.lang.Object)
|
||||
*/
|
||||
public boolean equals(Object s) {
|
||||
if (this.getClass().equals(s.getClass())) {
|
||||
return value_.equals(((ASN1AbstractString) s).getString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code value for the object calculated from the contained
|
||||
* <code>String</code>.
|
||||
*
|
||||
* @return a hash code value for this object.
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
public int hashCode() {
|
||||
return (this.getClass().hashCode() + value_.hashCode()) / 2;
|
||||
}
|
||||
|
||||
}
|
||||
299
src/codec/asn1/ASN1AbstractType.java
Normal file
299
src/codec/asn1/ASN1AbstractType.java
Normal file
@@ -0,0 +1,299 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Externalizable;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
/**
|
||||
* The basic interface for Java objects representing primitive ASN.1 types
|
||||
* according to ITU-T Recommendation X.680.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1AbstractType.java,v 1.4 2005/03/23 12:45:51 flautens Exp $"
|
||||
*/
|
||||
public abstract class ASN1AbstractType extends Object implements ASN1Type,
|
||||
Cloneable, Externalizable {
|
||||
/**
|
||||
* Holds the ASN.1 optional state. Optional types may be present in an
|
||||
* encoding but they need not be.
|
||||
*/
|
||||
private boolean optional_ = false;
|
||||
|
||||
/**
|
||||
* This flag defines the tagging variant which should be used by the
|
||||
* decoder/encoder while processing this type.
|
||||
*/
|
||||
private boolean explicit_ = true;
|
||||
|
||||
/**
|
||||
* Holds the constraint which should be checked if the internal value of a
|
||||
* sub class is modified.
|
||||
*/
|
||||
private Constraint constraint_;
|
||||
|
||||
/**
|
||||
* This abstract method should return the value wrapped by the ASN1Type.
|
||||
*
|
||||
* @return the internal value
|
||||
*/
|
||||
public abstract Object getValue();
|
||||
|
||||
/**
|
||||
* Returns the corresponding ASN.1 tag.
|
||||
*
|
||||
* @return the corresponding ASN.1 tag
|
||||
*/
|
||||
public abstract int getTag();
|
||||
|
||||
public abstract void encode(Encoder enc) throws ASN1Exception, IOException;
|
||||
|
||||
public abstract void decode(Decoder dec) throws ASN1Exception, IOException;
|
||||
|
||||
/*
|
||||
* Method declarations with default implementation.
|
||||
*/
|
||||
public ASN1AbstractType() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional types may be present in an encoding but they need not be.
|
||||
*
|
||||
* @param optional
|
||||
* <code>true</code> iff this type is optional.
|
||||
*/
|
||||
public void setOptional(boolean optional) {
|
||||
optional_ = optional;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if this type is optional.
|
||||
*/
|
||||
public boolean isOptional() {
|
||||
return optional_;
|
||||
}
|
||||
|
||||
/**
|
||||
* This default implementation returns {@link ASN1#CLASS_UNIVERSAL
|
||||
* UNIVERSAL}.
|
||||
*
|
||||
* @return The class of the ASN.1 tag.
|
||||
*/
|
||||
public int getTagClass() {
|
||||
return ASN1.CLASS_UNIVERSAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tagging of this type as either EXPLICIT or IMPLICIT. The default
|
||||
* is EXPLICIT. Encoders skip the encoding of identifier octets for types
|
||||
* that are declared as IMPLICIT.
|
||||
*
|
||||
* @param explicit
|
||||
* <code>true</code> if this type shall be tagged EXPLICIT
|
||||
* and <code>false</code> if it shall be encoded IMPLICIT.
|
||||
*/
|
||||
public void setExplicit(boolean explicit) {
|
||||
explicit_ = explicit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns code>true</code> if this type is tagged EXPLICIT and <code>false</code>
|
||||
* otherwise.
|
||||
*
|
||||
* @return <code>true</code> if this type is tagged EXPLICIT and <code>false</code>
|
||||
* if it is tagged IMPLICIT.
|
||||
*/
|
||||
public boolean isExplicit() {
|
||||
return explicit_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the given tag and tag class matches the
|
||||
* tag and tag class of this instance. This method is used primarily by
|
||||
* decoders and variable types such as {@link ASN1Choice ASN1Choice} and
|
||||
* {@link ASN1OpenType ASN1OpenType}. It enables decoders to query a
|
||||
* variable type whether a decoded type is accepted.
|
||||
* <p>
|
||||
*
|
||||
* This method provides a default implementation that matches the given tag
|
||||
* and tag class against the values returned by {@link #getTag getTag} and
|
||||
* {@link #getTagClass getTagClass} respectively.
|
||||
*
|
||||
* @param tag
|
||||
* The tag to compare with.
|
||||
* @param tagclass
|
||||
* The tag class to compare with.
|
||||
* @return <code>true</code> if the given tag and tag class matches this
|
||||
* type and <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean isType(int tag, int tagclass) {
|
||||
if ((getTag() == tag) && (getTagClass() == tagclass)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Constraint Constraint} of this type. For instance an
|
||||
* ASN.1 INTEGER might be constrained to a certain range such as INTEGER
|
||||
* (0..99). <code>null</code> can be passed as a constraint which disables
|
||||
* constraint checking.
|
||||
*
|
||||
* @param constraint
|
||||
* The {@link Constraint Constraint} of this type.
|
||||
*/
|
||||
public void setConstraint(Constraint constraint) {
|
||||
constraint_ = constraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Constraint Constraint} of this type or
|
||||
* <code>null</code> if there is none.
|
||||
*
|
||||
* @return The Constraint or <code>null</code>.
|
||||
*/
|
||||
public Constraint getConstraint() {
|
||||
return constraint_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the constraint on this type if it is set. Otherwise this method
|
||||
* returns silently.
|
||||
*
|
||||
* @throws ConstraintException
|
||||
* if this type is not in the appropriate range of values.
|
||||
*/
|
||||
public void checkConstraints() throws ConstraintException {
|
||||
if (constraint_ != null) {
|
||||
constraint_.constrain(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The writeExternal and readExternal methods of the Externalizable
|
||||
* interface are implemented by a class to give the serializable class
|
||||
* complete control over the format and contents of the stream for an object
|
||||
* and its supertypes.
|
||||
*
|
||||
* @param out -
|
||||
* the stream to write the object to
|
||||
* @throws IOException
|
||||
* if an I/0 error has occured
|
||||
* @see java.io.Externalizable
|
||||
*/
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
byte[] res = null;
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
try {
|
||||
encode(new DEREncoder(baos));
|
||||
res = baos.toByteArray();
|
||||
baos.close();
|
||||
out.write(res);
|
||||
} catch (ASN1Exception e) {
|
||||
throw new RuntimeException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The writeExternal and readExternal methods of the Externalizable
|
||||
* interface are implemented by a class to give the serializable class
|
||||
* complete control over the format and contents of the stream for an object
|
||||
* and its supertypes.
|
||||
*
|
||||
* @param in -
|
||||
* the stream to read data from in order to restore the
|
||||
* object
|
||||
* @throws IOException
|
||||
* if an I/0 error has occured
|
||||
* @see java.io.Externalizable
|
||||
*/
|
||||
public void readExternal(ObjectInput in) throws IOException {
|
||||
try {
|
||||
decode(new DERDecoder((ObjectInputStream) in));
|
||||
} catch (ASN1Exception e) {
|
||||
throw new RuntimeException(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
510
src/codec/asn1/ASN1BitString.java
Normal file
510
src/codec/asn1/ASN1BitString.java
Normal file
@@ -0,0 +1,510 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents an ASN.1 BIT STRING type. The corresponding Java type is
|
||||
* <code>boolean[]</code>.
|
||||
* <p>
|
||||
*
|
||||
* This class has to modes of initialization which play a crucial role in
|
||||
* standards compliant DER encoding. One mode initializes instances of this
|
||||
* class as a representation of "named bits". The second mode
|
||||
* initializes it as a plain bitstring.
|
||||
* <p>
|
||||
*
|
||||
* An ASN.1 structure with named bits looks e.g., as follows:
|
||||
*
|
||||
* <pre>
|
||||
* Rights ::= BIT STRING { read(0), write(1), execute(2)}
|
||||
* </pre>
|
||||
*
|
||||
* Such bitstrings have a special canonical encoding. The mode (and defaults)
|
||||
* are specified in the documentation of the constructors of this class.
|
||||
* Basically, in named bits mode, trailing zeroes are truncated from the
|
||||
* internal representation of the bitstring.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1BitString.java,v 1.6 2005/03/23 13:01:20 flautens Exp $"
|
||||
*/
|
||||
public class ASN1BitString extends ASN1AbstractType {
|
||||
|
||||
private static final byte[] DEFAULT_VALUE = new byte[0];
|
||||
|
||||
private static final byte[] MASK = { (byte) 0x80, (byte) 0x40, (byte) 0x20,
|
||||
(byte) 0x10, (byte) 0x08, (byte) 0x04, (byte) 0x02, (byte) 0x01 };
|
||||
|
||||
private static final byte[] TRAIL_MASK = { (byte) 0xff, (byte) 0xfe,
|
||||
(byte) 0xfc, (byte) 0xf8, (byte) 0xf0, (byte) 0xe0, (byte) 0xc0,
|
||||
(byte) 0x80 };
|
||||
|
||||
private int pad_ = 0;
|
||||
|
||||
private byte[] value_ = DEFAULT_VALUE;
|
||||
|
||||
/**
|
||||
* Says whether this instance is a "named bits" bitstring. The
|
||||
* default is <code>false</code>.
|
||||
*/
|
||||
private boolean namedBits_ = false;
|
||||
|
||||
/**
|
||||
* Initializes an instance for decoding. This initializes this instance to
|
||||
* be decoded as a plain bitstring (no named bits). Use this for bitstrings
|
||||
* with named bits as well. It does not make a difference for the
|
||||
* application, but it ensures that bitstrings that have been decoded are
|
||||
* encoded in the same way again.
|
||||
*/
|
||||
public ASN1BitString() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the instance for encoding with the given bits. The index of
|
||||
* each bit corresponds to its number in the ASN.1 definition. This
|
||||
* constructor initializes the instance as a bitstring with named bits. The
|
||||
* array is not copied into this instance and can be modified subsequently
|
||||
* without causing side effects.
|
||||
*
|
||||
* @param b
|
||||
* The string of bits to be encoded.
|
||||
*/
|
||||
public ASN1BitString(boolean[] b) {
|
||||
setBits0(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given contents. Use of this constructor
|
||||
* copies the given byte array by reference and may cause side effects. The
|
||||
* mode of this bitstring is plain (no named bits are assumed).
|
||||
*
|
||||
* @param b
|
||||
* The left aligned contents bits.
|
||||
* @param pad
|
||||
* The number of pad bits.
|
||||
*/
|
||||
public ASN1BitString(byte[] b, int pad) {
|
||||
setBits0(b, pad);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method calls {@link #getBits getBits()}.
|
||||
*
|
||||
* @return The contents bits as a boolean array.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return getBits();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents bits of this instance. No side effects occur when
|
||||
* the returned array is modified.
|
||||
*
|
||||
* @return The contents bits.
|
||||
*/
|
||||
public boolean[] getBits() {
|
||||
int n, i;
|
||||
boolean[] b;
|
||||
|
||||
if (value_.length == 0) {
|
||||
return new boolean[0];
|
||||
}
|
||||
b = new boolean[(value_.length * 8) - pad_];
|
||||
|
||||
for (n = 0, i = 0; i < b.length; i++) {
|
||||
if ((value_[n] & MASK[i & 0x07]) != 0) {
|
||||
b[i] = true;
|
||||
} else {
|
||||
b[i] = false;
|
||||
}
|
||||
if ((i & 0x07) == 0x07) {
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the contents bits of this instance. This method does not cause side
|
||||
* effects. It switches to the named bits mode.
|
||||
*
|
||||
* @param bits
|
||||
* The contents bits that are set.
|
||||
* @throws ConstraintException
|
||||
* if the given bits violates the specified constraint.
|
||||
*/
|
||||
public void setBits(boolean[] bits) throws ConstraintException {
|
||||
setBits0(bits);
|
||||
checkConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the contents bits of this instance. This method does not cause side
|
||||
* effects. It switches to named bits mode.
|
||||
*
|
||||
* @param bits
|
||||
* The contents bits that are set.
|
||||
*/
|
||||
protected void setBits0(boolean[] bits) {
|
||||
namedBits_ = true;
|
||||
|
||||
if ((bits == null) || (bits.length == 0)) {
|
||||
value_ = DEFAULT_VALUE;
|
||||
pad_ = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
int j;
|
||||
int n;
|
||||
int k;
|
||||
byte m;
|
||||
byte[] b;
|
||||
|
||||
/*
|
||||
* We skip trailing zero bits. Trailing bits are to the "right" in ASN.1
|
||||
* terms (bits with high numbers).
|
||||
*/
|
||||
for (k = bits.length - 1; k >= 0; k--) {
|
||||
if (bits[k]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If all bits are zero then we set the default zero and we are done.
|
||||
*/
|
||||
if (k < 0) {
|
||||
value_ = DEFAULT_VALUE;
|
||||
pad_ = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
k++;
|
||||
|
||||
/*
|
||||
* If required we truncate trailing bits. This is compliant to the
|
||||
* X.690/DER encoding rules and saves us trouble in the encoder.
|
||||
*/
|
||||
b = new byte[(k + 7) / 8];
|
||||
m = 0;
|
||||
|
||||
for (n = 0, i = 0; i < k; i++) {
|
||||
j = i & 0x07;
|
||||
|
||||
if (bits[i]) {
|
||||
m = (byte) (m | MASK[j]);
|
||||
}
|
||||
if (j == 7) {
|
||||
b[n++] = m;
|
||||
m = 0;
|
||||
}
|
||||
}
|
||||
j = i & 0x07;
|
||||
|
||||
if (j != 0) {
|
||||
b[n] = m;
|
||||
}
|
||||
value_ = b;
|
||||
pad_ = (8 - j) & 0x07;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bit string from the given byte aray and pad count. Bit 0 is the
|
||||
* most significant bit in the first byte of the array and bit <i>n</i> is
|
||||
* bit 7-(<i>n</i><code>&0x07</code>) in byte floor(<i>n</i>/8).
|
||||
* The length of the bit string is <code>b.length</code>*8-pad. The pad
|
||||
* value be in the range of [0..7]. In other words the bits in the byte
|
||||
* array are left aligned.
|
||||
* <p>
|
||||
*
|
||||
* The given byte array may be copied by reference. Subsequent modification
|
||||
* of it can cause side effects. The mode is set not to represent named
|
||||
* bits.
|
||||
*
|
||||
* @param b
|
||||
* The bits encoded into a byte array.
|
||||
* @param pad
|
||||
* The number of pad bits after the actual bits in the array.
|
||||
* @throws IllegalArgumentException
|
||||
* if the pad value is out of range.
|
||||
* @throws ConstraintException
|
||||
* if the given bits violates the
|
||||
*/
|
||||
public void setBits(byte[] b, int pad) throws ConstraintException {
|
||||
setBits0(b, pad);
|
||||
checkConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the bits and number of trailing pad bits from the given byte array.
|
||||
* The given instance is copied by reference. Therefor side effects can
|
||||
* occur if the given byte array is modified subsequently. The
|
||||
* initialization mode is plain (no named bits).
|
||||
*
|
||||
* @param b
|
||||
* The minimum number of bytes to hold the left aligned
|
||||
* contents bits. Any unused trailing bits (as defined by the
|
||||
* pad count) MUST be zero!
|
||||
* @param p
|
||||
* The number of trailing padding bits.
|
||||
*/
|
||||
protected void setBits0(byte[] b, int p) {
|
||||
int n;
|
||||
|
||||
if ((p < 0) || (p > 7)) {
|
||||
throw new IllegalArgumentException("Illegal pad value (" + p + ")");
|
||||
}
|
||||
namedBits_ = false;
|
||||
|
||||
/*
|
||||
* We first skip all leading zero bytes.
|
||||
*/
|
||||
for (n = b.length - 1; n >= 0; n--) {
|
||||
if (b[n] != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If all bytes are zero then we encode a zero bit string and are done.
|
||||
*/
|
||||
if (n < 0) {
|
||||
if (p != 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Zero length bit strings can't have pad bits!");
|
||||
}
|
||||
value_ = DEFAULT_VALUE;
|
||||
pad_ = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* We test whether the trailing pad bits are really zeroes.
|
||||
*/
|
||||
if ((b[b.length - 1] & ~TRAIL_MASK[p]) != 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"trailing pad bits are not zero!");
|
||||
}
|
||||
value_ = b;
|
||||
pad_ = p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents octets of this instance. The bits are left aligned
|
||||
* and the most significant bit is a one (or else the bitstring is zero and
|
||||
* an empty array is returned). The returned byte array is the one used
|
||||
* internally. Modifying it causes side effects which may result in
|
||||
* erroneous encoding. So, don't modify it!
|
||||
* <p>
|
||||
*
|
||||
* Please also note that the bits in the bytes are left aligned. In other
|
||||
* words, the bits are shifted to the left by the amount of pad bits. Bit X
|
||||
* in the byte array corresponds to the logical bit with the number X minus
|
||||
* pad count.
|
||||
*
|
||||
* @return The bits left aligned in a byte array with no trailing zeroes.
|
||||
*/
|
||||
public byte[] getBytes() {
|
||||
return value_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of unused bits in the last byte of the bitstring's
|
||||
* byte array representation. This number is always in the range
|
||||
* zero to seven.
|
||||
*/
|
||||
public int getPadCount() {
|
||||
return pad_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of bytes of the bitstring's byte array representation.
|
||||
*/
|
||||
public int byteCount() {
|
||||
return value_.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bits of the bitstring representation. Bits are
|
||||
* counted only to the most significant bit that is a one. Trailing zeroes
|
||||
* are neither present in the internal representation nor are they counted.
|
||||
*
|
||||
* @return The number of bits of the bitstring representation.
|
||||
*/
|
||||
public int bitCount() {
|
||||
return (value_.length * 8) - pad_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> iff this instance has named bits.
|
||||
*/
|
||||
public boolean isNamedBits() {
|
||||
return namedBits_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the bit string contains no bits that are
|
||||
* 1. Otherwise, <code>false</code> is returned. This method is used by
|
||||
* the {@link DEREncoder DEREncoder} in order to determine cases in which
|
||||
* special encoding is to be used. If no bits of a BIT STRING are 1 then it
|
||||
* is encoded as <tt>0x03 0x01 0x00
|
||||
* </tt> even if the BIT STRING has
|
||||
* hundreds of bits in length.
|
||||
*
|
||||
* @return <code>true</code> if all bits are zero.
|
||||
*/
|
||||
public boolean isZero() {
|
||||
return (value_.length == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @return DOCUMENT ME!
|
||||
*/
|
||||
public int getTag() {
|
||||
return ASN1.TAG_BITSTRING;
|
||||
}
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @param enc
|
||||
* The encoder which is used to encode
|
||||
*
|
||||
* @throws ASN1Exception
|
||||
* DOCUMENT ME!
|
||||
* @throws IOException
|
||||
* if an I/O error occures
|
||||
*/
|
||||
public void encode(Encoder enc) throws ASN1Exception, IOException {
|
||||
enc.writeBitString(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes this instance. After decoding, this method restores the mode
|
||||
* (named bits vs no named bits) of this instance to the one it had before
|
||||
* decoding. This is to maintain the original mode while assuring that
|
||||
* encoded values are identical to decoded ones even if the encoding.
|
||||
*
|
||||
* @param dec
|
||||
* The decoder which is used to decode
|
||||
* @throws IOException
|
||||
* if an I/O error occures
|
||||
*/
|
||||
public void decode(Decoder dec) throws ASN1Exception, IOException {
|
||||
boolean tmp;
|
||||
|
||||
tmp = namedBits_;
|
||||
|
||||
try {
|
||||
dec.readBitString(this);
|
||||
} finally {
|
||||
namedBits_ = tmp;
|
||||
}
|
||||
|
||||
// Redudant, also called by setBits(byte[], int)
|
||||
// checkConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string representation of this ASN1BitString.
|
||||
*
|
||||
* @return the string representation of this ASN1BitString
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer buf;
|
||||
boolean[] bits;
|
||||
int i;
|
||||
|
||||
bits = getBits();
|
||||
buf = new StringBuffer(12 + bits.length);
|
||||
|
||||
buf.append("BitString '");
|
||||
|
||||
for (i = 0; i < bits.length; i++) {
|
||||
if (bits[i]) {
|
||||
buf.append("1");
|
||||
} else {
|
||||
buf.append("0");
|
||||
}
|
||||
}
|
||||
buf.append("'");
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
127
src/codec/asn1/ASN1Boolean.java
Normal file
127
src/codec/asn1/ASN1Boolean.java
Normal file
@@ -0,0 +1,127 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents an ASN.1 BOOEAN type. The corresponding Java type is
|
||||
* <code>boolean</code>. This type does not support constraint checking.
|
||||
*
|
||||
* @see Constraint
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1Boolean.java,v 1.2 2000/12/06 17:47:23 vroth Exp $"
|
||||
*/
|
||||
public class ASN1Boolean extends ASN1AbstractType {
|
||||
|
||||
private boolean value_ = true;
|
||||
|
||||
public ASN1Boolean() {
|
||||
}
|
||||
|
||||
public ASN1Boolean(boolean t) {
|
||||
setTrue(t);
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return new Boolean(value_);
|
||||
}
|
||||
|
||||
public boolean isTrue() {
|
||||
return value_;
|
||||
}
|
||||
|
||||
public void setTrue(boolean b) {
|
||||
value_ = b;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return ASN1.TAG_BOOLEAN;
|
||||
}
|
||||
|
||||
public void encode(Encoder enc) throws ASN1Exception, IOException {
|
||||
enc.writeBoolean(this);
|
||||
}
|
||||
|
||||
public void decode(Decoder dec) throws ASN1Exception, IOException {
|
||||
dec.readBoolean(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "BOOLEAN " + value_;
|
||||
}
|
||||
}
|
||||
420
src/codec/asn1/ASN1Choice.java
Normal file
420
src/codec/asn1/ASN1Choice.java
Normal file
@@ -0,0 +1,420 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* This type represents the ASN.1 CHOICE type as specified in ITU-T
|
||||
* Recommendation X.680. On decoding, the decoder must be able to decide
|
||||
* umambiguously which alternative choice it has to decode. For this reason all
|
||||
* elements in a CHOICE type must have distinctive tags.
|
||||
* <p>
|
||||
*
|
||||
* This class does not enforce the distinctive tag rule. Instead, the
|
||||
* alternative with the first matching tag should be chosen by decoders. The
|
||||
* application that builds the CHOICE type must take care not to produce
|
||||
* ambiguous sets of alternatives.
|
||||
* <p>
|
||||
*
|
||||
* This class distinguishes alternative choices and an inner type. Upon
|
||||
* decoding, the inner type is selected from the list of choices based on the
|
||||
* identifier octets encountered in the encoded stream. This type is then
|
||||
* {@link #setInnerType set as the inner type} of this instance. Unless an inner
|
||||
* type is set (either explicitly or by means of decoding) the state of the
|
||||
* choice is undefined.
|
||||
* <p>
|
||||
*
|
||||
* This instance always mimicks its inner type. The methods
|
||||
* {@link ASN1Type#getTag getTag}, {@link ASN1Type#getTagClass getTagClass},
|
||||
* {@link ASN1Type#getValue getValue} all return the appropriate results of the
|
||||
* corresponding method of the inner type. On encoding an instance of this class
|
||||
* the inner type is encoded.
|
||||
* <p>
|
||||
*
|
||||
* No nested CHOICE classes are supported. In principle this is easily supported
|
||||
* but it is not good style to build such structures.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1Choice.java,v 1.3 2004/08/06 15:01:20 flautens Exp $"
|
||||
*/
|
||||
public class ASN1Choice extends ASN1AbstractType {
|
||||
private static final String NO_INNER = "No inner type defined!";
|
||||
|
||||
private ASN1Type inner_;
|
||||
|
||||
private ArrayList choices_;
|
||||
|
||||
/**
|
||||
* Creates an instance with an initial capacity of 2.
|
||||
*/
|
||||
public ASN1Choice() {
|
||||
choices_ = new ArrayList(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given initial capacity. The capacity
|
||||
* determines the number of choices to store. This instance is backed by an
|
||||
* ArrayList, hence the capacity is increased dynamically as required. Use
|
||||
* the {@link #trimToSize() trimToSize()} method to trim the internal list
|
||||
* to the number of stored choices in order to reclaim memory.
|
||||
*
|
||||
* @param capacity
|
||||
* The initial capacity for storing choices.
|
||||
* @throws IllegalArgumentException
|
||||
* if the capacity is less than 1.
|
||||
*/
|
||||
public ASN1Choice(int capacity) {
|
||||
if (capacity < 1)
|
||||
throw new IllegalArgumentException(
|
||||
"capacity must be greater than zero!");
|
||||
|
||||
choices_ = new ArrayList(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given type as an alternative choice to the collection of
|
||||
* choices. The caller has to take care that no ambiguous choices are added.
|
||||
* Each added type must have a distinctive tag.
|
||||
* <p>
|
||||
*
|
||||
* CHOICE elements must neither be OPTIONAL nor tagged IMPLICIT. For safety,
|
||||
* this method calls {@link ASN1Type#setOptional setOptional}(false) and
|
||||
* {@link ASN1Type#setExplicit setExplicit}(true) on the given type.
|
||||
* Callers must not alter this setting after adding a type to this choice.
|
||||
* However, the CHOICE itself can be declared OPTIONAL.
|
||||
*
|
||||
* @param t
|
||||
* The ASN.1 type to add as a choice.
|
||||
* @throws NullPointerException
|
||||
* if the given type is <code>null</code>.
|
||||
* @throws IllegalArgumentException
|
||||
* if the given type is a ASN1Choice type.
|
||||
*/
|
||||
public void addType(ASN1Type t) {
|
||||
if (t == null)
|
||||
throw new NullPointerException("Choice is null!");
|
||||
|
||||
if (t instanceof ASN1Choice)
|
||||
throw new IllegalArgumentException(
|
||||
"No nested CHOICE types are allowed!");
|
||||
|
||||
t.setOptional(false);
|
||||
t.setExplicit(true);
|
||||
|
||||
choices_.add(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the choice with the given tag and tagclass if it exists,
|
||||
* otherwise <code>null</code> is returned. This method is called by the
|
||||
* decoder in order to determine the appropriate type to decode. The
|
||||
* returned type is set up as the inner type by the decoder.
|
||||
*
|
||||
* @param tag
|
||||
* The tag of the type encountered in the encoded stream. The
|
||||
* tags of the various primitive ASN.1 types are defined in
|
||||
* class {@link ASN1 ASN1}.
|
||||
* @param tagclass
|
||||
* The tag class of the type encountered in the encoded
|
||||
* stream. The tag class identifiers are defined in class
|
||||
* {@link ASN1 ASN1}. See for instance
|
||||
* {@link ASN1#CLASS_UNIVERSAL CLASS_UNIVERSAL}.
|
||||
* @return The choice with matching tag and tag class or <code>null</code>
|
||||
* if no matching choice is found.
|
||||
*/
|
||||
public ASN1Type getType(int tag, int tagclass) {
|
||||
Iterator i;
|
||||
ASN1Type t;
|
||||
|
||||
for (i = choices_.iterator(); i.hasNext();) {
|
||||
t = (ASN1Type) i.next();
|
||||
if (t.getTag() != tag)
|
||||
continue;
|
||||
if (t.getTagClass() == tagclass)
|
||||
return t;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isType(int tag, int tagclass) {
|
||||
if (getType(tag, tagclass) != null)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims the internal list of choices to the actual number of choices stored
|
||||
* in it.
|
||||
*/
|
||||
public void trimToSize() {
|
||||
choices_.trimToSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the internal list of choices. The inner type remains unaffected if
|
||||
* it is already set.
|
||||
*
|
||||
* number of choices stored in it.
|
||||
*/
|
||||
public void clear() {
|
||||
choices_.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the inner ASN.1 type.
|
||||
*
|
||||
* @return The inner ASN.1 type.
|
||||
*/
|
||||
public ASN1Type getInnerType() {
|
||||
return inner_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the inner type.
|
||||
*
|
||||
* @param t
|
||||
* The type to set as the inner type.
|
||||
* @throws NullPointerException
|
||||
* if the given type is <code>null</code>.
|
||||
*/
|
||||
public void setInnerType(ASN1Type t) {
|
||||
if (t == null)
|
||||
throw new NullPointerException("No type given!");
|
||||
|
||||
inner_ = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tag of the inner type.
|
||||
*
|
||||
* @return The tag of the inner type.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not set.
|
||||
*/
|
||||
public int getTag() {
|
||||
if (inner_ == null)
|
||||
throw new IllegalStateException(NO_INNER);
|
||||
|
||||
return inner_.getTag();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tag class of the inner type.
|
||||
*
|
||||
* @return The tag class of the inner type.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not set.
|
||||
*/
|
||||
public int getTagClass() {
|
||||
if (inner_ == null)
|
||||
throw new IllegalStateException(NO_INNER);
|
||||
|
||||
return inner_.getTagClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the inner type. The default inner type is
|
||||
* {@link ASN1Null ASN1Null}. This method calls
|
||||
* {@link ASN1Type#getValue getValue} on the inner type and returns the
|
||||
* result.
|
||||
*
|
||||
* @return The value of the inner type.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not set.
|
||||
*/
|
||||
public Object getValue() {
|
||||
if (inner_ == null)
|
||||
throw new IllegalStateException(NO_INNER);
|
||||
|
||||
return inner_.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tagging of the inner type as either EXPLICIT or IMPLICIT. The
|
||||
* default is EXPLICIT. Encoders skip the encoding of identifier octets for
|
||||
* types that are declared as IMPLICIT.
|
||||
*
|
||||
* @param explicit
|
||||
* <code>true</code> if this type shall be tagged EXPLICIT
|
||||
* and <code>false</code> if it shall be encoded IMPLICIT.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not set.
|
||||
*/
|
||||
public void setExplicit(boolean explicit) {
|
||||
if (!explicit)
|
||||
throw new IllegalArgumentException(
|
||||
"CHOICE types must be tagged EXPLICIT!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tagging of the inner type.
|
||||
*
|
||||
* @return <code>true</code> if the inner type is tagged EXPLICIT and
|
||||
* <code>false</code> if it is tagged IMPLICIT.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not set.
|
||||
*/
|
||||
public boolean isExplicit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Constraint Constraint} of the inner type. For instance an
|
||||
* ASN.1 INTEGER might be constrained to a certain range such as INTEGER
|
||||
* (0..99). <code>null</code> can be passed as a constraint which disables
|
||||
* constraint checking.
|
||||
*
|
||||
* @param constraint
|
||||
* The {@link Constraint Constraint} of this type.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not set.
|
||||
*/
|
||||
public void setConstraint(Constraint constraint) {
|
||||
if (inner_ == null)
|
||||
throw new IllegalStateException(NO_INNER);
|
||||
|
||||
inner_.setConstraint(constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the constraint on the inner type if it is set. Otherwise this
|
||||
* method returns silently.
|
||||
*
|
||||
* @throws ConstraintException
|
||||
* if this type is not in the appropriate range of values.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not set.
|
||||
*/
|
||||
public void checkConstraints() throws ConstraintException {
|
||||
if (inner_ == null)
|
||||
throw new IllegalStateException(NO_INNER);
|
||||
|
||||
inner_.checkConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes this type to the given encoder. Before this method is called, the
|
||||
* inner type must be set. Otherwise an IllegalStateException is thrown.
|
||||
* <p>
|
||||
*
|
||||
* If this method is declared OPTIONAL then still an exception is thrown.
|
||||
* The OPTIONAL flag is checked only by {@link Encoder encoders} and
|
||||
* {@link Decoder decoders}. Transparent handling of CHOICE types can be
|
||||
* achieved by calling <code>{@link Encoder#writeType
|
||||
* writeType}(ASN1Choice choice)</code>
|
||||
* on the encoder. The encoder's method checks if its argument is OPTIONAL.
|
||||
*
|
||||
* @param enc
|
||||
* The {@link Encoder Encoder} to use for encoding.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not set.
|
||||
*/
|
||||
public void encode(Encoder enc) throws ASN1Exception, IOException {
|
||||
if (inner_ == null)
|
||||
throw new IllegalStateException(NO_INNER);
|
||||
|
||||
enc.writeType(inner_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the inner type to the given {@link Decoder decoder}.
|
||||
*
|
||||
* @param dec
|
||||
* The decoder to decode to.
|
||||
* @throws IllegalStateException
|
||||
* if the open type cannot be resolved on runtime.
|
||||
*/
|
||||
public void decode(Decoder dec) throws ASN1Exception, IOException {
|
||||
dec.readChoice(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this type.
|
||||
*
|
||||
* @return The string representation.
|
||||
*/
|
||||
public String toString() {
|
||||
if (inner_ == null)
|
||||
return "CHOICE <NOT InitializED>";
|
||||
|
||||
return "(CHOICE) " + inner_.toString();
|
||||
}
|
||||
}
|
||||
98
src/codec/asn1/ASN1Collection.java
Normal file
98
src/codec/asn1/ASN1Collection.java
Normal file
@@ -0,0 +1,98 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* The basic interface for Java objects representing a constructed ASN.1 type
|
||||
* such as a SEQUENCE or SET as specified in ITU-T Recommendation X.680.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1Collection.java,v 1.2 2000/12/06 17:47:23 vroth Exp $"
|
||||
*/
|
||||
public interface ASN1Collection extends ASN1Type, Collection {
|
||||
|
||||
/**
|
||||
* Returns the Java Collection that is used to maintain the embedded ASN.1
|
||||
* types.
|
||||
*
|
||||
* @return The collection used internally for storing the elements in this
|
||||
* constructed ASN.1 type.
|
||||
*/
|
||||
public Collection getCollection();
|
||||
}
|
||||
116
src/codec/asn1/ASN1CollectionOf.java
Normal file
116
src/codec/asn1/ASN1CollectionOf.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* The basic interface for Java objects representing a constructed ASN.1 type
|
||||
* such as a SEQUENCE or SET as specified in ITU-T Recommendation X.680.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1CollectionOf.java,v 1.2 2000/12/06 17:47:24 vroth Exp $"
|
||||
*/
|
||||
public interface ASN1CollectionOf extends ASN1Collection {
|
||||
|
||||
/**
|
||||
* Returns the Java class representing the ASN.1 type of the elements in
|
||||
* this collection.
|
||||
*
|
||||
* @return The ASN.1 type of the elements in this collection.
|
||||
*/
|
||||
public Class getElementType();
|
||||
|
||||
/**
|
||||
* Creates and returns a new instance of the class passed to the constructor
|
||||
* of this instance. The freshly created instance is added to this instance
|
||||
* automatically.
|
||||
* <p>
|
||||
*
|
||||
* If no new instance can be created then an IllegalStateException is
|
||||
* thrown.
|
||||
* <p>
|
||||
*
|
||||
* <b>{@link Decoder Decoders} should call this method in order to create
|
||||
* additional elements on decoding.</b> Subclasses may use this method to
|
||||
* keep track on elements added to them.
|
||||
*
|
||||
* @return A new instance of the element type of this sequence.
|
||||
* @throws IllegalStateException
|
||||
* if no new instance could be created.
|
||||
*/
|
||||
public ASN1Type newElement();
|
||||
|
||||
}
|
||||
93
src/codec/asn1/ASN1Exception.java
Normal file
93
src/codec/asn1/ASN1Exception.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1Exception.java,v 1.2 2000/12/06 17:47:24 vroth Exp $"
|
||||
*/
|
||||
public class ASN1Exception extends Exception {
|
||||
public ASN1Exception() {
|
||||
}
|
||||
|
||||
public ASN1Exception(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
120
src/codec/asn1/ASN1IA5String.java
Normal file
120
src/codec/asn1/ASN1IA5String.java
Normal file
@@ -0,0 +1,120 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* This class represents an ASN.1 IA5String as described in ITU-T Recommendation
|
||||
* X.680.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1IA5String.java,v 1.3 2004/08/06 15:04:44 flautens Exp $"
|
||||
*/
|
||||
public class ASN1IA5String extends ASN1AbstractString {
|
||||
|
||||
/**
|
||||
* Constructor declaration.
|
||||
*
|
||||
*/
|
||||
public ASN1IA5String() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given string value. No constraints can be
|
||||
* set yet so none are checked.
|
||||
*
|
||||
* @param s
|
||||
* The string value.
|
||||
*/
|
||||
public ASN1IA5String(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method declaration.
|
||||
*
|
||||
*
|
||||
* @return The tag value
|
||||
*/
|
||||
public int getTag() {
|
||||
return ASN1.TAG_IA5STRING;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*--- formatting done in "SeMoA Java Convention" style on 05-17-2000 ---*/
|
||||
|
||||
248
src/codec/asn1/ASN1Integer.java
Normal file
248
src/codec/asn1/ASN1Integer.java
Normal file
@@ -0,0 +1,248 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Represents an ASN.1 INTEGER type. The corresponding Java type is
|
||||
* java.math.BigInteger.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1Integer.java,v 1.2 2000/12/06 17:47:24 vroth Exp $"
|
||||
*/
|
||||
public class ASN1Integer extends ASN1AbstractType {
|
||||
/**
|
||||
* Holds the octets per integer count. This value is computed by means of
|
||||
* static initializer code below.
|
||||
*/
|
||||
private static int opi_;
|
||||
|
||||
/**
|
||||
* The value of this ASN.1 INTEGER.
|
||||
*/
|
||||
private BigInteger value_;
|
||||
|
||||
/*
|
||||
* Initializes the opi_ field above.
|
||||
*/
|
||||
static {
|
||||
int n;
|
||||
int i;
|
||||
|
||||
for (n = 1, i = 0; n != 0; n = n << 8) {
|
||||
i++;
|
||||
}
|
||||
opi_ = i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance ready for parsing. The value of this instance is
|
||||
* set to 0.
|
||||
*/
|
||||
public ASN1Integer() {
|
||||
value_ = BigInteger.ZERO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance with the given BigInteger as its initial value.
|
||||
*
|
||||
* @param val
|
||||
* The value.
|
||||
*/
|
||||
public ASN1Integer(BigInteger val) {
|
||||
if (val == null)
|
||||
throw new NullPointerException("Need a number!");
|
||||
|
||||
value_ = val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ASN.1 INTEGER from the given string representation.
|
||||
*
|
||||
* This method calls the equivalent constructor of class
|
||||
* {@link java.math.BigInteger java.math.BigInteger}.
|
||||
*
|
||||
* @param val
|
||||
* The string representation of the multiple precision
|
||||
* integer.
|
||||
* @throws NumberFormatException
|
||||
* if the string could not be parsed successfully.
|
||||
*/
|
||||
public ASN1Integer(String val) throws NumberFormatException {
|
||||
value_ = new BigInteger(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance from the given byte array. The byte array contains
|
||||
* the two's-complement binary representation of a BigInteger. The input
|
||||
* array is assumed to be in <i>big endian</i> byte-order. The most
|
||||
* significant byte is in the zeroth element.
|
||||
*
|
||||
* This method calls the equivalent constructor of class
|
||||
* {@link java.math.BigInteger java.math.BigInteger}.
|
||||
*
|
||||
* @param val
|
||||
* The two's-complement input number in big endian
|
||||
* byte-order.
|
||||
* @throws NumberFormatException
|
||||
* if val is zero bytes long.
|
||||
*/
|
||||
public ASN1Integer(byte[] val) throws NumberFormatException {
|
||||
value_ = new BigInteger(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the sign-magnitude representation of a BigInteger into an
|
||||
* ASN.1 INTEGER. The sign is represented as an integer signum value: -1 for
|
||||
* negative, 0 for zero, or 1 for positive. The magnitude is a byte array in
|
||||
* big-endian byte-order: the most significant byte is in the zeroth
|
||||
* element. A zero-length magnitude array is permissible, and will result in
|
||||
* in a BigInteger value of 0, whether signum is -1, 0 or 1.
|
||||
* <p>
|
||||
*
|
||||
* This method calls the equivalent constructor of class
|
||||
* {@link java.math.BigInteger java.math.BigInteger}.
|
||||
*
|
||||
* @param signum
|
||||
* signum of the number (-1 for negative, 0 for zero, 1 for
|
||||
* positive).
|
||||
* @param magnitude
|
||||
* The big endian binary representation of the magnitude of
|
||||
* the number.
|
||||
* @throws NumberFormatException
|
||||
* signum is not one of the three legal values (-1, 0, and
|
||||
* 1), or signum is 0 and magnitude contains one or more
|
||||
* non-zero bytes.
|
||||
*/
|
||||
public ASN1Integer(int signum, byte[] magnitude)
|
||||
throws NumberFormatException {
|
||||
value_ = new BigInteger(signum, magnitude);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given int value.
|
||||
*
|
||||
* @param n
|
||||
* The integer to initialize with.
|
||||
*/
|
||||
public ASN1Integer(int n) {
|
||||
byte[] b;
|
||||
int i;
|
||||
int m;
|
||||
|
||||
b = new byte[opi_];
|
||||
m = n;
|
||||
|
||||
for (i = opi_ - 1; i >= 0; i--) {
|
||||
b[i] = (byte) (m & 0xff);
|
||||
m = m >>> 8;
|
||||
}
|
||||
value_ = new BigInteger(b);
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value_;
|
||||
}
|
||||
|
||||
public BigInteger getBigInteger() {
|
||||
return value_;
|
||||
}
|
||||
|
||||
public void setBigInteger(BigInteger n) throws ConstraintException {
|
||||
value_ = n;
|
||||
checkConstraints();
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return ASN1.TAG_INTEGER;
|
||||
}
|
||||
|
||||
public void encode(Encoder enc) throws ASN1Exception, IOException {
|
||||
enc.writeInteger(this);
|
||||
}
|
||||
|
||||
public void decode(Decoder dec) throws ASN1Exception, IOException {
|
||||
dec.readInteger(this);
|
||||
checkConstraints();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Integer " + value_.toString();
|
||||
}
|
||||
}
|
||||
108
src/codec/asn1/ASN1Null.java
Normal file
108
src/codec/asn1/ASN1Null.java
Normal file
@@ -0,0 +1,108 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents the ASN.1 NULL type.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1Null.java,v 1.2 2000/12/06 17:47:24 vroth Exp $"
|
||||
*/
|
||||
public class ASN1Null extends ASN1AbstractType implements Cloneable {
|
||||
|
||||
public Object getValue() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return ASN1.TAG_NULL;
|
||||
}
|
||||
|
||||
public void encode(Encoder enc) throws ASN1Exception, IOException {
|
||||
enc.writeNull(this);
|
||||
}
|
||||
|
||||
public void decode(Decoder dec) throws ASN1Exception, IOException {
|
||||
dec.readNull(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "NULL";
|
||||
}
|
||||
}
|
||||
436
src/codec/asn1/ASN1ObjectIdentifier.java
Normal file
436
src/codec/asn1/ASN1ObjectIdentifier.java
Normal file
@@ -0,0 +1,436 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* Represents an ASN.1 OBJECT IDENTIFIER type. The corresponding Java type is
|
||||
* <code>int[]</code>. Constraints are checked for this type only at the end
|
||||
* of method {@link #decode decode}.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1ObjectIdentifier.java,v 1.4 2005/03/22 14:57:58 flautens
|
||||
* Exp $"
|
||||
*/
|
||||
public class ASN1ObjectIdentifier extends ASN1AbstractType implements
|
||||
Cloneable, Comparable {
|
||||
/**
|
||||
* holds the int[] representation of the OID
|
||||
*/
|
||||
private int[] value_ = new int[2];
|
||||
|
||||
/**
|
||||
* Creates a new ASN1ObjectIdentifier object.
|
||||
*/
|
||||
public ASN1ObjectIdentifier() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given array of integers as elements. No
|
||||
* constraints are checked by this constructor.
|
||||
*
|
||||
* @param oid
|
||||
* The array of consecutive integers of the OID.
|
||||
* @throws NullPointerException
|
||||
* if the given <code>oid
|
||||
* </code> is <code>null</code>.
|
||||
* @throws IllegalArgumentException
|
||||
* if the given <code>
|
||||
* oid</code> is not well-formed. For
|
||||
* instance, a bad <code>oid</code> might have a value
|
||||
* greater than 2 as its first element.
|
||||
*/
|
||||
public ASN1ObjectIdentifier(int[] oid) {
|
||||
set0(oid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ASN.1 OBJECT IDENTIFIER instance initialized from the given
|
||||
* OID string representation. The format must be either OID.1.2.3.4,
|
||||
* oid.1.2.3.4, or 1.2.3.4 for the initiliser to work properly. Trailing
|
||||
* dots are ignored.
|
||||
*
|
||||
* @param s
|
||||
* string representation of oid
|
||||
* @throws NumberFormatException
|
||||
* if some element of the OID string is not an integer
|
||||
* number.
|
||||
* @throws IllegalArgumentException
|
||||
* if the string is not a well-formed OID.
|
||||
*/
|
||||
public ASN1ObjectIdentifier(String s) throws NumberFormatException {
|
||||
int n;
|
||||
int[] oid;
|
||||
String t;
|
||||
StringTokenizer tok;
|
||||
|
||||
oid = new int[16];
|
||||
|
||||
if (s.startsWith("OID.") || s.startsWith("oid.")) {
|
||||
s = s.substring(4);
|
||||
}
|
||||
|
||||
tok = new StringTokenizer(s, ".");
|
||||
|
||||
if (tok.countTokens() >= oid.length) {
|
||||
throw new IllegalArgumentException("OID has too many elements!");
|
||||
}
|
||||
|
||||
n = 0;
|
||||
|
||||
while (tok.hasMoreTokens()) {
|
||||
t = tok.nextToken();
|
||||
oid[n++] = Integer.parseInt(t);
|
||||
}
|
||||
|
||||
int[] buf = new int[n];
|
||||
System.arraycopy(oid, 0, buf, 0, n);
|
||||
set0(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @return DOCUMENT ME!
|
||||
*/
|
||||
public Object getValue() {
|
||||
return value_.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @return DOCUMENT ME!
|
||||
*/
|
||||
public int[] getOID() {
|
||||
return (int[]) value_.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @param oid
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @throws ConstraintException
|
||||
* DOCUMENT ME!
|
||||
*/
|
||||
public void setOID(int[] oid) throws ConstraintException {
|
||||
set0(oid);
|
||||
checkConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given oid is valid and stores the oid. If the oid is not
|
||||
* valid the method throws an IllegalArgumentException.
|
||||
*
|
||||
* @param oid
|
||||
* The oid to be checked
|
||||
*/
|
||||
private void set0(int[] oid) {
|
||||
int n;
|
||||
|
||||
if (oid == null) {
|
||||
throw new NullPointerException("Need an OID!");
|
||||
}
|
||||
|
||||
n = oid.length;
|
||||
|
||||
if (n < 2) {
|
||||
throw new IllegalArgumentException(
|
||||
"OID must have at least 2 elements!");
|
||||
}
|
||||
|
||||
if ((oid[0] < 0) || (oid[0] > 2)) {
|
||||
throw new IllegalArgumentException("OID[0] must be 0, 1, or 2!");
|
||||
}
|
||||
|
||||
if ((oid[1] < 0) || (oid[1] > 39)) {
|
||||
throw new IllegalArgumentException(
|
||||
"OID[1] must be in the range 0,..,39!");
|
||||
}
|
||||
|
||||
value_ = new int[n];
|
||||
System.arraycopy(oid, 0, value_, 0, n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements of the oid.
|
||||
*
|
||||
* @return the number of elements
|
||||
*/
|
||||
public int elementCount() {
|
||||
return value_.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @return DOCUMENT ME!
|
||||
*/
|
||||
public int getTag() {
|
||||
return ASN1.TAG_OID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes this ASN1ObjectIdentifier.
|
||||
*
|
||||
* @param enc
|
||||
* The encoder to encode to.
|
||||
*
|
||||
* @throws ASN1Exception
|
||||
* @throws IOException
|
||||
*/
|
||||
public void encode(Encoder enc) throws ASN1Exception, IOException {
|
||||
enc.writeObjectIdentifier(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes to this ASN1ObjectIdentifier.
|
||||
*
|
||||
* @param dec
|
||||
* DOCUMENT ME!
|
||||
*
|
||||
* @throws ASN1Exception
|
||||
* @throws IOException
|
||||
*/
|
||||
public void decode(Decoder dec) throws ASN1Exception, IOException {
|
||||
dec.readObjectIdentifier(this);
|
||||
checkConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string representation of this OID. The string consists of the
|
||||
* numerical elements of the OID separated by periods.
|
||||
*
|
||||
* @return The string representation of the OID.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer buf;
|
||||
int i;
|
||||
|
||||
buf = new StringBuffer();
|
||||
|
||||
for (i = 0; i < value_.length; i++) {
|
||||
buf.append(value_[i] + ".");
|
||||
}
|
||||
|
||||
if (value_.length > 0) {
|
||||
buf.setLength(buf.length() - 1);
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two OIDs for equality. Two OIDs are equal if the have the same
|
||||
* number of elements and all corresponding elements are equal.
|
||||
*
|
||||
* @param o
|
||||
* The object to compare to.
|
||||
* @return <code>true</code> iff the given object is an
|
||||
* ASN1ObjectIdentifier and iff it equals this one.
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
int i;
|
||||
ASN1ObjectIdentifier oid;
|
||||
|
||||
if (!(o instanceof ASN1ObjectIdentifier)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
oid = (ASN1ObjectIdentifier) o;
|
||||
if (oid.value_.length != value_.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < value_.length; i++) {
|
||||
if (value_[i] != oid.value_[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method computes the hash code of this instance. The hash code of
|
||||
* this instance is defined as a hash function of the underlying integer
|
||||
* array.
|
||||
*
|
||||
* @return the hash code of this instance.
|
||||
*/
|
||||
public int hashCode() {
|
||||
int i;
|
||||
int h;
|
||||
|
||||
h = 23;
|
||||
for (i = 0; i < value_.length; i++) {
|
||||
h = (h * 7) + value_[i];
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method compares two OID and returns -1, 0, 1 if this OID is less
|
||||
* than, equal or greater than the given one. OID are interpreted as strings
|
||||
* of numbers. An OID that is a prefix of another is always smaller than the
|
||||
* other.
|
||||
*
|
||||
* @param o
|
||||
* The OID to compare to.
|
||||
* @return -1, 0, 1 if this OID is smaller than, equal to, or greater than
|
||||
* the given OID.
|
||||
* @throws ClassCastException
|
||||
* iff <code>o</code> is not an ASN1ObjectIdentifier.
|
||||
*/
|
||||
public int compareTo(Object o) {
|
||||
int n;
|
||||
int i;
|
||||
int[] oid;
|
||||
|
||||
oid = ((ASN1ObjectIdentifier) o).value_;
|
||||
|
||||
n = Math.min(value_.length, oid.length);
|
||||
for (i = 0; i < n; i++) {
|
||||
if (value_[i] < oid[i]) {
|
||||
return -1;
|
||||
} else if (value_[i] > oid[i]) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (value_.length > n) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (oid.length > n) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method determines whether the given OID is part of the OID family
|
||||
* defined by this OID prefix. In other words, this method returns
|
||||
* <code>true</code> if this OID is a prefix of the given one.
|
||||
*
|
||||
* @param o
|
||||
* the oid to check
|
||||
* @return true if this OID is a prefix of the given one.
|
||||
*/
|
||||
public boolean isPrefixOf(ASN1ObjectIdentifier o) {
|
||||
int i;
|
||||
|
||||
i = value_.length;
|
||||
if (o.value_.length < i) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (i > 0) {
|
||||
i--;
|
||||
if (value_[i] != o.value_[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone of this instance. This method is not thread safe. The
|
||||
* constraints are copied by reference.
|
||||
*
|
||||
* @return The clone.
|
||||
*/
|
||||
public Object clone() {
|
||||
int[] m;
|
||||
ASN1ObjectIdentifier oid;
|
||||
|
||||
oid = new ASN1ObjectIdentifier();
|
||||
m = new int[value_.length];
|
||||
System.arraycopy(value_, 0, m, 0, m.length);
|
||||
oid.value_ = m;
|
||||
|
||||
oid.setConstraint(getConstraint());
|
||||
|
||||
return oid;
|
||||
}
|
||||
}
|
||||
211
src/codec/asn1/ASN1OctetString.java
Normal file
211
src/codec/asn1/ASN1OctetString.java
Normal file
@@ -0,0 +1,211 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents an ASN.1 OCTET STRING type. The corresponding Java type is
|
||||
* <code>byte[]</code>.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1OctetString.java,v 1.3 2001/01/21 13:46:55 vroth Exp $"
|
||||
*/
|
||||
public class ASN1OctetString extends ASN1AbstractType {
|
||||
private static final byte[] DEFAULT_VALUE = new byte[0];
|
||||
|
||||
private byte[] value_ = DEFAULT_VALUE;
|
||||
|
||||
public ASN1OctetString() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with side effects. The given array is copied by
|
||||
* reference.
|
||||
*
|
||||
* @param b
|
||||
* The byte array that is set as contents.
|
||||
*/
|
||||
public ASN1OctetString(byte[] b) {
|
||||
setByteArray0(b);
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents octets as a byte array. The returned byte array is
|
||||
* is the instance used internally. Do not modify it, otherwise side effects
|
||||
* occur.
|
||||
*
|
||||
* @return The contents octets as a byte array.
|
||||
*/
|
||||
public byte[] getByteArray() {
|
||||
return (byte[]) value_.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given bytes. The given byte array is copied by reference. Be
|
||||
* careful, side effects can occur if the array is modified subsequent to
|
||||
* calling this method. Constraints are checked after setting the bytes.
|
||||
*
|
||||
* @param b
|
||||
* The byte array that is set.
|
||||
* @throws ConstraintException
|
||||
* if the constraint is not met by the given byte array.
|
||||
*/
|
||||
public void setByteArray(byte[] b) throws ConstraintException {
|
||||
setByteArray0(b);
|
||||
checkConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given bytes. The given byte array is copied by reference. Be
|
||||
* careful, side effects can occur if the array is modified subsequent to
|
||||
* calling this method.
|
||||
*
|
||||
* @param b
|
||||
* The byte array that is set.
|
||||
*/
|
||||
private void setByteArray0(byte[] b) {
|
||||
if (b == null)
|
||||
value_ = DEFAULT_VALUE;
|
||||
else
|
||||
value_ = b;
|
||||
}
|
||||
|
||||
public int byteCount() {
|
||||
return value_.length;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return ASN1.TAG_OCTETSTRING;
|
||||
}
|
||||
|
||||
public void encode(Encoder enc) throws ASN1Exception, IOException {
|
||||
enc.writeOctetString(this);
|
||||
}
|
||||
|
||||
public void decode(Decoder dec) throws ASN1Exception, IOException {
|
||||
dec.readOctetString(this);
|
||||
checkConstraints();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buf;
|
||||
String octet;
|
||||
int i;
|
||||
|
||||
buf = new StringBuffer("Octet String");
|
||||
|
||||
for (i = 0; i < value_.length; i++) {
|
||||
octet = Integer.toHexString(value_[i] & 0xff);
|
||||
|
||||
buf.append(' ');
|
||||
|
||||
if (octet.length() == 1) {
|
||||
buf.append('0');
|
||||
}
|
||||
buf.append(octet);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone. The clone is a deep copy of this instance with the
|
||||
* exception of constraints. Constraints are copied by reference.
|
||||
*
|
||||
* @return The clone.
|
||||
*/
|
||||
public Object clone() {
|
||||
ASN1OctetString o;
|
||||
|
||||
try {
|
||||
o = (ASN1OctetString) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
/*
|
||||
* This cannot, cannot, cannot, CANNOT happen ! If it does, put back
|
||||
* the import statement for 'Cloneable' into ASN1AbstractType !
|
||||
*/
|
||||
throw new Error("Internal, clone support mismatch!");
|
||||
}
|
||||
o.value_ = (byte[]) value_.clone();
|
||||
|
||||
return o;
|
||||
}
|
||||
}
|
||||
266
src/codec/asn1/ASN1Opaque.java
Normal file
266
src/codec/asn1/ASN1Opaque.java
Normal file
@@ -0,0 +1,266 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents an opaque type. An opaque type merely decodes the tag and tag
|
||||
* class and stores the contents octets in an OCTET STRING. The opaque type is
|
||||
* represented in ASN.1 as <code><blockquote>
|
||||
* [UNIVERSAL x] IMPLICIT OCTET STRING
|
||||
* </blockquote></code>
|
||||
* where <code>x</code> is the tag.
|
||||
* <p>
|
||||
*
|
||||
* The opaque type is comparable to an {@link ASN1OpenType open type} in that it
|
||||
* matches any type (just like the deprecated ANY type) on decoding. The
|
||||
* encoding can be reconstructed easily. This type is used whenever decoding of
|
||||
* a structure should be deferred to a later point in time. For instance an
|
||||
* AlgorithmIdentifier implementation can use an opaque type in order to decode
|
||||
* algorithm parameters. The encoding of the algorithm parameters is then done
|
||||
* by JCA/JCE classes later on.
|
||||
* <p>
|
||||
*
|
||||
* One drawback of the opaque type is that special handling by the encoders and
|
||||
* decoders is rquired to make it work properly. The main problem is that the
|
||||
* opaque type does not store whether the underlying type is constructed or
|
||||
* primitive. This decision must be made by the encoder.
|
||||
* <p>
|
||||
*
|
||||
* Due to this limitation the opaque type can be used only for decoding types of
|
||||
* class UNIVERSAL.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1Opaque.java,v 1.2 2000/12/06 17:47:25 vroth Exp $"
|
||||
*/
|
||||
public class ASN1Opaque extends ASN1TaggedType {
|
||||
/**
|
||||
* Creates an instance. On decoding, opaque types pretend to be of a
|
||||
* particular type and read the actual type's encoding into an OCTET STRING
|
||||
* from which it can be retrieved later.
|
||||
*
|
||||
*/
|
||||
public ASN1Opaque() {
|
||||
super(-1, ASN1.CLASS_UNIVERSAL, new ASN1OctetString(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that stores the given encoding. The encoding must be
|
||||
* a valid DER encoding as specified in X.690. This constructor uses a
|
||||
* {@link DERDecoder DERDecoder} in order to decode the identifier octets in
|
||||
* the given encoding.
|
||||
* <p>
|
||||
*
|
||||
* <b>Note:</b> If the given encoding contains the concatenation of
|
||||
* multiple encodings then only the first one will be stored. All others
|
||||
* will be lost.
|
||||
*
|
||||
* @throws ASN1Exception
|
||||
* if the given code cannot be decoded.
|
||||
*/
|
||||
public ASN1Opaque(byte[] code) throws ASN1Exception {
|
||||
super(-1, ASN1.CLASS_UNIVERSAL, new ASN1OctetString(), false);
|
||||
|
||||
ByteArrayInputStream bis;
|
||||
DERDecoder dec;
|
||||
|
||||
try {
|
||||
bis = new ByteArrayInputStream(code);
|
||||
dec = new DERDecoder(bis);
|
||||
decode(dec);
|
||||
dec.close();
|
||||
} catch (IOException e) {
|
||||
throw new ASN1Exception("Internal, caught IOException!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given type, class, and inner type. <b>Be
|
||||
* careful</b>, the given octet string must contain the valid DER encoding
|
||||
* of the contents octets of a type that matches the tag and tag class.
|
||||
* Otherwise coding exceptions are most probably thrown subsequently.
|
||||
*
|
||||
* @param tag
|
||||
* The ASN.1 tag of the opaque type.
|
||||
* @param tagclass
|
||||
* The tag class of the opaque type.
|
||||
* @param b
|
||||
* The DER compliant encoding of the contents octets of the
|
||||
* opaque type.
|
||||
* @throws NullPointerException
|
||||
* if the given byte array is <code>null</code>.
|
||||
*/
|
||||
public ASN1Opaque(int tag, int tagclass, byte[] b) {
|
||||
super(tag, tagclass, new ASN1OctetString((byte[]) b.clone()), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adopts the given tag and tag class if this instance is not
|
||||
* yet initialized with a tag or tag class. In that case <code>true</code>
|
||||
* is returned.
|
||||
* <p>
|
||||
*
|
||||
* If a tag or tag class is already set then this method calls its super
|
||||
* method.
|
||||
*
|
||||
* @param tag
|
||||
* The tag to compare with.
|
||||
* @param tagclass
|
||||
* The tag class to compare with.
|
||||
*/
|
||||
public boolean isType(int tag, int tagclass) {
|
||||
if (tagclass != ASN1.CLASS_UNIVERSAL)
|
||||
return false;
|
||||
|
||||
if (getTag() == -1) {
|
||||
setTag(tag);
|
||||
return true;
|
||||
}
|
||||
return super.isType(tag, tagclass);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a convenience method in order to encode this type with
|
||||
* DER. It uses a {@link DEREncoder DEREncoder} in order to encode this type
|
||||
* to a byte array which is returned.
|
||||
* <p>
|
||||
*
|
||||
* @return The DER encoding of this type.
|
||||
*/
|
||||
public byte[] getEncoded() throws ASN1Exception {
|
||||
ByteArrayOutputStream bos;
|
||||
DEREncoder enc;
|
||||
byte[] code;
|
||||
|
||||
try {
|
||||
bos = new ByteArrayOutputStream();
|
||||
enc = new DEREncoder(bos);
|
||||
encode(enc);
|
||||
code = bos.toByteArray();
|
||||
enc.close();
|
||||
|
||||
return code;
|
||||
} catch (IOException e) {
|
||||
throw new ASN1Exception("Internal, caught IOException!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the inner type of this opaque type. The given type must be
|
||||
* {@link ASN1OctetString ASN1OctetString} or a ClassCastException is
|
||||
* thrown.
|
||||
*
|
||||
* @param t
|
||||
* The type to set as the inner type.
|
||||
* @throws NullPointerException
|
||||
* if the given type is <code>null</code>.
|
||||
* @throws ClassCastException
|
||||
* if the given type is not an ASN1OctetString.
|
||||
*/
|
||||
public void setInnerType(ASN1Type t) {
|
||||
super.setInnerType(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone. The clone is a deep copy of this instance except the
|
||||
* constraints. Constraints are copied by reference.
|
||||
*
|
||||
* @return The clone.
|
||||
*/
|
||||
public Object clone() {
|
||||
ASN1OctetString b;
|
||||
ASN1Opaque o;
|
||||
|
||||
try {
|
||||
o = (ASN1Opaque) super.clone();
|
||||
b = (ASN1OctetString) o.getInnerType();
|
||||
|
||||
o.setInnerType((ASN1OctetString) b.clone());
|
||||
} catch (CloneNotSupportedException e) {
|
||||
/*
|
||||
* This cannot, cannot, cannot, CANNOT happen ! If it does, put back
|
||||
* the import statement for 'Cloneable' into ASN1AbstractType !
|
||||
*/
|
||||
throw new Error("Internal, clone support mismatch!");
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
}
|
||||
385
src/codec/asn1/ASN1OpenType.java
Normal file
385
src/codec/asn1/ASN1OpenType.java
Normal file
@@ -0,0 +1,385 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This type represents what was formerly called the ASN.1 ANY type. The ANY and
|
||||
* ANY DEFINED BY types are superseded as of ITU-T Recommendation X.680 version
|
||||
* current December 1997 by the ability to define type classes. Modelling type
|
||||
* classes is beyond the scope of this ASN.1 package although the package can be
|
||||
* enhanced accordingly. ASN.1 type classes can contain components whose type is
|
||||
* unspecified. Such components are called "open types". This class
|
||||
* mimics an open type insofar as it decodes any type encountered in an encoded
|
||||
* stream of ASN.1 types. On encoding the proper type is encoded in place of the
|
||||
* open type. Decoding an open type that was not properly initialized either by
|
||||
* a call to a creator with an argument or by decoding it from a valid ASN.1
|
||||
* encoding results in an {@link ASN1Null ASN1Null} being decoded.
|
||||
* <p>
|
||||
*
|
||||
* This class enforces as an invariant that inner types have the same tagging as
|
||||
* the type itself. For instance: <blockquote>
|
||||
*
|
||||
* <pre>
|
||||
* ASN1OpenType ot;
|
||||
* ASN1Integer n;
|
||||
* n = new Integer("42");
|
||||
* n.setExplicit(true);
|
||||
* ot = new OpenType(new FooResolver());
|
||||
* ot.setExplicit(false);
|
||||
* ot.setInnerType(n);
|
||||
* </pre>
|
||||
*
|
||||
* </blockquote> will cause the tagging method of <code>n</code> to be changed
|
||||
* into EXPLICIT upon the call to <code>ot.setInnerType()</code>.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1OpenType.java,v 1.4 2004/08/06 15:13:01 flautens Exp $"
|
||||
*/
|
||||
public class ASN1OpenType extends ASN1AbstractType {
|
||||
private static final String NO_INNER = "No inner type defined!";
|
||||
|
||||
private ASN1Type inner_;
|
||||
|
||||
protected Resolver resolver_;
|
||||
|
||||
public ASN1OpenType() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that attempts to resolve the actual type on decoding
|
||||
* using the given {@link Resolver Resolver}.
|
||||
*
|
||||
* @param resolver
|
||||
* The instance that is asked to deliver the type to decode.
|
||||
*/
|
||||
public ASN1OpenType(Resolver resolver) {
|
||||
resolver_ = resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* This constructor corresponds to the superseded ANY DEFINED BY type. The
|
||||
* open type attempts to resolve the type to decode right before decoding by
|
||||
* a call to the given registry with the given OID as the argument. The
|
||||
* exact OID instance is used that is passed to this method as the argument.
|
||||
* If this instance is decoded before the open type is decoded (because the
|
||||
* OID is encountered earlier in a decoded stream) then the open type can
|
||||
* determine the exact type to decode by a call to the registry.
|
||||
*
|
||||
* @param oid
|
||||
* The OID that is passed to the given registry on resolving.
|
||||
*/
|
||||
public ASN1OpenType(OIDRegistry registry, ASN1ObjectIdentifier oid) {
|
||||
resolver_ = new DefinedByResolver(registry, oid);
|
||||
}
|
||||
|
||||
public ASN1OpenType(ASN1ObjectIdentifier oid) {
|
||||
resolver_ = new DefinedByResolver(oid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the inner ASN.1 type. If the inner type is not set and a
|
||||
* {@link Resolver Resolver} is set then the Resolver is asked to resolve
|
||||
* the inner type. The resulting type is then returned.
|
||||
* <p>
|
||||
*
|
||||
* This method may return <code>null</code> if the resolver cannot
|
||||
* determine the inner type of the open type. In particular, if the Resolver
|
||||
* is <code>null</code> and no inner type is already set then
|
||||
* <code>null</code> is returned.
|
||||
*
|
||||
* @return The inner ASN.1 type.
|
||||
*/
|
||||
public ASN1Type getInnerType() throws ResolverException {
|
||||
if (inner_ != null) {
|
||||
return inner_;
|
||||
}
|
||||
if (resolver_ == null) {
|
||||
return null;
|
||||
}
|
||||
inner_ = resolver_.resolve(this);
|
||||
|
||||
return inner_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the inner type. The inner type inherits the tagging of this type.
|
||||
*
|
||||
* @param t
|
||||
* The type to set as the inner type.
|
||||
* @throws NullPointerException
|
||||
* if the given type is <code>null</code>.
|
||||
*/
|
||||
protected void setInnerType(ASN1Type t) {
|
||||
inner_ = t;
|
||||
inner_.setExplicit(isExplicit());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tag of the inner type.
|
||||
*
|
||||
* @return The tag of the inner type.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not yet initialized.
|
||||
*/
|
||||
public int getTag() {
|
||||
if (inner_ == null) {
|
||||
throw new IllegalStateException(NO_INNER);
|
||||
}
|
||||
return inner_.getTag();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tag class of the inner type.
|
||||
*
|
||||
* @return The tag class of the inner type.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not yet initialized.
|
||||
*/
|
||||
public int getTagClass() {
|
||||
if (inner_ == null) {
|
||||
throw new IllegalStateException(NO_INNER);
|
||||
}
|
||||
return inner_.getTagClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the inner type. The default inner type is
|
||||
* {@link ASN1Null ASN1Null}. This method calls
|
||||
* {@link ASN1Type#getValue getValue} on the inner type and returns the
|
||||
* result.
|
||||
*
|
||||
* @return The value of the inner type.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not yet initialized.
|
||||
*/
|
||||
public Object getValue() {
|
||||
if (inner_ == null) {
|
||||
throw new IllegalStateException(NO_INNER);
|
||||
}
|
||||
return inner_.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tagging to either EXPLICIT or IMPLICIT. If this type already has
|
||||
* an inner type set then the tagging of the inner type is set to the same
|
||||
* tagging.
|
||||
*
|
||||
* @param explicit
|
||||
* <code>true</code> if this type shall be tagged EXPLICIT
|
||||
* and <code>false</code> if it shall be encoded IMPLICIT.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not yet initialized.
|
||||
*/
|
||||
public void setExplicit(boolean explicit) {
|
||||
super.setExplicit(explicit);
|
||||
|
||||
if (inner_ != null) {
|
||||
inner_.setExplicit(explicit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Constraint Constraint} of the inner type. For instance an
|
||||
* ASN.1 INTEGER might be constrained to a certain range such as INTEGER
|
||||
* (0..99). <code>null</code> can be passed as a constraint which disables
|
||||
* constraint checking.
|
||||
*
|
||||
* @param constraint
|
||||
* The {@link Constraint Constraint} of this type.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not yet initialized.
|
||||
*/
|
||||
public void setConstraint(Constraint constraint) {
|
||||
if (inner_ == null) {
|
||||
throw new IllegalStateException(NO_INNER);
|
||||
}
|
||||
inner_.setConstraint(constraint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the constraint on the inner type if it is set. Otherwise this
|
||||
* method returns silently.
|
||||
*
|
||||
* @throws ConstraintException
|
||||
* if this type is not in the appropriate range of values.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not yet initialized.
|
||||
*/
|
||||
public void checkConstraints() throws ConstraintException {
|
||||
if (inner_ == null) {
|
||||
throw new IllegalStateException(NO_INNER);
|
||||
}
|
||||
inner_.checkConstraints();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method compares the given tag and tag class with the tag and tag
|
||||
* class of the resolved type.
|
||||
* <p>
|
||||
* If an exception is thrown by the {@link Resolver Resolver} upon resolving
|
||||
* the inner type of this type then <code>false</code> is returned in
|
||||
* order to provoke a decoding error.
|
||||
* <p>
|
||||
*
|
||||
* If no inner type can be resolved then <code>true
|
||||
* </code> is returned. In
|
||||
* that case this type behaves like the ANY type known from previous ASN.1
|
||||
* versions.
|
||||
*
|
||||
* @param tag
|
||||
* The tag to match.
|
||||
* @param tagclass
|
||||
* The tag class to match.
|
||||
* @return <code>true</code> iff the given tag and tag class match one of
|
||||
* the alternative types represented by this variable type.
|
||||
*/
|
||||
public boolean isType(int tag, int tagclass) {
|
||||
if (inner_ != null) {
|
||||
return inner_.isType(tag, tagclass);
|
||||
}
|
||||
try {
|
||||
if (resolver_ != null) {
|
||||
inner_ = resolver_.resolve(this);
|
||||
}
|
||||
} catch (ResolverException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* If no inner type could be resolved then we behave like the ANY type.
|
||||
*/
|
||||
if (inner_ == null) {
|
||||
return true;
|
||||
}
|
||||
return inner_.isType(tag, tagclass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the inner typeof this open type using the given
|
||||
* {@link Encoder Encoder}. If the inner type is not yet initialized then
|
||||
* an exception is thrown.
|
||||
*
|
||||
* @param enc
|
||||
* The {@link Encoder Encoder} to use for encoding the inner
|
||||
* type.
|
||||
* @throws IllegalStateException
|
||||
* if the inner type is not yet initialized.
|
||||
*/
|
||||
public void encode(Encoder enc) throws ASN1Exception, IOException {
|
||||
if (inner_ == null) {
|
||||
throw new IllegalStateException(NO_INNER);
|
||||
}
|
||||
enc.writeType(inner_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the inner type to the given {@link Decoder decoder}. If a
|
||||
* {@link Resolver resolver} was specified then it is asked to provide an
|
||||
* ASN.1 type to decode.
|
||||
*
|
||||
* @param dec
|
||||
* The decoder to decode to.
|
||||
* @throws IllegalStateException
|
||||
* if the open type cannot be resolved on runtime.
|
||||
*/
|
||||
public void decode(Decoder dec) throws ASN1Exception, IOException {
|
||||
if (resolver_ != null && inner_ == null) {
|
||||
inner_ = resolver_.resolve(this);
|
||||
}
|
||||
if (inner_ == null) {
|
||||
inner_ = dec.readType();
|
||||
} else {
|
||||
inner_.decode(dec);
|
||||
}
|
||||
inner_.setExplicit(isExplicit());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string representation of this instance.
|
||||
*
|
||||
* @return The string representation of this instance.
|
||||
*/
|
||||
public String toString() {
|
||||
if (inner_ == null) {
|
||||
return "Open Type <NOT InitializED>";
|
||||
}
|
||||
return "(Open Type) " + inner_.toString();
|
||||
}
|
||||
}
|
||||
122
src/codec/asn1/ASN1Permission.java
Normal file
122
src/codec/asn1/ASN1Permission.java
Normal file
@@ -0,0 +1,122 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.security.BasicPermission;
|
||||
|
||||
/**
|
||||
* This permission is for controlling access to functionality of the ASN.1
|
||||
* package. In particular, registering and unregistering {@link OIDRegistry
|
||||
* ASN.1 Object Identifier Registries} is protected using this permission.
|
||||
* Malicious code may not access the global OIDRegistries, nor register new ones
|
||||
* or remove registered ones.
|
||||
* <p>
|
||||
*
|
||||
* This permission is a simple named permission. The names distinguished are:
|
||||
* <ul>
|
||||
* <li> <code>OIDRegistry.add</code>
|
||||
* <li> <code>OIDRegistry.remove</code>
|
||||
* </ul>
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1Permission.java,v 1.2 2000/12/06 17:47:25 vroth Exp $"
|
||||
*/
|
||||
public class ASN1Permission extends BasicPermission {
|
||||
|
||||
/**
|
||||
* Creates an instance with the given name and actions list.
|
||||
*
|
||||
* @param name
|
||||
* The name of the permission.
|
||||
* @param actions
|
||||
* The actions (not used).
|
||||
*/
|
||||
public ASN1Permission(String name, String actions) {
|
||||
super(name, actions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given name and actions list.
|
||||
*
|
||||
* @param name
|
||||
* The name of the permission.
|
||||
*/
|
||||
public ASN1Permission(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
}
|
||||
94
src/codec/asn1/ASN1RegisteredType.java
Normal file
94
src/codec/asn1/ASN1RegisteredType.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* This class represents an ASN.1 type that is officially registered. In other
|
||||
* words, this type is associated with a unique OID.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1RegisteredType.java,v 1.3 2004/08/06 15:14:52 flautens Exp $"
|
||||
*/
|
||||
public interface ASN1RegisteredType extends ASN1Type {
|
||||
/**
|
||||
* This method returns the official OID that identifies this ASN.1 type.
|
||||
*
|
||||
* @return The official ASN.1 OID of this type.
|
||||
*/
|
||||
public ASN1ObjectIdentifier getOID();
|
||||
|
||||
}
|
||||
110
src/codec/asn1/ASN1Sequence.java
Normal file
110
src/codec/asn1/ASN1Sequence.java
Normal file
@@ -0,0 +1,110 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* Represents an ASN.1 SEQUENCE type as specified in ITU-T Recommendation X.680.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1Sequence.java,v 1.2 2000/12/06 17:47:25 vroth Exp $"
|
||||
*/
|
||||
public class ASN1Sequence extends ASN1AbstractCollection {
|
||||
|
||||
public ASN1Sequence() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given capacity.
|
||||
*
|
||||
* @param capacity
|
||||
* The capacity.
|
||||
*/
|
||||
public ASN1Sequence(int capacity) {
|
||||
super(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ASN1#TAG_SEQUENCE SEQUENCE} tag.
|
||||
*
|
||||
* @return The {@link ASN1#TAG_SEQUENCE SEQUENCE} tag.
|
||||
*/
|
||||
public int getTag() {
|
||||
return ASN1.TAG_SEQUENCE;
|
||||
}
|
||||
|
||||
}
|
||||
227
src/codec/asn1/ASN1SequenceOf.java
Normal file
227
src/codec/asn1/ASN1SequenceOf.java
Normal file
@@ -0,0 +1,227 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents an ASN.1 SEQUENCE OF type as specified in ITU-T Recommendation
|
||||
* X.680. The SequenceOf and SetOf types do not have default constructors in
|
||||
* contrast to all the other ASN1Types. The reason is that these types are never
|
||||
* created directly on decoding ASN.1 structures. The decoding process always
|
||||
* decodes Sequence and Set types because creating the appropriate SequenceOf or
|
||||
* SetOf type requires explicit knowledge of the syntactic structure definition.
|
||||
* On the other hand, if an explicit structure is given for decoding then the
|
||||
* SequenceOf and SetOf types are decoded properly (because they do not have to
|
||||
* be created and hence the decoder need not know the component type).
|
||||
* <p>
|
||||
*
|
||||
* Constraints are checked only after decoding by a call to method
|
||||
* {@link #decode decode}.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1SequenceOf.java,v 1.3 2004/08/06 15:16:08 flautens Exp $"
|
||||
*/
|
||||
public class ASN1SequenceOf extends ASN1Sequence implements ASN1CollectionOf {
|
||||
/**
|
||||
* The {@link ASN1Type ASN1Type} from which the component types of this
|
||||
* collection are created.
|
||||
*/
|
||||
private Resolver resolver_;
|
||||
|
||||
/**
|
||||
* Creates an instance with the given capacity. This constructor is provided
|
||||
* for subclasses that wish to handle creation of new elements themselves
|
||||
* and do not rely on an application-provided element type.
|
||||
*
|
||||
* @param capacity
|
||||
* The initial capacity of the set.
|
||||
*/
|
||||
protected ASN1SequenceOf(int capacity) {
|
||||
super(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that keeps elements of the given type. The type must
|
||||
* be a valid {@link ASN1Type ASN1Type}. The given class must be public and
|
||||
* it must have a public default constructor.
|
||||
*
|
||||
* @param type
|
||||
* The class that represents the component type of this SET
|
||||
* OF.
|
||||
* @throws IllegalArgumentException
|
||||
* if the given class does not implement ASN1Type.
|
||||
* @throws NullPointerException
|
||||
* if <code>type</code> is <code>null</code>.
|
||||
*/
|
||||
public ASN1SequenceOf(Class type) {
|
||||
if (type == null)
|
||||
throw new NullPointerException("Need a class!");
|
||||
|
||||
resolver_ = new ClassInstanceResolver(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given capacity.
|
||||
*
|
||||
* @param capacity
|
||||
* The capacity.
|
||||
*/
|
||||
public ASN1SequenceOf(Class type, int capacity) {
|
||||
super(capacity);
|
||||
|
||||
if (type == null)
|
||||
throw new NullPointerException("Need a class!");
|
||||
|
||||
resolver_ = new ClassInstanceResolver(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that uses the given {@link Resolver Resolver} to
|
||||
* create new elements.
|
||||
*
|
||||
* @param resolver
|
||||
* The resolver to use for generating elements.
|
||||
*/
|
||||
public ASN1SequenceOf(Resolver resolver) {
|
||||
if (resolver == null) {
|
||||
throw new NullPointerException("Need a resolver!");
|
||||
}
|
||||
resolver_ = resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java class representing the ASN.1 type of the elements in
|
||||
* this collection or <code>ASN1Type.class
|
||||
* </code> if the type cannot be
|
||||
* determined.
|
||||
*
|
||||
* @return The ASN.1 type of the elements in this collection.
|
||||
*/
|
||||
public Class getElementType() {
|
||||
if (resolver_ instanceof ClassInstanceResolver) {
|
||||
return ((ClassInstanceResolver) resolver_).getFactoryClass();
|
||||
}
|
||||
return ASN1Type.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a new instance of the element type of this instance.
|
||||
* The freshly created instance is added to this instance automatically.
|
||||
* <p>
|
||||
*
|
||||
* New instances are created by invoking the <code>Resolver</code>
|
||||
* instance set in this instance.
|
||||
* <p>
|
||||
*
|
||||
* If no new instance can be created then an IllegalStateException is
|
||||
* thrown.
|
||||
* <p>
|
||||
*
|
||||
* <b>{@link Decoder Decoders} should call this method in order to create
|
||||
* additional elements on decoding.</b> Subclasses may use this method to
|
||||
* keep track on elements added to them.
|
||||
*
|
||||
* @return A new instance of the element type of this set.
|
||||
* @throws IllegalStateException
|
||||
* if no new instance could be created.
|
||||
*/
|
||||
public ASN1Type newElement() {
|
||||
try {
|
||||
ASN1Type o;
|
||||
|
||||
o = resolver_.resolve(this);
|
||||
add(o);
|
||||
|
||||
return o;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Caught " + e.getClass().getName()
|
||||
+ "(\"" + e.getMessage() + "\")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads this collection from the given {@link Decoder Decoder}.
|
||||
*
|
||||
* @param dec
|
||||
* The decoder to read from.
|
||||
*/
|
||||
public void decode(Decoder dec) throws ASN1Exception, IOException {
|
||||
dec.readCollectionOf(this);
|
||||
checkConstraints();
|
||||
}
|
||||
}
|
||||
115
src/codec/asn1/ASN1Set.java
Normal file
115
src/codec/asn1/ASN1Set.java
Normal file
@@ -0,0 +1,115 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* Represents an ASN.1 SET type as specified in ITU-T Recommendation X.680.
|
||||
* <p>
|
||||
*
|
||||
* This implementation does not sort the elements according to their encodings
|
||||
* as required (in principle) by the standard. Upon decoding, all decoded
|
||||
* elements are kept in the order they appeared in the encoded stream.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1Set.java,v 1.2 2000/12/06 17:47:26 vroth Exp $"
|
||||
*/
|
||||
public class ASN1Set extends ASN1AbstractCollection {
|
||||
|
||||
public ASN1Set() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given capacity.
|
||||
*
|
||||
* @param capacity
|
||||
* The capacity.
|
||||
*/
|
||||
public ASN1Set(int capacity) {
|
||||
super(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ASN1#TAG_SET SET} tag.
|
||||
*
|
||||
* @return The {@link ASN1#TAG_SET SET} tag.
|
||||
*/
|
||||
public int getTag() {
|
||||
return ASN1.TAG_SET;
|
||||
}
|
||||
|
||||
}
|
||||
253
src/codec/asn1/ASN1SetOf.java
Normal file
253
src/codec/asn1/ASN1SetOf.java
Normal file
@@ -0,0 +1,253 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents an ASN.1 SEQUENCE OF type as specified in ITU-T Recommendation
|
||||
* X.680. The SequenceOf and SetOf types do not have default constructors in
|
||||
* contrast to all the other ASN1Types. The reason is that these types are never
|
||||
* created directly on decoding ASN.1 structures. The decoding process always
|
||||
* decodes Sequence and Set types because creating the appropriate SequenceOf or
|
||||
* SetOf type requires explicit knowledge of the syntactic structure definition.
|
||||
* On the other hand, if an explicit structure is given for decoding then the
|
||||
* SequenceOf and SetOf types are decoded properly (because they do not have to
|
||||
* be created and hence the decoder need not know the component type).
|
||||
* <p>
|
||||
*
|
||||
* This implementation does not sort the elements according to their encodings
|
||||
* as required (in principle) by the standard. Upon decoding, all decoded
|
||||
* elements are kept in the order they appeared in the encoded stream.
|
||||
* <p>
|
||||
*
|
||||
* Constraints are checked after decoding instances of this type.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1SetOf.java,v 1.3 2004/08/09 06:59:23 flautens Exp $"
|
||||
*/
|
||||
public class ASN1SetOf extends ASN1Set implements ASN1CollectionOf {
|
||||
/**
|
||||
* The {@link ASN1Type ASN1Type} from which the component types of this
|
||||
* collection are created.
|
||||
*/
|
||||
private Resolver resolver_;
|
||||
|
||||
/**
|
||||
* Creates an instance with the given capacity. This constructor is provided
|
||||
* for subclasses that wish to handle creation of new elements themselves
|
||||
* and do not rely on an application-provided element type.
|
||||
*
|
||||
* @param capacity
|
||||
* The initial capacity of the set.
|
||||
*/
|
||||
protected ASN1SetOf(int capacity) {
|
||||
super(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that keeps elements of the given type. The type must
|
||||
* be a valid {@link ASN1Type ASN1Type}. The given class must be public and
|
||||
* it must have a public default constructor.
|
||||
*
|
||||
* @param type
|
||||
* The class that represents the component type of this SET
|
||||
* OF.
|
||||
* @throws IllegalArgumentException
|
||||
* if the given class does not implement ASN1Type.
|
||||
* @throws NullPointerException
|
||||
* if <code>type</code> is <code>null</code>.
|
||||
*/
|
||||
public ASN1SetOf(Class type) {
|
||||
if (type == null)
|
||||
throw new NullPointerException("Need a class!");
|
||||
|
||||
resolver_ = new ClassInstanceResolver(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given capacity.
|
||||
*
|
||||
* @param capacity
|
||||
* The capacity.
|
||||
*/
|
||||
public ASN1SetOf(Class type, int capacity) {
|
||||
super(capacity);
|
||||
|
||||
if (type == null)
|
||||
throw new NullPointerException("Need a class!");
|
||||
|
||||
resolver_ = new ClassInstanceResolver(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that uses the given {@link Resolver Resolver} to
|
||||
* create new elements.
|
||||
*
|
||||
* @param resolver
|
||||
* The resolver to use for generating elements.
|
||||
*/
|
||||
public ASN1SetOf(Resolver resolver) {
|
||||
if (resolver == null) {
|
||||
throw new NullPointerException("Need a resolver!");
|
||||
}
|
||||
resolver_ = resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that uses the given {@link Resolver Resolver} to
|
||||
* create new elements.
|
||||
*
|
||||
* @param resolver
|
||||
* The resolver to use for generating elements.
|
||||
* @param capacity
|
||||
* The capacity.
|
||||
*/
|
||||
public ASN1SetOf(Resolver resolver, int capacity) {
|
||||
/*
|
||||
* This method is used by the updated codec.x501.Name class. I inserted
|
||||
* this method. --volker roth
|
||||
*/
|
||||
super(capacity);
|
||||
|
||||
if (resolver == null) {
|
||||
throw new NullPointerException("Need a resolver!");
|
||||
}
|
||||
resolver_ = resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Java class representing the ASN.1 type of the elements in
|
||||
* this collection or <code>ASN1Type.class
|
||||
* </code> if the type cannot be
|
||||
* determined.
|
||||
*
|
||||
* @return The ASN.1 type of the elements in this collection.
|
||||
*/
|
||||
public Class getElementType() {
|
||||
if (resolver_ instanceof ClassInstanceResolver) {
|
||||
return ((ClassInstanceResolver) resolver_).getFactoryClass();
|
||||
}
|
||||
return ASN1Type.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a new instance of the element type of this instance.
|
||||
* The freshly created instance is added to this instance automatically.
|
||||
* <p>
|
||||
*
|
||||
* New instances are created by invoking the <code>Resolver</code>
|
||||
* instance set in this instance.
|
||||
* <p>
|
||||
*
|
||||
* If no new instance can be created then an IllegalStateException is
|
||||
* thrown.
|
||||
* <p>
|
||||
*
|
||||
* <b>{@link Decoder Decoders} should call this method in order to create
|
||||
* additional elements on decoding.</b> Subclasses may use this method to
|
||||
* keep track on elements added to them.
|
||||
*
|
||||
* @return A new instance of the element type of this set.
|
||||
* @throws IllegalStateException
|
||||
* if no new instance could be created.
|
||||
*/
|
||||
public ASN1Type newElement() {
|
||||
try {
|
||||
ASN1Type o;
|
||||
|
||||
o = resolver_.resolve(this);
|
||||
add(o);
|
||||
|
||||
return o;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Caught " + e.getClass().getName()
|
||||
+ "(\"" + e.getMessage() + "\")");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads this collection from the given {@link Decoder Decoder}.
|
||||
*
|
||||
* @param dec
|
||||
* The decoder to read from.
|
||||
*/
|
||||
public void decode(Decoder dec) throws ASN1Exception, IOException {
|
||||
dec.readCollectionOf(this);
|
||||
checkConstraints();
|
||||
}
|
||||
}
|
||||
143
src/codec/asn1/ASN1String.java
Normal file
143
src/codec/asn1/ASN1String.java
Normal file
@@ -0,0 +1,143 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* The common interface of all ASN.1 string types. This interface specifies
|
||||
* setter and getter methods for string values and methods for string to octet
|
||||
* and octet to string conversion. See {@link ASN1AbstractString
|
||||
* ASN1AbstractString} for details on strings.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1String.java,v 1.2 2000/12/06 17:47:26 vroth Exp $"
|
||||
* @see ASN1AbstractString
|
||||
*/
|
||||
public interface ASN1String extends ASN1Type {
|
||||
/**
|
||||
* Returns the represented string value.
|
||||
*
|
||||
* @return The string value of this type.
|
||||
*/
|
||||
public String getString();
|
||||
|
||||
/**
|
||||
* Sets the string value.
|
||||
*
|
||||
* @param s
|
||||
* The string value.
|
||||
*/
|
||||
public void setString(String s) throws ConstraintException;
|
||||
|
||||
/**
|
||||
* Converts the given byte array to a string.
|
||||
*
|
||||
* @param b
|
||||
* The byte array to convert.
|
||||
*/
|
||||
public String convert(byte[] b) throws ASN1Exception;
|
||||
|
||||
/**
|
||||
* Converts the given string to a byte array.
|
||||
*
|
||||
* @param s
|
||||
* The string to convert.
|
||||
*/
|
||||
public byte[] convert(String s) throws ASN1Exception;
|
||||
|
||||
/**
|
||||
* Returns the number of octets required to encode the given string
|
||||
* according to the basic encoding scheme of this type. For restricted
|
||||
* string types this likely equals the number of characters in the string
|
||||
* unless special characters or escape sequences are allowed. For
|
||||
* {@link ASN1BMPString BMPStrings} this is twice the number of characters
|
||||
* and for {@link ASN1UniversalString UniversalStrings} it is four times the
|
||||
* number of characters in the string.
|
||||
* <p>
|
||||
*
|
||||
* The number returned must equal the number returned by the method call
|
||||
* {@link #convert(java.lang.String) convert(s)}. This method is required
|
||||
* for DER encoding of string types in order to determine the number of
|
||||
* octets required for encoding the given string. For BER encoding this
|
||||
* method is not and the encoding of the string may be broken up into
|
||||
* consecutive OCTET STRINGS.
|
||||
*
|
||||
* @param s
|
||||
* The string whose encoding length is determined.
|
||||
*/
|
||||
public int convertedLength(String s) throws ASN1Exception;
|
||||
|
||||
}
|
||||
110
src/codec/asn1/ASN1TagComparator.java
Normal file
110
src/codec/asn1/ASN1TagComparator.java
Normal file
@@ -0,0 +1,110 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* ASN1 Comparator, used for Sorting an ASN1 Set. First TagClasses of the
|
||||
* ASN1Types are compared. If they are equal, the Tags of the ASN1Types are
|
||||
* compared. result is : 1, 0, -1 for a1 > a2, a1 = a2, a1 < a2
|
||||
*/
|
||||
|
||||
public class ASN1TagComparator implements Comparator {
|
||||
|
||||
public int compare(Object o1, Object o2) {
|
||||
|
||||
ASN1Type a1 = (ASN1Type) o1;
|
||||
ASN1Type a2 = (ASN1Type) o2;
|
||||
|
||||
if (a1.getTagClass() > a2.getTagClass())
|
||||
return 1;
|
||||
if (a1.getTagClass() == a2.getTagClass()) {
|
||||
if (a1.getTag() > a2.getTag()) {
|
||||
return 1;
|
||||
}
|
||||
if (a1.getTag() == a2.getTag()) {
|
||||
return 0;
|
||||
}
|
||||
// only this option, a1.Tag() < a2.Tag() left
|
||||
return -1;
|
||||
}
|
||||
// only this option, a1.TagClass() < a2.TagClass() left
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
328
src/codec/asn1/ASN1TaggedType.java
Normal file
328
src/codec/asn1/ASN1TaggedType.java
Normal file
@@ -0,0 +1,328 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Represents an ASN.1 tagged type. Tagged types are types that modify the tag
|
||||
* of an underlying type. The ASN.1 type classes
|
||||
* {@link ASN1#CLASS_CONTEXT CONTEXT}, {@link ASN1#CLASS_PRIVATE PRIVATE}, and
|
||||
* {@link ASN1#CLASS_APPLICATION APPLICATION} specify tagged types.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1TaggedType.java,v 1.4 2004/08/09 07:45:30 flautens Exp $"
|
||||
*/
|
||||
public class ASN1TaggedType extends ASN1AbstractType {
|
||||
private int tag_;
|
||||
private int cls_ = ASN1.CLASS_CONTEXT;
|
||||
|
||||
private ASN1Type inner_;
|
||||
|
||||
/**
|
||||
* Creates an instance with the given tag, tag class, and inner type. The
|
||||
* tagging method is EXPLICIT if <code>
|
||||
* explicit</code> is
|
||||
* <code>true</code> and IMPLICIT otherwise.
|
||||
*
|
||||
* @param tag
|
||||
* The tag of this type.
|
||||
* @param cls
|
||||
* The tag class of this type, for instance
|
||||
* {@link ASN1#CLASS_CONTEXT CONTEXT SPECIFIC}.
|
||||
* @param inner
|
||||
* The inner type of this tagged type.
|
||||
* @param explicit
|
||||
* <code>true</code> if EXPLICIT tagging shall be used and
|
||||
* <code>false</code> if the tagging method shall be
|
||||
* IMPLICIT.
|
||||
* @throws NullPointerException
|
||||
* if the given inner type is <code>null</code>.
|
||||
*/
|
||||
public ASN1TaggedType(int tag, int cls, ASN1Type inner, boolean explicit) {
|
||||
setTag(tag);
|
||||
setTagClass(cls);
|
||||
setInnerType(inner);
|
||||
inner_.setExplicit(explicit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given tag and inner type. The tagging method
|
||||
* is EXPLICIT if <code>
|
||||
* explicit</code> is <code>true</code> and
|
||||
* IMPLICIT otherwise. The tag class is set to {@link ASN1#CLASS_CONTEXT
|
||||
* CONTEXT SPECIFIC}.
|
||||
*
|
||||
* @param tag
|
||||
* The tag of this type.
|
||||
* @param inner
|
||||
* The inner type of this tagged type.
|
||||
* @param explicit
|
||||
* <code>true</code> if EXPLICIT tagging shall be used and
|
||||
* <code>false</code> if the tagging method shall be
|
||||
* IMPLICIT.
|
||||
* @throws NullPointerException
|
||||
* if the given inner type is <code>null</code>.
|
||||
*/
|
||||
public ASN1TaggedType(int tag, ASN1Type inner, boolean explicit) {
|
||||
setTag(tag);
|
||||
setTagClass(ASN1.CLASS_CONTEXT);
|
||||
setInnerType(inner);
|
||||
inner_.setExplicit(explicit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given tag, tag class, and inner type. The
|
||||
* tagging method is EXPLICIT if <code>
|
||||
* explicit</code> is
|
||||
* <code>true</code> and IMPLICIT otherwise. The tag class is set to
|
||||
* {@link ASN1#CLASS_CONTEXT CONTEXT SPECIFIC}. If <code>
|
||||
* optional</code>
|
||||
* is <code>true</code> then this type is declared OPTIONAL.
|
||||
*
|
||||
* @param tag
|
||||
* The tag of this type.
|
||||
* @param inner
|
||||
* The inner type of this tagged type.
|
||||
* @param explicit
|
||||
* <code>true</code> if EXPLICIT tagging shall be used and
|
||||
* <code>false</code> if the tagging method shall be
|
||||
* IMPLICIT.
|
||||
* @param optional
|
||||
* <code>true</code> declares this type as OPTIONAL.
|
||||
* @throws NullPointerException
|
||||
* if the given inner type is <code>null</code>.
|
||||
*/
|
||||
public ASN1TaggedType(int tag, ASN1Type inner, boolean explicit,
|
||||
boolean optional) {
|
||||
setTag(tag);
|
||||
setTagClass(ASN1.CLASS_CONTEXT);
|
||||
setInnerType(inner);
|
||||
inner_.setExplicit(explicit);
|
||||
setOptional(optional);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying ASN.1 type. Please note that OPTIONAL modifiers of
|
||||
* (for instance) context-specific types in compound ASN.1 types refer to
|
||||
* the outer type and not to the inner type. Types are declared OPTIONAL by
|
||||
* calling their {@link ASN1Type#setOptional setOptional} method.
|
||||
*
|
||||
* @return The underlying ASN.1 type.
|
||||
*/
|
||||
public ASN1Type getInnerType() {
|
||||
return inner_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the inner type. The default inner type is
|
||||
* {@link ASN1Null ASN1Null}. This method calls
|
||||
* {@link ASN1Type#getValue getValue} on the inner type and returns the
|
||||
* result.
|
||||
*
|
||||
* @return The value of the inner type.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return inner_.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the inner type of this CONTEXT SPECIFIC type.
|
||||
*
|
||||
* @param t
|
||||
* The type to set as the inner type.
|
||||
* @throws NullPointerException
|
||||
* if the given type is <code>null</code>.
|
||||
*/
|
||||
public void setInnerType(ASN1Type t) {
|
||||
if (t == null) {
|
||||
throw new NullPointerException("Type is NULL!");
|
||||
}
|
||||
inner_ = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tag of this type.
|
||||
*
|
||||
* @param tag
|
||||
* The tag.
|
||||
*/
|
||||
public void setTag(int tag) {
|
||||
tag_ = tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tag of this type.
|
||||
*
|
||||
* @return The tag of this type.
|
||||
*/
|
||||
public int getTag() {
|
||||
return tag_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tag class of this type. This tag class may be one of
|
||||
* {@link ASN1#CLASS_UNIVERSAL UNIVERSAL}, {@link ASN1#CLASS_CONTEXT
|
||||
* CONTEXT SPECIFIC}, {@link ASN1#CLASS_PRIVATE PRIVATE}, or {@link
|
||||
* ASN1#CLASS_APPLICATION APPLICATION}.
|
||||
*
|
||||
* @param cls
|
||||
* The tag class.
|
||||
*/
|
||||
public void setTagClass(int cls) {
|
||||
cls_ = cls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tag class of this type. The default class of this instance is
|
||||
* {@link ASN1#CLASS_CONTEXT CONTEXT SPECIFIC}.
|
||||
*
|
||||
* @return The class of this ASN.1 tag.
|
||||
*/
|
||||
public int getTagClass() {
|
||||
return cls_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tagged types themselves are always tagged EXPLICIT. The inner type can be
|
||||
* tagged either EXPLICIT or IMPLICIT. IMPLICIT types are isomorphic to the
|
||||
* underlying type except that the tag and tag class is distinct (with
|
||||
* regard to encoding).
|
||||
*
|
||||
* @return <code>true</code>, tagged types themselves are always tagged
|
||||
* EXPLICIT.
|
||||
*/
|
||||
public boolean isExplicit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception if the give tagging type is not EXPLICIT (<code>true</code>).
|
||||
* Tagged types themselves are always EXPLICIT; re-tagging tagged types is
|
||||
* <b> very</b> bad style!
|
||||
*
|
||||
* @param explicit
|
||||
* The tagging method of the tagged (outer) type. This should
|
||||
* not be mixed with the tagging method of the inner type
|
||||
* which can be tagged either EXPLICIT or IMPLICIT.
|
||||
*/
|
||||
public void setExplicit(boolean explicit) {
|
||||
if (!explicit)
|
||||
throw new IllegalArgumentException(
|
||||
"Tagget types are never IMPLICIT!");
|
||||
}
|
||||
|
||||
public void encode(Encoder enc) throws ASN1Exception, IOException {
|
||||
enc.writeTaggedType(this);
|
||||
}
|
||||
|
||||
public void decode(Decoder dec) throws ASN1Exception, IOException {
|
||||
dec.readTaggedType(this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buf;
|
||||
|
||||
buf = new StringBuffer();
|
||||
buf.append("[");
|
||||
|
||||
switch (cls_) {
|
||||
case ASN1.CLASS_CONTEXT:
|
||||
buf.append("CONTEXT SPECIFIC ");
|
||||
break;
|
||||
case ASN1.CLASS_UNIVERSAL:
|
||||
buf.append("UNIVERSAL ");
|
||||
break;
|
||||
case ASN1.CLASS_APPLICATION:
|
||||
buf.append("APPLICATION ");
|
||||
break;
|
||||
case ASN1.CLASS_PRIVATE:
|
||||
buf.append("PRIVATE ");
|
||||
break;
|
||||
}
|
||||
buf.append(tag_ + "] ");
|
||||
|
||||
if (inner_.isExplicit())
|
||||
buf.append("EXPLICIT ");
|
||||
else
|
||||
buf.append("IMPLICIT ");
|
||||
|
||||
buf.append(inner_.toString());
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
}
|
||||
502
src/codec/asn1/ASN1Time.java
Normal file
502
src/codec/asn1/ASN1Time.java
Normal file
@@ -0,0 +1,502 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/**
|
||||
* This is the root class of all ASN.1 time types. In principle, the known time
|
||||
* types are all of type VisibleString.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1Time.java,v 1.7 2004/09/20 15:22:31 pebinger Exp $"
|
||||
*/
|
||||
abstract public class ASN1Time extends ASN1VisibleString {
|
||||
/**
|
||||
* The <code>TimeZone</code> representing universal coordinated time
|
||||
* (UTC).
|
||||
*/
|
||||
private static final TimeZone TZ = TimeZone.getTimeZone("GMT");
|
||||
|
||||
/**
|
||||
* Used to fill with zeroes.
|
||||
*/
|
||||
protected static final String ZEROES = "0000";
|
||||
|
||||
/**
|
||||
* The internal storage of the date.
|
||||
*/
|
||||
protected Date date_;
|
||||
|
||||
/**
|
||||
* Returns a Java Date instance representing the time in this ASN.1 time
|
||||
* type.
|
||||
*
|
||||
* @return The time as a Java Date instance.
|
||||
*/
|
||||
public Date getDate() {
|
||||
return (Date) date_.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Java long representing the time in milliseconds since January
|
||||
* 1, 1970, 00:00:00 GMT in this ASN.1 time type.
|
||||
*
|
||||
* @return The number of milliseconds since January 1, 1970, 00:00:00 GMT.
|
||||
*/
|
||||
public long getTime() {
|
||||
return date_.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time from the given <code>Calendar</code>.
|
||||
*
|
||||
* @param calendar
|
||||
* The <code>Calendar</code> with the date that shall be
|
||||
* set.
|
||||
*/
|
||||
public void setDate(Calendar calendar) {
|
||||
if (calendar == null) {
|
||||
throw new NullPointerException("calendar");
|
||||
}
|
||||
date_ = calendar.getTime();
|
||||
|
||||
setString0(toString(date_));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time from the given Date instance.
|
||||
*
|
||||
* @param date
|
||||
* The Date.
|
||||
*/
|
||||
public void setDate(Date date) {
|
||||
if (date == null) {
|
||||
throw new NullPointerException("date");
|
||||
}
|
||||
date_ = (Date) date.clone();
|
||||
|
||||
setString0(toString(date_));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time from the given time in milliseconds since January 1, 1970,
|
||||
* 00:00:00 GMT.
|
||||
*
|
||||
* @param time
|
||||
* The number of milliseconds since January 1, 1970, 00:00:00
|
||||
* GMT.
|
||||
*/
|
||||
public void setDate(long time) {
|
||||
date_ = new Date(time);
|
||||
|
||||
setString0(toString(date_));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the date to the one represented by the given string. The internal
|
||||
* string representation is normalized and complies to DER. The date string
|
||||
* is thus converted to GMT.
|
||||
*
|
||||
* @param date
|
||||
* The date as a X.680 date string.
|
||||
* @throws IllegalArgumentException
|
||||
* if the string is not well-formed.
|
||||
* @throws StringIndexOutOfBoundsException
|
||||
* if the string is not well-formed.
|
||||
*/
|
||||
public void setDate(String date) {
|
||||
if (date == null) {
|
||||
throw new NullPointerException("date string");
|
||||
}
|
||||
date_ = toDate(date);
|
||||
|
||||
setString0(toString(date_));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the string value.
|
||||
*
|
||||
* @param s
|
||||
* The string value.
|
||||
*/
|
||||
public void setString(String s) {
|
||||
date_ = toDate(s);
|
||||
|
||||
/*
|
||||
* The value must be set literally because this method is called by the
|
||||
* decoders. This ensures that the encoding is bitwise identical to the
|
||||
* decoding.
|
||||
*/
|
||||
setString0(s);
|
||||
}
|
||||
|
||||
public void encode(Encoder enc) throws ASN1Exception, IOException {
|
||||
enc.writeTime(this);
|
||||
}
|
||||
|
||||
public void decode(Decoder enc) throws ASN1Exception, IOException {
|
||||
enc.readTime(this);
|
||||
}
|
||||
|
||||
abstract protected int[] getFields();
|
||||
|
||||
abstract protected int[] getFieldLengths();
|
||||
|
||||
abstract protected int[] getFieldCorrections();
|
||||
|
||||
/**
|
||||
* Converts the given <code>Date</code> into a string representation
|
||||
* according to DER as described in X.690.
|
||||
*
|
||||
* @param date
|
||||
* The <code>Date</code> that is converted.
|
||||
* @return The string with the date.
|
||||
*/
|
||||
protected String toString(Date date) {
|
||||
StringBuffer buf;
|
||||
Calendar cal;
|
||||
String s;
|
||||
int[] lengths;
|
||||
int[] correct;
|
||||
int[] fields;
|
||||
int len;
|
||||
int w;
|
||||
int n;
|
||||
int v;
|
||||
int lastzero;
|
||||
|
||||
if (date == null) {
|
||||
throw new NullPointerException("date");
|
||||
}
|
||||
cal = new GregorianCalendar(TZ);
|
||||
fields = getFields();
|
||||
correct = getFieldCorrections();
|
||||
lengths = getFieldLengths();
|
||||
buf = new StringBuffer(20);
|
||||
|
||||
/*
|
||||
* Date is UTC time (most of the time ;-) and we set Calendar to UTC.
|
||||
*/
|
||||
cal.setTime(date);
|
||||
|
||||
for (n = 0; n < fields.length; n++) {
|
||||
v = cal.get(fields[n]) - correct[n];
|
||||
s = String.valueOf(v);
|
||||
len = s.length();
|
||||
|
||||
/*
|
||||
* If the target length is zero then we truncate to the left, and
|
||||
* take only the hundreds if they are greater than zero. Hence, only
|
||||
* one digit is printed. In summary, we handle the case of
|
||||
* milliseconds.
|
||||
*/
|
||||
w = lengths[n];
|
||||
|
||||
if (w == 0) {
|
||||
if (v > 0) {
|
||||
|
||||
buf.append(".");
|
||||
// add leading 0s if necessary
|
||||
s = ZEROES.substring(0, 3 - s.length()) + s;
|
||||
|
||||
if (s.charAt(s.length() - 1) != '0') {
|
||||
buf.append(s);
|
||||
} else {
|
||||
lastzero = s.length() - 1;
|
||||
while ((lastzero > 0)
|
||||
&& (s.charAt(lastzero - 1) == '0')) {
|
||||
lastzero--;
|
||||
}
|
||||
buf.append(s.substring(0, lastzero));
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* If we have to fill up then we fill zeroes to the left. This
|
||||
* accounts for days as well as hours and minutes.
|
||||
*/
|
||||
if (w < 0) {
|
||||
w = -w;
|
||||
}
|
||||
if (len < w) {
|
||||
buf.append(ZEROES.substring(0, w - len));
|
||||
buf.append(s);
|
||||
}
|
||||
/*
|
||||
* If we must truncate then we take the rightmost characters. This
|
||||
* accounts for truncated years e.g. "98" instead of "1998".
|
||||
*/
|
||||
else if (len > w) {
|
||||
buf.append(s.substring(len - w));
|
||||
}
|
||||
/*
|
||||
* Everything is fine, we got the length we need.
|
||||
*/
|
||||
else {
|
||||
buf.append(s);
|
||||
}
|
||||
}
|
||||
buf.append('Z');
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given string to a <code>Date</code> object.
|
||||
*
|
||||
* @param code
|
||||
* The string encoding of the date to be converted.
|
||||
* @return The <code>Date</code> object.
|
||||
* @throws IllegalArgumentException
|
||||
* if the given string is not a valid BER encoding of a
|
||||
* date.
|
||||
*/
|
||||
protected Date toDate(String code) {
|
||||
Calendar cal;
|
||||
Calendar res;
|
||||
TimeZone tz;
|
||||
int[] lengths;
|
||||
int[] correct;
|
||||
int[] fields;
|
||||
String s;
|
||||
int pos;
|
||||
int len;
|
||||
int n;
|
||||
int w;
|
||||
int v;
|
||||
int c;
|
||||
|
||||
if (code == null) {
|
||||
throw new NullPointerException("code");
|
||||
}
|
||||
cal = new GregorianCalendar(TZ);
|
||||
cal.setTime(new Date(0));
|
||||
fields = getFields();
|
||||
correct = getFieldCorrections();
|
||||
lengths = getFieldLengths();
|
||||
len = code.length();
|
||||
|
||||
for (pos = 0, n = 0; n < fields.length; n++) {
|
||||
/*
|
||||
* If the field length is zero then we handle milliseconds. In
|
||||
* particular, we test whether the milliseconds are present.
|
||||
*/
|
||||
w = lengths[n];
|
||||
|
||||
if (w == 0) {
|
||||
/*
|
||||
* No character, no period or comma, therefor no milliseconds
|
||||
* either.
|
||||
*/
|
||||
if (pos >= len) {
|
||||
continue;
|
||||
}
|
||||
c = code.charAt(pos);
|
||||
|
||||
/*
|
||||
* No period or comma but another character presumably means
|
||||
* that there are no millis but a time zone offset - or a bad
|
||||
* code.
|
||||
*/
|
||||
if (c != '.' && c != ',') {
|
||||
continue;
|
||||
}
|
||||
pos++;
|
||||
|
||||
/*
|
||||
* We have millis, and now we're gonna read them!
|
||||
*/
|
||||
for (v = 0; (v < 3 && pos < len); v++) {
|
||||
if (!Character.isDigit(code.charAt(pos))) {
|
||||
break;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
/*
|
||||
* If we did not consume at least one digit then we have a bad
|
||||
* encoding.
|
||||
*/
|
||||
if (v == 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Milliseconds format error!");
|
||||
}
|
||||
s = code.substring(pos - v, pos);
|
||||
|
||||
if (v < 3) {
|
||||
s = s + ZEROES.substring(0, 3 - v);
|
||||
}
|
||||
v = Integer.parseInt(s);
|
||||
v = v + correct[n];
|
||||
|
||||
cal.set(fields[n], v);
|
||||
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Here we deal with optional digit fields such as seconds in BER.
|
||||
*/
|
||||
if (w < 0) {
|
||||
w = -w;
|
||||
|
||||
if (pos >= len || !Character.isDigit(code.charAt(pos))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* We fetch the required number of characters and try to decode
|
||||
* them.
|
||||
*/
|
||||
s = code.substring(pos, pos + w);
|
||||
v = Integer.parseInt(s);
|
||||
v = v + correct[n];
|
||||
pos = pos + w;
|
||||
|
||||
/*
|
||||
* Special case for UTCTime: we have to correct for years before
|
||||
* 1970.
|
||||
*/
|
||||
if (fields[n] == Calendar.YEAR && lengths[n] == 2) {
|
||||
v = v + ((v < 70) ? 2000 : 1900);
|
||||
}
|
||||
cal.set(fields[n], v);
|
||||
}
|
||||
/*
|
||||
* We still have to deal with time zone offsets and time zone
|
||||
* specifications - nasty stuff.
|
||||
*/
|
||||
if (pos < len) {
|
||||
c = code.charAt(pos);
|
||||
|
||||
/*
|
||||
* If there is a '+' or '-' then we have a time differential to GMT
|
||||
* and no trailing 'Z'.
|
||||
*/
|
||||
if (c == '+' || c == '-') {
|
||||
s = code.substring(pos, pos + 5);
|
||||
tz = TimeZone.getTimeZone("GMT" + s);
|
||||
pos = pos + 5;
|
||||
}
|
||||
/*
|
||||
* No time differential means we either have a 'Z' or a bad
|
||||
* encoding.
|
||||
*/
|
||||
else if (code.charAt(pos) != 'Z') {
|
||||
throw new IllegalArgumentException(
|
||||
"Illegal char in place of 'Z' (" + pos + ")");
|
||||
}
|
||||
/*
|
||||
* We got the 'Z', thus we have GMT.
|
||||
*/
|
||||
else {
|
||||
tz = TimeZone.getTimeZone("GMT");
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* We reached the end of the string without encountering a time
|
||||
* differential or a 'Z', therefor we use the local time zone. This
|
||||
* should rarely happen unless someone screws up. Nevertheless, it's a
|
||||
* valid code.
|
||||
*/
|
||||
else {
|
||||
tz = TimeZone.getDefault();
|
||||
}
|
||||
if (pos != len) {
|
||||
throw new IllegalArgumentException(
|
||||
"Trailing characters after encoding! (" + pos + ")");
|
||||
}
|
||||
/*
|
||||
* we now have a Calendar calibrated to GMT and a time zone in tz. Now
|
||||
* we merge both together in order to get the correct time according to
|
||||
* GMT.
|
||||
*/
|
||||
res = Calendar.getInstance(tz);
|
||||
res.setTime(new Date(0));
|
||||
|
||||
for (n = 0; n < fields.length; n++) {
|
||||
res.set(fields[n], cal.get(fields[n]));
|
||||
}
|
||||
return res.getTime();
|
||||
}
|
||||
|
||||
}
|
||||
168
src/codec/asn1/ASN1Type.java
Normal file
168
src/codec/asn1/ASN1Type.java
Normal file
@@ -0,0 +1,168 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* The basic interface for Java objects representing primitive ASN.1 types
|
||||
* according to ITU-T Recommendation X.680. A special feature are
|
||||
* {@link Constraint constraints}. With constraints the range of valid values
|
||||
* of an ASN.1 type can be limited. Constraints are validated for most types in
|
||||
* the setter methods allowing initialization with Java types.
|
||||
* <p>
|
||||
*
|
||||
* An abstract implementation of most of the methods declared in this interface
|
||||
* can be found in {@link ASN1AbstractType ASN1AbstractType}.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ASN1Type.java,v 1.2 2000/12/06 17:47:26 vroth Exp $"
|
||||
*/
|
||||
public interface ASN1Type {
|
||||
|
||||
public Object getValue();
|
||||
|
||||
public void setOptional(boolean optional);
|
||||
|
||||
public boolean isOptional();
|
||||
|
||||
public int getTag();
|
||||
|
||||
public int getTagClass();
|
||||
|
||||
public void setExplicit(boolean explicit);
|
||||
|
||||
public boolean isExplicit();
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if this type matches the given tag and
|
||||
* tagclass. This method is primarily used by decoders in order to verify
|
||||
* the tag and tag class of a decoded type. Basic types need not implement
|
||||
* this method since {@link ASN1AbstractType ASN1AbstractType} provides a
|
||||
* default implementation. Certain variable types such as {@link ASN1Choice
|
||||
* ASN1Choice} and {@link ASN1OpenType ASN1OpenType} implement this method.
|
||||
* This helps decoders to determine if a decoded type matches a given ASN.1
|
||||
* structure.
|
||||
*
|
||||
* @param tag
|
||||
* The tag to match.
|
||||
* @param tagclass
|
||||
* The tag class to match.
|
||||
* @return <code>true</code> if this type matches the given tag and tag
|
||||
* class.
|
||||
*/
|
||||
public boolean isType(int tag, int tagclass);
|
||||
|
||||
public void encode(Encoder enc) throws ASN1Exception, IOException;
|
||||
|
||||
public void decode(Decoder dec) throws ASN1Exception, IOException;
|
||||
|
||||
/**
|
||||
* Sets a {@link Constraint constraint} for this type. Constraints are
|
||||
* checked by setter methods and as the last operation of a call to the
|
||||
* {@link ASN1Type#decode decode()} method.
|
||||
*
|
||||
* A number of constraints can be defined in ASN.1; one example is the SIZE
|
||||
* constraint on string types. For instance,
|
||||
* <tt>foo IA5String (SIZE 10..20)</tt> means the string <tt>foo</tt>
|
||||
* can be 10 to 20 characters long. Strings can also be constrained with
|
||||
* regard to the character sets. The constraint model of this package allows
|
||||
* to add arbitrary constraints on types.
|
||||
* <p>
|
||||
*
|
||||
* @param o
|
||||
* The constraint to set.
|
||||
*/
|
||||
public void setConstraint(Constraint o);
|
||||
|
||||
/**
|
||||
* Returns the {@link Constraint Constraint} of this type or
|
||||
* <code>null</code> if there is none.
|
||||
*
|
||||
* @return The Constraint or <code>null</code>.
|
||||
*/
|
||||
public Constraint getConstraint();
|
||||
|
||||
/**
|
||||
* Checks the {@link Constraint constraints} registered with this instance.
|
||||
*
|
||||
* @see Constraint
|
||||
* @see ConstraintCollection
|
||||
*/
|
||||
public void checkConstraints() throws ConstraintException;
|
||||
|
||||
}
|
||||
105
src/codec/asn1/ASN1VisibleString.java
Normal file
105
src/codec/asn1/ASN1VisibleString.java
Normal file
@@ -0,0 +1,105 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* This class represents an ASN.1 T61String as described in ITU-T Recommendation
|
||||
* X.680. Note that no value checking is performed!
|
||||
*
|
||||
* @author Markus Tak (by cut-and-paste ;-) )
|
||||
* @version "$Id: ASN1VisibleString.java,v 1.1 2004/08/09 07:53:21 flautens Exp $"
|
||||
*/
|
||||
public class ASN1VisibleString extends ASN1AbstractString {
|
||||
public ASN1VisibleString() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given string value. No constraints can be
|
||||
* set yet so none are checked.
|
||||
*
|
||||
* @param s
|
||||
* The string value.
|
||||
*/
|
||||
public ASN1VisibleString(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return ASN1.TAG_VISIBLESTRING;
|
||||
}
|
||||
}
|
||||
262
src/codec/asn1/AbstractEncoder.java
Normal file
262
src/codec/asn1/AbstractEncoder.java
Normal file
@@ -0,0 +1,262 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: AbstractEncoder.java,v 1.3 2005/03/22 15:55:36 flautens Exp $"
|
||||
*/
|
||||
public abstract class AbstractEncoder extends FilterOutputStream implements
|
||||
Encoder {
|
||||
/**
|
||||
* Creates an encoder that writes its output to the given output stream.
|
||||
*
|
||||
* @param out
|
||||
* The output stream to which the encoded ASN.1 objects are
|
||||
* written.
|
||||
*/
|
||||
public AbstractEncoder(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void writeType(ASN1Type t) throws ASN1Exception, IOException {
|
||||
t.encode(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method encodes identifier and length octets. The given length can be
|
||||
* negative in which case 0x80 is written to indicate INDEFINITE LENGTH
|
||||
* encoding. Please note that this is appropriate only for a BER encoding or
|
||||
* CER encoding (ITU-T Recommenation X.690). Encoders are responsible for
|
||||
* writing the end of code octets <code>0x00 0x00</code> after encoding
|
||||
* the content octets.
|
||||
*
|
||||
* @param tag
|
||||
* The ASN.1 tag
|
||||
* @param cls
|
||||
* The ASN.1 tag class.
|
||||
* @param prim
|
||||
* <code>true</code> if the encoding is PRIMITIVE and
|
||||
* <code>false</code> if it is CONSTRUCTED.
|
||||
* @param len
|
||||
* The number of content octets or -1 to indicate INDEFINITE
|
||||
* LENGTH encoding.
|
||||
*/
|
||||
protected void writeHeader(int tag, int cls, boolean prim, int len)
|
||||
throws IOException {
|
||||
int b;
|
||||
int i;
|
||||
|
||||
b = cls & ASN1.CLASS_MASK;
|
||||
|
||||
if (!prim) {
|
||||
b = b | ASN1.CONSTRUCTED;
|
||||
}
|
||||
|
||||
if (tag > 30) {
|
||||
b = b | ASN1.TAG_MASK;
|
||||
out.write(b);
|
||||
writeBase128(tag);
|
||||
} else {
|
||||
b = b | tag;
|
||||
out.write(b);
|
||||
}
|
||||
if (len == -1) {
|
||||
out.write(0x80);
|
||||
} else {
|
||||
if (len > 127) {
|
||||
i = (significantBits(len) + 7) / 8;
|
||||
out.write(i | 0x80);
|
||||
writeBase256(len);
|
||||
} else {
|
||||
out.write(len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method computes the number of octets needed to encode the identifier
|
||||
* and length octets of the {@link ASN1Type ASN.1 type} with the given tag
|
||||
* and contents length. The given length can be negative in which case
|
||||
* INDEFINITE LENGTH encoding is assumed.
|
||||
*
|
||||
* @return The number of octets required for encoding the identifier and
|
||||
* length octets.
|
||||
* @param tag
|
||||
* The ASN.1 tag.
|
||||
* @param len
|
||||
* The number of contents octets of the ASN.1 type with the
|
||||
* given tag and length.
|
||||
*/
|
||||
protected int getHeaderLength(int tag, int len) {
|
||||
int n;
|
||||
|
||||
n = 2;
|
||||
if (tag > 30) {
|
||||
n = n + ((significantBits(tag) + 6) / 7);
|
||||
}
|
||||
|
||||
if (len > 127) {
|
||||
n = n + ((significantBits(len) + 7) / 8);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given integer to the output in base 128 representation with
|
||||
* bit 7 of all octets except the last one being set to "1". The
|
||||
* minimum number of octets necessary is used.
|
||||
*
|
||||
* @param n
|
||||
* The integer to be written to the output.
|
||||
* @throws IOException
|
||||
* Thrown by the underlying output stream.
|
||||
*/
|
||||
protected void writeBase128(int n) throws IOException {
|
||||
int i;
|
||||
int j;
|
||||
|
||||
i = (significantBits(n) + 6) / 7;
|
||||
j = (i - 1) * 7;
|
||||
|
||||
while (i > 1) {
|
||||
out.write(((n >>> j) & 0x7f) | 0x80);
|
||||
j = j - 7;
|
||||
i--;
|
||||
}
|
||||
out.write(n & 0x7f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given integer to the output in base 256 with the minimal
|
||||
* number of octets.
|
||||
*
|
||||
* @param n
|
||||
* The integer to be written to the output.
|
||||
* @throws IOException
|
||||
* Thrown by the underlying output stream.
|
||||
*/
|
||||
protected void writeBase256(int n) throws IOException {
|
||||
int i;
|
||||
int j;
|
||||
|
||||
i = (significantBits(n) + 7) / 8;
|
||||
j = (i - 1) * 8;
|
||||
|
||||
while (i > 0) {
|
||||
out.write((n >>> j) & 0xff);
|
||||
j = j - 8;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of significant bits in the given integer. There is
|
||||
* always at least one significant bit.
|
||||
*
|
||||
* @param n
|
||||
* The integer.
|
||||
* @return The number of significant bits in the given integer.
|
||||
*/
|
||||
protected int significantBits(int n) {
|
||||
int i;
|
||||
|
||||
if (n == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (n > 255) {
|
||||
n = n >>> 8;
|
||||
i += 8;
|
||||
}
|
||||
while (n > 0) {
|
||||
n = n >>> 1;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
149
src/codec/asn1/ClassInstanceResolver.java
Normal file
149
src/codec/asn1/ClassInstanceResolver.java
Normal file
@@ -0,0 +1,149 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* Resolves requests for instances based on a class object. New instances are
|
||||
* generated by invoking <code>newInstance()
|
||||
* </code> on the wrapped class
|
||||
* object. The class must provide a no-arg default constructor.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ClassInstanceResolver.java,v 1.2 2000/12/06 17:47:27 vroth Exp $"
|
||||
*/
|
||||
public class ClassInstanceResolver extends Object implements Resolver {
|
||||
/**
|
||||
* The class that is used as a factory.
|
||||
*/
|
||||
private Class factory_;
|
||||
|
||||
/**
|
||||
* Creates an instance with the given factory class.
|
||||
*
|
||||
* @param factory
|
||||
* The factory class.
|
||||
* @throws IllegalArgumentException
|
||||
* if <code>factory</code> has no default constructor, or
|
||||
* does not implement <code>
|
||||
* ASN1Type</code>.
|
||||
*/
|
||||
public ClassInstanceResolver(Class factory) {
|
||||
if (factory == null) {
|
||||
throw new NullPointerException("Need a factory class!");
|
||||
}
|
||||
try {
|
||||
factory.getConstructor(new Class[0]);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new IllegalArgumentException("Class " + factory.getName()
|
||||
+ " has no default constructor!");
|
||||
}
|
||||
if (!ASN1Type.class.isAssignableFrom(factory)) {
|
||||
throw new IllegalArgumentException("Class " + factory.getName()
|
||||
+ " is not an ASN1Type!");
|
||||
}
|
||||
factory_ = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class object of the factory class.
|
||||
*
|
||||
* @return The class object.
|
||||
*/
|
||||
public Class getFactoryClass() {
|
||||
return factory_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the call by returning a new instance of the the factory class.
|
||||
* The factory class must have been specified at the time of constructing
|
||||
* this instance.
|
||||
*
|
||||
* @param caller
|
||||
* The caller. The caller is ignored.
|
||||
* @throws ResolverException
|
||||
* if for some reason the call cannot be resolved.
|
||||
*/
|
||||
public ASN1Type resolve(ASN1Type caller) throws ResolverException {
|
||||
try {
|
||||
return (ASN1Type) factory_.newInstance();
|
||||
} catch (Exception e) {
|
||||
throw new ResolverException("Caught " + e.getClass().getName()
|
||||
+ "(\"" + e.getMessage() + "\")");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
93
src/codec/asn1/Constraint.java
Normal file
93
src/codec/asn1/Constraint.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* This interface specifies a constraint of some ASN.1 type. Constraints are
|
||||
* called to check the validity of a type right after initialization and after
|
||||
* decoding. For instance an OCTET STRING may be defined to be at most 8 octets
|
||||
* long. This may be implemented by adding a constraint to an
|
||||
* {@link ASN1OctetString ASN1OctetString} instance that verifies the length of
|
||||
* the octets string.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: Constraint.java,v 1.2 2000/12/06 17:47:28 vroth Exp $"
|
||||
*/
|
||||
public interface Constraint {
|
||||
public void constrain(ASN1Type o) throws ConstraintException;
|
||||
|
||||
}
|
||||
94
src/codec/asn1/ConstraintException.java
Normal file
94
src/codec/asn1/ConstraintException.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* Thrown by {@link Constraint Constraint} instances if the validation of some
|
||||
* ASN.1 type fails.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ConstraintException.java,v 1.2 2000/12/06 17:47:28 vroth Exp $"
|
||||
*/
|
||||
public class ConstraintException extends ASN1Exception {
|
||||
public ConstraintException() {
|
||||
}
|
||||
|
||||
public ConstraintException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
119
src/codec/asn1/DERCodeComparator.java
Normal file
119
src/codec/asn1/DERCodeComparator.java
Normal file
@@ -0,0 +1,119 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* Compares two DER Encodings and orders them according to the strict ordering
|
||||
* rules applied in DER encoded SET OF types.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: DERCodeComparator.java,v 1.1 2004/08/09 07:57:53 flautens Exp $"
|
||||
*/
|
||||
public class DERCodeComparator extends Object implements Comparator {
|
||||
public int compare(Object o1, Object o2) {
|
||||
byte[] a1;
|
||||
byte[] a2;
|
||||
int n;
|
||||
int m;
|
||||
int x;
|
||||
int y;
|
||||
|
||||
a1 = (byte[]) o1;
|
||||
a2 = (byte[]) o2;
|
||||
m = Math.min(a1.length, a2.length);
|
||||
|
||||
for (n = 0; n < m; n++) {
|
||||
x = a1[n] & 0xff;
|
||||
y = a2[n] & 0xff;
|
||||
|
||||
if (x < y) {
|
||||
return -1;
|
||||
} else if (x > y) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (a1.length == a2.length) {
|
||||
return 0;
|
||||
} else if (a1.length < a2.length) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
1246
src/codec/asn1/DERDecoder.java
Normal file
1246
src/codec/asn1/DERDecoder.java
Normal file
File diff suppressed because it is too large
Load Diff
571
src/codec/asn1/DEREncoder.java
Normal file
571
src/codec/asn1/DEREncoder.java
Normal file
@@ -0,0 +1,571 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* If ,right after instantiating the encoder, the strict parameter is set to
|
||||
* true, the encoder uses the strict encoding rules from X680/X690 for Sets and
|
||||
* SetOfs. As long as the flag is not set, the encoder behaves as usual.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: DEREncoder.java,v 1.7 2004/08/09 11:10:08 flautens Exp $"
|
||||
*/
|
||||
public class DEREncoder extends AbstractEncoder {
|
||||
private int[] stack_;
|
||||
private int sp_;
|
||||
|
||||
/**
|
||||
* if true, the strict encoding rules for sets and set of are used.
|
||||
*/
|
||||
private boolean strict = false;
|
||||
|
||||
/**
|
||||
* This variable has a bit set for each tag that denotes a CONSTRUCTED type.
|
||||
*/
|
||||
private int constructed_ = ((1 << ASN1.TAG_SEQUENCE) | (1 << ASN1.TAG_SET) | (1 << ASN1.TAG_REAL));
|
||||
|
||||
/**
|
||||
* Creates an encoder that writes its output to the given output stream.
|
||||
*
|
||||
* @param out
|
||||
* The output stream to which the encoded ASN.1 objects are
|
||||
* written.
|
||||
*/
|
||||
public DEREncoder(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the value of the strict parameter.
|
||||
*/
|
||||
public boolean isStrict() {
|
||||
return this.strict;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the strict parameter.
|
||||
*/
|
||||
public void setStrict(boolean _strictness) {
|
||||
this.strict = _strictness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the identifier and length octets. If there are no known lengths
|
||||
* then this method creates and runs a
|
||||
* {@link RunLengthEncoder RunLengthEncoder} on the given type in order to
|
||||
* establish the length of it and of any contained types. This method must
|
||||
* not be called with OPTIONAL types else errors may occur. It is the
|
||||
* responsibility of the caller to ascertain this precondition. Only the
|
||||
* headers of types that are tagged {@link ASN1Type#isExplicit EXPLICIT} are
|
||||
* encoded. If the given type is tagged IMPLICIT then this method simply
|
||||
* returns.
|
||||
*
|
||||
* @param t
|
||||
* The type of which the header is encoded.
|
||||
* @param primitive
|
||||
* <code>true</code> if the encoding is PRIMITIVE and
|
||||
* <code>false</code> if it is CONSTRUCTED.
|
||||
*/
|
||||
protected void writeHeader(ASN1Type t, boolean primitive)
|
||||
throws ASN1Exception, IOException {
|
||||
int length;
|
||||
|
||||
if (!t.isExplicit()) {
|
||||
return;
|
||||
}
|
||||
if (stack_ == null || sp_ == 0) {
|
||||
RunLengthEncoder enc;
|
||||
|
||||
enc = new RunLengthEncoder();
|
||||
enc.writeType(t);
|
||||
stack_ = enc.getLengthFields();
|
||||
sp_ = stack_.length;
|
||||
|
||||
if (sp_ < 1) {
|
||||
throw new ASN1Exception("Cannot determine length!");
|
||||
}
|
||||
}
|
||||
length = stack_[--sp_];
|
||||
|
||||
writeHeader(t.getTag(), t.getTagClass(), primitive, length);
|
||||
}
|
||||
|
||||
public void writeBoolean(ASN1Boolean t) throws ASN1Exception, IOException {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
writeHeader(t, true);
|
||||
write(t.isTrue() ? 0xff : 0x00);
|
||||
}
|
||||
|
||||
public void writeInteger(ASN1Integer t) throws ASN1Exception, IOException {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
writeHeader(t, true);
|
||||
write(t.getBigInteger().toByteArray());
|
||||
}
|
||||
|
||||
public void help(byte[] b) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < b.length; i++) {
|
||||
System.err.println(" " + (b[i] & 0xff));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a bitstring. This method expects that the bitstring instance is
|
||||
* already compact. In other words, it does not contain trailing zeroes and
|
||||
* the pad count is in the range of zero to seven.
|
||||
*/
|
||||
public void writeBitString(ASN1BitString t) throws ASN1Exception,
|
||||
IOException {
|
||||
if (t.isOptional()) {
|
||||
return;
|
||||
}
|
||||
writeHeader(t, true);
|
||||
write(t.getPadCount());
|
||||
|
||||
if (!t.isZero()) {
|
||||
write(t.getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
public void writeOctetString(ASN1OctetString t) throws ASN1Exception,
|
||||
IOException {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
writeHeader(t, true);
|
||||
write(t.getByteArray());
|
||||
}
|
||||
|
||||
public void writeNull(ASN1Null t) throws ASN1Exception, IOException {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
writeHeader(t, true);
|
||||
}
|
||||
|
||||
public void writeObjectIdentifier(ASN1ObjectIdentifier t)
|
||||
throws ASN1Exception, IOException {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
writeHeader(t, true);
|
||||
|
||||
int i;
|
||||
int[] e;
|
||||
|
||||
e = t.getOID();
|
||||
if (e.length < 2)
|
||||
throw new ASN1Exception("OID must have at least 2 elements!");
|
||||
|
||||
write(e[0] * 40 + e[1]);
|
||||
for (i = 2; i < e.length; i++)
|
||||
writeBase128(e[i]);
|
||||
}
|
||||
|
||||
public void writeReal(ASN1Type t) {
|
||||
throw new UnsupportedOperationException("Real is not yet supported!");
|
||||
}
|
||||
|
||||
public void writeString(ASN1String t) throws ASN1Exception, IOException {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
writeHeader(t, true);
|
||||
write(t.convert(t.getString()));
|
||||
}
|
||||
|
||||
public void writeCollection(ASN1Collection t) throws ASN1Exception,
|
||||
IOException {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
Iterator i;
|
||||
Collection c;
|
||||
// Collection h;
|
||||
ArrayList h;
|
||||
writeHeader(t, false);
|
||||
|
||||
c = t.getCollection();
|
||||
|
||||
if (isStrict() && t instanceof ASN1SetOf) {
|
||||
// von VR war writeStrictSetOf(t);
|
||||
writeStrictSetOf((ASN1SetOf) t);
|
||||
return;
|
||||
}
|
||||
if (isStrict() && t instanceof ASN1Set) {
|
||||
h = new ArrayList(c.size());
|
||||
|
||||
h.addAll(c);
|
||||
Collections.sort(h, new ASN1TagComparator());
|
||||
|
||||
c = h;
|
||||
}
|
||||
try {
|
||||
for (i = c.iterator(); i.hasNext();)
|
||||
writeType((ASN1Type) i.next());
|
||||
} catch (ClassCastException e) {
|
||||
throw new ASN1Exception("Non-ASN.1 type in collection!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method fixes the DER SET OF strict encoding issue brought up by
|
||||
* pea-counter implementations of decoders that insist on sorting the SET OF
|
||||
* components by encoding -- something no sane implementation requires.
|
||||
*
|
||||
* The method of implementation is basically a hack. Don't take this as a
|
||||
* good programming pattern. Moreover, this implementation becomes
|
||||
* completely and utterly THREAD UNSAFE. Not that this would mater too much.
|
||||
*/
|
||||
protected void writeStrictSetOf(ASN1SetOf t) throws ASN1Exception,
|
||||
IOException {
|
||||
ByteArrayOutputStream bos;
|
||||
OutputStream old;
|
||||
Collection c;
|
||||
ArrayList res;
|
||||
Iterator i;
|
||||
byte[] buf;
|
||||
|
||||
/*
|
||||
* Prepare working variables
|
||||
*/
|
||||
c = t.getCollection();
|
||||
res = new ArrayList(c.size());
|
||||
bos = new ByteArrayOutputStream();
|
||||
|
||||
/*
|
||||
* Safe the original output stream and replace it with our byte array
|
||||
* output stream.
|
||||
*/
|
||||
old = super.out;
|
||||
super.out = bos;
|
||||
|
||||
try {
|
||||
/*
|
||||
* Go ahead and encode everything into byte arrays.
|
||||
*/
|
||||
for (i = c.iterator(); i.hasNext();) {
|
||||
writeType((ASN1Type) i.next());
|
||||
|
||||
/*
|
||||
* If something has been encoded then we safe it for later
|
||||
* sorting.
|
||||
*/
|
||||
if (bos.size() > 0) {
|
||||
res.add(bos.toByteArray());
|
||||
bos.reset();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
/*
|
||||
* Restore the original output stream.
|
||||
*/
|
||||
super.out = old;
|
||||
}
|
||||
/*
|
||||
* Now, we sort the different codes and write them
|
||||
*/
|
||||
Collections.sort(res, new DERCodeComparator());
|
||||
|
||||
for (i = res.iterator(); i.hasNext();) {
|
||||
buf = (byte[]) i.next();
|
||||
|
||||
write(buf, 0, buf.length);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeTime(ASN1Time t) throws ASN1Exception, IOException {
|
||||
writeString(t);
|
||||
}
|
||||
|
||||
public void writeTaggedType(ASN1TaggedType t) throws ASN1Exception,
|
||||
IOException {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
boolean primitive;
|
||||
ASN1Type o;
|
||||
int tag;
|
||||
|
||||
o = t.getInnerType();
|
||||
|
||||
if (!o.isExplicit()) {
|
||||
if (t instanceof ASN1Opaque)
|
||||
tag = t.getTag();
|
||||
else
|
||||
tag = o.getTag();
|
||||
|
||||
primitive = ((constructed_ & (1 << tag)) == 0);
|
||||
} else
|
||||
primitive = false;
|
||||
|
||||
writeHeader(t, primitive);
|
||||
writeType(t.getInnerType());
|
||||
}
|
||||
|
||||
public void writeTypeIdentifier(ASN1Type t) {
|
||||
throw new UnsupportedOperationException(
|
||||
"TypeIdentifier is not yet supported!");
|
||||
}
|
||||
|
||||
public void write(byte[] b) throws IOException {
|
||||
out.write(b);
|
||||
}
|
||||
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
out.write(b, off, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an arbitrary {@link ASN1Type ASN1Type}. The given type is written
|
||||
* only if it is not declared OPTIONAL. The type is written by calling its
|
||||
* {@link ASN1Type#encode encode} method with <code>this</code> as the
|
||||
* argument. The called emthod then should invoke the appropriate encoder
|
||||
* method of the primitive type to which the given type corresponds.
|
||||
*
|
||||
* @param t
|
||||
* The type to write.
|
||||
* @throws ASN1Exception
|
||||
* if the given type cannot be encoded.
|
||||
* @throws IOException
|
||||
* if an I/O error occurs.
|
||||
*/
|
||||
public void writeType(ASN1Type t) throws ASN1Exception, IOException {
|
||||
if (!t.isOptional())
|
||||
t.encode(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method encodes identifier and length octets. The given length can be
|
||||
* negative in which case 0x80 is written to indicate INDEFINITE LENGTH
|
||||
* encoding. Please note that this is appropriate only for a BER encoding or
|
||||
* CER encoding (ITU-T Recommenation X.690). Encoders are responsible for
|
||||
* writing the end of code octets <code>0x00 0x00</code> after encoding
|
||||
* the content octets.
|
||||
*
|
||||
* @param tag
|
||||
* The ASN.1 tag
|
||||
* @param cls
|
||||
* The ASN.1 tag class.
|
||||
* @param prim
|
||||
* <code>true</code> if the encoding is PRIMITIVE and
|
||||
* <code>false</code> if it is CONSTRUCTED.
|
||||
* @param len
|
||||
* The number of content octets or -1 to indicate INDEFINITE
|
||||
* LENGTH encoding.
|
||||
*/
|
||||
protected void writeHeader(int tag, int cls, boolean prim, int len)
|
||||
throws IOException {
|
||||
int b, i;
|
||||
|
||||
b = cls & ASN1.CLASS_MASK;
|
||||
|
||||
if (!prim)
|
||||
b = b | ASN1.CONSTRUCTED;
|
||||
|
||||
if (tag > 30) {
|
||||
b = b | ASN1.TAG_MASK;
|
||||
out.write(b);
|
||||
writeBase128(tag);
|
||||
} else {
|
||||
b = b | tag;
|
||||
out.write(b);
|
||||
}
|
||||
if (len == -1)
|
||||
out.write(0x80);
|
||||
else {
|
||||
if (len > 127) {
|
||||
i = (significantBits(len) + 7) / 8;
|
||||
out.write(i | 0x80);
|
||||
writeBase256(len);
|
||||
} else
|
||||
out.write(len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method computes the number of octets needed to encode the identifier
|
||||
* and length octets of the {@link ASN1Type ASN.1 type} with the given tag
|
||||
* and contents length. The given length can be negative in which case
|
||||
* INDEFINITE LENGTH encoding is assumed.
|
||||
*
|
||||
* @return The number of octets required for encoding the identifier and
|
||||
* length octets.
|
||||
* @param tag
|
||||
* The ASN.1 tag.
|
||||
* @param len
|
||||
* The number of contents octets of the ASN.1 type with the
|
||||
* given tag and length.
|
||||
*/
|
||||
protected int getHeaderLength(int tag, int len) {
|
||||
int n;
|
||||
|
||||
n = 2;
|
||||
if (tag > 30)
|
||||
n = n + (significantBits(tag) + 6) / 7;
|
||||
|
||||
if (len > 127)
|
||||
n = n + (significantBits(len) + 7) / 8;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given integer to the output in base 128 representation with
|
||||
* bit 7 of all octets except the last one being set to "1". The
|
||||
* minimum number of octets necessary is used.
|
||||
*
|
||||
* @param n
|
||||
* The integer to be written to the output.
|
||||
* @throws IOException
|
||||
* Thrown by the underlying output stream.
|
||||
*/
|
||||
protected void writeBase128(int n) throws IOException {
|
||||
int i, j;
|
||||
|
||||
i = (significantBits(n) + 6) / 7;
|
||||
j = (i - 1) * 7;
|
||||
|
||||
while (i > 1) {
|
||||
out.write(((n >>> j) & 0x7f) | 0x80);
|
||||
j = j - 7;
|
||||
i--;
|
||||
}
|
||||
out.write(n & 0x7f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given integer to the output in base 256 with the minimal
|
||||
* number of octets.
|
||||
*
|
||||
* @param n
|
||||
* The integer to be written to the output.
|
||||
* @throws IOException
|
||||
* Thrown by the underlying output stream.
|
||||
*/
|
||||
protected void writeBase256(int n) throws IOException {
|
||||
int i, j;
|
||||
|
||||
i = (significantBits(n) + 7) / 8;
|
||||
j = (i - 1) * 8;
|
||||
|
||||
while (i > 0) {
|
||||
out.write((n >>> j) & 0xff);
|
||||
j = j - 8;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of significant bits in the given integer. There is
|
||||
* always at least one significant bit.
|
||||
*
|
||||
* @param n
|
||||
* The integer.
|
||||
* @return The number of significant bits in the given integer.
|
||||
*/
|
||||
protected int significantBits(int n) {
|
||||
int i;
|
||||
|
||||
if (n == 0)
|
||||
return 1;
|
||||
|
||||
i = 0;
|
||||
while (n > 255) {
|
||||
n = n >>> 8;
|
||||
i += 8;
|
||||
}
|
||||
while (n > 0) {
|
||||
n = n >>> 1;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
126
src/codec/asn1/Decoder.java
Normal file
126
src/codec/asn1/Decoder.java
Normal file
@@ -0,0 +1,126 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Defines the methods that must be implemented by decoders of ASN.1 types.
|
||||
*
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: Decoder.java,v 1.2 2000/12/06 17:47:28 vroth Exp $"
|
||||
*/
|
||||
public interface Decoder {
|
||||
|
||||
public ASN1Type readType() throws ASN1Exception, IOException;
|
||||
|
||||
public void readType(ASN1Type t) throws ASN1Exception, IOException;
|
||||
|
||||
public void readBoolean(ASN1Boolean t) throws ASN1Exception, IOException;
|
||||
|
||||
public void readInteger(ASN1Integer t) throws ASN1Exception, IOException;
|
||||
|
||||
public void readBitString(ASN1BitString t) throws ASN1Exception,
|
||||
IOException;
|
||||
|
||||
public void readOctetString(ASN1OctetString t) throws ASN1Exception,
|
||||
IOException;
|
||||
|
||||
public void readNull(ASN1Null t) throws ASN1Exception, IOException;
|
||||
|
||||
public void readObjectIdentifier(ASN1ObjectIdentifier t)
|
||||
throws ASN1Exception, IOException;
|
||||
|
||||
public void readReal(ASN1Type t) throws ASN1Exception, IOException;
|
||||
|
||||
public void readString(ASN1String t) throws ASN1Exception, IOException;
|
||||
|
||||
public void readCollection(ASN1Collection t) throws ASN1Exception,
|
||||
IOException;
|
||||
|
||||
public void readCollectionOf(ASN1CollectionOf t) throws ASN1Exception,
|
||||
IOException;
|
||||
|
||||
public void readTime(ASN1Time t) throws ASN1Exception, IOException;
|
||||
|
||||
public void readTaggedType(ASN1TaggedType t) throws ASN1Exception,
|
||||
IOException;
|
||||
|
||||
public void readChoice(ASN1Choice t) throws ASN1Exception, IOException;
|
||||
|
||||
}
|
||||
154
src/codec/asn1/DefinedByResolver.java
Normal file
154
src/codec/asn1/DefinedByResolver.java
Normal file
@@ -0,0 +1,154 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* This interface is used by the {@link ASN1OpenType ASN1OpenType} in order to
|
||||
* resolve the ASN.1 type to decode at runtime. Concrete implementations of this
|
||||
* interface can be used to model references to type classes as well or to
|
||||
* compensate for the superseded ASN.1 ANY DEFINED BY type.
|
||||
* <p>
|
||||
*
|
||||
* Implementations shall determine and return the correct ASN.1 type to be
|
||||
* decoded in the defined method.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: DefinedByResolver.java,v 1.2 2000/12/06 17:47:28 vroth Exp $"
|
||||
*/
|
||||
public class DefinedByResolver extends Object implements Resolver {
|
||||
private OIDRegistry registry_;
|
||||
private ASN1ObjectIdentifier oid_;
|
||||
|
||||
/**
|
||||
* Creates an instance that attempts to resolve the given OID against the
|
||||
* given registry upon calling {@link #resolve resolve}. The OID instance
|
||||
* used or resolving is the one passed to this constructor. Hence, an OID
|
||||
* can be added to a compound ASN.1 type and an {@link ASN1OpenType
|
||||
* ASN1OpenType} can be initialized with this. If the OID is decoded before
|
||||
* the open type then the open type is resolved against the given registry
|
||||
* and the decoded OID. In other words the ASN.1 ANY DEFINED BY type can be
|
||||
* modelled with an ASN1OpenType and an instance of this resolver class.
|
||||
*
|
||||
* @param registry
|
||||
* The registry to resolve the given OID against.
|
||||
* @param oid
|
||||
* The oid instance to use when resolving.
|
||||
*/
|
||||
public DefinedByResolver(OIDRegistry registry, ASN1ObjectIdentifier oid) {
|
||||
if (registry == null || oid == null)
|
||||
throw new NullPointerException("Registry or OID is null!");
|
||||
|
||||
registry_ = registry;
|
||||
oid_ = oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that resolves the given OID against the
|
||||
* {@link OIDRegistry#getGlobalOIDRegistry global OID registry}.
|
||||
*
|
||||
* @param oid
|
||||
* The OID to resolve.
|
||||
*/
|
||||
public DefinedByResolver(ASN1ObjectIdentifier oid) {
|
||||
if (oid == null)
|
||||
throw new NullPointerException("OID is null!");
|
||||
|
||||
registry_ = OIDRegistry.getGlobalOIDRegistry();
|
||||
oid_ = oid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the private OID in the private registry and returns the resolved
|
||||
* ASN.1 type. If the OID cannot be resolved against the registry then an
|
||||
* exception is thrown.
|
||||
*
|
||||
* @param caller
|
||||
* The calling ASN.1 type.
|
||||
* @throws ResolverException
|
||||
* if the private OID cannot be mapped onto an ASN.1 type by
|
||||
* the private registry.
|
||||
*/
|
||||
public ASN1Type resolve(ASN1Type caller) throws ResolverException {
|
||||
ASN1Type t;
|
||||
|
||||
t = registry_.getASN1Type(oid_);
|
||||
if (t == null) {
|
||||
throw new ResolverException("Cannot resolve " + oid_);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
122
src/codec/asn1/Encoder.java
Normal file
122
src/codec/asn1/Encoder.java
Normal file
@@ -0,0 +1,122 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Defines the methods that must be implemented by encoders of ASN.1 types.
|
||||
*
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: Encoder.java,v 1.2 2000/12/06 17:47:29 vroth Exp $"
|
||||
*/
|
||||
public interface Encoder {
|
||||
|
||||
public void writeType(ASN1Type t) throws ASN1Exception, IOException;
|
||||
|
||||
public void writeBoolean(ASN1Boolean t) throws ASN1Exception, IOException;
|
||||
|
||||
public void writeInteger(ASN1Integer t) throws ASN1Exception, IOException;
|
||||
|
||||
public void writeBitString(ASN1BitString t) throws ASN1Exception,
|
||||
IOException;
|
||||
|
||||
public void writeOctetString(ASN1OctetString t) throws ASN1Exception,
|
||||
IOException;
|
||||
|
||||
public void writeNull(ASN1Null t) throws ASN1Exception, IOException;
|
||||
|
||||
public void writeObjectIdentifier(ASN1ObjectIdentifier t)
|
||||
throws ASN1Exception, IOException;
|
||||
|
||||
public void writeReal(ASN1Type t) throws ASN1Exception, IOException;
|
||||
|
||||
public void writeString(ASN1String t) throws ASN1Exception, IOException;
|
||||
|
||||
public void writeCollection(ASN1Collection t) throws ASN1Exception,
|
||||
IOException;
|
||||
|
||||
public void writeTime(ASN1Time t) throws ASN1Exception, IOException;
|
||||
|
||||
public void writeTaggedType(ASN1TaggedType t) throws ASN1Exception,
|
||||
IOException;
|
||||
|
||||
public void writeTypeIdentifier(ASN1Type t) throws ASN1Exception,
|
||||
IOException;
|
||||
|
||||
}
|
||||
319
src/codec/asn1/OIDRegistry.java
Normal file
319
src/codec/asn1/OIDRegistry.java
Normal file
@@ -0,0 +1,319 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class maps ASN.1 object identifiers onto ASN.1 types suitable for
|
||||
* decoding the structure defined by the given OID. It is modelled along the
|
||||
* lines of the ClassLoader and provides a hierarchy and top-level OID
|
||||
* registries.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: OIDRegistry.java,v 1.4 2004/08/09 08:32:22 flautens Exp $"
|
||||
*/
|
||||
public class OIDRegistry extends Object {
|
||||
|
||||
/**
|
||||
* The list of global OID registries.
|
||||
*/
|
||||
private static Set registries_ = Collections.synchronizedSet(new HashSet());
|
||||
|
||||
/**
|
||||
* The global instance of OID registries.
|
||||
*/
|
||||
private static OIDRegistry global_ = new OIDRegistry();
|
||||
|
||||
/**
|
||||
* The parent OID registry.
|
||||
*/
|
||||
private OIDRegistry parent_ = null;
|
||||
|
||||
/**
|
||||
* Creates an OID registry.
|
||||
*/
|
||||
private OIDRegistry() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the global OIDRegistry instance that may be used for
|
||||
* querying
|
||||
*
|
||||
* @return The global OID registry.
|
||||
*/
|
||||
final static public OIDRegistry getGlobalOIDRegistry() {
|
||||
return global_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a registry to the set of globally known ones unless it is already in
|
||||
* the global set. This method checks the permission
|
||||
* <p>
|
||||
*
|
||||
* {@link ASN1Permission ASN1Permission}, " OIDRegistry.add"
|
||||
* <p>
|
||||
*
|
||||
* The reference to the parent registry of the given registry is cleared
|
||||
* before it is added.
|
||||
*
|
||||
* @param r
|
||||
* The registry to add.
|
||||
* @throws SecurityException
|
||||
* iff the caller has no right to add registries to the
|
||||
* global ones.
|
||||
*/
|
||||
final public static void addOIDRegistry(OIDRegistry r) {
|
||||
if (r == null) {
|
||||
return;
|
||||
}
|
||||
AccessController.checkPermission(new ASN1Permission("OIDRegistry.add"));
|
||||
|
||||
r.parent_ = null;
|
||||
|
||||
registries_.add(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given OID registry from the set of globally known ones. This
|
||||
* method checks the permission
|
||||
* <p>
|
||||
*
|
||||
* {@link ASN1Permission ASN1Permission}, " OIDRegistry.remove"
|
||||
*
|
||||
* @param r
|
||||
* The registry to remove.
|
||||
* @throws SecurityException
|
||||
* iff the caller has no right to remove OID registries.
|
||||
*/
|
||||
final public static void removeOIDRegistry(OIDRegistry r) {
|
||||
if (r == null) {
|
||||
return;
|
||||
}
|
||||
AccessController.checkPermission(new ASN1Permission(
|
||||
"OIDRegistry.remove"));
|
||||
|
||||
registries_.remove(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an OID registry with the given parent. If an OID is not found by
|
||||
* this registry then the search is delegated to the parent registry.
|
||||
*
|
||||
* @param parent
|
||||
* The parent OID registry.
|
||||
*/
|
||||
public OIDRegistry(OIDRegistry parent) {
|
||||
parent_ = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an ASN.1 type based on the given OID. If no type is found then
|
||||
* <code>null</code> is returned. This method first calls {@link
|
||||
* #getLocalASN1Type(ASN1ObjectIdentifier) getLocalASN1Type}. If no ASN.1
|
||||
* type is found for the given OID then <code>getASN1Type</code> is called
|
||||
* for the parent OIDRegistry.
|
||||
*
|
||||
* @param oid
|
||||
* The registered OID of the desired type.
|
||||
* @return The type or <code>null</code> if no type with the given OID is
|
||||
* known.
|
||||
*/
|
||||
final public ASN1Type getASN1Type(ASN1ObjectIdentifier oid) {
|
||||
ASN1Type o;
|
||||
|
||||
o = getLocalASN1Type(oid);
|
||||
|
||||
if (o == null && parent_ != null) {
|
||||
return parent_.getASN1Type(oid);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an ASN.1 type for the given OID or <code>null</code> if no
|
||||
* such type was found.
|
||||
* <p>
|
||||
*
|
||||
* This method should be overridden by subclasses. Subclasses should
|
||||
* retrieve a pointer to their private synchronized Map with OID to String
|
||||
* (or Class) mappings, and call the method with the same name but which
|
||||
* takes an additional Map.
|
||||
* <p>
|
||||
*
|
||||
* This implementation searches the global registries for a matching entry.
|
||||
*/
|
||||
protected ASN1Type getLocalASN1Type(ASN1ObjectIdentifier oid) {
|
||||
Iterator i;
|
||||
ASN1Type o;
|
||||
OIDRegistry r;
|
||||
|
||||
for (i = registries_.iterator(); i.hasNext();) {
|
||||
r = (OIDRegistry) i.next();
|
||||
o = r.getASN1Type(oid);
|
||||
|
||||
if (o != null) {
|
||||
return o;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an ASN.1 type for the given OID or <code>null</code> if no
|
||||
* such type was found. Strings in the given <code>Map</code> are replaced
|
||||
* by the resolved classes.
|
||||
* <p>
|
||||
*
|
||||
* This is a convenience method that can be called by subclasses with a Map
|
||||
* that is specific to the subclass.
|
||||
*
|
||||
* @param oid
|
||||
* The OID that is resolved.
|
||||
* @param map
|
||||
* The <code>Map</code> that holds the OID to class (name)
|
||||
* mapping. The <code>Map</code> values consist either of
|
||||
* strings (class names) or of the resolved class objects.
|
||||
*/
|
||||
protected ASN1Type getLocalASN1Type(ASN1ObjectIdentifier oid, Map map) {
|
||||
Object o;
|
||||
Class c;
|
||||
|
||||
if (oid == null || map == null) {
|
||||
throw new NullPointerException("oid or map");
|
||||
}
|
||||
o = map.get(oid);
|
||||
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
if (o instanceof String) {
|
||||
c = Class.forName((String) o);
|
||||
|
||||
map.put(new ASN1ObjectIdentifier(oid.getOID()), c);
|
||||
|
||||
o = c;
|
||||
}
|
||||
c = (Class) o;
|
||||
|
||||
return (ASN1Type) c.newInstance();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace(System.err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the default OID registry. Subclasses should override
|
||||
* this method and provide a static instance of an OID registry that
|
||||
* delegates to the global OID registry if a requested OID could not be
|
||||
* found locally. This implementation returns the global OID registry by
|
||||
* default.
|
||||
*
|
||||
* @return The default OID registry.
|
||||
*/
|
||||
static public OIDRegistry getDefaultRegistry() {
|
||||
return OIDRegistry.getGlobalOIDRegistry();
|
||||
}
|
||||
|
||||
/**
|
||||
* An OIDRegistry equals another iff both are of the same class.
|
||||
*
|
||||
* @return <code>true</code> if both registries are of the same class.
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (getClass() == o.getClass()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The hash code of an instance is the hash code of its class. This is
|
||||
* required to be consistent with the {@link #equals equals()} method.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return getClass().hashCode();
|
||||
}
|
||||
|
||||
}
|
||||
94
src/codec/asn1/Resolver.java
Normal file
94
src/codec/asn1/Resolver.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* This interface is used by the {@link ASN1OpenType ASN1OpenType} in order to
|
||||
* resolve the ASN.1 type to decode at runtime. Concrete implementations of this
|
||||
* interface can be used to model references to type classes as well or to
|
||||
* compensate for the superseded ASN.1 ANY DEFINED BY type.
|
||||
* <p>
|
||||
*
|
||||
* Implementations shall determine and return the correct ASN.1 type to be
|
||||
* decoded in the defined method.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: Resolver.java,v 1.2 2000/12/06 17:47:29 vroth Exp $"
|
||||
*/
|
||||
public interface Resolver {
|
||||
public ASN1Type resolve(ASN1Type caller) throws ResolverException;
|
||||
}
|
||||
93
src/codec/asn1/ResolverException.java
Normal file
93
src/codec/asn1/ResolverException.java
Normal file
@@ -0,0 +1,93 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
/**
|
||||
* Thrown by {@link OpenTypeResolver resolvers} if a problem is detected.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: ResolverException.java,v 1.2 2000/12/06 17:47:29 vroth Exp $"
|
||||
*/
|
||||
public class ResolverException extends ASN1Exception {
|
||||
public ResolverException() {
|
||||
}
|
||||
|
||||
public ResolverException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
419
src/codec/asn1/RunLengthEncoder.java
Normal file
419
src/codec/asn1/RunLengthEncoder.java
Normal file
@@ -0,0 +1,419 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.asn1;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* This encoder makes one pass through the given ASN.1 type and computes the
|
||||
* length of the type encoding according to the DER (ITU-T Recommendation
|
||||
* X.690). The result is an array of integers with the length of the individual
|
||||
* non-optional and non-implicit type encodings in the reverse order of the
|
||||
* order in which the given type is traversed during actual encoding. This array
|
||||
* is used by the {@link DEREncoder DEREncoder} when encoding a type.
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: RunLengthEncoder.java,v 1.2 2000/12/06 17:47:29 vroth Exp $"
|
||||
*/
|
||||
public class RunLengthEncoder extends Object implements Encoder {
|
||||
/**
|
||||
* The number of slots by which the internal buffer is incremented if its
|
||||
* capacity is eexceeded.
|
||||
*/
|
||||
public static final int INCREMENT = 256;
|
||||
|
||||
private int[] stack_;
|
||||
private int tops_;
|
||||
|
||||
private int[] acc_;
|
||||
private int topa_;
|
||||
|
||||
/**
|
||||
* Creates an encoder.
|
||||
*/
|
||||
public RunLengthEncoder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method brings in the harvest of the encoding procedure. It returns
|
||||
* the individual lengths of the DER encodings of the types written to to
|
||||
* this encoder. The order of length fields is the reverse order of the pre
|
||||
* order parsing of the written types.
|
||||
* <p>
|
||||
*
|
||||
* If this method is called before a type has been encoded then an array of
|
||||
* zero length is returned. Only non-optional types are counted thus the
|
||||
* zero length array might be returned also when all encoded types were
|
||||
* declared optional.
|
||||
*
|
||||
* @return The lengths fields.
|
||||
*/
|
||||
public int[] getLengthFields() {
|
||||
if (tops_ == 0)
|
||||
return new int[0];
|
||||
|
||||
int[] res;
|
||||
|
||||
res = new int[tops_];
|
||||
System.arraycopy(stack_, 0, res, 0, tops_);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the length array of the given type.
|
||||
*/
|
||||
public void writeType(ASN1Type o) throws ASN1Exception {
|
||||
try {
|
||||
o.encode(this);
|
||||
} catch (IOException e) {
|
||||
throw new ASN1Exception("Caught IOException without I/O!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method computes the number of octets needed to encode the identifier
|
||||
* and length octets of the {@link ASN1Type ASN.1 type} with the given tag
|
||||
* and contents length. The length must not be negative else an exception is
|
||||
* thrown. Since this encoder is meant to work in conjunction with a
|
||||
* {@link DEREncoder DEREncoder} no indefinite length is supported.
|
||||
*
|
||||
* @return The number of octets required for encoding the identifier and
|
||||
* length octets.
|
||||
* @param tag
|
||||
* The ASN.1 tag.
|
||||
* @param len
|
||||
* The number of contents octets of the ASN.1 type with the
|
||||
* given tag and length.
|
||||
* @throws ASN1Exception
|
||||
* if the given length is negative.
|
||||
*/
|
||||
public int getHeaderLength(int tag, int len) throws ASN1Exception {
|
||||
int n;
|
||||
|
||||
if (len < 0)
|
||||
throw new ASN1Exception("Length is negative!");
|
||||
|
||||
n = 2;
|
||||
if (tag > 30)
|
||||
n = n + (significantBits(tag) + 6) / 7;
|
||||
|
||||
if (len > 127)
|
||||
n = n + (significantBits(len) + 7) / 8;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of significant bits in the given integer. There is
|
||||
* always at least one significant bit.
|
||||
*
|
||||
* @param n
|
||||
* The integer.
|
||||
* @return The number of significant bits in the given integer.
|
||||
*/
|
||||
protected int significantBits(int n) {
|
||||
int i;
|
||||
|
||||
if (n == 0)
|
||||
return 1;
|
||||
|
||||
i = 0;
|
||||
while (n > 255) {
|
||||
n = n >>> 8;
|
||||
i += 8;
|
||||
}
|
||||
while (n > 0) {
|
||||
n = n >>> 1;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
public void writeBoolean(ASN1Boolean t) throws ASN1Exception {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
push(t, 1);
|
||||
}
|
||||
|
||||
public void writeInteger(ASN1Integer t) throws ASN1Exception {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
int n;
|
||||
|
||||
n = t.getBigInteger().bitLength() / 8 + 1;
|
||||
push(t, n);
|
||||
}
|
||||
|
||||
public void writeBitString(ASN1BitString t) throws ASN1Exception {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
int n;
|
||||
|
||||
if (t.isZero())
|
||||
n = 1;
|
||||
else
|
||||
n = (t.bitCount() + 7) / 8 + 1;
|
||||
|
||||
push(t, n);
|
||||
}
|
||||
|
||||
public void writeOctetString(ASN1OctetString t) throws ASN1Exception {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
push(t, t.byteCount());
|
||||
}
|
||||
|
||||
public void writeNull(ASN1Null t) throws ASN1Exception {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
push(t, 0);
|
||||
}
|
||||
|
||||
public void writeObjectIdentifier(ASN1ObjectIdentifier t)
|
||||
throws ASN1Exception {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
int n;
|
||||
int i;
|
||||
int[] e;
|
||||
|
||||
e = t.getOID();
|
||||
if (e.length < 2)
|
||||
throw new ASN1Exception("OID must have at least 2 elements!");
|
||||
|
||||
for (n = 1, i = 2; i < e.length; i++)
|
||||
n = n + (significantBits(e[i]) + 6) / 7;
|
||||
|
||||
push(t, n);
|
||||
}
|
||||
|
||||
public void writeReal(ASN1Type t) {
|
||||
throw new UnsupportedOperationException("Real is not yet supported!");
|
||||
}
|
||||
|
||||
public void writeString(ASN1String t) throws ASN1Exception {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
push(t, t.convertedLength(t.getString()));
|
||||
}
|
||||
|
||||
public void writeCollection(ASN1Collection t) throws ASN1Exception {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
int n;
|
||||
int p;
|
||||
int i;
|
||||
ArrayList l;
|
||||
Collection c;
|
||||
|
||||
c = t.getCollection();
|
||||
if (c instanceof ArrayList)
|
||||
l = (ArrayList) c;
|
||||
else {
|
||||
l = new ArrayList(c.size());
|
||||
l.addAll(c);
|
||||
}
|
||||
try {
|
||||
for (p = sp(), i = l.size() - 1; i >= 0; i--)
|
||||
writeType((ASN1Type) l.get(i));
|
||||
|
||||
n = accumulate(p);
|
||||
push(t, n);
|
||||
} catch (ClassCastException e) {
|
||||
throw new ASN1Exception("Non-ASN.1 type in collection!");
|
||||
}
|
||||
}
|
||||
|
||||
public void writeCollectionOf(ASN1Collection t) throws ASN1Exception {
|
||||
writeCollection(t);
|
||||
}
|
||||
|
||||
public void writeTime(ASN1Time t) throws ASN1Exception {
|
||||
writeString(t);
|
||||
}
|
||||
|
||||
public void writeTaggedType(ASN1TaggedType t) throws ASN1Exception {
|
||||
if (t.isOptional())
|
||||
return;
|
||||
|
||||
int n;
|
||||
int p;
|
||||
|
||||
p = sp();
|
||||
writeType(t.getInnerType());
|
||||
n = accumulate(p);
|
||||
push(t, n);
|
||||
}
|
||||
|
||||
public void writeTypeIdentifier(ASN1Type t) {
|
||||
throw new UnsupportedOperationException(
|
||||
"TypeIdentifier is not yet supported!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the length array and prepares this encoder for a new run.
|
||||
*/
|
||||
protected void reset() {
|
||||
tops_ = 0;
|
||||
topa_ = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes another length integer onto the internal stacks. The value is
|
||||
* pushed both on the running stack as well as on the accumulator stack. The
|
||||
* stacks increase dynamically in size in chunks of
|
||||
* {@link #INCREMENT INCREMENT} integers and never shrink in capacity.
|
||||
*
|
||||
* @param t
|
||||
* The ASN.1 type.
|
||||
* @param n
|
||||
* The integer.
|
||||
*/
|
||||
protected void push(ASN1Type t, int n) throws ASN1Exception {
|
||||
if (stack_ == null) {
|
||||
stack_ = new int[INCREMENT];
|
||||
tops_ = 0;
|
||||
}
|
||||
if (tops_ == stack_.length) {
|
||||
int[] stack;
|
||||
|
||||
stack = new int[stack_.length + INCREMENT];
|
||||
System.arraycopy(stack_, 0, stack, 0, stack_.length);
|
||||
stack_ = stack;
|
||||
}
|
||||
if (acc_ == null) {
|
||||
acc_ = new int[INCREMENT];
|
||||
topa_ = 0;
|
||||
}
|
||||
if (topa_ == acc_.length) {
|
||||
int[] stack;
|
||||
|
||||
stack = new int[acc_.length + INCREMENT];
|
||||
System.arraycopy(acc_, 0, stack, 0, acc_.length);
|
||||
acc_ = stack;
|
||||
}
|
||||
if (t.isExplicit()) {
|
||||
stack_[tops_++] = n;
|
||||
acc_[topa_++] = n + getHeaderLength(t.getTag(), n);
|
||||
} else
|
||||
acc_[topa_++] = n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the accumulator stack pointer.
|
||||
*
|
||||
* @return The accumulator stack pointer.
|
||||
*/
|
||||
protected int sp() {
|
||||
return topa_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates all values on the accumulator stack from the given position
|
||||
* to the top of the stack and returns the result. All accumulated values
|
||||
* are popped off the stack.
|
||||
*
|
||||
* @param pos
|
||||
* The position to start from.
|
||||
* @throws IllegalStateException
|
||||
* if the given position is atop the top of the stack.
|
||||
*/
|
||||
protected int accumulate(int pos) {
|
||||
int n;
|
||||
int i;
|
||||
|
||||
if (pos > topa_)
|
||||
throw new IllegalStateException(
|
||||
"Internal error, bad stack pointer!");
|
||||
|
||||
for (n = 0, i = pos; i < topa_; i++)
|
||||
n = n + acc_[i];
|
||||
|
||||
topa_ = pos;
|
||||
return n;
|
||||
}
|
||||
}
|
||||
528
src/codec/pkcs8/PrivateKeyInfo.java
Normal file
528
src/codec/pkcs8/PrivateKeyInfo.java
Normal file
@@ -0,0 +1,528 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.pkcs8;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import codec.CorruptedCodeException;
|
||||
import codec.InconsistentStateException;
|
||||
import codec.asn1.ASN1Exception;
|
||||
import codec.asn1.ASN1Integer;
|
||||
import codec.asn1.ASN1ObjectIdentifier;
|
||||
import codec.asn1.ASN1OctetString;
|
||||
import codec.asn1.ASN1Sequence;
|
||||
import codec.asn1.ASN1Set;
|
||||
import codec.asn1.ASN1SetOf;
|
||||
import codec.asn1.ASN1TaggedType;
|
||||
import codec.asn1.ASN1Type;
|
||||
import codec.asn1.DERDecoder;
|
||||
import codec.asn1.DEREncoder;
|
||||
import codec.x501.Attribute;
|
||||
import codec.x509.AlgorithmIdentifier;
|
||||
|
||||
/**
|
||||
* This class represents a <code>PrivateKeyInfo</code> as defined in <a
|
||||
* href="http://www.rsa.com/rsalabs/pubs/PKCS/html/pkcs-8.html"> PKCS#8</a>.
|
||||
* The ASN.1 definition of this structure is
|
||||
* <p>
|
||||
* <blockquote>
|
||||
*
|
||||
* <pre>
|
||||
* PrivateKeyInfo ::= SEQUENCE (
|
||||
* version Version, -- 0 for version 1.2 Nov 93
|
||||
* privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
|
||||
* privateKey PrivateKey,
|
||||
* attributes [0] IMPLICIT Attributes OPTIONAL
|
||||
* }
|
||||
* Version ::= INTEGER
|
||||
* PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
|
||||
* PrivateKey ::= OCTET STRING
|
||||
* Attributes ::= SET OF Attribute
|
||||
* </pre>
|
||||
*
|
||||
* The following definitions are taken from the X501 standard:
|
||||
*
|
||||
* <pre>
|
||||
* Attribute ::= SEQUENCE {
|
||||
* type AttributeType
|
||||
* values SET OF AttributeValue
|
||||
* -- at least one value is required --
|
||||
* }
|
||||
* AttributeType ::= OBJECT IDENTIFIER
|
||||
* AttributeValue ::= ANY
|
||||
* </pre>
|
||||
*
|
||||
* </blockquote>
|
||||
*
|
||||
* @author Markus Tak
|
||||
* @author Volker Roth
|
||||
* @version "$Id: PrivateKeyInfo.java,v 1.3 2004/08/24 10:01:21 pebinger Exp $"
|
||||
*/
|
||||
public class PrivateKeyInfo extends ASN1Sequence {
|
||||
/**
|
||||
* The default version.
|
||||
*/
|
||||
public static final int VERSION = 0;
|
||||
|
||||
/**
|
||||
* Version 1.2 November 1993 identifier.
|
||||
*/
|
||||
public static final int VERSION_1_2 = 0;
|
||||
|
||||
/**
|
||||
* Version is the syntax version number, for compatibility with future
|
||||
* revisions of the <a
|
||||
* href="http://www.rsa.com/rsalabs/pubs/PKCS/html/pkcs-8.html" PKCS#8
|
||||
* Standard</a>. It shall be 0 for that version.
|
||||
*/
|
||||
protected ASN1Integer version_;
|
||||
|
||||
/**
|
||||
* The {@link ASN1ObjectIdentifier OID} of the private key algorithm used in
|
||||
* this structure.
|
||||
*/
|
||||
protected AlgorithmIdentifier algorithm_;
|
||||
|
||||
/**
|
||||
* Stores the <b>encoded</b> {@link PrivateKey private Key}. The
|
||||
* interpretation of the contents is defined in the registration of the
|
||||
* private-key algorithm. For an RSA private key, for example, the contents
|
||||
* are a DER encoding of a value of type RSAPrivateKey.
|
||||
*/
|
||||
transient private ASN1OctetString encodedKey_;
|
||||
|
||||
/**
|
||||
* Attributes are the extended information that is encrypted along with the
|
||||
* private-key information.
|
||||
*/
|
||||
protected ASN1Set attributes_;
|
||||
|
||||
/**
|
||||
* This constructor builds the data structure.
|
||||
*/
|
||||
public PrivateKeyInfo() {
|
||||
version_ = new ASN1Integer(VERSION);
|
||||
add(version_);
|
||||
|
||||
algorithm_ = new AlgorithmIdentifier();
|
||||
add(algorithm_);
|
||||
|
||||
encodedKey_ = new ASN1OctetString();
|
||||
add(encodedKey_);
|
||||
|
||||
attributes_ = new ASN1SetOf(Attribute.class);
|
||||
add(new ASN1TaggedType(0, attributes_, false, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given <b>pre encoded raw key</b>. The
|
||||
* encoded is embedded "as is", the key encoding can be either a
|
||||
* DER compliant one or a special encoding.
|
||||
*
|
||||
* Please note that the byte array returned by the <code>
|
||||
* getEncoded()</code>
|
||||
* method of the <code>Key</code> interface must not be passed to this
|
||||
* constructor because the bytes returned by this method do not contain a
|
||||
* raw key but a complete PrivateKeyInfo structure (as this one).
|
||||
*
|
||||
* @param aid
|
||||
* The AlgorithmIdentifier with the OID and parameters for
|
||||
* the raw algorithm that belongs to the given key.
|
||||
* @param key
|
||||
* The raw key that shall be wrapped in this instance.
|
||||
*/
|
||||
public PrivateKeyInfo(AlgorithmIdentifier aid, byte[] key) {
|
||||
version_ = new ASN1Integer(VERSION);
|
||||
add(version_);
|
||||
|
||||
algorithm_ = aid;
|
||||
add(algorithm_);
|
||||
|
||||
encodedKey_ = new ASN1OctetString(key);
|
||||
add(encodedKey_);
|
||||
|
||||
attributes_ = new ASN1Set();
|
||||
add(new ASN1TaggedType(0, attributes_, false, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given <b>ASN.1 raw key</b>. The given raw
|
||||
* key is <b>encoded using DER</b> before it is set up in this instance.
|
||||
* <p>
|
||||
*
|
||||
* @param aid
|
||||
* The AlgorithmIdentifier with the OID and parameters for
|
||||
* the raw algorithm that belongs to the given key.
|
||||
* @param key
|
||||
* The raw key that shall be wrapped in this instance.
|
||||
* @throws InconsistentStateException
|
||||
* if an exception is thrown while encoding the given key.
|
||||
* No such exception should ever happen.
|
||||
*/
|
||||
public PrivateKeyInfo(AlgorithmIdentifier aid, ASN1Type key) {
|
||||
ByteArrayOutputStream bos;
|
||||
DEREncoder enc;
|
||||
byte[] code;
|
||||
|
||||
version_ = new ASN1Integer(VERSION);
|
||||
add(version_);
|
||||
|
||||
algorithm_ = aid;
|
||||
add(algorithm_);
|
||||
|
||||
try {
|
||||
bos = new ByteArrayOutputStream();
|
||||
enc = new DEREncoder(bos);
|
||||
key.encode(enc);
|
||||
code = bos.toByteArray();
|
||||
enc.close();
|
||||
} catch (IOException e) {
|
||||
throw new InconsistentStateException("Caught IOException!");
|
||||
} catch (ASN1Exception e) {
|
||||
throw new InconsistentStateException("Caught ASN1Exception!");
|
||||
}
|
||||
encodedKey_ = new ASN1OctetString(code);
|
||||
add(encodedKey_);
|
||||
|
||||
attributes_ = new ASN1Set();
|
||||
add(new ASN1TaggedType(0, attributes_, false, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given private key.
|
||||
*
|
||||
* @param key
|
||||
* the actual private key as a java object
|
||||
* @throws NullPointerException
|
||||
* if the given key is <code>null</code>.
|
||||
*/
|
||||
public PrivateKeyInfo(PrivateKey key) throws InvalidKeyException {
|
||||
super(2);
|
||||
setPrivateKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link AlgorithmIdentifier AlgorithmIdentifier} of the
|
||||
* embedded key.
|
||||
*
|
||||
* @return The AlgorithmIdentifier.
|
||||
*/
|
||||
public AlgorithmIdentifier getAlgorithmIdentifier() {
|
||||
return algorithm_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the private key embedded in this structure.
|
||||
* <p>
|
||||
*
|
||||
* This method creates an PKCS8EncodedKeySpec of this instance and feeds it
|
||||
* into a key factory. In order to locate a suitable key factory, the
|
||||
* installed providers must define appropriate OID mappings.
|
||||
*
|
||||
* @return The private key.
|
||||
* @throws InconsistentStateException
|
||||
* if the key spec generated by this method is rejected by
|
||||
* the key factory that is used to generate the key.
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if there is no key factory registered for the algorithm
|
||||
* of the embedded key or no appropriate OID mapping is
|
||||
* defined by the installed providers.
|
||||
*/
|
||||
public PrivateKey getPrivateKey() throws NoSuchAlgorithmException {
|
||||
ByteArrayOutputStream bos;
|
||||
PKCS8EncodedKeySpec spec;
|
||||
DEREncoder enc;
|
||||
KeyFactory kf;
|
||||
String alg;
|
||||
|
||||
try {
|
||||
bos = new ByteArrayOutputStream();
|
||||
enc = new DEREncoder(bos);
|
||||
encode(enc);
|
||||
spec = new PKCS8EncodedKeySpec(bos.toByteArray());
|
||||
enc.close();
|
||||
|
||||
alg = algorithm_.getAlgorithmOID().toString();
|
||||
kf = KeyFactory.getInstance(alg);
|
||||
|
||||
return kf.generatePrivate(spec);
|
||||
} catch (ASN1Exception e) {
|
||||
throw new InconsistentStateException("Internal, encoding error!");
|
||||
} catch (IOException e) {
|
||||
throw new InconsistentStateException(
|
||||
"Internal, I/O exception caught!");
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw new InconsistentStateException(
|
||||
"Encoded key spec rejected by key factory!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this instance with the given private key.
|
||||
*
|
||||
* @param key
|
||||
* The private key from which this instance is initialized.
|
||||
* @throws InvalidKeyException
|
||||
* if the given key cannot be decoded properly.
|
||||
* @throws NullPointerException
|
||||
* if the given key is <code>null</code>.
|
||||
*/
|
||||
public void setPrivateKey(PrivateKey key) throws InvalidKeyException {
|
||||
if (key == null)
|
||||
throw new NullPointerException("Key is null!");
|
||||
|
||||
DERDecoder dec;
|
||||
|
||||
clear();
|
||||
|
||||
version_ = new ASN1Integer(VERSION);
|
||||
add(version_);
|
||||
|
||||
algorithm_ = new AlgorithmIdentifier();
|
||||
add(algorithm_);
|
||||
|
||||
encodedKey_ = new ASN1OctetString();
|
||||
add(encodedKey_);
|
||||
|
||||
attributes_ = new ASN1SetOf(Attribute.class);
|
||||
add(new ASN1TaggedType(0, attributes_, false, true));
|
||||
|
||||
try {
|
||||
dec = new DERDecoder(new ByteArrayInputStream(key.getEncoded()));
|
||||
|
||||
decode(dec);
|
||||
dec.close();
|
||||
} catch (IOException e) {
|
||||
throw new InvalidKeyException("Caught IOException!");
|
||||
} catch (ASN1Exception e) {
|
||||
throw new InvalidKeyException("Bad encoding!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the version number of this instance.
|
||||
*
|
||||
* @return The version number.
|
||||
*/
|
||||
public int getVersion() {
|
||||
return version_.getBigInteger().intValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the version number of this instance.
|
||||
*
|
||||
* @param version
|
||||
* The version number.
|
||||
*/
|
||||
public void setVersion(int version) {
|
||||
version_ = new ASN1Integer(version);
|
||||
set(0, version_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link AlgorithmIdentifier AlgorithmIdentifier} of this
|
||||
* instance. This algorithm identifier must match the raw key of this
|
||||
* instance.
|
||||
* <p>
|
||||
*
|
||||
* The given instance is set up in this structure. Side effects will occur
|
||||
* if it is modified subsequently.
|
||||
*
|
||||
* @param aid
|
||||
* The AlgorithmIdentifier.
|
||||
*/
|
||||
public void setAlgorithm(AlgorithmIdentifier aid) {
|
||||
if (aid == null)
|
||||
throw new NullPointerException("Algorithm identifier is null!");
|
||||
|
||||
set(1, aid);
|
||||
algorithm_ = aid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes and sets the given ASN.1 key structure as the raw key.
|
||||
*
|
||||
* @throws InconsistentStateException
|
||||
* if an internal error occurs while the key is encoded.
|
||||
* This should never happen.
|
||||
*/
|
||||
protected void setRawKey(ASN1Type key) {
|
||||
ByteArrayOutputStream bos;
|
||||
DEREncoder enc;
|
||||
|
||||
try {
|
||||
bos = new ByteArrayOutputStream();
|
||||
enc = new DEREncoder(bos);
|
||||
key.encode(enc);
|
||||
encodedKey_ = new ASN1OctetString(bos.toByteArray());
|
||||
enc.close();
|
||||
set(2, encodedKey_);
|
||||
} catch (ASN1Exception e) {
|
||||
throw new InconsistentStateException("Internal, encoding error!");
|
||||
} catch (IOException e) {
|
||||
throw new InconsistentStateException(
|
||||
"Internal, I/O exception caught!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable list view on the attributes.
|
||||
*
|
||||
* @return The attributes.
|
||||
*/
|
||||
public List getAttributes() {
|
||||
if (attributes_.isOptional()) {
|
||||
return null;
|
||||
}
|
||||
return Collections.unmodifiableList(attributes_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given attributes.
|
||||
*
|
||||
* @param attributes
|
||||
* The attributes.
|
||||
*/
|
||||
public void setAttributes(Collection attributes) {
|
||||
if (attributes == null) {
|
||||
throw new NullPointerException("Attributes instance is null!");
|
||||
}
|
||||
attributes_.clear();
|
||||
attributes_.addAll(attributes);
|
||||
attributes_.setOptional(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw key material. <b>The key material consists of an encoded
|
||||
* key structure.</b> ASN.1/DER is often used as the encoding. However,
|
||||
* this need not always be the case. Elliptic curve cryptosystems use
|
||||
* specific encodings.
|
||||
* <p>
|
||||
*
|
||||
* If the key encoding is ASN.1/DER then the raw key can be retrieved as an
|
||||
* ASN.1 type by means of the {@link #getDecodedRawKey getDecodedRawKey()}
|
||||
* method.
|
||||
* <p>
|
||||
*
|
||||
* The returned value is a copy. No side effects are caused by modifying it.
|
||||
*
|
||||
* @return The raw key bits as a byte array.
|
||||
*/
|
||||
public byte[] getRawKey() {
|
||||
return (byte[]) encodedKey_.getByteArray().clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ASN.1 type that represents the decoded raw key. Decoding is
|
||||
* done by means of ASN.1/DER. <b>Be careful, not all public keys are
|
||||
* encoded according to DER.</b> Elliptic curve cryptosystems use specific
|
||||
* encodings.
|
||||
*
|
||||
* @return The raw key decoded according to DER.
|
||||
*/
|
||||
public ASN1Type getDecodedRawKey() throws CorruptedCodeException {
|
||||
DERDecoder dec;
|
||||
ASN1Type raw;
|
||||
|
||||
try {
|
||||
dec = new DERDecoder(new ByteArrayInputStream(encodedKey_
|
||||
.getByteArray()));
|
||||
|
||||
raw = dec.readType();
|
||||
dec.close();
|
||||
|
||||
return raw;
|
||||
} catch (ASN1Exception e) {
|
||||
throw new CorruptedCodeException("Cannot decode raw key!");
|
||||
} catch (IOException e) {
|
||||
throw new InconsistentStateException(
|
||||
"Internal, I/O exception caught!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
621
src/codec/util/JCA.java
Normal file
621
src/codec/util/JCA.java
Normal file
@@ -0,0 +1,621 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.util;
|
||||
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A number of invariants must hold for the properties defined by the installed
|
||||
* providers such that this class can work properly:
|
||||
* <ul>
|
||||
* <li> Aliases must be mapped to standard JCA/JCE names whenever possible. All
|
||||
* Aliases for an engine must map to the same name.
|
||||
* <li> Two OID mappings with the same OID must map to the same name.
|
||||
* <li> The slashed form of signature names must be set up as an alias.
|
||||
* <li> Signature engines that do not have a corresponding cipher engine still
|
||||
* require a reverse OID mapping of the form Alg.Alias.Cipher.OID.<i>oid</i> =
|
||||
* <i>name</i>, where <i>name</i> is the cipher name component of a slashed
|
||||
* form alias for that signature engine.
|
||||
* </ul>
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: JCA.java,v 1.5 2004/08/11 14:33:49 flautens Exp $"
|
||||
*/
|
||||
public class JCA extends Object {
|
||||
/**
|
||||
* The digest/cipher name to signature algorithm name mapping.
|
||||
*/
|
||||
private static Map dc2s_ = new HashMap();
|
||||
|
||||
/**
|
||||
* The signature algorithm name to digest/cipher name mapping.
|
||||
*/
|
||||
private static Map s2dc_ = new HashMap();
|
||||
|
||||
/**
|
||||
* The root alias map. Each map entry consists of the lower case engine name
|
||||
* mapped to another map that holds the aliases for that engine.
|
||||
*/
|
||||
protected static Map aliases_ = initAliasLookup();
|
||||
|
||||
/**
|
||||
* Let no-one create an instance.
|
||||
*
|
||||
*/
|
||||
private JCA() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the properties of the installed providers and builds an optimized
|
||||
* alias lookup table. All entries of the form
|
||||
* <ol>
|
||||
* <li> "Alg.Alias."+<engine>+"."+<alias> =
|
||||
* <value>
|
||||
* <li> "Alg.Alias."+<engine>+".OID."+<oid> =
|
||||
* <value>
|
||||
* <li> "Alg.Alias."+<engine>+"."+<oid> =
|
||||
* <value>
|
||||
* </ol>
|
||||
* are transformed and stored in a hashmap which is used by this class in
|
||||
* order to do quick lookups of aliases and OID mappings. The stored entries
|
||||
* are of the form:
|
||||
* <ol>
|
||||
* <li> <engine>+"."+<alias> = <value>
|
||||
* <li> "oid."+<value> = <oid>
|
||||
* <li> "oid."+<oid> = <value>
|
||||
* </ol>
|
||||
* In case multiple providers define mappings for the same keys the mapping
|
||||
* of the first registered provider wins.
|
||||
*/
|
||||
static private Map initAliasLookup() {
|
||||
Enumeration e;
|
||||
Provider[] provider;
|
||||
String k; // key
|
||||
String v; // value
|
||||
String s; // string
|
||||
String p; // previous mapping
|
||||
Map map;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
map = new HashMap();
|
||||
provider = Security.getProviders();
|
||||
|
||||
/*
|
||||
* We start from the last provider and work our way to the first one
|
||||
* such that aliases of preferred providers overwrite entries of less
|
||||
* favoured providers.
|
||||
*/
|
||||
for (i = provider.length - 1; i >= 0; i--) {
|
||||
e = provider[i].propertyNames();
|
||||
|
||||
while (e.hasMoreElements()) {
|
||||
k = (String) e.nextElement();
|
||||
v = provider[i].getProperty(k);
|
||||
|
||||
if (!k.startsWith("Alg.Alias.")) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Truncate k to <engine>.<alias>
|
||||
*/
|
||||
k = k.substring(10).toLowerCase();
|
||||
j = k.indexOf('.');
|
||||
|
||||
if (j < 1) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Copy <engine> to s Truncate k to <alias>
|
||||
*/
|
||||
s = k.substring(0, j);
|
||||
k = k.substring(j + 1);
|
||||
|
||||
if (k.length() < 1) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* If <alias> starts with a digit then we assume it is an OID.
|
||||
* OIDs are uniquely defined, hence we ommit <engine> in the oid
|
||||
* mappings. But we also include the alias mapping for this oid.
|
||||
*/
|
||||
if (Character.isDigit(k.charAt(0))) {
|
||||
p = (String) map.get("oid." + k);
|
||||
|
||||
if (p != null && p.length() >= v.length()) {
|
||||
continue;
|
||||
}
|
||||
map.put("oid." + k, v);
|
||||
map.put(s + "." + k, v);
|
||||
}
|
||||
/*
|
||||
* If <alias> starts with the string "OID." then we found a
|
||||
* reverse mapping. In that case we swap <alias> and the value
|
||||
* of the mapping, and make an entry of the form "oid."+<value> =
|
||||
* <oid>
|
||||
*/
|
||||
else if (k.startsWith("oid.")) {
|
||||
k = k.substring(4);
|
||||
v = v.toLowerCase();
|
||||
|
||||
map.put("oid." + v, k);
|
||||
}
|
||||
/*
|
||||
* In all other cases we make an entry of the form <engine>+"."+<alias> =
|
||||
* <value> as is defined in the providers.
|
||||
*/
|
||||
else {
|
||||
map.put(s + "." + k, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
// System.out.println("MAP : "+map);
|
||||
return map;
|
||||
}
|
||||
|
||||
/*
|
||||
* static private void dump(Map map) { Iterator i; Map.Entry entry;
|
||||
*
|
||||
* for (i=map.entrySet().iterator(); i.hasNext();) { entry =
|
||||
* (Map.Entry)i.next(); System.out.println( entry.getKey()+" =
|
||||
* "+entry.getValue()); } }
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the JCA standard name for a given OID. The OID must be a string
|
||||
* of numbers separated by dots, and can be preceded by the prefix
|
||||
* "OID.". If the OID is not defined in a mapping of some
|
||||
* registered provider then <code>null</code> is returned.
|
||||
* <p>
|
||||
*
|
||||
* OID mappings are unambigous; no engine type is required for the mapping
|
||||
* and no engine type is returned as part of the result. The returned string
|
||||
* consists only of the name of the algorithm.
|
||||
*
|
||||
* @param oid
|
||||
* The string with the OID that shall be resolved.
|
||||
* @return The standard JCA engine name for the given OID or
|
||||
* <code>null</code> if no such OID is defined.
|
||||
* @throws NullPointerException
|
||||
* if the oid is <code>null</code>.
|
||||
*/
|
||||
public static String getName(String oid) {
|
||||
if (oid == null) {
|
||||
throw new NullPointerException("OID is null!");
|
||||
}
|
||||
if (oid.startsWith("OID.") || oid.startsWith("oid.")) {
|
||||
oid = oid.substring(4);
|
||||
}
|
||||
return (String) aliases_.get("oid." + oid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the given alias to the standard JCA name for the given engine
|
||||
* type. If no appropriate mapping is defined then <code>null</code> is
|
||||
* returned. If the given alias is actually an OID string and there is an
|
||||
* appropriate alias mapping defined for that OID by some provider then the
|
||||
* corresponding JCA name is returned.
|
||||
*
|
||||
* @param engine
|
||||
* The JCA engine type name.
|
||||
* @param alias
|
||||
* The alias to resolve for the given engine type.
|
||||
* @return The standard JCA name or <code>null</code> if no appropriate
|
||||
* mapping could be found.
|
||||
* @throws IllegalArgumentException
|
||||
* if the alias is an empty string.
|
||||
* @throws NullPointerException
|
||||
* if the alias or engine name is <code>null</code>.
|
||||
*/
|
||||
public static String resolveAlias(String engine, String alias) {
|
||||
if (alias == null || engine == null) {
|
||||
throw new NullPointerException("Engine or alias is null!");
|
||||
}
|
||||
if (alias.length() < 1) {
|
||||
throw new IllegalArgumentException("Zero-length alias!");
|
||||
}
|
||||
return (String) aliases_.get(engine.toLowerCase() + "."
|
||||
+ alias.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the OID of the given algorithm name. The given name must be the
|
||||
* JCA standard name of the algorithm and not an alias. Use
|
||||
* {@link #resolveAlias resolveAlias} to map aliases onto their standard
|
||||
* names.
|
||||
*
|
||||
* @param algorithm
|
||||
* The JCA standard name of the algorithm for which the OID
|
||||
* should be returned.
|
||||
* @return The OID or <code>null</code> if no appropriate mapping could be
|
||||
* found.
|
||||
* @throws NullPointerException
|
||||
* if engine or algorithm is <code>null</code>.
|
||||
*/
|
||||
public static String getOID(String algorithm) {
|
||||
if (algorithm == null) {
|
||||
throw new NullPointerException("Algorithm is null!");
|
||||
}
|
||||
if (algorithm.length() < 1) {
|
||||
throw new IllegalArgumentException("Algorithm name is empty!");
|
||||
}
|
||||
if (Character.isDigit(algorithm.charAt(0))) {
|
||||
return algorithm;
|
||||
}
|
||||
return (String) aliases_.get("oid." + algorithm.toLowerCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the OID of the given algorithm name. The given engine name is
|
||||
* taken as a hint if the given algorithm name is a non-standard name. In
|
||||
* that case one shot is given to alias resolving before a second attempt is
|
||||
* made to map the algorithm to an OID. Alias resolving is done by means of
|
||||
* the {@link #resolveAlias resolveAlias} method.
|
||||
*
|
||||
* @param algorithm
|
||||
* The JCA standard name of the algorithm for which the OID
|
||||
* should be returned.
|
||||
* @param engine
|
||||
* The engine name that is taken as a hint for alias
|
||||
* resolving if the algorithm name cannot be resolved in the
|
||||
* first attempt.
|
||||
* @return The OID or <code>null</code> if no appropriate mapping could be
|
||||
* found.
|
||||
* @throws NullPointerException
|
||||
* if engine or algorithm is <code>null</code>.
|
||||
*/
|
||||
public static String getOID(String algorithm, String engine) {
|
||||
String oid;
|
||||
|
||||
oid = getOID(algorithm);
|
||||
|
||||
if (oid != null) {
|
||||
return oid;
|
||||
}
|
||||
algorithm = resolveAlias(engine, algorithm);
|
||||
|
||||
if (algorithm == null) {
|
||||
return null;
|
||||
}
|
||||
return getOID(algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method maps a given digest algorithm OID and cipher algorithm OID
|
||||
* onto the standard name of the combined signature algorithm. For this to
|
||||
* work the aliases must be well defined such as described below:
|
||||
* <dl>
|
||||
* <dt> Digest Algorithm
|
||||
* <dd> Alg.Alias.MessageDigest.<i>oid</i><sub>1</sub> = <i>digestAlg</i>
|
||||
* <dt> Cipher Algorithm
|
||||
* <dd> Alg.Alias.Cipher.<i>oid</i><sub>2</sub> = <i>cipherAlg</i>
|
||||
* <dt> Signature Algorithm
|
||||
* <dd> Alg.Alias.Signature.<i>digestAlg</i>/<i>cipherAlg</i> =
|
||||
* <i>signatureAlg</i>
|
||||
* </dl>
|
||||
* The <i>oid</i> denotes the sequence of OID numbers separated by dots but
|
||||
* without a leading "OID.". In some cases, such as the DSA, there
|
||||
* is no cipher engine corresponding to <i>oid</i><sub>2</sub>. In this
|
||||
* case, <i>oid</i><sub>2</sub> must be mapped to the corresponding name
|
||||
* by other engine types, such as a KeyFactory.
|
||||
* <p>
|
||||
*
|
||||
* All found mappings are cached for future use, as well as the reverse
|
||||
* mapping, which is much more complicated to synthesise.
|
||||
*
|
||||
* @param doid
|
||||
* The string representation of the digest algorithm OID. The
|
||||
* OID must have a "OID." prefix.
|
||||
* @return The standard JCE name of the signature algorithm or
|
||||
* <code>null</code> if no mapping could be found.
|
||||
*/
|
||||
public static String getSignatureName(String doid, String coid) {
|
||||
String dn;
|
||||
String cn;
|
||||
String sn;
|
||||
String dc;
|
||||
|
||||
dn = getName(doid);
|
||||
cn = getName(coid);
|
||||
|
||||
if (dn == null || cn == null) {
|
||||
return null;
|
||||
}
|
||||
dc = dn + "/" + cn;
|
||||
|
||||
synchronized (dc2s_) {
|
||||
sn = (String) dc2s_.get(dc);
|
||||
|
||||
if (sn != null) {
|
||||
return sn;
|
||||
}
|
||||
}
|
||||
sn = resolveAlias("signature", dc);
|
||||
|
||||
if (sn != null) {
|
||||
synchronized (dc2s_) {
|
||||
cn = dc.toLowerCase();
|
||||
|
||||
if (!dc2s_.containsKey(cn)) {
|
||||
dc2s_.put(cn, sn);
|
||||
}
|
||||
}
|
||||
synchronized (s2dc_) {
|
||||
cn = sn.toLowerCase();
|
||||
|
||||
if (!s2dc_.containsKey(cn)) {
|
||||
s2dc_.put(cn, dc);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sn;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method maps the standard signature algorithm name to the
|
||||
* <i>digestAlg</i>/<i>cipherAlg</i> format. This format can be used to
|
||||
* retrieve the OID of the digest algorithm and cipher algorithm
|
||||
* respectively. For this to work the aliases must be well defined such as
|
||||
* described below:
|
||||
* <dl>
|
||||
* <dt> Signature Algorithm
|
||||
* <dd> Alg.Alias.Signature.<i>d</i>/<i>c</i> = <i>sigAlg</i> where
|
||||
* <i>d</i> denotes the digest algorithm and <i>c</i> the cipher
|
||||
* algorithm. <i>sigAlg</i> must be the name under which the algorithm
|
||||
* engine is published.
|
||||
* </dl>
|
||||
*
|
||||
* If <code>sigAlg</code> contains a "/" then we assume that the
|
||||
* given algorithm name is already of the desired form and return
|
||||
* <code>sigAlg</code>.
|
||||
*
|
||||
* @param sigAlg
|
||||
* The standard signature algorithm name.
|
||||
* @return The <i>digestAlg</i>/<i>cipherAlg</i> format of the given
|
||||
* signature algorithm name or <code>
|
||||
* null</code> if no suitable
|
||||
* mapping could be found.
|
||||
*/
|
||||
public static String getSlashedForm(String sigAlg) {
|
||||
String v;
|
||||
|
||||
if (sigAlg.indexOf("/") > 0) {
|
||||
return sigAlg;
|
||||
}
|
||||
sigAlg = sigAlg.toLowerCase();
|
||||
|
||||
synchronized (s2dc_) {
|
||||
v = (String) s2dc_.get(sigAlg);
|
||||
|
||||
if (v != null) {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
Iterator i;
|
||||
String k;
|
||||
int m;
|
||||
|
||||
for (i = aliases_.keySet().iterator(); i.hasNext();) {
|
||||
k = (String) i.next();
|
||||
|
||||
if (!k.startsWith("signature.")) {
|
||||
continue;
|
||||
}
|
||||
v = (String) aliases_.get(k);
|
||||
|
||||
if (!v.equalsIgnoreCase(sigAlg)) {
|
||||
continue;
|
||||
}
|
||||
k = k.substring(10);
|
||||
m = k.indexOf("/");
|
||||
|
||||
if (m < 0) {
|
||||
continue;
|
||||
}
|
||||
synchronized (s2dc_) {
|
||||
if (!s2dc_.containsKey(sigAlg)) {
|
||||
s2dc_.put(sigAlg, k);
|
||||
}
|
||||
}
|
||||
return k;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method maps the given standard signature algorithm name to the
|
||||
* string representation of the OID associated with the digest algorithm of
|
||||
* the given signature algorithm.
|
||||
*
|
||||
* @param sigAlg
|
||||
* The standard signature algorithm name.
|
||||
* @return The string representation of the OID associated with the digest
|
||||
* alorithm used for <code>sigAlg</code>.
|
||||
*/
|
||||
public static String getDigestOID(String sigAlg) {
|
||||
int n;
|
||||
String v;
|
||||
String h;
|
||||
String r;
|
||||
|
||||
v = getSlashedForm(sigAlg);
|
||||
|
||||
if (v == null) {
|
||||
return null;
|
||||
}
|
||||
n = v.indexOf("/");
|
||||
|
||||
if (n < 0) {
|
||||
return null;
|
||||
}
|
||||
h = v.substring(0, n);
|
||||
r = getOID(h);
|
||||
|
||||
if (r != null) {
|
||||
return r;
|
||||
}
|
||||
/*
|
||||
* We now try to "repair" the bad algorithm name if we find a fitting
|
||||
* alias instead.
|
||||
*/
|
||||
h = resolveAlias("MessageDigest", h);
|
||||
|
||||
if (h == null) {
|
||||
return null;
|
||||
}
|
||||
r = getOID(h);
|
||||
|
||||
if (r != null) {
|
||||
v = h + "/" + v.substring(n + 1);
|
||||
|
||||
synchronized (s2dc_) {
|
||||
s2dc_.put(sigAlg, v);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method maps the given standard signature algorithm name to the
|
||||
* string representation of the OID associated with the cipher algorithm of
|
||||
* the given signature algorithm.
|
||||
* <p>
|
||||
* This conversion is a bit tricky. In cases such as DSA, no corresponding
|
||||
* Cipher engine exists, since DSA is not designed to be used as a cipher.
|
||||
* In such cases, some provider needs to set up a bogus alias of the form:
|
||||
* <dl>
|
||||
* <dt> Signature Algorithm
|
||||
* <dd> Alg.Alias.Cipher.OID.<i>oid</i> = DSA
|
||||
* </dl>
|
||||
*
|
||||
* The <i>oid</i> denotes the sequence of OID numbers separated by dots but
|
||||
* without a leading "OID.".
|
||||
*
|
||||
* @param sigAlg
|
||||
* The standard signature algorithm name.
|
||||
* @return The string representation of the OID associated with the cipher
|
||||
* alorithm used for <code>sigAlg</code>.
|
||||
*/
|
||||
public static String getCipherOID(String sigAlg) {
|
||||
int n;
|
||||
String s;
|
||||
String v;
|
||||
String r;
|
||||
|
||||
v = getSlashedForm(sigAlg);
|
||||
|
||||
if (v == null) {
|
||||
return null;
|
||||
}
|
||||
n = v.indexOf("/");
|
||||
|
||||
if (n < 0) {
|
||||
return null;
|
||||
}
|
||||
s = v.substring(n + 1);
|
||||
r = getOID(s);
|
||||
|
||||
if (r != null) {
|
||||
return r;
|
||||
}
|
||||
/*
|
||||
* We now try to "repair" the bad algorithm name if we find a fitting
|
||||
* alias instead.
|
||||
*/
|
||||
s = resolveAlias("Signature", s);
|
||||
|
||||
if (s == null) {
|
||||
return null;
|
||||
}
|
||||
r = getOID(s);
|
||||
|
||||
if (r != null) {
|
||||
v = v.substring(0, n) + "/" + s;
|
||||
|
||||
synchronized (s2dc_) {
|
||||
s2dc_.put(sigAlg, v);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
}
|
||||
312
src/codec/x501/Attribute.java
Normal file
312
src/codec/x501/Attribute.java
Normal file
@@ -0,0 +1,312 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.x501;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import codec.asn1.ASN1Exception;
|
||||
import codec.asn1.ASN1Null;
|
||||
import codec.asn1.ASN1ObjectIdentifier;
|
||||
import codec.asn1.ASN1OpenType;
|
||||
import codec.asn1.ASN1RegisteredType;
|
||||
import codec.asn1.ASN1Sequence;
|
||||
import codec.asn1.ASN1Set;
|
||||
import codec.asn1.ASN1SetOf;
|
||||
import codec.asn1.ASN1Type;
|
||||
import codec.asn1.Decoder;
|
||||
import codec.asn1.DefinedByResolver;
|
||||
import codec.asn1.OIDRegistry;
|
||||
|
||||
/**
|
||||
* This class represents an <code>Attribute</code> as defined in X.501
|
||||
* standard. The ASN.1 definition of this structure is
|
||||
* <p>
|
||||
*
|
||||
* <pre>
|
||||
* Attribute ::= SEQUENCE {
|
||||
* type AttributeType,
|
||||
* values SET OF AttributeValue
|
||||
* }
|
||||
* AttributeType ::= ObjectIdentifier
|
||||
* AttributeValue ::= ANY
|
||||
* </pre>
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: Attribute.java,v 1.4 2007/08/30 08:45:05 pebinger Exp $"
|
||||
*/
|
||||
|
||||
public class Attribute extends ASN1Sequence implements ASN1RegisteredType {
|
||||
/**
|
||||
* The Object Identifier specifying the attribute type.
|
||||
*/
|
||||
protected ASN1ObjectIdentifier type_;
|
||||
|
||||
/**
|
||||
* The List of Attribute values.
|
||||
*/
|
||||
protected ASN1Set values_;
|
||||
|
||||
/**
|
||||
* Creates an instance ready for parsing. Any type of ASN.1 structure will
|
||||
* be accepted as the values of this attribute. An <code>ASN1OpenType</code>
|
||||
* is used for this.
|
||||
*/
|
||||
public Attribute() {
|
||||
super(2);
|
||||
|
||||
type_ = new ASN1ObjectIdentifier();
|
||||
values_ = new ASN1SetOf(ASN1OpenType.class);
|
||||
|
||||
add(type_);
|
||||
add(values_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance ready for parsing. The given
|
||||
* {@link OIDRegistry OIDRegistry} is used to resolve the attribute type. If
|
||||
* the attribute type cannot be resolved upon decoding then an exception is
|
||||
* thrown.
|
||||
*
|
||||
* @param registry
|
||||
* The <code>OIDRegistry</code> to use for resolving
|
||||
* attribute value types, or <code>null
|
||||
* </code> if the
|
||||
* global registry shall be used.
|
||||
*/
|
||||
public Attribute(OIDRegistry registry) {
|
||||
super(2);
|
||||
|
||||
if (registry == null) {
|
||||
registry = OIDRegistry.getGlobalOIDRegistry();
|
||||
}
|
||||
type_ = new ASN1ObjectIdentifier();
|
||||
values_ = new ASN1SetOf(new DefinedByResolver(registry, type_));
|
||||
|
||||
add(type_);
|
||||
add(values_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance that is initialized with the given OID and value.
|
||||
* <b>Note:</b> the given values are not cloned or copied, they are used
|
||||
* directly. Hence, the given types must not be modified after hereafter in
|
||||
* order to avoid side effects.
|
||||
* <p>
|
||||
*
|
||||
* The OID must not be <code>null</code>. The <code>
|
||||
* value</code> can be
|
||||
* <code>null</code> and is replaced by {@link ASN1Null ASN1Null} in that
|
||||
* case.
|
||||
*
|
||||
* @param oid
|
||||
* The OID that identifies the given value.
|
||||
* @param value
|
||||
* The ASN.1 type.
|
||||
*/
|
||||
public Attribute(ASN1ObjectIdentifier oid, ASN1Type value) {
|
||||
super(2);
|
||||
|
||||
if (oid == null) {
|
||||
throw new NullPointerException("Need an OID!");
|
||||
}
|
||||
if (value == null) {
|
||||
value = new ASN1Null();
|
||||
}
|
||||
type_ = oid;
|
||||
values_ = new ASN1Set(1);
|
||||
|
||||
values_.add(value);
|
||||
|
||||
add(oid);
|
||||
add(values_);
|
||||
}
|
||||
|
||||
/**
|
||||
* The arguments passed to this constructor are set up directly for parsing.
|
||||
* They are not cloned! The OID of the Attribute is the OID returned by the
|
||||
* registered type.
|
||||
*
|
||||
* @param value
|
||||
* The registered ASN.1 type.
|
||||
*/
|
||||
public Attribute(ASN1RegisteredType value) {
|
||||
super(2);
|
||||
|
||||
if (value == null) {
|
||||
throw new NullPointerException("Need a value!");
|
||||
}
|
||||
type_ = value.getOID();
|
||||
|
||||
if (type_ == null) {
|
||||
throw new NullPointerException("Value does not provide an OID!");
|
||||
}
|
||||
values_ = new ASN1Set(1);
|
||||
values_.add(value);
|
||||
|
||||
add(type_);
|
||||
add(values_);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the OID of this Attribute.
|
||||
*
|
||||
* @return The OID
|
||||
*/
|
||||
public ASN1ObjectIdentifier getOID() {
|
||||
return type_;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an unmodifiable view of the list of values of this
|
||||
* Attribute.
|
||||
*
|
||||
* @return The unmodifiable view of the list of attribute values.
|
||||
*/
|
||||
public List valueList() {
|
||||
return Collections.unmodifiableList(values_);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the number of values in this attribute.
|
||||
*
|
||||
* @return The number of values.
|
||||
*/
|
||||
public int valueCount() {
|
||||
return values_.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at the given position where position is between 0 and
|
||||
* <code>valueCount()-1</code>.
|
||||
*
|
||||
* @return The value at the given position.
|
||||
* @throws ArrayIndexOutOfBoundsException
|
||||
* if the given position is not within the bounds of the
|
||||
* list of attribute values.
|
||||
*/
|
||||
public ASN1Type valueAt(int index) {
|
||||
return (ASN1Type) values_.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes this instance. If the internal storage object of attributes is a
|
||||
* <code>ASN1SetOf</code> then that set is transformed into a
|
||||
* <code>ASN1Set</code>, and any <code>ASN1OpenType</code> instances
|
||||
* are stripped away. This makes a number of internal objects available for
|
||||
* garbage collection.
|
||||
* <p>
|
||||
*
|
||||
* Consequently, after decoding this instance contains a set with the pure
|
||||
* attribute values.
|
||||
*
|
||||
* @param dec
|
||||
* The decoder to use.
|
||||
*/
|
||||
public void decode(Decoder dec) throws IOException, ASN1Exception {
|
||||
super.decode(dec);
|
||||
|
||||
if (!(values_ instanceof ASN1SetOf)) {
|
||||
return;
|
||||
}
|
||||
ArrayList list;
|
||||
ASN1Type o;
|
||||
Iterator i;
|
||||
|
||||
try {
|
||||
list = new ArrayList(values_.size());
|
||||
|
||||
for (i = values_.iterator(); i.hasNext();) {
|
||||
o = (ASN1Type) i.next();
|
||||
|
||||
if (o instanceof ASN1OpenType) {
|
||||
o = ((ASN1OpenType) o).getInnerType();
|
||||
}
|
||||
list.add(o);
|
||||
}
|
||||
values_.clear();
|
||||
values_.addAll(list);
|
||||
} catch (ClassCastException e) {
|
||||
throw new ASN1Exception("Unexpected type in SET OF!");
|
||||
} catch (NullPointerException e) {
|
||||
throw new ASN1Exception("NULL in SET OF!");
|
||||
}
|
||||
}
|
||||
}
|
||||
558
src/codec/x509/AlgorithmIdentifier.java
Normal file
558
src/codec/x509/AlgorithmIdentifier.java
Normal file
@@ -0,0 +1,558 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.x509;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
|
||||
import codec.CorruptedCodeException;
|
||||
import codec.InconsistentStateException;
|
||||
import codec.asn1.ASN1;
|
||||
import codec.asn1.ASN1Exception;
|
||||
import codec.asn1.ASN1Null;
|
||||
import codec.asn1.ASN1ObjectIdentifier;
|
||||
import codec.asn1.ASN1Opaque;
|
||||
import codec.asn1.ASN1Sequence;
|
||||
import codec.asn1.ASN1Type;
|
||||
import codec.asn1.DEREncoder;
|
||||
import codec.pkcs8.PrivateKeyInfo;
|
||||
import codec.util.JCA;
|
||||
|
||||
/**
|
||||
* This class represents the ASN.1/DER value of the AlgorithmIdentifier defined
|
||||
* in Annex D to Recommendation X.509. This structure is extensively used for
|
||||
* instance in the PKCS standards of RSA Inc. The ASN.1 definition of this
|
||||
* structure is as given below:
|
||||
* <p>
|
||||
*
|
||||
* <pre>
|
||||
* AlgorithmIdentifier ::= SEQUENCE{
|
||||
* algorithm OBJECT IDENTIFIER,
|
||||
* parameters ANY DEFINED BY algorithm OPTIONAL
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* For this class to work properly, providers need to define the following
|
||||
* algorithm aliases for the {@link java.security.AlgorithmParameters
|
||||
* AlgorithmParameters} implementations they provide:
|
||||
* <ol>
|
||||
* <li> AlgorithmParameters.MyAlg = <i>class</i>
|
||||
* <li> Alg.Alias.AlgorithmParameters.1.2.3.4 = MyAlg
|
||||
* <li> Alg.Alias.AlgorithmParameters.OID.1.2.3.4 = MyAlg
|
||||
* </ol>
|
||||
* The first property defined the mapping of the JCE compliant standard name of
|
||||
* the algorithm to the implementing class. The second provider entry allows
|
||||
* mapping OID to those algorithm names while the third allows mapping those
|
||||
* names on corresponding OID.
|
||||
* <p>
|
||||
*
|
||||
* The alias definitions are used by this class in order to find an
|
||||
* AlgorithmParameters implementation for the OID embedded in the X.509
|
||||
* AlgorithmIdentifier structure, and to create the OID for a given
|
||||
* AlgorithmParameters instances. This is done by means of the {@link JCA JCA}
|
||||
* class, which operates on the engine and alias definitions of the installed
|
||||
* providers.
|
||||
* <p>
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* @author Volker Roth
|
||||
* @version "$Id: AlgorithmIdentifier.java,v 1.3 2004/08/13 11:37:03 pebinger
|
||||
* Exp $"
|
||||
* @see JCA
|
||||
*/
|
||||
public class AlgorithmIdentifier extends ASN1Sequence {
|
||||
|
||||
/**
|
||||
* The algorithm parameters of the algorithm specified by this algorithm
|
||||
* identifier.
|
||||
*/
|
||||
protected ASN1Opaque parameters_;
|
||||
|
||||
/**
|
||||
* The OID of the algorithm.
|
||||
*/
|
||||
protected ASN1ObjectIdentifier algorithm_;
|
||||
|
||||
/**
|
||||
* Creates an {@link AlgorithmIdentifier AlgorithmIdentifier} from the given
|
||||
* key. The key must be either a public key or a private key. No secret
|
||||
* (symmetric) keys are accepted.
|
||||
* <p>
|
||||
*
|
||||
* The keys encoding must be either a a {@link PrivateKeyInfo
|
||||
* PrivateKeyInfo} or a {@link SubjectPublicKeyInfo SubjectPublicKeyInfo}.
|
||||
*
|
||||
* @param key
|
||||
* The key from which the AlgorithmIdentifier shall be
|
||||
* extracted.
|
||||
* @throws IllegalArgumentException
|
||||
* if the given key is neither a PublicKey or a PrivateKey.
|
||||
* @throws CorruptedCodeException
|
||||
* if an exception was caught while decoding the key's
|
||||
* encoding.
|
||||
*/
|
||||
public static AlgorithmIdentifier createAlgorithmIdentifier(Key key)
|
||||
throws CorruptedCodeException {
|
||||
try {
|
||||
if (key instanceof PublicKey) {
|
||||
return new SubjectPublicKeyInfo((PublicKey) key)
|
||||
.getAlgorithmIdentifier();
|
||||
}
|
||||
|
||||
if (key instanceof PrivateKey) {
|
||||
return new PrivateKeyInfo((PrivateKey) key)
|
||||
.getAlgorithmIdentifier();
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Key type not supported!");
|
||||
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new CorruptedCodeException("Error decoding key!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method builds the tree of ASN.1 objects used for decoding this
|
||||
* structure.
|
||||
*/
|
||||
public AlgorithmIdentifier() {
|
||||
super(2);
|
||||
|
||||
algorithm_ = new ASN1ObjectIdentifier();
|
||||
parameters_ = new ASN1Opaque();
|
||||
parameters_.setOptional(true);
|
||||
add(algorithm_);
|
||||
add(parameters_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance initialized to the given algorithm. The algorithm
|
||||
* must not have parameters since this constructor does not take a parameter
|
||||
* argument.
|
||||
*
|
||||
* @param algorithm
|
||||
* The JCE standard algorithm name.
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the name cannot be resolved to an OID or the OID has a
|
||||
* bad syntax.
|
||||
* @throws NullPointerException
|
||||
* if <code>algorithm</code> is <code>null</code>.
|
||||
*/
|
||||
public AlgorithmIdentifier(String algorithm)
|
||||
throws NoSuchAlgorithmException {
|
||||
super(2);
|
||||
|
||||
if (algorithm == null)
|
||||
throw new NullPointerException("Need an algorithm name!");
|
||||
|
||||
String oid;
|
||||
|
||||
oid = JCA.getOID(algorithm);
|
||||
if (oid == null)
|
||||
throw new NoSuchAlgorithmException("No OID alias for algorithm "
|
||||
+ algorithm);
|
||||
|
||||
try {
|
||||
algorithm_ = new ASN1ObjectIdentifier(oid);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new NoSuchAlgorithmException("Bad OID alias for algorithm "
|
||||
+ algorithm);
|
||||
}
|
||||
parameters_ = new ASN1Opaque(ASN1.TAG_NULL, ASN1.CLASS_UNIVERSAL,
|
||||
new byte[0]);
|
||||
|
||||
add(algorithm_);
|
||||
add(parameters_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given OID and opaque algorithm parameter
|
||||
* representation. Both the given OID and the parameter encoding is cloned
|
||||
* or copied. No side effects occur if these arguments are modified after
|
||||
* completition of this constructor.
|
||||
*
|
||||
* @param oid
|
||||
* The algorithm object identifier.
|
||||
* @param b
|
||||
* The opaque DER encoding of the parameters for the
|
||||
* algorithm known under the given OID. If no parameters are
|
||||
* required then <code>null</code> might be passed. In that
|
||||
* case {@link ASN1Null ASN.1 NULL} is encoded.
|
||||
* @throws ASN1Exception
|
||||
* if the opaque representation does not contain a valid DER
|
||||
* header and contents octets.
|
||||
*/
|
||||
public AlgorithmIdentifier(ASN1ObjectIdentifier oid, byte[] b)
|
||||
throws ASN1Exception {
|
||||
super(2);
|
||||
|
||||
if (oid == null)
|
||||
throw new NullPointerException("Need an OID!");
|
||||
|
||||
algorithm_ = (ASN1ObjectIdentifier) oid.clone();
|
||||
|
||||
if (b == null) {
|
||||
/*
|
||||
* Usually, we'd define the following type as OPTIONAl. However, in
|
||||
* case no parameters are given a NULL is set instead.
|
||||
*/
|
||||
parameters_ = new ASN1Opaque(ASN1.TAG_NULL, ASN1.CLASS_UNIVERSAL,
|
||||
new byte[0]);
|
||||
} else
|
||||
parameters_ = new ASN1Opaque(b);
|
||||
|
||||
add(algorithm_);
|
||||
add(parameters_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that is initialized from the given
|
||||
* AlgorithmParameters instance. This method attempts to map the algorithm
|
||||
* name to an ASN.1 OID by calling {@link JCA#getOID(String) JCA#getOID}.
|
||||
* <p>
|
||||
*
|
||||
* @param alg
|
||||
* The name of the algorithm.
|
||||
* @param params
|
||||
* The AlgorithmParameters.
|
||||
* @throws NullPointerException
|
||||
* if <code>alg</code> is <code>null</code>.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given parameters have a bad encoding, or the OID
|
||||
* of the algorithm cannot be determined.
|
||||
*/
|
||||
public AlgorithmIdentifier(String alg, AlgorithmParameters params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
super(2);
|
||||
|
||||
String s;
|
||||
|
||||
if (alg == null)
|
||||
throw new NullPointerException("Algorithm is null!");
|
||||
|
||||
s = JCA.getOID(alg);
|
||||
|
||||
if (s == null) {
|
||||
s = "1.3.14.3.2.7"; // DES_CBC
|
||||
}
|
||||
|
||||
try {
|
||||
algorithm_ = new ASN1ObjectIdentifier(s);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"Bad OID alias for algorithm " + params.getAlgorithm());
|
||||
}
|
||||
|
||||
try {
|
||||
if (params == null) {
|
||||
parameters_ = new ASN1Opaque(ASN1.TAG_NULL,
|
||||
ASN1.CLASS_UNIVERSAL, new byte[0]);
|
||||
} else {
|
||||
parameters_ = new ASN1Opaque(params.getEncoded());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"Error during parameter encoding!");
|
||||
} catch (ASN1Exception e) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"Parameter encoding is not ASN.1/DER!");
|
||||
}
|
||||
|
||||
add(algorithm_);
|
||||
add(parameters_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given OID and parameters. The parameters are
|
||||
* encoded according to DER and stored by means of an opaque type. If the
|
||||
* given parameters are <code>null</code> then an ASN.1 NULL is encoded.
|
||||
*
|
||||
* @param oid
|
||||
* The OID to use.
|
||||
* @param params
|
||||
* The ASN.1 type of which the parameters consist.
|
||||
* @throws InconsistentStateException
|
||||
* if an internal error occurs; this should never happen.
|
||||
* @throws ASN1Exception
|
||||
* if the given parameters cannot be encoded. This should
|
||||
* rarely happen.
|
||||
*/
|
||||
public AlgorithmIdentifier(ASN1ObjectIdentifier oid, ASN1Type params)
|
||||
throws ASN1Exception {
|
||||
super(2);
|
||||
|
||||
DEREncoder enc;
|
||||
ByteArrayOutputStream bos;
|
||||
|
||||
if (oid == null)
|
||||
throw new NullPointerException("Need an OID!");
|
||||
|
||||
algorithm_ = (ASN1ObjectIdentifier) oid.clone();
|
||||
|
||||
try {
|
||||
if (params == null || (params instanceof ASN1Null))
|
||||
parameters_ = new ASN1Opaque(ASN1.TAG_NULL,
|
||||
ASN1.CLASS_UNIVERSAL, new byte[0]);
|
||||
else {
|
||||
bos = new ByteArrayOutputStream();
|
||||
enc = new DEREncoder(bos);
|
||||
params.encode(enc);
|
||||
|
||||
parameters_ = new ASN1Opaque(bos.toByteArray());
|
||||
bos.close();
|
||||
}
|
||||
add(algorithm_);
|
||||
add(parameters_);
|
||||
} catch (IOException e) {
|
||||
throw new InconsistentStateException(
|
||||
"Internal, caught IOException!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method locates a suitable {@link java.security.AlgorithmParameters
|
||||
* AlgorithmParameters} implementation if it is available from the JCE
|
||||
* compliant security providers that are installed locally.
|
||||
* <p>
|
||||
*
|
||||
* Such providers need to specify the following aliases for this to work:
|
||||
* <ul>
|
||||
* <li> AlgorithmParameters.MyAlg = <i>class</i>
|
||||
* <li> Alg.Alias.AlgorithmParameters.1.2.3.4 = MyAlg
|
||||
* </ul>
|
||||
* If you ever want to test a provider for compliance with the JCE and
|
||||
* <i>cleverness</i>, test it against the FhG-IGD PKCS package. If it
|
||||
* doesn't work then better demand fixes from the provider's vendor.
|
||||
* <p>
|
||||
*
|
||||
* This method may be called only if this instance is initialized properly
|
||||
* either by specifying AlgorithmParameters in a constructor or by parsing a
|
||||
* valid ASN.1/DER encoding.
|
||||
*
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if no matching AlgorithmParameters engine is found.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the parameters cannot be decoded properly.
|
||||
* @return The AlgorithmParameters or <code>null</code> if none are
|
||||
* enclosed in this structure.
|
||||
*/
|
||||
public AlgorithmParameters getParameters() throws NoSuchAlgorithmException,
|
||||
InvalidAlgorithmParameterException {
|
||||
AlgorithmParameters params;
|
||||
String s;
|
||||
|
||||
if (parameters_.isOptional())
|
||||
return null;
|
||||
|
||||
if (parameters_.getTag() == ASN1.TAG_NULL
|
||||
&& parameters_.getTagClass() == ASN1.CLASS_UNIVERSAL)
|
||||
return null;
|
||||
|
||||
/*
|
||||
* Since alias resolution is Provider-local and hardly any Provider does
|
||||
* it right and complete, we have to resolve aliases on our own.
|
||||
*/
|
||||
s = JCA.getName(algorithm_.toString());
|
||||
|
||||
if (s == null)
|
||||
throw new NoSuchAlgorithmException("Cannot resolve "
|
||||
+ algorithm_.toString());
|
||||
|
||||
/*
|
||||
* If we resolve cipher names then we have to remove the trailing
|
||||
* padding string, if present.
|
||||
*/
|
||||
int n;
|
||||
|
||||
n = s.indexOf("/");
|
||||
|
||||
if (n > 0)
|
||||
s = s.substring(0, n);
|
||||
|
||||
params = AlgorithmParameters.getInstance(s);
|
||||
|
||||
try {
|
||||
params.init(parameters_.getEncoded());
|
||||
} catch (IOException e) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"Caught IOException(\"" + e.getMessage() + "\")");
|
||||
} catch (ASN1Exception e) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"Caught ASN1Exception(\"" + e.getMessage() + "\")");
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the OID of the algorithm represented by this
|
||||
* AlgorithmIdentifier. The OID returned is the one used internally. Do not
|
||||
* modify the returned OID! Otherwise, side effects occur.
|
||||
*
|
||||
* @return The algorithm OID.
|
||||
*/
|
||||
public ASN1ObjectIdentifier getAlgorithmOID() {
|
||||
return algorithm_;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the JCE standard name of the algorithm specified in
|
||||
* this AlgorithmIdentifier. However, for this to work a proper alias for
|
||||
* the algorithm must be defined by some provider. See the general
|
||||
* documentation of this class for details on that.
|
||||
* <p>
|
||||
*
|
||||
* This method calls {@link JCA#getName(String) JCA.getName()} with the
|
||||
* string representation of this instance's
|
||||
* {@link #algorithm_ object identifier}.
|
||||
* <p>
|
||||
*
|
||||
* If you are {@link #getParameters retrieving the parameters} anyway then
|
||||
* avoid calling this method and call
|
||||
* {@link java.security.AlgorithmParameters#getAlgorithm getAlgorithm} on
|
||||
* the parameter instance instead.
|
||||
*/
|
||||
public String getAlgorithmName() {
|
||||
return JCA.getName(algorithm_.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this object.
|
||||
*
|
||||
* @return The string representation.
|
||||
*/
|
||||
public String toString() {
|
||||
String s;
|
||||
String t;
|
||||
|
||||
t = "X.509 AlgorithmIdentifier " + algorithm_.toString();
|
||||
s = getAlgorithmName();
|
||||
|
||||
if (s != null)
|
||||
return t + " (" + s + ")";
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns <code>true</code> if the given object is an
|
||||
* instance of this class or a subclass thereof and the algorithm OID of the
|
||||
* given object equals this object's algorithm OID.
|
||||
*
|
||||
* @return <code>true</code> if the given object equals this one.
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof AlgorithmIdentifier))
|
||||
return false;
|
||||
|
||||
return algorithm_.equals(((AlgorithmIdentifier) o).getAlgorithmOID());
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return algorithm_.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a clone. The clone is a deep copy of this instance except from
|
||||
* the constraints. Constraints are copied by reference.
|
||||
*
|
||||
* @return The clone.
|
||||
*/
|
||||
public Object clone() {
|
||||
AlgorithmIdentifier aid;
|
||||
|
||||
aid = (AlgorithmIdentifier) super.clone();
|
||||
aid.clear();
|
||||
aid.algorithm_ = (ASN1ObjectIdentifier) algorithm_.clone();
|
||||
aid.parameters_ = (ASN1Opaque) parameters_.clone();
|
||||
|
||||
aid.add(algorithm_);
|
||||
aid.add(parameters_);
|
||||
|
||||
return aid;
|
||||
}
|
||||
|
||||
}
|
||||
418
src/codec/x509/SubjectPublicKeyInfo.java
Normal file
418
src/codec/x509/SubjectPublicKeyInfo.java
Normal file
@@ -0,0 +1,418 @@
|
||||
/* ========================================================================
|
||||
*
|
||||
* This file is part of CODEC, which is a Java package for encoding
|
||||
* and decoding ASN.1 data structures.
|
||||
*
|
||||
* Author: Fraunhofer Institute for Computer Graphics Research IGD
|
||||
* Department A8: Security Technology
|
||||
* Fraunhoferstr. 5, 64283 Darmstadt, Germany
|
||||
*
|
||||
* Rights: Copyright (c) 2004 by Fraunhofer-Gesellschaft
|
||||
* zur Foerderung der angewandten Forschung e.V.
|
||||
* Hansastr. 27c, 80686 Munich, Germany.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The software package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2.1 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this software package; if not, write to the Free
|
||||
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301, USA or obtain a copy of the license at
|
||||
* http://www.fsf.org/licensing/licenses/lgpl.txt.
|
||||
*
|
||||
* ------------------------------------------------------------------------
|
||||
*
|
||||
* The CODEC library can solely be used and distributed according to
|
||||
* the terms and conditions of the GNU Lesser General Public License for
|
||||
* non-commercial research purposes and shall not be embedded in any
|
||||
* products or services of any user or of any third party and shall not
|
||||
* be linked with any products or services of any user or of any third
|
||||
* party that will be commercially exploited.
|
||||
*
|
||||
* The CODEC library has not been tested for the use or application
|
||||
* for a determined purpose. It is a developing version that can
|
||||
* possibly contain errors. Therefore, Fraunhofer-Gesellschaft zur
|
||||
* Foerderung der angewandten Forschung e.V. does not warrant that the
|
||||
* operation of the CODEC library will be uninterrupted or error-free.
|
||||
* Neither does Fraunhofer-Gesellschaft zur Foerderung der angewandten
|
||||
* Forschung e.V. warrant that the CODEC library will operate and
|
||||
* interact in an uninterrupted or error-free way together with the
|
||||
* computer program libraries of third parties which the CODEC library
|
||||
* accesses and which are distributed together with the CODEC library.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not warrant that the operation of the third parties's computer
|
||||
* program libraries themselves which the CODEC library accesses will
|
||||
* be uninterrupted or error-free.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* shall not be liable for any errors or direct, indirect, special,
|
||||
* incidental or consequential damages, including lost profits resulting
|
||||
* from the combination of the CODEC library with software of any user
|
||||
* or of any third party or resulting from the implementation of the
|
||||
* CODEC library in any products, systems or services of any user or
|
||||
* of any third party.
|
||||
*
|
||||
* Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
|
||||
* does not provide any warranty nor any liability that utilization of
|
||||
* the CODEC library will not interfere with third party intellectual
|
||||
* property rights or with any other protected third party rights or will
|
||||
* cause damage to third parties. Fraunhofer Gesellschaft zur Foerderung
|
||||
* der angewandten Forschung e.V. is currently not aware of any such
|
||||
* rights.
|
||||
*
|
||||
* The CODEC library is supplied without any accompanying services.
|
||||
*
|
||||
* ========================================================================
|
||||
*/
|
||||
package codec.x509;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
import codec.CorruptedCodeException;
|
||||
import codec.InconsistentStateException;
|
||||
import codec.asn1.ASN1BitString;
|
||||
import codec.asn1.ASN1Exception;
|
||||
import codec.asn1.ASN1Sequence;
|
||||
import codec.asn1.ASN1Type;
|
||||
import codec.asn1.DERDecoder;
|
||||
import codec.asn1.DEREncoder;
|
||||
|
||||
/**
|
||||
* Subject Public Key Info according to RFC2459. Consists of an AlgorithmID and
|
||||
* the corresponding public key <blockquote>
|
||||
*
|
||||
* <pre>
|
||||
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
* algorithm AlgorithmIdentifier,
|
||||
* subjectPublicKey BIT STRING
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <blockquote>
|
||||
*
|
||||
* Raw public key material embedded in this structure need not be ASN.1/DER
|
||||
* encoded. Some crypto systems such as elliptic curve systems use specific
|
||||
* encodings of keys. For this reason, keys can be retrieved by means of two
|
||||
* alternative ways:
|
||||
* <ul>
|
||||
* <li> Raw encoded keys, returned as byte arrays, and
|
||||
* <li> Raw decoded keys, returned as ASN.1 types.
|
||||
* </ul>
|
||||
* Only ASN.1/DER is supported as decoding method. Keys encoded in another code
|
||||
* must be decoded externally.
|
||||
*
|
||||
* Creation date: (18.08.99 15:23:09)
|
||||
*
|
||||
* @author Markus Tak
|
||||
* @version "$Id: SubjectPublicKeyInfo.java,v 1.3 2004/08/16 08:53:58 pebinger
|
||||
* Exp $"
|
||||
*/
|
||||
public class SubjectPublicKeyInfo extends ASN1Sequence {
|
||||
|
||||
private AlgorithmIdentifier algorithm_;
|
||||
|
||||
private ASN1BitString encodedKey_;
|
||||
|
||||
/**
|
||||
* Creates an instance that is ready for decoding.
|
||||
*/
|
||||
public SubjectPublicKeyInfo() {
|
||||
super(2);
|
||||
|
||||
algorithm_ = new AlgorithmIdentifier();
|
||||
add(algorithm_);
|
||||
|
||||
encodedKey_ = new ASN1BitString();
|
||||
add(encodedKey_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given {@link AlgorithmIdentifier
|
||||
* AlgorithmIdentifier} and encoded public key. The public key is wrapped
|
||||
* into an {@link ASN1BitString ASN1BitString} as required by the
|
||||
* specification of this structure. Hence, the encoded key is taken "as
|
||||
* is".
|
||||
* <p>
|
||||
*
|
||||
* The given arguments are put into this instance literally. The arguments
|
||||
* are not copied or cloned. Therefor side effects can occur when the given
|
||||
* arguments are modified after this constructor was called.
|
||||
*
|
||||
* @param aid
|
||||
* AlgorithmIdentifier of the public key algorithm
|
||||
* @param key
|
||||
* The encoded key material.
|
||||
* @throws NullPointerException
|
||||
* if either argument is <code>null</code>.
|
||||
*/
|
||||
public SubjectPublicKeyInfo(AlgorithmIdentifier aid, byte[] key) {
|
||||
super(2);
|
||||
|
||||
if (aid == null || key == null)
|
||||
throw new NullPointerException("Some arg is null!");
|
||||
|
||||
algorithm_ = aid;
|
||||
add(algorithm_);
|
||||
encodedKey_ = new ASN1BitString(key, 0);
|
||||
add(encodedKey_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with the given {@link AlgorithmIdentifier
|
||||
* AlgorithmIdentifier} and key. <b>The given key must be a raw key
|
||||
* structure represented by means of an ASN.1 structure. The key structure
|
||||
* is encoded into a bit string which is put into this instance.</b>
|
||||
*
|
||||
* @param aid
|
||||
* The AlgorithmIdentifier of the public key algorithm.
|
||||
* @param key
|
||||
* The public key as a ASN.1 data structure.
|
||||
*/
|
||||
public SubjectPublicKeyInfo(AlgorithmIdentifier aid, ASN1Type key) {
|
||||
super(2);
|
||||
|
||||
algorithm_ = aid;
|
||||
add(algorithm_);
|
||||
add(null);
|
||||
setRawKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance that is initialized from the given public key.
|
||||
*
|
||||
* @param key
|
||||
* The public key.
|
||||
* @throws InvalidKeyException
|
||||
* if the key cannot be decoded properly.
|
||||
* @throws NullPointerException
|
||||
* if the given key is <code>null</code>.
|
||||
*/
|
||||
public SubjectPublicKeyInfo(PublicKey key) throws InvalidKeyException {
|
||||
super(2);
|
||||
setPublicKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the public key embedded in this structure.
|
||||
* <p>
|
||||
*
|
||||
* This method creates an X509EncodedKeySpec of this instance and feeds it
|
||||
* into a key factory. In order to locate a suitable key factory, the
|
||||
* installed providers must define appropriate OID mappings.
|
||||
*
|
||||
* @return The public key.
|
||||
* @throws InconsistentStateException
|
||||
* if the key spec generated by this method is rejected by
|
||||
* the key factory that is used to generate the key.
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if there is no key factory registered for the algorithm
|
||||
* of the embedded key or no appropriate OID mapping is
|
||||
* defined by the installed providers.
|
||||
*/
|
||||
public PublicKey getPublicKey() throws NoSuchAlgorithmException {
|
||||
ByteArrayOutputStream bos;
|
||||
X509EncodedKeySpec spec;
|
||||
DEREncoder enc;
|
||||
KeyFactory kf;
|
||||
String alg;
|
||||
|
||||
try {
|
||||
bos = new ByteArrayOutputStream();
|
||||
enc = new DEREncoder(bos);
|
||||
encode(enc);
|
||||
spec = new X509EncodedKeySpec(bos.toByteArray());
|
||||
enc.close();
|
||||
|
||||
alg = algorithm_.getAlgorithmOID().toString();
|
||||
kf = KeyFactory.getInstance(alg);
|
||||
|
||||
return kf.generatePublic(spec);
|
||||
} catch (ASN1Exception e) {
|
||||
throw new InconsistentStateException("Internal, encoding error!");
|
||||
} catch (IOException e) {
|
||||
throw new InconsistentStateException(
|
||||
"Internal, I/O exception caught!");
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw new InconsistentStateException(
|
||||
"Encoded key spec rejected by key factory!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this instance with the given public key.
|
||||
*
|
||||
* @param key
|
||||
* The public key from which this instance is initialized.
|
||||
* @throws InvalidKeyException
|
||||
* if the given key cannot be decoded properly.
|
||||
* @throws NullPointerException
|
||||
* if the given key is <code>null</code>.
|
||||
*/
|
||||
public void setPublicKey(PublicKey key) throws InvalidKeyException {
|
||||
if (key == null)
|
||||
throw new NullPointerException("Key is null!");
|
||||
|
||||
DERDecoder dec;
|
||||
|
||||
clear();
|
||||
|
||||
algorithm_ = new AlgorithmIdentifier();
|
||||
add(algorithm_);
|
||||
encodedKey_ = new ASN1BitString();
|
||||
add(encodedKey_);
|
||||
|
||||
try {
|
||||
dec = new DERDecoder(new ByteArrayInputStream(key.getEncoded()));
|
||||
|
||||
decode(dec);
|
||||
dec.close();
|
||||
} catch (IOException e) {
|
||||
throw new InvalidKeyException("Caught IOException!");
|
||||
} catch (ASN1Exception e) {
|
||||
throw new InvalidKeyException("Bad encoding!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes and sets the given ASN.1 key structure as the raw key.
|
||||
*
|
||||
* @throws InconsistentStateException
|
||||
* if an internal error occurs while the key is encoded.
|
||||
* This should never happen.
|
||||
*/
|
||||
protected void setRawKey(ASN1Type key) {
|
||||
ByteArrayOutputStream bos;
|
||||
DEREncoder enc;
|
||||
|
||||
try {
|
||||
bos = new ByteArrayOutputStream();
|
||||
enc = new DEREncoder(bos);
|
||||
key.encode(enc);
|
||||
encodedKey_ = new ASN1BitString(bos.toByteArray(), 0);
|
||||
enc.close();
|
||||
set(1, encodedKey_);
|
||||
} catch (ASN1Exception e) {
|
||||
throw new InconsistentStateException("Internal, encoding error!");
|
||||
} catch (IOException e) {
|
||||
throw new InconsistentStateException(
|
||||
"Internal, I/O exception caught!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw key material. <b>The key material consists of an encoded
|
||||
* key structure.</b> ASN.1/DER is often used as the encoding. However,
|
||||
* this need not always be the case. Elliptic curve cryptosystems use
|
||||
* specific encodings.
|
||||
* <p>
|
||||
*
|
||||
* If the key encoding is ASN.1/DER then the raw key can be retrieved as an
|
||||
* ASN.1 type by means of the {@link #getDecodedRawKey getDecodedRawKey()}
|
||||
* method.
|
||||
*
|
||||
* @return The raw key bytes as a byte array.
|
||||
*/
|
||||
public byte[] getRawKey() {
|
||||
return encodedKey_.getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an ASN.1 type that represents the decoded raw key. Decoding is
|
||||
* done by means of ASN.1/DER. <b>Be careful, not all public keys are
|
||||
* encoded according to DER.</b> Elliptic curve cryptosystems use specific
|
||||
* encodings.
|
||||
*
|
||||
* @return The raw key decoded according to DER.
|
||||
*/
|
||||
public ASN1Type getDecodedRawKey() throws CorruptedCodeException {
|
||||
DERDecoder dec;
|
||||
ASN1Type raw;
|
||||
|
||||
try {
|
||||
dec = new DERDecoder(new ByteArrayInputStream(encodedKey_
|
||||
.getBytes()));
|
||||
|
||||
raw = dec.readType();
|
||||
dec.close();
|
||||
|
||||
return raw;
|
||||
} catch (ASN1Exception e) {
|
||||
throw new CorruptedCodeException("Cannot decode raw key!");
|
||||
} catch (IOException e) {
|
||||
throw new InconsistentStateException(
|
||||
"Internal, I/O exception caught!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link AlgorithmIdentifier AlgorithmIdentifier} of the public
|
||||
* key.
|
||||
*
|
||||
* @return The key algorithm's AlgorithmIdentifier.
|
||||
*/
|
||||
public AlgorithmIdentifier getAlgorithmIdentifier() {
|
||||
return algorithm_;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the AlgorithmIdentifier for this public key
|
||||
*
|
||||
* @param aid
|
||||
* AlgorithmIdentifier of this public key
|
||||
*/
|
||||
public void setAlgorithmIdentifier(AlgorithmIdentifier aid) {
|
||||
if (aid == null)
|
||||
throw new NullPointerException("Need an algorithm identifier!");
|
||||
|
||||
set(0, aid);
|
||||
algorithm_ = aid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated This method is no longer used.
|
||||
*/
|
||||
public ASN1Type getKeyStruct() throws CorruptedCodeException {
|
||||
return getKeyStruct(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param derDecode
|
||||
* <code>true</code> if the raw key shall be decoded.
|
||||
* @deprecated This method is no longer used.
|
||||
*/
|
||||
public ASN1Type getKeyStruct(boolean derDecode)
|
||||
throws CorruptedCodeException {
|
||||
if (derDecode)
|
||||
return getDecodedRawKey();
|
||||
|
||||
return encodedKey_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The key structure.
|
||||
* @deprecated This method is no longer used.
|
||||
*/
|
||||
public void setKeyStruct(ASN1Type key) {
|
||||
setRawKey(key);
|
||||
}
|
||||
|
||||
}
|
||||
555
src/de/flexiprovider/api/AsymmetricBlockCipher.java
Normal file
555
src/de/flexiprovider/api/AsymmetricBlockCipher.java
Normal file
@@ -0,0 +1,555 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2003 by The FlexiProvider Group,
|
||||
* Technische Universitaet Darmstadt
|
||||
*
|
||||
* For conditions of usage and distribution please refer to the
|
||||
* file COPYING in the root directory of this package.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.flexiprovider.api;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import de.flexiprovider.api.exceptions.BadPaddingException;
|
||||
import de.flexiprovider.api.exceptions.IllegalBlockSizeException;
|
||||
import de.flexiprovider.api.exceptions.InvalidAlgorithmParameterException;
|
||||
import de.flexiprovider.api.exceptions.InvalidKeyException;
|
||||
import de.flexiprovider.api.exceptions.InvalidParameterException;
|
||||
import de.flexiprovider.api.exceptions.ShortBufferException;
|
||||
import de.flexiprovider.api.keys.Key;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameterSpec;
|
||||
|
||||
/**
|
||||
* The AsymmetricBlockCipher class extends CipherSpi. An instance of this class
|
||||
* will be created by the Cipher.getInstance(String)-mechanism of the Cipher
|
||||
* class.<br>
|
||||
* NOTE: Some Ciphers are using Padding. OneAndZeroesPadding is used as default
|
||||
* padding. However padding can still be specified, but mode is not supported:
|
||||
* Example: Cipher.getInstance("SomeCipher/NONE/SomePadding"); If you try to
|
||||
* intantiate the cipher with something else than "NONE" as mode,
|
||||
* NoSuchAlgorithmException is thrown.
|
||||
*
|
||||
* @author Thomas Wahrenbruch
|
||||
* @author Hristo Indzhov
|
||||
*/
|
||||
public abstract class AsymmetricBlockCipher extends Cipher {
|
||||
|
||||
/**
|
||||
* ParameterSpec used with this cipher
|
||||
*/
|
||||
protected AlgorithmParameterSpec paramSpec;
|
||||
|
||||
/**
|
||||
* Internal buffer
|
||||
*/
|
||||
protected ByteArrayOutputStream buf;
|
||||
|
||||
/**
|
||||
* The maximum number of bytes the cipher can decrypt.
|
||||
*/
|
||||
protected int maxPlainTextSize;
|
||||
|
||||
/**
|
||||
* The maximum number of bytes the cipher can encrypt.
|
||||
*/
|
||||
protected int cipherTextSize;
|
||||
|
||||
/**
|
||||
* The AsymmetricBlockCipher() constructor
|
||||
*/
|
||||
public AsymmetricBlockCipher() {
|
||||
buf = new ByteArrayOutputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the block size (in bytes). Note: although the ciphers extending
|
||||
* this class are not block ciphers, the method was adopted to return the
|
||||
* maximal plaintext and ciphertext sizes for non hybrid ciphers. If the
|
||||
* cipher is hybrid, it returns 0.
|
||||
*
|
||||
* @return if the cipher is not a hybrid one the max plain/cipher text size
|
||||
* is returned, otherwise 0 is returned
|
||||
*/
|
||||
public final int getBlockSize() {
|
||||
return opMode == ENCRYPT_MODE ? maxPlainTextSize : cipherTextSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <tt>null</tt> since no initialization vector is used.
|
||||
*/
|
||||
public final byte[] getIV() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length in bytes that an output buffer would need to be in
|
||||
* order to hold the result of the next update or doFinal operation, given
|
||||
* the input length <tt>inLen</tt> (in bytes). This call takes into
|
||||
* account any unprocessed (buffered) data from a previous update call, and
|
||||
* padding. The actual output length of the next update() or doFinal() call
|
||||
* may be smaller than the length returned by this method.
|
||||
* <p>
|
||||
* If the input length plus the length of the buffered data exceeds the
|
||||
* maximum length, <tt>0</tt> is returned.
|
||||
*
|
||||
* @param inLen
|
||||
* the length of the input
|
||||
* @return the length of the ciphertext or <tt>0</tt> if the input is too
|
||||
* long.
|
||||
*/
|
||||
public final int getOutputSize(int inLen) {
|
||||
|
||||
int totalLen = inLen + buf.size();
|
||||
|
||||
int maxLen = getBlockSize();
|
||||
|
||||
if (totalLen > maxLen) {
|
||||
// the length of the input exceeds the maximal supported length
|
||||
return 0;
|
||||
}
|
||||
|
||||
return maxLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns the parameters used with this cipher.
|
||||
* <p>
|
||||
* The returned parameters may be the same that were used to initialize this
|
||||
* cipher, or may contain the default set of parameters or a set of randomly
|
||||
* generated parameters used by the underlying cipher implementation
|
||||
* (provided that the underlying cipher implementation uses a default set of
|
||||
* parameters or creates new parameters if it needs parameters but was not
|
||||
* initialized with any).
|
||||
* <p>
|
||||
*
|
||||
* @return the parameters used with this cipher, or null if this cipher does
|
||||
* not use any parameters.
|
||||
*/
|
||||
public final AlgorithmParameterSpec getParameters() {
|
||||
return paramSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the cipher for encryption by forwarding it to
|
||||
* initEncrypt(Key, FlexiSecureRandom).
|
||||
*
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters that cannot be derived
|
||||
* from the given key, the underlying cipher implementation is supposed to
|
||||
* generate the required parameters itself (using provider-specific default
|
||||
* or random values) if it is being initialized for encryption, and raise an
|
||||
* InvalidKeyException if it is being initialized for decryption. The
|
||||
* generated parameters can be retrieved using engineGetParameters or
|
||||
* engineGetIV (if the parameter is an IV).
|
||||
*
|
||||
* @param key
|
||||
* the encryption or decryption key.
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher.
|
||||
*/
|
||||
public final void initEncrypt(Key key) throws InvalidKeyException {
|
||||
try {
|
||||
initEncrypt(key, null, Registry.getSecureRandom());
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
throw new InvalidParameterException(
|
||||
"This cipher needs algorithm parameters for initialization (cannot be null).");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this cipher for encryption by forwarding it to
|
||||
* initEncrypt(Key, FlexiSecureRandom, AlgorithmParameterSpec).
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters that cannot be derived
|
||||
* from the given key, the underlying cipher implementation is supposed to
|
||||
* generate the required parameters itself (using provider-specific default
|
||||
* or random values) if it is being initialized for encryption, and raise an
|
||||
* InvalidKeyException if it is being initialized for decryption. The
|
||||
* generated parameters can be retrieved using engineGetParameters or
|
||||
* engineGetIV (if the parameter is an IV).
|
||||
*
|
||||
* @param key
|
||||
* the encryption or decryption key.
|
||||
* @param random
|
||||
* the source of randomness.
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher.
|
||||
*/
|
||||
public final void initEncrypt(Key key, SecureRandom random)
|
||||
throws InvalidKeyException {
|
||||
|
||||
try {
|
||||
initEncrypt(key, null, random);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new InvalidParameterException(
|
||||
"This cipher needs algorithm parameters for initialization (cannot be null).");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the cipher for encryption by forwarding it to
|
||||
* initEncrypt(Key, FlexiSecureRandom, AlgorithmParameterSpec).
|
||||
*
|
||||
* @param key
|
||||
* the encryption or decryption key.
|
||||
* @param params
|
||||
* the algorithm parameters.
|
||||
*
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given algortihm parameters are inappropriate for
|
||||
* this cipher, or if this cipher is being initialized for
|
||||
* decryption and requires algorithm parameters and params
|
||||
* is null.
|
||||
*/
|
||||
public final void initEncrypt(Key key, AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
initEncrypt(key, params, Registry.getSecureRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes the AsymmetricBlockCipher with a certain key for
|
||||
* data encryption.
|
||||
* <p>
|
||||
* If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from random.
|
||||
* <p>
|
||||
* Note that when a Cipher object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it
|
||||
* <p>
|
||||
*
|
||||
* @param key
|
||||
* the key which has to be used to encrypt data.
|
||||
* @param secureRandom
|
||||
* the source of randomness.
|
||||
* @param params
|
||||
* the algorithm parameters.
|
||||
*
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given algorithm parameters are inappropriate for
|
||||
* this cipher, or if this cipher is being initialized for
|
||||
* decryption and requires algorithm parameters and params
|
||||
* is null.
|
||||
*/
|
||||
public final void initEncrypt(Key key, AlgorithmParameterSpec params,
|
||||
SecureRandom secureRandom) throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException {
|
||||
opMode = ENCRYPT_MODE;
|
||||
initCipherEncrypt(key, params, secureRandom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the cipher for decryption by forwarding it to
|
||||
* {@link #initDecrypt(Key, AlgorithmParameterSpec)}.
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters that cannot be derived
|
||||
* from the given key, the underlying cipher implementation is supposed to
|
||||
* generate the required parameters itself (using provider-specific default
|
||||
* or random values) if it is being initialized for encryption, and raise an
|
||||
* InvalidKeyException if it is being initialized for decryption. The
|
||||
* generated parameters can be retrieved using engineGetParameters or
|
||||
* engineGetIV (if the parameter is an IV).
|
||||
*
|
||||
* @param key
|
||||
* the encryption or decryption key.
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher.
|
||||
*/
|
||||
public final void initDecrypt(Key key) throws InvalidKeyException {
|
||||
try {
|
||||
initDecrypt(key, null);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new InvalidParameterException(
|
||||
"This cipher needs algorithm parameters for initialization (cannot be null).");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes the AsymmetricBlockCipher with a certain key for
|
||||
* data decryption.
|
||||
* <p>
|
||||
* If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from random.
|
||||
* <p>
|
||||
* Note that when a Cipher object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it
|
||||
* <p>
|
||||
*
|
||||
* @param key
|
||||
* the key which has to be used to decrypt data.
|
||||
* @param params
|
||||
* the algorithm parameters.
|
||||
*
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given algorithm parameters are inappropriate for
|
||||
* this cipher, or if this cipher is being initialized for
|
||||
* decryption and requires algorithm parameters and params
|
||||
* is null.
|
||||
*/
|
||||
public final void initDecrypt(Key key, AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
opMode = DECRYPT_MODE;
|
||||
initCipherDecrypt(key, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Continue a multiple-part encryption or decryption operation. This method
|
||||
* just writes the input into an internal buffer.
|
||||
*
|
||||
* @param input
|
||||
* byte array containing the next part of the input
|
||||
* @param inOff
|
||||
* index in the array where the input starts
|
||||
* @param inLen
|
||||
* length of the input
|
||||
* @return a new buffer with the result (always empty)
|
||||
*/
|
||||
public final byte[] update(byte[] input, int inOff, int inLen) {
|
||||
if (inLen != 0) {
|
||||
buf.write(input, inOff, inLen);
|
||||
}
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Continue a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized), processing another data part.
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @param output
|
||||
* the output buffer
|
||||
* @param outOff
|
||||
* the offset where the result is stored
|
||||
* @return the length of the output (always 0)
|
||||
*/
|
||||
public final int update(byte[] input, int inOff, int inLen, byte[] output,
|
||||
int outOff) {
|
||||
update(input, inOff, inLen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized).
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @return a new buffer with the result
|
||||
* @throws IllegalBlockSizeException
|
||||
* if the plaintext or ciphertext size is too large.
|
||||
* @throws BadPaddingException
|
||||
* if the ciphertext is invalid.
|
||||
*/
|
||||
public final byte[] doFinal(byte[] input, int inOff, int inLen)
|
||||
throws IllegalBlockSizeException, BadPaddingException {
|
||||
|
||||
checkLength(inLen);
|
||||
update(input, inOff, inLen);
|
||||
byte[] mBytes = buf.toByteArray();
|
||||
buf.reset();
|
||||
|
||||
switch (opMode) {
|
||||
case ENCRYPT_MODE:
|
||||
return messageEncrypt(mBytes);
|
||||
|
||||
case DECRYPT_MODE:
|
||||
return messageDecrypt(mBytes);
|
||||
|
||||
default:
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized).
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @param output
|
||||
* the buffer for the result
|
||||
* @param outOff
|
||||
* the offset where the result is stored
|
||||
* @return the output length
|
||||
* @throws ShortBufferException
|
||||
* if the output buffer is too small to hold the result.
|
||||
* @throws IllegalBlockSizeException
|
||||
* if the plaintext or ciphertext size is too large.
|
||||
* @throws BadPaddingException
|
||||
* if the ciphertext is invalid.
|
||||
*/
|
||||
public final int doFinal(byte[] input, int inOff, int inLen, byte[] output,
|
||||
int outOff) throws ShortBufferException, IllegalBlockSizeException,
|
||||
BadPaddingException {
|
||||
|
||||
if (output.length < getOutputSize(inLen)) {
|
||||
throw new ShortBufferException("Output buffer too short.");
|
||||
}
|
||||
|
||||
byte[] out = doFinal(input, inOff, inLen);
|
||||
System.arraycopy(out, 0, output, outOff, out.length);
|
||||
return out.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since asymmetric block ciphers do not support modes, this method does
|
||||
* nothing.
|
||||
*
|
||||
* @param modeName
|
||||
* the cipher mode (unused)
|
||||
*/
|
||||
protected final void setMode(String modeName) {
|
||||
// empty
|
||||
}
|
||||
|
||||
/**
|
||||
* Since asymmetric block ciphers do not support padding, this method does
|
||||
* nothing.
|
||||
*
|
||||
* @param paddingName
|
||||
* the name of the padding scheme (not used)
|
||||
*/
|
||||
protected final void setPadding(String paddingName) {
|
||||
// empty
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the message length plus the length of the input length can be
|
||||
* en/decrypted. This method uses the specific values
|
||||
* {@link #maxPlainTextSize} and {@link #cipherTextSize} which are set by
|
||||
* the implementations. If the input length plus the length of the internal
|
||||
* buffer is greater than {@link #maxPlainTextSize} for encryption or not
|
||||
* equal to {@link #cipherTextSize} for decryption, an
|
||||
* {@link IllegalBlockSizeException} will be thrown.
|
||||
*
|
||||
* @param inLen
|
||||
* length of the input to check
|
||||
* @throws IllegalBlockSizeException
|
||||
* if the input length is invalid.
|
||||
*/
|
||||
protected void checkLength(int inLen) throws IllegalBlockSizeException {
|
||||
|
||||
int inLength = inLen + buf.size();
|
||||
|
||||
if (opMode == ENCRYPT_MODE) {
|
||||
if (inLength > maxPlainTextSize) {
|
||||
throw new IllegalBlockSizeException(
|
||||
"The length of the plaintext (" + inLength
|
||||
+ " bytes) is not supported by "
|
||||
+ "the cipher (max. " + maxPlainTextSize
|
||||
+ " bytes).");
|
||||
}
|
||||
} else if (opMode == DECRYPT_MODE) {
|
||||
if (inLength != cipherTextSize) {
|
||||
throw new IllegalBlockSizeException(
|
||||
"Illegal ciphertext length (expected " + cipherTextSize
|
||||
+ " bytes, was " + inLength + " bytes).");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the AsymmetricBlockCipher with a certain key for data
|
||||
* encryption.
|
||||
*
|
||||
* @param key
|
||||
* the key which has to be used to encrypt data
|
||||
* @param params
|
||||
* the algorithm parameters
|
||||
* @param sr
|
||||
* the source of randomness
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given parameters are inappropriate for
|
||||
* initializing this cipher.
|
||||
*/
|
||||
protected abstract void initCipherEncrypt(Key key,
|
||||
AlgorithmParameterSpec params, SecureRandom sr)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Initialize the AsymmetricBlockCipher with a certain key for data
|
||||
* encryption.
|
||||
*
|
||||
* @param key
|
||||
* the key which has to be used to decrypt data
|
||||
* @param params
|
||||
* the algorithm parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given parameters are inappropriate for
|
||||
* initializing this cipher.
|
||||
*/
|
||||
protected abstract void initCipherDecrypt(Key key,
|
||||
AlgorithmParameterSpec params) throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Encrypt the message stored in input. The method should also perform an
|
||||
* additional length check.
|
||||
*
|
||||
* @param input
|
||||
* the message to be encrypted (usually the message length is
|
||||
* less than or equal to maxPlainTextSize)
|
||||
* @return the encrypted message (it has length equal to maxCipherTextSize_)
|
||||
* @throws IllegalBlockSizeException
|
||||
* if the input is inappropriate for this cipher.
|
||||
* @throws BadPaddingException
|
||||
* if the input format is invalid.
|
||||
*/
|
||||
protected abstract byte[] messageEncrypt(byte[] input)
|
||||
throws IllegalBlockSizeException, BadPaddingException;
|
||||
|
||||
/**
|
||||
* Decrypt the ciphertext stored in input. The method should also perform an
|
||||
* additional length check.
|
||||
*
|
||||
* @param input
|
||||
* the ciphertext to be decrypted (the ciphertext length is
|
||||
* less than or equal to maxCipherTextSize)
|
||||
* @return the decrypted message
|
||||
* @throws IllegalBlockSizeException
|
||||
* if the input is inappropriate for this cipher.
|
||||
* @throws BadPaddingException
|
||||
* if the input format is invalid.
|
||||
*/
|
||||
protected abstract byte[] messageDecrypt(byte[] input)
|
||||
throws IllegalBlockSizeException, BadPaddingException;
|
||||
|
||||
}
|
||||
431
src/de/flexiprovider/api/AsymmetricHybridCipher.java
Normal file
431
src/de/flexiprovider/api/AsymmetricHybridCipher.java
Normal file
@@ -0,0 +1,431 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2003 by The FlexiProvider Group,
|
||||
* Technische Universitaet Darmstadt
|
||||
*
|
||||
* For conditions of usage and distribution please refer to the
|
||||
* file COPYING in the root directory of this package.
|
||||
*/
|
||||
package de.flexiprovider.api;
|
||||
|
||||
import de.flexiprovider.api.exceptions.BadPaddingException;
|
||||
import de.flexiprovider.api.exceptions.InvalidAlgorithmParameterException;
|
||||
import de.flexiprovider.api.exceptions.InvalidKeyException;
|
||||
import de.flexiprovider.api.exceptions.InvalidParameterException;
|
||||
import de.flexiprovider.api.exceptions.ShortBufferException;
|
||||
import de.flexiprovider.api.keys.Key;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameterSpec;
|
||||
|
||||
/**
|
||||
* The AsymmetricHybridCipher class extends CipherSpi. An instance of this class
|
||||
* will be created by the Cipher.getInstance(String)-mechanism of the Cipher
|
||||
* class.<br>
|
||||
* NOTE: Some Ciphers are using Padding. OneAndZeroesPadding is used as default
|
||||
* padding. However padding can still be specified, but mode is not supported:
|
||||
* Example: Cipher.getInstance("SomeCipher/NONE/SomePadding"); If you try to
|
||||
* intantiate the cipher with something else than "NONE" as mode,
|
||||
* NoSuchAlgorithmException is thrown.
|
||||
*
|
||||
* @author Thomas Wahrenbruch
|
||||
* @author Hristo Indzhov
|
||||
*/
|
||||
public abstract class AsymmetricHybridCipher extends Cipher {
|
||||
|
||||
/**
|
||||
* ParameterSpec used with this cipher
|
||||
*/
|
||||
protected AlgorithmParameterSpec paramSpec;
|
||||
|
||||
/**
|
||||
* Since asymmetric hybrid ciphers do not support modes, this method does
|
||||
* nothing.
|
||||
*
|
||||
* @param modeName
|
||||
* the cipher mode (unused)
|
||||
*/
|
||||
protected final void setMode(String modeName) {
|
||||
// empty
|
||||
}
|
||||
|
||||
/**
|
||||
* Since asymmetric hybrid ciphers do not support padding, this method does
|
||||
* nothing.
|
||||
*
|
||||
* @param paddingName
|
||||
* the name of the padding scheme (not used)
|
||||
*/
|
||||
protected final void setPadding(String paddingName) {
|
||||
// empty
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <tt>null</tt> since no initialization vector is used.
|
||||
*/
|
||||
public final byte[] getIV() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 0 since the implementing algorithms are not block ciphers
|
||||
*/
|
||||
public final int getBlockSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parameters used with this cipher.
|
||||
* <p>
|
||||
* The returned parameters may be the same that were used to initialize this
|
||||
* cipher, or may contain the default set of parameters or a set of randomly
|
||||
* generated parameters used by the underlying cipher implementation
|
||||
* (provided that the underlying cipher implementation uses a default set of
|
||||
* parameters or creates new parameters if it needs parameters but was not
|
||||
* initialized with any).
|
||||
*
|
||||
* @return the parameters used with this cipher, or <tt>null</tt> if this
|
||||
* cipher does not use any parameters.
|
||||
*/
|
||||
public final AlgorithmParameterSpec getParameters() {
|
||||
return paramSpec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length in bytes that an output buffer would need to be in
|
||||
* order to hold the result of the next update or doFinal operation, given
|
||||
* the input length <tt>inLen</tt> (in bytes). This call takes into
|
||||
* account any unprocessed (buffered) data from a previous update call, and
|
||||
* padding. The actual output length of the next update() or doFinal() call
|
||||
* may be smaller than the length returned by this method.
|
||||
*
|
||||
* @param inLen
|
||||
* the length of the input
|
||||
* @return the length of the output of the next <tt>update()</tt> or
|
||||
* <tt>doFinal()</tt> call
|
||||
*/
|
||||
public final int getOutputSize(int inLen) {
|
||||
return opMode == ENCRYPT_MODE ? encryptOutputSize(inLen)
|
||||
: decryptOutputSize(inLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the cipher for encryption by forwarding it to
|
||||
* {@link #initEncrypt(Key, AlgorithmParameterSpec, SecureRandom)}.
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters that cannot be derived
|
||||
* from the given key, the underlying cipher implementation is supposed to
|
||||
* generate the required parameters itself (using provider-specific default
|
||||
* or random values) if it is being initialized for encryption, and raise an
|
||||
* InvalidKeyException if it is being initialized for decryption. The
|
||||
* generated parameters can be retrieved using {@link #getParameters()}.
|
||||
*
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher.
|
||||
* @throws InvalidParameterException
|
||||
* if this cipher needs algorithm parameters for
|
||||
* initialization and cannot generate parameters itself.
|
||||
*/
|
||||
public final void initEncrypt(Key key) throws InvalidKeyException {
|
||||
try {
|
||||
initEncrypt(key, null, Registry.getSecureRandom());
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
throw new InvalidParameterException(
|
||||
"This cipher needs algorithm parameters for initialization (cannot be null).");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this cipher for encryption by forwarding it to
|
||||
* {@link #initEncrypt(Key, AlgorithmParameterSpec, SecureRandom)}.
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters that cannot be derived
|
||||
* from the given key, the underlying cipher implementation is supposed to
|
||||
* generate the required parameters itself (using provider-specific default
|
||||
* or random values) if it is being initialized for encryption, and raise an
|
||||
* InvalidKeyException if it is being initialized for decryption. The
|
||||
* generated parameters can be retrieved using {@link #getParameters()}.
|
||||
*
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @param random
|
||||
* the source of randomness
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher.
|
||||
* @throws InvalidParameterException
|
||||
* if this cipher needs algorithm parameters for
|
||||
* initialization and cannot generate parameters itself.
|
||||
*/
|
||||
public final void initEncrypt(Key key, SecureRandom random)
|
||||
throws InvalidKeyException {
|
||||
try {
|
||||
initEncrypt(key, null, random);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new InvalidParameterException(
|
||||
"This cipher needs algorithm parameters for initialization (cannot be null).");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the cipher for encryption by forwarding it to initEncrypt(Key,
|
||||
* FlexiSecureRandom, AlgorithmParameterSpec).
|
||||
*
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @param params
|
||||
* the algorithm parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given algorithm parameters are inappropriate for
|
||||
* this cipher, or if this cipher is initialized with
|
||||
* <tt>null</tt> parameters and cannot generate parameters
|
||||
* itself.
|
||||
*/
|
||||
public final void initEncrypt(Key key, AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
initEncrypt(key, params, Registry.getSecureRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the cipher with a certain key for data encryption.
|
||||
* <p>
|
||||
* If this cipher requires any random bytes (e.g., for parameter
|
||||
* generation), it will get them from <tt>random</tt>.
|
||||
* <p>
|
||||
* Note that when a Cipher object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it.
|
||||
*
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @param random
|
||||
* the source of randomness
|
||||
* @param params
|
||||
* the algorithm parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given algorithm parameters are inappropriate for
|
||||
* this cipher, or if this cipher is initialized with
|
||||
* <tt>null</tt> parameters and cannot generate parameters
|
||||
* itself.
|
||||
*/
|
||||
public final void initEncrypt(Key key, AlgorithmParameterSpec params,
|
||||
SecureRandom random) throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException {
|
||||
opMode = ENCRYPT_MODE;
|
||||
initCipherEncrypt(key, params, random);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the cipher for decryption by forwarding it to initDecrypt(Key,
|
||||
* FlexiSecureRandom).
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters that cannot be derived
|
||||
* from the given key, the underlying cipher implementation is supposed to
|
||||
* generate the required parameters itself (using provider-specific default
|
||||
* or random values) if it is being initialized for encryption, and raise an
|
||||
* InvalidKeyException if it is being initialized for decryption. The
|
||||
* generated parameters can be retrieved using {@link #getParameters()}.
|
||||
*
|
||||
* @param key
|
||||
* the decryption key
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher.
|
||||
*/
|
||||
public final void initDecrypt(Key key) throws InvalidKeyException {
|
||||
try {
|
||||
initDecrypt(key, null);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new InvalidParameterException(
|
||||
"This cipher needs algorithm parameters for initialization (cannot be null).");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the cipher with a certain key for data decryption.
|
||||
* <p>
|
||||
* If this cipher requires any random bytes (e.g., for parameter
|
||||
* generation), it will get them from <tt>random</tt>.
|
||||
* <p>
|
||||
* Note that when a Cipher object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it
|
||||
*
|
||||
* @param key
|
||||
* the decryption key
|
||||
* @param params
|
||||
* the algorithm parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given algorithm parameters are inappropriate for
|
||||
* this cipher, or if this cipher is initialized with
|
||||
* <tt>null</tt> parameters and cannot generate parameters
|
||||
* itself.
|
||||
*/
|
||||
public final void initDecrypt(Key key, AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
opMode = DECRYPT_MODE;
|
||||
initCipherDecrypt(key, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Continue a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized), processing another data part.
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @return a new buffer with the result (maybe an empty byte array)
|
||||
*/
|
||||
public abstract byte[] update(byte[] input, int inOff, int inLen);
|
||||
|
||||
/**
|
||||
* Continue a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized), processing another data part.
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @param output
|
||||
* the output buffer
|
||||
* @param outOff
|
||||
* the offset where the result is stored
|
||||
* @return the length of the output
|
||||
* @throws ShortBufferException
|
||||
* if the output buffer is too small to hold the result.
|
||||
*/
|
||||
public final int update(byte[] input, int inOff, int inLen, byte[] output,
|
||||
int outOff) throws ShortBufferException {
|
||||
if (output.length < getOutputSize(inLen)) {
|
||||
throw new ShortBufferException("output");
|
||||
}
|
||||
byte[] out = update(input, inOff, inLen);
|
||||
System.arraycopy(out, 0, output, outOff, out.length);
|
||||
return out.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized).
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @return a new buffer with the result
|
||||
* @throws BadPaddingException
|
||||
* if the ciphertext is invalid.
|
||||
*/
|
||||
public abstract byte[] doFinal(byte[] input, int inOff, int inLen)
|
||||
throws BadPaddingException;
|
||||
|
||||
/**
|
||||
* Finish a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized).
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @param output
|
||||
* the buffer for the result
|
||||
* @param outOff
|
||||
* the offset where the result is stored
|
||||
* @return the output length
|
||||
* @throws ShortBufferException
|
||||
* if the output buffer is too small to hold the result.
|
||||
* @throws BadPaddingException
|
||||
* if the ciphertext is invalid.
|
||||
*/
|
||||
public final int doFinal(byte[] input, int inOff, int inLen, byte[] output,
|
||||
int outOff) throws ShortBufferException, BadPaddingException {
|
||||
|
||||
if (output.length < getOutputSize(inLen)) {
|
||||
throw new ShortBufferException("Output buffer too short.");
|
||||
}
|
||||
byte[] out = doFinal(input, inOff, inLen);
|
||||
System.arraycopy(out, 0, output, outOff, out.length);
|
||||
return out.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the output size of an update() or doFinal() operation of a hybrid
|
||||
* asymmetric cipher in encryption mode when given input of the specified
|
||||
* length.
|
||||
*
|
||||
* @param inLen
|
||||
* the length of the input
|
||||
* @return the output size
|
||||
*/
|
||||
protected abstract int encryptOutputSize(int inLen);
|
||||
|
||||
/**
|
||||
* Compute the output size of an update() or doFinal() operation of a hybrid
|
||||
* asymmetric cipher in decryption mode when given input of the specified
|
||||
* length.
|
||||
*
|
||||
* @param inLen
|
||||
* the length of the input
|
||||
* @return the output size
|
||||
*/
|
||||
protected abstract int decryptOutputSize(int inLen);
|
||||
|
||||
/**
|
||||
* Initialize the AsymmetricHybridCipher with a certain key for data
|
||||
* encryption.
|
||||
*
|
||||
* @param key
|
||||
* the key which has to be used to encrypt data
|
||||
* @param params
|
||||
* the algorithm parameters
|
||||
* @param sr
|
||||
* the source of randomness
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given parameters are inappropriate for
|
||||
* initializing this cipher.
|
||||
*/
|
||||
protected abstract void initCipherEncrypt(Key key,
|
||||
AlgorithmParameterSpec params, SecureRandom sr)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Initialize the AsymmetricHybridCipher with a certain key for data
|
||||
* encryption.
|
||||
*
|
||||
* @param key
|
||||
* the key which has to be used to decrypt data
|
||||
* @param params
|
||||
* the algorithm parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given parameters are inappropriate for
|
||||
* initializing this cipher.
|
||||
*/
|
||||
protected abstract void initCipherDecrypt(Key key,
|
||||
AlgorithmParameterSpec params) throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException;
|
||||
|
||||
}
|
||||
897
src/de/flexiprovider/api/BlockCipher.java
Normal file
897
src/de/flexiprovider/api/BlockCipher.java
Normal file
@@ -0,0 +1,897 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2003 by The FlexiProvider Group,
|
||||
* Technische Universitaet Darmstadt
|
||||
*
|
||||
* For conditions of usage and distribution please refer to the
|
||||
* file COPYING in the root directory of this package.
|
||||
*
|
||||
*/
|
||||
package de.flexiprovider.api;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import de.flexiprovider.api.exceptions.BadPaddingException;
|
||||
import de.flexiprovider.api.exceptions.IllegalBlockSizeException;
|
||||
import de.flexiprovider.api.exceptions.InvalidAlgorithmParameterException;
|
||||
import de.flexiprovider.api.exceptions.InvalidKeyException;
|
||||
import de.flexiprovider.api.exceptions.InvalidParameterException;
|
||||
import de.flexiprovider.api.exceptions.NoSuchModeException;
|
||||
import de.flexiprovider.api.exceptions.NoSuchPaddingException;
|
||||
import de.flexiprovider.api.exceptions.ShortBufferException;
|
||||
import de.flexiprovider.api.keys.Key;
|
||||
import de.flexiprovider.api.keys.SecretKey;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameterSpec;
|
||||
import de.flexiprovider.common.mode.ModeParameterSpec;
|
||||
import de.flexiprovider.common.util.JavaSecureRandomWrapper;
|
||||
|
||||
/**
|
||||
* The BlockCipher class extends CipherSpi and handles the creation of
|
||||
* PaddingScheme, BlockCipher and Mode. An instance of this class will be
|
||||
* created by the Cipher.getInstance(String)-mechanism of the Cipher class.
|
||||
* <p>
|
||||
* BlockCipher ensures that a Mode and a PaddingsScheme are created, even if the
|
||||
* user has set no preferences. For this to work, BlockCipher requires version
|
||||
* 1.3 of the mode class that can handle a getInstance()-call without arguments
|
||||
* to return a default Mode or Padding.
|
||||
* <p>
|
||||
* BlockCipher will acknowledge only <b>one</b> call of engineSetMode() and
|
||||
* engineSetPadding() to ensure that these settings aren't changed while
|
||||
* encrypting.
|
||||
*
|
||||
* @author Christoph Sesterhenn, Christoph Ender
|
||||
* @author Ralf-Philipp Weinmann
|
||||
* @author Martin D<>ring, Johannes M<>ller
|
||||
*/
|
||||
public abstract class BlockCipher extends Cipher {
|
||||
|
||||
/**
|
||||
* The reference to the mode class.
|
||||
*/
|
||||
private Mode mode;
|
||||
|
||||
/**
|
||||
* The reference to the padding scheme.
|
||||
*/
|
||||
private PaddingScheme paddingScheme;
|
||||
|
||||
/**
|
||||
* AlgorithmParameterSpec
|
||||
*/
|
||||
private AlgorithmParameterSpec paramSpec;
|
||||
|
||||
/**
|
||||
* This buffer holds the outsize left by an update operation
|
||||
*/
|
||||
private byte[] buffer = null;
|
||||
|
||||
/**
|
||||
* the block size of the mode
|
||||
*/
|
||||
private int modeBlockSize;
|
||||
|
||||
/**
|
||||
* Used to check if an initialization method has been called.
|
||||
*/
|
||||
private boolean initialized = false;
|
||||
|
||||
/**
|
||||
* the source of randomness, if necessary
|
||||
*/
|
||||
protected SecureRandom random;
|
||||
|
||||
// ****************************************************
|
||||
// JCA adapter methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* Initialize this cipher object with proper key and algorithm parameters,
|
||||
* and some random seed. Before a cipher object is ready for data
|
||||
* processing, it has to be initialized according to the desired
|
||||
* cryptographic operation, which is specified by the opmode parameter
|
||||
* (either ENCRYPT_MODE or DECCRYPT_MODE). e.g.
|
||||
* cipher_obj.init(Cipher.ENCRYPT_MODE, key, alg_params, random_seed); The
|
||||
* Cipher init will call the proper CipherSpi engineInit method. Note: If
|
||||
* the Mode needs an initialization vector, a try to retrieve it from the
|
||||
* AlgorithmParametersSpec is made.
|
||||
*
|
||||
* @param opmode
|
||||
* the operation mode for which this cipher is used
|
||||
* (ENCRYPT_MODE or DECRYPT_MODE)
|
||||
* @param key
|
||||
* the key
|
||||
* @param paramSpec
|
||||
* the algorithm parameters
|
||||
* @param javaRand
|
||||
* the random seed
|
||||
* @throws java.security.InvalidKeyException
|
||||
* if the key is inappropriate for initializing this block
|
||||
* cipher.
|
||||
* @throws java.security.InvalidAlgorithmParameterException
|
||||
* if the parameters are inappropriate for initializing this
|
||||
* block cipher.
|
||||
*/
|
||||
protected final void engineInit(int opmode, java.security.Key key,
|
||||
java.security.spec.AlgorithmParameterSpec paramSpec,
|
||||
java.security.SecureRandom javaRand)
|
||||
throws java.security.InvalidKeyException,
|
||||
java.security.InvalidAlgorithmParameterException {
|
||||
|
||||
random = new JavaSecureRandomWrapper(javaRand);
|
||||
initModeAndPadding();
|
||||
opMode = opmode;
|
||||
|
||||
buffer = new byte[0];
|
||||
ModeParameterSpec modeParams;
|
||||
AlgorithmParameterSpec cipherParams;
|
||||
|
||||
if (paramSpec == null) {
|
||||
modeParams = null;
|
||||
cipherParams = null;
|
||||
} else if (paramSpec instanceof javax.crypto.spec.IvParameterSpec) {
|
||||
modeParams = new ModeParameterSpec(
|
||||
(javax.crypto.spec.IvParameterSpec) paramSpec);
|
||||
cipherParams = null;
|
||||
|
||||
} else if (paramSpec instanceof ModeParameterSpec) {
|
||||
modeParams = (ModeParameterSpec) paramSpec;
|
||||
cipherParams = null;
|
||||
|
||||
} else {
|
||||
if (!(paramSpec instanceof AlgorithmParameterSpec)) {
|
||||
throw new java.security.InvalidAlgorithmParameterException(
|
||||
"unsupported type");
|
||||
}
|
||||
cipherParams = (AlgorithmParameterSpec) paramSpec;
|
||||
|
||||
byte[] iv;
|
||||
Method getIV;
|
||||
try {
|
||||
getIV = cipherParams.getClass().getMethod("getIV", null);
|
||||
iv = (byte[]) getIV.invoke(cipherParams, null);
|
||||
} catch (Exception ex) {
|
||||
// if no getIV() method is found, iv remains null
|
||||
iv = null;
|
||||
}
|
||||
|
||||
if (iv == null) {
|
||||
modeParams = null;
|
||||
} else {
|
||||
modeParams = new ModeParameterSpec(iv);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(key instanceof SecretKey)) {
|
||||
throw new java.security.InvalidKeyException("unsupported type");
|
||||
}
|
||||
|
||||
if (opmode == ENCRYPT_MODE) {
|
||||
mode.initEncrypt((SecretKey) key, modeParams, cipherParams);
|
||||
} else if (opmode == DECRYPT_MODE) {
|
||||
mode.initDecrypt((SecretKey) key, modeParams, cipherParams);
|
||||
}
|
||||
modeBlockSize = mode.blockSize;
|
||||
paddingScheme.setBlockSize(modeBlockSize);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// FlexiAPI methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* Set the mode of this cipher. The mode can only be set once.
|
||||
*
|
||||
* @param modeName
|
||||
* the cipher mode
|
||||
* @throws NoSuchModeException
|
||||
* if neither the mode with the given name nor the default
|
||||
* mode can be found
|
||||
*/
|
||||
public final void setMode(String modeName) throws NoSuchModeException {
|
||||
if (mode != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((modeName == null) || (modeName == "")) {
|
||||
mode = Registry.getMode();
|
||||
} else {
|
||||
mode = Registry.getMode(modeName);
|
||||
}
|
||||
mode.setBlockCipher(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the padding scheme of this cipher. The padding scheme can only be set
|
||||
* once.
|
||||
*
|
||||
* @param paddingName
|
||||
* the padding scheme
|
||||
* @throws NoSuchPaddingException
|
||||
* if the requested padding scheme cannot be found.
|
||||
*/
|
||||
public final void setPadding(String paddingName)
|
||||
throws NoSuchPaddingException {
|
||||
if (paddingScheme != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (paddingName == null || paddingName.equals("")) {
|
||||
paddingScheme = Registry.getPaddingScheme();
|
||||
} else {
|
||||
paddingScheme = Registry.getPaddingScheme(paddingName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the initialization vector. This is useful in the context of
|
||||
* password-based encryption or decryption, where the IV is derived from a
|
||||
* user-provided passphrase.
|
||||
*
|
||||
* @return the initialization vector in a new buffer, or <tt>null</tt> if
|
||||
* the underlying algorithm does not use an IV, or if the IV has not
|
||||
* yet been set.
|
||||
*/
|
||||
public final byte[] getIV() {
|
||||
return initialized ? mode.iv : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the blocksize the algorithm uses. This method will usually be
|
||||
* called by the mode.
|
||||
*
|
||||
* @return the blocksize of the cipher
|
||||
*/
|
||||
protected abstract int getCipherBlockSize();
|
||||
|
||||
/**
|
||||
* @return the block size of the used mode, or -1 if the cipher has not been
|
||||
* initialized.
|
||||
*/
|
||||
public final int getBlockSize() {
|
||||
return initialized ? modeBlockSize : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length in bytes that an output buffer would need to be in
|
||||
* order to hold the result of the next update or doFinal operation, given
|
||||
* the input length inputLen (in bytes).
|
||||
* <p>
|
||||
* This call takes into account any unprocessed (buffered) data from a
|
||||
* previous update call, and padding.
|
||||
* <p>
|
||||
* The actual output length of the next update or doFinal call may be
|
||||
* smaller than the length returned by this method.
|
||||
*
|
||||
* @param inLen
|
||||
* the input length (in bytes)
|
||||
* @return the required output buffer size (in bytes)
|
||||
*/
|
||||
public final int getOutputSize(int inLen) {
|
||||
if (!initialized) {
|
||||
return -1;
|
||||
}
|
||||
final int newInLen = inLen + (buffer == null ? 0 : buffer.length);
|
||||
return newInLen + paddingScheme.padLength(newInLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the parameters used with this cipher.
|
||||
* <p>
|
||||
* The returned parameters may be the same that were used to initialize this
|
||||
* cipher, or may contain the default set of parameters or a set of randomly
|
||||
* generated parameters used by the underlying cipher implementation
|
||||
* (provided that the underlying cipher implementation uses a default set of
|
||||
* parameters or creates new parameters if it needs parameters but was not
|
||||
* initialized with any).
|
||||
*
|
||||
* @return the parameters used with this cipher, or null if this cipher does
|
||||
* not use any parameters.
|
||||
*/
|
||||
public final AlgorithmParameterSpec getParameters() {
|
||||
return initialized ? paramSpec : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this cipher with a key and a source of randomness for
|
||||
* encryption.
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters that cannot be derived
|
||||
* from the given key, the underlying cipher implementation is supposed to
|
||||
* generate the required parameters itself (using provider-specific default
|
||||
* or random values) if it is being initialized for encryption, and raise an
|
||||
* InvalidKeyException if it is being initialized for decryption. The
|
||||
* generated parameters can be retrieved using engineGetParameters or
|
||||
* engineGetIV (if the parameter is an IV).
|
||||
* <p>
|
||||
* If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from random.
|
||||
* <p>
|
||||
* Note that when a {@link BlockCipher} object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it
|
||||
*
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher
|
||||
* @throws InvalidParameterException
|
||||
* if this block cipher requires parameters for
|
||||
* initialization and cannot generate parameters itself.
|
||||
*/
|
||||
public final void initEncrypt(Key key) throws InvalidKeyException,
|
||||
InvalidParameterException {
|
||||
initEncrypt(key, Registry.getSecureRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this cipher with a key and a source of randomness for
|
||||
* encryption.
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters that cannot be derived
|
||||
* from the given key, the underlying cipher implementation is supposed to
|
||||
* generate the required parameters itself (using provider-specific default
|
||||
* or random values) if it is being initialized for encryption, and raise an
|
||||
* InvalidKeyException if it is being initialized for decryption. The
|
||||
* generated parameters can be retrieved using engineGetParameters or
|
||||
* engineGetIV (if the parameter is an IV).
|
||||
* <p>
|
||||
* If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from random and they will be stored in the class variable rndBytes.
|
||||
* <p>
|
||||
* Note that when a {@link BlockCipher} object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it
|
||||
*
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @param random
|
||||
* the source of randomness
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher
|
||||
* @throws InvalidParameterException
|
||||
* if this block cipher requires parameters for
|
||||
* initialization and cannot generate parameters itself.
|
||||
*/
|
||||
public final void initEncrypt(Key key, SecureRandom random)
|
||||
throws InvalidKeyException, InvalidParameterException {
|
||||
|
||||
try {
|
||||
initEncrypt(key, (ModeParameterSpec) null,
|
||||
(AlgorithmParameterSpec) null, random);
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
throw new InvalidParameterException(
|
||||
"This cipher needs algorithm parameters for initialization (cannot be null).");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this cipher with a key, a set of algorithm parameters, and a
|
||||
* source of randomness for encryption.
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters and paramSpec is null,
|
||||
* the underlying cipher implementation is supposed to generate the required
|
||||
* parameters itself (using provider-specific default or random values) if
|
||||
* it is being initialized for encryption, and raise an
|
||||
* InvalidAlgorithmParameterException if it is being initialized for
|
||||
* decryption. The generated parameters can be retrieved using
|
||||
* engineGetParameters or engineGetIV (if the parameter is an IV).
|
||||
* <p>
|
||||
* If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from random.
|
||||
* <p>
|
||||
* Note that when a {@link BlockCipher} object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it.
|
||||
*
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @param cipherParams
|
||||
* the cipher parameters
|
||||
* @param random
|
||||
* the source of randomness
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* block cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the parameters are inappropriate for initializing this
|
||||
* block cipher.
|
||||
*/
|
||||
public final void initEncrypt(Key key, AlgorithmParameterSpec cipherParams,
|
||||
SecureRandom random) throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException {
|
||||
initEncrypt(key, null, cipherParams, random);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this cipher with a key, a set of algorithm parameters, and a
|
||||
* source of randomness for encryption.
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters and paramSpec is null,
|
||||
* the underlying cipher implementation is supposed to generate the required
|
||||
* parameters itself (using provider-specific default or random values) if
|
||||
* it is being initialized for encryption, and raise an
|
||||
* InvalidAlgorithmParameterException if it is being initialized for
|
||||
* decryption. The generated parameters can be retrieved using
|
||||
* engineGetParameters or engineGetIV (if the parameter is an IV).
|
||||
* <p>
|
||||
* If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from random.
|
||||
* <p>
|
||||
* Note that when a {@link BlockCipher} object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it.
|
||||
*
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @param modeParams
|
||||
* the mode parameters
|
||||
* @param cipherParams
|
||||
* the cipher parameters
|
||||
* @param random
|
||||
* the source of randomness
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* block cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the parameters are inappropriate for initializing this
|
||||
* block cipher.
|
||||
*/
|
||||
public final void initEncrypt(Key key, ModeParameterSpec modeParams,
|
||||
AlgorithmParameterSpec cipherParams, SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
|
||||
this.random = random != null ? random : Registry.getSecureRandom();
|
||||
initModeAndPadding();
|
||||
opMode = ENCRYPT_MODE;
|
||||
|
||||
buffer = new byte[0];
|
||||
paramSpec = cipherParams;
|
||||
|
||||
if (!(key instanceof SecretKey)) {
|
||||
throw new InvalidKeyException("unsupported type");
|
||||
}
|
||||
|
||||
mode.initEncrypt((SecretKey) key, modeParams, cipherParams);
|
||||
modeBlockSize = mode.blockSize;
|
||||
paddingScheme.setBlockSize(modeBlockSize);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this cipher with a key and a source of randomness for
|
||||
* decryption.
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters that cannot be derived
|
||||
* from the given key, the underlying cipher implementation is supposed to
|
||||
* generate the required parameters itself (using provider-specific default
|
||||
* or random values) if it is being initialized for encryption, and raise an
|
||||
* InvalidKeyException if it is being initialized for decryption. The
|
||||
* generated parameters can be retrieved using engineGetParameters or
|
||||
* engineGetIV (if the parameter is an IV).
|
||||
* <p>
|
||||
* If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from random.
|
||||
* <p>
|
||||
* Note that when a {@link BlockCipher} object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it
|
||||
*
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher
|
||||
* @throws InvalidParameterException
|
||||
* if the parameters are
|
||||
*/
|
||||
public final void initDecrypt(Key key) throws InvalidKeyException,
|
||||
InvalidParameterException {
|
||||
try {
|
||||
initDecrypt(key, (ModeParameterSpec) null,
|
||||
(AlgorithmParameterSpec) null);
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
throw new InvalidParameterException(
|
||||
"This cipher needs algorithm parameters for initialization (cannot be null).");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this cipher with a key, a set of algorithm parameters, and a
|
||||
* source of randomness for decryption.
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters and paramSpec is null,
|
||||
* the underlying cipher implementation is supposed to generate the required
|
||||
* parameters itself (using provider-specific default or random values) if
|
||||
* it is being initialized for encryption, and throw an
|
||||
* {@link InvalidAlgorithmParameterException} if it is being initialized for
|
||||
* decryption. The generated parameters can be retrieved using
|
||||
* engineGetParameters or engineGetIV (if the parameter is an IV).
|
||||
* <p>
|
||||
* If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from random.
|
||||
* <p>
|
||||
* Note that when a {@link BlockCipher} object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it.
|
||||
*
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @param cipherParams
|
||||
* the cipher parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* block cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the parameters are inappropriate for initializing this
|
||||
* block cipher.
|
||||
*/
|
||||
public final void initDecrypt(Key key, AlgorithmParameterSpec cipherParams)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
initDecrypt(key, null, cipherParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this cipher with a key, a set of algorithm parameters, and a
|
||||
* source of randomness for decryption.
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters and paramSpec is null,
|
||||
* the underlying cipher implementation is supposed to generate the required
|
||||
* parameters itself (using provider-specific default or random values) if
|
||||
* it is being initialized for encryption, and throw an
|
||||
* {@link InvalidAlgorithmParameterException} if it is being initialized for
|
||||
* decryption. The generated parameters can be retrieved using
|
||||
* engineGetParameters or engineGetIV (if the parameter is an IV).
|
||||
* <p>
|
||||
* If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from random.
|
||||
* <p>
|
||||
* Note that when a {@link BlockCipher} object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it.
|
||||
*
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @param modeParams
|
||||
* the mode parameters
|
||||
* @param cipherParams
|
||||
* the cipher parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* block cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the parameters are inappropriate for initializing this
|
||||
* block cipher.
|
||||
*/
|
||||
public final void initDecrypt(Key key, ModeParameterSpec modeParams,
|
||||
AlgorithmParameterSpec cipherParams) throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException {
|
||||
|
||||
initModeAndPadding();
|
||||
opMode = DECRYPT_MODE;
|
||||
|
||||
buffer = new byte[0];
|
||||
paramSpec = cipherParams;
|
||||
|
||||
if (!(key instanceof SecretKey)) {
|
||||
throw new InvalidKeyException("unsupported type");
|
||||
}
|
||||
|
||||
mode.initDecrypt((SecretKey) key, modeParams, cipherParams);
|
||||
modeBlockSize = mode.blockSize;
|
||||
paddingScheme.setBlockSize(modeBlockSize);
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Continue a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized), processing another data part.
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @return a new buffer with the result (maybe an empty byte array)
|
||||
*/
|
||||
public final byte[] update(byte[] input, int inOff, int inLen) {
|
||||
|
||||
// if the cipher is not initialized or input is empty, return an empty
|
||||
// byte array
|
||||
if (!initialized || input == null || inLen <= 0) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
// concatenate buffer and input (only if buffer is not empty)
|
||||
int bufLen = buffer.length;
|
||||
int newInLen, newInOff;
|
||||
byte[] newInput;
|
||||
if (bufLen == 0) {
|
||||
newInOff = inOff;
|
||||
newInLen = inLen;
|
||||
newInput = input;
|
||||
} else {
|
||||
newInLen = bufLen + inLen;
|
||||
newInOff = 0;
|
||||
newInput = new byte[newInLen];
|
||||
System.arraycopy(buffer, 0, newInput, 0, bufLen);
|
||||
System.arraycopy(input, inOff, newInput, bufLen, inLen);
|
||||
}
|
||||
|
||||
// compute number of blocks to process and remaining bytes
|
||||
int numBlocks = newInLen / modeBlockSize;
|
||||
int numBytes = numBlocks * modeBlockSize;
|
||||
int remaining = newInLen - numBytes;
|
||||
if (opMode == DECRYPT_MODE && remaining == 0) {
|
||||
remaining = modeBlockSize;
|
||||
numBlocks--;
|
||||
numBytes -= modeBlockSize;
|
||||
}
|
||||
|
||||
byte[] output = new byte[numBytes];
|
||||
int outOff = 0;
|
||||
|
||||
// process whole blocks
|
||||
for (int block = 0; block < numBlocks; block++) {
|
||||
if (opMode == ENCRYPT_MODE) {
|
||||
mode.nextChunkEncrypt(newInput, newInOff, output, outOff);
|
||||
} else if (opMode == DECRYPT_MODE) {
|
||||
mode.nextChunkDecrypt(newInput, newInOff, output, outOff);
|
||||
}
|
||||
newInOff += modeBlockSize;
|
||||
outOff += modeBlockSize;
|
||||
}
|
||||
|
||||
// copy unprocessed bytes to buffer
|
||||
buffer = new byte[remaining];
|
||||
System.arraycopy(newInput, newInOff, buffer, 0, remaining);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Continue a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized), processing another data part.
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @param output
|
||||
* the output buffer
|
||||
* @param outOff
|
||||
* the offset where the result is stored
|
||||
* @return the length of the output
|
||||
* @throws ShortBufferException
|
||||
* if the output buffer is too small to hold the result.
|
||||
*/
|
||||
public final int update(byte[] input, int inOff, int inLen, byte[] output,
|
||||
int outOff) throws ShortBufferException {
|
||||
|
||||
// if the cipher is not initialized or input is empty return 0
|
||||
if (!initialized || input == null || inLen <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// compute number of bytes to process
|
||||
int newInLen = buffer.length + inLen;
|
||||
int remaining = newInLen % modeBlockSize;
|
||||
if (opMode == DECRYPT_MODE && remaining == 0) {
|
||||
remaining = modeBlockSize;
|
||||
}
|
||||
int numBytes = newInLen - remaining;
|
||||
|
||||
if (output.length - outOff < numBytes) {
|
||||
throw new ShortBufferException("output");
|
||||
}
|
||||
|
||||
byte[] update = update(input, inOff, inLen);
|
||||
System.arraycopy(update, 0, output, outOff, update.length);
|
||||
|
||||
return update.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized).
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @return a new buffer with the result
|
||||
* @throws IllegalBlockSizeException
|
||||
* if the total input length is not a multiple of the block
|
||||
* size (for encryption when no padding is used or for
|
||||
* decryption).
|
||||
* @throws BadPaddingException
|
||||
* if unpadding fails.
|
||||
*/
|
||||
public final byte[] doFinal(byte[] input, int inOff, int inLen)
|
||||
throws IllegalBlockSizeException, BadPaddingException {
|
||||
|
||||
byte[] output = new byte[0];
|
||||
|
||||
if (input == null && buffer == null) {
|
||||
return output;
|
||||
}
|
||||
|
||||
byte[] update = update(input, inOff, inLen);
|
||||
int updLen = update.length;
|
||||
int bufLen = buffer.length;
|
||||
|
||||
if (opMode == ENCRYPT_MODE) {
|
||||
int padLen = paddingScheme.padLength(bufLen);
|
||||
if (padLen == 0) {
|
||||
return update;
|
||||
}
|
||||
output = new byte[updLen + bufLen + padLen];
|
||||
System.arraycopy(update, 0, output, 0, updLen);
|
||||
System.arraycopy(buffer, 0, output, updLen, bufLen);
|
||||
paddingScheme.pad(output, updLen, bufLen);
|
||||
mode.nextChunkEncrypt(output, updLen, output, updLen);
|
||||
} else if (opMode == DECRYPT_MODE) {
|
||||
if (bufLen != modeBlockSize) {
|
||||
throw new IllegalBlockSizeException(
|
||||
"ciphertext length is not a multiple of block size");
|
||||
}
|
||||
mode.nextChunkDecrypt(buffer, 0, buffer, 0);
|
||||
int padOffset = paddingScheme.unpad(buffer, 0, modeBlockSize);
|
||||
output = new byte[updLen + padOffset];
|
||||
System.arraycopy(update, 0, output, 0, updLen);
|
||||
System.arraycopy(buffer, 0, output, updLen, padOffset);
|
||||
}
|
||||
|
||||
buffer = null;
|
||||
mode.reset();
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized).
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @param output
|
||||
* the buffer for the result
|
||||
* @param outOff
|
||||
* the offset where the result is stored
|
||||
* @return the output length
|
||||
* @throws ShortBufferException
|
||||
* if the output buffer is too small to hold the result.
|
||||
* @throws IllegalBlockSizeException
|
||||
* if the total input length is not a multiple of the block
|
||||
* size (for encryption when no padding is used or for
|
||||
* decryption).
|
||||
* @throws BadPaddingException
|
||||
* if unpadding fails.
|
||||
*/
|
||||
public final int doFinal(byte[] input, int inOff, int inLen, byte[] output,
|
||||
int outOff) throws ShortBufferException, IllegalBlockSizeException,
|
||||
BadPaddingException {
|
||||
|
||||
byte[] doFinal = doFinal(input, inOff, inLen);
|
||||
int outLen = doFinal.length;
|
||||
if (outLen == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (output.length - outOff < outLen) {
|
||||
throw new ShortBufferException("output");
|
||||
}
|
||||
System.arraycopy(doFinal, 0, output, outOff, outLen);
|
||||
return outLen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the block cipher with a secret key and parameters for data
|
||||
* encryption.
|
||||
*
|
||||
* @param key
|
||||
* the secret key
|
||||
* @param params
|
||||
* the parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for this cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given parameters are inappropriate for this
|
||||
* cipher.
|
||||
*/
|
||||
protected abstract void initCipherEncrypt(SecretKey key,
|
||||
AlgorithmParameterSpec params) throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Initialize the block cipher with a secret key and parameters for data
|
||||
* decryption.
|
||||
*
|
||||
* @param key
|
||||
* the secret key
|
||||
* @param params
|
||||
* the parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for this cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given parameters are inappropriate for this
|
||||
* cipher.
|
||||
*/
|
||||
protected abstract void initCipherDecrypt(SecretKey key,
|
||||
AlgorithmParameterSpec params) throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Encrypt a single block of data. It has to be assured that the array
|
||||
* <tt>input</tt> contains a whole block starting at <tt>inOff</tt> and
|
||||
* that <tt>out</tt> is large enough to hold an encrypted block starting
|
||||
* at <tt>outOff</tt>.
|
||||
*
|
||||
* @param input
|
||||
* array of bytes which contains the plaintext to be
|
||||
* encrypted
|
||||
* @param inOff
|
||||
* index in array in, where the plaintext block starts
|
||||
* @param output
|
||||
* array of bytes which will contain the ciphertext startig
|
||||
* at outOffset
|
||||
* @param outOff
|
||||
* index in array out, where the ciphertext block will start
|
||||
*/
|
||||
protected abstract void singleBlockEncrypt(byte[] input, int inOff,
|
||||
byte[] output, int outOff);
|
||||
|
||||
/**
|
||||
* Decrypt a single block of data. It has to be assured that the array
|
||||
* <tt>input</tt> contains a whole block starting at <tt>inOff</tt> and
|
||||
* that <tt>output</tt> is large enough to hold an decrypted block
|
||||
* starting at <tt>outOff</tt>.
|
||||
*
|
||||
* @param input
|
||||
* array of bytes which contains the ciphertext to be
|
||||
* decrypted
|
||||
* @param inOff
|
||||
* index in array in, where the ciphertext block starts
|
||||
* @param output
|
||||
* array of bytes which will contain the plaintext starting
|
||||
* at outOffset
|
||||
* @param outOff
|
||||
* index in array out, where the plaintext block will start
|
||||
*/
|
||||
protected abstract void singleBlockDecrypt(byte[] input, int inOff,
|
||||
byte[] output, int outOff);
|
||||
|
||||
/**
|
||||
* Check if mode and padding are set. If not, instantiate the default ones.
|
||||
*/
|
||||
private void initModeAndPadding() {
|
||||
if (mode == null) {
|
||||
mode = Registry.getMode();
|
||||
mode.setBlockCipher(this);
|
||||
}
|
||||
|
||||
if (paddingScheme == null) {
|
||||
paddingScheme = Registry.getPaddingScheme();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
729
src/de/flexiprovider/api/Cipher.java
Normal file
729
src/de/flexiprovider/api/Cipher.java
Normal file
@@ -0,0 +1,729 @@
|
||||
package de.flexiprovider.api;
|
||||
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
|
||||
import de.flexiprovider.api.exceptions.BadPaddingException;
|
||||
import de.flexiprovider.api.exceptions.IllegalBlockSizeException;
|
||||
import de.flexiprovider.api.exceptions.InvalidAlgorithmParameterException;
|
||||
import de.flexiprovider.api.exceptions.InvalidKeyException;
|
||||
import de.flexiprovider.api.exceptions.InvalidParameterException;
|
||||
import de.flexiprovider.api.exceptions.NoSuchAlgorithmException;
|
||||
import de.flexiprovider.api.exceptions.NoSuchModeException;
|
||||
import de.flexiprovider.api.exceptions.NoSuchPaddingException;
|
||||
import de.flexiprovider.api.exceptions.ShortBufferException;
|
||||
import de.flexiprovider.api.keys.Key;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameterSpec;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameters;
|
||||
import de.flexiprovider.common.util.JavaSecureRandomWrapper;
|
||||
|
||||
public abstract class Cipher extends javax.crypto.CipherSpi {
|
||||
|
||||
/**
|
||||
* Constant specifying encrypt mode.
|
||||
*/
|
||||
public static final int ENCRYPT_MODE = javax.crypto.Cipher.ENCRYPT_MODE;
|
||||
|
||||
/**
|
||||
* Constant specifying decrypt mode.
|
||||
*/
|
||||
public static final int DECRYPT_MODE = javax.crypto.Cipher.DECRYPT_MODE;
|
||||
|
||||
/**
|
||||
* The operation mode for this cipher ({@link #ENCRYPT_MODE} or
|
||||
* {@link #DECRYPT_MODE}).
|
||||
*/
|
||||
protected int opMode;
|
||||
|
||||
// ****************************************************
|
||||
// JCA adapter methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* Initialize this cipher object with a proper key and some random seed.
|
||||
* Before a cipher object is ready for data processing, it has to be
|
||||
* initialized according to the desired cryptographic operation, which is
|
||||
* specified by the <tt>opMode</tt> parameter.
|
||||
* <p>
|
||||
* If this cipher (including its underlying mode or padding scheme) requires
|
||||
* any random bytes, it will obtain them from <tt>random</tt>.
|
||||
* <p>
|
||||
* Note: If the mode needs an initialization vector, a blank array is used
|
||||
* in this case.
|
||||
*
|
||||
* @param opMode
|
||||
* the operation mode ({@link #ENCRYPT_MODE} or
|
||||
* {@link #DECRYPT_MODE})
|
||||
* @param key
|
||||
* the key
|
||||
* @param random
|
||||
* the random seed
|
||||
* @throws java.security.InvalidKeyException
|
||||
* if the key is inappropriate for initializing this cipher.
|
||||
*/
|
||||
protected final void engineInit(int opMode, java.security.Key key,
|
||||
java.security.SecureRandom random)
|
||||
throws java.security.InvalidKeyException {
|
||||
|
||||
try {
|
||||
engineInit(opMode, key,
|
||||
(java.security.spec.AlgorithmParameterSpec) null, random);
|
||||
} catch (java.security.InvalidAlgorithmParameterException e) {
|
||||
throw new InvalidParameterException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this cipher with a key, a set of algorithm parameters, and a
|
||||
* source of randomness. The cipher is initialized for encryption or
|
||||
* decryption, depending on the value of <tt>opMode</tt>.
|
||||
* <p>
|
||||
* If this cipher (including its underlying mode or padding scheme) requires
|
||||
* any random bytes, it will obtain them from <tt>random</tt>. Note that
|
||||
* when a {@link BlockCipher} object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it.
|
||||
* <p>
|
||||
* Note: If the mode needs an initialization vector, a try to retrieve it
|
||||
* from the AlgorithmParametersSpec is made.
|
||||
*
|
||||
* @param opMode
|
||||
* the operation mode ({@link #ENCRYPT_MODE} or
|
||||
* {@link #DECRYPT_MODE})
|
||||
* @param key
|
||||
* the key
|
||||
* @param algParams
|
||||
* the algorithm parameters
|
||||
* @param random
|
||||
* the random seed
|
||||
* @throws java.security.InvalidKeyException
|
||||
* if the key is inappropriate for initializing this block
|
||||
* cipher.
|
||||
* @throws java.security.InvalidAlgorithmParameterException
|
||||
* if the parameters are inappropriate for initializing this
|
||||
* block cipher.
|
||||
*/
|
||||
protected final void engineInit(int opMode, java.security.Key key,
|
||||
java.security.AlgorithmParameters algParams,
|
||||
java.security.SecureRandom random)
|
||||
throws java.security.InvalidKeyException,
|
||||
java.security.InvalidAlgorithmParameterException {
|
||||
|
||||
// if algParams are not specified, initialize without them
|
||||
if (algParams == null) {
|
||||
engineInit(opMode, key, random);
|
||||
return;
|
||||
}
|
||||
|
||||
java.security.spec.AlgorithmParameterSpec paramSpec = null;
|
||||
try {
|
||||
paramSpec = algParams.getParameterSpec(Registry
|
||||
.getAlgParamSpecClass(algParams.getAlgorithm()));
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"Unknown algorithm parameters.");
|
||||
} catch (InvalidParameterSpecException e) {
|
||||
throw new RuntimeException(
|
||||
"Internal error: invalid parameters type.");
|
||||
}
|
||||
|
||||
engineInit(opMode, key, paramSpec, random);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this cipher with a key, a set of algorithm parameters, and a
|
||||
* source of randomness. The cipher is initialized for one of the following
|
||||
* four operations: encryption, decryption, key wrapping or key unwrapping,
|
||||
* depending on the value of opMode. If this cipher (including its
|
||||
* underlying feedback or padding scheme) requires any random bytes (e.g.,
|
||||
* for parameter generation), it will get them from random. Note that when a
|
||||
* Cipher object is initialized, it loses all previously-acquired state. In
|
||||
* other words, initializing a Cipher is equivalent to creating a new
|
||||
* instance of that Cipher and initializing it.
|
||||
*
|
||||
* @param opMode
|
||||
* the operation mode ({@link #ENCRYPT_MODE} or
|
||||
* {@link #DECRYPT_MODE})
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @param params
|
||||
* the algorithm parameters
|
||||
* @param javaRand
|
||||
* the source of randomness
|
||||
* @throws java.security.InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* cipher
|
||||
* @throws java.security.InvalidAlgorithmParameterException
|
||||
* if the given algorithm parameters are inappropriate for
|
||||
* this cipher, or if this cipher is being initialized for
|
||||
* decryption and requires algorithm parameters and the
|
||||
* parameters are null.
|
||||
*/
|
||||
protected void engineInit(int opMode, java.security.Key key,
|
||||
java.security.spec.AlgorithmParameterSpec params,
|
||||
java.security.SecureRandom javaRand)
|
||||
throws java.security.InvalidKeyException,
|
||||
java.security.InvalidAlgorithmParameterException {
|
||||
|
||||
if ((params != null) && !(params instanceof AlgorithmParameterSpec)) {
|
||||
throw new java.security.InvalidAlgorithmParameterException();
|
||||
}
|
||||
|
||||
if ((key == null) || !(key instanceof Key)) {
|
||||
throw new java.security.InvalidKeyException();
|
||||
}
|
||||
|
||||
this.opMode = opMode;
|
||||
|
||||
if (opMode == ENCRYPT_MODE) {
|
||||
SecureRandom flexiRand = new JavaSecureRandomWrapper(javaRand);
|
||||
initEncrypt((Key) key, (AlgorithmParameterSpec) params, flexiRand);
|
||||
|
||||
} else if (opMode == DECRYPT_MODE) {
|
||||
initDecrypt((Key) key, (AlgorithmParameterSpec) params);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the result of the last step of a multi-step en-/decryption
|
||||
* operation or the result of a single-step en-/decryption operation by
|
||||
* processing the given input data and any remaining buffered data. The data
|
||||
* to be processed is given in an input byte array. Beginning at
|
||||
* inputOffset, only the first inputLen bytes are en-/decrypted, including
|
||||
* any buffered bytes of a previous update operation. If necessary, padding
|
||||
* is performed. The result is returned as a output byte array.
|
||||
*
|
||||
* @param input
|
||||
* the byte array holding the data to be processed
|
||||
* @param inOff
|
||||
* the offset indicating the start position within the input
|
||||
* byte array
|
||||
* @param inLen
|
||||
* the number of bytes to be processed
|
||||
* @return the byte array containing the en-/decrypted data
|
||||
* @throws javax.crypto.IllegalBlockSizeException
|
||||
* if the ciphertext length is not a multiple of the
|
||||
* blocklength.
|
||||
* @throws javax.crypto.BadPaddingException
|
||||
* if unpadding is not possible.
|
||||
*/
|
||||
protected final byte[] engineDoFinal(byte[] input, int inOff, int inLen)
|
||||
throws javax.crypto.IllegalBlockSizeException,
|
||||
javax.crypto.BadPaddingException {
|
||||
return doFinal(input, inOff, inLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the last step of a multi-step en-/decryption operation or a
|
||||
* single-step en-/decryption operation by processing the given input data
|
||||
* and any remaining buffered data. The data to be processed is given in an
|
||||
* input byte array. Beginning at inputOffset, only the first inputLen bytes
|
||||
* are en-/decrypted, including any buffered bytes of a previous update
|
||||
* operation. If necessary, padding is performed. The result is stored in
|
||||
* the given output byte array, beginning at outputOffset. The number of
|
||||
* bytes stored in this byte array are returned.
|
||||
*
|
||||
* @param input
|
||||
* the byte array holding the data to be processed
|
||||
* @param inOff
|
||||
* the offset indicating the start position within the input
|
||||
* byte array
|
||||
* @param inLen
|
||||
* the number of bytes to be processed
|
||||
* @param output
|
||||
* the byte array for holding the result
|
||||
* @param outOff
|
||||
* the offset indicating the start position within the output
|
||||
* byte array to which the en/decrypted data is written
|
||||
* @return the number of bytes stored in the output byte array
|
||||
* @throws javax.crypto.ShortBufferException
|
||||
* if the output buffer is too short to hold the output.
|
||||
* @throws javax.crypto.IllegalBlockSizeException
|
||||
* if the ciphertext length is not a multiple of the
|
||||
* blocklength.
|
||||
* @throws javax.crypto.BadPaddingException
|
||||
* if unpadding is not possible.
|
||||
*/
|
||||
protected final int engineDoFinal(byte[] input, int inOff, int inLen,
|
||||
byte[] output, int outOff)
|
||||
throws javax.crypto.ShortBufferException,
|
||||
javax.crypto.IllegalBlockSizeException,
|
||||
javax.crypto.BadPaddingException {
|
||||
return doFinal(input, inOff, inLen, output, outOff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the block size (in bytes), or 0 if the underlying algorithm is
|
||||
* not a block cipher
|
||||
*/
|
||||
protected final int engineGetBlockSize() {
|
||||
return getBlockSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key size of the given key object in bits.
|
||||
*
|
||||
* @param key
|
||||
* the key object
|
||||
* @return the key size in bits of the given key object
|
||||
* @throws java.security.InvalidKeyException
|
||||
* if key is invalid.
|
||||
*/
|
||||
protected final int engineGetKeySize(java.security.Key key)
|
||||
throws java.security.InvalidKeyException {
|
||||
if (!(key instanceof Key)) {
|
||||
throw new java.security.InvalidKeyException("Unsupported key.");
|
||||
}
|
||||
return getKeySize((Key) key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the initialization vector. This is useful in the context of
|
||||
* password-based encryption or decryption, where the IV is derived from a
|
||||
* user-provided passphrase.
|
||||
*
|
||||
* @return the initialization vector in a new buffer, or <tt>null</tt> if
|
||||
* the underlying algorithm does not use an IV, or if the IV has not
|
||||
* yet been set.
|
||||
*/
|
||||
protected final byte[] engineGetIV() {
|
||||
return getIV();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the length in bytes that an output buffer would need to be in
|
||||
* order to hold the result of the next update or doFinal operation, given
|
||||
* the input length inputLen (in bytes).
|
||||
* <p>
|
||||
* This call takes into account any unprocessed (buffered) data from a
|
||||
* previous update call, and padding.
|
||||
* <p>
|
||||
* The actual output length of the next update or doFinal call may be
|
||||
* smaller than the length returned by this method.
|
||||
*
|
||||
* @param inLen
|
||||
* the input length (in bytes)
|
||||
* @return the required output buffer size (in bytes)
|
||||
*/
|
||||
protected final int engineGetOutputSize(int inLen) {
|
||||
return getOutputSize(inLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parameters used with this cipher.
|
||||
* <p>
|
||||
* The returned parameters may be the same that were used to initialize this
|
||||
* cipher, or may contain the default set of parameters or a set of randomly
|
||||
* generated parameters used by the underlying cipher implementation
|
||||
* (provided that the underlying cipher implementation uses a default set of
|
||||
* parameters or creates new parameters if it needs parameters but was not
|
||||
* initialized with any).
|
||||
*
|
||||
* @return the parameters used with this cipher, or null if this cipher does
|
||||
* not use any parameters.
|
||||
*/
|
||||
protected final java.security.AlgorithmParameters engineGetParameters() {
|
||||
|
||||
final class JavaAlgorithmParameters extends
|
||||
java.security.AlgorithmParameters {
|
||||
JavaAlgorithmParameters(AlgorithmParameters params, String algName) {
|
||||
super(params, null, algName);
|
||||
}
|
||||
}
|
||||
|
||||
String algName = getName();
|
||||
AlgorithmParameters params;
|
||||
try {
|
||||
params = Registry.getAlgParams(algName);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
JavaAlgorithmParameters algParams = new JavaAlgorithmParameters(params,
|
||||
algName);
|
||||
|
||||
AlgorithmParameterSpec algParamSpec = getParameters();
|
||||
if (algParamSpec == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
algParams.init(algParamSpec);
|
||||
} catch (java.security.spec.InvalidParameterSpecException ipse) {
|
||||
throw new RuntimeException("InvalidParameterSpecException: "
|
||||
+ ipse.getMessage());
|
||||
}
|
||||
|
||||
return algParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mode of this cipher.
|
||||
*
|
||||
* @param modeName
|
||||
* the cipher mode
|
||||
* @throws java.security.NoSuchAlgorithmException
|
||||
* if neither the mode with the given name nor the default
|
||||
* mode can be found
|
||||
*/
|
||||
protected final void engineSetMode(String modeName)
|
||||
throws java.security.NoSuchAlgorithmException {
|
||||
setMode(modeName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the padding scheme of this cipher.
|
||||
*
|
||||
* @param paddingName
|
||||
* the padding scheme
|
||||
* @throws javax.crypto.NoSuchPaddingException
|
||||
* if the requested padding scheme cannot be found.
|
||||
*/
|
||||
protected final void engineSetPadding(String paddingName)
|
||||
throws javax.crypto.NoSuchPaddingException {
|
||||
setPadding(paddingName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the result of the next step of a multi-step en-/decryption
|
||||
* operation. The data to be processed is given in an input byte array.
|
||||
* Beginning at inputOffset, only the first inputLen bytes are
|
||||
* en-/decrypted. The result is returned as a byte array.
|
||||
*
|
||||
* @param input
|
||||
* the byte array holding the data to be processed
|
||||
* @param inOff
|
||||
* the offset indicating the start position within the input
|
||||
* byte array
|
||||
* @param inLen
|
||||
* the number of bytes to be processed
|
||||
* @return the byte array containing the en-/decrypted data
|
||||
*/
|
||||
protected final byte[] engineUpdate(byte[] input, int inOff, int inLen) {
|
||||
return update(input, inOff, inLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the next step of a multi-step en-/decryption operation. The data
|
||||
* to be processed is given in an input byte array. Beginning at
|
||||
* inputOffset, only the first inputLen bytes are en-/decrypted. The result
|
||||
* is stored in the given output byte array, beginning at outputOffset. The
|
||||
* number of bytes stored in this output byte array are returned.
|
||||
*
|
||||
* @param input
|
||||
* the byte array holding the data to be processed
|
||||
* @param inOff
|
||||
* the offset indicating the start position within the input
|
||||
* byte array
|
||||
* @param inLen
|
||||
* the number of bytes to be processed
|
||||
* @param output
|
||||
* the byte array for holding the result
|
||||
* @param outOff
|
||||
* the offset indicating the start position within the output
|
||||
* byte array to which the en-/decrypted data is written
|
||||
* @return the number of bytes that are stored in the output byte array
|
||||
* @throws javax.crypto.ShortBufferException
|
||||
* if the output buffer is too short to hold the output.
|
||||
*/
|
||||
protected final int engineUpdate(final byte[] input, final int inOff,
|
||||
final int inLen, byte[] output, final int outOff)
|
||||
throws javax.crypto.ShortBufferException {
|
||||
return update(input, inOff, inLen, output, outOff);
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// FlexiAPI methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* Initialize this cipher with a key, a set of algorithm parameters, and a
|
||||
* source of randomness for encryption.
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters and paramSpec is null,
|
||||
* the underlying cipher implementation is supposed to generate the required
|
||||
* parameters itself (using provider-specific default or random values) if
|
||||
* it is being initialized for encryption, and raise an
|
||||
* InvalidAlgorithmParameterException if it is being initialized for
|
||||
* decryption. The generated parameters can be retrieved using
|
||||
* engineGetParameters or engineGetIV (if the parameter is an IV).
|
||||
* <p>
|
||||
* If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from random.
|
||||
* <p>
|
||||
* Note that when a {@link BlockCipher} object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it.
|
||||
*
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @param cipherParams
|
||||
* the cipher parameters
|
||||
* @param random
|
||||
* the source of randomness
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* block cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the parameters are inappropriate for initializing this
|
||||
* block cipher.
|
||||
*/
|
||||
public abstract void initEncrypt(Key key,
|
||||
AlgorithmParameterSpec cipherParams, SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Initialize this cipher with a key, a set of algorithm parameters, and a
|
||||
* source of randomness for decryption.
|
||||
* <p>
|
||||
* If this cipher requires any algorithm parameters and paramSpec is null,
|
||||
* the underlying cipher implementation is supposed to generate the required
|
||||
* parameters itself (using provider-specific default or random values) if
|
||||
* it is being initialized for encryption, and throw an
|
||||
* {@link InvalidAlgorithmParameterException} if it is being initialized for
|
||||
* decryption. The generated parameters can be retrieved using
|
||||
* engineGetParameters or engineGetIV (if the parameter is an IV).
|
||||
* <p>
|
||||
* If this cipher (including its underlying feedback or padding scheme)
|
||||
* requires any random bytes (e.g., for parameter generation), it will get
|
||||
* them from random.
|
||||
* <p>
|
||||
* Note that when a {@link BlockCipher} object is initialized, it loses all
|
||||
* previously-acquired state. In other words, initializing a Cipher is
|
||||
* equivalent to creating a new instance of that Cipher and initializing it.
|
||||
*
|
||||
* @param key
|
||||
* the encryption key
|
||||
* @param cipherParams
|
||||
* the cipher parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for initializing this
|
||||
* block cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the parameters are inappropriate for initializing this
|
||||
* block cipher.
|
||||
*/
|
||||
public abstract void initDecrypt(Key key,
|
||||
AlgorithmParameterSpec cipherParams) throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* @return the name of this cipher
|
||||
*/
|
||||
public abstract String getName();
|
||||
|
||||
/**
|
||||
* @return the block size (in bytes), or 0 if the underlying algorithm is
|
||||
* not a block cipher
|
||||
*/
|
||||
public abstract int getBlockSize();
|
||||
|
||||
/**
|
||||
* Returns the length in bytes that an output buffer would need to be in
|
||||
* order to hold the result of the next update or doFinal operation, given
|
||||
* the input length inputLen (in bytes).
|
||||
* <p>
|
||||
* This call takes into account any unprocessed (buffered) data from a
|
||||
* previous update call, and padding.
|
||||
* <p>
|
||||
* The actual output length of the next update or doFinal call may be
|
||||
* smaller than the length returned by this method.
|
||||
*
|
||||
* @param inputLen
|
||||
* the input length (in bytes)
|
||||
* @return the required output buffer size (in bytes)
|
||||
*/
|
||||
public abstract int getOutputSize(int inputLen);
|
||||
|
||||
/**
|
||||
* Return the key size of the given key object in bits.
|
||||
*
|
||||
* @param key
|
||||
* the key object
|
||||
* @return the key size in bits of the given key object
|
||||
* @throws InvalidKeyException
|
||||
* if key is invalid.
|
||||
*/
|
||||
public abstract int getKeySize(Key key) throws InvalidKeyException;
|
||||
|
||||
/**
|
||||
* Returns the parameters used with this cipher.
|
||||
* <p>
|
||||
* The returned parameters may be the same that were used to initialize this
|
||||
* cipher, or may contain the default set of parameters or a set of randomly
|
||||
* generated parameters used by the underlying cipher implementation
|
||||
* (provided that the underlying cipher implementation uses a default set of
|
||||
* parameters or creates new parameters if it needs parameters but was not
|
||||
* initialized with any).
|
||||
*
|
||||
* @return the parameters used with this cipher, or null if this cipher does
|
||||
* not use any parameters.
|
||||
*/
|
||||
public abstract AlgorithmParameterSpec getParameters();
|
||||
|
||||
/**
|
||||
* Return the initialization vector. This is useful in the context of
|
||||
* password-based encryption or decryption, where the IV is derived from a
|
||||
* user-provided passphrase.
|
||||
*
|
||||
* @return the initialization vector in a new buffer, or <tt>null</tt> if
|
||||
* the underlying algorithm does not use an IV, or if the IV has not
|
||||
* yet been set.
|
||||
*/
|
||||
public abstract byte[] getIV();
|
||||
|
||||
/**
|
||||
* Set the mode of this cipher.
|
||||
*
|
||||
* @param mode
|
||||
* the cipher mode
|
||||
* @throws NoSuchModeException
|
||||
* if the requested mode cannot be found.
|
||||
*/
|
||||
protected abstract void setMode(String mode) throws NoSuchModeException;
|
||||
|
||||
/**
|
||||
* Set the padding mechanism of this cipher.
|
||||
*
|
||||
* @param padding
|
||||
* the padding mechanism
|
||||
* @throws NoSuchPaddingException
|
||||
* if the requested padding scheme cannot be found.
|
||||
*/
|
||||
protected abstract void setPadding(String padding)
|
||||
throws NoSuchPaddingException;
|
||||
|
||||
/**
|
||||
* Continue a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized), processing another data part.
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @return a new buffer with the result (maybe an empty byte array)
|
||||
*/
|
||||
public final byte[] update(byte[] input) {
|
||||
return update(input, 0, input.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Continue a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized), processing another data part.
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @return a new buffer with the result (maybe an empty byte array)
|
||||
*/
|
||||
public abstract byte[] update(byte[] input, int inOff, int inLen);
|
||||
|
||||
/**
|
||||
* Continue a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized), processing another data part.
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @param output
|
||||
* the output buffer
|
||||
* @param outOff
|
||||
* the offset where the result is stored
|
||||
* @return the length of the output
|
||||
* @throws ShortBufferException
|
||||
* if the output buffer is too small to hold the result.
|
||||
*/
|
||||
public abstract int update(byte[] input, int inOff, int inLen,
|
||||
byte[] output, int outOff) throws ShortBufferException;
|
||||
|
||||
/**
|
||||
* Finish a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized).
|
||||
*
|
||||
* @return a new buffer with the result
|
||||
* @throws IllegalBlockSizeException
|
||||
* if this cipher is a block cipher and the total input
|
||||
* length is not a multiple of the block size (for
|
||||
* encryption when no padding is used or for decryption).
|
||||
* @throws BadPaddingException
|
||||
* if this cipher is a block cipher and unpadding fails.
|
||||
*/
|
||||
public final byte[] doFinal() throws IllegalBlockSizeException,
|
||||
BadPaddingException {
|
||||
return doFinal(null, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized).
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @return a new buffer with the result
|
||||
* @throws IllegalBlockSizeException
|
||||
* if this cipher is a block cipher and the total input
|
||||
* length is not a multiple of the block size (for
|
||||
* encryption when no padding is used or for decryption).
|
||||
* @throws BadPaddingException
|
||||
* if this cipher is a block cipher and unpadding fails.
|
||||
*/
|
||||
public final byte[] doFinal(byte[] input) throws IllegalBlockSizeException,
|
||||
BadPaddingException {
|
||||
return doFinal(input, 0, input.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized).
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @return a new buffer with the result
|
||||
* @throws IllegalBlockSizeException
|
||||
* if this cipher is a block cipher and the total input
|
||||
* length is not a multiple of the block size (for
|
||||
* encryption when no padding is used or for decryption).
|
||||
* @throws BadPaddingException
|
||||
* if this cipher is a block cipher and unpadding fails.
|
||||
*/
|
||||
public abstract byte[] doFinal(byte[] input, int inOff, int inLen)
|
||||
throws IllegalBlockSizeException, BadPaddingException;
|
||||
|
||||
/**
|
||||
* Finish a multiple-part encryption or decryption operation (depending on
|
||||
* how this cipher was initialized).
|
||||
*
|
||||
* @param input
|
||||
* the input buffer
|
||||
* @param inOff
|
||||
* the offset where the input starts
|
||||
* @param inLen
|
||||
* the input length
|
||||
* @param output
|
||||
* the buffer for the result
|
||||
* @param outOff
|
||||
* the offset where the result is stored
|
||||
* @return the output length
|
||||
* @throws ShortBufferException
|
||||
* if the output buffer is too small to hold the result.
|
||||
* @throws IllegalBlockSizeException
|
||||
* if this cipher is a block cipher and the total input
|
||||
* length is not a multiple of the block size (for
|
||||
* encryption when no padding is used or for decryption).
|
||||
* @throws BadPaddingException
|
||||
* if this cipher is a block cipher and unpadding fails.
|
||||
*/
|
||||
public abstract int doFinal(byte[] input, int inOff, int inLen,
|
||||
byte[] output, int outOff) throws ShortBufferException,
|
||||
IllegalBlockSizeException, BadPaddingException;
|
||||
|
||||
}
|
||||
259
src/de/flexiprovider/api/KeyAgreement.java
Normal file
259
src/de/flexiprovider/api/KeyAgreement.java
Normal file
@@ -0,0 +1,259 @@
|
||||
package de.flexiprovider.api;
|
||||
|
||||
import javax.crypto.KeyAgreementSpi;
|
||||
|
||||
import de.flexiprovider.api.exceptions.InvalidAlgorithmParameterException;
|
||||
import de.flexiprovider.api.exceptions.InvalidKeyException;
|
||||
import de.flexiprovider.api.exceptions.NoSuchAlgorithmException;
|
||||
import de.flexiprovider.api.exceptions.ShortBufferException;
|
||||
import de.flexiprovider.api.keys.Key;
|
||||
import de.flexiprovider.api.keys.PrivateKey;
|
||||
import de.flexiprovider.api.keys.PublicKey;
|
||||
import de.flexiprovider.api.keys.SecretKey;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameterSpec;
|
||||
import de.flexiprovider.common.util.JavaSecureRandomWrapper;
|
||||
|
||||
public abstract class KeyAgreement extends KeyAgreementSpi {
|
||||
|
||||
// ****************************************************
|
||||
// JCA adapter methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method init(): initialize this
|
||||
* <tt>KeyAgreementSpi</tt> with a key and a source of randomness.
|
||||
*
|
||||
* @param key
|
||||
* the secret key of the party initializing the key agreement
|
||||
* @param javaRand
|
||||
* the source of randomness
|
||||
* @throws java.security.InvalidKeyException
|
||||
* if the key is invalid.
|
||||
* @throws RuntimeException
|
||||
* if parameters are required for initialization.
|
||||
*/
|
||||
protected final void engineInit(java.security.Key key,
|
||||
java.security.SecureRandom javaRand)
|
||||
throws java.security.InvalidKeyException {
|
||||
|
||||
if (!(key instanceof PrivateKey)) {
|
||||
throw new java.security.InvalidKeyException();
|
||||
}
|
||||
|
||||
try {
|
||||
SecureRandom flexiRand = new JavaSecureRandomWrapper(javaRand);
|
||||
init((PrivateKey) key, (AlgorithmParameterSpec) null, flexiRand);
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
throw new RuntimeException("algorithm parameters required");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method init(): initialize this
|
||||
* <tt>KeyAgreementSpi</tt> with a key, algorithm parameters, and a source
|
||||
* of randomness.
|
||||
*
|
||||
* @param key
|
||||
* the secret key of the party initializing the key agreement
|
||||
* @param params
|
||||
* the algorithm parameters
|
||||
* @param javaRand
|
||||
* the source of randomness
|
||||
* @throws java.security.InvalidKeyException
|
||||
* if the key is invalid.
|
||||
* @throws java.security.InvalidAlgorithmParameterException
|
||||
* if the parameters are invalid or null and parameters are
|
||||
* needed for initialization.
|
||||
*/
|
||||
protected final void engineInit(java.security.Key key,
|
||||
java.security.spec.AlgorithmParameterSpec params,
|
||||
java.security.SecureRandom javaRand)
|
||||
throws java.security.InvalidKeyException,
|
||||
java.security.InvalidAlgorithmParameterException {
|
||||
|
||||
if (!(key instanceof PrivateKey)) {
|
||||
throw new java.security.InvalidKeyException();
|
||||
}
|
||||
|
||||
SecureRandom flexiRand = new JavaSecureRandomWrapper(javaRand);
|
||||
init((PrivateKey) key, (AlgorithmParameterSpec) params, flexiRand);
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method {@link #generateSecret()} : generate a
|
||||
* shared secret and return it as a byte array.
|
||||
*
|
||||
* @return the shared secret as byte array.
|
||||
* @throws IllegalStateException
|
||||
* if the object is not in doPhase.
|
||||
*/
|
||||
protected final byte[] engineGenerateSecret() throws IllegalStateException {
|
||||
return generateSecret();
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method {@link #generateSecret(byte[], int)}:
|
||||
* generate a shared secret and place it into the buffer
|
||||
* <tt>sharedSecret</tt>, beginning at <tt>offset</tt>.
|
||||
*
|
||||
* @param sharedSecret
|
||||
* the buffer to hold the shared secret
|
||||
* @param offset
|
||||
* the offset in <tt>sharedSecret</tt> where the shared
|
||||
* secret will be stored
|
||||
* @return the number of bytes written in <tt>sharedSecret</tt>
|
||||
* @throws IllegalStateException
|
||||
* if the key agreement scheme has not been initialized
|
||||
* properly.
|
||||
* @throws javax.crypto.ShortBufferException
|
||||
* if <tt>sharedSecret</tt> is too small to to hold the
|
||||
* shared secret
|
||||
*/
|
||||
protected final int engineGenerateSecret(byte[] sharedSecret, int offset)
|
||||
throws IllegalStateException, javax.crypto.ShortBufferException {
|
||||
|
||||
return generateSecret(sharedSecret, offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method {@link #generateSecret(String)}:
|
||||
* generate a shared secret via the algorithm specified in
|
||||
* <tt>algorithm</tt>.
|
||||
*
|
||||
* @param algorithm
|
||||
* the desired algorithm for the generation of the secret
|
||||
* @return the shared secret
|
||||
* @throws IllegalStateException
|
||||
* if the key agreement scheme has not been initialized
|
||||
* properly.
|
||||
* @throws java.security.NoSuchAlgorithmException
|
||||
* if <tt>algorithm</tt> is invalid.
|
||||
*/
|
||||
protected final javax.crypto.SecretKey engineGenerateSecret(String algorithm)
|
||||
throws IllegalStateException,
|
||||
java.security.NoSuchAlgorithmException {
|
||||
|
||||
return generateSecret(algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method {@link #doPhase(PublicKey, boolean)}:
|
||||
* execute the next phase of this key agreement with the given key that was
|
||||
* received from one of the other parties involved in this key agreement.
|
||||
*
|
||||
* @param key
|
||||
* the public key of the other party
|
||||
* @param lastPhase
|
||||
* <tt>true</tt> if this is the last phase of the key
|
||||
* agreement. After the last phase only
|
||||
* <tt>generateSecret</tt> may be called.
|
||||
* @return the shared secret
|
||||
* @throws IllegalStateException
|
||||
* if the key agreement scheme has not been initialized
|
||||
* properly.
|
||||
* @throws java.security.InvalidKeyException
|
||||
* if the key is invalid.
|
||||
*/
|
||||
protected final java.security.Key engineDoPhase(java.security.Key key,
|
||||
boolean lastPhase) throws java.security.InvalidKeyException,
|
||||
IllegalStateException {
|
||||
|
||||
if (!(key instanceof PublicKey)) {
|
||||
throw new java.security.InvalidKeyException();
|
||||
}
|
||||
|
||||
return doPhase((PublicKey) key, lastPhase);
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// FlexiAPI methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* Initialize this key agreement with a private key, algorithm parameters,
|
||||
* and a source of randomness.
|
||||
*
|
||||
* @param privKey
|
||||
* the private key of the party initializing the key
|
||||
* agreement
|
||||
* @param params
|
||||
* the algorithm parameters
|
||||
* @param random
|
||||
* the source of randomness
|
||||
* @throws InvalidKeyException
|
||||
* if the key is invalid.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the parameters are invalid.
|
||||
*/
|
||||
public abstract void init(PrivateKey privKey,
|
||||
AlgorithmParameterSpec params, SecureRandom random)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Generate a shared secret and return it as a byte array.
|
||||
*
|
||||
* @return the shared secret as byte array.
|
||||
* @throws IllegalStateException
|
||||
* if the key agreement scheme has not been initialized
|
||||
* properly.
|
||||
*/
|
||||
public abstract byte[] generateSecret() throws IllegalStateException;
|
||||
|
||||
/**
|
||||
* Generate a shared secret and place it into the buffer
|
||||
* <tt>sharedSecret</tt>, beginning at <tt>offset</tt>.
|
||||
*
|
||||
* @param sharedSecret
|
||||
* the buffer to hold the shared secret
|
||||
* @param offset
|
||||
* the offset in <tt>sharedSecret</tt> where the shared
|
||||
* secret will be stored
|
||||
* @return the number of bytes written in <tt>sharedSecret</tt>
|
||||
* @throws IllegalStateException
|
||||
* if the key agreement scheme has not been initialized
|
||||
* properly.
|
||||
* @throws ShortBufferException
|
||||
* if <tt>sharedSecret</tt> is too small to to hold the
|
||||
* shared secret
|
||||
*/
|
||||
public abstract int generateSecret(byte[] sharedSecret, int offset)
|
||||
throws IllegalStateException, ShortBufferException;
|
||||
|
||||
/**
|
||||
* Generate a shared secret via the algorithm specified in
|
||||
* <tt>algorithm</tt>.
|
||||
*
|
||||
* @param algorithm
|
||||
* the desired algorithm for the generation of the secret
|
||||
* @return the shared secret
|
||||
* @throws IllegalStateException
|
||||
* if the key agreement scheme has not been initialized
|
||||
* properly.
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if <tt>algorithm</tt> is invalid.
|
||||
*/
|
||||
public abstract SecretKey generateSecret(String algorithm)
|
||||
throws IllegalStateException, NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* Execute the next phase of this key agreement with the given public key
|
||||
* that was received from one of the other parties involved in this key
|
||||
* agreement.
|
||||
*
|
||||
* @param pubKey
|
||||
* the public key of the other party
|
||||
* @param lastPhase
|
||||
* <tt>true</tt> if this is the last phase of the key
|
||||
* agreement. After the last phase only
|
||||
* <tt>generateSecret</tt> may be called.
|
||||
* @return the shared secret
|
||||
* @throws IllegalStateException
|
||||
* if the key agreement scheme has not been initialized
|
||||
* properly.
|
||||
* @throws InvalidKeyException
|
||||
* if the key is invalid.
|
||||
*/
|
||||
public abstract Key doPhase(PublicKey pubKey, boolean lastPhase)
|
||||
throws InvalidKeyException, IllegalStateException;
|
||||
|
||||
}
|
||||
58
src/de/flexiprovider/api/KeyDerivation.java
Normal file
58
src/de/flexiprovider/api/KeyDerivation.java
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2003 by The FlexiProvider Group,
|
||||
* Technische Universitaet Darmstadt
|
||||
*
|
||||
* For conditions of usage and distribution please refer to the
|
||||
* file COPYING in the root directory of this package.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.flexiprovider.api;
|
||||
|
||||
import de.flexiprovider.api.exceptions.InvalidAlgorithmParameterException;
|
||||
import de.flexiprovider.api.exceptions.InvalidKeyException;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameterSpec;
|
||||
|
||||
/**
|
||||
* This class defines a <b>key derivation function</b>. All the abstract
|
||||
* methods in this class must be implemented by each cryptographic service
|
||||
* provider who wishes to supply the implementation of a particular Key
|
||||
* Derivation algorithm. A key derivation function is used to generate a longer
|
||||
* or shorter secret key, with a second secret shared by both parties. The
|
||||
* derived secret key may be used by other schemes which use different key
|
||||
* length, to the normal secret keys.
|
||||
*
|
||||
* @author Jochen Hechler
|
||||
* @author Marcus St<53>gbauer
|
||||
* @author Martin D<>ring
|
||||
*/
|
||||
public abstract class KeyDerivation {
|
||||
|
||||
/**
|
||||
* Initialize this KDF with a secret and parameters.
|
||||
*
|
||||
* @param secret
|
||||
* the secret from which to derive the key
|
||||
* @param params
|
||||
* the parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the secret is invalid.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the parameters are invalid.
|
||||
*/
|
||||
public abstract void init(byte[] secret, AlgorithmParameterSpec params)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Start the derivation process and return the derived key. If supported by
|
||||
* the concrete implementation, the derived key will be of the specified
|
||||
* length.
|
||||
*
|
||||
* @param keySize
|
||||
* the desired length of the derived key
|
||||
* @return the derived key with the specified length, or <tt>null</tt> if
|
||||
* the key size is <tt>< 0</tt>.
|
||||
*/
|
||||
public abstract byte[] deriveKey(int keySize);
|
||||
|
||||
}
|
||||
211
src/de/flexiprovider/api/Mac.java
Normal file
211
src/de/flexiprovider/api/Mac.java
Normal file
@@ -0,0 +1,211 @@
|
||||
package de.flexiprovider.api;
|
||||
|
||||
import de.flexiprovider.api.exceptions.InvalidAlgorithmParameterException;
|
||||
import de.flexiprovider.api.exceptions.InvalidKeyException;
|
||||
import de.flexiprovider.api.exceptions.ShortBufferException;
|
||||
import de.flexiprovider.api.keys.SecretKey;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameterSpec;
|
||||
|
||||
/**
|
||||
* This class implements a "message authentication code" (MAC), a method to
|
||||
* ensure the integrity of data transmitted between two parties who share a
|
||||
* common secret key.
|
||||
*
|
||||
* <p>
|
||||
* The best way to describe a MAC is as a <i>keyed one-way hash function</i>,
|
||||
* which looks like:
|
||||
*
|
||||
* <blockquote>
|
||||
* <p>
|
||||
* <tt>D = MAC(K, M)</tt></blockquote>
|
||||
*
|
||||
* <p>
|
||||
* where <tt>K</tt> is the key, <tt>M</tt> is the message, and <tt>D</tt>
|
||||
* is the resulting digest. One party will usually send the concatenation
|
||||
* <tt>M || D</tt> to the other party, who will then verify <tt>D</tt> by
|
||||
* computing <tt>D'</tt> in a similar fashion. If <tt>D == D'</tt>, then
|
||||
* the message is assumed to be authentic.
|
||||
*
|
||||
* @author Martin D<>ring, Johannes M<>ller
|
||||
*/
|
||||
public abstract class Mac extends javax.crypto.MacSpi {
|
||||
|
||||
// ****************************************************
|
||||
// JCA adapter methods
|
||||
// ****************************************************
|
||||
|
||||
protected final int engineGetMacLength() {
|
||||
return getMacLength();
|
||||
}
|
||||
|
||||
protected void engineInit(java.security.Key key,
|
||||
java.security.spec.AlgorithmParameterSpec params)
|
||||
throws java.security.InvalidKeyException,
|
||||
java.security.InvalidAlgorithmParameterException {
|
||||
|
||||
if (!(key instanceof SecretKey)) {
|
||||
throw new java.security.InvalidKeyException();
|
||||
}
|
||||
if ((params != null) && !(params instanceof AlgorithmParameterSpec)) {
|
||||
throw new java.security.InvalidAlgorithmParameterException();
|
||||
}
|
||||
init((SecretKey) key, (AlgorithmParameterSpec) params);
|
||||
}
|
||||
|
||||
protected final void engineUpdate(byte input) {
|
||||
update(input);
|
||||
}
|
||||
|
||||
protected final void engineUpdate(byte[] input, int offset, int len) {
|
||||
update(input, offset, len);
|
||||
}
|
||||
|
||||
protected final byte[] engineDoFinal() {
|
||||
return doFinal();
|
||||
}
|
||||
|
||||
protected final void engineReset() {
|
||||
reset();
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// FlexiAPI methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* Return the MAC length. This method is guaranteed to return a sane value
|
||||
* only after the MAC has been initialized.
|
||||
*
|
||||
* @return the MAC length
|
||||
*/
|
||||
public abstract int getMacLength();
|
||||
|
||||
/**
|
||||
* Initialize this MAC with a key and no parameters.
|
||||
*
|
||||
* @param key
|
||||
* The key to initialize this instance with.
|
||||
* @throws InvalidKeyException
|
||||
* If the key is unacceptable.
|
||||
*/
|
||||
public final void init(SecretKey key) throws InvalidKeyException {
|
||||
try {
|
||||
init(key, null);
|
||||
} catch (InvalidAlgorithmParameterException iape) {
|
||||
throw new IllegalArgumentException("This MAC needs parameters");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this MAC with a key and parameters.
|
||||
*
|
||||
* @param key
|
||||
* The key to initialize this instance with.
|
||||
* @param params
|
||||
* The algorithm-specific parameters.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* If the algorithm parameters are unacceptable.
|
||||
* @throws InvalidKeyException
|
||||
* If the key is unacceptable.
|
||||
*/
|
||||
public abstract void init(SecretKey key, AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException, InvalidKeyException;
|
||||
|
||||
/**
|
||||
* Update the computation with a single byte.
|
||||
*
|
||||
* @param input
|
||||
* The next byte.
|
||||
*/
|
||||
public abstract void update(byte input);
|
||||
|
||||
/**
|
||||
* Update the computation with a byte array.
|
||||
*
|
||||
* @param input
|
||||
* The next bytes.
|
||||
*/
|
||||
public final void update(byte[] input) {
|
||||
update(input, 0, input.length);
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// FlexiAPI methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* Update the computation with a portion of a byte array.
|
||||
*
|
||||
* @param input
|
||||
* The next bytes.
|
||||
* @param offset
|
||||
* The index in <tt>input</tt> to start.
|
||||
* @param length
|
||||
* The number of bytes to update.
|
||||
*/
|
||||
public abstract void update(byte[] input, int offset, int length);
|
||||
|
||||
/**
|
||||
* Finishes the computation of a MAC and returns the digest.
|
||||
*
|
||||
* <p>
|
||||
* After this method succeeds, it may be used again as just after a call to
|
||||
* <tt>init</tt>, and can compute another MAC using the same key and
|
||||
* parameters.
|
||||
*
|
||||
* @return The message authentication code.
|
||||
*/
|
||||
public abstract byte[] doFinal();
|
||||
|
||||
/**
|
||||
* Finishes the computation of a MAC with a final byte array (or computes a
|
||||
* MAC over those bytes only) and returns the digest.
|
||||
*
|
||||
* <p>
|
||||
* After this method succeeds, it may be used again as just after a call to
|
||||
* <tt>init</tt>, and can compute another MAC using the same key and
|
||||
* parameters.
|
||||
*
|
||||
* @param input
|
||||
* The bytes to add.
|
||||
* @return The message authentication code.
|
||||
*/
|
||||
public final byte[] doFinal(byte[] input) {
|
||||
update(input);
|
||||
return doFinal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes the computation of a MAC and places the result into the given
|
||||
* array.
|
||||
* <p>
|
||||
* After this method succeeds, it may be used again as just after a call to
|
||||
* <tt>init</tt>, and can compute another MAC using the same key and
|
||||
* parameters.
|
||||
*
|
||||
* @param output
|
||||
* The destination for the result.
|
||||
* @param outOffset
|
||||
* The index in the output array to start.
|
||||
* @return the number of bytes stored in output.
|
||||
* @throws ShortBufferException
|
||||
* If <tt>output</tt> is not large enough to hold the
|
||||
* result.
|
||||
*/
|
||||
public final int doFinal(byte[] output, int outOffset)
|
||||
throws ShortBufferException {
|
||||
if (output.length - outOffset < getMacLength()) {
|
||||
throw new ShortBufferException();
|
||||
}
|
||||
byte[] mac = doFinal();
|
||||
System.arraycopy(mac, 0, output, outOffset, mac.length);
|
||||
return mac.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset this instance. A call to this method returns this instance back to
|
||||
* the state it was in just after it was initialized.
|
||||
*/
|
||||
public abstract void reset();
|
||||
|
||||
}
|
||||
143
src/de/flexiprovider/api/MessageDigest.java
Normal file
143
src/de/flexiprovider/api/MessageDigest.java
Normal file
@@ -0,0 +1,143 @@
|
||||
package de.flexiprovider.api;
|
||||
|
||||
import de.flexiprovider.api.exceptions.DigestException;
|
||||
|
||||
public abstract class MessageDigest extends java.security.MessageDigestSpi {
|
||||
|
||||
// ****************************************************
|
||||
// JCA adapter methods
|
||||
// ****************************************************
|
||||
|
||||
protected final int engineGetDigestLength() {
|
||||
return getDigestLength();
|
||||
}
|
||||
|
||||
protected final void engineUpdate(byte input) {
|
||||
update(input);
|
||||
}
|
||||
|
||||
protected final void engineUpdate(byte[] input, int offset, int len) {
|
||||
update(input, offset, len);
|
||||
}
|
||||
|
||||
protected final byte[] engineDigest() {
|
||||
return digest();
|
||||
}
|
||||
|
||||
protected final void engineReset() {
|
||||
reset();
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// FlexiAPI methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* @return the digest length in bytes
|
||||
*/
|
||||
public abstract int getDigestLength();
|
||||
|
||||
/**
|
||||
* Update the digest using the specified byte.
|
||||
*
|
||||
* @param input
|
||||
* the byte to use for the update
|
||||
*/
|
||||
public abstract void update(byte input);
|
||||
|
||||
/**
|
||||
* Update the digest using the specified array of bytes, starting at the
|
||||
* specified offset.
|
||||
*
|
||||
* @param input
|
||||
* the array of bytes to use for the update
|
||||
*/
|
||||
public final void update(byte[] input) {
|
||||
if (input == null) {
|
||||
return;
|
||||
}
|
||||
update(input, 0, input.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the digest using the specified array of bytes, starting at the
|
||||
* specified offset.
|
||||
*
|
||||
* @param input
|
||||
* the array of bytes to use for the update
|
||||
* @param offset
|
||||
* the offset to start from in the array of bytes
|
||||
* @param len
|
||||
* the number of bytes to use, starting at <tt>offset</tt>
|
||||
*/
|
||||
public abstract void update(byte[] input, int offset, int len);
|
||||
|
||||
/**
|
||||
* Complete the hash computation by performing final operations such as
|
||||
* padding. Once {@link #digest()} has been called, the engine should be
|
||||
* reset (see {@link #reset()}). Resetting is the responsibility of the
|
||||
* engine implementor.
|
||||
*
|
||||
* @return the array of bytes for the resulting hash value.
|
||||
*/
|
||||
public abstract byte[] digest();
|
||||
|
||||
/**
|
||||
* Update the digest and complete the hash computation by performing final
|
||||
* operations such as padding. Once {@link #digest(byte[])} has been called,
|
||||
* the engine should be reset (see {@link #reset()}). Resetting is the
|
||||
* responsibility of the engine implementor.
|
||||
*
|
||||
* @param input
|
||||
* the array of bytes to use for the update
|
||||
* @return the array of bytes for the resulting hash value
|
||||
*/
|
||||
public final byte[] digest(byte[] input) {
|
||||
update(input);
|
||||
return digest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete the hash computation by performing final operations such as
|
||||
* padding. Once {@link #digest(byte[], int, int)} has been called, the
|
||||
* engine should be reset (see {@link #reset()}). Resetting is the
|
||||
* responsibility of the engine implementor.
|
||||
*
|
||||
* @param buf
|
||||
* the output buffer in which to store the digest
|
||||
* @param offset
|
||||
* offset to start from in the output buffer
|
||||
* @param len
|
||||
* number of bytes within buf allotted for the digest. Both
|
||||
* this default implementation and the SUN provider do not
|
||||
* return partial digests. The presence of this parameter is
|
||||
* solely for consistency in our API's. If the value of this
|
||||
* parameter is less than the actual digest length, the
|
||||
* method will throw a DigestException. This parameter is
|
||||
* ignored if its value is greater than or equal to the
|
||||
* actual digest length.
|
||||
* @return the length of the digest stored in the output buffer.
|
||||
* @throws DigestException
|
||||
* if an error occurs.
|
||||
*/
|
||||
public final int digest(byte[] buf, int offset, int len)
|
||||
throws DigestException {
|
||||
|
||||
byte[] digest = digest();
|
||||
if (len < digest.length) {
|
||||
throw new DigestException("partial digests not returned");
|
||||
}
|
||||
if (buf.length - offset < digest.length) {
|
||||
throw new DigestException("insufficient space in the output "
|
||||
+ "buffer to store the digest");
|
||||
}
|
||||
System.arraycopy(digest, 0, buf, offset, digest.length);
|
||||
return digest.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the digest for further use.
|
||||
*/
|
||||
public abstract void reset();
|
||||
|
||||
}
|
||||
236
src/de/flexiprovider/api/Mode.java
Normal file
236
src/de/flexiprovider/api/Mode.java
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2003 by The FlexiProvider Group,
|
||||
* Technische Universitaet Darmstadt
|
||||
*
|
||||
* For conditions of usage and distribution please refer to the
|
||||
* file COPYING in the root directory of this package.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.flexiprovider.api;
|
||||
|
||||
import de.flexiprovider.api.exceptions.InvalidAlgorithmParameterException;
|
||||
import de.flexiprovider.api.exceptions.InvalidKeyException;
|
||||
import de.flexiprovider.api.keys.SecretKey;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameterSpec;
|
||||
import de.flexiprovider.common.mode.ModeParameterSpec;
|
||||
|
||||
/**
|
||||
* The abstract class Mode is the base for all modes implemented in the package
|
||||
* cdc. It defines the set of methods which have to be implemented to cooperate
|
||||
* with the BasicCipher class. Each class that implements such a mode has to
|
||||
* exist in the package "de.flexiprovider.common.mode" and the classname must be
|
||||
* the same as the name used in the call of <tt>Cipher.getInstance()</tt>.
|
||||
* e.g. if you call <tt>Cipher.getInstance("SAFER+/CBC/NoPadding")</tt>, the
|
||||
* code will look for the class de.flexiprovider.common.mode.CBC
|
||||
*
|
||||
* @author Marcus Lippert
|
||||
* @author Ralf-Philipp Weinmann
|
||||
*/
|
||||
public abstract class Mode {
|
||||
|
||||
/**
|
||||
* Reference to the underlying block cipher
|
||||
*/
|
||||
private BlockCipher blockCipher;
|
||||
|
||||
/**
|
||||
* The initialization vector
|
||||
*/
|
||||
protected byte[] iv;
|
||||
|
||||
/**
|
||||
* The block size of the mode
|
||||
*/
|
||||
protected int blockSize;
|
||||
|
||||
/**
|
||||
* Set the {@link BlockCipher} to use with this mode.
|
||||
*
|
||||
* @param blockCipher
|
||||
* the block cipher
|
||||
*/
|
||||
final void setBlockCipher(BlockCipher blockCipher) {
|
||||
this.blockCipher = blockCipher;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------
|
||||
* Mode specific abstract methods
|
||||
---------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Initialize the Mode object for encryption and compute the mode block
|
||||
* size. This value usually depends on the block size of the used block
|
||||
* cipher. It is supposed that all block ciphers return a sane value via
|
||||
* {@link BlockCipher#getCipherBlockSize()} after initialization.
|
||||
*
|
||||
* @param key
|
||||
* the key used for encryption
|
||||
* @param modeParams
|
||||
* additional mode parameters
|
||||
* @param cipherParams
|
||||
* additional algorithm parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the key is inappropriate for initializing the
|
||||
* underlying block cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the parameters are inappropriate for initializing the
|
||||
* underlying block cipher.
|
||||
*/
|
||||
protected abstract void initEncrypt(SecretKey key,
|
||||
ModeParameterSpec modeParams, AlgorithmParameterSpec cipherParams)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Initialize the Mode object for decryption and compute the mode block
|
||||
* size. This value usually depends on the block size of the used block
|
||||
* cipher. It is supposed that all block ciphers return a sane value via
|
||||
* {@link BlockCipher#getCipherBlockSize()} after initialization.
|
||||
*
|
||||
* @param key
|
||||
* the key used for decryption
|
||||
* @param modeParams
|
||||
* additional mode parameters
|
||||
* @param cipherParams
|
||||
* additional algorithm parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the key is inappropriate for initializing the
|
||||
* underlying block cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the parameters are inappropriate for initializing the
|
||||
* underlying block cipher.
|
||||
*/
|
||||
protected abstract void initDecrypt(SecretKey key,
|
||||
ModeParameterSpec modeParams, AlgorithmParameterSpec cipherParams)
|
||||
throws InvalidKeyException, InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Encrypt the next data block. Any special features of the Mode should be
|
||||
* implemented here.
|
||||
*
|
||||
* @param input
|
||||
* input data buffer
|
||||
* @param inOff
|
||||
* input data offset
|
||||
* @param output
|
||||
* output data buffer
|
||||
* @param outOff
|
||||
* output data offset
|
||||
*/
|
||||
protected abstract void nextChunkEncrypt(final byte[] input,
|
||||
final int inOff, byte[] output, final int outOff);
|
||||
|
||||
/**
|
||||
* Decrypt the next data block. Any special features of the Mode should be
|
||||
* implemented here.
|
||||
*
|
||||
* @param input
|
||||
* input data buffer
|
||||
* @param inOff
|
||||
* input data offset
|
||||
* @param output
|
||||
* output data buffer
|
||||
* @param outOff
|
||||
* output data offset
|
||||
*/
|
||||
protected abstract void nextChunkDecrypt(final byte[] input,
|
||||
final int inOff, byte[] output, final int outOff);
|
||||
|
||||
/**
|
||||
* reset() is called after doFinal() in order to prepare the mode for the
|
||||
* next operation.
|
||||
*/
|
||||
protected abstract void reset();
|
||||
|
||||
/*---------------------------------------------------
|
||||
* Adapter classes to BlockCipher
|
||||
---------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Initialize the block cipher for encryption.
|
||||
*
|
||||
* @param key
|
||||
* the secret key to use for encryption
|
||||
* @param cipherParams
|
||||
* the parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for this cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given parameters are inappropriate for this
|
||||
* cipher.
|
||||
*/
|
||||
protected final void initCipherEncrypt(SecretKey key,
|
||||
AlgorithmParameterSpec cipherParams) throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException {
|
||||
blockCipher.initCipherEncrypt(key, cipherParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the block cipher for decryption.
|
||||
*
|
||||
* @param key
|
||||
* the secret key to use for decryption
|
||||
* @param cipherParams
|
||||
* the parameters
|
||||
* @throws InvalidKeyException
|
||||
* if the given key is inappropriate for this cipher.
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given parameters are inappropriate for this
|
||||
* cipher.
|
||||
*/
|
||||
protected final void initCipherDecrypt(SecretKey key,
|
||||
AlgorithmParameterSpec cipherParams) throws InvalidKeyException,
|
||||
InvalidAlgorithmParameterException {
|
||||
blockCipher.initCipherDecrypt(key, cipherParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the block size of the underlying cipher. It is supposed that all
|
||||
* block ciphers return a sane value via
|
||||
* {@link BlockCipher#getCipherBlockSize()} after initialization.
|
||||
*
|
||||
* @return the block size of the underlying cipher
|
||||
*/
|
||||
protected final int getCipherBlockSize() {
|
||||
return blockCipher.getCipherBlockSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt a single block with the cipher engine.
|
||||
*
|
||||
* @param input
|
||||
* array of bytes which contains the plaintext to be
|
||||
* encrypted
|
||||
* @param inOff
|
||||
* index in array in, where the plaintext block starts
|
||||
* @param output
|
||||
* array of bytes which will contain the ciphertext startig
|
||||
* at outOffset
|
||||
* @param outOff
|
||||
* index in array out, where the ciphertext block will start
|
||||
*/
|
||||
protected final void singleBlockEncrypt(byte[] input, int inOff,
|
||||
byte[] output, int outOff) {
|
||||
blockCipher.singleBlockEncrypt(input, inOff, output, outOff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt a single block with the cipher engine.
|
||||
*
|
||||
* @param input
|
||||
* array of bytes which contains the ciphertext to be
|
||||
* decrypted
|
||||
* @param inOff
|
||||
* index in array in, where the ciphertext block starts
|
||||
* @param output
|
||||
* array of bytes which will contain the plaintext starting
|
||||
* at outOffset
|
||||
* @param outOff
|
||||
* index in array out, where the plaintext block will start
|
||||
*/
|
||||
protected final void singleBlockDecrypt(byte[] input, int inOff,
|
||||
byte[] output, int outOff) {
|
||||
blockCipher.singleBlockDecrypt(input, inOff, output, outOff);
|
||||
}
|
||||
|
||||
}
|
||||
99
src/de/flexiprovider/api/PaddingScheme.java
Normal file
99
src/de/flexiprovider/api/PaddingScheme.java
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2003 by The FlexiProvider Group,
|
||||
* Technische Universitaet Darmstadt
|
||||
*
|
||||
* For conditions of usage and distribution please refer to the
|
||||
* file COPYING in the root directory of this package.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.flexiprovider.api;
|
||||
|
||||
import de.flexiprovider.api.exceptions.BadPaddingException;
|
||||
|
||||
/**
|
||||
* To encrypt a plaintext with a block cipher the input is divided into blocks
|
||||
* whose length depends on the encryption algorithm used. To ensure that the
|
||||
* block size will divide the length of the input, the last block is padded to
|
||||
* the needed length. Vice versa, when decrypting a ciphertext, the padding has
|
||||
* to be removed.
|
||||
* <p>
|
||||
* To make a new padding scheme available, one has to write a subclass of
|
||||
* <tt>de.flexiprovider.common.padding.PaddingScheme</tt> in order to allow a
|
||||
* blockcipher to use it. This subclass has to exist in the package
|
||||
* <tt>de.flexiprovider.common.padding</tt> and the class name must be the
|
||||
* same as the name used in the call of Cipher.getInstance(). E.g., if you call
|
||||
* Cipher.getInstance("SAFER+/CBC/NoPadding"), then there must exist a class
|
||||
* <tt>de.flexiprovider.common.padding.NoPadding</tt>.
|
||||
*
|
||||
* @author Christoph Ender
|
||||
* @author Christoph Sesterhenn
|
||||
* @author Marcus Lippert
|
||||
* @author Martin Strese
|
||||
*/
|
||||
public abstract class PaddingScheme {
|
||||
|
||||
/**
|
||||
* Block size used for padding
|
||||
*/
|
||||
protected int blockSize = -1;
|
||||
|
||||
/**
|
||||
* Tell the padding scheme the block size to which input will be padded.
|
||||
*
|
||||
* @param blockSize
|
||||
* length of one block
|
||||
*/
|
||||
final void setBlockSize(int blockSize) {
|
||||
if (blockSize > 0) {
|
||||
this.blockSize = blockSize;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of bytes which will be appended to the the plaintext
|
||||
* during padding.
|
||||
*
|
||||
* @param inLen
|
||||
* the length of the plaintext to be padded
|
||||
* @return the number of padding bytes (may be 0)
|
||||
*/
|
||||
protected abstract int padLength(int inLen);
|
||||
|
||||
/**
|
||||
* Pad the input to make its length divisible by the the block length. The
|
||||
* padding is written to the same buffer which is used for input. The caller
|
||||
* has to ensure that the input array is large enough to hold the padding
|
||||
* bytes.
|
||||
*
|
||||
* @param input
|
||||
* byte array containing the plaintext to be padded
|
||||
* @param inOff
|
||||
* index where the plaintext starts
|
||||
* @param inLen
|
||||
* length of the plaintext
|
||||
* @throws BadPaddingException
|
||||
* if the input buffer is too small to hold the padding
|
||||
* bytes.
|
||||
*/
|
||||
protected abstract void pad(byte[] input, int inOff, int inLen)
|
||||
throws BadPaddingException;
|
||||
|
||||
/**
|
||||
* Given the plaintext that includes the padding bytes, unpad the plaintext
|
||||
* and return the index indicating where the padding bytes start.
|
||||
*
|
||||
* @param input
|
||||
* byte array containing the padded plaintext
|
||||
* @param inOff
|
||||
* index where the plaintext starts
|
||||
* @param inLen
|
||||
* size of the plaintext
|
||||
* @return index in the array where the padding bytes start
|
||||
* @throws BadPaddingException
|
||||
* if unpadding fails.
|
||||
*/
|
||||
protected abstract int unpad(byte[] input, int inOff, int inLen)
|
||||
throws BadPaddingException;
|
||||
|
||||
}
|
||||
804
src/de/flexiprovider/api/Registry.java
Normal file
804
src/de/flexiprovider/api/Registry.java
Normal file
@@ -0,0 +1,804 @@
|
||||
package de.flexiprovider.api;
|
||||
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Vector;
|
||||
|
||||
import de.flexiprovider.api.exceptions.InvalidAlgorithmParameterException;
|
||||
import de.flexiprovider.api.exceptions.NoSuchAlgorithmException;
|
||||
import de.flexiprovider.api.exceptions.NoSuchModeException;
|
||||
import de.flexiprovider.api.exceptions.NoSuchPaddingException;
|
||||
import de.flexiprovider.api.exceptions.RegistrationException;
|
||||
import de.flexiprovider.api.keys.KeyFactory;
|
||||
import de.flexiprovider.api.keys.KeyPairGenerator;
|
||||
import de.flexiprovider.api.keys.SecretKeyFactory;
|
||||
import de.flexiprovider.api.keys.SecretKeyGenerator;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameterGenerator;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameterSpec;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameters;
|
||||
import de.flexiprovider.common.mode.CBC;
|
||||
import de.flexiprovider.common.mode.CFB;
|
||||
import de.flexiprovider.common.mode.CFBParameterSpec;
|
||||
import de.flexiprovider.common.mode.CTR;
|
||||
import de.flexiprovider.common.mode.ECB;
|
||||
import de.flexiprovider.common.mode.ModeParamGenParameterSpec;
|
||||
import de.flexiprovider.common.mode.ModeParameterGenerator;
|
||||
import de.flexiprovider.common.mode.ModeParameterSpec;
|
||||
import de.flexiprovider.common.mode.ModeParameters;
|
||||
import de.flexiprovider.common.mode.OFB;
|
||||
import de.flexiprovider.common.mode.OFBParameterSpec;
|
||||
import de.flexiprovider.common.padding.NoPadding;
|
||||
import de.flexiprovider.common.padding.OneAndZeroesPadding;
|
||||
import de.flexiprovider.common.padding.PKCS5Padding;
|
||||
import de.flexiprovider.common.util.DefaultPRNG;
|
||||
|
||||
/**
|
||||
* This class is responsible for the registration and instantiation of all
|
||||
* cryptographic algorithms of the FlexiProvider. It provides methods for adding
|
||||
* registrations of algorithms and methods for instantiating registered
|
||||
* algorithms.
|
||||
*
|
||||
* @author Johannes M<>ller
|
||||
* @author Martin D<>ring
|
||||
*/
|
||||
public abstract class Registry {
|
||||
|
||||
/* algorithm type constants */
|
||||
|
||||
/**
|
||||
* Constant for asymmetric block ciphers
|
||||
*/
|
||||
public static final int ASYMMETRIC_BLOCK_CIPHER = 0;
|
||||
|
||||
/**
|
||||
* Constant for asymmetric hybrid ciphers
|
||||
*/
|
||||
public static final int ASYMMETRIC_HYBRID_CIPHER = 1;
|
||||
|
||||
/**
|
||||
* Constant for symmetric block ciphers
|
||||
*/
|
||||
public static final int BLOCK_CIPHER = 2;
|
||||
|
||||
/**
|
||||
* Constant for modes of operation
|
||||
*/
|
||||
public static final int MODE = 3;
|
||||
|
||||
/**
|
||||
* Constant for padding schemes
|
||||
*/
|
||||
public static final int PADDING_SCHEME = 4;
|
||||
|
||||
/**
|
||||
* Constant for generic ciphers
|
||||
*/
|
||||
public static final int CIPHER = 5;
|
||||
|
||||
/**
|
||||
* Constant for message authentication codes (MACs)
|
||||
*/
|
||||
public static final int MAC = 6;
|
||||
|
||||
/**
|
||||
* Constant for message digests (hash functions)
|
||||
*/
|
||||
public static final int MESSAGE_DIGEST = 7;
|
||||
|
||||
/**
|
||||
* Constant for PRNGs
|
||||
*/
|
||||
public static final int SECURE_RANDOM = 8;
|
||||
|
||||
/**
|
||||
* Constant for digital signatures
|
||||
*/
|
||||
public static final int SIGNATURE = 9;
|
||||
|
||||
/**
|
||||
* Constant for algorithm parameter specifications
|
||||
*/
|
||||
public static final int ALG_PARAM_SPEC = 10;
|
||||
|
||||
/**
|
||||
* Constant for algorithm parameters (used to encode and decode parameter
|
||||
* specifications)
|
||||
*/
|
||||
public static final int ALG_PARAMS = 11;
|
||||
|
||||
/**
|
||||
* Constant for algorithm parameter generators
|
||||
*/
|
||||
public static final int ALG_PARAM_GENERATOR = 12;
|
||||
|
||||
/**
|
||||
* Constant for secret key generators
|
||||
*/
|
||||
public static final int SECRET_KEY_GENERATOR = 13;
|
||||
|
||||
/**
|
||||
* Constant for key pair generators
|
||||
*/
|
||||
public static final int KEY_PAIR_GENERATOR = 14;
|
||||
|
||||
/**
|
||||
* Constant for secret key factories
|
||||
*/
|
||||
public static final int SECRET_KEY_FACTORY = 15;
|
||||
|
||||
/**
|
||||
* Constant for key factories
|
||||
*/
|
||||
public static final int KEY_FACTORY = 16;
|
||||
|
||||
/**
|
||||
* Constant for key derivations
|
||||
*/
|
||||
public static final int KEY_DERIVATION = 17;
|
||||
|
||||
/**
|
||||
* Constant for key agreements
|
||||
*/
|
||||
public static final int KEY_AGREEMENT = 18;
|
||||
|
||||
/* hash tables for the different algorithm types */
|
||||
|
||||
private static final Hashtable asymBlockCiphers = new Hashtable();
|
||||
private static final Hashtable asymHybridCiphers = new Hashtable();
|
||||
private static final Hashtable blockCiphers = new Hashtable();
|
||||
private static final Hashtable modes = new Hashtable();
|
||||
private static final Hashtable paddingSchemes = new Hashtable();
|
||||
private static final Hashtable ciphers = new Hashtable();
|
||||
private static final Hashtable macs = new Hashtable();
|
||||
private static final Hashtable messageDigests = new Hashtable();
|
||||
private static final Hashtable secureRandoms = new Hashtable();
|
||||
private static final Hashtable signatures = new Hashtable();
|
||||
private static final Hashtable algParamSpecs = new Hashtable();
|
||||
private static final Hashtable algParams = new Hashtable();
|
||||
private static final Hashtable algParamGenerators = new Hashtable();
|
||||
private static final Hashtable secretKeyGenerators = new Hashtable();
|
||||
private static final Hashtable keyPairGenerators = new Hashtable();
|
||||
private static final Hashtable secretKeyFactories = new Hashtable();
|
||||
private static final Hashtable keyFactories = new Hashtable();
|
||||
private static final Hashtable keyDerivations = new Hashtable();
|
||||
private static final Hashtable keyAgreements = new Hashtable();
|
||||
|
||||
// array holding all hash tables (indexed by algorithm type)
|
||||
private static final Hashtable[] hashtables = { asymBlockCiphers,
|
||||
asymHybridCiphers, blockCiphers, modes, paddingSchemes, ciphers,
|
||||
macs, messageDigests, secureRandoms, signatures, algParamSpecs,
|
||||
algParams, algParamGenerators, secretKeyGenerators,
|
||||
keyPairGenerators, secretKeyFactories, keyFactories,
|
||||
keyDerivations, keyAgreements };
|
||||
|
||||
// array holding all algorithm types (used for registration type checking)
|
||||
private static final Class[] algClasses = { AsymmetricBlockCipher.class,
|
||||
AsymmetricHybridCipher.class, BlockCipher.class, Mode.class,
|
||||
PaddingScheme.class, Cipher.class, Mac.class, MessageDigest.class,
|
||||
SecureRandom.class, Signature.class, AlgorithmParameterSpec.class,
|
||||
AlgorithmParameters.class, AlgorithmParameterGenerator.class,
|
||||
SecretKeyGenerator.class, KeyPairGenerator.class,
|
||||
SecretKeyFactory.class, KeyFactory.class, KeyDerivation.class,
|
||||
KeyAgreement.class };
|
||||
|
||||
// hash table for standard algorithm parameters
|
||||
private static final Hashtable standardAlgParams = new Hashtable();
|
||||
|
||||
static {
|
||||
add(ALG_PARAM_SPEC, CFBParameterSpec.class, "CFB");
|
||||
add(ALG_PARAM_SPEC, OFBParameterSpec.class, "OFB");
|
||||
add(ALG_PARAM_SPEC, ModeParameterSpec.class, new String[] { "Mode",
|
||||
"IV" });
|
||||
add(ALG_PARAMS, ModeParameters.class, new String[] { "Mode", "IV" });
|
||||
add(ALG_PARAM_SPEC, ModeParamGenParameterSpec.class, new String[] {
|
||||
"ModeParamGen", "IVParamGen" });
|
||||
add(ALG_PARAM_GENERATOR, ModeParameterGenerator.class, new String[] {
|
||||
"Mode", "IV" });
|
||||
|
||||
add(MODE, ECB.class, "ECB");
|
||||
add(MODE, CBC.class, "CBC");
|
||||
add(MODE, OFB.class, "OFB");
|
||||
add(MODE, CFB.class, "CFB");
|
||||
add(MODE, CTR.class, "CTR");
|
||||
|
||||
add(PADDING_SCHEME, NoPadding.class, "NoPadding");
|
||||
add(PADDING_SCHEME, OneAndZeroesPadding.class, "OneAndZeroesPadding");
|
||||
add(PADDING_SCHEME, PKCS5Padding.class, "PKCS5Padding");
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an algorithm of the given type under the given name.
|
||||
*
|
||||
* @param type
|
||||
* the algorithm type
|
||||
* @param algClass
|
||||
* the class implementing the algorithm
|
||||
* @param algName
|
||||
* the name for the algorithm
|
||||
* @throws RegistrationException
|
||||
* if the expected and actual algorithm types do not match or an
|
||||
* algorithm is already registered under the given name.
|
||||
*/
|
||||
public static final void add(int type, Class algClass, String algName) {
|
||||
add(type, algClass, new String[] { algName });
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an algorithm of the given type under the given names.
|
||||
*
|
||||
* @param type
|
||||
* the algorithm type
|
||||
* @param algClass
|
||||
* the class implementing the algorithm
|
||||
* @param algNames
|
||||
* the names for the algorithm
|
||||
* @throws RegistrationException
|
||||
* if the expected and actual algorithm types do not match or an
|
||||
* algorithm is already registered under one of the given names.
|
||||
*/
|
||||
public static final void add(int type, Class algClass, String[] algNames) {
|
||||
Hashtable table = getHashtable(type);
|
||||
// trivial cases
|
||||
if ((table == null) || (algClass == null) || (algNames == null)
|
||||
|| (algNames.length == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// type checking
|
||||
Class expClass = algClasses[type];
|
||||
if (!expClass.isAssignableFrom(algClass)) {
|
||||
throw new RegistrationException(
|
||||
"expected and actual algorithm types do not match");
|
||||
}
|
||||
|
||||
// register first name
|
||||
table.put(algNames[0], algClass);
|
||||
|
||||
// register additional names (aliases)
|
||||
for (int i = 1; i < algNames.length; i++) {
|
||||
table.put(algNames[i], algNames[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all algorithms of the given type.
|
||||
*
|
||||
* @param type
|
||||
* the algorithm type
|
||||
* @return an {@link Enumeration} of all algorithms contained in the hash
|
||||
* table
|
||||
*/
|
||||
public static final Enumeration getAlgorithms(int type) {
|
||||
Hashtable table = getHashtable(type);
|
||||
if (table == null) {
|
||||
return null;
|
||||
}
|
||||
return table.keys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all names of the given algorithm and type.
|
||||
*
|
||||
* @param type
|
||||
* the algorithm type
|
||||
* @param name
|
||||
* (one of the) names of the algorithm
|
||||
* @return a {@link Vector} containing all names of the algorithm
|
||||
*/
|
||||
public static final Vector getNames(int type, String name) {
|
||||
Hashtable table = getHashtable(type);
|
||||
if (table == null) {
|
||||
return null;
|
||||
}
|
||||
Enumeration algorithms = getAlgorithms(type);
|
||||
Object target = resolveAlias(table, name);
|
||||
Vector result = new Vector();
|
||||
while (algorithms.hasMoreElements()) {
|
||||
String key = (String) algorithms.nextElement();
|
||||
if (resolveAlias(table, key).equals(target)) {
|
||||
result.addElement(key);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified asymmetric block cipher.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the asymmetric block cipher
|
||||
* @return a new {@link AsymmetricBlockCipher} object implementing the
|
||||
* chosen algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the asymmetric block cipher cannot be found.
|
||||
*/
|
||||
public static final AsymmetricBlockCipher getAsymmetricBlockCipher(
|
||||
String algName) throws NoSuchAlgorithmException {
|
||||
return (AsymmetricBlockCipher) getInstance(asymBlockCiphers, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified asymmetric hybrid cipher.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the asymmetric hybrid cipher
|
||||
* @return a new {@link AsymmetricHybridCipher} object implementing the
|
||||
* chosen algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the asymmetric hybrid cipher cannot be found.
|
||||
*/
|
||||
public static final AsymmetricHybridCipher getAsymmetricHybridCipher(
|
||||
String algName) throws NoSuchAlgorithmException {
|
||||
return (AsymmetricHybridCipher) getInstance(asymHybridCiphers, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find an algorithm with the specified name inside the corresponding
|
||||
* hashtable and return an instance of the algorithm.
|
||||
*
|
||||
* @param transformation
|
||||
* the transformation (either of the form 'algorithm' or
|
||||
* 'algorithm/mode/padding')
|
||||
* @return block cipher object
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the block cipher or mode cannot be found.
|
||||
* @throws NoSuchPaddingException
|
||||
* if the padding scheme cannot be found.
|
||||
*/
|
||||
public static final BlockCipher getBlockCipher(String transformation)
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException {
|
||||
|
||||
String algName, modeName = null, paddingName = null;
|
||||
int endIndex = transformation.indexOf('/');
|
||||
if (endIndex < 0) {
|
||||
// transformation is of the form 'algorithm'
|
||||
algName = transformation;
|
||||
} else {
|
||||
// transformation is of the form 'algorithm/mode/padding'
|
||||
|
||||
// get 'algorithm'
|
||||
algName = transformation.substring(0, endIndex);
|
||||
|
||||
// get 'mode/padding'
|
||||
String modePadding = transformation.substring(endIndex + 1);
|
||||
endIndex = modePadding.indexOf("/");
|
||||
if (endIndex == -1) {
|
||||
// if no padding is specified
|
||||
throw new NoSuchAlgorithmException(
|
||||
"Badly formed transformation: only 'algorithm' "
|
||||
+ "or 'algorithm/mode/padding' allowed.");
|
||||
}
|
||||
|
||||
// get 'mode'
|
||||
modeName = modePadding.substring(0, endIndex);
|
||||
|
||||
// get 'padding'
|
||||
paddingName = modePadding.substring(endIndex + 1);
|
||||
|
||||
// if even more information is provided, transformation is invalid
|
||||
if (paddingName.indexOf("/") != -1) {
|
||||
throw new NoSuchAlgorithmException(
|
||||
"Badly formed transformation: only 'algorithm' "
|
||||
+ "or 'algorithm/mode/padding' allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
BlockCipher result = (BlockCipher) getInstance(blockCiphers, algName);
|
||||
if(modeName != null)
|
||||
result.setMode(modeName);
|
||||
if(paddingName != null)
|
||||
result.setPadding(paddingName);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an instance of the default mode (CBC)
|
||||
*/
|
||||
protected static final Mode getMode() {
|
||||
return new CBC();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified mode.
|
||||
*
|
||||
* @param modeName
|
||||
* the name of the mode
|
||||
* @return a new {@link Mode} object implementing the chosen algorithm
|
||||
* @throws NoSuchModeException
|
||||
* if the mode cannot be found.
|
||||
*/
|
||||
protected static final Mode getMode(String modeName)
|
||||
throws NoSuchModeException {
|
||||
try {
|
||||
return (Mode) getInstance(modes, modeName);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new NoSuchModeException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an instance of the default padding scheme (PKCS5Padding)
|
||||
*/
|
||||
protected static final PaddingScheme getPaddingScheme() {
|
||||
return new PKCS5Padding();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified padding scheme.
|
||||
*
|
||||
* @param paddingName
|
||||
* the name of the padding scheme
|
||||
* @return a new {@link PaddingScheme} object implementing the chosen
|
||||
* algorithm
|
||||
* @throws NoSuchPaddingException
|
||||
* if the padding scheme cannot be found.
|
||||
*/
|
||||
protected static final PaddingScheme getPaddingScheme(String paddingName)
|
||||
throws NoSuchPaddingException {
|
||||
try {
|
||||
return (PaddingScheme) getInstance(paddingSchemes, paddingName);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new NoSuchPaddingException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified cipher.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the cipher
|
||||
* @return a new {@link Cipher} object implementing the chosen algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the cipher cannot be found.
|
||||
*/
|
||||
public static final Cipher getCipher(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return (Cipher) getInstance(ciphers, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified message authentication code (MAC).
|
||||
*
|
||||
* @param algName
|
||||
* the name of the MAC
|
||||
* @return a new {@link Mac} object implementing the chosen algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the MAC cannot be found.
|
||||
*/
|
||||
public static final Mac getMAC(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return (Mac) getInstance(macs, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified message digest.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the message digest
|
||||
* @return a new {@link MessageDigest} object implementing the chosen
|
||||
* algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the message digest cannot be found.
|
||||
*/
|
||||
public static final MessageDigest getMessageDigest(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return (MessageDigest) getInstance(messageDigests, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified source of randomness.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the source of randomness
|
||||
* @return a new {@link SecureRandom} object implementing the chosen
|
||||
* algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the source of randomness cannot be found.
|
||||
*/
|
||||
public static final SecureRandom getSecureRandom(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return (SecureRandom) getInstance(secureRandoms, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the default secure random
|
||||
* @throws RuntimeException
|
||||
* if the default secure random cannot be instantiated.
|
||||
*/
|
||||
public static final SecureRandom getSecureRandom() {
|
||||
return new DefaultPRNG();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified signature.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the signature
|
||||
* @return a new {@link Signature} object implementing the chosen algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the signature cannot be found.
|
||||
*/
|
||||
public static final Signature getSignature(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return (Signature) getInstance(signatures, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the algorithm parameter specification class corresponding to the
|
||||
* given algorithm name.
|
||||
*
|
||||
* @param algName
|
||||
* the algorithm name
|
||||
* @return the corresponding algorithm parameter specification class
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the parameters class cannot be found.
|
||||
*/
|
||||
public static final Class getAlgParamSpecClass(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
Class algorithmClass = (Class) resolveAlias(algParamSpecs, algName);
|
||||
if (algorithmClass == null) {
|
||||
throw new NoSuchAlgorithmException(algName);
|
||||
}
|
||||
return algorithmClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the algorithm parameter specification class
|
||||
* corresponding to the given algorithm name.
|
||||
*
|
||||
* @param paramName
|
||||
* the name of the standard algorithm parameters
|
||||
* @return the standard algorithm parameters
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the parameters cannot be found.
|
||||
*/
|
||||
public static final AlgorithmParameterSpec getAlgParamSpec(String paramName)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
try {
|
||||
return (AlgorithmParameterSpec) getInstance(algParamSpecs,
|
||||
paramName);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"Unknown parameters: '" + paramName + "'.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a list of (names of) standardized algorithm parameters for the
|
||||
* given algorithm. Additionally, each parameter set has to be registered
|
||||
* separately using the {@link #add(int, Class, String)} or
|
||||
* {@link #add(int, Class, String[])} method with the
|
||||
* {@link #ALG_PARAM_SPEC} type.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the algorithm
|
||||
* @param paramNames
|
||||
* the names of the standardized algorithm parameters suitable
|
||||
* for the specified algorithm
|
||||
*/
|
||||
public static final void addStandardAlgParams(String algName,
|
||||
String[] paramNames) {
|
||||
addStandardAlgParams(new String[] { algName }, paramNames);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a list of standardized algorithm parameters for the given list
|
||||
* of algorithms. Additionally, each parameter set has to be registered
|
||||
* separately using the {@link #add(int, Class, String)} or
|
||||
* {@link #add(int, Class, String[])} method with the
|
||||
* {@link #ALG_PARAM_SPEC} type.
|
||||
*
|
||||
* @param algNames
|
||||
* the names of the algorithms
|
||||
* @param paramNames
|
||||
* the names of the standardized algorithm parameters suitable
|
||||
* for the specified algorithm
|
||||
*/
|
||||
public static final void addStandardAlgParams(String[] algNames,
|
||||
String[] paramNames) {
|
||||
|
||||
if ((algNames == null) || (paramNames == null)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// build vector containing the parameter set names
|
||||
Vector params = new Vector(paramNames.length);
|
||||
for (int i = 0; i < paramNames.length; i++) {
|
||||
params.addElement(paramNames[i]);
|
||||
}
|
||||
|
||||
// register first name
|
||||
standardAlgParams.put(algNames[0], params);
|
||||
|
||||
// register additional names (aliases)
|
||||
for (int i = 1; i < algNames.length; i++) {
|
||||
standardAlgParams.put(algNames[i], algNames[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the set of standardized algorithm parameters registered for the
|
||||
* given algorithm, or <tt>null</tt> if no parameters are registered for the
|
||||
* given algorithm.
|
||||
*
|
||||
* @param algName
|
||||
* the algorithm name
|
||||
* @return the {@link Vector} of standardized algorithms parameters for the
|
||||
* specified algorithm, or <tt>null</tt> if no parameters are
|
||||
* registered for the algorithm
|
||||
*/
|
||||
public static final Vector getStandardAlgParams(String algName) {
|
||||
return (Vector) resolveAlias(standardAlgParams, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified algorithm parameters.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the algorithm parameters
|
||||
* @return a new {@link AlgorithmParameters} object implementing the chosen
|
||||
* algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the algorithm parameters cannot be found.
|
||||
*/
|
||||
public static final AlgorithmParameters getAlgParams(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return (AlgorithmParameters) getInstance(algParams, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified algorithm parameter generator.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the algorithm parameter generator
|
||||
* @return a new {@link AlgorithmParameterGenerator} object implementing the
|
||||
* chosen algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the algorithm parameter generator cannot be found.
|
||||
*/
|
||||
public static final AlgorithmParameterGenerator getAlgParamGenerator(
|
||||
String algName) throws NoSuchAlgorithmException {
|
||||
return (AlgorithmParameterGenerator) getInstance(algParamGenerators,
|
||||
algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified secret key generator.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the secret key generator
|
||||
* @return a new {@link SecretKeyGenerator} object implementing the chosen
|
||||
* algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the secret key generator cannot be found.
|
||||
*/
|
||||
public static final SecretKeyGenerator getSecretKeyGenerator(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return (SecretKeyGenerator) getInstance(secretKeyGenerators, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified key pair generator.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the key pair generator
|
||||
* @return a new {@link KeyPairGenerator} object implementing the chosen
|
||||
* algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the key pair generator cannot be found.
|
||||
*/
|
||||
public static final KeyPairGenerator getKeyPairGenerator(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return (KeyPairGenerator) getInstance(keyPairGenerators, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified secret key factory.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the secret key factory
|
||||
* @return a new {@link SecretKeyFactory} object implementing the chosen
|
||||
* algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the secret key factory cannot be found.
|
||||
*/
|
||||
public static final SecretKeyFactory getSecretKeyFactory(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return (SecretKeyFactory) getInstance(secretKeyFactories, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified key factory.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the key factory
|
||||
* @return a new {@link KeyFactory} object implementing the chosen algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the key factory cannot be found.
|
||||
*/
|
||||
public static final KeyFactory getKeyFactory(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return (KeyFactory) getInstance(keyFactories, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified key derivation function.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the key derivation function
|
||||
* @return a new {@link KeyDerivation} object implementing the chosen
|
||||
* algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the key derivation cannot be found.
|
||||
*/
|
||||
public static final KeyDerivation getKeyDerivation(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return (KeyDerivation) getInstance(keyDerivations, algName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an instance of the specified key agreement scheme.
|
||||
*
|
||||
* @param algName
|
||||
* the name of the key agreement scheme
|
||||
* @return a new {@link KeyAgreement} object implementing the chosen
|
||||
* algorithm
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the key agreement scheme cannot be found.
|
||||
*/
|
||||
public static final KeyAgreement getKeyAgreement(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
return (KeyAgreement) getInstance(keyAgreements, algName);
|
||||
}
|
||||
|
||||
private static Hashtable getHashtable(int type) {
|
||||
if (type > hashtables.length) {
|
||||
return null;
|
||||
}
|
||||
return hashtables[type];
|
||||
}
|
||||
|
||||
private static Object resolveAlias(Hashtable table, String name) {
|
||||
Object value = name;
|
||||
do {
|
||||
String algName = (String) value;
|
||||
value = table.get(algName);
|
||||
} while (value != null && (value instanceof String));
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to find an algorithm with the specified name inside the corresponding
|
||||
* hashtable and return an instance of the algorithm.
|
||||
*
|
||||
* @param table
|
||||
* hashtable containing the algorithm
|
||||
* @param name
|
||||
* the algorithm name
|
||||
* @return a new object implementing the chosen algorithm, or <tt>null</tt>
|
||||
* if the algorithm name is <tt>null</tt>
|
||||
* @throws NoSuchAlgorithmException
|
||||
* if the algorithm cannot be found.
|
||||
*/
|
||||
private static Object getInstance(Hashtable table, String name)
|
||||
throws NoSuchAlgorithmException {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
Class algClass = (Class) resolveAlias(table, name);
|
||||
if (algClass == null) {
|
||||
throw new NoSuchAlgorithmException(name);
|
||||
}
|
||||
try {
|
||||
return algClass.newInstance();
|
||||
} catch (InstantiationException e) {
|
||||
throw new RegistrationException("Instantiation exception: "
|
||||
+ e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RegistrationException("Illegal access exception: "
|
||||
+ e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
59
src/de/flexiprovider/api/SecureRandom.java
Normal file
59
src/de/flexiprovider/api/SecureRandom.java
Normal file
@@ -0,0 +1,59 @@
|
||||
package de.flexiprovider.api;
|
||||
|
||||
import de.flexiprovider.common.math.FlexiBigInt;
|
||||
import de.flexiprovider.common.math.IntegerFunctions;
|
||||
import de.flexiprovider.common.util.BigEndianConversions;
|
||||
import de.flexiprovider.common.util.LittleEndianConversions;
|
||||
|
||||
public abstract class SecureRandom extends java.security.SecureRandomSpi {
|
||||
|
||||
protected final byte[] engineGenerateSeed(int numBytes) {
|
||||
return generateSeed(numBytes);
|
||||
}
|
||||
|
||||
protected final void engineNextBytes(byte[] bytes) {
|
||||
nextBytes(bytes);
|
||||
}
|
||||
|
||||
protected final void engineSetSeed(byte[] seed) {
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
public abstract byte[] generateSeed(int numBytes);
|
||||
|
||||
public abstract void nextBytes(byte[] bytes);
|
||||
|
||||
public abstract void setSeed(byte[] seed);
|
||||
|
||||
public final int nextInt() {
|
||||
byte[] intBytes = new byte[4];
|
||||
nextBytes(intBytes);
|
||||
return BigEndianConversions.OS2IP(intBytes);
|
||||
}
|
||||
|
||||
public final int nextInt(int upperBound) {
|
||||
int result;
|
||||
int octL = IntegerFunctions.ceilLog256(upperBound);
|
||||
do {
|
||||
byte[] intBytes = new byte[octL];
|
||||
nextBytes(intBytes);
|
||||
result = BigEndianConversions.OS2IP(intBytes, 0, octL);
|
||||
} while (result < 0 || result >= upperBound);
|
||||
return result;
|
||||
}
|
||||
|
||||
public final long nextLong(long upperBound){
|
||||
int octL = IntegerFunctions.ceilLog256(upperBound);
|
||||
int bitLength=IntegerFunctions.floorLog(FlexiBigInt.valueOf(upperBound))+1;
|
||||
int difference=octL*8-bitLength;
|
||||
|
||||
long result;
|
||||
do {
|
||||
byte[] intBytes = new byte[octL];
|
||||
nextBytes(intBytes);
|
||||
result = LittleEndianConversions.toLong(intBytes);
|
||||
result>>>=difference;
|
||||
} while (result < 0 || result >= upperBound);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
314
src/de/flexiprovider/api/Signature.java
Normal file
314
src/de/flexiprovider/api/Signature.java
Normal file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2003 by The FlexiProvider Group,
|
||||
* Technische Universitaet Darmstadt
|
||||
*
|
||||
* For conditions of usage and distribution please refer to the
|
||||
* file COPYING in the root directory of this package.
|
||||
*
|
||||
*/
|
||||
package de.flexiprovider.api;
|
||||
|
||||
import de.flexiprovider.api.exceptions.InvalidAlgorithmParameterException;
|
||||
import de.flexiprovider.api.exceptions.InvalidKeyException;
|
||||
import de.flexiprovider.api.exceptions.SignatureException;
|
||||
import de.flexiprovider.api.keys.PrivateKey;
|
||||
import de.flexiprovider.api.keys.PublicKey;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameterSpec;
|
||||
import de.flexiprovider.common.util.JavaSecureRandomWrapper;
|
||||
|
||||
/**
|
||||
* This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) for
|
||||
* the <tt>Signature</tt> class, which is used to provide the functionality of
|
||||
* a digital signature algorithm. Digital signatures are used for authentication
|
||||
* and integrity assurance of digital data. .
|
||||
* <p>
|
||||
* All the abstract methods in this class must be implemented by each
|
||||
* cryptographic service provider who wishes to supply the implementation of a
|
||||
* particular signature algorithm.
|
||||
*
|
||||
* @author Martin D<>ring, Johannes M<>ller
|
||||
*/
|
||||
public abstract class Signature extends java.security.SignatureSpi {
|
||||
|
||||
// ****************************************************
|
||||
// JCA adapter methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
protected final Object engineGetParameter(String param)
|
||||
throws java.security.InvalidParameterException {
|
||||
// method is deprecated
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
protected final void engineSetParameter(String param, Object value)
|
||||
throws java.security.InvalidParameterException {
|
||||
// method is deprecated
|
||||
}
|
||||
|
||||
protected final void engineInitSign(java.security.PrivateKey privateKey)
|
||||
throws java.security.InvalidKeyException {
|
||||
if ((privateKey == null) || !(privateKey instanceof PrivateKey)) {
|
||||
throw new java.security.InvalidKeyException();
|
||||
}
|
||||
initSign((PrivateKey) privateKey);
|
||||
}
|
||||
|
||||
protected final void engineInitSign(java.security.PrivateKey privateKey,
|
||||
java.security.SecureRandom javaRand)
|
||||
throws java.security.InvalidKeyException {
|
||||
if ((privateKey == null) || !(privateKey instanceof PrivateKey)) {
|
||||
throw new java.security.InvalidKeyException();
|
||||
}
|
||||
SecureRandom flexiRand = new JavaSecureRandomWrapper(javaRand);
|
||||
initSign((PrivateKey) privateKey, flexiRand);
|
||||
}
|
||||
|
||||
protected final void engineInitVerify(java.security.PublicKey publicKey)
|
||||
throws java.security.InvalidKeyException {
|
||||
if ((publicKey == null) || !(publicKey instanceof PublicKey)) {
|
||||
throw new java.security.InvalidKeyException();
|
||||
}
|
||||
initVerify((PublicKey) publicKey);
|
||||
}
|
||||
|
||||
protected void engineSetParameter(
|
||||
java.security.spec.AlgorithmParameterSpec params)
|
||||
throws java.security.InvalidAlgorithmParameterException {
|
||||
if (params != null && !(params instanceof AlgorithmParameterSpec)) {
|
||||
throw new java.security.InvalidAlgorithmParameterException();
|
||||
}
|
||||
setParameters((AlgorithmParameterSpec) params);
|
||||
}
|
||||
|
||||
protected final void engineUpdate(byte b)
|
||||
throws java.security.SignatureException {
|
||||
update(b);
|
||||
}
|
||||
|
||||
protected final void engineUpdate(byte[] b, int off, int len)
|
||||
throws java.security.SignatureException {
|
||||
update(b, off, len);
|
||||
}
|
||||
|
||||
protected final byte[] engineSign() throws java.security.SignatureException {
|
||||
return sign();
|
||||
}
|
||||
|
||||
protected final boolean engineVerify(byte[] sigBytes)
|
||||
throws java.security.SignatureException {
|
||||
return verify(sigBytes);
|
||||
}
|
||||
|
||||
protected final boolean engineVerify(byte[] sigBytes, int offset, int length)
|
||||
throws java.security.SignatureException {
|
||||
return verify(sigBytes, offset, length);
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// FlexiAPI methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* Initialize the signature with the specified private key for signing
|
||||
* operations.
|
||||
*
|
||||
* @param privKey
|
||||
* the private key of the identity whose signature will be
|
||||
* generated.
|
||||
* @throws InvalidKeyException
|
||||
* if the key is invalid for initializing the signature.
|
||||
*/
|
||||
public final void initSign(PrivateKey privKey) throws InvalidKeyException {
|
||||
initSign(privKey, Registry.getSecureRandom());
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the signature with the specified private key and source of
|
||||
* randomness for signing operations.
|
||||
*
|
||||
* @param privKey
|
||||
* the private key of the identity whose signature will be
|
||||
* generated.
|
||||
* @param random
|
||||
* the source of randomness
|
||||
* @throws InvalidKeyException
|
||||
* if the key is invalid for initializing the signature.
|
||||
*/
|
||||
public abstract void initSign(PrivateKey privKey, SecureRandom random)
|
||||
throws InvalidKeyException;
|
||||
|
||||
/**
|
||||
* Initialize the signature with the specified public key for verification
|
||||
* operations.
|
||||
*
|
||||
* @param pubKey
|
||||
* the public key of the identity whose signature is going to
|
||||
* be verified
|
||||
* @throws InvalidKeyException
|
||||
* if the key is invalid for initializing the signature.
|
||||
*/
|
||||
public abstract void initVerify(PublicKey pubKey)
|
||||
throws InvalidKeyException;
|
||||
|
||||
/**
|
||||
* Initialize the signature with the specified parameters.
|
||||
*
|
||||
* @param params
|
||||
* the parameters
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given parameters are inappropriate for this
|
||||
* signature.
|
||||
*/
|
||||
public abstract void setParameters(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Update the data to be signed or verified using the specified byte.
|
||||
*
|
||||
* @param input
|
||||
* the data byte
|
||||
* @throws SignatureException
|
||||
* if the engine is not initialized properly.
|
||||
*/
|
||||
public abstract void update(byte input) throws SignatureException;
|
||||
|
||||
/**
|
||||
* Update the data to be signed or verified using the specified byte array.
|
||||
*
|
||||
* @param input
|
||||
* the data byte array
|
||||
* @throws SignatureException
|
||||
* if the engine is not initialized properly.
|
||||
*/
|
||||
public final void update(byte[] input) throws SignatureException {
|
||||
update(input, 0, input.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the data to be signed or verified, using the specified byte array
|
||||
* of the specified length, starting at the specified offset.
|
||||
*
|
||||
* @param input
|
||||
* the data byte array
|
||||
* @param inOff
|
||||
* the offset to start from in the array of bytes
|
||||
* @param inLen
|
||||
* the number of bytes to use, starting at <tt>inOff</tt>
|
||||
* @throws SignatureException
|
||||
* if the engine is not initialized properly
|
||||
*/
|
||||
public abstract void update(byte[] input, int inOff, int inLen)
|
||||
throws SignatureException;
|
||||
|
||||
/**
|
||||
* Return the signature of all the data updated so far.
|
||||
*
|
||||
* @return the signature
|
||||
* @throws SignatureException
|
||||
* if the engine is not initialized properly.
|
||||
*/
|
||||
public abstract byte[] sign() throws SignatureException;
|
||||
|
||||
/**
|
||||
* Update the data to be signed and return the signature of all the data
|
||||
* updated so far.
|
||||
*
|
||||
* @param input
|
||||
* the data byte array
|
||||
* @return the signature
|
||||
* @throws SignatureException
|
||||
* if the engine is not initialized properly.
|
||||
*/
|
||||
public final byte[] sign(byte[] input) throws SignatureException {
|
||||
update(input);
|
||||
return sign();
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the passed-in signature of the specified message.
|
||||
*
|
||||
* @param signature
|
||||
* the signature
|
||||
* @return <tt>true</tt> if the signature is valid, <tt>false</tt>
|
||||
* otherwise.
|
||||
* @throws SignatureException
|
||||
* if the engine is not initialized properly or the
|
||||
* passed-in signature is improperly encoded or of the wrong
|
||||
* type.
|
||||
*/
|
||||
public abstract boolean verify(byte[] signature) throws SignatureException;
|
||||
|
||||
/**
|
||||
* Update the data to be verified and verify the passed-in signature.
|
||||
*
|
||||
* @param input
|
||||
* the data byte array
|
||||
* @param signature
|
||||
* the signature
|
||||
* @return <tt>true</tt> if the signature is valid, <tt>false</tt>
|
||||
* otherwise.
|
||||
* @throws SignatureException
|
||||
* if the engine is not initialized properly or the
|
||||
* passed-in signature is improperly encoded or of the wrong
|
||||
* type.
|
||||
*/
|
||||
public final boolean verify(byte[] input, byte[] signature)
|
||||
throws SignatureException {
|
||||
update(input);
|
||||
return verify(signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the passed-in signature.
|
||||
*
|
||||
* @param signature
|
||||
* the signature
|
||||
* @param sigOff
|
||||
* the offset where the signature starts
|
||||
* @param sigLen
|
||||
* the length of the signature
|
||||
* @return <tt>true</tt> if the signature is valid, <tt>false</tt>
|
||||
* otherwise.
|
||||
* @throws SignatureException
|
||||
* if the engine is not initialized properly or the
|
||||
* passed-in signature is improperly encoded or of the wrong
|
||||
* type.
|
||||
*/
|
||||
public final boolean verify(byte[] signature, int sigOff, int sigLen)
|
||||
throws SignatureException {
|
||||
byte[] sig = new byte[sigLen];
|
||||
System.arraycopy(signature, sigOff, sig, 0, sigLen);
|
||||
return verify(sig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the data to be verified and verify the passed-in signature.
|
||||
*
|
||||
* @param input
|
||||
* the data byte array
|
||||
* @param signature
|
||||
* the signature
|
||||
* @param sigOff
|
||||
* the offset where the signature starts
|
||||
* @param sigLen
|
||||
* the length of the signature
|
||||
* @return <tt>true</tt> if the signature is valid, <tt>false</tt>
|
||||
* otherwise.
|
||||
* @throws SignatureException
|
||||
* if the engine is not initialized properly or the
|
||||
* passed-in signature is improperly encoded or of the wrong
|
||||
* type.
|
||||
*/
|
||||
public final boolean verify(byte[] input, byte[] signature, int sigOff,
|
||||
int sigLen) throws SignatureException {
|
||||
update(input);
|
||||
return verify(signature, sigOff, sigLen);
|
||||
}
|
||||
|
||||
}
|
||||
13
src/de/flexiprovider/api/exceptions/BadPaddingException.java
Normal file
13
src/de/flexiprovider/api/exceptions/BadPaddingException.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
public class BadPaddingException extends javax.crypto.BadPaddingException {
|
||||
|
||||
public BadPaddingException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public BadPaddingException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
9
src/de/flexiprovider/api/exceptions/DigestException.java
Normal file
9
src/de/flexiprovider/api/exceptions/DigestException.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
public class DigestException extends java.security.DigestException {
|
||||
|
||||
public DigestException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
public class IllegalBlockSizeException extends
|
||||
javax.crypto.IllegalBlockSizeException {
|
||||
|
||||
public IllegalBlockSizeException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
public class InvalidAlgorithmParameterException extends
|
||||
java.security.InvalidAlgorithmParameterException {
|
||||
|
||||
public InvalidAlgorithmParameterException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public InvalidAlgorithmParameterException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
13
src/de/flexiprovider/api/exceptions/InvalidKeyException.java
Normal file
13
src/de/flexiprovider/api/exceptions/InvalidKeyException.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
public class InvalidKeyException extends java.security.InvalidKeyException {
|
||||
|
||||
public InvalidKeyException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public InvalidKeyException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
public class InvalidKeySpecException extends
|
||||
java.security.spec.InvalidKeySpecException {
|
||||
|
||||
public InvalidKeySpecException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public InvalidKeySpecException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
public class InvalidParameterException extends
|
||||
java.security.InvalidParameterException {
|
||||
|
||||
public InvalidParameterException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
public class InvalidParameterSpecException extends
|
||||
java.security.spec.InvalidParameterSpecException {
|
||||
|
||||
public InvalidParameterSpecException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
public class NoSuchAlgorithmException extends
|
||||
java.security.NoSuchAlgorithmException {
|
||||
|
||||
public NoSuchAlgorithmException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
20
src/de/flexiprovider/api/exceptions/NoSuchModeException.java
Normal file
20
src/de/flexiprovider/api/exceptions/NoSuchModeException.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
/**
|
||||
* Exception used to indicate that a mode of operation cannot be found.
|
||||
*
|
||||
* @author Martin D<>ring
|
||||
*/
|
||||
public class NoSuchModeException extends NoSuchAlgorithmException {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param msg
|
||||
* the error message
|
||||
*/
|
||||
public NoSuchModeException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
public class NoSuchPaddingException extends javax.crypto.NoSuchPaddingException {
|
||||
|
||||
public NoSuchPaddingException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
/**
|
||||
* Exception used to indicate registration errors (used by the
|
||||
* {@link de.flexiprovider.api.Registry Registry} class). Since this exception
|
||||
* is thrown during static initialization, it extends {@link RuntimeException}.
|
||||
*
|
||||
* @author Martin D<>ring
|
||||
*/
|
||||
public class RegistrationException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public RegistrationException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param s
|
||||
* the error message
|
||||
*/
|
||||
public RegistrationException(String s) {
|
||||
super(s);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
public class ShortBufferException extends javax.crypto.ShortBufferException {
|
||||
|
||||
public ShortBufferException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ShortBufferException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package de.flexiprovider.api.exceptions;
|
||||
|
||||
public class SignatureException extends java.security.SignatureException {
|
||||
|
||||
public SignatureException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
}
|
||||
7
src/de/flexiprovider/api/keys/Key.java
Normal file
7
src/de/flexiprovider/api/keys/Key.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package de.flexiprovider.api.keys;
|
||||
|
||||
public interface Key extends java.security.Key {
|
||||
|
||||
// empty
|
||||
|
||||
}
|
||||
189
src/de/flexiprovider/api/keys/KeyFactory.java
Normal file
189
src/de/flexiprovider/api/keys/KeyFactory.java
Normal file
@@ -0,0 +1,189 @@
|
||||
package de.flexiprovider.api.keys;
|
||||
|
||||
import de.flexiprovider.api.exceptions.InvalidKeyException;
|
||||
import de.flexiprovider.api.exceptions.InvalidKeySpecException;
|
||||
import de.flexiprovider.pki.PKCS8EncodedKeySpec;
|
||||
import de.flexiprovider.pki.X509EncodedKeySpec;
|
||||
|
||||
public abstract class KeyFactory extends java.security.KeyFactorySpi {
|
||||
|
||||
// ****************************************************
|
||||
// JCA adapter methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method generatePublic(): generates a public key
|
||||
* object from the provided key specification (key material).
|
||||
*
|
||||
* @param keySpec
|
||||
* the specification (key material) of the public key
|
||||
* @return the public key
|
||||
* @throws java.security.spec.InvalidKeySpecException
|
||||
* if the given key specification is inappropriate for this
|
||||
* key factory to produce a public key.
|
||||
*/
|
||||
protected java.security.PublicKey engineGeneratePublic(
|
||||
java.security.spec.KeySpec keySpec)
|
||||
throws java.security.spec.InvalidKeySpecException {
|
||||
|
||||
if (keySpec != null && !(keySpec instanceof KeySpec)) {
|
||||
if (keySpec instanceof java.security.spec.X509EncodedKeySpec) {
|
||||
KeySpec encKeySpec = new X509EncodedKeySpec(
|
||||
(java.security.spec.X509EncodedKeySpec) keySpec);
|
||||
return generatePublic(encKeySpec);
|
||||
}
|
||||
|
||||
throw new java.security.spec.InvalidKeySpecException();
|
||||
}
|
||||
|
||||
return generatePublic((KeySpec) keySpec);
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method generatePrivate(): generate a private key
|
||||
* object from the provided key specification (key material).
|
||||
*
|
||||
* @param keySpec
|
||||
* the specification (key material) of the private key
|
||||
* @return the private key
|
||||
* @throws java.security.spec.InvalidKeySpecException
|
||||
* if the given key specification is inappropriate for this
|
||||
* key factory to produce a private key.
|
||||
*/
|
||||
protected java.security.PrivateKey engineGeneratePrivate(
|
||||
java.security.spec.KeySpec keySpec)
|
||||
throws java.security.spec.InvalidKeySpecException {
|
||||
|
||||
if (keySpec != null && !(keySpec instanceof KeySpec)) {
|
||||
if (keySpec instanceof java.security.spec.PKCS8EncodedKeySpec) {
|
||||
KeySpec encKeySpec = new PKCS8EncodedKeySpec(
|
||||
(java.security.spec.PKCS8EncodedKeySpec) keySpec);
|
||||
return generatePrivate(encKeySpec);
|
||||
}
|
||||
|
||||
throw new java.security.spec.InvalidKeySpecException();
|
||||
}
|
||||
|
||||
return generatePrivate((KeySpec) keySpec);
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method getKeySpec(): return a specification (key
|
||||
* material) of the given key object. <tt>keySpec</tt> identifies the
|
||||
* specification class in which the key material should be returned. It
|
||||
* could, for example, be <tt>DSAPublicKeySpec.class</tt>, to indicate
|
||||
* that the key material should be returned in an instance of the
|
||||
* <tt>DSAPublicKeySpec</tt> class.
|
||||
*
|
||||
* @param key
|
||||
* the key
|
||||
* @param keySpec
|
||||
* the specification class in which the key material should
|
||||
* be returned
|
||||
* @return the underlying key specification (key material) in an instance of
|
||||
* the requested specification class
|
||||
* @throws java.security.spec.InvalidKeySpecException
|
||||
* if the requested key specification is inappropriate for
|
||||
* the given key, or the given key cannot be dealt with
|
||||
* (e.g., the given key has an unrecognized format).
|
||||
*/
|
||||
protected final java.security.spec.KeySpec engineGetKeySpec(
|
||||
java.security.Key key, Class keySpec)
|
||||
throws java.security.spec.InvalidKeySpecException {
|
||||
|
||||
if (!(key instanceof Key)) {
|
||||
throw new java.security.spec.InvalidKeySpecException();
|
||||
}
|
||||
|
||||
return getKeySpec((Key) key, keySpec);
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method translateKey(): translate a key object,
|
||||
* whose provider may be unknown or potentially untrusted, into a
|
||||
* corresponding key object of this key factory.
|
||||
*
|
||||
* @param key
|
||||
* the key whose provider is unknown or untrusted
|
||||
* @return the translated key
|
||||
* @throws java.security.InvalidKeyException
|
||||
* if the given key cannot be processed by this key factory.
|
||||
*/
|
||||
protected final java.security.Key engineTranslateKey(java.security.Key key)
|
||||
throws java.security.InvalidKeyException {
|
||||
|
||||
if (!(key instanceof Key)) {
|
||||
throw new java.security.InvalidKeyException();
|
||||
}
|
||||
|
||||
return translateKey((Key) key);
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// FlexiAPI methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* Generate a public key object from the provided key specification (key
|
||||
* material).
|
||||
*
|
||||
* @param keySpec
|
||||
* the specification (key material) of the public key
|
||||
* @return the public key
|
||||
* @throws InvalidKeySpecException
|
||||
* if the given key specification is inappropriate for this
|
||||
* key factory to produce a public key.
|
||||
*/
|
||||
public abstract PublicKey generatePublic(KeySpec keySpec)
|
||||
throws InvalidKeySpecException;
|
||||
|
||||
/**
|
||||
* Generate a private key object from the provided key specification (key
|
||||
* material).
|
||||
*
|
||||
* @param keySpec
|
||||
* the specification (key material) of the private key
|
||||
* @return the private key
|
||||
* @throws InvalidKeySpecException
|
||||
* if the given key specification is inappropriate for this
|
||||
* key factory to produce a private key.
|
||||
*/
|
||||
public abstract PrivateKey generatePrivate(KeySpec keySpec)
|
||||
throws InvalidKeySpecException;
|
||||
|
||||
/**
|
||||
* Return a specification (key material) of the given key object.
|
||||
* <tt>keySpec</tt> identifies the specification class in which the key
|
||||
* material should be returned. It could, for example, be
|
||||
* <tt>DSAPublicKeySpec.class</tt>, to indicate that the key material
|
||||
* should be returned in an instance of the <tt>DSAPublicKeySpec</tt>
|
||||
* class.
|
||||
*
|
||||
* @param key
|
||||
* the key
|
||||
* @param keySpec
|
||||
* the specification class in which the key material should
|
||||
* be returned
|
||||
* @return the underlying key specification (key material) in an instance of
|
||||
* the requested specification class
|
||||
* @throws InvalidKeySpecException
|
||||
* if the requested key specification is inappropriate for
|
||||
* the given key, or the given key cannot be dealt with
|
||||
* (e.g., the given key has an unrecognized format).
|
||||
*/
|
||||
public abstract KeySpec getKeySpec(Key key, Class keySpec)
|
||||
throws InvalidKeySpecException;
|
||||
|
||||
/**
|
||||
* Translate a key object, whose provider may be unknown or potentially
|
||||
* untrusted, into a corresponding key object of this key factory.
|
||||
*
|
||||
* @param key
|
||||
* the key whose provider is unknown or untrusted
|
||||
* @return the translated key
|
||||
* @throws InvalidKeyException
|
||||
* if the given key cannot be processed by this key factory.
|
||||
*/
|
||||
public abstract Key translateKey(Key key) throws InvalidKeyException;
|
||||
|
||||
}
|
||||
47
src/de/flexiprovider/api/keys/KeyPair.java
Normal file
47
src/de/flexiprovider/api/keys/KeyPair.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package de.flexiprovider.api.keys;
|
||||
|
||||
/**
|
||||
* This class is a simple holder for a key pair (a public key and a private
|
||||
* key). It does not enforce any security, and, when initialized, should be
|
||||
* treated like a private key.
|
||||
*/
|
||||
public final class KeyPair {
|
||||
|
||||
java.security.KeyPair pair;
|
||||
|
||||
/**
|
||||
* Construct a key pair from the given public key and private key.
|
||||
* <p>
|
||||
* Note that this constructor only stores references to the public and
|
||||
* private key components in the generated key pair. This is safe, because
|
||||
* <tt>Key</tt> objects are immutable.
|
||||
*
|
||||
* @param publicKey
|
||||
* the public key.
|
||||
*
|
||||
* @param privateKey
|
||||
* the private key.
|
||||
*/
|
||||
public KeyPair(PublicKey publicKey, PrivateKey privateKey) {
|
||||
pair = new java.security.KeyPair(publicKey, privateKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the public key component of this key pair.
|
||||
*
|
||||
* @return a reference to the public key.
|
||||
*/
|
||||
public PublicKey getPublic() {
|
||||
return (PublicKey) pair.getPublic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the private key component of this key pair.
|
||||
*
|
||||
* @return a reference to the private key.
|
||||
*/
|
||||
public PrivateKey getPrivate() {
|
||||
return (PrivateKey) pair.getPrivate();
|
||||
}
|
||||
|
||||
}
|
||||
132
src/de/flexiprovider/api/keys/KeyPairGenerator.java
Normal file
132
src/de/flexiprovider/api/keys/KeyPairGenerator.java
Normal file
@@ -0,0 +1,132 @@
|
||||
package de.flexiprovider.api.keys;
|
||||
|
||||
import de.flexiprovider.api.SecureRandom;
|
||||
import de.flexiprovider.api.exceptions.InvalidAlgorithmParameterException;
|
||||
import de.flexiprovider.api.exceptions.InvalidParameterException;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameterSpec;
|
||||
import de.flexiprovider.common.util.JavaSecureRandomWrapper;
|
||||
|
||||
public abstract class KeyPairGenerator extends
|
||||
java.security.KeyPairGeneratorSpi {
|
||||
|
||||
// ****************************************************
|
||||
// JCA adapter methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method
|
||||
* {@link #initialize(AlgorithmParameterSpec, SecureRandom)}: initialize
|
||||
* the key pair generator using the specified parameter set and source of
|
||||
* randomness.
|
||||
*
|
||||
* @param params
|
||||
* the parameter set used to generate the keys
|
||||
* @param javaRand
|
||||
* the source of randomness for this generator
|
||||
* @throws java.security.InvalidAlgorithmParameterException
|
||||
* if the given parameters are inappropriate for this key
|
||||
* pair generator.
|
||||
*/
|
||||
public void initialize(java.security.spec.AlgorithmParameterSpec params,
|
||||
java.security.SecureRandom javaRand)
|
||||
throws java.security.InvalidAlgorithmParameterException {
|
||||
|
||||
if (params != null && !(params instanceof AlgorithmParameterSpec)) {
|
||||
throw new java.security.InvalidAlgorithmParameterException();
|
||||
}
|
||||
SecureRandom flexiRand = new JavaSecureRandomWrapper(javaRand);
|
||||
initialize((AlgorithmParameterSpec) params, flexiRand);
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// JCA adapter methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* Initialize the key pair generator for a certain key size using a default
|
||||
* parameter set and the <tt>SecureRandom</tt> implementation of the
|
||||
* highest-priority installed provider as the source of randomness. (If none
|
||||
* of the installed providers supply an implementation of
|
||||
* <tt>SecureRandom</tt>, a system-provided source of randomness is
|
||||
* used.)
|
||||
*
|
||||
* @param keysize
|
||||
* the keysize. This is an algorithm-specific metric, such as
|
||||
* modulus length, specified in number of bits.
|
||||
* @param javaRand
|
||||
* the source of randomness for this generator
|
||||
* @throws InvalidParameterException
|
||||
* if the <tt>keysize</tt> is not supported by this
|
||||
* KeyPairGenerator object.
|
||||
*/
|
||||
public final void initialize(int keysize,
|
||||
java.security.SecureRandom javaRand)
|
||||
throws InvalidParameterException {
|
||||
SecureRandom flexiRand = new JavaSecureRandomWrapper(javaRand);
|
||||
initialize(keysize, flexiRand);
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter to FlexiAPI method {@link #genKeyPair()}: generate a key
|
||||
* pair. Unless an initialization method is called using a KeyPairGenerator
|
||||
* interface, algorithm-specific defaults will be used. This will generate a
|
||||
* new key pair every time it is called.
|
||||
*
|
||||
* @return a newly generated <tt>KeyPair</tt>
|
||||
*/
|
||||
public final java.security.KeyPair generateKeyPair() {
|
||||
return genKeyPair().pair;
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// FlexiAPI methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* Initialize the key pair generator using the specified parameter set and
|
||||
* the <tt>SecureRandom</tt> implementation of the highest-priority
|
||||
* installed provider as the source of randomness. (If none of the installed
|
||||
* providers supply an implementation of <tt>SecureRandom</tt>, a
|
||||
* system-provided source of randomness is used.).
|
||||
*
|
||||
* @param params
|
||||
* the parameter set used to generate the keys
|
||||
* @param random
|
||||
* a source of randomness
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given parameters are inappropriate for this key
|
||||
* pair generator.
|
||||
*/
|
||||
public abstract void initialize(AlgorithmParameterSpec params,
|
||||
SecureRandom random) throws InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Initialize the key pair generator for a certain keysize using a default
|
||||
* parameter set and the <tt>SecureRandom</tt> implementation of the
|
||||
* highest-priority installed provider as the source of randomness. (If none
|
||||
* of the installed providers supply an implementation of
|
||||
* <tt>SecureRandom</tt>, a system-provided source of randomness is
|
||||
* used.)
|
||||
*
|
||||
* @param keysize
|
||||
* the keysize. This is an algorithm-specific metric, such as
|
||||
* modulus length, specified in number of bits.
|
||||
* @param random
|
||||
* the source of randomness for this generator
|
||||
* @throws InvalidParameterException
|
||||
* if the <tt>keysize</tt> is not supported by this
|
||||
* KeyPairGenerator object.
|
||||
*/
|
||||
public abstract void initialize(int keysize, SecureRandom random)
|
||||
throws InvalidParameterException;
|
||||
|
||||
/**
|
||||
* Generate a key pair. Unless an initialization method is called using a
|
||||
* KeyPairGenerator interface, algorithm-specific defaults will be used.
|
||||
* This will generate a new key pair every time it is called.
|
||||
*
|
||||
* @return a newly generated {@link KeyPair}
|
||||
*/
|
||||
public abstract KeyPair genKeyPair();
|
||||
|
||||
}
|
||||
11
src/de/flexiprovider/api/keys/KeySpec.java
Normal file
11
src/de/flexiprovider/api/keys/KeySpec.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package de.flexiprovider.api.keys;
|
||||
|
||||
/**
|
||||
* A (transparent) specification of the key material that constitutes a
|
||||
* cryptographic key.
|
||||
*/
|
||||
public interface KeySpec extends java.security.spec.KeySpec {
|
||||
|
||||
// empty
|
||||
|
||||
}
|
||||
53
src/de/flexiprovider/api/keys/PrivateKey.java
Normal file
53
src/de/flexiprovider/api/keys/PrivateKey.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package de.flexiprovider.api.keys;
|
||||
|
||||
import codec.asn1.ASN1Exception;
|
||||
import codec.asn1.ASN1ObjectIdentifier;
|
||||
import codec.asn1.ASN1Type;
|
||||
import codec.pkcs8.PrivateKeyInfo;
|
||||
import de.flexiprovider.common.util.ASN1Tools;
|
||||
import de.flexiprovider.pki.AlgorithmIdentifier;
|
||||
|
||||
public abstract class PrivateKey implements Key, java.security.PrivateKey {
|
||||
|
||||
/**
|
||||
* Return the encoding format, PKCS #8.
|
||||
*
|
||||
* @return "PKCS#8"
|
||||
*/
|
||||
public final String getFormat() {
|
||||
return "PKCS#8";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key in its primary encoding format, PKCS #8.
|
||||
*
|
||||
* @return the PKCS #8 encoded key.
|
||||
*/
|
||||
public final byte[] getEncoded() {
|
||||
AlgorithmIdentifier aid;
|
||||
try {
|
||||
aid = new AlgorithmIdentifier(getOID(), getAlgParams());
|
||||
} catch (ASN1Exception asn1e) {
|
||||
throw new RuntimeException("ASN1Exception: " + asn1e.getMessage());
|
||||
}
|
||||
PrivateKeyInfo spki = new PrivateKeyInfo(aid, getKeyData());
|
||||
return ASN1Tools.derEncode(spki);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the OID to encode in the SubjectPublicKeyInfo structure
|
||||
*/
|
||||
protected abstract ASN1ObjectIdentifier getOID();
|
||||
|
||||
/**
|
||||
* @return the algorithm parameters to encode in the SubjectPublicKeyInfo
|
||||
* structure
|
||||
*/
|
||||
protected abstract ASN1Type getAlgParams();
|
||||
|
||||
/**
|
||||
* @return the keyData to encode in the SubjectPublicKeyInfo structure
|
||||
*/
|
||||
protected abstract byte[] getKeyData();
|
||||
|
||||
}
|
||||
53
src/de/flexiprovider/api/keys/PublicKey.java
Normal file
53
src/de/flexiprovider/api/keys/PublicKey.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package de.flexiprovider.api.keys;
|
||||
|
||||
import codec.asn1.ASN1Exception;
|
||||
import codec.asn1.ASN1ObjectIdentifier;
|
||||
import codec.asn1.ASN1Type;
|
||||
import codec.x509.SubjectPublicKeyInfo;
|
||||
import de.flexiprovider.common.util.ASN1Tools;
|
||||
import de.flexiprovider.pki.AlgorithmIdentifier;
|
||||
|
||||
public abstract class PublicKey implements Key, java.security.PublicKey {
|
||||
|
||||
/**
|
||||
* Return the encoding format, X.509.
|
||||
*
|
||||
* @return "X.509"
|
||||
*/
|
||||
public final String getFormat() {
|
||||
return "X.509";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the key in its primary encoding format, X.509.
|
||||
*
|
||||
* @return the X.509 encoded key.
|
||||
*/
|
||||
public final byte[] getEncoded() {
|
||||
AlgorithmIdentifier aid;
|
||||
try {
|
||||
aid = new AlgorithmIdentifier(getOID(), getAlgParams());
|
||||
} catch (ASN1Exception asn1e) {
|
||||
throw new RuntimeException("ASN1Exception: " + asn1e.getMessage());
|
||||
}
|
||||
SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo(aid, getKeyData());
|
||||
return ASN1Tools.derEncode(spki);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the OID to encode in the SubjectPublicKeyInfo structure
|
||||
*/
|
||||
protected abstract ASN1ObjectIdentifier getOID();
|
||||
|
||||
/**
|
||||
* @return the algorithm parameters to encode in the SubjectPublicKeyInfo
|
||||
* structure
|
||||
*/
|
||||
protected abstract ASN1Type getAlgParams();
|
||||
|
||||
/**
|
||||
* @return the keyData to encode in the SubjectPublicKeyInfo structure
|
||||
*/
|
||||
protected abstract byte[] getKeyData();
|
||||
|
||||
}
|
||||
7
src/de/flexiprovider/api/keys/SecretKey.java
Normal file
7
src/de/flexiprovider/api/keys/SecretKey.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package de.flexiprovider.api.keys;
|
||||
|
||||
public interface SecretKey extends Key, javax.crypto.SecretKey {
|
||||
|
||||
// empty
|
||||
|
||||
}
|
||||
69
src/de/flexiprovider/api/keys/SecretKeyFactory.java
Normal file
69
src/de/flexiprovider/api/keys/SecretKeyFactory.java
Normal file
@@ -0,0 +1,69 @@
|
||||
package de.flexiprovider.api.keys;
|
||||
|
||||
import javax.crypto.SecretKeyFactorySpi;
|
||||
|
||||
import de.flexiprovider.api.exceptions.InvalidKeyException;
|
||||
import de.flexiprovider.api.exceptions.InvalidKeySpecException;
|
||||
|
||||
public abstract class SecretKeyFactory extends SecretKeyFactorySpi {
|
||||
|
||||
// ****************************************************
|
||||
// JCA adapter methods
|
||||
// ****************************************************
|
||||
|
||||
protected javax.crypto.SecretKey engineGenerateSecret(
|
||||
java.security.spec.KeySpec keySpec)
|
||||
throws java.security.spec.InvalidKeySpecException {
|
||||
|
||||
if (keySpec == null) {
|
||||
throw new java.security.spec.InvalidKeySpecException();
|
||||
}
|
||||
|
||||
if (!(keySpec instanceof KeySpec)) {
|
||||
if (keySpec instanceof javax.crypto.spec.SecretKeySpec) {
|
||||
javax.crypto.spec.SecretKeySpec javaSpec = (javax.crypto.spec.SecretKeySpec) keySpec;
|
||||
KeySpec secretKeySpec = new SecretKeySpec(
|
||||
javaSpec.getEncoded(), javaSpec.getAlgorithm());
|
||||
return generateSecret(secretKeySpec);
|
||||
}
|
||||
|
||||
throw new java.security.spec.InvalidKeySpecException();
|
||||
}
|
||||
|
||||
return generateSecret((KeySpec) keySpec);
|
||||
}
|
||||
|
||||
protected java.security.spec.KeySpec engineGetKeySpec(
|
||||
javax.crypto.SecretKey key, Class keySpec)
|
||||
throws java.security.spec.InvalidKeySpecException {
|
||||
|
||||
if ((key == null) || (keySpec == null) || !(key instanceof SecretKey)) {
|
||||
throw new java.security.spec.InvalidKeySpecException();
|
||||
}
|
||||
return getKeySpec((SecretKey) key, keySpec);
|
||||
}
|
||||
|
||||
protected javax.crypto.SecretKey engineTranslateKey(
|
||||
javax.crypto.SecretKey key)
|
||||
throws java.security.InvalidKeyException {
|
||||
|
||||
if ((key == null) || !(key instanceof SecretKey)) {
|
||||
throw new java.security.InvalidKeyException();
|
||||
}
|
||||
return translateKey((SecretKey) key);
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// FlexiAPI methods
|
||||
// ****************************************************
|
||||
|
||||
public abstract SecretKey generateSecret(KeySpec keySpec)
|
||||
throws InvalidKeySpecException;
|
||||
|
||||
public abstract KeySpec getKeySpec(SecretKey key, Class keySpec)
|
||||
throws InvalidKeySpecException;
|
||||
|
||||
public abstract SecretKey translateKey(SecretKey key)
|
||||
throws InvalidKeyException;
|
||||
|
||||
}
|
||||
64
src/de/flexiprovider/api/keys/SecretKeyGenerator.java
Normal file
64
src/de/flexiprovider/api/keys/SecretKeyGenerator.java
Normal file
@@ -0,0 +1,64 @@
|
||||
package de.flexiprovider.api.keys;
|
||||
|
||||
import de.flexiprovider.api.Registry;
|
||||
import de.flexiprovider.api.SecureRandom;
|
||||
import de.flexiprovider.api.exceptions.InvalidAlgorithmParameterException;
|
||||
import de.flexiprovider.api.parameters.AlgorithmParameterSpec;
|
||||
import de.flexiprovider.common.util.JavaSecureRandomWrapper;
|
||||
|
||||
public abstract class SecretKeyGenerator extends javax.crypto.KeyGeneratorSpi {
|
||||
|
||||
// ****************************************************
|
||||
// JCA adapter methods
|
||||
// ****************************************************
|
||||
|
||||
protected final javax.crypto.SecretKey engineGenerateKey() {
|
||||
return generateKey();
|
||||
}
|
||||
|
||||
protected final void engineInit(java.security.SecureRandom javaRand) {
|
||||
init(new JavaSecureRandomWrapper(javaRand));
|
||||
}
|
||||
|
||||
protected final void engineInit(int keysize,
|
||||
java.security.SecureRandom javaRand) {
|
||||
init(keysize, new JavaSecureRandomWrapper(javaRand));
|
||||
}
|
||||
|
||||
protected void engineInit(java.security.spec.AlgorithmParameterSpec params,
|
||||
java.security.SecureRandom javaRand)
|
||||
throws java.security.InvalidAlgorithmParameterException {
|
||||
if (params != null && !(params instanceof AlgorithmParameterSpec)) {
|
||||
throw new java.security.InvalidAlgorithmParameterException();
|
||||
}
|
||||
init((AlgorithmParameterSpec) params, new JavaSecureRandomWrapper(
|
||||
javaRand));
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// FlexiAPI methods
|
||||
// ****************************************************
|
||||
|
||||
public abstract SecretKey generateKey();
|
||||
|
||||
public final void init() {
|
||||
init(Registry.getSecureRandom());
|
||||
}
|
||||
|
||||
public abstract void init(SecureRandom random);
|
||||
|
||||
public final void init(int keySize) {
|
||||
init(keySize, Registry.getSecureRandom());
|
||||
}
|
||||
|
||||
public abstract void init(int keySize, SecureRandom random);
|
||||
|
||||
public final void init(AlgorithmParameterSpec params)
|
||||
throws InvalidAlgorithmParameterException {
|
||||
init(params, Registry.getSecureRandom());
|
||||
}
|
||||
|
||||
public abstract void init(AlgorithmParameterSpec params, SecureRandom random)
|
||||
throws InvalidAlgorithmParameterException;
|
||||
|
||||
}
|
||||
14
src/de/flexiprovider/api/keys/SecretKeySpec.java
Normal file
14
src/de/flexiprovider/api/keys/SecretKeySpec.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package de.flexiprovider.api.keys;
|
||||
|
||||
public class SecretKeySpec extends javax.crypto.spec.SecretKeySpec implements
|
||||
KeySpec {
|
||||
|
||||
public SecretKeySpec(byte[] key, String algorithm) {
|
||||
super(key, algorithm);
|
||||
}
|
||||
|
||||
public SecretKeySpec(byte[] key, int offset, int len, String algorithm) {
|
||||
super(key, offset, len, algorithm);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
package de.flexiprovider.api.parameters;
|
||||
|
||||
import de.flexiprovider.api.SecureRandom;
|
||||
import de.flexiprovider.api.exceptions.InvalidAlgorithmParameterException;
|
||||
import de.flexiprovider.common.mode.ModeParameterSpec;
|
||||
import de.flexiprovider.common.util.JavaSecureRandomWrapper;
|
||||
|
||||
public abstract class AlgorithmParameterGenerator extends
|
||||
java.security.AlgorithmParameterGeneratorSpi {
|
||||
|
||||
// ****************************************************
|
||||
// JCA adapter methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method {@link #generateParameters()}: generate
|
||||
* parameters.
|
||||
*
|
||||
* @return the generated parameters
|
||||
*/
|
||||
protected final java.security.AlgorithmParameters engineGenerateParameters() {
|
||||
|
||||
/**
|
||||
* JCA adapter class, used to translate from {@link AlgorithmParameters}
|
||||
* to {@link java.security.AlgorithmParameters}.
|
||||
*/
|
||||
final class JCAAlgorithmParameters extends
|
||||
java.security.AlgorithmParameters {
|
||||
private JCAAlgorithmParameters(AlgorithmParameters params) {
|
||||
super(params, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
JCAAlgorithmParameters algParams = new JCAAlgorithmParameters(
|
||||
getAlgorithmParameters());
|
||||
|
||||
try {
|
||||
algParams.init(generateParameters());
|
||||
} catch (java.security.spec.InvalidParameterSpecException ipse) {
|
||||
throw new RuntimeException("InvalidParameterSpecException: "
|
||||
+ ipse.getMessage());
|
||||
}
|
||||
|
||||
return algParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI methods init(): initialize the parameter
|
||||
* generator with a key size and a source of randomness.
|
||||
*
|
||||
* @param keySize
|
||||
* the key size
|
||||
* @param javaRand
|
||||
* the source of randomness
|
||||
*/
|
||||
protected final void engineInit(int keySize,
|
||||
java.security.SecureRandom javaRand) {
|
||||
SecureRandom flexiRand = new JavaSecureRandomWrapper(javaRand);
|
||||
init(keySize, flexiRand);
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI methods init(): initialize the parameter
|
||||
* generator with a parameter specification and a source of randomness.
|
||||
*
|
||||
* @param genParamSpec
|
||||
* the parameter specification
|
||||
* @param javaRand
|
||||
* the source of randomness
|
||||
* @throws java.security.InvalidAlgorithmParameterException
|
||||
* if the given parameters are invalid.
|
||||
*/
|
||||
protected final void engineInit(
|
||||
java.security.spec.AlgorithmParameterSpec genParamSpec,
|
||||
java.security.SecureRandom javaRand)
|
||||
throws java.security.InvalidAlgorithmParameterException {
|
||||
SecureRandom flexiRand = new JavaSecureRandomWrapper(javaRand);
|
||||
ModeParameterSpec paramSpec;
|
||||
if (genParamSpec instanceof javax.crypto.spec.IvParameterSpec) {
|
||||
paramSpec = new ModeParameterSpec(
|
||||
(javax.crypto.spec.IvParameterSpec) genParamSpec);
|
||||
init(paramSpec, flexiRand);
|
||||
} else {
|
||||
if (!(genParamSpec instanceof AlgorithmParameterSpec)) {
|
||||
throw new java.security.InvalidAlgorithmParameterException();
|
||||
}
|
||||
init((AlgorithmParameterSpec) genParamSpec, flexiRand);
|
||||
}
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// FlexiAPI methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* @return an instance of the {@link AlgorithmParameters} class
|
||||
* corresponding to the generated parameters
|
||||
*/
|
||||
protected abstract AlgorithmParameters getAlgorithmParameters();
|
||||
|
||||
/**
|
||||
* Initialize the parameter generator with a key size and a source of
|
||||
* randomness.
|
||||
*
|
||||
* @param keySize
|
||||
* the key size
|
||||
* @param random
|
||||
* the source of randomness
|
||||
*/
|
||||
public abstract void init(int keySize, SecureRandom random);
|
||||
|
||||
/**
|
||||
* Initialize the parameter generator with a parameter specification and a
|
||||
* source of randomness.
|
||||
*
|
||||
* @param genParamSpec
|
||||
* the parameter specification
|
||||
* @param random
|
||||
* the source of randomness
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* if the given parameters are invalid.
|
||||
*/
|
||||
public abstract void init(AlgorithmParameterSpec genParamSpec,
|
||||
SecureRandom random) throws InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* Generate parameters.
|
||||
*
|
||||
* @return the generated parameters
|
||||
*/
|
||||
public abstract AlgorithmParameterSpec generateParameters();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package de.flexiprovider.api.parameters;
|
||||
|
||||
/**
|
||||
* A (transparent) specification of cryptographic parameters.
|
||||
* <p>
|
||||
* This interface contains no methods or constants. Its only purpose is to group
|
||||
* (and provide type safety for) all parameter specifications. All parameter
|
||||
* specifications must implement this interface.
|
||||
*/
|
||||
public interface AlgorithmParameterSpec extends
|
||||
java.security.spec.AlgorithmParameterSpec {
|
||||
|
||||
// empty
|
||||
|
||||
}
|
||||
221
src/de/flexiprovider/api/parameters/AlgorithmParameters.java
Normal file
221
src/de/flexiprovider/api/parameters/AlgorithmParameters.java
Normal file
@@ -0,0 +1,221 @@
|
||||
package de.flexiprovider.api.parameters;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import de.flexiprovider.api.exceptions.InvalidParameterSpecException;
|
||||
|
||||
/**
|
||||
* This class defines the interface used to manage algorithm parameters.
|
||||
*
|
||||
* @see de.flexiprovider.api.parameters.AlgorithmParameterSpec
|
||||
*/
|
||||
public abstract class AlgorithmParameters extends
|
||||
java.security.AlgorithmParametersSpi {
|
||||
|
||||
// ****************************************************
|
||||
// JCA adapter methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method {@link #init(AlgorithmParameterSpec)}:
|
||||
* initialize this parameters object using the parameters specified in
|
||||
* <tt>paramSpec</tt>.
|
||||
*
|
||||
* @param params
|
||||
* the parameter specification
|
||||
* @throws java.security.spec.InvalidParameterSpecException
|
||||
* if <tt>paramSpec</tt> is inappropriate for
|
||||
* initialization.
|
||||
*/
|
||||
protected void engineInit(java.security.spec.AlgorithmParameterSpec params)
|
||||
throws java.security.spec.InvalidParameterSpecException {
|
||||
|
||||
if ((params == null) || !(params instanceof AlgorithmParameterSpec)) {
|
||||
throw new java.security.spec.InvalidParameterSpecException();
|
||||
}
|
||||
init((AlgorithmParameterSpec) params);
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method {@link #init(byte[])}: import the
|
||||
* specified parameters and decode them according to the primary decoding
|
||||
* format for parameters. The primary decoding format for parameters is
|
||||
* ASN.1, if an ASN.1 specification for this type of parameters exists.
|
||||
*
|
||||
* @param params
|
||||
* the encoded parameters
|
||||
* @throws IOException
|
||||
* on decoding errors.
|
||||
*/
|
||||
protected final void engineInit(byte[] params) throws IOException {
|
||||
init(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method {@link #init(byte[], String)}: import
|
||||
* the specified parameters and decode them according to the specified
|
||||
* decoding format. If <tt>format</tt> is null, the primary decoding
|
||||
* format for parameters is used. The primary decoding format is ASN.1, if
|
||||
* an ASN.1 specification for these parameters exists.
|
||||
*
|
||||
* @param params
|
||||
* the encoded parameters
|
||||
* @param format
|
||||
* the decoding format
|
||||
* @throws IOException
|
||||
* on decoding errors.
|
||||
*/
|
||||
protected final void engineInit(byte[] params, String format)
|
||||
throws IOException {
|
||||
init(params, format);
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method {@link #getEncoded()}: return the
|
||||
* parameters in their primary encoding format. The primary encoding format
|
||||
* for parameters is ASN.1, if an ASN.1 specification for this type of
|
||||
* parameters exists.
|
||||
*
|
||||
* @return the parameters encoded in their primary encoding format
|
||||
* @throws IOException
|
||||
* on encoding errors.
|
||||
*/
|
||||
protected final byte[] engineGetEncoded() throws IOException {
|
||||
return getEncoded();
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method {@link #getEncoded(String)}: return the
|
||||
* parameters in the specified encoding format. If <tt>format</tt> is
|
||||
* null, the primary decoding format is used. The primary encoding format
|
||||
* for parameters is ASN.1, if an ASN.1 specification for this type of
|
||||
* parameters exists.
|
||||
*
|
||||
* @param format
|
||||
* the encoding format
|
||||
* @return the parameters encoded in the specified encoding format
|
||||
* @throws IOException
|
||||
* on encoding errors.
|
||||
*/
|
||||
protected final byte[] engineGetEncoded(String format) throws IOException {
|
||||
return getEncoded(format);
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method {@link #getParameterSpec(Class)}: return
|
||||
* a (transparent) specification of this parameters object.
|
||||
* <tt>paramSpec</tt> identifies the specification class in which the
|
||||
* parameters should be returned. It could, for example, be
|
||||
* {@link java.security.spec.DSAParameterSpec}<tt>.class</tt> , to
|
||||
* indicate that the parameters should be returned in an instance of the
|
||||
* {@link java.security.spec.DSAParameterSpec} class.
|
||||
*
|
||||
* @param paramSpec
|
||||
* the the specification class in which the parameters should
|
||||
* be returned
|
||||
* @return the parameter specification
|
||||
* @throws java.security.spec.InvalidParameterSpecException
|
||||
* if the requested parameter specification is inappropriate
|
||||
* for this parameter object.
|
||||
*/
|
||||
protected java.security.spec.AlgorithmParameterSpec engineGetParameterSpec(
|
||||
Class paramSpec)
|
||||
throws java.security.spec.InvalidParameterSpecException {
|
||||
if (!(AlgorithmParameterSpec.class.isAssignableFrom(paramSpec))) {
|
||||
throw new java.security.spec.InvalidParameterSpecException(
|
||||
"Unsupported parameter specification.");
|
||||
}
|
||||
return getParameterSpec(paramSpec);
|
||||
}
|
||||
|
||||
/**
|
||||
* JCA adapter for FlexiAPI method {@link #toString()}.
|
||||
*
|
||||
* @return a human readable form of this parameters object
|
||||
*/
|
||||
protected final String engineToString() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
// ****************************************************
|
||||
// FlexiAPI methods
|
||||
// ****************************************************
|
||||
|
||||
/**
|
||||
* Initialize the parameters with the given parameter specification.
|
||||
*
|
||||
* @param paramSpec
|
||||
* the parameter specification
|
||||
* @throws InvalidParameterSpecException
|
||||
* if the parameter specification is <tt>null</tt> or of
|
||||
* an unsupported type.
|
||||
*/
|
||||
public abstract void init(AlgorithmParameterSpec paramSpec)
|
||||
throws InvalidParameterSpecException;
|
||||
|
||||
/**
|
||||
* Import the given encoded parameters and decode them according to the
|
||||
* primary encoding format (ASN.1).
|
||||
*
|
||||
* @param encParams
|
||||
* the encoded parameters
|
||||
* @throws IOException
|
||||
* on decoding errors.
|
||||
*/
|
||||
public abstract void init(byte[] encParams) throws IOException;
|
||||
|
||||
/**
|
||||
* Import the given encoded parameters and decode them according to the
|
||||
* specified encoding format.
|
||||
*
|
||||
* @param encParams
|
||||
* the encoded parameters
|
||||
* @param format
|
||||
* the encoding format
|
||||
* @throws IOException
|
||||
* on decoding errors or if the encoding format is
|
||||
* <tt>null</tt> or not supported.
|
||||
*/
|
||||
public abstract void init(byte[] encParams, String format)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Encode the parameters according to the primary encoding format (ASN.1).
|
||||
*
|
||||
* @return the encoded parameters
|
||||
* @throws IOException
|
||||
* on encoding errors.
|
||||
*/
|
||||
public abstract byte[] getEncoded() throws IOException;
|
||||
|
||||
/**
|
||||
* Encode the parameters according to the specified encoding format.
|
||||
*
|
||||
* @param format
|
||||
* the encoding format
|
||||
* @return the encoded parameters
|
||||
* @throws IOException
|
||||
* on encoding errors or if the encoding format is
|
||||
* <tt>null</tt> or not supported.
|
||||
*/
|
||||
public abstract byte[] getEncoded(String format) throws IOException;
|
||||
|
||||
/**
|
||||
* Return a transparent specification of the parameters.
|
||||
*
|
||||
* @param paramSpec
|
||||
* the desired parameter specification type
|
||||
* @return the parameter specification
|
||||
* @throws InvalidParameterSpecException
|
||||
* if the parameter specification type is <tt>null</tt> or
|
||||
* or not supported
|
||||
*/
|
||||
public abstract AlgorithmParameterSpec getParameterSpec(Class paramSpec)
|
||||
throws InvalidParameterSpecException;
|
||||
|
||||
/**
|
||||
* @return a human readable form of the parameters
|
||||
*/
|
||||
public abstract String toString();
|
||||
|
||||
}
|
||||
43
src/de/flexiprovider/common/exceptions/ECException.java
Normal file
43
src/de/flexiprovider/common/exceptions/ECException.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2003 by The FlexiProvider Group,
|
||||
* Technische Universitaet Darmstadt
|
||||
*
|
||||
* For conditions of usage and distribution please refer to the
|
||||
* file COPYING in the root directory of this package.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.flexiprovider.common.exceptions;
|
||||
|
||||
/**
|
||||
* This exception is the parentclass of all exceptions, that relate to the ec -
|
||||
* arithmetic.
|
||||
*
|
||||
* @author Birgit Henhapl
|
||||
* @see de.flexiprovider.common.math.ellipticcurves.Point
|
||||
* @see de.flexiprovider.common.math.ellipticcurves.PointGFP
|
||||
*/
|
||||
public class ECException extends RuntimeException {
|
||||
|
||||
private static final String diagnostic = "An ec-specific exception was thrown";
|
||||
|
||||
/**
|
||||
* Default constructor. Calls super-constructor with the message "An
|
||||
* ec-specific exception was thrown".
|
||||
*/
|
||||
public ECException() {
|
||||
super(diagnostic);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with the message "An ec-specific exception was thrown:
|
||||
* <em>cause</em>"
|
||||
*
|
||||
* @param cause
|
||||
* String specifying cause of exception
|
||||
*/
|
||||
public ECException(String cause) {
|
||||
super(diagnostic + ": " + cause);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2003 by The FlexiProvider Group,
|
||||
* Technische Universitaet Darmstadt
|
||||
*
|
||||
* For conditions of usage and distribution please refer to the
|
||||
* file COPYING in the root directory of this package.
|
||||
*
|
||||
*/
|
||||
|
||||
package de.flexiprovider.common.exceptions;
|
||||
|
||||
import de.flexiprovider.common.math.FlexiBigInt;
|
||||
|
||||
/**
|
||||
* This exception is thrown, if the square root modulo a prime of a nonquadratic
|
||||
* residue is to be calculated.
|
||||
*
|
||||
* @author Birgit Henhapl
|
||||
* @see de.flexiprovider.common.math.ellipticcurves.Point
|
||||
* @see de.flexiprovider.common.math.ellipticcurves.PointGFP
|
||||
*/
|
||||
public class NoQuadraticResidueException extends ECException {
|
||||
|
||||
/**
|
||||
* Default constructor. Calls super-constructor with no message.
|
||||
*/
|
||||
public NoQuadraticResidueException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs NoQuadraticResidueException with the message:<br>
|
||||
* NoQuadraticResidueException:<br>
|
||||
* a = <tt>a</tt> is not a quadratic residue mod p = <tt>p</tt>.
|
||||
*
|
||||
* @param a
|
||||
* the value to calculate the square root from
|
||||
* @param p
|
||||
* characteristic of the underlying field
|
||||
*/
|
||||
public NoQuadraticResidueException(FlexiBigInt a, FlexiBigInt p) {
|
||||
super("NoQuadraticResidueException:\na = " + a + " is not"
|
||||
+ "a quadratic residue mod p = " + p + ".");
|
||||
}
|
||||
|
||||
}
|
||||
224
src/de/flexiprovider/common/math/FlexiBigInt.java
Normal file
224
src/de/flexiprovider/common/math/FlexiBigInt.java
Normal file
@@ -0,0 +1,224 @@
|
||||
package de.flexiprovider.common.math;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import de.flexiprovider.api.SecureRandom;
|
||||
|
||||
public final class FlexiBigInt {
|
||||
|
||||
private class JavaSecureRandom extends java.security.SecureRandom {
|
||||
JavaSecureRandom(SecureRandom flexiRand) {
|
||||
super(flexiRand, null);
|
||||
}
|
||||
}
|
||||
|
||||
public BigInteger bigInt;
|
||||
|
||||
public FlexiBigInt(byte[] val) {
|
||||
bigInt = new BigInteger(val);
|
||||
}
|
||||
|
||||
public FlexiBigInt(String val) {
|
||||
bigInt = new BigInteger(val);
|
||||
}
|
||||
|
||||
public FlexiBigInt(int signum, byte[] magnitude) {
|
||||
bigInt = new BigInteger(signum, magnitude);
|
||||
}
|
||||
|
||||
public FlexiBigInt(String val, int radix) {
|
||||
bigInt = new BigInteger(val, radix);
|
||||
}
|
||||
|
||||
public FlexiBigInt(int numBits, SecureRandom flexiRand) {
|
||||
JavaSecureRandom javaRand = new JavaSecureRandom(flexiRand);
|
||||
bigInt = new BigInteger(numBits, javaRand);
|
||||
}
|
||||
|
||||
public FlexiBigInt(int bitLength, int certainty, SecureRandom flexiRand) {
|
||||
JavaSecureRandom javaRand = new JavaSecureRandom(flexiRand);
|
||||
bigInt = new BigInteger(bitLength, certainty, javaRand);
|
||||
}
|
||||
|
||||
public FlexiBigInt(BigInteger bigInt) {
|
||||
this.bigInt = bigInt;
|
||||
}
|
||||
|
||||
public static FlexiBigInt valueOf(long val) {
|
||||
return new FlexiBigInt(BigInteger.valueOf(val));
|
||||
}
|
||||
|
||||
public static final FlexiBigInt ZERO = new FlexiBigInt(BigInteger.ZERO);
|
||||
|
||||
public static final FlexiBigInt ONE = valueOf(1);
|
||||
|
||||
public FlexiBigInt add(FlexiBigInt addend) {
|
||||
return new FlexiBigInt(bigInt.add(addend.bigInt));
|
||||
}
|
||||
|
||||
public FlexiBigInt subtract(FlexiBigInt minuend) {
|
||||
return new FlexiBigInt(bigInt.subtract(minuend.bigInt));
|
||||
}
|
||||
|
||||
public FlexiBigInt multiply(FlexiBigInt factor) {
|
||||
return new FlexiBigInt(bigInt.multiply(factor.bigInt));
|
||||
}
|
||||
|
||||
public FlexiBigInt divide(FlexiBigInt divisor) {
|
||||
return new FlexiBigInt(bigInt.divide(divisor.bigInt));
|
||||
}
|
||||
|
||||
public FlexiBigInt[] divideAndRemainder(FlexiBigInt divisor) {
|
||||
BigInteger[] dar = bigInt.divideAndRemainder(divisor.bigInt);
|
||||
return new FlexiBigInt[] { new FlexiBigInt(dar[0]),
|
||||
new FlexiBigInt(dar[1]) };
|
||||
}
|
||||
|
||||
public FlexiBigInt remainder(FlexiBigInt divisor) {
|
||||
return new FlexiBigInt(bigInt.remainder(divisor.bigInt));
|
||||
}
|
||||
|
||||
public FlexiBigInt pow(int exponent) {
|
||||
return new FlexiBigInt(bigInt.pow(exponent));
|
||||
}
|
||||
|
||||
public FlexiBigInt gcd(FlexiBigInt val) {
|
||||
return new FlexiBigInt(bigInt.gcd(val.bigInt));
|
||||
}
|
||||
|
||||
public FlexiBigInt abs() {
|
||||
return new FlexiBigInt(bigInt.abs());
|
||||
}
|
||||
|
||||
public FlexiBigInt negate() {
|
||||
return new FlexiBigInt(bigInt.negate());
|
||||
}
|
||||
|
||||
public int signum() {
|
||||
return bigInt.signum();
|
||||
}
|
||||
|
||||
public FlexiBigInt mod(FlexiBigInt modulus) {
|
||||
return new FlexiBigInt(bigInt.mod(modulus.bigInt));
|
||||
}
|
||||
|
||||
public FlexiBigInt modPow(FlexiBigInt exponent, FlexiBigInt modulus) {
|
||||
return new FlexiBigInt(bigInt.modPow(exponent.bigInt, modulus.bigInt));
|
||||
}
|
||||
|
||||
public FlexiBigInt modInverse(FlexiBigInt modulus) {
|
||||
return new FlexiBigInt(bigInt.modInverse(modulus.bigInt));
|
||||
}
|
||||
|
||||
public FlexiBigInt shiftLeft(int n) {
|
||||
return new FlexiBigInt(bigInt.shiftLeft(n));
|
||||
}
|
||||
|
||||
public FlexiBigInt shiftRight(int n) {
|
||||
return new FlexiBigInt(bigInt.shiftRight(n));
|
||||
}
|
||||
|
||||
public FlexiBigInt and(FlexiBigInt val) {
|
||||
return new FlexiBigInt(bigInt.and(val.bigInt));
|
||||
}
|
||||
|
||||
public FlexiBigInt or(FlexiBigInt val) {
|
||||
return new FlexiBigInt(bigInt.or(val.bigInt));
|
||||
}
|
||||
|
||||
public FlexiBigInt xor(FlexiBigInt val) {
|
||||
return new FlexiBigInt(bigInt.xor(val.bigInt));
|
||||
}
|
||||
|
||||
public FlexiBigInt not() {
|
||||
return new FlexiBigInt(bigInt.not());
|
||||
}
|
||||
|
||||
public FlexiBigInt andNot(FlexiBigInt val) {
|
||||
return new FlexiBigInt(bigInt.andNot(val.bigInt));
|
||||
}
|
||||
|
||||
public boolean testBit(int n) {
|
||||
return bigInt.testBit(n);
|
||||
}
|
||||
|
||||
public FlexiBigInt setBit(int n) {
|
||||
return new FlexiBigInt(bigInt.setBit(n));
|
||||
}
|
||||
|
||||
public FlexiBigInt clearBit(int n) {
|
||||
return new FlexiBigInt(bigInt.clearBit(n));
|
||||
}
|
||||
|
||||
public FlexiBigInt flipBit(int n) {
|
||||
return new FlexiBigInt(bigInt.flipBit(n));
|
||||
}
|
||||
|
||||
public int getLowestSetBit() {
|
||||
return bigInt.getLowestSetBit();
|
||||
}
|
||||
|
||||
public int bitLength() {
|
||||
return bigInt.bitLength();
|
||||
}
|
||||
|
||||
public int bitCount() {
|
||||
return bigInt.bitCount();
|
||||
}
|
||||
|
||||
public boolean isProbablePrime(int certainty) {
|
||||
return bigInt.isProbablePrime(certainty);
|
||||
}
|
||||
|
||||
public int compareTo(FlexiBigInt other) {
|
||||
return bigInt.compareTo(other.bigInt);
|
||||
}
|
||||
|
||||
public FlexiBigInt min(FlexiBigInt other) {
|
||||
return new FlexiBigInt(bigInt.min(other.bigInt));
|
||||
}
|
||||
|
||||
public FlexiBigInt max(FlexiBigInt other) {
|
||||
return new FlexiBigInt(bigInt.max(other.bigInt));
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof FlexiBigInt)) {
|
||||
return false;
|
||||
}
|
||||
return bigInt.equals(((FlexiBigInt) other).bigInt);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return bigInt.hashCode();
|
||||
}
|
||||
|
||||
public String toString(int radix) {
|
||||
return bigInt.toString(radix);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return bigInt.toString();
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
return bigInt.toByteArray();
|
||||
}
|
||||
|
||||
public int intValue() {
|
||||
return bigInt.intValue();
|
||||
}
|
||||
|
||||
public long longValue() {
|
||||
return bigInt.longValue();
|
||||
}
|
||||
|
||||
public float floatValue() {
|
||||
return bigInt.floatValue();
|
||||
}
|
||||
|
||||
public double doubleValue() {
|
||||
return bigInt.doubleValue();
|
||||
}
|
||||
|
||||
}
|
||||
1327
src/de/flexiprovider/common/math/IntegerFunctions.java
Normal file
1327
src/de/flexiprovider/common/math/IntegerFunctions.java
Normal file
File diff suppressed because it is too large
Load Diff
278
src/de/flexiprovider/common/math/MathFunctions.java
Normal file
278
src/de/flexiprovider/common/math/MathFunctions.java
Normal file
@@ -0,0 +1,278 @@
|
||||
package de.flexiprovider.common.math;
|
||||
|
||||
/**
|
||||
* Class of number-theory related functions providing J2ME conform
|
||||
* implementations of functions contained in the java.lang.Math package but not
|
||||
* provided for J2ME.
|
||||
*
|
||||
*
|
||||
* @author Johannes Braun
|
||||
*
|
||||
*/
|
||||
public final class MathFunctions {
|
||||
|
||||
private MathFunctions(){
|
||||
//empty
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute <tt>e<sup>exponent</sup></tt>
|
||||
* J2ME conform implementation of the "Math.exp" function.
|
||||
* @param exponent
|
||||
* the exponent
|
||||
* @return <tt>e<sup>exponent</sup></tt>
|
||||
*/
|
||||
public static double exp(double exponent) {
|
||||
double d = exponent;
|
||||
boolean negative = false;
|
||||
double result = 1;
|
||||
int iterations = 20;
|
||||
|
||||
if (d < 0) {
|
||||
negative = true;
|
||||
d *= -1;
|
||||
}
|
||||
|
||||
if (d >= 1) {
|
||||
int temp = (int) d;
|
||||
double a=Math.E;
|
||||
while (temp > 0) {
|
||||
if ((temp & 1) == 1) {
|
||||
result *=a;
|
||||
}
|
||||
a *= a;
|
||||
temp >>>= 1;
|
||||
}
|
||||
if ((d - Math.floor(d)) == 0) {
|
||||
if (negative) {
|
||||
return 1 / result;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double temp = d - Math.floor(d);
|
||||
double den = 1;
|
||||
double num = 1;
|
||||
double result2 = 1;
|
||||
|
||||
for (int i = 1; i < iterations; i++) {
|
||||
den *= i;
|
||||
num *= temp;
|
||||
result2 += num / den;
|
||||
}
|
||||
|
||||
if (negative) {
|
||||
return 1 / (result * result2);
|
||||
} else {
|
||||
return result * result2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate the logarithm to the base 2.
|
||||
*
|
||||
* @param x
|
||||
* any double value
|
||||
* @return log_2(x)
|
||||
*/
|
||||
public static double log(double x) {
|
||||
if(x<=0)
|
||||
throw new ArithmeticException("log(x) only defined for positive values");
|
||||
if(x>0&&x<1){
|
||||
double d= 1/x;
|
||||
double result=-log(d);
|
||||
return result;
|
||||
}
|
||||
|
||||
int tmp=0;
|
||||
double tmp2=1;
|
||||
double d=x;
|
||||
|
||||
while(d>2){
|
||||
d=d/2;
|
||||
tmp+=1;
|
||||
tmp2*=2;
|
||||
}
|
||||
double rem = x / tmp2;
|
||||
rem = logBKM(rem);
|
||||
return (double) tmp + rem;
|
||||
}
|
||||
|
||||
/**
|
||||
* calculate the logarithm to the base 2.
|
||||
*
|
||||
* @param x
|
||||
* any long value >=1
|
||||
* @return log_2(x)
|
||||
*/
|
||||
public static double log(long x) {
|
||||
if(x<=0)
|
||||
throw new ArithmeticException("log(x) only defined for positive values");
|
||||
|
||||
int tmp = IntegerFunctions.floorLog(FlexiBigInt.valueOf(x));
|
||||
long tmp2 = 1l << tmp;
|
||||
double rem = (double) x / (double) tmp2;
|
||||
rem = logBKM(rem);
|
||||
return (double) tmp + rem;
|
||||
}
|
||||
|
||||
/**
|
||||
* BKM Algorithm to calculate logarithms to the base 2.
|
||||
*
|
||||
* @param arg
|
||||
* a double value with 1<= arg<= 4.768462058
|
||||
*
|
||||
* @return log_2(arg)
|
||||
*/
|
||||
private static double logBKM(double arg) {
|
||||
if(arg<=0)
|
||||
throw new ArithmeticException("logBKM(x) only defined for positive values");
|
||||
double ae[] = // A_e[k] = log_2 (1 + 0.5^k)
|
||||
{
|
||||
1.0000000000000000000000000000000000000000000000000000000000000000000000000000,
|
||||
0.5849625007211561814537389439478165087598144076924810604557526545410982276485,
|
||||
0.3219280948873623478703194294893901758648313930245806120547563958159347765589,
|
||||
0.1699250014423123629074778878956330175196288153849621209115053090821964552970,
|
||||
0.0874628412503394082540660108104043540112672823448206881266090643866965081686,
|
||||
0.0443941193584534376531019906736094674630459333742491317685543002674288465967,
|
||||
0.0223678130284545082671320837460849094932677948156179815932199216587899627785,
|
||||
0.0112272554232541203378805844158839407281095943600297940811823651462712311786,
|
||||
0.0056245491938781069198591026740666017211096815383520359072957784732489771013,
|
||||
0.0028150156070540381547362547502839489729507927389771959487826944878598909400,
|
||||
0.0014081943928083889066101665016890524233311715793462235597709051792834906001,
|
||||
0.0007042690112466432585379340422201964456668872087249334581924550139514213168,
|
||||
0.0003521774803010272377989609925281744988670304302127133979341729842842377649,
|
||||
0.0001760994864425060348637509459678580940163670081839283659942864068257522373,
|
||||
0.0000880524301221769086378699983597183301490534085738474534831071719854721939,
|
||||
0.0000440268868273167176441087067175806394819146645511899503059774914593663365,
|
||||
0.0000220136113603404964890728830697555571275493801909791504158295359319433723,
|
||||
0.0000110068476674814423006223021573490183469930819844945565597452748333526464,
|
||||
0.0000055034343306486037230640321058826431606183125807276574241540303833251704,
|
||||
0.0000027517197895612831123023958331509538486493412831626219340570294203116559,
|
||||
0.0000013758605508411382010566802834037147561973553922354232704569052932922954,
|
||||
0.0000006879304394358496786728937442939160483304056131990916985043387874690617,
|
||||
0.0000003439652607217645360118314743718005315334062644619363447395987584138324,
|
||||
0.0000001719826406118446361936972479533123619972434705828085978955697643547921,
|
||||
0.0000000859913228686632156462565208266682841603921494181830811515318381744650,
|
||||
0.0000000429956620750168703982940244684787907148132725669106053076409624949917,
|
||||
0.0000000214978311976797556164155504126645192380395989504741781512309853438587,
|
||||
0.0000000107489156388827085092095702361647949603617203979413516082280717515504,
|
||||
0.0000000053744578294520620044408178949217773318785601260677517784797554422804,
|
||||
0.0000000026872289172287079490026152352638891824761667284401180026908031182361,
|
||||
0.0000000013436144592400232123622589569799954658536700992739887706412976115422,
|
||||
0.0000000006718072297764289157920422846078078155859484240808550018085324187007,
|
||||
0.0000000003359036149273187853169587152657145221968468364663464125722491530858,
|
||||
0.0000000001679518074734354745159899223037458278711244127245990591908996412262,
|
||||
0.0000000000839759037391617577226571237484864917411614198675604731728132152582,
|
||||
0.0000000000419879518701918839775296677020135040214077417929807824842667285938,
|
||||
0.0000000000209939759352486932678195559552767641474249812845414125580747434389,
|
||||
0.0000000000104969879676625344536740142096218372850561859495065136990936290929,
|
||||
0.0000000000052484939838408141817781356260462777942148580518406975851213868092,
|
||||
0.0000000000026242469919227938296243586262369156865545638305682553644113887909,
|
||||
0.0000000000013121234959619935994960031017850191710121890821178731821983105443,
|
||||
0.0000000000006560617479811459709189576337295395590603644549624717910616347038,
|
||||
0.0000000000003280308739906102782522178545328259781415615142931952662153623493,
|
||||
0.0000000000001640154369953144623242936888032768768777422997704541618141646683,
|
||||
0.0000000000000820077184976595619616930350508356401599552034612281802599177300,
|
||||
0.0000000000000410038592488303636807330652208397742314215159774270270147020117,
|
||||
0.0000000000000205019296244153275153381695384157073687186580546938331088730952,
|
||||
0.0000000000000102509648122077001764119940017243502120046885379813510430378661,
|
||||
0.0000000000000051254824061038591928917243090559919209628584150482483994782302,
|
||||
0.0000000000000025627412030519318726172939815845367496027046030028595094737777,
|
||||
0.0000000000000012813706015259665053515049475574143952543145124550608158430592,
|
||||
0.0000000000000006406853007629833949364669629701200556369782295210193569318434,
|
||||
0.0000000000000003203426503814917330334121037829290364330169106716787999052925,
|
||||
0.0000000000000001601713251907458754080007074659337446341494733882570243497196,
|
||||
0.0000000000000000800856625953729399268240176265844257044861248416330071223615,
|
||||
0.0000000000000000400428312976864705191179247866966320469710511619971334577509,
|
||||
0.0000000000000000200214156488432353984854413866994246781519154793320684126179,
|
||||
0.0000000000000000100107078244216177339743404416874899847406043033792202127070,
|
||||
0.0000000000000000050053539122108088756700751579281894640362199287591340285355,
|
||||
0.0000000000000000025026769561054044400057638132352058574658089256646014899499,
|
||||
0.0000000000000000012513384780527022205455634651853807110362316427807660551208,
|
||||
0.0000000000000000006256692390263511104084521222346348012116229213309001913762,
|
||||
0.0000000000000000003128346195131755552381436585278035120438976487697544916191,
|
||||
0.0000000000000000001564173097565877776275512286165232838833090480508502328437,
|
||||
0.0000000000000000000782086548782938888158954641464170239072244145219054734086,
|
||||
0.0000000000000000000391043274391469444084776945327473574450334092075712154016,
|
||||
0.0000000000000000000195521637195734722043713378812583900953755962557525252782,
|
||||
0.0000000000000000000097760818597867361022187915943503728909029699365320287407,
|
||||
0.0000000000000000000048880409298933680511176764606054809062553340323879609794,
|
||||
0.0000000000000000000024440204649466840255609083961603140683286362962192177597,
|
||||
0.0000000000000000000012220102324733420127809717395445504379645613448652614939,
|
||||
0.0000000000000000000006110051162366710063906152551383735699323415812152114058,
|
||||
0.0000000000000000000003055025581183355031953399739107113727036860315024588989,
|
||||
0.0000000000000000000001527512790591677515976780735407368332862218276873443537,
|
||||
0.0000000000000000000000763756395295838757988410584167137033767056170417508383,
|
||||
0.0000000000000000000000381878197647919378994210346199431733717514843471513618,
|
||||
0.0000000000000000000000190939098823959689497106436628681671067254111334889005,
|
||||
0.0000000000000000000000095469549411979844748553534196582286585751228071408728,
|
||||
0.0000000000000000000000047734774705989922374276846068851506055906657137209047,
|
||||
0.0000000000000000000000023867387352994961187138442777065843718711089344045782,
|
||||
0.0000000000000000000000011933693676497480593569226324192944532044984865894525,
|
||||
0.0000000000000000000000005966846838248740296784614396011477934194852481410926,
|
||||
0.0000000000000000000000002983423419124370148392307506484490384140516252814304,
|
||||
0.0000000000000000000000001491711709562185074196153830361933046331030629430117,
|
||||
0.0000000000000000000000000745855854781092537098076934460888486730708440475045,
|
||||
0.0000000000000000000000000372927927390546268549038472050424734256652501673274,
|
||||
0.0000000000000000000000000186463963695273134274519237230207489851150821191330,
|
||||
0.0000000000000000000000000093231981847636567137259618916352525606281553180093,
|
||||
0.0000000000000000000000000046615990923818283568629809533488457973317312233323,
|
||||
0.0000000000000000000000000023307995461909141784314904785572277779202790023236,
|
||||
0.0000000000000000000000000011653997730954570892157452397493151087737428485431,
|
||||
0.0000000000000000000000000005826998865477285446078726199923328593402722606924,
|
||||
0.0000000000000000000000000002913499432738642723039363100255852559084863397344,
|
||||
0.0000000000000000000000000001456749716369321361519681550201473345138307215067,
|
||||
0.0000000000000000000000000000728374858184660680759840775119123438968122488047,
|
||||
0.0000000000000000000000000000364187429092330340379920387564158411083803465567,
|
||||
0.0000000000000000000000000000182093714546165170189960193783228378441837282509,
|
||||
0.0000000000000000000000000000091046857273082585094980096891901482445902524441,
|
||||
0.0000000000000000000000000000045523428636541292547490048446022564529197237262,
|
||||
0.0000000000000000000000000000022761714318270646273745024223029238091160103901};
|
||||
int n= 53;
|
||||
double x = 1;
|
||||
double y = 0;
|
||||
double z;
|
||||
double s = 1;
|
||||
int k;
|
||||
|
||||
for (k = 0; k < n; k++) {
|
||||
z = x + x * s;
|
||||
if (z <= arg) {
|
||||
x = z;
|
||||
y += ae[k];
|
||||
}
|
||||
s *= 0.5;
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* round a double value to its nearest long integer value
|
||||
* @param d
|
||||
* the double to be rounded
|
||||
* @return the nearest long integer
|
||||
*/
|
||||
public static long round(double d){
|
||||
return (long)((d >= 0) ? Math.floor(d+0.5) : Math.ceil(d-0.5));
|
||||
}
|
||||
|
||||
/**
|
||||
* round a double value to a specified number of decimal places
|
||||
* @param d
|
||||
* the double to be rounded
|
||||
* @param digits
|
||||
* the number of remaining decimal places after rounding
|
||||
* @return the rounded double
|
||||
*/
|
||||
public static double round(double d, int digits) {
|
||||
int m = IntegerFunctions.pow(10, digits);
|
||||
double d2 = d * m;
|
||||
double res =(d >= 0) ? Math.floor(d2+0.5) : Math.ceil(d2-0.5);
|
||||
return res / m;
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user