Author: nextgens
Date: 2006-02-12 18:12:16 +0000 (Sun, 12 Feb 2006)
New Revision: 8029
Added:
trunk/apps/installer/build/
trunk/apps/installer/src/gnu/
trunk/apps/installer/src/gnu/crypto/
trunk/apps/installer/src/gnu/crypto/Registry.java
trunk/apps/installer/src/gnu/crypto/hash/
trunk/apps/installer/src/gnu/crypto/hash/BaseHash.java
trunk/apps/installer/src/gnu/crypto/hash/IMessageDigest.java
trunk/apps/installer/src/gnu/crypto/hash/Sha160.java
trunk/apps/installer/src/gnu/crypto/util/
trunk/apps/installer/src/gnu/crypto/util/Util.java
Modified:
trunk/apps/installer/build-installer.xml
trunk/apps/installer/src/Sha1Test.java
trunk/apps/installer/src/freenet/support/HexUtil.java
Log:
Antinstaller: Now we use GNU-crypto for sha1sums
Modified: trunk/apps/installer/build-installer.xml
===================================================================
--- trunk/apps/installer/build-installer.xml 2006-02-12 17:41:47 UTC (rev
8028)
+++ trunk/apps/installer/build-installer.xml 2006-02-12 18:12:16 UTC (rev
8029)
@@ -14,7 +14,7 @@
classname="org.tp23.antinstaller.taskdefs.Installer"
classpathref="taskdef.cp"/>
- <target name="selfextract" depends="jar_sha1test">
+ <target name="selfextract" depends="compile_sha1test">
<echo message="Building INSTALLER SELFEXTRACT"/>
<installer file="./selfextractpack.jar" compress="true"
extractType="SelfExtractor"
@@ -37,7 +37,7 @@
<!-- Create the build directory structure used by compile -->
<javac srcdir="./src" destdir="./build" optimize="on" source="1.4">
- <include name="freenet/crypt/SHA1.java"/>
+ <include name="gnu/**/*.java"/>
<include name="freenet/support/HexUtil"/>
<include name="Sha1Test.java"/>
</javac>
Modified: trunk/apps/installer/src/Sha1Test.java
===================================================================
--- trunk/apps/installer/src/Sha1Test.java 2006-02-12 17:41:47 UTC (rev
8028)
+++ trunk/apps/installer/src/Sha1Test.java 2006-02-12 18:12:16 UTC (rev
8029)
@@ -1,5 +1,5 @@
-import freenet.crypt.SHA1;
import freenet.support.HexUtil;
+import gnu.crypto.hash.*;
import java.io.File;
import java.io.FileInputStream;
@@ -17,7 +17,7 @@
* @return 2 if an error occured
*/
public static void main(String[] args) {
- SHA1 hash=new SHA1();
+ Sha160 hash=new Sha160();
if(args.length != 1) System.exit(2);
try{
Modified: trunk/apps/installer/src/freenet/support/HexUtil.java
===================================================================
--- trunk/apps/installer/src/freenet/support/HexUtil.java 2006-02-12
17:41:47 UTC (rev 8028)
+++ trunk/apps/installer/src/freenet/support/HexUtil.java 2006-02-12
18:12:16 UTC (rev 8029)
@@ -15,7 +15,6 @@
* @author syoung
*/
public class HexUtil {
- private static boolean logDEBUG
=Logger.logger.instanceShouldLog(Logger.DEBUG,HexUtil.class);
private HexUtil() {
}
@@ -110,7 +109,6 @@
int bytesAlloc = countBytesForBits(size);
byte[] b = new byte[bytesAlloc];
StringBuffer sb =null;
- if(logDEBUG) sb = new StringBuffer(8*bytesAlloc); //TODO:
Should it be 2*8*bytesAlloc here?
for(int i=0;i<b.length;i++) {
short s = 0;
for(int j=0;j<8;j++) {
@@ -124,8 +122,6 @@
if(s > 255) throw new IllegalStateException("WTF? s =
"+s);
b[i] = (byte)s;
}
- if(logDEBUG) Logger.debug(HexUtil.class, "bytes: "+bytesAlloc+"
returned from bitsToBytes("
- +ba+","+size+"): "+bytesToHex(b)+" for
"+sb.toString());
return b;
}
@@ -154,7 +150,6 @@
* @param ba the bitset to write to
*/
public static void bytesToBits(byte[] b, BitSet ba, int maxSize) {
- if(logDEBUG) Logger.debug(HexUtil.class,
"bytesToBits("+bytesToHex(b)+",ba,"+maxSize);
int x = 0;
for(int i=0;i<b.length;i++) {
for(int j=0;j<8;j++) {
@@ -186,7 +181,6 @@
*/
public static void writeBigInteger(BigInteger integer, DataOutputStream
out) throws IOException {
if(integer.signum() == -1) {
- //dump("Negative BigInteger", Logger.ERROR, true);
throw new IllegalStateException("Negative BigInteger!");
}
byte[] buf = integer.toByteArray();
Added: trunk/apps/installer/src/gnu/crypto/Registry.java
===================================================================
--- trunk/apps/installer/src/gnu/crypto/Registry.java 2006-02-12 17:41:47 UTC
(rev 8028)
+++ trunk/apps/installer/src/gnu/crypto/Registry.java 2006-02-12 18:12:16 UTC
(rev 8029)
@@ -0,0 +1,364 @@
+package gnu.crypto;
+
+// ----------------------------------------------------------------------------
+// $Id: Registry.java.in,v 1.4 2005/10/06 04:24:13 rsdio Exp $
+//
+// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+//
+// This file is part of GNU Crypto.
+//
+// GNU Crypto is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GNU Crypto 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to the
+//
+// Free Software Foundation Inc.,
+// 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301
+// USA
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give
+// you permission to link this library with independent modules to
+// produce an executable, regardless of the license terms of these
+// independent modules, and to copy and distribute the resulting
+// executable under terms of your choice, provided that you also meet,
+// for each linked independent module, the terms and conditions of the
+// license of that module. An independent module is a module which is
+// not derived from or based on this library. If you modify this
+// library, you may extend this exception to your version of the
+// library, but you are not obligated to do so. If you do not wish to
+// do so, delete this exception statement from your version.
+// ----------------------------------------------------------------------------
+
+/**
+ * A placeholder for <i>names</i> and <i>literals</i> used throughout this
+ * library.
+ *
+ * @version $Revision: 1.4 $
+ */
+public interface Registry {
+
+ // Constants
+ // -------------------------------------------------------------------------
+
+ /** The name of our Providers. */
+ String GNU_CRYPTO = "GNU-CRYPTO";
+ String GNU_SASL = "GNU-SASL";
+ String GNU_SECURITY = "GNU-SECURITY";
+
+ /** Our version number. */
+ String VERSION_STRING = "@VERSION@@PRERELEASE@";
+
+ // Names of properties to use in Maps when initialising primitives .........
+
+ // Symmetric block cipher algorithms and synonyms...........................
+
+ String ANUBIS_CIPHER = "anubis";
+ String BLOWFISH_CIPHER = "blowfish";
+ String DES_CIPHER = "des";
+ String KHAZAD_CIPHER = "khazad";
+ String RIJNDAEL_CIPHER = "rijndael";
+ String SERPENT_CIPHER = "serpent";
+ String SQUARE_CIPHER = "square";
+ String TRIPLEDES_CIPHER = "tripledes";
+ String TWOFISH_CIPHER = "twofish";
+ String CAST5_CIPHER = "cast5";
+ String NULL_CIPHER = "null";
+
+ /** AES is synonymous to Rijndael for 128-bit block size only. */
+ String AES_CIPHER = "aes";
+
+ /** TripleDES is also known as DESede. */
+ String DESEDE_CIPHER = "desede";
+
+ /** CAST5 is also known as CAST-128. */
+ String CAST128_CIPHER = "cast128";
+ String CAST_128_CIPHER = "cast-128";
+
+ // Message digest algorithms and synonyms...................................
+
+ String WHIRLPOOL_HASH = "whirlpool";
+ String RIPEMD128_HASH = "ripemd128";
+ String RIPEMD160_HASH = "ripemd160";
+ String SHA160_HASH = "sha-160";
+ String SHA256_HASH = "sha-256";
+ String SHA384_HASH = "sha-384";
+ String SHA512_HASH = "sha-512";
+ String TIGER_HASH = "tiger";
+ String HAVAL_HASH = "haval";
+ String MD5_HASH = "md5";
+ String MD4_HASH = "md4";
+ String MD2_HASH = "md2";
+
+ /** RIPEMD-128 is synonymous to RIPEMD128. */
+ String RIPEMD_128_HASH = "ripemd-128";
+
+ /** RIPEMD-160 is synonymous to RIPEMD160. */
+ String RIPEMD_160_HASH = "ripemd-160";
+
+ /** SHA-1 is synonymous to SHA-160. */
+ String SHA_1_HASH = "sha-1";
+
+ /** SHA1 is synonymous to SHA-160. */
+ String SHA1_HASH = "sha1";
+
+ /** SHA is synonymous to SHA-160. */
+ String SHA_HASH = "sha";
+
+ // Symmetric block cipher modes of operations...............................
+
+ /** Electronic CodeBook mode. */
+ String ECB_MODE = "ecb";
+
+ /** Counter (NIST) mode. */
+ String CTR_MODE = "ctr";
+
+ /** Integer Counter Mode (David McGrew). */
+ String ICM_MODE = "icm";
+
+ /** Output Feedback Mode (NIST). */
+ String OFB_MODE = "ofb";
+
+ /** Cipher block chaining mode (NIST). */
+ String CBC_MODE = "cbc";
+
+ /** Cipher feedback mode (NIST). */
+ String CFB_MODE = "cfb";
+
+ /** Authenticated-Encrypted mode. */
+ String EAX_MODE = "eax";
+
+ // Padding scheme names and synonyms........................................
+
+ /** PKCS#7 padding scheme. */
+ String PKCS7_PAD = "pkcs7";
+
+ /** Trailing Bit Complement padding scheme. */
+ String TBC_PAD = "tbc";
+
+ /** EME-PKCS1-v1_5 padding as described in section 7.2 in RFC-3447. */
+ String EME_PKCS1_V1_5_PAD = "eme-pkcs1-v1.5";
+
+ /** SSLv3 padding scheme. */
+ String SSL3_PAD = "ssl3";
+
+ /** TLSv1 padding scheme. */
+ String TLS1_PAD = "tls1";
+
+ // Pseudo-random number generators..........................................
+
+ /** (Apparently) RC4 keystream PRNG. */
+ String ARCFOUR_PRNG = "arcfour";
+
+ /** We use "rc4" as an alias for "arcfour". */
+ String RC4_PRNG = "rc4";
+
+ /** PRNG based on David McGrew's Integer Counter Mode. */
+ String ICM_PRNG = "icm";
+
+ /** PRNG based on a designated hash function. */
+ String MD_PRNG = "md";
+
+ /** PRNG based on UMAC's Key Derivation Function. */
+ String UMAC_PRNG = "umac-kdf";
+
+ /**
+ * PRNG based on PBKDF2 from PKCS #5 v.2. This is suffixed with the name
+ * of a MAC to be used as a PRF.
+ */
+ String PBKDF2_PRNG_PREFIX = "pbkdf2-";
+
+ /** The continuously-seeded pseudo-random number generator. */
+ String CSPRNG_PRNG = "csprng";
+
+ /** The Fortuna PRNG. */
+ String FORTUNA_PRNG = "fortuna";
+
+ /** The Fortuna generator PRNG. */
+ String FORTUNA_GENERATOR_PRNG = "fortuna-generator";
+
+ // Asymmetric keypair generators............................................
+
+ String DSS_KPG = "dss";
+ String RSA_KPG = "rsa";
+ String DH_KPG = "dh";
+ String SRP_KPG = "srp";
+
+ /** DSA is synonymous to DSS. */
+ String DSA_KPG = "dsa";
+
+ // Signature-with-appendix schemes..........................................
+
+ String DSS_SIG = "dss";
+ String RSA_PSS_SIG = "rsa-pss";
+ String RSA_PKCS1_V1_5_SIG = "rsa-pkcs1-v1.5";
+
+ /** DSA is synonymous to DSS. */
+ String DSA_SIG = "dsa";
+
+ // Key agreement protocols .................................................
+
+ String DH_KA = "dh";
+ String ELGAMAL_KA = "elgamal";
+ String SRP6_KA = "srp6";
+ String SRP_SASL_KA = "srp-sasl";
+ String SRP_TLS_KA = "srp-tls";
+
+ // Keyed-Hash Message Authentication Code ..................................
+
+ /** Name prefix of every HMAC implementation. */
+ String HMAC_NAME_PREFIX = "hmac-";
+
+ // Other MAC algorithms ....................................................
+
+ /** The One-key CBC MAC. */
+ String OMAC_PREFIX = "omac-";
+
+ /** Message Authentication Code using Universal Hashing (Ted Krovetz). */
+ String UHASH32 = "uhash32";
+ String UMAC32 = "umac32";
+ /** The Truncated Multi-Modular Hash Function -v1 (David McGrew). */
+ String TMMH16 = "tmmh16";
+// String TMMH32 = "tmmh32";
+
+ // Format IDs used to identify how we externalise asymmetric keys ..........
+ String RAW_ENCODING = "gnu.crypto.raw.format";
+ int RAW_ENCODING_ID = 1;
+
+ // Magic bytes we generate/expect in externalised asymmetric keys ..........
+ // the four bytes represent G (0x47) for GNU, 1 (0x01) for Raw format,
+ // D (0x44) for DSS, R (0x52) for RSA, H (0x48) for Diffie-Hellman, or S
+ // (0x53) for SRP-6, and finally P (0x50) for Public, p (0x70) for private,
+ // or S (0x53) for signature.
+ byte[] MAGIC_RAW_DSS_PUBLIC_KEY = new byte[] {0x47, RAW_ENCODING_ID,
0x44, 0x50};
+ byte[] MAGIC_RAW_DSS_PRIVATE_KEY = new byte[] {0x47, RAW_ENCODING_ID,
0x44, 0x70};
+ byte[] MAGIC_RAW_DSS_SIGNATURE = new byte[] {0x47, RAW_ENCODING_ID,
0x44, 0x53};
+ byte[] MAGIC_RAW_RSA_PUBLIC_KEY = new byte[] {0x47, RAW_ENCODING_ID,
0x52, 0x50};
+ byte[] MAGIC_RAW_RSA_PRIVATE_KEY = new byte[] {0x47, RAW_ENCODING_ID,
0x52, 0x70};
+ byte[] MAGIC_RAW_RSA_PSS_SIGNATURE = new byte[] {0x47, RAW_ENCODING_ID,
0x52, 0x53};
+
+ byte[] MAGIC_RAW_DH_PUBLIC_KEY = new byte[] {0x47, RAW_ENCODING_ID,
0x48, 0x50};
+ byte[] MAGIC_RAW_DH_PRIVATE_KEY = new byte[] {0x47, RAW_ENCODING_ID,
0x48, 0x70};
+
+ byte[] MAGIC_RAW_SRP_PUBLIC_KEY = new byte[] {0x47, RAW_ENCODING_ID,
0x53, 0x50};
+ byte[] MAGIC_RAW_SRP_PRIVATE_KEY = new byte[] {0x47, RAW_ENCODING_ID,
0x53, 0x70};
+
+ // SASL Property names .....................................................
+
+ String SASL_PREFIX = "gnu.crypto.sasl";
+
+ /** Name of username property. */
+ String SASL_USERNAME = SASL_PREFIX + ".username";
+
+ /** Name of password property. */
+ String SASL_PASSWORD = SASL_PREFIX + ".password";
+
+ /** Name of authentication information provider packages. */
+ String SASL_AUTH_INFO_PROVIDER_PKGS = SASL_PREFIX +
".auth.info.provider.pkgs";
+
+ /** SASL authorization ID. */
+ String SASL_AUTHORISATION_ID = SASL_PREFIX + ".authorisation.ID";
+
+ /** SASL protocol. */
+ String SASL_PROTOCOL = SASL_PREFIX + ".protocol";
+
+ /** SASL Server name. */
+ String SASL_SERVER_NAME = SASL_PREFIX + ".server.name";
+
+ /** SASL Callback handler. */
+ String SASL_CALLBACK_HANDLER = SASL_PREFIX + ".callback.handler";
+
+ /** SASL channel binding. */
+ String SASL_CHANNEL_BINDING = SASL_PREFIX + ".channel.binding";
+
+ // SASL data element size limits ...........................................
+
+ /** The size limit, in bytes, of a SASL OS (Octet Sequence) element. */
+ int SASL_ONE_BYTE_MAX_LIMIT = 255;
+
+ /**
+ * The size limit, in bytes, of both a SASL MPI (Multi-Precision Integer)
+ * element and a SASL Text element.
+ */
+ int SASL_TWO_BYTE_MAX_LIMIT = 65535;
+
+ /** The size limit, in bytes, of a SASL EOS (Extended Octet Sequence)
element. */
+ int SASL_FOUR_BYTE_MAX_LIMIT = 2147483383;
+
+ /** The size limit, in bytes, of a SASL Buffer. */
+ int SASL_BUFFER_MAX_LIMIT = 2147483643;
+
+ // Canonical names of SASL mechanisms ......................................
+
+ String SASL_ANONYMOUS_MECHANISM = "ANONYMOUS";
+ String SASL_CRAM_MD5_MECHANISM = "CRAM-MD5";
+ String SASL_PLAIN_MECHANISM = "PLAIN";
+ String SASL_SRP_MECHANISM = "SRP";
+
+ // Canonical names of Integrity Protection algorithms ......................
+
+ String SASL_HMAC_MD5_IALG = "HMACwithMD5";
+ String SASL_HMAC_SHA_IALG = "HMACwithSHA";
+
+ // Quality Of Protection string representations ............................
+
+ /** authentication only. */
+ String QOP_AUTH = "auth";
+ /** authentication plus integrity protection. */
+ String QOP_AUTH_INT = "auth-int";
+ /** authentication plus integrity and confidentiality protection. */
+ String QOP_AUTH_CONF = "auth-conf";
+
+ // SASL mechanism strength string representation ...........................
+
+ String STRENGTH_HIGH = "high";
+ String STRENGTH_MEDIUM = "medium";
+ String STRENGTH_LOW = "low";
+
+ // SASL Server Authentication requirement ..................................
+
+ /** Server must authenticate to the client. */
+ String SERVER_AUTH_TRUE = "true";
+ /** Server does not need to, or cannot, authenticate to the client. */
+ String SERVER_AUTH_FALSE = "false";
+
+ // SASL mechanism reuse capability .........................................
+
+ String REUSE_TRUE = "true";
+ String REUSE_FALSE = "false";
+
+ // Keyrings ...............................................................
+
+ byte[] GKR_MAGIC = new byte[] { 0x47, 0x4b, 0x52, 0x01 };
+
+ // Ring usage fields.
+ int GKR_PRIVATE_KEYS = 1 << 0;
+ int GKR_PUBLIC_CREDENTIALS = 1 << 1;
+ int GKR_CERTIFICATES = 1 << 2;
+
+ // HMac types.
+ int GKR_HMAC_MD5_128 = 0;
+ int GKR_HMAC_SHA_160 = 1;
+ int GKR_HMAC_MD5_96 = 2;
+ int GKR_HMAC_SHA_96 = 3;
+
+ // Cipher types.
+ int GKR_CIPHER_AES_128_OFB = 0;
+ int GKR_CIPHER_AES_128_CBC = 1;
+
+ // Methods
+ // -------------------------------------------------------------------------
+}
Added: trunk/apps/installer/src/gnu/crypto/hash/BaseHash.java
===================================================================
--- trunk/apps/installer/src/gnu/crypto/hash/BaseHash.java 2006-02-12
17:41:47 UTC (rev 8028)
+++ trunk/apps/installer/src/gnu/crypto/hash/BaseHash.java 2006-02-12
18:12:16 UTC (rev 8029)
@@ -0,0 +1,198 @@
+package gnu.crypto.hash;
+
+// ----------------------------------------------------------------------------
+// $Id: BaseHash.java,v 1.10 2005/10/06 04:24:14 rsdio Exp $
+//
+// Copyright (C) 2001, 2002, Free Software Foundation, Inc.
+//
+// This file is part of GNU Crypto.
+//
+// GNU Crypto is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GNU Crypto 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to the
+//
+// Free Software Foundation Inc.,
+// 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301
+// USA
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give
+// you permission to link this library with independent modules to
+// produce an executable, regardless of the license terms of these
+// independent modules, and to copy and distribute the resulting
+// executable under terms of your choice, provided that you also meet,
+// for each linked independent module, the terms and conditions of the
+// license of that module. An independent module is a module which is
+// not derived from or based on this library. If you modify this
+// library, you may extend this exception to your version of the
+// library, but you are not obligated to do so. If you do not wish to
+// do so, delete this exception statement from your version.
+// ----------------------------------------------------------------------------
+
+/**
+ * <p>A base abstract class to facilitate hash implementations.</p>
+ *
+ * @version $Revision: 1.10 $
+ */
+public abstract class BaseHash implements IMessageDigest {
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ /** The canonical name prefix of the hash. */
+ protected String name;
+
+ /** The hash (output) size in bytes. */
+ protected int hashSize;
+
+ /** The hash (inner) block size in bytes. */
+ protected int blockSize;
+
+ /** Number of bytes processed so far. */
+ protected long count;
+
+ /** Temporary input buffer. */
+ protected byte[] buffer;
+
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ /**
+ * <p>Trivial constructor for use by concrete subclasses.</p>
+ *
+ * @param name the canonical name prefix of this instance.
+ * @param hashSize the block size of the output in bytes.
+ * @param blockSize the block size of the internal transform.
+ */
+ protected BaseHash(String name, int hashSize, int blockSize) {
+ super();
+
+ this.name = name;
+ this.hashSize = hashSize;
+ this.blockSize = blockSize;
+ this.buffer = new byte[blockSize];
+
+ resetContext();
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ // IMessageDigest interface implementation ---------------------------------
+
+ public String name() {
+ return name;
+ }
+
+ public int hashSize() {
+ return hashSize;
+ }
+
+ public int blockSize() {
+ return blockSize;
+ }
+
+ public void update(byte b) {
+ // compute number of bytes still unhashed; ie. present in buffer
+ int i = (int)(count % blockSize);
+ count++;
+ buffer[i] = b;
+ if (i == (blockSize - 1)) {
+ transform(buffer, 0);
+ }
+ }
+
+ public void update(byte[] b) {
+ update(b, 0, b.length);
+ }
+
+ public void update(byte[] b, int offset, int len) {
+ int n = (int)(count % blockSize);
+ count += len;
+ int partLen = blockSize - n;
+ int i = 0;
+
+ if (len >= partLen) {
+ System.arraycopy(b, offset, buffer, n, partLen);
+ transform(buffer, 0);
+ for (i = partLen; i + blockSize - 1 < len; i+= blockSize) {
+ transform(b, offset + i);
+ }
+ n = 0;
+ }
+
+ if (i < len) {
+ System.arraycopy(b, offset + i, buffer, n, len - i);
+ }
+ }
+
+ public byte[] digest() {
+ byte[] tail = padBuffer(); // pad remaining bytes in buffer
+ update(tail, 0, tail.length); // last transform of a message
+ byte[] result = getResult(); // make a result out of context
+
+ reset(); // reset this instance for future re-use
+
+ return result;
+ }
+
+ public void reset() { // reset this instance for future re-use
+ count = 0L;
+ for (int i = 0; i < blockSize; ) {
+ buffer[i++] = 0;
+ }
+
+ resetContext();
+ }
+
+ // methods to be implemented by concrete subclasses ------------------------
+
+ public abstract Object clone();
+
+ public abstract boolean selfTest();
+
+ /**
+ * <p>Returns the byte array to use as padding before completing a hash
+ * operation.</p>
+ *
+ * @return the bytes to pad the remaining bytes in the buffer before
+ * completing a hash operation.
+ */
+ protected abstract byte[] padBuffer();
+
+ /**
+ * <p>Constructs the result from the contents of the current context.</p>
+ *
+ * @return the output of the completed hash operation.
+ */
+ protected abstract byte[] getResult();
+
+ /** Resets the instance for future re-use. */
+ protected abstract void resetContext();
+
+ /**
+ * <p>The block digest transformation per se.</p>
+ *
+ * @param in the <i>blockSize</i> long block, as an array of bytes to
digest.
+ * @param offset the index where the data to digest is located within the
+ * input buffer.
+ */
+ protected abstract void transform(byte[] in, int offset);
+}
Added: trunk/apps/installer/src/gnu/crypto/hash/IMessageDigest.java
===================================================================
--- trunk/apps/installer/src/gnu/crypto/hash/IMessageDigest.java
2006-02-12 17:41:47 UTC (rev 8028)
+++ trunk/apps/installer/src/gnu/crypto/hash/IMessageDigest.java
2006-02-12 18:12:16 UTC (rev 8029)
@@ -0,0 +1,141 @@
+package gnu.crypto.hash;
+
+// ----------------------------------------------------------------------------
+// $Id: IMessageDigest.java,v 1.11 2005/10/06 04:24:14 rsdio Exp $
+//
+// Copyright (C) 2001, 2002, Free Software Foundation, Inc.
+//
+// This file is part of GNU Crypto.
+//
+// GNU Crypto is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GNU Crypto 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to the
+//
+// Free Software Foundation Inc.,
+// 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301
+// USA
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give
+// you permission to link this library with independent modules to
+// produce an executable, regardless of the license terms of these
+// independent modules, and to copy and distribute the resulting
+// executable under terms of your choice, provided that you also meet,
+// for each linked independent module, the terms and conditions of the
+// license of that module. An independent module is a module which is
+// not derived from or based on this library. If you modify this
+// library, you may extend this exception to your version of the
+// library, but you are not obligated to do so. If you do not wish to
+// do so, delete this exception statement from your version.
+// ----------------------------------------------------------------------------
+
+/**
+ * <p>The basic visible methods of any hash algorithm.</p>
+ *
+ * <p>A hash (or message digest) algorithm produces its output by iterating a
+ * basic compression function on blocks of data.</p>
+ *
+ * @version $Revision: 1.11 $
+ */
+public interface IMessageDigest extends Cloneable {
+
+ // Constants
+ // -------------------------------------------------------------------------
+
+ // Methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * <p>Returns the canonical name of this algorithm.</p>
+ *
+ * @return the canonical name of this instance.
+ */
+ String name();
+
+ /**
+ * <p>Returns the output length in bytes of this message digest
algorithm.</p>
+ *
+ * @return the output length in bytes of this message digest algorithm.
+ */
+ int hashSize();
+
+ /**
+ * <p>Returns the algorithm's (inner) block size in bytes.</p>
+ *
+ * @return the algorithm's inner block size in bytes.
+ */
+ int blockSize();
+
+ /**
+ * <p>Continues a message digest operation using the input byte.</p>
+ *
+ * @param b the input byte to digest.
+ */
+ void update(byte b);
+
+ /**
+ * <p>Continues a message digest operation, by filling the buffer,
processing
+ * data in the algorithm's HASH_SIZE-bit block(s), updating the context and
+ * count, and buffering the remaining bytes in buffer for the next
+ * operation.</p>
+ *
+ * @param in the input block.
+ */
+ void update(byte[] in);
+
+ /**
+ * <p>Continues a message digest operation, by filling the buffer,
processing
+ * data in the algorithm's HASH_SIZE-bit block(s), updating the context and
+ * count, and buffering the remaining bytes in buffer for the next
+ * operation.</p>
+ *
+ * @param in the input block.
+ * @param offset start of meaningful bytes in input block.
+ * @param length number of bytes, in input block, to consider.
+ */
+ void update(byte[] in, int offset, int length);
+
+ /**
+ * <p>Completes the message digest by performing final operations such as
+ * padding and resetting the instance.</p>
+ *
+ * @return the array of bytes representing the hash value.
+ */
+ byte[] digest();
+
+ /**
+ * <p>Resets the current context of this instance clearing any eventually
cached
+ * intermediary values.</p>
+ */
+ void reset();
+
+ /**
+ * <p>A basic test. Ensures that the digest of a pre-determined message is
equal
+ * to a known pre-computed value.</p>
+ *
+ * @return <tt>true</tt> if the implementation passes a basic self-test.
+ * Returns <tt>false</tt> otherwise.
+ */
+ boolean selfTest();
+
+ /**
+ * <p>Returns a clone copy of this instance.</p>
+ *
+ * @return a clone copy of this instance.
+ */
+ Object clone();
+}
Added: trunk/apps/installer/src/gnu/crypto/hash/Sha160.java
===================================================================
--- trunk/apps/installer/src/gnu/crypto/hash/Sha160.java 2006-02-12
17:41:47 UTC (rev 8028)
+++ trunk/apps/installer/src/gnu/crypto/hash/Sha160.java 2006-02-12
18:12:16 UTC (rev 8029)
@@ -0,0 +1,295 @@
+package gnu.crypto.hash;
+
+// ----------------------------------------------------------------------------
+// $Id: Sha160.java,v 1.10 2005/10/06 04:24:14 rsdio Exp $
+//
+// Copyright (C) 2001, 2002, Free Software Foundation, Inc.
+//
+// This file is part of GNU Crypto.
+//
+// GNU Crypto is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GNU Crypto 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to the
+//
+// Free Software Foundation Inc.,
+// 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301
+// USA
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give
+// you permission to link this library with independent modules to
+// produce an executable, regardless of the license terms of these
+// independent modules, and to copy and distribute the resulting
+// executable under terms of your choice, provided that you also meet,
+// for each linked independent module, the terms and conditions of the
+// license of that module. An independent module is a module which is
+// not derived from or based on this library. If you modify this
+// library, you may extend this exception to your version of the
+// library, but you are not obligated to do so. If you do not wish to
+// do so, delete this exception statement from your version.
+// ----------------------------------------------------------------------------
+
+import gnu.crypto.Registry;
+import gnu.crypto.util.Util;
+
+/**
+ * <p>The Secure Hash Algorithm (SHA-1) is required for use with the Digital
+ * Signature Algorithm (DSA) as specified in the Digital Signature Standard
+ * (DSS) and whenever a secure hash algorithm is required for federal
+ * applications. For a message of length less than 2^64 bits, the SHA-1
+ * produces a 160-bit condensed representation of the message called a message
+ * digest. The message digest is used during generation of a signature for the
+ * message. The SHA-1 is also used to compute a message digest for the received
+ * version of the message during the process of verifying the signature. Any
+ * change to the message in transit will, with very high probability, result in
+ * a different message digest, and the signature will fail to verify.</p>
+ *
+ * <p>The SHA-1 is designed to have the following properties: it is
+ * computationally infeasible to find a message which corresponds to a given
+ * message digest, or to find two different messages which produce the same
+ * message digest.</p>
+ *
+ * <p>References:</p>
+ *
+ * <ol>
+ * <li><a href="http://www.itl.nist.gov/fipspubs/fip180-1.htm">SECURE HASH
+ * STANDARD</a><br>
+ * Federal Information, Processing Standards Publication 180-1, 1995 April
17.
+ * </li>
+ * </ol>
+ *
+ * @version $Revision: 1.10 $
+ */
+public class Sha160 extends BaseHash {
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ private static final int BLOCK_SIZE = 64; // inner block size in bytes
+
+ private static final String DIGEST0 =
"A9993E364706816ABA3E25717850C26C9CD0D89D";
+
+ private static final int[] w = new int[80];
+
+ /** caches the result of the correctness test, once executed. */
+ private static Boolean valid;
+
+ /** 160-bit interim result. */
+ private int h0, h1, h2, h3, h4;
+
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ /** Trivial 0-arguments constructor. */
+ public Sha160() {
+ super(Registry.SHA160_HASH, 20, BLOCK_SIZE);
+ }
+
+ /**
+ * <p>Private constructor for cloning purposes.</p>
+ *
+ * @param md the instance to clone.
+ */
+ private Sha160(Sha160 md) {
+ this();
+
+ this.h0 = md.h0;
+ this.h1 = md.h1;
+ this.h2 = md.h2;
+ this.h3 = md.h3;
+ this.h4 = md.h4;
+ this.count = md.count;
+ this.buffer = (byte[]) md.buffer.clone();
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ public static final int[]
+ G(int hh0, int hh1, int hh2, int hh3, int hh4, byte[] in, int offset) {
+// int[] w = new int[80];
+// int i, T;
+// for (i = 0; i < 16; i++) {
+// w[i] = in[offset++] << 24 |
+// (in[offset++] & 0xFF) << 16 |
+// (in[offset++] & 0xFF) << 8 |
+// (in[offset++] & 0xFF);
+// }
+// for (i = 16; i < 80; i++) {
+// T = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16];
+// w[i] = T << 1 | T >>> 31;
+// }
+
+// return sha(hh0, hh1, hh2, hh3, hh4, in, offset, w);
+ return sha(hh0, hh1, hh2, hh3, hh4, in, offset);
+ }
+
+ // Instance methods
+ // -------------------------------------------------------------------------
+
+ // java.lang.Cloneable interface implementation ----------------------------
+
+ public Object clone() {
+ return new Sha160(this);
+ }
+
+ // Implementation of concrete methods in BaseHash --------------------------
+
+ protected void transform(byte[] in, int offset) {
+// int i, T;
+// for (i = 0; i < 16; i++) {
+// W[i] = in[offset++] << 24 |
+// (in[offset++] & 0xFF) << 16 |
+// (in[offset++] & 0xFF) << 8 |
+// (in[offset++] & 0xFF);
+// }
+// for (i = 16; i < 80; i++) {
+// T = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
+// W[i] = T << 1 | T >>> 31;
+// }
+
+// int[] result = sha(h0, h1, h2, h3, h4, in, offset, W);
+ int[] result = sha(h0, h1, h2, h3, h4, in, offset);
+
+ h0 = result[0];
+ h1 = result[1];
+ h2 = result[2];
+ h3 = result[3];
+ h4 = result[4];
+ }
+
+ protected byte[] padBuffer() {
+ int n = (int)(count % BLOCK_SIZE);
+ int padding = (n < 56) ? (56 - n) : (120 - n);
+ byte[] result = new byte[padding + 8];
+
+ // padding is always binary 1 followed by binary 0s
+ result[0] = (byte) 0x80;
+
+ // save number of bits, casting the long to an array of 8 bytes
+ long bits = count << 3;
+ result[padding++] = (byte)(bits >>> 56);
+ result[padding++] = (byte)(bits >>> 48);
+ result[padding++] = (byte)(bits >>> 40);
+ result[padding++] = (byte)(bits >>> 32);
+ result[padding++] = (byte)(bits >>> 24);
+ result[padding++] = (byte)(bits >>> 16);
+ result[padding++] = (byte)(bits >>> 8);
+ result[padding ] = (byte) bits;
+
+ return result;
+ }
+
+ protected byte[] getResult() {
+ byte[] result = new byte[] {
+ (byte)(h0 >>> 24), (byte)(h0 >>> 16), (byte)(h0 >>> 8), (byte) h0,
+ (byte)(h1 >>> 24), (byte)(h1 >>> 16), (byte)(h1 >>> 8), (byte) h1,
+ (byte)(h2 >>> 24), (byte)(h2 >>> 16), (byte)(h2 >>> 8), (byte) h2,
+ (byte)(h3 >>> 24), (byte)(h3 >>> 16), (byte)(h3 >>> 8), (byte) h3,
+ (byte)(h4 >>> 24), (byte)(h4 >>> 16), (byte)(h4 >>> 8), (byte) h4
+ };
+
+ return result;
+ }
+
+ protected void resetContext() {
+ // magic SHA-1/RIPEMD160 initialisation constants
+ h0 = 0x67452301;
+ h1 = 0xEFCDAB89;
+ h2 = 0x98BADCFE;
+ h3 = 0x10325476;
+ h4 = 0xC3D2E1F0;
+ }
+
+ public boolean selfTest() {
+ if (valid == null) {
+ Sha160 md = new Sha160();
+ md.update((byte) 0x61); // a
+ md.update((byte) 0x62); // b
+ md.update((byte) 0x63); // c
+ String result = Util.toString(md.digest());
+ valid = new Boolean(DIGEST0.equals(result));
+ }
+ return valid.booleanValue();
+ }
+
+ // SHA specific methods ----------------------------------------------------
+
+ private static final synchronized int[]
+// sha(int hh0, int hh1, int hh2, int hh3, int hh4, byte[] in, int offset,
int[] w) {
+ sha(int hh0, int hh1, int hh2, int hh3, int hh4, byte[] in, int offset) {
+ int A = hh0;
+ int B = hh1;
+ int C = hh2;
+ int D = hh3;
+ int E = hh4;
+ int r, T;
+
+ for (r = 0; r < 16; r++) {
+ w[r] = in[offset++] << 24 |
+ (in[offset++] & 0xFF) << 16 |
+ (in[offset++] & 0xFF) << 8 |
+ (in[offset++] & 0xFF);
+ }
+ for (r = 16; r < 80; r++) {
+ T = w[r-3] ^ w[r-8] ^ w[r-14] ^ w[r-16];
+ w[r] = T << 1 | T >>> 31;
+ }
+
+ // rounds 0-19
+ for (r = 0; r < 20; r++) {
+ T = (A << 5 | A >>> 27) + ((B & C) | (~B & D)) + E + w[r] +
0x5A827999;
+ E = D;
+ D = C;
+ C = B << 30 | B >>> 2;
+ B = A;
+ A = T;
+ }
+
+ // rounds 20-39
+ for (r = 20; r < 40; r++) {
+ T = (A << 5 | A >>> 27) + (B ^ C ^ D) + E + w[r] + 0x6ED9EBA1;
+ E = D;
+ D = C;
+ C = B << 30 | B >>> 2;
+ B = A;
+ A = T;
+ }
+
+ // rounds 40-59
+ for (r = 40; r < 60; r++) {
+ T = (A << 5 | A >>> 27) + (B & C | B & D | C & D) + E + w[r] +
0x8F1BBCDC;
+ E = D;
+ D = C;
+ C = B << 30 | B >>> 2;
+ B = A;
+ A = T;
+ }
+
+ // rounds 60-79
+ for (r = 60; r < 80; r++) {
+ T = (A << 5 | A >>> 27) + (B ^ C ^ D) + E + w[r] + 0xCA62C1D6;
+ E = D;
+ D = C;
+ C = B << 30 | B >>> 2;
+ B = A;
+ A = T;
+ }
+
+ return new int[] {hh0+A, hh1+B, hh2+C, hh3+D, hh4+E};
+ }
+}
Added: trunk/apps/installer/src/gnu/crypto/util/Util.java
===================================================================
--- trunk/apps/installer/src/gnu/crypto/util/Util.java 2006-02-12 17:41:47 UTC
(rev 8028)
+++ trunk/apps/installer/src/gnu/crypto/util/Util.java 2006-02-12 18:12:16 UTC
(rev 8029)
@@ -0,0 +1,612 @@
+package gnu.crypto.util;
+
+// ----------------------------------------------------------------------------
+// $Id: Util.java,v 1.11 2005/10/06 04:24:19 rsdio Exp $
+//
+// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
+//
+// This file is part of GNU Crypto.
+//
+// GNU Crypto is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// GNU Crypto 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to the
+//
+// Free Software Foundation Inc.,
+// 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301
+// USA
+//
+// Linking this library statically or dynamically with other modules is
+// making a combined work based on this library. Thus, the terms and
+// conditions of the GNU General Public License cover the whole
+// combination.
+//
+// As a special exception, the copyright holders of this library give
+// you permission to link this library with independent modules to
+// produce an executable, regardless of the license terms of these
+// independent modules, and to copy and distribute the resulting
+// executable under terms of your choice, provided that you also meet,
+// for each linked independent module, the terms and conditions of the
+// license of that module. An independent module is a module which is
+// not derived from or based on this library. If you modify this
+// library, you may extend this exception to your version of the
+// library, but you are not obligated to do so. If you do not wish to
+// do so, delete this exception statement from your version.
+// ----------------------------------------------------------------------------
+
+import java.math.BigInteger;
+
+/**
+ * <p>A collection of utility methods used throughout this project.</p>
+ *
+ * @version $Revision: 1.11 $
+ */
+public class Util {
+
+ // Constants and variables
+ // -------------------------------------------------------------------------
+
+ // Hex charset
+ private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();
+
+ // Base-64 charset
+ private static final String BASE64_CHARS =
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
+ private static final char[] BASE64_CHARSET = BASE64_CHARS.toCharArray();
+
+ // Constructor(s)
+ // -------------------------------------------------------------------------
+
+ /** Trivial constructor to enforce Singleton pattern. */
+ private Util() {
+ super();
+ }
+
+ // Class methods
+ // -------------------------------------------------------------------------
+
+ /**
+ * <p>Returns a string of hexadecimal digits from a byte array. Each byte is
+ * converted to 2 hex symbols; zero(es) included.</p>
+ *
+ * <p>This method calls the method with same name and three arguments
as:</p>
+ *
+ * <pre>
+ * toString(ba, 0, ba.length);
+ * </pre>
+ *
+ * @param ba the byte array to convert.
+ * @return a string of hexadecimal characters (two for each byte)
+ * representing the designated input byte array.
+ */
+ public static String toString(byte[] ba) {
+ return toString(ba, 0, ba.length);
+ }
+
+ /**
+ * <p>Returns a string of hexadecimal digits from a byte array, starting at
+ * <code>offset</code> and consisting of <code>length</code> bytes. Each
byte
+ * is converted to 2 hex symbols; zero(es) included.</p>
+ *
+ * @param ba the byte array to convert.
+ * @param offset the index from which to start considering the bytes to
+ * convert.
+ * @param length the count of bytes, starting from the designated offset to
+ * convert.
+ * @return a string of hexadecimal characters (two for each byte)
+ * representing the designated input byte sub-array.
+ */
+ public static final String toString(byte[] ba, int offset, int length) {
+ char[] buf = new char[length * 2];
+ for (int i = 0, j = 0, k; i < length; ) {
+ k = ba[offset + i++];
+ buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
+ buf[j++] = HEX_DIGITS[ k & 0x0F];
+ }
+ return new String(buf);
+ }
+
+ /**
+ * <p>Returns a string of hexadecimal digits from a byte array. Each byte is
+ * converted to 2 hex symbols; zero(es) included. The argument is
+ * treated as a large little-endian integer and is returned as a
+ * large big-endian integer.</p>
+ *
+ * <p>This method calls the method with same name and three arguments
as:</p>
+ *
+ * <pre>
+ * toReversedString(ba, 0, ba.length);
+ * </pre>
+ *
+ * @param ba the byte array to convert.
+ * @return a string of hexadecimal characters (two for each byte)
+ * representing the designated input byte array.
+ */
+ public static String toReversedString(byte[] ba) {
+ return toReversedString(ba, 0, ba.length);
+ }
+
+ /**
+ * <p>Returns a string of hexadecimal digits from a byte array, starting at
+ * <code>offset</code> and consisting of <code>length</code> bytes. Each
byte
+ * is converted to 2 hex symbols; zero(es) included.</p>
+ *
+ * <p>The byte array is treated as a large little-endian integer, and
+ * is returned as a large big-endian integer.</p>
+ *
+ * @param ba the byte array to convert.
+ * @param offset the index from which to start considering the bytes to
+ * convert.
+ * @param length the count of bytes, starting from the designated offset to
+ * convert.
+ * @return a string of hexadecimal characters (two for each byte)
+ * representing the designated input byte sub-array.
+ */
+ public static final String
+ toReversedString(byte[] ba, int offset, int length) {
+ char[] buf = new char[length * 2];
+ for (int i = offset+length-1, j = 0, k; i >= offset; ) {
+ k = ba[offset + i--];
+ buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
+ buf[j++] = HEX_DIGITS[ k & 0x0F];
+ }
+ return new String(buf);
+ }
+
+ /**
+ * <p>Returns a byte array from a string of hexadecimal digits.</p>
+ *
+ * @param s a string of hexadecimal ASCII characters
+ * @return the decoded byte array from the input hexadecimal string.
+ */
+ public static byte[] toBytesFromString(String s) {
+ int limit = s.length();
+ byte[] result = new byte[((limit + 1) / 2)];
+ int i = 0, j = 0;
+ if ((limit % 2) == 1) {
+ result[j++] = (byte) fromDigit(s.charAt(i++));
+ }
+ while (i < limit) {
+ result[j ] = (byte) (fromDigit(s.charAt(i++)) << 4);
+ result[j++] |= (byte) fromDigit(s.charAt(i++));
+ }
+ return result;
+ }
+
+ /**
+ * <p>Returns a byte array from a string of hexadecimal digits, interpreting
+ * them as a large big-endian integer and returning it as a large
+ * little-endian integer.</p>
+ *
+ * @param s a string of hexadecimal ASCII characters
+ * @return the decoded byte array from the input hexadecimal string.
+ */
+ public static byte[] toReversedBytesFromString(String s) {
+ int limit = s.length();
+ byte[] result = new byte[((limit + 1) / 2)];
+ int i = 0;
+ if ((limit % 2) == 1) {
+ result[i++] = (byte) fromDigit(s.charAt(--limit));
+ }
+ while (limit > 0) {
+ result[i ] = (byte) fromDigit(s.charAt(--limit));
+ result[i++] |= (byte) (fromDigit(s.charAt(--limit)) << 4);
+ }
+ return result;
+ }
+
+ /**
+ * <p>Returns a number from <code>0</code> to <code>15</code> corresponding
+ * to the designated hexadecimal digit.</p>
+ *
+ * @param c a hexadecimal ASCII symbol.
+ */
+ public static int fromDigit(char c) {
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ } else if (c >= 'A' && c <= 'F') {
+ return c - 'A' + 10;
+ } else if (c >= 'a' && c <= 'f') {
+ return c - 'a' + 10;
+ } else
+ throw new IllegalArgumentException("Invalid hexadecimal digit: " + c);
+ }
+
+ /**
+ * <p>Returns a string of 8 hexadecimal digits (most significant digit
first)
+ * corresponding to the unsigned integer <code>n</code>.</p>
+ *
+ * @param n the unsigned integer to convert.
+ * @return a hexadecimal string 8-character long.
+ */
+ public static String toString(int n) {
+ char[] buf = new char[8];
+ for (int i = 7; i >= 0; i--) {
+ buf[i] = HEX_DIGITS[n & 0x0F];
+ n >>>= 4;
+ }
+ return new String(buf);
+ }
+
+ /**
+ * <p>Returns a string of hexadecimal digits from an integer array. Each int
+ * is converted to 4 hex symbols.</p>
+ */
+ public static String toString(int[] ia) {
+ int length = ia.length;
+ char[] buf = new char[length * 8];
+ for (int i = 0, j = 0, k; i < length; i++) {
+ k = ia[i];
+ buf[j++] = HEX_DIGITS[(k >>> 28) & 0x0F];
+ buf[j++] = HEX_DIGITS[(k >>> 24) & 0x0F];
+ buf[j++] = HEX_DIGITS[(k >>> 20) & 0x0F];
+ buf[j++] = HEX_DIGITS[(k >>> 16) & 0x0F];
+ buf[j++] = HEX_DIGITS[(k >>> 12) & 0x0F];
+ buf[j++] = HEX_DIGITS[(k >>> 8) & 0x0F];
+ buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
+ buf[j++] = HEX_DIGITS[ k & 0x0F];
+ }
+ return new String(buf);
+ }
+
+ /**
+ * <p>Returns a string of 16 hexadecimal digits (most significant digit
first)
+ * corresponding to the unsigned long <code>n</code>.</p>
+ *
+ * @param n the unsigned long to convert.
+ * @return a hexadecimal string 16-character long.
+ */
+ public static String toString(long n) {
+ char[] b = new char[16];
+ for (int i = 15; i >= 0; i--) {
+ b[i] = HEX_DIGITS[(int)(n & 0x0FL)];
+ n >>>= 4;
+ }
+ return new String(b);
+ }
+
+ /**
+ * <p>Similar to the <code>toString()</code> method except that the Unicode
+ * escape character is inserted before every pair of bytes. Useful to
+ * externalise byte arrays that will be constructed later from such strings;
+ * eg. s-box values.</p>
+ *
+ * @throws ArrayIndexOutOfBoundsException if the length is odd.
+ */
+ public static String toUnicodeString(byte[] ba) {
+ return toUnicodeString(ba, 0, ba.length);
+ }
+
+ /**
+ * <p>Similar to the <code>toString()</code> method except that the Unicode
+ * escape character is inserted before every pair of bytes. Useful to
+ * externalise byte arrays that will be constructed later from such strings;
+ * eg. s-box values.</p>
+ *
+ * @throws ArrayIndexOutOfBoundsException if the length is odd.
+ */
+ public static final String
+ toUnicodeString(byte[] ba, int offset, int length) {
+ StringBuffer sb = new StringBuffer();
+ int i = 0;
+ int j = 0;
+ int k;
+ sb.append('\n').append("\"");
+ while (i < length) {
+ sb.append("\\u");
+
+ k = ba[offset + i++];
+ sb.append(HEX_DIGITS[(k >>> 4) & 0x0F]);
+ sb.append(HEX_DIGITS[ k & 0x0F]);
+
+ k = ba[offset + i++];
+ sb.append(HEX_DIGITS[(k >>> 4) & 0x0F]);
+ sb.append(HEX_DIGITS[ k & 0x0F]);
+
+ if ((++j % 8) == 0) {
+ sb.append("\"+").append('\n').append("\"");
+ }
+ }
+ sb.append("\"").append('\n');
+ return sb.toString();
+ }
+
+ /**
+ * <p>Similar to the <code>toString()</code> method except that the Unicode
+ * escape character is inserted before every pair of bytes. Useful to
+ * externalise integer arrays that will be constructed later from such
+ * strings; eg. s-box values.</p>
+ *
+ * @throws ArrayIndexOutOfBoundsException if the length is not a multiple
of 4.
+ */
+ public static String toUnicodeString(int[] ia) {
+ StringBuffer sb = new StringBuffer();
+ int i = 0;
+ int j = 0;
+ int k;
+ sb.append('\n').append("\"");
+ while (i < ia.length) {
+ k = ia[i++];
+ sb.append("\\u");
+ sb.append(HEX_DIGITS[(k >>> 28) & 0x0F]);
+ sb.append(HEX_DIGITS[(k >>> 24) & 0x0F]);
+ sb.append(HEX_DIGITS[(k >>> 20) & 0x0F]);
+ sb.append(HEX_DIGITS[(k >>> 16) & 0x0F]);
+ sb.append("\\u");
+ sb.append(HEX_DIGITS[(k >>> 12) & 0x0F]);
+ sb.append(HEX_DIGITS[(k >>> 8) & 0x0F]);
+ sb.append(HEX_DIGITS[(k >>> 4) & 0x0F]);
+ sb.append(HEX_DIGITS[ k & 0x0F]);
+
+ if ((++j % 4) == 0) {
+ sb.append("\"+").append('\n').append("\"");
+ }
+ }
+ sb.append("\"").append('\n');
+ return sb.toString();
+ }
+
+ public static byte[] toBytesFromUnicode(String s) {
+ int limit = s.length() * 2;
+ byte[] result = new byte[limit];
+ char c;
+ for (int i = 0; i < limit; i++) {
+ c = s.charAt(i >>> 1);
+ result[i] = (byte)(((i & 1) == 0) ? c >>> 8 : c);
+ }
+ return result;
+ }
+
+ /**
+ * <p>Dumps a byte array as a string, in a format that is easy to read for
+ * debugging. The string <code>m</code> is prepended to the start of each
+ * line.</p>
+ *
+ * <p>If <code>offset</code> and <code>length</code> are omitted, the whole
+ * array is used. If <code>m</code> is omitted, nothing is prepended to each
+ * line.</p>
+ *
+ * @param data the byte array to be dumped.
+ * @param offset the offset within <i>data</i> to start from.
+ * @param length the number of bytes to dump.
+ * @param m a string to be prepended to each line.
+ * @return a string containing the result.
+ */
+ public static String dumpString(byte[] data, int offset, int length, String
m) {
+ if (data == null) {
+ return m + "null\n";
+ }
+ StringBuffer sb = new StringBuffer(length * 3);
+ if (length > 32) {
+ sb.append(m).append("Hexadecimal dump of ").append(length).append("
bytes...\n");
+ }
+ // each line will list 32 bytes in 4 groups of 8 each
+ int end = offset + length;
+ String s;
+ int l = Integer.toString(length).length();
+ if (l < 4) {
+ l = 4;
+ }
+ for ( ; offset < end; offset += 32) {
+ if (length > 32) {
+ s = " " + offset;
+ sb.append(m).append(s.substring(s.length()-l)).append(": ");
+ }
+ int i = 0;
+ for ( ; i < 32 && offset + i + 7 < end; i += 8) {
+ sb.append(toString(data, offset + i, 8)).append(' ');
+ }
+ if (i < 32) {
+ for ( ; i < 32 && offset + i < end; i++) {
+ sb.append(byteToString(data[offset + i]));
+ }
+ }
+ sb.append('\n');
+ }
+ return sb.toString();
+ }
+
+ public static String dumpString(byte[] data) {
+ return (data == null) ? "null\n" : dumpString(data, 0, data.length, "");
+ }
+
+ public static String dumpString(byte[] data, String m) {
+ return (data == null) ? "null\n" : dumpString(data, 0, data.length, m);
+ }
+
+ public static String dumpString(byte[] data, int offset, int length) {
+ return dumpString(data, offset, length, "");
+ }
+
+ /**
+ * <p>Returns a string of 2 hexadecimal digits (most significant digit
first)
+ * corresponding to the lowest 8 bits of <code>n</code>.</p>
+ *
+ * @param n the byte value to convert.
+ * @return a string of 2 hex characters representing the input.
+ */
+ public static String byteToString(int n) {
+ char[] buf = { HEX_DIGITS[(n >>> 4) & 0x0F], HEX_DIGITS[n & 0x0F] };
+ return new String(buf);
+ }
+
+ /**
+ * <p>Converts a designated byte array to a Base-64 representation, with the
+ * exceptions that (a) leading 0-byte(s) are ignored, and (b) the character
+ * '.' (dot) shall be used instead of "+' (plus).</p>
+ *
+ * <p>Used by SASL password file manipulation primitives.</p>
+ *
+ * @param buffer an arbitrary sequence of bytes to represent in Base-64.
+ * @return unpadded (without the '=' character(s)) Base-64 representation of
+ * the input.
+ */
+ public static final String toBase64(byte[] buffer) {
+ int len = buffer.length, pos = len % 3;
+ byte b0 = 0, b1 = 0, b2 = 0;
+ switch (pos) {
+ case 1:
+ b2 = buffer[0];
+ break;
+ case 2:
+ b1 = buffer[0];
+ b2 = buffer[1];
+ break;
+ }
+ StringBuffer sb = new StringBuffer();
+ int c;
+ boolean notleading = false;
+ do {
+ c = (b0 & 0xFC) >>> 2;
+ if (notleading || c != 0) {
+ sb.append(BASE64_CHARSET[c]);
+ notleading = true;
+ }
+ c = ((b0 & 0x03) << 4) | ((b1 & 0xF0) >>> 4);
+ if (notleading || c != 0) {
+ sb.append(BASE64_CHARSET[c]);
+ notleading = true;
+ }
+ c = ((b1 & 0x0F) << 2) | ((b2 & 0xC0) >>> 6);
+ if (notleading || c != 0) {
+ sb.append(BASE64_CHARSET[c]);
+ notleading = true;
+ }
+ c = b2 & 0x3F;
+ if (notleading || c != 0) {
+ sb.append(BASE64_CHARSET[c]);
+ notleading = true;
+ }
+ if (pos >= len) {
+ break;
+ } else {
+ try {
+ b0 = buffer[pos++];
+ b1 = buffer[pos++];
+ b2 = buffer[pos++];
+ } catch (ArrayIndexOutOfBoundsException x) {
+ break;
+ }
+ }
+ } while (true);
+
+ if (notleading) {
+ return sb.toString();
+ }
+ return "0";
+ }
+
+ /**
+ * <p>The inverse function of the above.</p>
+ *
+ * <p>Converts a string representing the encoding of some bytes in Base-64
+ * to their original form.</p>
+ *
+ * @param str the Base-64 encoded representation of some byte(s).
+ * @return the bytes represented by the <code>str</code>.
+ * @throws NumberFormatException if <code>str</code> is <code>null</code>,
or
+ * <code>str</code> contains an illegal Base-64 character.
+ * @see #toBase64(byte[])
+ */
+ public static final byte[] fromBase64(String str) {
+ int len = str.length();
+ if (len == 0) {
+ throw new NumberFormatException("Empty string");
+ }
+ byte[] a = new byte[len + 1];
+ int i, j;
+ for (i = 0; i < len; i++) {
+ try {
+ a[i] = (byte) BASE64_CHARS.indexOf(str.charAt(i));
+ } catch (ArrayIndexOutOfBoundsException x) {
+ throw new NumberFormatException("Illegal character at #"+i);
+ }
+ }
+ i = len - 1;
+ j = len;
+ try {
+ while (true) {
+ a[j] = a[i];
+ if (--i < 0) {
+ break;
+ }
+ a[j] |= (a[i] & 0x03) << 6;
+ j--;
+ a[j] = (byte)((a[i] & 0x3C) >>> 2);
+ if (--i < 0) {
+ break;
+ }
+ a[j] |= (a[i] & 0x0F) << 4;
+ j--;
+ a[j] = (byte)((a[i] & 0x30) >>> 4);
+ if (--i < 0) {
+ break;
+ }
+ a[j] |= (a[i] << 2);
+ j--;
+ a[j] = 0;
+ if (--i < 0) {
+ break;
+ }
+ }
+ } catch (Exception ignored) {
+ }
+
+ try { // ignore leading 0-bytes
+ while(a[j] == 0) {
+ j++;
+ }
+ } catch (Exception x) {
+ return new byte[1]; // one 0-byte
+ }
+ byte[] result = new byte[len - j + 1];
+ System.arraycopy(a, j, result, 0, len - j + 1);
+ return result;
+ }
+
+ // BigInteger utilities ----------------------------------------------------
+
+ /**
+ * <p>Treats the input as the MSB representation of a number, and discards
+ * leading zero elements. For efficiency, the input is simply returned if no
+ * leading zeroes are found.</p>
+ *
+ * @param n the {@link BigInteger} to trim.
+ * @return the byte array representation of the designated {@link
BigInteger}
+ * with no leading 0-bytes.
+ */
+ public static final byte[] trim(BigInteger n) {
+ byte[] in = n.toByteArray();
+ if (in.length == 0 || in[0] != 0) {
+ return in;
+ }
+ int len = in.length;
+ int i = 1;
+ while (in[i] == 0 && i < len) {
+ ++i;
+ }
+ byte[] result = new byte[len - i];
+ System.arraycopy(in, i, result, 0, len - i);
+ return result;
+ }
+
+ /**
+ * <p>Returns a hexadecimal dump of the trimmed bytes of a {@link
BigInteger}.
+ * </p>
+ *
+ * @param x the {@link BigInteger} to display.
+ * @return the string representation of the designated {@link BigInteger}.
+ */
+ public static final String dump(BigInteger x) {
+ return dumpString(trim(x));
+ }
+}