diff options
author | mark <mark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-10 21:46:48 +0000 |
---|---|---|
committer | mark <mark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-10 21:46:48 +0000 |
commit | ce57ab760f69de6db452def7ffbf5b114a2d8694 (patch) | |
tree | ea38c56431c5d4528fb54254c3f8e50f517bede3 /libjava/classpath/gnu/java/security | |
parent | 50996fe55769882de3f410896032c887f0ff0d04 (diff) | |
download | ppe42-gcc-ce57ab760f69de6db452def7ffbf5b114a2d8694.tar.gz ppe42-gcc-ce57ab760f69de6db452def7ffbf5b114a2d8694.zip |
Imported GNU Classpath 0.90
* scripts/makemake.tcl: Set gnu/java/awt/peer/swing to ignore.
* gnu/classpath/jdwp/VMFrame.java (SIZE): New constant.
* java/lang/VMCompiler.java: Use gnu.java.security.hash.MD5.
* java/lang/Math.java: New override file.
* java/lang/Character.java: Merged from Classpath.
(start, end): Now 'int's.
(canonicalName): New field.
(CANONICAL_NAME, NO_SPACES_NAME, CONSTANT_NAME): New constants.
(UnicodeBlock): Added argument.
(of): New overload.
(forName): New method.
Updated unicode blocks.
(sets): Updated.
* sources.am: Regenerated.
* Makefile.in: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111942 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava/classpath/gnu/java/security')
138 files changed, 23074 insertions, 3272 deletions
diff --git a/libjava/classpath/gnu/java/security/Properties.java b/libjava/classpath/gnu/java/security/Properties.java new file mode 100644 index 00000000000..813888c20a8 --- /dev/null +++ b/libjava/classpath/gnu/java/security/Properties.java @@ -0,0 +1,374 @@ +/* Properties.java -- run-time configuration properties. + Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.HashMap; +import java.util.PropertyPermission; + +/** + * <p>A global object containing build-specific properties that affect the + * behaviour of the generated binaries from this library.</p> + */ +public final class Properties +{ + + // Debugging methods and variables + // ------------------------------------------------------------------------- + + private static final String NAME = "Properties"; + + private static final boolean DEBUG = false; + + // private static final int debuglevel = 9; + private static final PrintWriter err = new PrintWriter(System.out, true); + + private static void debug(final String s) + { + err.println(">>> " + NAME + ": " + s); + } + + // Constants and variables + // ------------------------------------------------------------------------- + + public static final String VERSION = "gnu.crypto.version"; + + public static final String PROPERTIES_FILE = "gnu.crypto.properties.file"; + + public static final String REPRODUCIBLE_PRNG = "gnu.crypto.with.reproducible.prng"; + + public static final String CHECK_WEAK_KEYS = "gnu.crypto.with.check.for.weak.keys"; + + public static final String DO_RSA_BLINDING = "gnu.crypto.with.rsa.blinding"; + + private static final String TRUE = Boolean.TRUE.toString(); + + private static final String FALSE = Boolean.FALSE.toString(); + + private static final HashMap props = new HashMap(); + + private static Properties singleton = null; + + private boolean reproducible = false; + + private boolean checkForWeakKeys = true; + + private boolean doRSABlinding = true; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial constructor to enforce Singleton pattern. */ + private Properties() + { + super(); + init(); + } + + // Class methods + // ------------------------------------------------------------------------- + + /** + * <p>Returns the string representation of the library global configuration + * property with the designated <code>key</code>.</p> + * + * @param key the case-insensitive, non-null and non-empty name of a + * configuration property. + * @return the string representation of the designated property, or + * <code>null</code> if such property is not yet set, or <code>key</code> is + * empty. + */ + public static final synchronized String getProperty(String key) + { + if (key == null) + return null; + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new PropertyPermission(key, "read")); + key = key.trim().toLowerCase(); + if ("".equals(key)) + return null; + return (String) props.get(key); + } + + /** + * <p>Sets the value of a designated library global configuration property, + * to a string representation of what should be a legal value.</p> + * + * @param key the case-insensitive, non-null and non-empty name of a + * configuration property. + * @param value the non-null, non-empty string representation of a legal + * value of the configuration property named by <code>key</code>. + */ + public static final synchronized void setProperty(String key, String value) + { + if (key == null || value == null) + return; + key = key.trim().toLowerCase(); + if ("".equals(key)) + return; + if (key.equals(VERSION)) + return; + value = value.trim(); + if ("".equals(value)) + return; + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new PropertyPermission(key, "write")); + if (key.equals(REPRODUCIBLE_PRNG) + && (value.equalsIgnoreCase(TRUE) || value.equalsIgnoreCase(FALSE))) + setReproducible(Boolean.valueOf(value).booleanValue()); + else if (key.equals(CHECK_WEAK_KEYS) + && (value.equalsIgnoreCase(TRUE) || value.equalsIgnoreCase(FALSE))) + setCheckForWeakKeys(Boolean.valueOf(value).booleanValue()); + else if (key.equals(DO_RSA_BLINDING) + && (value.equalsIgnoreCase(TRUE) || value.equalsIgnoreCase(FALSE))) + setDoRSABlinding(Boolean.valueOf(value).booleanValue()); + else + props.put(key, value); + } + + /** + * <p>A convenience method that returns, as a boolean, the library global + * configuration property indicating if the default Pseudo Random Number + * Generator produces, or not, the same bit stream when instantiated.</p> + * + * @return <code>true</code> if the default PRNG produces the same bit stream + * with every VM instance. Returns <code>false</code> if the default PRNG is + * seeded with the time of day of its first invocation. + */ + public static final synchronized boolean isReproducible() + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new PropertyPermission(REPRODUCIBLE_PRNG, "read")); + return instance().reproducible; + } + + /** + * <p>A convenience method that returns, as a boolean, the library global + * configuration property indicating if the implementations of symmetric + * key block ciphers check, or not, for possible/potential weak and semi-weak + * keys that may be produced in the course of generating round encryption + * and/or decryption keys.</p> + * + * @return <code>true</code> if the cipher implementations check for weak and + * semi-weak keys. Returns <code>false</code> if the cipher implementations + * do not check for weak or semi-weak keys. + */ + public static final synchronized boolean checkForWeakKeys() + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new PropertyPermission(CHECK_WEAK_KEYS, "read")); + return instance().checkForWeakKeys; + } + + /** + * <p>A convenience method that returns, as a boolean, the library global + * configuration property indicating if RSA decryption (RSADP primitive), + * does, or not, blinding against timing attacks.</p> + * + * @return <code>true</code> if the RSA decryption primitive includes a + * blinding operation. Returns <code>false</code> if the RSA decryption + * primitive does not include the additional blinding operation. + */ + public static final synchronized boolean doRSABlinding() + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new PropertyPermission(DO_RSA_BLINDING, "read")); + return instance().doRSABlinding; + } + + /** + * <p>A convenience method to set the global property for reproducibility of + * the default PRNG bit stream output.</p> + * + * @param value if <code>true</code> then the default PRNG bit stream output + * is the same with every invocation of the VM. + */ + public static final synchronized void setReproducible(final boolean value) + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new PropertyPermission(REPRODUCIBLE_PRNG, "write")); + instance().reproducible = value; + props.put(REPRODUCIBLE_PRNG, String.valueOf(value)); + } + + /** + * <p>A convenience method to set the global property for checking for weak + * and semi-weak cipher keys.</p> + * + * @param value if <code>true</code> then the cipher implementations will + * invoke additional checks for weak and semi-weak key values that may get + * generated. + */ + public static final synchronized void setCheckForWeakKeys(final boolean value) + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new PropertyPermission(CHECK_WEAK_KEYS, "write")); + instance().checkForWeakKeys = value; + props.put(CHECK_WEAK_KEYS, String.valueOf(value)); + } + + /** + * <p>A convenience method to set the global property fo adding a blinding + * operation when executing the RSA decryption primitive.</p> + * + * @param value if <code>true</code> then the code for performing the RSA + * decryption primitive will include a blinding operation. + */ + public static final synchronized void setDoRSABlinding(final boolean value) + { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) + sm.checkPermission(new PropertyPermission(DO_RSA_BLINDING, "write")); + instance().doRSABlinding = value; + props.put(DO_RSA_BLINDING, String.valueOf(value)); + } + + private static final synchronized Properties instance() + { + if (singleton == null) + singleton = new Properties(); + return singleton; + } + + // Instance methods + // ------------------------------------------------------------------------- + private void init() + { + // default values + props.put(REPRODUCIBLE_PRNG, (reproducible ? "true" : "false")); + props.put(CHECK_WEAK_KEYS, (checkForWeakKeys ? "true" : "false")); + props.put(DO_RSA_BLINDING, (doRSABlinding ? "true" : "false")); + + // 1. allow site-wide override by reading a properties file + String propFile = null; + try + { + propFile = (String) AccessController.doPrivileged(new PrivilegedAction() + { + public Object run() + { + return System.getProperty(PROPERTIES_FILE); + } + }); + } + catch (SecurityException se) + { + if (DEBUG) + debug("Reading property " + PROPERTIES_FILE + + " not allowed. Ignored."); + } + if (propFile != null) + { + try + { + final java.util.Properties temp = new java.util.Properties(); + final FileInputStream fin = new FileInputStream(propFile); + temp.load(fin); + temp.list(System.out); + props.putAll(temp); + } + catch (IOException ioe) + { + if (DEBUG) + debug("IO error reading " + propFile + ": " + ioe.getMessage()); + } + catch (SecurityException se) + { + if (DEBUG) + debug("Security error reading " + propFile + ": " + + se.getMessage()); + } + } + + // 2. allow vm-specific override by allowing -D options in launcher + handleBooleanProperty(REPRODUCIBLE_PRNG); + handleBooleanProperty(CHECK_WEAK_KEYS); + handleBooleanProperty(DO_RSA_BLINDING); + + // re-sync the 'known' properties + reproducible = new Boolean((String) props.get(REPRODUCIBLE_PRNG)).booleanValue(); + checkForWeakKeys = new Boolean((String) props.get(CHECK_WEAK_KEYS)).booleanValue(); + doRSABlinding = new Boolean((String) props.get(DO_RSA_BLINDING)).booleanValue(); + + // This does not change. + props.put(VERSION, Registry.VERSION_STRING); + } + + private void handleBooleanProperty(final String name) + { + String s = null; + try + { + s = System.getProperty(name); + } + catch (SecurityException x) + { + if (DEBUG) + debug("SecurityManager forbids reading system properties. Ignored"); + } + if (s != null) + { + s = s.trim().toLowerCase(); + // we have to test for explicit "true" or "false". anything else may + // hide valid value set previously + if (s.equals(TRUE) || s.equals(FALSE)) + { + if (DEBUG) + debug("Setting " + name + " to '" + s + "'"); + props.put(name, s); + } + else + { + if (DEBUG) + debug("Invalid value for -D" + name + ": " + s + ". Ignored"); + } + } + } +} diff --git a/libjava/classpath/gnu/java/security/Registry.java b/libjava/classpath/gnu/java/security/Registry.java new file mode 100644 index 00000000000..efb54e71470 --- /dev/null +++ b/libjava/classpath/gnu/java/security/Registry.java @@ -0,0 +1,455 @@ +/* Registry.java -- + Copyright (C) 2001, 2002, 2003, 2004, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security; + +/** + * A placeholder for <i>names</i> and <i>literals</i> used throughout this + * library. + */ +public interface Registry +{ + + // Constants + // ------------------------------------------------------------------------- + + /** The name of our Providers. */ + String GNU_SECURITY = "GNU"; + String GNU_CRYPTO = "GNU-CRYPTO"; + String GNU_SASL = "GNU-SASL"; + + /** Our version number. */ + String VERSION_STRING = "2.1.0"; + + // 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_SIG_PREFIX = "rsa-"; + + String RSA_PSS_ENCODING = "pss"; + + String RSA_PSS_SIG = RSA_SIG_PREFIX + RSA_PSS_ENCODING; + + String RSA_PKCS1_V1_5_ENCODING = "pkcs1-v1.5"; + + String RSA_PKCS1_V1_5_SIG = RSA_SIG_PREFIX + RSA_PKCS1_V1_5_ENCODING; + + /** 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 .......... + // fully-qualified names of the supported codecs + String RAW_ENCODING = "gnu.crypto.raw.format"; + String X509_ENCODING = "gnu.crypto.x509.format"; + String PKCS8_ENCODING = "gnu.crypto.pkcs8.format"; + String ASN1_ENCODING = "gnu.crypto.asn1.format"; + + // short names of the same. used by JCE adapters + String RAW_ENCODING_SHORT_NAME = "RAW"; + String X509_ENCODING_SORT_NAME = "X.509"; + String PKCS8_ENCODING_SHORT_NAME = "PKCS#8"; + String ASN1_ENCODING_SHORT_NAME = "ASN.1"; + + // unique identifiers of the same + int RAW_ENCODING_ID = 1; + int X509_ENCODING_ID = 2; + int PKCS8_ENCODING_ID = 3; + int ASN1_ENCODING_ID = 4; + + // OID strings used in encoding/decoding keys + String DSA_OID_STRING = "1.2.840.10040.4.1"; + String RSA_OID_STRING = "1.2.840.113549.1.1.1"; + String DH_OID_STRING = "1.2.840.10046.2.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_RSA_PKCS1V1_5_SIGNATURE = new byte[] { 0x47, RAW_ENCODING_ID, + 0x52, 0x54 }; + + 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 + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/der/DERValue.java b/libjava/classpath/gnu/java/security/der/DERValue.java index 9a597d724cc..d98ce78ec55 100644 --- a/libjava/classpath/gnu/java/security/der/DERValue.java +++ b/libjava/classpath/gnu/java/security/der/DERValue.java @@ -38,6 +38,8 @@ exception statement from your version. */ package gnu.java.security.der; +import gnu.java.security.x509.Util; + import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -108,7 +110,9 @@ public class DERValue implements DER } catch (IOException ioe) { - encoded = new byte[0]; + IllegalArgumentException iae = new IllegalArgumentException (); + iae.initCause (ioe); + throw iae; } } return length; @@ -138,7 +142,9 @@ public class DERValue implements DER } catch (IOException ioe) { - encoded = new byte[0]; + IllegalArgumentException iae = new IllegalArgumentException (); + iae.initCause (ioe); + throw iae; } } return (byte[]) encoded.clone(); @@ -156,7 +162,9 @@ public class DERValue implements DER } catch (IOException ioe) { - encoded = new byte[0]; + IllegalArgumentException iae = new IllegalArgumentException (); + iae.initCause (ioe); + throw iae; } } return encoded.length; @@ -164,7 +172,18 @@ public class DERValue implements DER public String toString() { - return "DERValue [ tag=" + tag + ", class=" + tagClass + ", constructed=" - + constructed + ", value=" + value + " ]"; + String start = "DERValue ( ["; + if (tagClass == DER.UNIVERSAL) + start = start + "UNIVERSAL "; + else if (tagClass == DER.PRIVATE) + start = start + "PRIVATE "; + else if (tagClass == DER.APPLICATION) + start = start + "APPLICATION "; + start = start + tag + "] constructed=" + constructed + ", value="; + if (constructed) + start = start + "\n" + Util.hexDump(getEncoded(), "\t"); + else + start = start + value; + return start + " )"; } } diff --git a/libjava/classpath/gnu/java/security/der/DERWriter.java b/libjava/classpath/gnu/java/security/der/DERWriter.java index 78524fc949f..0c26336053c 100644 --- a/libjava/classpath/gnu/java/security/der/DERWriter.java +++ b/libjava/classpath/gnu/java/security/der/DERWriter.java @@ -84,6 +84,12 @@ public class DERWriter implements DER public static int write(OutputStream out, DERValue object) throws IOException { + if (DER.CONSTRUCTED_VALUE.equals (object.getValue ())) + { + out.write (object.getEncoded ()); + return object.getLength (); + } + out.write(object.getExternalTag()); Object value = object.getValue(); if (value == null) @@ -216,10 +222,10 @@ public class DERWriter implements DER throws IOException { byte[] buf = bs.getShiftedByteArray(); - out.write(buf.length + 1); + writeLength(out, buf.length + 1); out.write(bs.getIgnoredBits()); out.write(buf); - return buf.length; + return buf.length + 1; } private static int writeString(OutputStream out, int tag, String str) diff --git a/libjava/classpath/gnu/java/security/hash/BaseHash.java b/libjava/classpath/gnu/java/security/hash/BaseHash.java new file mode 100644 index 00000000000..720b835392a --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/BaseHash.java @@ -0,0 +1,206 @@ +/* BaseHash.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +/** + * <p>A base abstract class to facilitate hash implementations.</p> + */ +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); +} diff --git a/libjava/classpath/gnu/java/security/hash/HashFactory.java b/libjava/classpath/gnu/java/security/hash/HashFactory.java new file mode 100644 index 00000000000..e5209212365 --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/HashFactory.java @@ -0,0 +1,178 @@ +/* HashFactory.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +import gnu.java.security.Registry; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * <p>A <i>Factory</i> to instantiate message digest algorithm instances.</p> + */ +public class HashFactory +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial constructor to enforce <i>Singleton</i> pattern. */ + private HashFactory() + { + super(); + } + + // Class methods + // ------------------------------------------------------------------------- + + /** + * <p>Return an instance of a hash algorithm given its name.</p> + * + * @param name the name of the hash algorithm. + * @return an instance of the hash algorithm, or null if none found. + * @exception InternalError if the implementation does not pass its self- + * test. + */ + public static IMessageDigest getInstance(String name) + { + if (name == null) + { + return null; + } + + name = name.trim(); + IMessageDigest result = null; + if (name.equalsIgnoreCase(Registry.WHIRLPOOL_HASH)) + { + result = new Whirlpool(); + } + else if (name.equalsIgnoreCase(Registry.RIPEMD128_HASH) + || name.equalsIgnoreCase(Registry.RIPEMD_128_HASH)) + { + result = new RipeMD128(); + } + else if (name.equalsIgnoreCase(Registry.RIPEMD160_HASH) + || name.equalsIgnoreCase(Registry.RIPEMD_160_HASH)) + { + result = new RipeMD160(); + } + else if (name.equalsIgnoreCase(Registry.SHA160_HASH) + || name.equalsIgnoreCase(Registry.SHA_1_HASH) + || name.equalsIgnoreCase(Registry.SHA1_HASH) + || name.equalsIgnoreCase(Registry.SHA_HASH)) + { + result = new Sha160(); + } + else if (name.equalsIgnoreCase(Registry.SHA256_HASH)) + { + result = new Sha256(); + } + else if (name.equalsIgnoreCase(Registry.SHA384_HASH)) + { + result = new Sha384(); + } + else if (name.equalsIgnoreCase(Registry.SHA512_HASH)) + { + result = new Sha512(); + } + else if (name.equalsIgnoreCase(Registry.TIGER_HASH)) + { + result = new Tiger(); + } + else if (name.equalsIgnoreCase(Registry.HAVAL_HASH)) + { + result = new Haval(); + } + else if (name.equalsIgnoreCase(Registry.MD5_HASH)) + { + result = new MD5(); + } + else if (name.equalsIgnoreCase(Registry.MD4_HASH)) + { + result = new MD4(); + } + else if (name.equalsIgnoreCase(Registry.MD2_HASH)) + { + result = new MD2(); + } + else if (name.equalsIgnoreCase(Registry.HAVAL_HASH)) + { + result = new Haval(); + } + + if (result != null && !result.selfTest()) + { + throw new InternalError(result.name()); + } + + return result; + } + + /** + * <p>Returns a {@link Set} of names of hash algorithms supported by this + * <i>Factory</i>.</p> + * + * @return a {@link Set} of hash names (Strings). + */ + public static final Set getNames() + { + HashSet hs = new HashSet(); + hs.add(Registry.WHIRLPOOL_HASH); + hs.add(Registry.RIPEMD128_HASH); + hs.add(Registry.RIPEMD160_HASH); + hs.add(Registry.SHA160_HASH); + hs.add(Registry.SHA256_HASH); + hs.add(Registry.SHA384_HASH); + hs.add(Registry.SHA512_HASH); + hs.add(Registry.TIGER_HASH); + hs.add(Registry.HAVAL_HASH); + hs.add(Registry.MD5_HASH); + hs.add(Registry.MD4_HASH); + hs.add(Registry.MD2_HASH); + + return Collections.unmodifiableSet(hs); + } + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/hash/Haval.java b/libjava/classpath/gnu/java/security/hash/Haval.java new file mode 100644 index 00000000000..f9f3282f278 --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/Haval.java @@ -0,0 +1,759 @@ +/* Haval.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +import gnu.java.security.Registry; +import gnu.java.security.util.Util; + +/** + * <p>The <i>HAVAL</i> message-digest algorithm is a variable output length, + * with variable number of rounds. By default, this implementation allows + * <i>HAVAL</i> to be used as a drop-in replacement for <i>MD5</i>.</p> + * + * <p>References:</p> + * + * <ol> + * <li>HAVAL - A One-Way Hashing Algorithm with Variable Length of Output<br> + * Advances in Cryptology - AUSCRYPT'92, Lecture Notes in Computer Science,<br> + * Springer-Verlag, 1993; <br> + * Y. Zheng, J. Pieprzyk and J. Seberry.</li> + * </ol> + */ +public class Haval extends BaseHash +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + public static final int HAVAL_VERSION = 1; + + public static final int HAVAL_128_BIT = 16; + + public static final int HAVAL_160_BIT = 20; + + public static final int HAVAL_192_BIT = 24; + + public static final int HAVAL_224_BIT = 28; + + public static final int HAVAL_256_BIT = 32; + + public static final int HAVAL_3_ROUND = 3; + + public static final int HAVAL_4_ROUND = 4; + + public static final int HAVAL_5_ROUND = 5; + + private static final int BLOCK_SIZE = 128; // inner block size in bytes + + private static final String DIGEST0 = "C68F39913F901F3DDF44C707357A7D70"; + + /** caches the result of the correctness test, once executed. */ + private static Boolean valid; + + /** + * Number of HAVAL rounds. Allowed values are integers in the range <code>3 + * .. 5</code>. The default is <code>3</code>. + */ + private int rounds = HAVAL_3_ROUND; + + /** 128-bit interim result. */ + private int h0, h1, h2, h3, h4, h5, h6, h7; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * <p>Calls the constructor with two argument using {@link #HAVAL_128_BIT} as + * the value for the output size (i.e. <code>128</code> bits, and + * {@link #HAVAL_3_ROUND} for the value of number of rounds.</p> + */ + public Haval() + { + this(HAVAL_128_BIT, HAVAL_3_ROUND); + } + + /** + * <p>Calls the constructor with two arguments using the designated output + * size, and {@link #HAVAL_3_ROUND} for the value of number of rounds.</p> + * + * @param size the output size in bytes of this instance. + * @throws IllegalArgumentException if the designated output size is invalid. + * @see #HAVAL_128_BIT + * @see #HAVAL_160_BIT + * @see #HAVAL_192_BIT + * @see #HAVAL_224_BIT + * @see #HAVAL_256_BIT + */ + public Haval(int size) + { + this(size, HAVAL_3_ROUND); + } + + /** + * <p>Constructs a <code>Haval</code> instance with the designated output + * size (in bytes). Valid output <code>size</code> values are <code>16</code>, + * <code>20</code>, <code>24</code>, <code>28</code> and <code>32</code>. + * Valid values for <code>rounds</code> are in the range <code>3..5</code> + * inclusive.</p> + * + * @param size the output size in bytes of this instance. + * @param rounds the number of rounds to apply when transforming data. + * @throws IllegalArgumentException if the designated output size is invalid, + * or if the number of rounds is invalid. + * @see #HAVAL_128_BIT + * @see #HAVAL_160_BIT + * @see #HAVAL_192_BIT + * @see #HAVAL_224_BIT + * @see #HAVAL_256_BIT + * @see #HAVAL_3_ROUND + * @see #HAVAL_4_ROUND + * @see #HAVAL_5_ROUND + */ + public Haval(int size, int rounds) + { + super(Registry.HAVAL_HASH, size, BLOCK_SIZE); + + if (size != HAVAL_128_BIT && size != HAVAL_160_BIT && size != HAVAL_192_BIT + && size != HAVAL_224_BIT && size != HAVAL_256_BIT) + { + throw new IllegalArgumentException("Invalid HAVAL output size"); + } + + if (rounds != HAVAL_3_ROUND && rounds != HAVAL_4_ROUND + && rounds != HAVAL_5_ROUND) + { + throw new IllegalArgumentException("Invalid HAVAL number of rounds"); + } + + this.rounds = rounds; + } + + /** + * <p>Private constructor for cloning purposes.</p> + * + * @param md the instance to clone. + */ + private Haval(Haval md) + { + this(md.hashSize, md.rounds); + + this.h0 = md.h0; + this.h1 = md.h1; + this.h2 = md.h2; + this.h3 = md.h3; + this.h4 = md.h4; + this.h5 = md.h5; + this.h6 = md.h6; + this.h7 = md.h7; + this.count = md.count; + this.buffer = (byte[]) md.buffer.clone(); + } + + // Constructor(s) + // ------------------------------------------------------------------------- + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // java.lang.Cloneable interface implementation ---------------------------- + + public Object clone() + { + return new Haval(this); + } + + // Implementation of concrete methods in BaseHash -------------------------- + + protected synchronized void transform(byte[] in, int i) + { + int X0 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X1 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X2 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X3 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X4 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X5 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X6 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X7 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X8 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X9 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X10 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X11 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X12 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X13 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X14 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X15 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X16 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X17 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X18 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X19 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X20 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X21 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X22 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X23 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X24 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X25 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X26 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X27 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X28 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X29 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X30 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + int X31 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | (in[i++] & 0xFF) << 24; + + int t0 = h0, t1 = h1, t2 = h2, t3 = h3, t4 = h4, t5 = h5, t6 = h6, t7 = h7; + + // Pass 1 + t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X0); + t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X1); + t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X2); + t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X3); + t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X4); + t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X5); + t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X6); + t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X7); + + t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X8); + t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X9); + t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X10); + t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X11); + t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X12); + t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X13); + t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X14); + t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X15); + + t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X16); + t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X17); + t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X18); + t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X19); + t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X20); + t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X21); + t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X22); + t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X23); + + t7 = FF1(t7, t6, t5, t4, t3, t2, t1, t0, X24); + t6 = FF1(t6, t5, t4, t3, t2, t1, t0, t7, X25); + t5 = FF1(t5, t4, t3, t2, t1, t0, t7, t6, X26); + t4 = FF1(t4, t3, t2, t1, t0, t7, t6, t5, X27); + t3 = FF1(t3, t2, t1, t0, t7, t6, t5, t4, X28); + t2 = FF1(t2, t1, t0, t7, t6, t5, t4, t3, X29); + t1 = FF1(t1, t0, t7, t6, t5, t4, t3, t2, X30); + t0 = FF1(t0, t7, t6, t5, t4, t3, t2, t1, X31); + + // Pass 2 + t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X5, 0x452821E6); + t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X14, 0x38D01377); + t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X26, 0xBE5466CF); + t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X18, 0x34E90C6C); + t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X11, 0xC0AC29B7); + t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X28, 0xC97C50DD); + t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X7, 0x3F84D5B5); + t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X16, 0xB5470917); + + t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X0, 0x9216D5D9); + t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X23, 0x8979FB1B); + t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X20, 0xD1310BA6); + t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X22, 0x98DFB5AC); + t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X1, 0x2FFD72DB); + t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X10, 0xD01ADFB7); + t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X4, 0xB8E1AFED); + t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X8, 0x6A267E96); + + t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X30, 0xBA7C9045); + t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X3, 0xF12C7F99); + t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X21, 0x24A19947); + t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X9, 0xB3916CF7); + t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X17, 0x0801F2E2); + t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X24, 0x858EFC16); + t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X29, 0x636920D8); + t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X6, 0x71574E69); + + t7 = FF2(t7, t6, t5, t4, t3, t2, t1, t0, X19, 0xA458FEA3); + t6 = FF2(t6, t5, t4, t3, t2, t1, t0, t7, X12, 0xF4933D7E); + t5 = FF2(t5, t4, t3, t2, t1, t0, t7, t6, X15, 0x0D95748F); + t4 = FF2(t4, t3, t2, t1, t0, t7, t6, t5, X13, 0x728EB658); + t3 = FF2(t3, t2, t1, t0, t7, t6, t5, t4, X2, 0x718BCD58); + t2 = FF2(t2, t1, t0, t7, t6, t5, t4, t3, X25, 0x82154AEE); + t1 = FF2(t1, t0, t7, t6, t5, t4, t3, t2, X31, 0x7B54A41D); + t0 = FF2(t0, t7, t6, t5, t4, t3, t2, t1, X27, 0xC25A59B5); + + // Pass 3 + t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X19, 0x9C30D539); + t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X9, 0x2AF26013); + t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X4, 0xC5D1B023); + t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X20, 0x286085F0); + t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X28, 0xCA417918); + t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X17, 0xB8DB38EF); + t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X8, 0x8E79DCB0); + t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X22, 0x603A180E); + + t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X29, 0x6C9E0E8B); + t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X14, 0xB01E8A3E); + t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X25, 0xD71577C1); + t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X12, 0xBD314B27); + t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X24, 0x78AF2FDA); + t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X30, 0x55605C60); + t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X16, 0xE65525F3); + t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X26, 0xAA55AB94); + + t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X31, 0x57489862); + t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X15, 0x63E81440); + t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X7, 0x55CA396A); + t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X3, 0x2AAB10B6); + t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X1, 0xB4CC5C34); + t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X0, 0x1141E8CE); + t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X18, 0xA15486AF); + t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X27, 0x7C72E993); + + t7 = FF3(t7, t6, t5, t4, t3, t2, t1, t0, X13, 0xB3EE1411); + t6 = FF3(t6, t5, t4, t3, t2, t1, t0, t7, X6, 0x636FBC2A); + t5 = FF3(t5, t4, t3, t2, t1, t0, t7, t6, X21, 0x2BA9C55D); + t4 = FF3(t4, t3, t2, t1, t0, t7, t6, t5, X10, 0x741831F6); + t3 = FF3(t3, t2, t1, t0, t7, t6, t5, t4, X23, 0xCE5C3E16); + t2 = FF3(t2, t1, t0, t7, t6, t5, t4, t3, X11, 0x9B87931E); + t1 = FF3(t1, t0, t7, t6, t5, t4, t3, t2, X5, 0xAFD6BA33); + t0 = FF3(t0, t7, t6, t5, t4, t3, t2, t1, X2, 0x6C24CF5C); + + if (rounds >= 4) + { + t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X24, 0x7A325381); + t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X4, 0x28958677); + t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X0, 0x3B8F4898); + t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X14, 0x6B4BB9AF); + t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X2, 0xC4BFE81B); + t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X7, 0x66282193); + t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X28, 0x61D809CC); + t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X23, 0xFB21A991); + t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X26, 0x487CAC60); + t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X6, 0x5DEC8032); + t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X30, 0xEF845D5D); + t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X20, 0xE98575B1); + t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X18, 0xDC262302); + t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X25, 0xEB651B88); + t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X19, 0x23893E81); + t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X3, 0xD396ACC5); + + t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X22, 0x0F6D6FF3); + t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X11, 0x83F44239); + t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X31, 0x2E0B4482); + t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X21, 0xA4842004); + t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X8, 0x69C8F04A); + t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X27, 0x9E1F9B5E); + t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X12, 0x21C66842); + t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X9, 0xF6E96C9A); + t7 = FF4(t7, t6, t5, t4, t3, t2, t1, t0, X1, 0x670C9C61); + t6 = FF4(t6, t5, t4, t3, t2, t1, t0, t7, X29, 0xABD388F0); + t5 = FF4(t5, t4, t3, t2, t1, t0, t7, t6, X5, 0x6A51A0D2); + t4 = FF4(t4, t3, t2, t1, t0, t7, t6, t5, X15, 0xD8542F68); + t3 = FF4(t3, t2, t1, t0, t7, t6, t5, t4, X17, 0x960FA728); + t2 = FF4(t2, t1, t0, t7, t6, t5, t4, t3, X10, 0xAB5133A3); + t1 = FF4(t1, t0, t7, t6, t5, t4, t3, t2, X16, 0x6EEF0B6C); + t0 = FF4(t0, t7, t6, t5, t4, t3, t2, t1, X13, 0x137A3BE4); + + if (rounds == 5) + { + t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X27, 0xBA3BF050); + t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X3, 0x7EFB2A98); + t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X21, 0xA1F1651D); + t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X26, 0x39AF0176); + t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X17, 0x66CA593E); + t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X11, 0x82430E88); + t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X20, 0x8CEE8619); + t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X29, 0x456F9FB4); + + t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X19, 0x7D84A5C3); + t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X0, 0x3B8B5EBE); + t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X12, 0xE06F75D8); + t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X7, 0x85C12073); + t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X13, 0x401A449F); + t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X8, 0x56C16AA6); + t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X31, 0x4ED3AA62); + t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X10, 0x363F7706); + + t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X5, 0x1BFEDF72); + t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X9, 0x429B023D); + t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X14, 0x37D0D724); + t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X30, 0xD00A1248); + t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X18, 0xDB0FEAD3); + t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X6, 0x49F1C09B); + t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X28, 0x075372C9); + t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X24, 0x80991B7B); + + t7 = FF5(t7, t6, t5, t4, t3, t2, t1, t0, X2, 0x25D479D8); + t6 = FF5(t6, t5, t4, t3, t2, t1, t0, t7, X23, 0xF6E8DEF7); + t5 = FF5(t5, t4, t3, t2, t1, t0, t7, t6, X16, 0xE3FE501A); + t4 = FF5(t4, t3, t2, t1, t0, t7, t6, t5, X22, 0xB6794C3B); + t3 = FF5(t3, t2, t1, t0, t7, t6, t5, t4, X4, 0x976CE0BD); + t2 = FF5(t2, t1, t0, t7, t6, t5, t4, t3, X1, 0x04C006BA); + t1 = FF5(t1, t0, t7, t6, t5, t4, t3, t2, X25, 0xC1A94FB6); + t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X15, 0x409F60C4); + } + } + + h7 += t7; + h6 += t6; + h5 += t5; + h4 += t4; + h3 += t3; + h2 += t2; + h1 += t1; + h0 += t0; + } + + protected byte[] padBuffer() + { + // pad out to 118 mod 128. other 10 bytes have special use. + int n = (int) (count % BLOCK_SIZE); + int padding = (n < 118) ? (118 - n) : (246 - n); + byte[] result = new byte[padding + 10]; + result[0] = (byte) 0x01; + + // save the version number (LSB 3), the number of rounds (3 bits in the + // middle), the fingerprint length (MSB 2 bits and next byte) and the + // number of bits in the unpadded message. + int bl = hashSize * 8; + result[padding++] = (byte) (((bl & 0x03) << 6) | ((rounds & 0x07) << 3) | (HAVAL_VERSION & 0x07)); + result[padding++] = (byte) (bl >>> 2); + + // save number of bits, casting the long to an array of 8 bytes + long bits = count << 3; + result[padding++] = (byte) bits; + result[padding++] = (byte) (bits >>> 8); + result[padding++] = (byte) (bits >>> 16); + result[padding++] = (byte) (bits >>> 24); + result[padding++] = (byte) (bits >>> 32); + result[padding++] = (byte) (bits >>> 40); + result[padding++] = (byte) (bits >>> 48); + result[padding] = (byte) (bits >>> 56); + + return result; + } + + protected byte[] getResult() + { + tailorDigestBits(); // tailor context for the designated output size + // cast enough top context values into an array of hashSize bytes + byte[] result = new byte[hashSize]; + if (hashSize >= HAVAL_256_BIT) + { + result[31] = (byte) (h7 >>> 24); + result[30] = (byte) (h7 >>> 16); + result[29] = (byte) (h7 >>> 8); + result[28] = (byte) h7; + } + if (hashSize >= HAVAL_224_BIT) + { + result[27] = (byte) (h6 >>> 24); + result[26] = (byte) (h6 >>> 16); + result[25] = (byte) (h6 >>> 8); + result[24] = (byte) h6; + } + if (hashSize >= HAVAL_192_BIT) + { + result[23] = (byte) (h5 >>> 24); + result[22] = (byte) (h5 >>> 16); + result[21] = (byte) (h5 >>> 8); + result[20] = (byte) h5; + } + if (hashSize >= HAVAL_160_BIT) + { + result[19] = (byte) (h4 >>> 24); + result[18] = (byte) (h4 >>> 16); + result[17] = (byte) (h4 >>> 8); + result[16] = (byte) h4; + } + result[15] = (byte) (h3 >>> 24); + result[14] = (byte) (h3 >>> 16); + result[13] = (byte) (h3 >>> 8); + result[12] = (byte) h3; + result[11] = (byte) (h2 >>> 24); + result[10] = (byte) (h2 >>> 16); + result[9] = (byte) (h2 >>> 8); + result[8] = (byte) h2; + result[7] = (byte) (h1 >>> 24); + result[6] = (byte) (h1 >>> 16); + result[5] = (byte) (h1 >>> 8); + result[4] = (byte) h1; + result[3] = (byte) (h0 >>> 24); + result[2] = (byte) (h0 >>> 16); + result[1] = (byte) (h0 >>> 8); + result[0] = (byte) h0; + + return result; + } + + protected void resetContext() + { + h0 = 0x243F6A88; + h1 = 0x85A308D3; + h2 = 0x13198A2E; + h3 = 0x03707344; + h4 = 0xA4093822; + h5 = 0x299F31D0; + h6 = 0x082EFA98; + h7 = 0xEC4E6C89; + } + + public boolean selfTest() + { + if (valid == null) + { + valid = new Boolean(DIGEST0.equals(Util.toString(new Haval().digest()))); + } + return valid.booleanValue(); + } + + // helper methods ---------------------------------------------------------- + + /** Tailors the last output. */ + private void tailorDigestBits() + { + int t; + switch (hashSize) + { + case HAVAL_128_BIT: + t = (h7 & 0x000000FF) | (h6 & 0xFF000000) | (h5 & 0x00FF0000) + | (h4 & 0x0000FF00); + h0 += t >>> 8 | t << 24; + t = (h7 & 0x0000FF00) | (h6 & 0x000000FF) | (h5 & 0xFF000000) + | (h4 & 0x00FF0000); + h1 += t >>> 16 | t << 16; + t = (h7 & 0x00FF0000) | (h6 & 0x0000FF00) | (h5 & 0x000000FF) + | (h4 & 0xFF000000); + h2 += t >>> 24 | t << 8; + t = (h7 & 0xFF000000) | (h6 & 0x00FF0000) | (h5 & 0x0000FF00) + | (h4 & 0x000000FF); + h3 += t; + break; + case HAVAL_160_BIT: + t = (h7 & 0x3F) | (h6 & (0x7F << 25)) | (h5 & (0x3F << 19)); + h0 += t >>> 19 | t << 13; + t = (h7 & (0x3F << 6)) | (h6 & 0x3F) | (h5 & (0x7F << 25)); + h1 += t >>> 25 | t << 7; + t = (h7 & (0x7F << 12)) | (h6 & (0x3F << 6)) | (h5 & 0x3F); + h2 += t; + t = (h7 & (0x3F << 19)) | (h6 & (0x7F << 12)) | (h5 & (0x3F << 6)); + h3 += (t >>> 6); + t = (h7 & (0x7F << 25)) | (h6 & (0x3F << 19)) | (h5 & (0x7F << 12)); + h4 += (t >>> 12); + break; + case HAVAL_192_BIT: + t = (h7 & 0x1F) | (h6 & (0x3F << 26)); + h0 += t >>> 26 | t << 6; + t = (h7 & (0x1F << 5)) | (h6 & 0x1F); + h1 += t; + t = (h7 & (0x3F << 10)) | (h6 & (0x1F << 5)); + h2 += (t >>> 5); + t = (h7 & (0x1F << 16)) | (h6 & (0x3F << 10)); + h3 += (t >>> 10); + t = (h7 & (0x1F << 21)) | (h6 & (0x1F << 16)); + h4 += (t >>> 16); + t = (h7 & (0x3F << 26)) | (h6 & (0x1F << 21)); + h5 += (t >>> 21); + break; + case HAVAL_224_BIT: + h0 += ((h7 >>> 27) & 0x1F); + h1 += ((h7 >>> 22) & 0x1F); + h2 += ((h7 >>> 18) & 0x0F); + h3 += ((h7 >>> 13) & 0x1F); + h4 += ((h7 >>> 9) & 0x0F); + h5 += ((h7 >>> 4) & 0x1F); + h6 += (h7 & 0x0F); + } + } + + /** + * Permutations phi_{i,j}, i=3,4,5, j=1,...,i. + * + * rounds = 3: 6 5 4 3 2 1 0 + * | | | | | | | (replaced by) + * phi_{3,1}: 1 0 3 5 6 2 4 + * phi_{3,2}: 4 2 1 0 5 3 6 + * phi_{3,3}: 6 1 2 3 4 5 0 + * + * rounds = 4: 6 5 4 3 2 1 0 + * | | | | | | | (replaced by) + * phi_{4,1}: 2 6 1 4 5 3 0 + * phi_{4,2}: 3 5 2 0 1 6 4 + * phi_{4,3}: 1 4 3 6 0 2 5 + * phi_{4,4}: 6 4 0 5 2 1 3 + * + * rounds = 5: 6 5 4 3 2 1 0 + * | | | | | | | (replaced by) + * phi_{5,1}: 3 4 1 0 5 2 6 + * phi_{5,2}: 6 2 1 0 3 4 5 + * phi_{5,3}: 2 6 0 4 3 1 5 + * phi_{5,4}: 1 5 3 2 0 4 6 + * phi_{5,5}: 2 5 0 6 4 3 1 + */ + private int FF1(int x7, int x6, int x5, int x4, int x3, int x2, int x1, + int x0, int w) + { + int t; + switch (rounds) + { + case 3: + t = f1(x1, x0, x3, x5, x6, x2, x4); + break; + case 4: + t = f1(x2, x6, x1, x4, x5, x3, x0); + break; + default: + t = f1(x3, x4, x1, x0, x5, x2, x6); + } + return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w; + } + + private int FF2(int x7, int x6, int x5, int x4, int x3, int x2, int x1, + int x0, int w, int c) + { + int t; + switch (rounds) + { + case 3: + t = f2(x4, x2, x1, x0, x5, x3, x6); + break; + case 4: + t = f2(x3, x5, x2, x0, x1, x6, x4); + break; + default: + t = f2(x6, x2, x1, x0, x3, x4, x5); + } + return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c; + } + + private int FF3(int x7, int x6, int x5, int x4, int x3, int x2, int x1, + int x0, int w, int c) + { + int t; + switch (rounds) + { + case 3: + t = f3(x6, x1, x2, x3, x4, x5, x0); + break; + case 4: + t = f3(x1, x4, x3, x6, x0, x2, x5); + break; + default: + t = f3(x2, x6, x0, x4, x3, x1, x5); + } + return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c; + } + + private int FF4(int x7, int x6, int x5, int x4, int x3, int x2, int x1, + int x0, int w, int c) + { + int t; + switch (rounds) + { + case 4: + t = f4(x6, x4, x0, x5, x2, x1, x3); + break; + default: + t = f4(x1, x5, x3, x2, x0, x4, x6); + } + return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c; + } + + private int FF5(int x7, int x6, int x5, int x4, int x3, int x2, int x1, + int x0, int w, int c) + { + int t = f5(x2, x5, x0, x6, x4, x3, x1); + return (t >>> 7 | t << 25) + (x7 >>> 11 | x7 << 21) + w + c; + } + + private int f1(int x6, int x5, int x4, int x3, int x2, int x1, int x0) + { + return x1 & (x0 ^ x4) ^ x2 & x5 ^ x3 & x6 ^ x0; + } + + private int f2(int x6, int x5, int x4, int x3, int x2, int x1, int x0) + { + return x2 & (x1 & ~x3 ^ x4 & x5 ^ x6 ^ x0) ^ x4 & (x1 ^ x5) ^ x3 & x5 ^ x0; + } + + private int f3(int x6, int x5, int x4, int x3, int x2, int x1, int x0) + { + return x3 & (x1 & x2 ^ x6 ^ x0) ^ x1 & x4 ^ x2 & x5 ^ x0; + } + + private int f4(int x6, int x5, int x4, int x3, int x2, int x1, int x0) + { + return x4 & (x5 & ~x2 ^ x3 & ~x6 ^ x1 ^ x6 ^ x0) ^ x3 & (x1 & x2 ^ x5 ^ x6) + ^ x2 & x6 ^ x0; + } + + private int f5(int x6, int x5, int x4, int x3, int x2, int x1, int x0) + { + return x0 & (x1 & x2 & x3 ^ ~x5) ^ x1 & x4 ^ x2 & x5 ^ x3 & x6; + } +} diff --git a/libjava/classpath/gnu/java/security/hash/IMessageDigest.java b/libjava/classpath/gnu/java/security/hash/IMessageDigest.java new file mode 100644 index 00000000000..b3d7f69ca2e --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/IMessageDigest.java @@ -0,0 +1,135 @@ +/* IMessageDigest.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +/** + * <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> + */ +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(); +} diff --git a/libjava/classpath/gnu/java/security/hash/MD2.java b/libjava/classpath/gnu/java/security/hash/MD2.java new file mode 100644 index 00000000000..41e876983bd --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/MD2.java @@ -0,0 +1,301 @@ +/* MD2.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +import gnu.java.security.Registry; +import gnu.java.security.util.Util; + +/** + * <p>An implementation of the MD2 message digest algorithm.</p> + * + * <p>MD2 is not widely used. Unless it is needed for compatibility with + * existing systems, it is not recommended for use in new applications.</p> + * + * <p>References:</p> + * + * <ol> + * <li>The <a href="http://www.ietf.org/rfc/rfc1319.txt">MD2</a> + * Message-Digest Algorithm.<br> + * B. Kaliski.</li> + * <li>The <a href="http://www.rfc-editor.org/errata.html">RFC ERRATA PAGE</a> + * under section RFC 1319.</li> + * </ol> + */ +public class MD2 extends BaseHash +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** An MD2 message digest is always 128-bits long, or 16 bytes. */ + private static final int DIGEST_LENGTH = 16; + + /** The MD2 algorithm operates on 128-bit blocks, or 16 bytes. */ + private static final int BLOCK_LENGTH = 16; + + /** 256 byte "random" permutation of the digits of pi. */ + private static final byte[] PI = { 41, 46, 67, -55, -94, -40, 124, 1, 61, 54, + 84, -95, -20, -16, 6, 19, 98, -89, 5, -13, + -64, -57, 115, -116, -104, -109, 43, -39, + -68, 76, -126, -54, 30, -101, 87, 60, -3, + -44, -32, 22, 103, 66, 111, 24, -118, 23, + -27, 18, -66, 78, -60, -42, -38, -98, -34, + 73, -96, -5, -11, -114, -69, 47, -18, 122, + -87, 104, 121, -111, 21, -78, 7, 63, -108, + -62, 16, -119, 11, 34, 95, 33, -128, 127, + 93, -102, 90, -112, 50, 39, 53, 62, -52, + -25, -65, -9, -105, 3, -1, 25, 48, -77, 72, + -91, -75, -47, -41, 94, -110, 42, -84, 86, + -86, -58, 79, -72, 56, -46, -106, -92, 125, + -74, 118, -4, 107, -30, -100, 116, 4, -15, + 69, -99, 112, 89, 100, 113, -121, 32, -122, + 91, -49, 101, -26, 45, -88, 2, 27, 96, 37, + -83, -82, -80, -71, -10, 28, 70, 97, 105, + 52, 64, 126, 15, 85, 71, -93, 35, -35, 81, + -81, 58, -61, 92, -7, -50, -70, -59, -22, + 38, 44, 83, 13, 110, -123, 40, -124, 9, + -45, -33, -51, -12, 65, -127, 77, 82, 106, + -36, 55, -56, 108, -63, -85, -6, 36, -31, + 123, 8, 12, -67, -79, 74, 120, -120, -107, + -117, -29, 99, -24, 109, -23, -53, -43, -2, + 59, 0, 29, 57, -14, -17, -73, 14, 102, 88, + -48, -28, -90, 119, 114, -8, -21, 117, 75, + 10, 49, 68, 80, -76, -113, -19, 31, 26, + -37, -103, -115, 51, -97, 17, -125, 20 }; + + /** The output of this message digest when no data has been input. */ + private static final String DIGEST0 = "8350E5A3E24C153DF2275C9F80692773"; + + /** caches the result of the correctness test, once executed. */ + private static Boolean valid; + + /** The checksum computed so far. */ + private byte[] checksum; + + /** + * Work array needed by encrypt method. First <code>BLOCK_LENGTH</code> bytes + * are also used to store the running digest. + */ + private byte[] work; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Creates a new MD2 digest ready for use. */ + public MD2() + { + super(Registry.MD2_HASH, DIGEST_LENGTH, BLOCK_LENGTH); + } + + /** + * <p>Private constructor used for cloning.</p> + * + * @param md2 the instance to clone. + */ + private MD2(MD2 md2) + { + this(); + + // superclass field + this.count = md2.count; + this.buffer = (byte[]) md2.buffer.clone(); + + // private field + this.checksum = (byte[]) md2.checksum.clone(); + this.work = (byte[]) md2.work.clone(); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // java.lang.Cloneable interface implementation ---------------------------- + + public Object clone() + { + return new MD2(this); + } + + // Implementation of abstract methods in BaseHash -------------------------- + + protected byte[] getResult() + { + byte[] result = new byte[DIGEST_LENGTH]; + + // Encrypt checksum as last block. + encryptBlock(checksum, 0); + + for (int i = 0; i < BLOCK_LENGTH; i++) + { + result[i] = work[i]; + } + + return result; + } + + protected void resetContext() + { + checksum = new byte[BLOCK_LENGTH]; + work = new byte[BLOCK_LENGTH * 3]; + } + + public boolean selfTest() + { + if (valid == null) + { + valid = new Boolean(DIGEST0.equals(Util.toString(new MD2().digest()))); + } + return valid.booleanValue(); + } + + /** + * <p>Generates an array of padding bytes. The padding is defined as + * <code>i</code> bytes of value <code>i</code>, where <code>i</code> is the + * number of bytes to fill the last block of the message to + * <code>BLOCK_LENGTH</code> bytes (or <code>BLOCK_LENGTH</code> bytes when + * the last block was completely full).</p> + * + * @return the bytes to pad the remaining bytes in the buffer before + * completing a hash operation. + */ + protected byte[] padBuffer() + { + int length = BLOCK_LENGTH - (int) (count % BLOCK_LENGTH); + if (length == 0) + { + length = BLOCK_LENGTH; + } + byte[] pad = new byte[length]; + for (int i = 0; i < length; i++) + { + pad[i] = (byte) length; + } + return pad; + } + + /** + * <p>Adds <code>BLOCK_LENGTH</code> bytes to the running digest.</p> + * + * @param in the byte array to take the <code>BLOCK_LENGTH</code> bytes from. + * @param off the offset to start from in the given byte array. + */ + protected void transform(byte[] in, int off) + { + // encryptBlock(in, off); + // updateCheckSum(in, off); + updateCheckSumAndEncryptBlock(in, off); + } + + // Private instance methods ------------------------------------------------ + + /** + * Updates the checksum with the <code>BLOCK_LENGTH</code> bytes from the + * given array starting at <code>off</code>. + */ + /* + private void updateCheckSum(byte[] in, int off) { + byte l = checksum[BLOCK_LENGTH-1]; + for (int i = 0; i < BLOCK_LENGTH; i++) { + byte b = in[off+i]; + // l = (byte)((checksum[i] & 0xFF) ^ (PI[((b & 0xFF) ^ (l & 0xFF))] & 0xFF)); + l = (byte)(checksum[i] ^ PI[(b ^ l) & 0xFF]); + checksum[i] = l; + } + } + */ + /** + * Adds a new block (<code>BLOCK_LENGTH</code> bytes) to the running digest + * from the given byte array starting from the given offset. + */ + private void encryptBlock(byte[] in, int off) + { + for (int i = 0; i < BLOCK_LENGTH; i++) + { + byte b = in[off + i]; + work[BLOCK_LENGTH + i] = b; + work[BLOCK_LENGTH * 2 + i] = (byte) (work[i] ^ b); + } + + byte t = 0; + for (int i = 0; i < 18; i++) + { + for (int j = 0; j < 3 * BLOCK_LENGTH; j++) + { + // t = (byte)((work[j] & 0xFF) ^ (PI[t & 0xFF] & 0xFF)); + t = (byte) (work[j] ^ PI[t & 0xFF]); + work[j] = t; + } + // t = (byte)((t + i) & 0xFF); + t = (byte) (t + i); + } + } + + /** + * Optimized method that combines a checksum update and encrypt of a block. + */ + private void updateCheckSumAndEncryptBlock(byte[] in, int off) + { + byte l = checksum[BLOCK_LENGTH - 1]; + for (int i = 0; i < BLOCK_LENGTH; i++) + { + byte b = in[off + i]; + work[BLOCK_LENGTH + i] = b; + // work[BLOCK_LENGTH*2+i] = (byte)((work[i] & 0xFF) ^ (b & 0xFF)); + work[BLOCK_LENGTH * 2 + i] = (byte) (work[i] ^ b); + // l = (byte)((checksum[i] & 0xFF) ^ (PI[((b & 0xFF) ^ (l & 0xFF))] & 0xFF)); + l = (byte) (checksum[i] ^ PI[(b ^ l) & 0xFF]); + checksum[i] = l; + } + + byte t = 0; + for (int i = 0; i < 18; i++) + { + for (int j = 0; j < 3 * BLOCK_LENGTH; j++) + { + // t = (byte)((work[j] & 0xFF) ^ (PI[t & 0xFF] & 0xFF)); + t = (byte) (work[j] ^ PI[t & 0xFF]); + work[j] = t; + } + // t = (byte)((t + i) & 0xFF); + t = (byte) (t + i); + } + } +} diff --git a/libjava/classpath/gnu/java/security/hash/MD4.java b/libjava/classpath/gnu/java/security/hash/MD4.java new file mode 100644 index 00000000000..54dda358b11 --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/MD4.java @@ -0,0 +1,328 @@ +/* MD4.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +import gnu.java.security.Registry; +import gnu.java.security.util.Util; + +/** + * <p>An implementation of Ron Rivest's MD4 message digest algorithm.</p> + * + * <p>MD4 was the precursor to the stronger {@link gnu.crypto.hash.MD5} + * algorithm, and while not considered cryptograpically secure itself, MD4 is + * in use in various applications. It is slightly faster than MD5.</p> + * + * <p>References:</p> + * + * <ol> + * <li>The <a href="http://www.ietf.org/rfc/rfc1320.txt">MD4</a> + * Message-Digest Algorithm.<br> + * R. Rivest.</li> + * </ol> + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public class MD4 extends BaseHash +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** An MD4 message digest is always 128-bits long, or 16 bytes. */ + private static final int DIGEST_LENGTH = 16; + + /** The MD4 algorithm operates on 512-bit blocks, or 64 bytes. */ + private static final int BLOCK_LENGTH = 64; + + private static final int A = 0x67452301; + + private static final int B = 0xefcdab89; + + private static final int C = 0x98badcfe; + + private static final int D = 0x10325476; + + /** The output of this message digest when no data has been input. */ + private static final String DIGEST0 = "31D6CFE0D16AE931B73C59D7E0C089C0"; + + /** caches the result of the correctness test, once executed. */ + private static Boolean valid; + + private int a, b, c, d; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * <p>Public constructor. Initializes the chaining variables, sets the byte + * count to <code>0</code>, and creates a new block of <code>512</code> bits. + * </p> + */ + public MD4() + { + super(Registry.MD4_HASH, DIGEST_LENGTH, BLOCK_LENGTH); + } + + /** + * <p>Trivial private constructor for cloning purposes.</p> + * + * @param that the instance to clone. + */ + private MD4(MD4 that) + { + this(); + + this.a = that.a; + this.b = that.b; + this.c = that.c; + this.d = that.d; + this.count = that.count; + this.buffer = (byte[]) that.buffer.clone(); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // java.lang.Cloneable interface implementation ---------------------------- + + public Object clone() + { + return new MD4(this); + } + + // Implementation of abstract methods in BashHash -------------------------- + + protected byte[] getResult() + { + byte[] digest = { (byte) a, (byte) (a >>> 8), (byte) (a >>> 16), + (byte) (a >>> 24), (byte) b, (byte) (b >>> 8), + (byte) (b >>> 16), (byte) (b >>> 24), (byte) c, + (byte) (c >>> 8), (byte) (c >>> 16), (byte) (c >>> 24), + (byte) d, (byte) (d >>> 8), (byte) (d >>> 16), + (byte) (d >>> 24) }; + return digest; + } + + protected void resetContext() + { + a = A; + b = B; + c = C; + d = D; + } + + public boolean selfTest() + { + if (valid == null) + { + valid = new Boolean(DIGEST0.equals(Util.toString(new MD4().digest()))); + } + return valid.booleanValue(); + } + + protected byte[] padBuffer() + { + int n = (int) (count % BLOCK_LENGTH); + int padding = (n < 56) ? (56 - n) : (120 - n); + byte[] pad = new byte[padding + 8]; + + pad[0] = (byte) 0x80; + long bits = count << 3; + pad[padding++] = (byte) bits; + pad[padding++] = (byte) (bits >>> 8); + pad[padding++] = (byte) (bits >>> 16); + pad[padding++] = (byte) (bits >>> 24); + pad[padding++] = (byte) (bits >>> 32); + pad[padding++] = (byte) (bits >>> 40); + pad[padding++] = (byte) (bits >>> 48); + pad[padding] = (byte) (bits >>> 56); + + return pad; + } + + protected void transform(byte[] in, int i) + { + int X0 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X1 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X2 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X3 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X4 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X5 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X6 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X7 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X8 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X9 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X10 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X11 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X12 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X13 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X14 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X15 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i] << 24; + + int aa, bb, cc, dd; + + aa = a; + bb = b; + cc = c; + dd = d; + + aa += ((bb & cc) | ((~bb) & dd)) + X0; + aa = aa << 3 | aa >>> -3; + dd += ((aa & bb) | ((~aa) & cc)) + X1; + dd = dd << 7 | dd >>> -7; + cc += ((dd & aa) | ((~dd) & bb)) + X2; + cc = cc << 11 | cc >>> -11; + bb += ((cc & dd) | ((~cc) & aa)) + X3; + bb = bb << 19 | bb >>> -19; + aa += ((bb & cc) | ((~bb) & dd)) + X4; + aa = aa << 3 | aa >>> -3; + dd += ((aa & bb) | ((~aa) & cc)) + X5; + dd = dd << 7 | dd >>> -7; + cc += ((dd & aa) | ((~dd) & bb)) + X6; + cc = cc << 11 | cc >>> -11; + bb += ((cc & dd) | ((~cc) & aa)) + X7; + bb = bb << 19 | bb >>> -19; + aa += ((bb & cc) | ((~bb) & dd)) + X8; + aa = aa << 3 | aa >>> -3; + dd += ((aa & bb) | ((~aa) & cc)) + X9; + dd = dd << 7 | dd >>> -7; + cc += ((dd & aa) | ((~dd) & bb)) + X10; + cc = cc << 11 | cc >>> -11; + bb += ((cc & dd) | ((~cc) & aa)) + X11; + bb = bb << 19 | bb >>> -19; + aa += ((bb & cc) | ((~bb) & dd)) + X12; + aa = aa << 3 | aa >>> -3; + dd += ((aa & bb) | ((~aa) & cc)) + X13; + dd = dd << 7 | dd >>> -7; + cc += ((dd & aa) | ((~dd) & bb)) + X14; + cc = cc << 11 | cc >>> -11; + bb += ((cc & dd) | ((~cc) & aa)) + X15; + bb = bb << 19 | bb >>> -19; + + aa += ((bb & (cc | dd)) | (cc & dd)) + X0 + 0x5a827999; + aa = aa << 3 | aa >>> -3; + dd += ((aa & (bb | cc)) | (bb & cc)) + X4 + 0x5a827999; + dd = dd << 5 | dd >>> -5; + cc += ((dd & (aa | bb)) | (aa & bb)) + X8 + 0x5a827999; + cc = cc << 9 | cc >>> -9; + bb += ((cc & (dd | aa)) | (dd & aa)) + X12 + 0x5a827999; + bb = bb << 13 | bb >>> -13; + aa += ((bb & (cc | dd)) | (cc & dd)) + X1 + 0x5a827999; + aa = aa << 3 | aa >>> -3; + dd += ((aa & (bb | cc)) | (bb & cc)) + X5 + 0x5a827999; + dd = dd << 5 | dd >>> -5; + cc += ((dd & (aa | bb)) | (aa & bb)) + X9 + 0x5a827999; + cc = cc << 9 | cc >>> -9; + bb += ((cc & (dd | aa)) | (dd & aa)) + X13 + 0x5a827999; + bb = bb << 13 | bb >>> -13; + aa += ((bb & (cc | dd)) | (cc & dd)) + X2 + 0x5a827999; + aa = aa << 3 | aa >>> -3; + dd += ((aa & (bb | cc)) | (bb & cc)) + X6 + 0x5a827999; + dd = dd << 5 | dd >>> -5; + cc += ((dd & (aa | bb)) | (aa & bb)) + X10 + 0x5a827999; + cc = cc << 9 | cc >>> -9; + bb += ((cc & (dd | aa)) | (dd & aa)) + X14 + 0x5a827999; + bb = bb << 13 | bb >>> -13; + aa += ((bb & (cc | dd)) | (cc & dd)) + X3 + 0x5a827999; + aa = aa << 3 | aa >>> -3; + dd += ((aa & (bb | cc)) | (bb & cc)) + X7 + 0x5a827999; + dd = dd << 5 | dd >>> -5; + cc += ((dd & (aa | bb)) | (aa & bb)) + X11 + 0x5a827999; + cc = cc << 9 | cc >>> -9; + bb += ((cc & (dd | aa)) | (dd & aa)) + X15 + 0x5a827999; + bb = bb << 13 | bb >>> -13; + + aa += (bb ^ cc ^ dd) + X0 + 0x6ed9eba1; + aa = aa << 3 | aa >>> -3; + dd += (aa ^ bb ^ cc) + X8 + 0x6ed9eba1; + dd = dd << 9 | dd >>> -9; + cc += (dd ^ aa ^ bb) + X4 + 0x6ed9eba1; + cc = cc << 11 | cc >>> -11; + bb += (cc ^ dd ^ aa) + X12 + 0x6ed9eba1; + bb = bb << 15 | bb >>> -15; + aa += (bb ^ cc ^ dd) + X2 + 0x6ed9eba1; + aa = aa << 3 | aa >>> -3; + dd += (aa ^ bb ^ cc) + X10 + 0x6ed9eba1; + dd = dd << 9 | dd >>> -9; + cc += (dd ^ aa ^ bb) + X6 + 0x6ed9eba1; + cc = cc << 11 | cc >>> -11; + bb += (cc ^ dd ^ aa) + X14 + 0x6ed9eba1; + bb = bb << 15 | bb >>> -15; + aa += (bb ^ cc ^ dd) + X1 + 0x6ed9eba1; + aa = aa << 3 | aa >>> -3; + dd += (aa ^ bb ^ cc) + X9 + 0x6ed9eba1; + dd = dd << 9 | dd >>> -9; + cc += (dd ^ aa ^ bb) + X5 + 0x6ed9eba1; + cc = cc << 11 | cc >>> -11; + bb += (cc ^ dd ^ aa) + X13 + 0x6ed9eba1; + bb = bb << 15 | bb >>> -15; + aa += (bb ^ cc ^ dd) + X3 + 0x6ed9eba1; + aa = aa << 3 | aa >>> -3; + dd += (aa ^ bb ^ cc) + X11 + 0x6ed9eba1; + dd = dd << 9 | dd >>> -9; + cc += (dd ^ aa ^ bb) + X7 + 0x6ed9eba1; + cc = cc << 11 | cc >>> -11; + bb += (cc ^ dd ^ aa) + X15 + 0x6ed9eba1; + bb = bb << 15 | bb >>> -15; + + a += aa; + b += bb; + c += cc; + d += dd; + } +} diff --git a/libjava/classpath/gnu/java/security/hash/MD5.java b/libjava/classpath/gnu/java/security/hash/MD5.java new file mode 100644 index 00000000000..463292984dd --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/MD5.java @@ -0,0 +1,365 @@ +/* MD5.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +import gnu.java.security.Registry; +import gnu.java.security.util.Util; + +/** + * <p>The MD5 message-digest algorithm takes as input a message of arbitrary + * length and produces as output a 128-bit "fingerprint" or "message digest" of + * the input. It is conjectured that it is computationally infeasible to + * produce two messages having the same message digest, or to produce any + * message having a given prespecified target message digest.</p> + * + * <p>References:</p> + * + * <ol> + * <li>The <a href="http://www.ietf.org/rfc/rfc1321.txt">MD5</a> Message- + * Digest Algorithm.<br> + * R. Rivest.</li> + * </ol> + */ +public class MD5 extends BaseHash +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + private static final int BLOCK_SIZE = 64; // inner block size in bytes + + private static final String DIGEST0 = "D41D8CD98F00B204E9800998ECF8427E"; + + /** caches the result of the correctness test, once executed. */ + private static Boolean valid; + + /** 128-bit interim result. */ + private int h0, h1, h2, h3; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial 0-arguments constructor. */ + public MD5() + { + super(Registry.MD5_HASH, 16, BLOCK_SIZE); + } + + /** + * <p>Private constructor for cloning purposes.</p> + * + * @param md the instance to clone. + */ + private MD5(MD5 md) + { + this(); + + this.h0 = md.h0; + this.h1 = md.h1; + this.h2 = md.h2; + this.h3 = md.h3; + this.count = md.count; + this.buffer = (byte[]) md.buffer.clone(); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // java.lang.Cloneable interface implementation ---------------------------- + + public Object clone() + { + return new MD5(this); + } + + // Implementation of concrete methods in BaseHash -------------------------- + + protected synchronized void transform(byte[] in, int i) + { + int X0 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X1 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X2 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X3 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X4 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X5 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X6 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X7 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X8 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X9 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X10 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X11 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X12 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X13 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X14 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i++] << 24; + int X15 = (in[i++] & 0xFF) | (in[i++] & 0xFF) << 8 | (in[i++] & 0xFF) << 16 + | in[i] << 24; + + int A = h0; + int B = h1; + int C = h2; + int D = h3; + + // hex constants are from md5.c in FSF Gnu Privacy Guard 0.9.2 + // round 1 + A += ((B & C) | (~B & D)) + X0 + 0xD76AA478; + A = B + (A << 7 | A >>> -7); + D += ((A & B) | (~A & C)) + X1 + 0xE8C7B756; + D = A + (D << 12 | D >>> -12); + C += ((D & A) | (~D & B)) + X2 + 0x242070DB; + C = D + (C << 17 | C >>> -17); + B += ((C & D) | (~C & A)) + X3 + 0xC1BDCEEE; + B = C + (B << 22 | B >>> -22); + + A += ((B & C) | (~B & D)) + X4 + 0xF57C0FAF; + A = B + (A << 7 | A >>> -7); + D += ((A & B) | (~A & C)) + X5 + 0x4787C62A; + D = A + (D << 12 | D >>> -12); + C += ((D & A) | (~D & B)) + X6 + 0xA8304613; + C = D + (C << 17 | C >>> -17); + B += ((C & D) | (~C & A)) + X7 + 0xFD469501; + B = C + (B << 22 | B >>> -22); + + A += ((B & C) | (~B & D)) + X8 + 0x698098D8; + A = B + (A << 7 | A >>> -7); + D += ((A & B) | (~A & C)) + X9 + 0x8B44F7AF; + D = A + (D << 12 | D >>> -12); + C += ((D & A) | (~D & B)) + X10 + 0xFFFF5BB1; + C = D + (C << 17 | C >>> -17); + B += ((C & D) | (~C & A)) + X11 + 0x895CD7BE; + B = C + (B << 22 | B >>> -22); + + A += ((B & C) | (~B & D)) + X12 + 0x6B901122; + A = B + (A << 7 | A >>> -7); + D += ((A & B) | (~A & C)) + X13 + 0xFD987193; + D = A + (D << 12 | D >>> -12); + C += ((D & A) | (~D & B)) + X14 + 0xA679438E; + C = D + (C << 17 | C >>> -17); + B += ((C & D) | (~C & A)) + X15 + 0x49B40821; + B = C + (B << 22 | B >>> -22); + + // round 2 + A += ((B & D) | (C & ~D)) + X1 + 0xF61E2562; + A = B + (A << 5 | A >>> -5); + D += ((A & C) | (B & ~C)) + X6 + 0xC040B340; + D = A + (D << 9 | D >>> -9); + C += ((D & B) | (A & ~B)) + X11 + 0x265E5A51; + C = D + (C << 14 | C >>> -14); + B += ((C & A) | (D & ~A)) + X0 + 0xE9B6C7AA; + B = C + (B << 20 | B >>> -20); + + A += ((B & D) | (C & ~D)) + X5 + 0xD62F105D; + A = B + (A << 5 | A >>> -5); + D += ((A & C) | (B & ~C)) + X10 + 0x02441453; + D = A + (D << 9 | D >>> -9); + C += ((D & B) | (A & ~B)) + X15 + 0xD8A1E681; + C = D + (C << 14 | C >>> -14); + B += ((C & A) | (D & ~A)) + X4 + 0xE7D3FBC8; + B = C + (B << 20 | B >>> -20); + + A += ((B & D) | (C & ~D)) + X9 + 0x21E1CDE6; + A = B + (A << 5 | A >>> -5); + D += ((A & C) | (B & ~C)) + X14 + 0xC33707D6; + D = A + (D << 9 | D >>> -9); + C += ((D & B) | (A & ~B)) + X3 + 0xF4D50D87; + C = D + (C << 14 | C >>> -14); + B += ((C & A) | (D & ~A)) + X8 + 0x455A14ED; + B = C + (B << 20 | B >>> -20); + + A += ((B & D) | (C & ~D)) + X13 + 0xA9E3E905; + A = B + (A << 5 | A >>> -5); + D += ((A & C) | (B & ~C)) + X2 + 0xFCEFA3F8; + D = A + (D << 9 | D >>> -9); + C += ((D & B) | (A & ~B)) + X7 + 0x676F02D9; + C = D + (C << 14 | C >>> -14); + B += ((C & A) | (D & ~A)) + X12 + 0x8D2A4C8A; + B = C + (B << 20 | B >>> -20); + + // round 3 + A += (B ^ C ^ D) + X5 + 0xFFFA3942; + A = B + (A << 4 | A >>> -4); + D += (A ^ B ^ C) + X8 + 0x8771F681; + D = A + (D << 11 | D >>> -11); + C += (D ^ A ^ B) + X11 + 0x6D9D6122; + C = D + (C << 16 | C >>> -16); + B += (C ^ D ^ A) + X14 + 0xFDE5380C; + B = C + (B << 23 | B >>> -23); + + A += (B ^ C ^ D) + X1 + 0xA4BEEA44; + A = B + (A << 4 | A >>> -4); + D += (A ^ B ^ C) + X4 + 0x4BDECFA9; + D = A + (D << 11 | D >>> -11); + C += (D ^ A ^ B) + X7 + 0xF6BB4B60; + C = D + (C << 16 | C >>> -16); + B += (C ^ D ^ A) + X10 + 0xBEBFBC70; + B = C + (B << 23 | B >>> -23); + + A += (B ^ C ^ D) + X13 + 0x289B7EC6; + A = B + (A << 4 | A >>> -4); + D += (A ^ B ^ C) + X0 + 0xEAA127FA; + D = A + (D << 11 | D >>> -11); + C += (D ^ A ^ B) + X3 + 0xD4EF3085; + C = D + (C << 16 | C >>> -16); + B += (C ^ D ^ A) + X6 + 0x04881D05; + B = C + (B << 23 | B >>> -23); + + A += (B ^ C ^ D) + X9 + 0xD9D4D039; + A = B + (A << 4 | A >>> -4); + D += (A ^ B ^ C) + X12 + 0xE6DB99E5; + D = A + (D << 11 | D >>> -11); + C += (D ^ A ^ B) + X15 + 0x1FA27CF8; + C = D + (C << 16 | C >>> -16); + B += (C ^ D ^ A) + X2 + 0xC4AC5665; + B = C + (B << 23 | B >>> -23); + + // round 4 + A += (C ^ (B | ~D)) + X0 + 0xF4292244; + A = B + (A << 6 | A >>> -6); + D += (B ^ (A | ~C)) + X7 + 0x432AFF97; + D = A + (D << 10 | D >>> -10); + C += (A ^ (D | ~B)) + X14 + 0xAB9423A7; + C = D + (C << 15 | C >>> -15); + B += (D ^ (C | ~A)) + X5 + 0xFC93A039; + B = C + (B << 21 | B >>> -21); + + A += (C ^ (B | ~D)) + X12 + 0x655B59C3; + A = B + (A << 6 | A >>> -6); + D += (B ^ (A | ~C)) + X3 + 0x8F0CCC92; + D = A + (D << 10 | D >>> -10); + C += (A ^ (D | ~B)) + X10 + 0xFFEFF47D; + C = D + (C << 15 | C >>> -15); + B += (D ^ (C | ~A)) + X1 + 0x85845dd1; + B = C + (B << 21 | B >>> -21); + + A += (C ^ (B | ~D)) + X8 + 0x6FA87E4F; + A = B + (A << 6 | A >>> -6); + D += (B ^ (A | ~C)) + X15 + 0xFE2CE6E0; + D = A + (D << 10 | D >>> -10); + C += (A ^ (D | ~B)) + X6 + 0xA3014314; + C = D + (C << 15 | C >>> -15); + B += (D ^ (C | ~A)) + X13 + 0x4E0811A1; + B = C + (B << 21 | B >>> -21); + + A += (C ^ (B | ~D)) + X4 + 0xF7537E82; + A = B + (A << 6 | A >>> -6); + D += (B ^ (A | ~C)) + X11 + 0xBD3AF235; + D = A + (D << 10 | D >>> -10); + C += (A ^ (D | ~B)) + X2 + 0x2AD7D2BB; + C = D + (C << 15 | C >>> -15); + B += (D ^ (C | ~A)) + X9 + 0xEB86D391; + B = C + (B << 21 | B >>> -21); + + h0 += A; + h1 += B; + h2 += C; + h3 += D; + } + + 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; + result[padding++] = (byte) (bits >>> 8); + result[padding++] = (byte) (bits >>> 16); + result[padding++] = (byte) (bits >>> 24); + result[padding++] = (byte) (bits >>> 32); + result[padding++] = (byte) (bits >>> 40); + result[padding++] = (byte) (bits >>> 48); + result[padding] = (byte) (bits >>> 56); + + return result; + } + + protected byte[] getResult() + { + byte[] result = new byte[] { (byte) h0, (byte) (h0 >>> 8), + (byte) (h0 >>> 16), (byte) (h0 >>> 24), + (byte) h1, (byte) (h1 >>> 8), + (byte) (h1 >>> 16), (byte) (h1 >>> 24), + (byte) h2, (byte) (h2 >>> 8), + (byte) (h2 >>> 16), (byte) (h2 >>> 24), + (byte) h3, (byte) (h3 >>> 8), + (byte) (h3 >>> 16), (byte) (h3 >>> 24) }; + + return result; + } + + protected void resetContext() + { + // magic MD5/RIPEMD128 initialisation constants + h0 = 0x67452301; + h1 = 0xEFCDAB89; + h2 = 0x98BADCFE; + h3 = 0x10325476; + } + + public boolean selfTest() + { + if (valid == null) + { + valid = new Boolean(DIGEST0.equals(Util.toString(new MD5().digest()))); + } + return valid.booleanValue(); + } +} diff --git a/libjava/classpath/gnu/java/security/hash/RipeMD128.java b/libjava/classpath/gnu/java/security/hash/RipeMD128.java new file mode 100644 index 00000000000..83e8f25044d --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/RipeMD128.java @@ -0,0 +1,291 @@ +/* RipeMD128.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +import gnu.java.security.Registry; +import gnu.java.security.util.Util; + +/** + * <p>RIPEMD-128 is a 128-bit message digest.</p> + * + * <p>References:</p> + * + * <ol> + * <li><a href="http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html"> + * RIPEMD160</a>: A Strengthened Version of RIPEMD.<br> + * Hans Dobbertin, Antoon Bosselaers and Bart Preneel.</li> + * </ol> + */ +public class RipeMD128 extends BaseHash +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + private static final int BLOCK_SIZE = 64; // inner block size in bytes + + private static final String DIGEST0 = "CDF26213A150DC3ECB610F18F6B38B46"; + + /** Constants for the transform method. */ + // selection of message word + private static final int[] R = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, + 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, + 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, + 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2 }; + + private static final int[] Rp = { 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, + 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, + 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, + 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, + 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14 }; + + // amount for rotate left (rol) + private static final int[] S = { 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, + 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, + 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, + 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, + 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, + 12 }; + + private static final int[] Sp = { 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, + 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, + 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, + 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, + 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, + 15, 8 }; + + /** caches the result of the correctness test, once executed. */ + private static Boolean valid; + + /** 128-bit h0, h1, h2, h3 (interim result) */ + private int h0, h1, h2, h3; + + /** 512 bits work buffer = 16 x 32-bit words */ + private int[] X = new int[16]; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial 0-arguments constructor. */ + public RipeMD128() + { + super(Registry.RIPEMD128_HASH, 16, BLOCK_SIZE); + } + + /** + * <p>Private constructor for cloning purposes.</p> + * + * @param md the instance to clone. + */ + private RipeMD128(RipeMD128 md) + { + this(); + + this.h0 = md.h0; + this.h1 = md.h1; + this.h2 = md.h2; + this.h3 = md.h3; + this.count = md.count; + this.buffer = (byte[]) md.buffer.clone(); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // java.lang.Cloneable interface implementation ---------------------------- + + public Object clone() + { + return new RipeMD128(this); + } + + // Implementation of concrete methods in BaseHash -------------------------- + + protected void transform(byte[] in, int offset) + { + int A, B, C, D, Ap, Bp, Cp, Dp, T, s, i; + + // encode 64 bytes from input block into an array of 16 unsigned + // integers. + for (i = 0; i < 16; i++) + { + X[i] = (in[offset++] & 0xFF) | (in[offset++] & 0xFF) << 8 + | (in[offset++] & 0xFF) << 16 | in[offset++] << 24; + } + + A = Ap = h0; + B = Bp = h1; + C = Cp = h2; + D = Dp = h3; + + for (i = 0; i < 16; i++) + { // rounds 0...15 + s = S[i]; + T = A + (B ^ C ^ D) + X[i]; + A = D; + D = C; + C = B; + B = T << s | T >>> (32 - s); + + s = Sp[i]; + T = Ap + ((Bp & Dp) | (Cp & ~Dp)) + X[Rp[i]] + 0x50A28BE6; + Ap = Dp; + Dp = Cp; + Cp = Bp; + Bp = T << s | T >>> (32 - s); + } + + for (; i < 32; i++) + { // rounds 16...31 + s = S[i]; + T = A + ((B & C) | (~B & D)) + X[R[i]] + 0x5A827999; + A = D; + D = C; + C = B; + B = T << s | T >>> (32 - s); + + s = Sp[i]; + T = Ap + ((Bp | ~Cp) ^ Dp) + X[Rp[i]] + 0x5C4DD124; + Ap = Dp; + Dp = Cp; + Cp = Bp; + Bp = T << s | T >>> (32 - s); + } + + for (; i < 48; i++) + { // rounds 32...47 + s = S[i]; + T = A + ((B | ~C) ^ D) + X[R[i]] + 0x6ED9EBA1; + A = D; + D = C; + C = B; + B = T << s | T >>> (32 - s); + + s = Sp[i]; + T = Ap + ((Bp & Cp) | (~Bp & Dp)) + X[Rp[i]] + 0x6D703EF3; + Ap = Dp; + Dp = Cp; + Cp = Bp; + Bp = T << s | T >>> (32 - s); + } + + for (; i < 64; i++) + { // rounds 48...63 + s = S[i]; + T = A + ((B & D) | (C & ~D)) + X[R[i]] + 0x8F1BBCDC; + A = D; + D = C; + C = B; + B = T << s | T >>> (32 - s); + + s = Sp[i]; + T = Ap + (Bp ^ Cp ^ Dp) + X[Rp[i]]; + Ap = Dp; + Dp = Cp; + Cp = Bp; + Bp = T << s | T >>> (32 - s); + } + + T = h1 + C + Dp; + h1 = h2 + D + Ap; + h2 = h3 + A + Bp; + h3 = h0 + B + Cp; + h0 = T; + } + + 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; + result[padding++] = (byte) (bits >>> 8); + result[padding++] = (byte) (bits >>> 16); + result[padding++] = (byte) (bits >>> 24); + result[padding++] = (byte) (bits >>> 32); + result[padding++] = (byte) (bits >>> 40); + result[padding++] = (byte) (bits >>> 48); + result[padding] = (byte) (bits >>> 56); + + return result; + } + + protected byte[] getResult() + { + byte[] result = new byte[] { (byte) h0, (byte) (h0 >>> 8), + (byte) (h0 >>> 16), (byte) (h0 >>> 24), + (byte) h1, (byte) (h1 >>> 8), + (byte) (h1 >>> 16), (byte) (h1 >>> 24), + (byte) h2, (byte) (h2 >>> 8), + (byte) (h2 >>> 16), (byte) (h2 >>> 24), + (byte) h3, (byte) (h3 >>> 8), + (byte) (h3 >>> 16), (byte) (h3 >>> 24) }; + + return result; + } + + protected void resetContext() + { + // magic RIPEMD128 initialisation constants + h0 = 0x67452301; + h1 = 0xEFCDAB89; + h2 = 0x98BADCFE; + h3 = 0x10325476; + } + + public boolean selfTest() + { + if (valid == null) + { + valid = new Boolean + (DIGEST0.equals(Util.toString(new RipeMD128().digest()))); + } + return valid.booleanValue(); + } +} diff --git a/libjava/classpath/gnu/java/security/hash/RipeMD160.java b/libjava/classpath/gnu/java/security/hash/RipeMD160.java new file mode 100644 index 00000000000..73ecc5161d7 --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/RipeMD160.java @@ -0,0 +1,328 @@ +/* RipeMD160.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +import gnu.java.security.Registry; +import gnu.java.security.util.Util; + +/** + * <p>RIPEMD-160 is a 160-bit message digest.</p> + * + * <p>References:</p> + * + * <ol> + * <li><a href="http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html"> + * RIPEMD160</a>: A Strengthened Version of RIPEMD.<br> + * Hans Dobbertin, Antoon Bosselaers and Bart Preneel.</li> + * </ol> + */ +public class RipeMD160 extends BaseHash +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + private static final int BLOCK_SIZE = 64; // inner block size in bytes + + private static final String DIGEST0 = "9C1185A5C5E9FC54612808977EE8F548B2258D31"; + + // selection of message word + private static final int[] R = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, + 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, + 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, + 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, + 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, + 13 }; + + private static final int[] Rp = { 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, + 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, + 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, + 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, + 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, + 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, + 3, 9, 11 }; + + // amount for rotate left (rol) + private static final int[] S = { 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, + 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, + 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, + 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, + 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, + 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, + 14, 11, 8, 5, 6 }; + + private static final int[] Sp = { 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, + 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, + 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, + 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, + 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, + 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, + 5, 15, 13, 11, 11 }; + + /** caches the result of the correctness test, once executed. */ + private static Boolean valid; + + /** 160-bit h0, h1, h2, h3, h4 (interim result) */ + private int h0, h1, h2, h3, h4; + + /** 512 bits work buffer = 16 x 32-bit words */ + private int[] X = new int[16]; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial 0-arguments constructor. */ + public RipeMD160() + { + super(Registry.RIPEMD160_HASH, 20, BLOCK_SIZE); + } + + /** + * <p>Private constructor for cloning purposes.</p> + * + * @param md the instance to clone. + */ + private RipeMD160(RipeMD160 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 + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // java.lang.Cloneable interface implementation ---------------------------- + + public Object clone() + { + return (new RipeMD160(this)); + } + + // Implementation of concrete methods in BaseHash -------------------------- + + protected void transform(byte[] in, int offset) + { + int A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, T, s, i; + + // encode 64 bytes from input block into an array of 16 unsigned integers + for (i = 0; i < 16; i++) + { + X[i] = (in[offset++] & 0xFF) | (in[offset++] & 0xFF) << 8 + | (in[offset++] & 0xFF) << 16 | in[offset++] << 24; + } + + A = Ap = h0; + B = Bp = h1; + C = Cp = h2; + D = Dp = h3; + E = Ep = h4; + + for (i = 0; i < 16; i++) + { // rounds 0...15 + s = S[i]; + T = A + (B ^ C ^ D) + X[i]; + A = E; + E = D; + D = C << 10 | C >>> 22; + C = B; + B = (T << s | T >>> (32 - s)) + A; + + s = Sp[i]; + T = Ap + (Bp ^ (Cp | ~Dp)) + X[Rp[i]] + 0x50A28BE6; + Ap = Ep; + Ep = Dp; + Dp = Cp << 10 | Cp >>> 22; + Cp = Bp; + Bp = (T << s | T >>> (32 - s)) + Ap; + } + + for (; i < 32; i++) + { // rounds 16...31 + s = S[i]; + T = A + ((B & C) | (~B & D)) + X[R[i]] + 0x5A827999; + A = E; + E = D; + D = C << 10 | C >>> 22; + C = B; + B = (T << s | T >>> (32 - s)) + A; + + s = Sp[i]; + T = Ap + ((Bp & Dp) | (Cp & ~Dp)) + X[Rp[i]] + 0x5C4DD124; + Ap = Ep; + Ep = Dp; + Dp = Cp << 10 | Cp >>> 22; + Cp = Bp; + Bp = (T << s | T >>> (32 - s)) + Ap; + } + + for (; i < 48; i++) + { // rounds 32...47 + s = S[i]; + T = A + ((B | ~C) ^ D) + X[R[i]] + 0x6ED9EBA1; + A = E; + E = D; + D = C << 10 | C >>> 22; + C = B; + B = (T << s | T >>> (32 - s)) + A; + + s = Sp[i]; + T = Ap + ((Bp | ~Cp) ^ Dp) + X[Rp[i]] + 0x6D703EF3; + Ap = Ep; + Ep = Dp; + Dp = Cp << 10 | Cp >>> 22; + Cp = Bp; + Bp = (T << s | T >>> (32 - s)) + Ap; + } + + for (; i < 64; i++) + { // rounds 48...63 + s = S[i]; + T = A + ((B & D) | (C & ~D)) + X[R[i]] + 0x8F1BBCDC; + A = E; + E = D; + D = C << 10 | C >>> 22; + C = B; + B = (T << s | T >>> (32 - s)) + A; + + s = Sp[i]; + T = Ap + ((Bp & Cp) | (~Bp & Dp)) + X[Rp[i]] + 0x7A6D76E9; + Ap = Ep; + Ep = Dp; + Dp = Cp << 10 | Cp >>> 22; + Cp = Bp; + Bp = (T << s | T >>> (32 - s)) + Ap; + } + + for (; i < 80; i++) + { // rounds 64...79 + s = S[i]; + T = A + (B ^ (C | ~D)) + X[R[i]] + 0xA953FD4E; + A = E; + E = D; + D = C << 10 | C >>> 22; + C = B; + B = (T << s | T >>> (32 - s)) + A; + + s = Sp[i]; + T = Ap + (Bp ^ Cp ^ Dp) + X[Rp[i]]; + Ap = Ep; + Ep = Dp; + Dp = Cp << 10 | Cp >>> 22; + Cp = Bp; + Bp = (T << s | T >>> (32 - s)) + Ap; + } + + T = h1 + C + Dp; + h1 = h2 + D + Ep; + h2 = h3 + E + Ap; + h3 = h4 + A + Bp; + h4 = h0 + B + Cp; + h0 = T; + } + + 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; + result[padding++] = (byte) (bits >>> 8); + result[padding++] = (byte) (bits >>> 16); + result[padding++] = (byte) (bits >>> 24); + result[padding++] = (byte) (bits >>> 32); + result[padding++] = (byte) (bits >>> 40); + result[padding++] = (byte) (bits >>> 48); + result[padding] = (byte) (bits >>> 56); + + return result; + } + + protected byte[] getResult() + { + byte[] result = new byte[] { (byte) h0, (byte) (h0 >>> 8), + (byte) (h0 >>> 16), (byte) (h0 >>> 24), + (byte) h1, (byte) (h1 >>> 8), + (byte) (h1 >>> 16), (byte) (h1 >>> 24), + (byte) h2, (byte) (h2 >>> 8), + (byte) (h2 >>> 16), (byte) (h2 >>> 24), + (byte) h3, (byte) (h3 >>> 8), + (byte) (h3 >>> 16), (byte) (h3 >>> 24), + (byte) h4, (byte) (h4 >>> 8), + (byte) (h4 >>> 16), (byte) (h4 >>> 24) }; + + return result; + } + + protected void resetContext() + { + // magic RIPEMD160 initialisation constants + h0 = 0x67452301; + h1 = 0xEFCDAB89; + h2 = 0x98BADCFE; + h3 = 0x10325476; + h4 = 0xC3D2E1F0; + } + + public boolean selfTest() + { + if (valid == null) + { + valid = new Boolean + (DIGEST0.equals(Util.toString(new RipeMD160().digest()))); + } + return valid.booleanValue(); + } +} diff --git a/libjava/classpath/gnu/java/security/hash/Sha160.java b/libjava/classpath/gnu/java/security/hash/Sha160.java new file mode 100644 index 00000000000..bf5f45652a1 --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/Sha160.java @@ -0,0 +1,308 @@ +/* Sha160.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +import gnu.java.security.Registry; +import gnu.java.security.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> + */ +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 }; + } +} diff --git a/libjava/classpath/gnu/java/security/hash/Sha256.java b/libjava/classpath/gnu/java/security/hash/Sha256.java new file mode 100644 index 00000000000..9ef70a1a6a3 --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/Sha256.java @@ -0,0 +1,278 @@ +/* Sha256.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +import gnu.java.security.Registry; +import gnu.java.security.util.Util; + +/** + * <p>Implementation of SHA2-1 [SHA-256] per the IETF Draft Specification.</p> + * + * <p>References:</p> + * <ol> + * <li><a href="http://ftp.ipv4.heanet.ie/pub/ietf/internet-drafts/draft-ietf-ipsec-ciph-aes-cbc-03.txt"> + * Descriptions of SHA-256, SHA-384, and SHA-512</a>,</li> + * <li>http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf</li> + * </ol> + */ +public class Sha256 extends BaseHash +{ + + // Constants and variables + // ------------------------------------------------------------------------- + private static final int[] k = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, + 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, + 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, + 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, + 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, + 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, + 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, + 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, + 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, + 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, + 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, + 0xc67178f2 }; + + private static final int BLOCK_SIZE = 64; // inner block size in bytes + + private static final String DIGEST0 = "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD"; + + private static final int[] w = new int[64]; + + /** caches the result of the correctness test, once executed. */ + private static Boolean valid; + + /** 256-bit interim result. */ + private int h0, h1, h2, h3, h4, h5, h6, h7; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial 0-arguments constructor. */ + public Sha256() + { + super(Registry.SHA256_HASH, 32, BLOCK_SIZE); + } + + /** + * <p>Private constructor for cloning purposes.</p> + * + * @param md the instance to clone. + */ + private Sha256(Sha256 md) + { + this(); + + this.h0 = md.h0; + this.h1 = md.h1; + this.h2 = md.h2; + this.h3 = md.h3; + this.h4 = md.h4; + this.h5 = md.h5; + this.h6 = md.h6; + this.h7 = md.h7; + 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, + int hh5, int hh6, int hh7, byte[] in, int offset) + { + return sha(hh0, hh1, hh2, hh3, hh4, hh5, hh6, hh7, in, offset); + } + + // Instance methods + // ------------------------------------------------------------------------- + + // java.lang.Cloneable interface implementation ---------------------------- + + public Object clone() + { + return new Sha256(this); + } + + // Implementation of concrete methods in BaseHash -------------------------- + + protected void transform(byte[] in, int offset) + { + int[] result = sha(h0, h1, h2, h3, h4, h5, h6, h7, in, offset); + + h0 = result[0]; + h1 = result[1]; + h2 = result[2]; + h3 = result[3]; + h4 = result[4]; + h5 = result[5]; + h6 = result[6]; + h7 = result[7]; + } + + 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() + { + return 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, (byte) (h5 >>> 24), + (byte) (h5 >>> 16), (byte) (h5 >>> 8), (byte) h5, + (byte) (h6 >>> 24), (byte) (h6 >>> 16), + (byte) (h6 >>> 8), (byte) h6, (byte) (h7 >>> 24), + (byte) (h7 >>> 16), (byte) (h7 >>> 8), (byte) h7 }; + } + + protected void resetContext() + { + // magic SHA-256 initialisation constants + h0 = 0x6a09e667; + h1 = 0xbb67ae85; + h2 = 0x3c6ef372; + h3 = 0xa54ff53a; + h4 = 0x510e527f; + h5 = 0x9b05688c; + h6 = 0x1f83d9ab; + h7 = 0x5be0cd19; + } + + public boolean selfTest() + { + if (valid == null) + { + Sha256 md = new Sha256(); + 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, int hh5, + int hh6, int hh7, byte[] in, + int offset) + { + int A = hh0; + int B = hh1; + int C = hh2; + int D = hh3; + int E = hh4; + int F = hh5; + int G = hh6; + int H = hh7; + int r, T, T2; + + 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 < 64; r++) + { + T = w[r - 2]; + T2 = w[r - 15]; + w[r] = ((((T >>> 17) | (T << 15)) ^ ((T >>> 19) | (T << 13)) ^ (T >>> 10)) + + w[r - 7] + + (((T2 >>> 7) | (T2 << 25)) ^ ((T2 >>> 18) | (T2 << 14)) ^ (T2 >>> 3)) + + w[r - 16]); + } + + for (r = 0; r < 64; r++) + { + T = (H + + (((E >>> 6) | (E << 26)) ^ ((E >>> 11) | (E << 21)) ^ ((E >>> 25) | (E << 7))) + + ((E & F) ^ (~E & G)) + k[r] + w[r]); + T2 = ((((A >>> 2) | (A << 30)) ^ ((A >>> 13) | (A << 19)) ^ ((A >>> 22) | (A << 10))) + + ((A & B) ^ (A & C) ^ (B & C))); + H = G; + G = F; + F = E; + E = D + T; + D = C; + C = B; + B = A; + A = T + T2; + } + + return new int[] { hh0 + A, hh1 + B, hh2 + C, hh3 + D, hh4 + E, hh5 + F, + hh6 + G, hh7 + H }; + } +} diff --git a/libjava/classpath/gnu/java/security/hash/Sha384.java b/libjava/classpath/gnu/java/security/hash/Sha384.java new file mode 100644 index 00000000000..2f619dc984d --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/Sha384.java @@ -0,0 +1,322 @@ +/* Sha384.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +import gnu.java.security.Registry; +import gnu.java.security.util.Util; + +/** + * <p>Implementation of SHA2-2 [SHA-384] per the IETF Draft Specification.</p> + * + * <p>References:</p> + * <ol> + * <li><a href="http://ftp.ipv4.heanet.ie/pub/ietf/internet-drafts/draft-ietf-ipsec-ciph-aes-cbc-03.txt"> + * Descriptions of SHA-256, SHA-384, and SHA-512</a>,</li> + * <li>http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf</li> + * </ol> + */ +public class Sha384 extends BaseHash +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + private static final long[] k = { 0x428a2f98d728ae22L, 0x7137449123ef65cdL, + 0xb5c0fbcfec4d3b2fL, 0xe9b5dba58189dbbcL, + 0x3956c25bf348b538L, 0x59f111f1b605d019L, + 0x923f82a4af194f9bL, 0xab1c5ed5da6d8118L, + 0xd807aa98a3030242L, 0x12835b0145706fbeL, + 0x243185be4ee4b28cL, 0x550c7dc3d5ffb4e2L, + 0x72be5d74f27b896fL, 0x80deb1fe3b1696b1L, + 0x9bdc06a725c71235L, 0xc19bf174cf692694L, + 0xe49b69c19ef14ad2L, 0xefbe4786384f25e3L, + 0x0fc19dc68b8cd5b5L, 0x240ca1cc77ac9c65L, + 0x2de92c6f592b0275L, 0x4a7484aa6ea6e483L, + 0x5cb0a9dcbd41fbd4L, 0x76f988da831153b5L, + 0x983e5152ee66dfabL, 0xa831c66d2db43210L, + 0xb00327c898fb213fL, 0xbf597fc7beef0ee4L, + 0xc6e00bf33da88fc2L, 0xd5a79147930aa725L, + 0x06ca6351e003826fL, 0x142929670a0e6e70L, + 0x27b70a8546d22ffcL, 0x2e1b21385c26c926L, + 0x4d2c6dfc5ac42aedL, 0x53380d139d95b3dfL, + 0x650a73548baf63deL, 0x766a0abb3c77b2a8L, + 0x81c2c92e47edaee6L, 0x92722c851482353bL, + 0xa2bfe8a14cf10364L, 0xa81a664bbc423001L, + 0xc24b8b70d0f89791L, 0xc76c51a30654be30L, + 0xd192e819d6ef5218L, 0xd69906245565a910L, + 0xf40e35855771202aL, 0x106aa07032bbd1b8L, + 0x19a4c116b8d2d0c8L, 0x1e376c085141ab53L, + 0x2748774cdf8eeb99L, 0x34b0bcb5e19b48a8L, + 0x391c0cb3c5c95a63L, 0x4ed8aa4ae3418acbL, + 0x5b9cca4f7763e373L, 0x682e6ff3d6b2b8a3L, + 0x748f82ee5defb2fcL, 0x78a5636f43172f60L, + 0x84c87814a1f0ab72L, 0x8cc702081a6439ecL, + 0x90befffa23631e28L, 0xa4506cebde82bde9L, + 0xbef9a3f7b2c67915L, 0xc67178f2e372532bL, + 0xca273eceea26619cL, 0xd186b8c721c0c207L, + 0xeada7dd6cde0eb1eL, 0xf57d4f7fee6ed178L, + 0x06f067aa72176fbaL, 0x0a637dc5a2c898a6L, + 0x113f9804bef90daeL, 0x1b710b35131c471bL, + 0x28db77f523047d84L, 0x32caab7b40c72493L, + 0x3c9ebe0a15c9bebcL, 0x431d67c49c100d4cL, + 0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL, + 0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L }; + + private static final int BLOCK_SIZE = 128; // inner block size in bytes + + private static final String DIGEST0 = "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED" + + "8086072BA1E7CC2358BAECA134C825A7"; + + private static final long[] w = new long[80]; + + /** caches the result of the correctness test, once executed. */ + private static Boolean valid; + + /** 512-bit interim result. */ + private long h0, h1, h2, h3, h4, h5, h6, h7; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial 0-arguments constructor. */ + public Sha384() + { + super(Registry.SHA384_HASH, 48, BLOCK_SIZE); + } + + /** + * <p>Private constructor for cloning purposes.</p> + * + * @param md the instance to clone. + */ + private Sha384(Sha384 md) + { + this(); + + this.h0 = md.h0; + this.h1 = md.h1; + this.h2 = md.h2; + this.h3 = md.h3; + this.h4 = md.h4; + this.h5 = md.h5; + this.h6 = md.h6; + this.h7 = md.h7; + this.count = md.count; + this.buffer = (byte[]) md.buffer.clone(); + } + + // Class methods + // ------------------------------------------------------------------------- + + public static final long[] G(long hh0, long hh1, long hh2, long hh3, + long hh4, long hh5, long hh6, long hh7, + byte[] in, int offset) + { + return sha(hh0, hh1, hh2, hh3, hh4, hh5, hh6, hh7, in, offset); + } + + // Instance methods + // ------------------------------------------------------------------------- + + // java.lang.Cloneable interface implementation ---------------------------- + + public Object clone() + { + return new Sha384(this); + } + + // Implementation of concrete methods in BaseHash -------------------------- + + protected void transform(byte[] in, int offset) + { + long[] result = sha(h0, h1, h2, h3, h4, h5, h6, h7, in, offset); + + h0 = result[0]; + h1 = result[1]; + h2 = result[2]; + h3 = result[3]; + h4 = result[4]; + h5 = result[5]; + h6 = result[6]; + h7 = result[7]; + } + + protected byte[] padBuffer() + { + int n = (int) (count % BLOCK_SIZE); + int padding = (n < 112) ? (112 - n) : (240 - n); + byte[] result = new byte[padding + 16]; + + // 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 + // TODO: FIX Only ~35 bits of 128 bit counter usable this way + long bits = count << 3; + padding += 8; + 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() + { + return new byte[] { (byte) (h0 >>> 56), (byte) (h0 >>> 48), + (byte) (h0 >>> 40), (byte) (h0 >>> 32), + (byte) (h0 >>> 24), (byte) (h0 >>> 16), + (byte) (h0 >>> 8), (byte) h0, (byte) (h1 >>> 56), + (byte) (h1 >>> 48), (byte) (h1 >>> 40), + (byte) (h1 >>> 32), (byte) (h1 >>> 24), + (byte) (h1 >>> 16), (byte) (h1 >>> 8), (byte) h1, + (byte) (h2 >>> 56), (byte) (h2 >>> 48), + (byte) (h2 >>> 40), (byte) (h2 >>> 32), + (byte) (h2 >>> 24), (byte) (h2 >>> 16), + (byte) (h2 >>> 8), (byte) h2, (byte) (h3 >>> 56), + (byte) (h3 >>> 48), (byte) (h3 >>> 40), + (byte) (h3 >>> 32), (byte) (h3 >>> 24), + (byte) (h3 >>> 16), (byte) (h3 >>> 8), (byte) h3, + (byte) (h4 >>> 56), (byte) (h4 >>> 48), + (byte) (h4 >>> 40), (byte) (h4 >>> 32), + (byte) (h4 >>> 24), (byte) (h4 >>> 16), + (byte) (h4 >>> 8), (byte) h4, (byte) (h5 >>> 56), + (byte) (h5 >>> 48), (byte) (h5 >>> 40), + (byte) (h5 >>> 32), (byte) (h5 >>> 24), + (byte) (h5 >>> 16), (byte) (h5 >>> 8), (byte) h5 + // (byte)(h6 >>> 56), (byte)(h6 >>> 48), (byte)(h6 >>> 40), (byte)(h6 >>> 32), + // (byte)(h6 >>> 24), (byte)(h6 >>> 16), (byte)(h6 >>> 8), (byte) h6, + // (byte)(h7 >>> 56), (byte)(h7 >>> 48), (byte)(h7 >>> 40), (byte)(h7 >>> 32), + // (byte)(h7 >>> 24), (byte)(h7 >>> 16), (byte)(h7 >>> 8), (byte) h7 + }; + } + + protected void resetContext() + { + // magic SHA-384 initialisation constants + h0 = 0xcbbb9d5dc1059ed8L; + h1 = 0x629a292a367cd507L; + h2 = 0x9159015a3070dd17L; + h3 = 0x152fecd8f70e5939L; + h4 = 0x67332667ffc00b31L; + h5 = 0x8eb44a8768581511L; + h6 = 0xdb0c2e0d64f98fa7L; + h7 = 0x47b5481dbefa4fa4L; + } + + public boolean selfTest() + { + if (valid == null) + { + Sha384 md = new Sha384(); + 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 long[] sha(long hh0, long hh1, long hh2, + long hh3, long hh4, long hh5, + long hh6, long hh7, byte[] in, + int offset) + { + long A = hh0; + long B = hh1; + long C = hh2; + long D = hh3; + long E = hh4; + long F = hh5; + long G = hh6; + long H = hh7; + long T, T2; + int r; + + for (r = 0; r < 16; r++) + { + w[r] = (long) in[offset++] << 56 | ((long) in[offset++] & 0xFF) << 48 + | ((long) in[offset++] & 0xFF) << 40 + | ((long) in[offset++] & 0xFF) << 32 + | ((long) in[offset++] & 0xFF) << 24 + | ((long) in[offset++] & 0xFF) << 16 + | ((long) in[offset++] & 0xFF) << 8 + | ((long) in[offset++] & 0xFF); + } + for (r = 16; r < 80; r++) + { + T = w[r - 2]; + T2 = w[r - 15]; + w[r] = (((T >>> 19) | (T << 45)) ^ ((T >>> 61) | (T << 3)) ^ (T >>> 6)) + + w[r - 7] + + (((T2 >>> 1) | (T2 << 63)) ^ ((T2 >>> 8) | (T2 << 56)) ^ (T2 >>> 7)) + + w[r - 16]; + } + + for (r = 0; r < 80; r++) + { + + T = H + + (((E >>> 14) | (E << 50)) ^ ((E >>> 18) | (E << 46)) ^ ((E >>> 41) | (E << 23))) + + ((E & F) ^ ((~E) & G)) + k[r] + w[r]; + // T IS INCORRECT SOMEHOW + T2 = (((A >>> 28) | (A << 36)) ^ ((A >>> 34) | (A << 30)) ^ ((A >>> 39) | (A << 25))) + + ((A & B) ^ (A & C) ^ (B & C)); + H = G; + G = F; + F = E; + E = D + T; + D = C; + C = B; + B = A; + A = T + T2; + } + + return new long[] { hh0 + A, hh1 + B, hh2 + C, hh3 + D, hh4 + E, hh5 + F, + hh6 + G, hh7 + H }; + } +} diff --git a/libjava/classpath/gnu/java/security/hash/Sha512.java b/libjava/classpath/gnu/java/security/hash/Sha512.java new file mode 100644 index 00000000000..798b34dfc1d --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/Sha512.java @@ -0,0 +1,322 @@ +/* Sha512.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +import gnu.java.security.Registry; +import gnu.java.security.util.Util; + +/** + * <p>Implementation of SHA2-3 [SHA-512] per the IETF Draft Specification.</p> + * + * <p>References:</p> + * <ol> + * <li><a href="http://ftp.ipv4.heanet.ie/pub/ietf/internet-drafts/draft-ietf-ipsec-ciph-aes-cbc-03.txt"> + * Descriptions of SHA-256, SHA-384, and SHA-512</a>,</li> + * <li>http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf</li> + * </ol> + */ +public class Sha512 extends BaseHash +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + private static final long[] k = { 0x428a2f98d728ae22L, 0x7137449123ef65cdL, + 0xb5c0fbcfec4d3b2fL, 0xe9b5dba58189dbbcL, + 0x3956c25bf348b538L, 0x59f111f1b605d019L, + 0x923f82a4af194f9bL, 0xab1c5ed5da6d8118L, + 0xd807aa98a3030242L, 0x12835b0145706fbeL, + 0x243185be4ee4b28cL, 0x550c7dc3d5ffb4e2L, + 0x72be5d74f27b896fL, 0x80deb1fe3b1696b1L, + 0x9bdc06a725c71235L, 0xc19bf174cf692694L, + 0xe49b69c19ef14ad2L, 0xefbe4786384f25e3L, + 0x0fc19dc68b8cd5b5L, 0x240ca1cc77ac9c65L, + 0x2de92c6f592b0275L, 0x4a7484aa6ea6e483L, + 0x5cb0a9dcbd41fbd4L, 0x76f988da831153b5L, + 0x983e5152ee66dfabL, 0xa831c66d2db43210L, + 0xb00327c898fb213fL, 0xbf597fc7beef0ee4L, + 0xc6e00bf33da88fc2L, 0xd5a79147930aa725L, + 0x06ca6351e003826fL, 0x142929670a0e6e70L, + 0x27b70a8546d22ffcL, 0x2e1b21385c26c926L, + 0x4d2c6dfc5ac42aedL, 0x53380d139d95b3dfL, + 0x650a73548baf63deL, 0x766a0abb3c77b2a8L, + 0x81c2c92e47edaee6L, 0x92722c851482353bL, + 0xa2bfe8a14cf10364L, 0xa81a664bbc423001L, + 0xc24b8b70d0f89791L, 0xc76c51a30654be30L, + 0xd192e819d6ef5218L, 0xd69906245565a910L, + 0xf40e35855771202aL, 0x106aa07032bbd1b8L, + 0x19a4c116b8d2d0c8L, 0x1e376c085141ab53L, + 0x2748774cdf8eeb99L, 0x34b0bcb5e19b48a8L, + 0x391c0cb3c5c95a63L, 0x4ed8aa4ae3418acbL, + 0x5b9cca4f7763e373L, 0x682e6ff3d6b2b8a3L, + 0x748f82ee5defb2fcL, 0x78a5636f43172f60L, + 0x84c87814a1f0ab72L, 0x8cc702081a6439ecL, + 0x90befffa23631e28L, 0xa4506cebde82bde9L, + 0xbef9a3f7b2c67915L, 0xc67178f2e372532bL, + 0xca273eceea26619cL, 0xd186b8c721c0c207L, + 0xeada7dd6cde0eb1eL, 0xf57d4f7fee6ed178L, + 0x06f067aa72176fbaL, 0x0a637dc5a2c898a6L, + 0x113f9804bef90daeL, 0x1b710b35131c471bL, + 0x28db77f523047d84L, 0x32caab7b40c72493L, + 0x3c9ebe0a15c9bebcL, 0x431d67c49c100d4cL, + 0x4cc5d4becb3e42b6L, 0x597f299cfc657e2aL, + 0x5fcb6fab3ad6faecL, 0x6c44198c4a475817L }; + + private static final int BLOCK_SIZE = 128; // inner block size in bytes + + private static final String DIGEST0 = "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A" + + "2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F"; + + private static final long[] w = new long[80]; + + /** caches the result of the correctness test, once executed. */ + private static Boolean valid; + + /** 512-bit interim result. */ + private long h0, h1, h2, h3, h4, h5, h6, h7; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial 0-arguments constructor. */ + public Sha512() + { + super(Registry.SHA512_HASH, 64, BLOCK_SIZE); + } + + /** + * <p>Private constructor for cloning purposes.</p> + * + * @param md the instance to clone. + */ + private Sha512(Sha512 md) + { + this(); + + this.h0 = md.h0; + this.h1 = md.h1; + this.h2 = md.h2; + this.h3 = md.h3; + this.h4 = md.h4; + this.h5 = md.h5; + this.h6 = md.h6; + this.h7 = md.h7; + this.count = md.count; + this.buffer = (byte[]) md.buffer.clone(); + } + + // Class methods + // ------------------------------------------------------------------------- + + public static final long[] G(long hh0, long hh1, long hh2, long hh3, + long hh4, long hh5, long hh6, long hh7, + byte[] in, int offset) + { + return sha(hh0, hh1, hh2, hh3, hh4, hh5, hh6, hh7, in, offset); + } + + // Instance methods + // ------------------------------------------------------------------------- + + // java.lang.Cloneable interface implementation ---------------------------- + + public Object clone() + { + return new Sha512(this); + } + + // Implementation of concrete methods in BaseHash -------------------------- + + protected void transform(byte[] in, int offset) + { + long[] result = sha(h0, h1, h2, h3, h4, h5, h6, h7, in, offset); + + h0 = result[0]; + h1 = result[1]; + h2 = result[2]; + h3 = result[3]; + h4 = result[4]; + h5 = result[5]; + h6 = result[6]; + h7 = result[7]; + } + + protected byte[] padBuffer() + { + int n = (int) (count % BLOCK_SIZE); + int padding = (n < 112) ? (112 - n) : (240 - n); + byte[] result = new byte[padding + 16]; + + // 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 + // TODO: FIX Only ~35 bits of 128 bit counter usable this way + long bits = count << 3; + padding += 8; + 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() + { + return new byte[] { (byte) (h0 >>> 56), (byte) (h0 >>> 48), + (byte) (h0 >>> 40), (byte) (h0 >>> 32), + (byte) (h0 >>> 24), (byte) (h0 >>> 16), + (byte) (h0 >>> 8), (byte) h0, (byte) (h1 >>> 56), + (byte) (h1 >>> 48), (byte) (h1 >>> 40), + (byte) (h1 >>> 32), (byte) (h1 >>> 24), + (byte) (h1 >>> 16), (byte) (h1 >>> 8), (byte) h1, + (byte) (h2 >>> 56), (byte) (h2 >>> 48), + (byte) (h2 >>> 40), (byte) (h2 >>> 32), + (byte) (h2 >>> 24), (byte) (h2 >>> 16), + (byte) (h2 >>> 8), (byte) h2, (byte) (h3 >>> 56), + (byte) (h3 >>> 48), (byte) (h3 >>> 40), + (byte) (h3 >>> 32), (byte) (h3 >>> 24), + (byte) (h3 >>> 16), (byte) (h3 >>> 8), (byte) h3, + (byte) (h4 >>> 56), (byte) (h4 >>> 48), + (byte) (h4 >>> 40), (byte) (h4 >>> 32), + (byte) (h4 >>> 24), (byte) (h4 >>> 16), + (byte) (h4 >>> 8), (byte) h4, (byte) (h5 >>> 56), + (byte) (h5 >>> 48), (byte) (h5 >>> 40), + (byte) (h5 >>> 32), (byte) (h5 >>> 24), + (byte) (h5 >>> 16), (byte) (h5 >>> 8), (byte) h5, + (byte) (h6 >>> 56), (byte) (h6 >>> 48), + (byte) (h6 >>> 40), (byte) (h6 >>> 32), + (byte) (h6 >>> 24), (byte) (h6 >>> 16), + (byte) (h6 >>> 8), (byte) h6, (byte) (h7 >>> 56), + (byte) (h7 >>> 48), (byte) (h7 >>> 40), + (byte) (h7 >>> 32), (byte) (h7 >>> 24), + (byte) (h7 >>> 16), (byte) (h7 >>> 8), (byte) h7 }; + } + + protected void resetContext() + { + // magic SHA-512 initialisation constants + h0 = 0x6a09e667f3bcc908L; + h1 = 0xbb67ae8584caa73bL; + h2 = 0x3c6ef372fe94f82bL; + h3 = 0xa54ff53a5f1d36f1L; + h4 = 0x510e527fade682d1L; + h5 = 0x9b05688c2b3e6c1fL; + h6 = 0x1f83d9abfb41bd6bL; + h7 = 0x5be0cd19137e2179L; + } + + public boolean selfTest() + { + if (valid == null) + { + Sha512 md = new Sha512(); + 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 long[] sha(long hh0, long hh1, long hh2, + long hh3, long hh4, long hh5, + long hh6, long hh7, byte[] in, + int offset) + { + long A = hh0; + long B = hh1; + long C = hh2; + long D = hh3; + long E = hh4; + long F = hh5; + long G = hh6; + long H = hh7; + long T, T2; + int r; + + for (r = 0; r < 16; r++) + { + w[r] = (long) in[offset++] << 56 | ((long) in[offset++] & 0xFF) << 48 + | ((long) in[offset++] & 0xFF) << 40 + | ((long) in[offset++] & 0xFF) << 32 + | ((long) in[offset++] & 0xFF) << 24 + | ((long) in[offset++] & 0xFF) << 16 + | ((long) in[offset++] & 0xFF) << 8 + | ((long) in[offset++] & 0xFF); + } + for (r = 16; r < 80; r++) + { + T = w[r - 2]; + T2 = w[r - 15]; + w[r] = (((T >>> 19) | (T << 45)) ^ ((T >>> 61) | (T << 3)) ^ (T >>> 6)) + + w[r - 7] + + (((T2 >>> 1) | (T2 << 63)) ^ ((T2 >>> 8) | (T2 << 56)) ^ (T2 >>> 7)) + + w[r - 16]; + } + + for (r = 0; r < 80; r++) + { + T = H + + (((E >>> 14) | (E << 50)) ^ ((E >>> 18) | (E << 46)) ^ ((E >>> 41) | (E << 23))) + + ((E & F) ^ ((~E) & G)) + k[r] + w[r]; + T2 = (((A >>> 28) | (A << 36)) ^ ((A >>> 34) | (A << 30)) ^ ((A >>> 39) | (A << 25))) + + ((A & B) ^ (A & C) ^ (B & C)); + H = G; + G = F; + F = E; + E = D + T; + D = C; + C = B; + B = A; + A = T + T2; + } + + return new long[] { hh0 + A, hh1 + B, hh2 + C, hh3 + D, hh4 + E, hh5 + F, + hh6 + G, hh7 + H }; + } +} diff --git a/libjava/classpath/gnu/java/security/hash/Tiger.java b/libjava/classpath/gnu/java/security/hash/Tiger.java new file mode 100644 index 00000000000..f39fed30d62 --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/Tiger.java @@ -0,0 +1,943 @@ +/* Tiger.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +import gnu.java.security.Registry; +import gnu.java.security.util.Util; + +/** + * The Tiger message digest. Tiger was designed by Ross Anderson and Eli + * Biham, with the goal of producing a secure, fast hash function that + * performs especially well on next-generation 64-bit architectures, but + * is still efficient on 32- and 16-bit architectures. + * + * <p>Tiger processes data in 512-bit blocks and produces a 192-bit + * digest.</p> + * + * <p>References:</p> + * <ol> + * <li><a + * href="http://www.cs.technion.ac.il/~biham/Reports/Tiger/">Tiger: A + * Fast New Hash Function</a>, Ross Anderson and Eli Biham.</a></li> + * </ol> + */ +public class Tiger extends BaseHash +{ + + // Constants and variables. + // ----------------------------------------------------------------------- + + private static final int HASH_SIZE = 24; + + private static final int BLOCK_SIZE = 64; + + /** Result when no data has been input. */ + private static final String DIGEST0 = "3293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3"; + + private static final long A = 0x0123456789ABCDEFL; + + private static final long B = 0xFEDCBA9876543210L; + + private static final long C = 0xF096A5B4C3B2E187L; + + /** S-Box T1. */ + private static final long[] T1 = { 0x02AAB17CF7E90C5EL, 0xAC424B03E243A8ECL, + 0x72CD5BE30DD5FCD3L, 0x6D019B93F6F97F3AL, + 0xCD9978FFD21F9193L, 0x7573A1C9708029E2L, + 0xB164326B922A83C3L, 0x46883EEE04915870L, + 0xEAACE3057103ECE6L, 0xC54169B808A3535CL, + 0x4CE754918DDEC47CL, 0x0AA2F4DFDC0DF40CL, + 0x10B76F18A74DBEFAL, 0xC6CCB6235AD1AB6AL, + 0x13726121572FE2FFL, 0x1A488C6F199D921EL, + 0x4BC9F9F4DA0007CAL, 0x26F5E6F6E85241C7L, + 0x859079DBEA5947B6L, 0x4F1885C5C99E8C92L, + 0xD78E761EA96F864BL, 0x8E36428C52B5C17DL, + 0x69CF6827373063C1L, 0xB607C93D9BB4C56EL, + 0x7D820E760E76B5EAL, 0x645C9CC6F07FDC42L, + 0xBF38A078243342E0L, 0x5F6B343C9D2E7D04L, + 0xF2C28AEB600B0EC6L, 0x6C0ED85F7254BCACL, + 0x71592281A4DB4FE5L, 0x1967FA69CE0FED9FL, + 0xFD5293F8B96545DBL, 0xC879E9D7F2A7600BL, + 0x860248920193194EL, 0xA4F9533B2D9CC0B3L, + 0x9053836C15957613L, 0xDB6DCF8AFC357BF1L, + 0x18BEEA7A7A370F57L, 0x037117CA50B99066L, + 0x6AB30A9774424A35L, 0xF4E92F02E325249BL, + 0x7739DB07061CCAE1L, 0xD8F3B49CECA42A05L, + 0xBD56BE3F51382F73L, 0x45FAED5843B0BB28L, + 0x1C813D5C11BF1F83L, 0x8AF0E4B6D75FA169L, + 0x33EE18A487AD9999L, 0x3C26E8EAB1C94410L, + 0xB510102BC0A822F9L, 0x141EEF310CE6123BL, + 0xFC65B90059DDB154L, 0xE0158640C5E0E607L, + 0x884E079826C3A3CFL, 0x930D0D9523C535FDL, + 0x35638D754E9A2B00L, 0x4085FCCF40469DD5L, + 0xC4B17AD28BE23A4CL, 0xCAB2F0FC6A3E6A2EL, + 0x2860971A6B943FCDL, 0x3DDE6EE212E30446L, + 0x6222F32AE01765AEL, 0x5D550BB5478308FEL, + 0xA9EFA98DA0EDA22AL, 0xC351A71686C40DA7L, + 0x1105586D9C867C84L, 0xDCFFEE85FDA22853L, + 0xCCFBD0262C5EEF76L, 0xBAF294CB8990D201L, + 0xE69464F52AFAD975L, 0x94B013AFDF133E14L, + 0x06A7D1A32823C958L, 0x6F95FE5130F61119L, + 0xD92AB34E462C06C0L, 0xED7BDE33887C71D2L, + 0x79746D6E6518393EL, 0x5BA419385D713329L, + 0x7C1BA6B948A97564L, 0x31987C197BFDAC67L, + 0xDE6C23C44B053D02L, 0x581C49FED002D64DL, + 0xDD474D6338261571L, 0xAA4546C3E473D062L, + 0x928FCE349455F860L, 0x48161BBACAAB94D9L, + 0x63912430770E6F68L, 0x6EC8A5E602C6641CL, + 0x87282515337DDD2BL, 0x2CDA6B42034B701BL, + 0xB03D37C181CB096DL, 0xE108438266C71C6FL, + 0x2B3180C7EB51B255L, 0xDF92B82F96C08BBCL, + 0x5C68C8C0A632F3BAL, 0x5504CC861C3D0556L, + 0xABBFA4E55FB26B8FL, 0x41848B0AB3BACEB4L, + 0xB334A273AA445D32L, 0xBCA696F0A85AD881L, + 0x24F6EC65B528D56CL, 0x0CE1512E90F4524AL, + 0x4E9DD79D5506D35AL, 0x258905FAC6CE9779L, + 0x2019295B3E109B33L, 0xF8A9478B73A054CCL, + 0x2924F2F934417EB0L, 0x3993357D536D1BC4L, + 0x38A81AC21DB6FF8BL, 0x47C4FBF17D6016BFL, + 0x1E0FAADD7667E3F5L, 0x7ABCFF62938BEB96L, + 0xA78DAD948FC179C9L, 0x8F1F98B72911E50DL, + 0x61E48EAE27121A91L, 0x4D62F7AD31859808L, + 0xECEBA345EF5CEAEBL, 0xF5CEB25EBC9684CEL, + 0xF633E20CB7F76221L, 0xA32CDF06AB8293E4L, + 0x985A202CA5EE2CA4L, 0xCF0B8447CC8A8FB1L, + 0x9F765244979859A3L, 0xA8D516B1A1240017L, + 0x0BD7BA3EBB5DC726L, 0xE54BCA55B86ADB39L, + 0x1D7A3AFD6C478063L, 0x519EC608E7669EDDL, + 0x0E5715A2D149AA23L, 0x177D4571848FF194L, + 0xEEB55F3241014C22L, 0x0F5E5CA13A6E2EC2L, + 0x8029927B75F5C361L, 0xAD139FABC3D6E436L, + 0x0D5DF1A94CCF402FL, 0x3E8BD948BEA5DFC8L, + 0xA5A0D357BD3FF77EL, 0xA2D12E251F74F645L, + 0x66FD9E525E81A082L, 0x2E0C90CE7F687A49L, + 0xC2E8BCBEBA973BC5L, 0x000001BCE509745FL, + 0x423777BBE6DAB3D6L, 0xD1661C7EAEF06EB5L, + 0xA1781F354DAACFD8L, 0x2D11284A2B16AFFCL, + 0xF1FC4F67FA891D1FL, 0x73ECC25DCB920ADAL, + 0xAE610C22C2A12651L, 0x96E0A810D356B78AL, + 0x5A9A381F2FE7870FL, 0xD5AD62EDE94E5530L, + 0xD225E5E8368D1427L, 0x65977B70C7AF4631L, + 0x99F889B2DE39D74FL, 0x233F30BF54E1D143L, + 0x9A9675D3D9A63C97L, 0x5470554FF334F9A8L, + 0x166ACB744A4F5688L, 0x70C74CAAB2E4AEADL, + 0xF0D091646F294D12L, 0x57B82A89684031D1L, + 0xEFD95A5A61BE0B6BL, 0x2FBD12E969F2F29AL, + 0x9BD37013FEFF9FE8L, 0x3F9B0404D6085A06L, + 0x4940C1F3166CFE15L, 0x09542C4DCDF3DEFBL, + 0xB4C5218385CD5CE3L, 0xC935B7DC4462A641L, + 0x3417F8A68ED3B63FL, 0xB80959295B215B40L, + 0xF99CDAEF3B8C8572L, 0x018C0614F8FCB95DL, + 0x1B14ACCD1A3ACDF3L, 0x84D471F200BB732DL, + 0xC1A3110E95E8DA16L, 0x430A7220BF1A82B8L, + 0xB77E090D39DF210EL, 0x5EF4BD9F3CD05E9DL, + 0x9D4FF6DA7E57A444L, 0xDA1D60E183D4A5F8L, + 0xB287C38417998E47L, 0xFE3EDC121BB31886L, + 0xC7FE3CCC980CCBEFL, 0xE46FB590189BFD03L, + 0x3732FD469A4C57DCL, 0x7EF700A07CF1AD65L, + 0x59C64468A31D8859L, 0x762FB0B4D45B61F6L, + 0x155BAED099047718L, 0x68755E4C3D50BAA6L, + 0xE9214E7F22D8B4DFL, 0x2ADDBF532EAC95F4L, + 0x32AE3909B4BD0109L, 0x834DF537B08E3450L, + 0xFA209DA84220728DL, 0x9E691D9B9EFE23F7L, + 0x0446D288C4AE8D7FL, 0x7B4CC524E169785BL, + 0x21D87F0135CA1385L, 0xCEBB400F137B8AA5L, + 0x272E2B66580796BEL, 0x3612264125C2B0DEL, + 0x057702BDAD1EFBB2L, 0xD4BABB8EACF84BE9L, + 0x91583139641BC67BL, 0x8BDC2DE08036E024L, + 0x603C8156F49F68EDL, 0xF7D236F7DBEF5111L, + 0x9727C4598AD21E80L, 0xA08A0896670A5FD7L, + 0xCB4A8F4309EBA9CBL, 0x81AF564B0F7036A1L, + 0xC0B99AA778199ABDL, 0x959F1EC83FC8E952L, + 0x8C505077794A81B9L, 0x3ACAAF8F056338F0L, + 0x07B43F50627A6778L, 0x4A44AB49F5ECCC77L, + 0x3BC3D6E4B679EE98L, 0x9CC0D4D1CF14108CL, + 0x4406C00B206BC8A0L, 0x82A18854C8D72D89L, + 0x67E366B35C3C432CL, 0xB923DD61102B37F2L, + 0x56AB2779D884271DL, 0xBE83E1B0FF1525AFL, + 0xFB7C65D4217E49A9L, 0x6BDBE0E76D48E7D4L, + 0x08DF828745D9179EL, 0x22EA6A9ADD53BD34L, + 0xE36E141C5622200AL, 0x7F805D1B8CB750EEL, + 0xAFE5C7A59F58E837L, 0xE27F996A4FB1C23CL, + 0xD3867DFB0775F0D0L, 0xD0E673DE6E88891AL, + 0x123AEB9EAFB86C25L, 0x30F1D5D5C145B895L, + 0xBB434A2DEE7269E7L, 0x78CB67ECF931FA38L, + 0xF33B0372323BBF9CL, 0x52D66336FB279C74L, + 0x505F33AC0AFB4EAAL, 0xE8A5CD99A2CCE187L, + 0x534974801E2D30BBL, 0x8D2D5711D5876D90L, + 0x1F1A412891BC038EL, 0xD6E2E71D82E56648L, + 0x74036C3A497732B7L, 0x89B67ED96361F5ABL, + 0xFFED95D8F1EA02A2L, 0xE72B3BD61464D43DL, + 0xA6300F170BDC4820L, 0xEBC18760ED78A77AL }; + + /** S-Box T2. */ + private static final long[] T2 = { 0xE6A6BE5A05A12138L, 0xB5A122A5B4F87C98L, + 0x563C6089140B6990L, 0x4C46CB2E391F5DD5L, + 0xD932ADDBC9B79434L, 0x08EA70E42015AFF5L, + 0xD765A6673E478CF1L, 0xC4FB757EAB278D99L, + 0xDF11C6862D6E0692L, 0xDDEB84F10D7F3B16L, + 0x6F2EF604A665EA04L, 0x4A8E0F0FF0E0DFB3L, + 0xA5EDEEF83DBCBA51L, 0xFC4F0A2A0EA4371EL, + 0xE83E1DA85CB38429L, 0xDC8FF882BA1B1CE2L, + 0xCD45505E8353E80DL, 0x18D19A00D4DB0717L, + 0x34A0CFEDA5F38101L, 0x0BE77E518887CAF2L, + 0x1E341438B3C45136L, 0xE05797F49089CCF9L, + 0xFFD23F9DF2591D14L, 0x543DDA228595C5CDL, + 0x661F81FD99052A33L, 0x8736E641DB0F7B76L, + 0x15227725418E5307L, 0xE25F7F46162EB2FAL, + 0x48A8B2126C13D9FEL, 0xAFDC541792E76EEAL, + 0x03D912BFC6D1898FL, 0x31B1AAFA1B83F51BL, + 0xF1AC2796E42AB7D9L, 0x40A3A7D7FCD2EBACL, + 0x1056136D0AFBBCC5L, 0x7889E1DD9A6D0C85L, + 0xD33525782A7974AAL, 0xA7E25D09078AC09BL, + 0xBD4138B3EAC6EDD0L, 0x920ABFBE71EB9E70L, + 0xA2A5D0F54FC2625CL, 0xC054E36B0B1290A3L, + 0xF6DD59FF62FE932BL, 0x3537354511A8AC7DL, + 0xCA845E9172FADCD4L, 0x84F82B60329D20DCL, + 0x79C62CE1CD672F18L, 0x8B09A2ADD124642CL, + 0xD0C1E96A19D9E726L, 0x5A786A9B4BA9500CL, + 0x0E020336634C43F3L, 0xC17B474AEB66D822L, + 0x6A731AE3EC9BAAC2L, 0x8226667AE0840258L, + 0x67D4567691CAECA5L, 0x1D94155C4875ADB5L, + 0x6D00FD985B813FDFL, 0x51286EFCB774CD06L, + 0x5E8834471FA744AFL, 0xF72CA0AEE761AE2EL, + 0xBE40E4CDAEE8E09AL, 0xE9970BBB5118F665L, + 0x726E4BEB33DF1964L, 0x703B000729199762L, + 0x4631D816F5EF30A7L, 0xB880B5B51504A6BEL, + 0x641793C37ED84B6CL, 0x7B21ED77F6E97D96L, + 0x776306312EF96B73L, 0xAE528948E86FF3F4L, + 0x53DBD7F286A3F8F8L, 0x16CADCE74CFC1063L, + 0x005C19BDFA52C6DDL, 0x68868F5D64D46AD3L, + 0x3A9D512CCF1E186AL, 0x367E62C2385660AEL, + 0xE359E7EA77DCB1D7L, 0x526C0773749ABE6EL, + 0x735AE5F9D09F734BL, 0x493FC7CC8A558BA8L, + 0xB0B9C1533041AB45L, 0x321958BA470A59BDL, + 0x852DB00B5F46C393L, 0x91209B2BD336B0E5L, + 0x6E604F7D659EF19FL, 0xB99A8AE2782CCB24L, + 0xCCF52AB6C814C4C7L, 0x4727D9AFBE11727BL, + 0x7E950D0C0121B34DL, 0x756F435670AD471FL, + 0xF5ADD442615A6849L, 0x4E87E09980B9957AL, + 0x2ACFA1DF50AEE355L, 0xD898263AFD2FD556L, + 0xC8F4924DD80C8FD6L, 0xCF99CA3D754A173AL, + 0xFE477BACAF91BF3CL, 0xED5371F6D690C12DL, + 0x831A5C285E687094L, 0xC5D3C90A3708A0A4L, + 0x0F7F903717D06580L, 0x19F9BB13B8FDF27FL, + 0xB1BD6F1B4D502843L, 0x1C761BA38FFF4012L, + 0x0D1530C4E2E21F3BL, 0x8943CE69A7372C8AL, + 0xE5184E11FEB5CE66L, 0x618BDB80BD736621L, + 0x7D29BAD68B574D0BL, 0x81BB613E25E6FE5BL, + 0x071C9C10BC07913FL, 0xC7BEEB7909AC2D97L, + 0xC3E58D353BC5D757L, 0xEB017892F38F61E8L, + 0xD4EFFB9C9B1CC21AL, 0x99727D26F494F7ABL, + 0xA3E063A2956B3E03L, 0x9D4A8B9A4AA09C30L, + 0x3F6AB7D500090FB4L, 0x9CC0F2A057268AC0L, + 0x3DEE9D2DEDBF42D1L, 0x330F49C87960A972L, + 0xC6B2720287421B41L, 0x0AC59EC07C00369CL, + 0xEF4EAC49CB353425L, 0xF450244EEF0129D8L, + 0x8ACC46E5CAF4DEB6L, 0x2FFEAB63989263F7L, + 0x8F7CB9FE5D7A4578L, 0x5BD8F7644E634635L, + 0x427A7315BF2DC900L, 0x17D0C4AA2125261CL, + 0x3992486C93518E50L, 0xB4CBFEE0A2D7D4C3L, + 0x7C75D6202C5DDD8DL, 0xDBC295D8E35B6C61L, + 0x60B369D302032B19L, 0xCE42685FDCE44132L, + 0x06F3DDB9DDF65610L, 0x8EA4D21DB5E148F0L, + 0x20B0FCE62FCD496FL, 0x2C1B912358B0EE31L, + 0xB28317B818F5A308L, 0xA89C1E189CA6D2CFL, + 0x0C6B18576AAADBC8L, 0xB65DEAA91299FAE3L, + 0xFB2B794B7F1027E7L, 0x04E4317F443B5BEBL, + 0x4B852D325939D0A6L, 0xD5AE6BEEFB207FFCL, + 0x309682B281C7D374L, 0xBAE309A194C3B475L, + 0x8CC3F97B13B49F05L, 0x98A9422FF8293967L, + 0x244B16B01076FF7CL, 0xF8BF571C663D67EEL, + 0x1F0D6758EEE30DA1L, 0xC9B611D97ADEB9B7L, + 0xB7AFD5887B6C57A2L, 0x6290AE846B984FE1L, + 0x94DF4CDEACC1A5FDL, 0x058A5BD1C5483AFFL, + 0x63166CC142BA3C37L, 0x8DB8526EB2F76F40L, + 0xE10880036F0D6D4EL, 0x9E0523C9971D311DL, + 0x45EC2824CC7CD691L, 0x575B8359E62382C9L, + 0xFA9E400DC4889995L, 0xD1823ECB45721568L, + 0xDAFD983B8206082FL, 0xAA7D29082386A8CBL, + 0x269FCD4403B87588L, 0x1B91F5F728BDD1E0L, + 0xE4669F39040201F6L, 0x7A1D7C218CF04ADEL, + 0x65623C29D79CE5CEL, 0x2368449096C00BB1L, + 0xAB9BF1879DA503BAL, 0xBC23ECB1A458058EL, + 0x9A58DF01BB401ECCL, 0xA070E868A85F143DL, + 0x4FF188307DF2239EL, 0x14D565B41A641183L, + 0xEE13337452701602L, 0x950E3DCF3F285E09L, + 0x59930254B9C80953L, 0x3BF299408930DA6DL, + 0xA955943F53691387L, 0xA15EDECAA9CB8784L, + 0x29142127352BE9A0L, 0x76F0371FFF4E7AFBL, + 0x0239F450274F2228L, 0xBB073AF01D5E868BL, + 0xBFC80571C10E96C1L, 0xD267088568222E23L, + 0x9671A3D48E80B5B0L, 0x55B5D38AE193BB81L, + 0x693AE2D0A18B04B8L, 0x5C48B4ECADD5335FL, + 0xFD743B194916A1CAL, 0x2577018134BE98C4L, + 0xE77987E83C54A4ADL, 0x28E11014DA33E1B9L, + 0x270CC59E226AA213L, 0x71495F756D1A5F60L, + 0x9BE853FB60AFEF77L, 0xADC786A7F7443DBFL, + 0x0904456173B29A82L, 0x58BC7A66C232BD5EL, + 0xF306558C673AC8B2L, 0x41F639C6B6C9772AL, + 0x216DEFE99FDA35DAL, 0x11640CC71C7BE615L, + 0x93C43694565C5527L, 0xEA038E6246777839L, + 0xF9ABF3CE5A3E2469L, 0x741E768D0FD312D2L, + 0x0144B883CED652C6L, 0xC20B5A5BA33F8552L, + 0x1AE69633C3435A9DL, 0x97A28CA4088CFDECL, + 0x8824A43C1E96F420L, 0x37612FA66EEEA746L, + 0x6B4CB165F9CF0E5AL, 0x43AA1C06A0ABFB4AL, + 0x7F4DC26FF162796BL, 0x6CBACC8E54ED9B0FL, + 0xA6B7FFEFD2BB253EL, 0x2E25BC95B0A29D4FL, + 0x86D6A58BDEF1388CL, 0xDED74AC576B6F054L, + 0x8030BDBC2B45805DL, 0x3C81AF70E94D9289L, + 0x3EFF6DDA9E3100DBL, 0xB38DC39FDFCC8847L, + 0x123885528D17B87EL, 0xF2DA0ED240B1B642L, + 0x44CEFADCD54BF9A9L, 0x1312200E433C7EE6L, + 0x9FFCC84F3A78C748L, 0xF0CD1F72248576BBL, + 0xEC6974053638CFE4L, 0x2BA7B67C0CEC4E4CL, + 0xAC2F4DF3E5CE32EDL, 0xCB33D14326EA4C11L, + 0xA4E9044CC77E58BCL, 0x5F513293D934FCEFL, + 0x5DC9645506E55444L, 0x50DE418F317DE40AL, + 0x388CB31A69DDE259L, 0x2DB4A83455820A86L, + 0x9010A91E84711AE9L, 0x4DF7F0B7B1498371L, + 0xD62A2EABC0977179L, 0x22FAC097AA8D5C0EL }; + + /** S-Box T3. */ + private static final long[] T3 = { 0xF49FCC2FF1DAF39BL, 0x487FD5C66FF29281L, + 0xE8A30667FCDCA83FL, 0x2C9B4BE3D2FCCE63L, + 0xDA3FF74B93FBBBC2L, 0x2FA165D2FE70BA66L, + 0xA103E279970E93D4L, 0xBECDEC77B0E45E71L, + 0xCFB41E723985E497L, 0xB70AAA025EF75017L, + 0xD42309F03840B8E0L, 0x8EFC1AD035898579L, + 0x96C6920BE2B2ABC5L, 0x66AF4163375A9172L, + 0x2174ABDCCA7127FBL, 0xB33CCEA64A72FF41L, + 0xF04A4933083066A5L, 0x8D970ACDD7289AF5L, + 0x8F96E8E031C8C25EL, 0xF3FEC02276875D47L, + 0xEC7BF310056190DDL, 0xF5ADB0AEBB0F1491L, + 0x9B50F8850FD58892L, 0x4975488358B74DE8L, + 0xA3354FF691531C61L, 0x0702BBE481D2C6EEL, + 0x89FB24057DEDED98L, 0xAC3075138596E902L, + 0x1D2D3580172772EDL, 0xEB738FC28E6BC30DL, + 0x5854EF8F63044326L, 0x9E5C52325ADD3BBEL, + 0x90AA53CF325C4623L, 0xC1D24D51349DD067L, + 0x2051CFEEA69EA624L, 0x13220F0A862E7E4FL, + 0xCE39399404E04864L, 0xD9C42CA47086FCB7L, + 0x685AD2238A03E7CCL, 0x066484B2AB2FF1DBL, + 0xFE9D5D70EFBF79ECL, 0x5B13B9DD9C481854L, + 0x15F0D475ED1509ADL, 0x0BEBCD060EC79851L, + 0xD58C6791183AB7F8L, 0xD1187C5052F3EEE4L, + 0xC95D1192E54E82FFL, 0x86EEA14CB9AC6CA2L, + 0x3485BEB153677D5DL, 0xDD191D781F8C492AL, + 0xF60866BAA784EBF9L, 0x518F643BA2D08C74L, + 0x8852E956E1087C22L, 0xA768CB8DC410AE8DL, + 0x38047726BFEC8E1AL, 0xA67738B4CD3B45AAL, + 0xAD16691CEC0DDE19L, 0xC6D4319380462E07L, + 0xC5A5876D0BA61938L, 0x16B9FA1FA58FD840L, + 0x188AB1173CA74F18L, 0xABDA2F98C99C021FL, + 0x3E0580AB134AE816L, 0x5F3B05B773645ABBL, + 0x2501A2BE5575F2F6L, 0x1B2F74004E7E8BA9L, + 0x1CD7580371E8D953L, 0x7F6ED89562764E30L, + 0xB15926FF596F003DL, 0x9F65293DA8C5D6B9L, + 0x6ECEF04DD690F84CL, 0x4782275FFF33AF88L, + 0xE41433083F820801L, 0xFD0DFE409A1AF9B5L, + 0x4325A3342CDB396BL, 0x8AE77E62B301B252L, + 0xC36F9E9F6655615AL, 0x85455A2D92D32C09L, + 0xF2C7DEA949477485L, 0x63CFB4C133A39EBAL, + 0x83B040CC6EBC5462L, 0x3B9454C8FDB326B0L, + 0x56F56A9E87FFD78CL, 0x2DC2940D99F42BC6L, + 0x98F7DF096B096E2DL, 0x19A6E01E3AD852BFL, + 0x42A99CCBDBD4B40BL, 0xA59998AF45E9C559L, + 0x366295E807D93186L, 0x6B48181BFAA1F773L, + 0x1FEC57E2157A0A1DL, 0x4667446AF6201AD5L, + 0xE615EBCACFB0F075L, 0xB8F31F4F68290778L, + 0x22713ED6CE22D11EL, 0x3057C1A72EC3C93BL, + 0xCB46ACC37C3F1F2FL, 0xDBB893FD02AAF50EL, + 0x331FD92E600B9FCFL, 0xA498F96148EA3AD6L, + 0xA8D8426E8B6A83EAL, 0xA089B274B7735CDCL, + 0x87F6B3731E524A11L, 0x118808E5CBC96749L, + 0x9906E4C7B19BD394L, 0xAFED7F7E9B24A20CL, + 0x6509EADEEB3644A7L, 0x6C1EF1D3E8EF0EDEL, + 0xB9C97D43E9798FB4L, 0xA2F2D784740C28A3L, + 0x7B8496476197566FL, 0x7A5BE3E6B65F069DL, + 0xF96330ED78BE6F10L, 0xEEE60DE77A076A15L, + 0x2B4BEE4AA08B9BD0L, 0x6A56A63EC7B8894EL, + 0x02121359BA34FEF4L, 0x4CBF99F8283703FCL, + 0x398071350CAF30C8L, 0xD0A77A89F017687AL, + 0xF1C1A9EB9E423569L, 0x8C7976282DEE8199L, + 0x5D1737A5DD1F7ABDL, 0x4F53433C09A9FA80L, + 0xFA8B0C53DF7CA1D9L, 0x3FD9DCBC886CCB77L, + 0xC040917CA91B4720L, 0x7DD00142F9D1DCDFL, + 0x8476FC1D4F387B58L, 0x23F8E7C5F3316503L, + 0x032A2244E7E37339L, 0x5C87A5D750F5A74BL, + 0x082B4CC43698992EL, 0xDF917BECB858F63CL, + 0x3270B8FC5BF86DDAL, 0x10AE72BB29B5DD76L, + 0x576AC94E7700362BL, 0x1AD112DAC61EFB8FL, + 0x691BC30EC5FAA427L, 0xFF246311CC327143L, + 0x3142368E30E53206L, 0x71380E31E02CA396L, + 0x958D5C960AAD76F1L, 0xF8D6F430C16DA536L, + 0xC8FFD13F1BE7E1D2L, 0x7578AE66004DDBE1L, + 0x05833F01067BE646L, 0xBB34B5AD3BFE586DL, + 0x095F34C9A12B97F0L, 0x247AB64525D60CA8L, + 0xDCDBC6F3017477D1L, 0x4A2E14D4DECAD24DL, + 0xBDB5E6D9BE0A1EEBL, 0x2A7E70F7794301ABL, + 0xDEF42D8A270540FDL, 0x01078EC0A34C22C1L, + 0xE5DE511AF4C16387L, 0x7EBB3A52BD9A330AL, + 0x77697857AA7D6435L, 0x004E831603AE4C32L, + 0xE7A21020AD78E312L, 0x9D41A70C6AB420F2L, + 0x28E06C18EA1141E6L, 0xD2B28CBD984F6B28L, + 0x26B75F6C446E9D83L, 0xBA47568C4D418D7FL, + 0xD80BADBFE6183D8EL, 0x0E206D7F5F166044L, + 0xE258A43911CBCA3EL, 0x723A1746B21DC0BCL, + 0xC7CAA854F5D7CDD3L, 0x7CAC32883D261D9CL, + 0x7690C26423BA942CL, 0x17E55524478042B8L, + 0xE0BE477656A2389FL, 0x4D289B5E67AB2DA0L, + 0x44862B9C8FBBFD31L, 0xB47CC8049D141365L, + 0x822C1B362B91C793L, 0x4EB14655FB13DFD8L, + 0x1ECBBA0714E2A97BL, 0x6143459D5CDE5F14L, + 0x53A8FBF1D5F0AC89L, 0x97EA04D81C5E5B00L, + 0x622181A8D4FDB3F3L, 0xE9BCD341572A1208L, + 0x1411258643CCE58AL, 0x9144C5FEA4C6E0A4L, + 0x0D33D06565CF620FL, 0x54A48D489F219CA1L, + 0xC43E5EAC6D63C821L, 0xA9728B3A72770DAFL, + 0xD7934E7B20DF87EFL, 0xE35503B61A3E86E5L, + 0xCAE321FBC819D504L, 0x129A50B3AC60BFA6L, + 0xCD5E68EA7E9FB6C3L, 0xB01C90199483B1C7L, + 0x3DE93CD5C295376CL, 0xAED52EDF2AB9AD13L, + 0x2E60F512C0A07884L, 0xBC3D86A3E36210C9L, + 0x35269D9B163951CEL, 0x0C7D6E2AD0CDB5FAL, + 0x59E86297D87F5733L, 0x298EF221898DB0E7L, + 0x55000029D1A5AA7EL, 0x8BC08AE1B5061B45L, + 0xC2C31C2B6C92703AL, 0x94CC596BAF25EF42L, + 0x0A1D73DB22540456L, 0x04B6A0F9D9C4179AL, + 0xEFFDAFA2AE3D3C60L, 0xF7C8075BB49496C4L, + 0x9CC5C7141D1CD4E3L, 0x78BD1638218E5534L, + 0xB2F11568F850246AL, 0xEDFABCFA9502BC29L, + 0x796CE5F2DA23051BL, 0xAAE128B0DC93537CL, + 0x3A493DA0EE4B29AEL, 0xB5DF6B2C416895D7L, + 0xFCABBD25122D7F37L, 0x70810B58105DC4B1L, + 0xE10FDD37F7882A90L, 0x524DCAB5518A3F5CL, + 0x3C9E85878451255BL, 0x4029828119BD34E2L, + 0x74A05B6F5D3CECCBL, 0xB610021542E13ECAL, + 0x0FF979D12F59E2ACL, 0x6037DA27E4F9CC50L, + 0x5E92975A0DF1847DL, 0xD66DE190D3E623FEL, + 0x5032D6B87B568048L, 0x9A36B7CE8235216EL, + 0x80272A7A24F64B4AL, 0x93EFED8B8C6916F7L, + 0x37DDBFF44CCE1555L, 0x4B95DB5D4B99BD25L, + 0x92D3FDA169812FC0L, 0xFB1A4A9A90660BB6L, + 0x730C196946A4B9B2L, 0x81E289AA7F49DA68L, + 0x64669A0F83B1A05FL, 0x27B3FF7D9644F48BL, + 0xCC6B615C8DB675B3L, 0x674F20B9BCEBBE95L, + 0x6F31238275655982L, 0x5AE488713E45CF05L, + 0xBF619F9954C21157L, 0xEABAC46040A8EAE9L, + 0x454C6FE9F2C0C1CDL, 0x419CF6496412691CL, + 0xD3DC3BEF265B0F70L, 0x6D0E60F5C3578A9EL }; + + /** S-Box T4. */ + private static final long[] T4 = { 0x5B0E608526323C55L, 0x1A46C1A9FA1B59F5L, + 0xA9E245A17C4C8FFAL, 0x65CA5159DB2955D7L, + 0x05DB0A76CE35AFC2L, 0x81EAC77EA9113D45L, + 0x528EF88AB6AC0A0DL, 0xA09EA253597BE3FFL, + 0x430DDFB3AC48CD56L, 0xC4B3A67AF45CE46FL, + 0x4ECECFD8FBE2D05EL, 0x3EF56F10B39935F0L, + 0x0B22D6829CD619C6L, 0x17FD460A74DF2069L, + 0x6CF8CC8E8510ED40L, 0xD6C824BF3A6ECAA7L, + 0x61243D581A817049L, 0x048BACB6BBC163A2L, + 0xD9A38AC27D44CC32L, 0x7FDDFF5BAAF410ABL, + 0xAD6D495AA804824BL, 0xE1A6A74F2D8C9F94L, + 0xD4F7851235DEE8E3L, 0xFD4B7F886540D893L, + 0x247C20042AA4BFDAL, 0x096EA1C517D1327CL, + 0xD56966B4361A6685L, 0x277DA5C31221057DL, + 0x94D59893A43ACFF7L, 0x64F0C51CCDC02281L, + 0x3D33BCC4FF6189DBL, 0xE005CB184CE66AF1L, + 0xFF5CCD1D1DB99BEAL, 0xB0B854A7FE42980FL, + 0x7BD46A6A718D4B9FL, 0xD10FA8CC22A5FD8CL, + 0xD31484952BE4BD31L, 0xC7FA975FCB243847L, + 0x4886ED1E5846C407L, 0x28CDDB791EB70B04L, + 0xC2B00BE2F573417FL, 0x5C9590452180F877L, + 0x7A6BDDFFF370EB00L, 0xCE509E38D6D9D6A4L, + 0xEBEB0F00647FA702L, 0x1DCC06CF76606F06L, + 0xE4D9F28BA286FF0AL, 0xD85A305DC918C262L, + 0x475B1D8732225F54L, 0x2D4FB51668CCB5FEL, + 0xA679B9D9D72BBA20L, 0x53841C0D912D43A5L, + 0x3B7EAA48BF12A4E8L, 0x781E0E47F22F1DDFL, + 0xEFF20CE60AB50973L, 0x20D261D19DFFB742L, + 0x16A12B03062A2E39L, 0x1960EB2239650495L, + 0x251C16FED50EB8B8L, 0x9AC0C330F826016EL, + 0xED152665953E7671L, 0x02D63194A6369570L, + 0x5074F08394B1C987L, 0x70BA598C90B25CE1L, + 0x794A15810B9742F6L, 0x0D5925E9FCAF8C6CL, + 0x3067716CD868744EL, 0x910AB077E8D7731BL, + 0x6A61BBDB5AC42F61L, 0x93513EFBF0851567L, + 0xF494724B9E83E9D5L, 0xE887E1985C09648DL, + 0x34B1D3C675370CFDL, 0xDC35E433BC0D255DL, + 0xD0AAB84234131BE0L, 0x08042A50B48B7EAFL, + 0x9997C4EE44A3AB35L, 0x829A7B49201799D0L, + 0x263B8307B7C54441L, 0x752F95F4FD6A6CA6L, + 0x927217402C08C6E5L, 0x2A8AB754A795D9EEL, + 0xA442F7552F72943DL, 0x2C31334E19781208L, + 0x4FA98D7CEAEE6291L, 0x55C3862F665DB309L, + 0xBD0610175D53B1F3L, 0x46FE6CB840413F27L, + 0x3FE03792DF0CFA59L, 0xCFE700372EB85E8FL, + 0xA7BE29E7ADBCE118L, 0xE544EE5CDE8431DDL, + 0x8A781B1B41F1873EL, 0xA5C94C78A0D2F0E7L, + 0x39412E2877B60728L, 0xA1265EF3AFC9A62CL, + 0xBCC2770C6A2506C5L, 0x3AB66DD5DCE1CE12L, + 0xE65499D04A675B37L, 0x7D8F523481BFD216L, + 0x0F6F64FCEC15F389L, 0x74EFBE618B5B13C8L, + 0xACDC82B714273E1DL, 0xDD40BFE003199D17L, + 0x37E99257E7E061F8L, 0xFA52626904775AAAL, + 0x8BBBF63A463D56F9L, 0xF0013F1543A26E64L, + 0xA8307E9F879EC898L, 0xCC4C27A4150177CCL, + 0x1B432F2CCA1D3348L, 0xDE1D1F8F9F6FA013L, + 0x606602A047A7DDD6L, 0xD237AB64CC1CB2C7L, + 0x9B938E7225FCD1D3L, 0xEC4E03708E0FF476L, + 0xFEB2FBDA3D03C12DL, 0xAE0BCED2EE43889AL, + 0x22CB8923EBFB4F43L, 0x69360D013CF7396DL, + 0x855E3602D2D4E022L, 0x073805BAD01F784CL, + 0x33E17A133852F546L, 0xDF4874058AC7B638L, + 0xBA92B29C678AA14AL, 0x0CE89FC76CFAADCDL, + 0x5F9D4E0908339E34L, 0xF1AFE9291F5923B9L, + 0x6E3480F60F4A265FL, 0xEEBF3A2AB29B841CL, + 0xE21938A88F91B4ADL, 0x57DFEFF845C6D3C3L, + 0x2F006B0BF62CAAF2L, 0x62F479EF6F75EE78L, + 0x11A55AD41C8916A9L, 0xF229D29084FED453L, + 0x42F1C27B16B000E6L, 0x2B1F76749823C074L, + 0x4B76ECA3C2745360L, 0x8C98F463B91691BDL, + 0x14BCC93CF1ADE66AL, 0x8885213E6D458397L, + 0x8E177DF0274D4711L, 0xB49B73B5503F2951L, + 0x10168168C3F96B6BL, 0x0E3D963B63CAB0AEL, + 0x8DFC4B5655A1DB14L, 0xF789F1356E14DE5CL, + 0x683E68AF4E51DAC1L, 0xC9A84F9D8D4B0FD9L, + 0x3691E03F52A0F9D1L, 0x5ED86E46E1878E80L, + 0x3C711A0E99D07150L, 0x5A0865B20C4E9310L, + 0x56FBFC1FE4F0682EL, 0xEA8D5DE3105EDF9BL, + 0x71ABFDB12379187AL, 0x2EB99DE1BEE77B9CL, + 0x21ECC0EA33CF4523L, 0x59A4D7521805C7A1L, + 0x3896F5EB56AE7C72L, 0xAA638F3DB18F75DCL, + 0x9F39358DABE9808EL, 0xB7DEFA91C00B72ACL, + 0x6B5541FD62492D92L, 0x6DC6DEE8F92E4D5BL, + 0x353F57ABC4BEEA7EL, 0x735769D6DA5690CEL, + 0x0A234AA642391484L, 0xF6F9508028F80D9DL, + 0xB8E319A27AB3F215L, 0x31AD9C1151341A4DL, + 0x773C22A57BEF5805L, 0x45C7561A07968633L, + 0xF913DA9E249DBE36L, 0xDA652D9B78A64C68L, + 0x4C27A97F3BC334EFL, 0x76621220E66B17F4L, + 0x967743899ACD7D0BL, 0xF3EE5BCAE0ED6782L, + 0x409F753600C879FCL, 0x06D09A39B5926DB6L, + 0x6F83AEB0317AC588L, 0x01E6CA4A86381F21L, + 0x66FF3462D19F3025L, 0x72207C24DDFD3BFBL, + 0x4AF6B6D3E2ECE2EBL, 0x9C994DBEC7EA08DEL, + 0x49ACE597B09A8BC4L, 0xB38C4766CF0797BAL, + 0x131B9373C57C2A75L, 0xB1822CCE61931E58L, + 0x9D7555B909BA1C0CL, 0x127FAFDD937D11D2L, + 0x29DA3BADC66D92E4L, 0xA2C1D57154C2ECBCL, + 0x58C5134D82F6FE24L, 0x1C3AE3515B62274FL, + 0xE907C82E01CB8126L, 0xF8ED091913E37FCBL, + 0x3249D8F9C80046C9L, 0x80CF9BEDE388FB63L, + 0x1881539A116CF19EL, 0x5103F3F76BD52457L, + 0x15B7E6F5AE47F7A8L, 0xDBD7C6DED47E9CCFL, + 0x44E55C410228BB1AL, 0xB647D4255EDB4E99L, + 0x5D11882BB8AAFC30L, 0xF5098BBB29D3212AL, + 0x8FB5EA14E90296B3L, 0x677B942157DD025AL, + 0xFB58E7C0A390ACB5L, 0x89D3674C83BD4A01L, + 0x9E2DA4DF4BF3B93BL, 0xFCC41E328CAB4829L, + 0x03F38C96BA582C52L, 0xCAD1BDBD7FD85DB2L, + 0xBBB442C16082AE83L, 0xB95FE86BA5DA9AB0L, + 0xB22E04673771A93FL, 0x845358C9493152D8L, + 0xBE2A488697B4541EL, 0x95A2DC2DD38E6966L, + 0xC02C11AC923C852BL, 0x2388B1990DF2A87BL, + 0x7C8008FA1B4F37BEL, 0x1F70D0C84D54E503L, + 0x5490ADEC7ECE57D4L, 0x002B3C27D9063A3AL, + 0x7EAEA3848030A2BFL, 0xC602326DED2003C0L, + 0x83A7287D69A94086L, 0xC57A5FCB30F57A8AL, + 0xB56844E479EBE779L, 0xA373B40F05DCBCE9L, + 0xD71A786E88570EE2L, 0x879CBACDBDE8F6A0L, + 0x976AD1BCC164A32FL, 0xAB21E25E9666D78BL, + 0x901063AAE5E5C33CL, 0x9818B34448698D90L, + 0xE36487AE3E1E8ABBL, 0xAFBDF931893BDCB4L, + 0x6345A0DC5FBBD519L, 0x8628FE269B9465CAL, + 0x1E5D01603F9C51ECL, 0x4DE44006A15049B7L, + 0xBF6C70E5F776CBB1L, 0x411218F2EF552BEDL, + 0xCB0C0708705A36A3L, 0xE74D14754F986044L, + 0xCD56D9430EA8280EL, 0xC12591D7535F5065L, + 0xC83223F1720AEF96L, 0xC3A0396F7363A51FL }; + + // The cached self-test result. + private static Boolean valid; + + // The context. + private long a, b, c; + + // Constructors. + // ----------------------------------------------------------------------- + + /** + * Trivial 0-arguments constructor. + */ + public Tiger() + { + super(Registry.TIGER_HASH, HASH_SIZE, BLOCK_SIZE); + } + + /** + * Private copying constructor for cloning. + * + * @param that The instance being cloned. + */ + private Tiger(Tiger that) + { + this(); + this.a = that.a; + this.b = that.b; + this.c = that.c; + this.count = that.count; + this.buffer = (that.buffer != null) ? (byte[]) that.buffer.clone() : null; + } + + // Instance methods implementing BaseHash. + // ----------------------------------------------------------------------- + + public Object clone() + { + return new Tiger(this); + } + + public boolean selfTest() + { + if (valid == null) + { + valid = new Boolean(DIGEST0.equals(Util.toString(new Tiger().digest()))); + } + return valid.booleanValue(); + } + + protected byte[] padBuffer() + { + int n = (int) (count % BLOCK_SIZE); + int padding = (n < 56) ? (56 - n) : (120 - n); + byte[] pad = new byte[padding + 8]; + + pad[0] = 1; + long bits = count << 3; + + pad[padding++] = (byte) bits; + pad[padding++] = (byte) (bits >>> 8); + pad[padding++] = (byte) (bits >>> 16); + pad[padding++] = (byte) (bits >>> 24); + pad[padding++] = (byte) (bits >>> 32); + pad[padding++] = (byte) (bits >>> 40); + pad[padding++] = (byte) (bits >>> 48); + pad[padding] = (byte) (bits >>> 56); + + return pad; + } + + protected byte[] getResult() + { + return new byte[] { (byte) a, (byte) (a >>> 8), (byte) (a >>> 16), + (byte) (a >>> 24), (byte) (a >>> 32), (byte) (a >>> 40), + (byte) (a >>> 48), (byte) (a >>> 56), (byte) b, + (byte) (b >>> 8), (byte) (b >>> 16), (byte) (b >>> 24), + (byte) (b >>> 32), (byte) (b >>> 40), (byte) (b >>> 48), + (byte) (b >>> 56), (byte) c, (byte) (c >>> 8), + (byte) (c >>> 16), (byte) (c >>> 24), (byte) (c >>> 32), + (byte) (c >>> 40), (byte) (c >>> 48), (byte) (c >>> 56) }; + } + + protected void resetContext() + { + a = A; + b = B; + c = C; + } + + protected void transform(byte[] in, int offset) + { + long x0, x1, x2, x3, x4, x5, x6, x7; + + x0 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8) + | ((long) (in[offset++] & 0xFF) << 16) + | ((long) (in[offset++] & 0xFF) << 24) + | ((long) (in[offset++] & 0xFF) << 32) + | ((long) (in[offset++] & 0xFF) << 40) + | ((long) (in[offset++] & 0xFF) << 48) + | ((long) (in[offset++] & 0xFF) << 56); + x1 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8) + | ((long) (in[offset++] & 0xFF) << 16) + | ((long) (in[offset++] & 0xFF) << 24) + | ((long) (in[offset++] & 0xFF) << 32) + | ((long) (in[offset++] & 0xFF) << 40) + | ((long) (in[offset++] & 0xFF) << 48) + | ((long) (in[offset++] & 0xFF) << 56); + x2 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8) + | ((long) (in[offset++] & 0xFF) << 16) + | ((long) (in[offset++] & 0xFF) << 24) + | ((long) (in[offset++] & 0xFF) << 32) + | ((long) (in[offset++] & 0xFF) << 40) + | ((long) (in[offset++] & 0xFF) << 48) + | ((long) (in[offset++] & 0xFF) << 56); + x3 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8) + | ((long) (in[offset++] & 0xFF) << 16) + | ((long) (in[offset++] & 0xFF) << 24) + | ((long) (in[offset++] & 0xFF) << 32) + | ((long) (in[offset++] & 0xFF) << 40) + | ((long) (in[offset++] & 0xFF) << 48) + | ((long) (in[offset++] & 0xFF) << 56); + x4 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8) + | ((long) (in[offset++] & 0xFF) << 16) + | ((long) (in[offset++] & 0xFF) << 24) + | ((long) (in[offset++] & 0xFF) << 32) + | ((long) (in[offset++] & 0xFF) << 40) + | ((long) (in[offset++] & 0xFF) << 48) + | ((long) (in[offset++] & 0xFF) << 56); + x5 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8) + | ((long) (in[offset++] & 0xFF) << 16) + | ((long) (in[offset++] & 0xFF) << 24) + | ((long) (in[offset++] & 0xFF) << 32) + | ((long) (in[offset++] & 0xFF) << 40) + | ((long) (in[offset++] & 0xFF) << 48) + | ((long) (in[offset++] & 0xFF) << 56); + x6 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8) + | ((long) (in[offset++] & 0xFF) << 16) + | ((long) (in[offset++] & 0xFF) << 24) + | ((long) (in[offset++] & 0xFF) << 32) + | ((long) (in[offset++] & 0xFF) << 40) + | ((long) (in[offset++] & 0xFF) << 48) + | ((long) (in[offset++] & 0xFF) << 56); + x7 = ((long) in[offset++] & 0xFF) | ((long) (in[offset++] & 0xFF) << 8) + | ((long) (in[offset++] & 0xFF) << 16) + | ((long) (in[offset++] & 0xFF) << 24) + | ((long) (in[offset++] & 0xFF) << 32) + | ((long) (in[offset++] & 0xFF) << 40) + | ((long) (in[offset++] & 0xFF) << 48) + | ((long) (in[offset] & 0xFF) << 56); + + // save_abc ::= + long aa = a, bb = b, cc = c; + + // pass(aa, bb, cc, 5) ::= + cc ^= x0; + aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff] + ^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff]; + bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff] + ^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff]; + bb *= 5; + aa ^= x1; + bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff] + ^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff]; + cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff] + ^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff]; + cc *= 5; + bb ^= x2; + cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff] + ^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff]; + aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff] + ^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff]; + aa *= 5; + cc ^= x3; + aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff] + ^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff]; + bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff] + ^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff]; + bb *= 5; + aa ^= x4; + bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff] + ^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff]; + cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff] + ^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff]; + cc *= 5; + bb ^= x5; + cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff] + ^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff]; + aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff] + ^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff]; + aa *= 5; + cc ^= x6; + aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff] + ^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff]; + bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff] + ^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff]; + bb *= 5; + aa ^= x7; + bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff] + ^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff]; + cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff] + ^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff]; + cc *= 5; + + // key_schedule ::= + x0 -= x7 ^ 0xA5A5A5A5A5A5A5A5L; + x1 ^= x0; + x2 += x1; + x3 -= x2 ^ ((~x1) << 19); + x4 ^= x3; + x5 += x4; + x6 -= x5 ^ ((~x4) >>> 23); + x7 ^= x6; + x0 += x7; + x1 -= x0 ^ ((~x7) << 19); + x2 ^= x1; + x3 += x2; + x4 -= x3 ^ ((~x2) >>> 23); + x5 ^= x4; + x6 += x5; + x7 -= x6 ^ 0x0123456789ABCDEFL; + + // pass(cc, aa, bb, 7) ::= + bb ^= x0; + cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff] + ^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff]; + aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff] + ^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff]; + aa *= 7; + cc ^= x1; + aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff] + ^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff]; + bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff] + ^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff]; + bb *= 7; + aa ^= x2; + bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff] + ^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff]; + cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff] + ^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff]; + cc *= 7; + bb ^= x3; + cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff] + ^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff]; + aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff] + ^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff]; + aa *= 7; + cc ^= x4; + aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff] + ^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff]; + bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff] + ^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff]; + bb *= 7; + aa ^= x5; + bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff] + ^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff]; + cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff] + ^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff]; + cc *= 7; + bb ^= x6; + cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff] + ^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff]; + aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff] + ^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff]; + aa *= 7; + cc ^= x7; + aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff] + ^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff]; + bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff] + ^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff]; + bb *= 7; + + // key_schedule ::= + x0 -= x7 ^ 0xA5A5A5A5A5A5A5A5L; + x1 ^= x0; + x2 += x1; + x3 -= x2 ^ ((~x1) << 19); + x4 ^= x3; + x5 += x4; + x6 -= x5 ^ ((~x4) >>> 23); + x7 ^= x6; + x0 += x7; + x1 -= x0 ^ ((~x7) << 19); + x2 ^= x1; + x3 += x2; + x4 -= x3 ^ ((~x2) >>> 23); + x5 ^= x4; + x6 += x5; + x7 -= x6 ^ 0x0123456789ABCDEFL; + + // pass(bb,cc,aa,9) ::= + aa ^= x0; + bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff] + ^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff]; + cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff] + ^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff]; + cc *= 9; + bb ^= x1; + cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff] + ^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff]; + aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff] + ^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff]; + aa *= 9; + cc ^= x2; + aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff] + ^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff]; + bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff] + ^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff]; + bb *= 9; + aa ^= x3; + bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff] + ^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff]; + cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff] + ^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff]; + cc *= 9; + bb ^= x4; + cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff] + ^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff]; + aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff] + ^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff]; + aa *= 9; + cc ^= x5; + aa -= T1[(int) cc & 0xff] ^ T2[(int) (cc >> 16) & 0xff] + ^ T3[(int) (cc >> 32) & 0xff] ^ T4[(int) (cc >> 48) & 0xff]; + bb += T4[(int) (cc >> 8) & 0xff] ^ T3[(int) (cc >> 24) & 0xff] + ^ T2[(int) (cc >> 40) & 0xff] ^ T1[(int) (cc >> 56) & 0xff]; + bb *= 9; + aa ^= x6; + bb -= T1[(int) aa & 0xff] ^ T2[(int) (aa >> 16) & 0xff] + ^ T3[(int) (aa >> 32) & 0xff] ^ T4[(int) (aa >> 48) & 0xff]; + cc += T4[(int) (aa >> 8) & 0xff] ^ T3[(int) (aa >> 24) & 0xff] + ^ T2[(int) (aa >> 40) & 0xff] ^ T1[(int) (aa >> 56) & 0xff]; + cc *= 9; + bb ^= x7; + cc -= T1[(int) bb & 0xff] ^ T2[(int) (bb >> 16) & 0xff] + ^ T3[(int) (bb >> 32) & 0xff] ^ T4[(int) (bb >> 48) & 0xff]; + aa += T4[(int) (bb >> 8) & 0xff] ^ T3[(int) (bb >> 24) & 0xff] + ^ T2[(int) (bb >> 40) & 0xff] ^ T1[(int) (bb >> 56) & 0xff]; + aa *= 9; + + // feedforward ::= + a ^= aa; + b = bb - b; + c += cc; + } +} diff --git a/libjava/classpath/gnu/java/security/hash/Whirlpool.java b/libjava/classpath/gnu/java/security/hash/Whirlpool.java new file mode 100644 index 00000000000..8c5d9f360d0 --- /dev/null +++ b/libjava/classpath/gnu/java/security/hash/Whirlpool.java @@ -0,0 +1,626 @@ +/* Whirlpool.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.hash; + +import gnu.java.security.Registry; +import gnu.java.security.util.Util; + +/** + * <p>Whirlpool, a new 512-bit hashing function operating on messages less than + * 2 ** 256 bits in length. The function structure is designed according to the + * Wide Trail strategy and permits a wide variety of implementation trade-offs. + * </p> + * + * <p><b>IMPORTANT</b>: This implementation is not thread-safe.</p> + * + * <p>References:</p> + * + * <ol> + * <li><a href="http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html"> + * The WHIRLPOOL Hashing Function</a>.<br> + * <a href="mailto:paulo.barreto@terra.com.br">Paulo S.L.M. Barreto</a> and + * <a href="mailto:vincent.rijmen@esat.kuleuven.ac.be">Vincent Rijmen</a>.</li> + * </ol> + */ +public final class Whirlpool extends BaseHash +{ + + // Debugging methods and variables + // ------------------------------------------------------------------------- + + private static final boolean DEBUG = false; + + private static final int debuglevel = 3; + + // Constants and variables + // ------------------------------------------------------------------------- + + private static final int BLOCK_SIZE = 64; // inner block size in bytes + + /** The digest of the 0-bit long message. */ + private static final String DIGEST0 = "470F0409ABAA446E49667D4EBE12A14387CEDBD10DD17B8243CAD550A089DC0F" + + "EEA7AA40F6C2AAAB71C6EBD076E43C7CFCA0AD32567897DCB5969861049A0F5A"; + + private static final int R = 10; // default number of rounds + + private static final String Sd = // p. 19 [WHIRLPOOL] + "\u1823\uc6E8\u87B8\u014F\u36A6\ud2F5\u796F\u9152" + + "\u60Bc\u9B8E\uA30c\u7B35\u1dE0\ud7c2\u2E4B\uFE57" + + "\u1577\u37E5\u9FF0\u4AdA\u58c9\u290A\uB1A0\u6B85" + + "\uBd5d\u10F4\ucB3E\u0567\uE427\u418B\uA77d\u95d8" + + "\uFBEE\u7c66\udd17\u479E\ucA2d\uBF07\uAd5A\u8333" + + "\u6302\uAA71\uc819\u49d9\uF2E3\u5B88\u9A26\u32B0" + + "\uE90F\ud580\uBEcd\u3448\uFF7A\u905F\u2068\u1AAE" + + "\uB454\u9322\u64F1\u7312\u4008\uc3Ec\udBA1\u8d3d" + + "\u9700\ucF2B\u7682\ud61B\uB5AF\u6A50\u45F3\u30EF" + + "\u3F55\uA2EA\u65BA\u2Fc0\udE1c\uFd4d\u9275\u068A" + + "\uB2E6\u0E1F\u62d4\uA896\uF9c5\u2559\u8472\u394c" + + "\u5E78\u388c\ud1A5\uE261\uB321\u9c1E\u43c7\uFc04" + + "\u5199\u6d0d\uFAdF\u7E24\u3BAB\ucE11\u8F4E\uB7EB" + + "\u3c81\u94F7\uB913\u2cd3\uE76E\uc403\u5644\u7FA9" + + "\u2ABB\uc153\udc0B\u9d6c\u3174\uF646\uAc89\u14E1" + + "\u163A\u6909\u70B6\ud0Ed\ucc42\u98A4\u285c\uF886"; + + private static final long[] T0 = new long[256]; + + private static final long[] T1 = new long[256]; + + private static final long[] T2 = new long[256]; + + private static final long[] T3 = new long[256]; + + private static final long[] T4 = new long[256]; + + private static final long[] T5 = new long[256]; + + private static final long[] T6 = new long[256]; + + private static final long[] T7 = new long[256]; + + private static final long[] rc = new long[R]; + + /** caches the result of the correctness test, once executed. */ + private static Boolean valid; + + /** The 512-bit context as 8 longs. */ + private long H0, H1, H2, H3, H4, H5, H6, H7; + + /** Work area for computing the round key schedule. */ + private long k00, k01, k02, k03, k04, k05, k06, k07; + + private long Kr0, Kr1, Kr2, Kr3, Kr4, Kr5, Kr6, Kr7; + + /** work area for transforming the 512-bit buffer. */ + private long n0, n1, n2, n3, n4, n5, n6, n7; + + private long nn0, nn1, nn2, nn3, nn4, nn5, nn6, nn7; + + /** work area for holding block cipher's intermediate values. */ + private long w0, w1, w2, w3, w4, w5, w6, w7; + + // Static code - to intialise lookup tables -------------------------------- + + static + { + long time = System.currentTimeMillis(); + + int ROOT = 0x11d; // para. 2.1 [WHIRLPOOL] + int i, r, j; + long s, s2, s3, s4, s5, s8, s9, t; + char c; + final byte[] S = new byte[256]; + for (i = 0; i < 256; i++) + { + c = Sd.charAt(i >>> 1); + + s = ((i & 1) == 0 ? c >>> 8 : c) & 0xFFL; + s2 = s << 1; + if (s2 > 0xFFL) + { + s2 ^= ROOT; + } + s3 = s2 ^ s; + s4 = s2 << 1; + if (s4 > 0xFFL) + { + s4 ^= ROOT; + } + s5 = s4 ^ s; + s8 = s4 << 1; + if (s8 > 0xFFL) + { + s8 ^= ROOT; + } + s9 = s8 ^ s; + + S[i] = (byte) s; + T0[i] = t = s << 56 | s << 48 | s3 << 40 | s << 32 | s5 << 24 + | s8 << 16 | s9 << 8 | s5; + T1[i] = t >>> 8 | t << 56; + T2[i] = t >>> 16 | t << 48; + T3[i] = t >>> 24 | t << 40; + T4[i] = t >>> 32 | t << 32; + T5[i] = t >>> 40 | t << 24; + T6[i] = t >>> 48 | t << 16; + T7[i] = t >>> 56 | t << 8; + } + + for (r = 1, i = 0, j = 0; r < R + 1; r++) + { + rc[i++] = (S[j++] & 0xFFL) << 56 | (S[j++] & 0xFFL) << 48 + | (S[j++] & 0xFFL) << 40 | (S[j++] & 0xFFL) << 32 + | (S[j++] & 0xFFL) << 24 | (S[j++] & 0xFFL) << 16 + | (S[j++] & 0xFFL) << 8 | (S[j++] & 0xFFL); + } + + time = System.currentTimeMillis() - time; + + if (DEBUG && debuglevel > 8) + { + System.out.println("=========="); + System.out.println(); + System.out.println("Static data"); + System.out.println(); + + System.out.println(); + System.out.println("T0[]:"); + for (i = 0; i < 64; i++) + { + for (j = 0; j < 4; j++) + { + System.out.print("0x" + Util.toString(T0[i * 4 + j]) + ", "); + } + System.out.println(); + } + System.out.println(); + System.out.println("T1[]:"); + for (i = 0; i < 64; i++) + { + for (j = 0; j < 4; j++) + { + System.out.print("0x" + Util.toString(T1[i * 4 + j]) + ", "); + } + System.out.println(); + } + System.out.println(); + System.out.println("T2[]:"); + for (i = 0; i < 64; i++) + { + for (j = 0; j < 4; j++) + { + System.out.print("0x" + Util.toString(T2[i * 4 + j]) + ", "); + } + System.out.println(); + } + System.out.println(); + System.out.println("T3[]:"); + for (i = 0; i < 64; i++) + { + for (j = 0; j < 4; j++) + { + System.out.print("0x" + Util.toString(T3[i * 4 + j]) + ", "); + } + System.out.println(); + } + System.out.println(); + System.out.println("T4[]:"); + for (i = 0; i < 64; i++) + { + for (j = 0; j < 4; j++) + { + System.out.print("0x" + Util.toString(T4[i * 4 + j]) + ", "); + } + System.out.println(); + } + System.out.println(); + System.out.println("T5[]:"); + for (i = 0; i < 64; i++) + { + for (j = 0; j < 4; j++) + { + System.out.print("0x" + Util.toString(T5[i * 4 + j]) + ", "); + } + System.out.println(); + } + System.out.println(); + System.out.println("T6[]:"); + for (i = 0; i < 64; i++) + { + for (j = 0; j < 4; j++) + { + System.out.print("0x" + Util.toString(T5[i * 4 + j]) + ", "); + } + System.out.println(); + } + System.out.println(); + System.out.println("T7[]:"); + for (i = 0; i < 64; i++) + { + for (j = 0; j < 4; j++) + { + System.out.print("0x" + Util.toString(T5[i * 4 + j]) + ", "); + } + System.out.println(); + } + System.out.println(); + System.out.println("rc[]:"); + for (i = 0; i < R; i++) + { + System.out.println("0x" + Util.toString(rc[i])); + } + System.out.println(); + + System.out.println(); + System.out.println("Total initialization time: " + time + " ms."); + System.out.println(); + } + } + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial 0-arguments constructor. */ + public Whirlpool() + { + super(Registry.WHIRLPOOL_HASH, 20, BLOCK_SIZE); + } + + /** + * <p>Private constructor for cloning purposes.</p> + * + * @param md the instance to clone. + */ + private Whirlpool(Whirlpool md) + { + this(); + + this.H0 = md.H0; + this.H1 = md.H1; + this.H2 = md.H2; + this.H3 = md.H3; + this.H4 = md.H4; + this.H5 = md.H5; + this.H6 = md.H6; + this.H7 = md.H7; + this.count = md.count; + this.buffer = (byte[]) md.buffer.clone(); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // java.lang.Cloneable interface implementation ---------------------------- + + public Object clone() + { + return (new Whirlpool(this)); + } + + // Implementation of concrete methods in BaseHash -------------------------- + + protected void transform(byte[] in, int offset) + { + // apply mu to the input + n0 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48 + | (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32 + | (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16 + | (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL); + n1 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48 + | (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32 + | (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16 + | (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL); + n2 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48 + | (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32 + | (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16 + | (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL); + n3 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48 + | (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32 + | (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16 + | (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL); + n4 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48 + | (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32 + | (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16 + | (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL); + n5 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48 + | (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32 + | (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16 + | (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL); + n6 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48 + | (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32 + | (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16 + | (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL); + n7 = (in[offset++] & 0xFFL) << 56 | (in[offset++] & 0xFFL) << 48 + | (in[offset++] & 0xFFL) << 40 | (in[offset++] & 0xFFL) << 32 + | (in[offset++] & 0xFFL) << 24 | (in[offset++] & 0xFFL) << 16 + | (in[offset++] & 0xFFL) << 8 | (in[offset++] & 0xFFL); + + // transform K into the key schedule Kr; 0 <= r <= R + k00 = H0; + k01 = H1; + k02 = H2; + k03 = H3; + k04 = H4; + k05 = H5; + k06 = H6; + k07 = H7; + + nn0 = n0 ^ k00; + nn1 = n1 ^ k01; + nn2 = n2 ^ k02; + nn3 = n3 ^ k03; + nn4 = n4 ^ k04; + nn5 = n5 ^ k05; + nn6 = n6 ^ k06; + nn7 = n7 ^ k07; + + // intermediate cipher output + w0 = w1 = w2 = w3 = w4 = w5 = w6 = w7 = 0L; + + for (int r = 0; r < R; r++) + { + // 1. compute intermediate round key schedule by applying ro[rc] + // to the previous round key schedule --rc being the round constant + Kr0 = T0[(int) ((k00 >> 56) & 0xFFL)] ^ T1[(int) ((k07 >> 48) & 0xFFL)] + ^ T2[(int) ((k06 >> 40) & 0xFFL)] + ^ T3[(int) ((k05 >> 32) & 0xFFL)] + ^ T4[(int) ((k04 >> 24) & 0xFFL)] + ^ T5[(int) ((k03 >> 16) & 0xFFL)] + ^ T6[(int) ((k02 >> 8) & 0xFFL)] ^ T7[(int) (k01 & 0xFFL)] + ^ rc[r]; + + Kr1 = T0[(int) ((k01 >> 56) & 0xFFL)] ^ T1[(int) ((k00 >> 48) & 0xFFL)] + ^ T2[(int) ((k07 >> 40) & 0xFFL)] + ^ T3[(int) ((k06 >> 32) & 0xFFL)] + ^ T4[(int) ((k05 >> 24) & 0xFFL)] + ^ T5[(int) ((k04 >> 16) & 0xFFL)] + ^ T6[(int) ((k03 >> 8) & 0xFFL)] ^ T7[(int) (k02 & 0xFFL)]; + + Kr2 = T0[(int) ((k02 >> 56) & 0xFFL)] ^ T1[(int) ((k01 >> 48) & 0xFFL)] + ^ T2[(int) ((k00 >> 40) & 0xFFL)] + ^ T3[(int) ((k07 >> 32) & 0xFFL)] + ^ T4[(int) ((k06 >> 24) & 0xFFL)] + ^ T5[(int) ((k05 >> 16) & 0xFFL)] + ^ T6[(int) ((k04 >> 8) & 0xFFL)] ^ T7[(int) (k03 & 0xFFL)]; + + Kr3 = T0[(int) ((k03 >> 56) & 0xFFL)] ^ T1[(int) ((k02 >> 48) & 0xFFL)] + ^ T2[(int) ((k01 >> 40) & 0xFFL)] + ^ T3[(int) ((k00 >> 32) & 0xFFL)] + ^ T4[(int) ((k07 >> 24) & 0xFFL)] + ^ T5[(int) ((k06 >> 16) & 0xFFL)] + ^ T6[(int) ((k05 >> 8) & 0xFFL)] ^ T7[(int) (k04 & 0xFFL)]; + + Kr4 = T0[(int) ((k04 >> 56) & 0xFFL)] ^ T1[(int) ((k03 >> 48) & 0xFFL)] + ^ T2[(int) ((k02 >> 40) & 0xFFL)] + ^ T3[(int) ((k01 >> 32) & 0xFFL)] + ^ T4[(int) ((k00 >> 24) & 0xFFL)] + ^ T5[(int) ((k07 >> 16) & 0xFFL)] + ^ T6[(int) ((k06 >> 8) & 0xFFL)] ^ T7[(int) (k05 & 0xFFL)]; + + Kr5 = T0[(int) ((k05 >> 56) & 0xFFL)] ^ T1[(int) ((k04 >> 48) & 0xFFL)] + ^ T2[(int) ((k03 >> 40) & 0xFFL)] + ^ T3[(int) ((k02 >> 32) & 0xFFL)] + ^ T4[(int) ((k01 >> 24) & 0xFFL)] + ^ T5[(int) ((k00 >> 16) & 0xFFL)] + ^ T6[(int) ((k07 >> 8) & 0xFFL)] ^ T7[(int) (k06 & 0xFFL)]; + + Kr6 = T0[(int) ((k06 >> 56) & 0xFFL)] ^ T1[(int) ((k05 >> 48) & 0xFFL)] + ^ T2[(int) ((k04 >> 40) & 0xFFL)] + ^ T3[(int) ((k03 >> 32) & 0xFFL)] + ^ T4[(int) ((k02 >> 24) & 0xFFL)] + ^ T5[(int) ((k01 >> 16) & 0xFFL)] + ^ T6[(int) ((k00 >> 8) & 0xFFL)] ^ T7[(int) (k07 & 0xFFL)]; + + Kr7 = T0[(int) ((k07 >> 56) & 0xFFL)] ^ T1[(int) ((k06 >> 48) & 0xFFL)] + ^ T2[(int) ((k05 >> 40) & 0xFFL)] + ^ T3[(int) ((k04 >> 32) & 0xFFL)] + ^ T4[(int) ((k03 >> 24) & 0xFFL)] + ^ T5[(int) ((k02 >> 16) & 0xFFL)] + ^ T6[(int) ((k01 >> 8) & 0xFFL)] ^ T7[(int) (k00 & 0xFFL)]; + + k00 = Kr0; + k01 = Kr1; + k02 = Kr2; + k03 = Kr3; + k04 = Kr4; + k05 = Kr5; + k06 = Kr6; + k07 = Kr7; + + // 2. incrementally compute the cipher output + w0 = T0[(int) ((nn0 >> 56) & 0xFFL)] ^ T1[(int) ((nn7 >> 48) & 0xFFL)] + ^ T2[(int) ((nn6 >> 40) & 0xFFL)] + ^ T3[(int) ((nn5 >> 32) & 0xFFL)] + ^ T4[(int) ((nn4 >> 24) & 0xFFL)] + ^ T5[(int) ((nn3 >> 16) & 0xFFL)] ^ T6[(int) ((nn2 >> 8) & 0xFFL)] + ^ T7[(int) (nn1 & 0xFFL)] ^ Kr0; + w1 = T0[(int) ((nn1 >> 56) & 0xFFL)] ^ T1[(int) ((nn0 >> 48) & 0xFFL)] + ^ T2[(int) ((nn7 >> 40) & 0xFFL)] + ^ T3[(int) ((nn6 >> 32) & 0xFFL)] + ^ T4[(int) ((nn5 >> 24) & 0xFFL)] + ^ T5[(int) ((nn4 >> 16) & 0xFFL)] ^ T6[(int) ((nn3 >> 8) & 0xFFL)] + ^ T7[(int) (nn2 & 0xFFL)] ^ Kr1; + w2 = T0[(int) ((nn2 >> 56) & 0xFFL)] ^ T1[(int) ((nn1 >> 48) & 0xFFL)] + ^ T2[(int) ((nn0 >> 40) & 0xFFL)] + ^ T3[(int) ((nn7 >> 32) & 0xFFL)] + ^ T4[(int) ((nn6 >> 24) & 0xFFL)] + ^ T5[(int) ((nn5 >> 16) & 0xFFL)] ^ T6[(int) ((nn4 >> 8) & 0xFFL)] + ^ T7[(int) (nn3 & 0xFFL)] ^ Kr2; + w3 = T0[(int) ((nn3 >> 56) & 0xFFL)] ^ T1[(int) ((nn2 >> 48) & 0xFFL)] + ^ T2[(int) ((nn1 >> 40) & 0xFFL)] + ^ T3[(int) ((nn0 >> 32) & 0xFFL)] + ^ T4[(int) ((nn7 >> 24) & 0xFFL)] + ^ T5[(int) ((nn6 >> 16) & 0xFFL)] ^ T6[(int) ((nn5 >> 8) & 0xFFL)] + ^ T7[(int) (nn4 & 0xFFL)] ^ Kr3; + w4 = T0[(int) ((nn4 >> 56) & 0xFFL)] ^ T1[(int) ((nn3 >> 48) & 0xFFL)] + ^ T2[(int) ((nn2 >> 40) & 0xFFL)] + ^ T3[(int) ((nn1 >> 32) & 0xFFL)] + ^ T4[(int) ((nn0 >> 24) & 0xFFL)] + ^ T5[(int) ((nn7 >> 16) & 0xFFL)] ^ T6[(int) ((nn6 >> 8) & 0xFFL)] + ^ T7[(int) (nn5 & 0xFFL)] ^ Kr4; + w5 = T0[(int) ((nn5 >> 56) & 0xFFL)] ^ T1[(int) ((nn4 >> 48) & 0xFFL)] + ^ T2[(int) ((nn3 >> 40) & 0xFFL)] + ^ T3[(int) ((nn2 >> 32) & 0xFFL)] + ^ T4[(int) ((nn1 >> 24) & 0xFFL)] + ^ T5[(int) ((nn0 >> 16) & 0xFFL)] ^ T6[(int) ((nn7 >> 8) & 0xFFL)] + ^ T7[(int) (nn6 & 0xFFL)] ^ Kr5; + w6 = T0[(int) ((nn6 >> 56) & 0xFFL)] ^ T1[(int) ((nn5 >> 48) & 0xFFL)] + ^ T2[(int) ((nn4 >> 40) & 0xFFL)] + ^ T3[(int) ((nn3 >> 32) & 0xFFL)] + ^ T4[(int) ((nn2 >> 24) & 0xFFL)] + ^ T5[(int) ((nn1 >> 16) & 0xFFL)] ^ T6[(int) ((nn0 >> 8) & 0xFFL)] + ^ T7[(int) (nn7 & 0xFFL)] ^ Kr6; + w7 = T0[(int) ((nn7 >> 56) & 0xFFL)] ^ T1[(int) ((nn6 >> 48) & 0xFFL)] + ^ T2[(int) ((nn5 >> 40) & 0xFFL)] + ^ T3[(int) ((nn4 >> 32) & 0xFFL)] + ^ T4[(int) ((nn3 >> 24) & 0xFFL)] + ^ T5[(int) ((nn2 >> 16) & 0xFFL)] ^ T6[(int) ((nn1 >> 8) & 0xFFL)] + ^ T7[(int) (nn0 & 0xFFL)] ^ Kr7; + + nn0 = w0; + nn1 = w1; + nn2 = w2; + nn3 = w3; + nn4 = w4; + nn5 = w5; + nn6 = w6; + nn7 = w7; + } + + // apply the Miyaguchi-Preneel hash scheme + H0 ^= w0 ^ n0; + H1 ^= w1 ^ n1; + H2 ^= w2 ^ n2; + H3 ^= w3 ^ n3; + H4 ^= w4 ^ n4; + H5 ^= w5 ^ n5; + H6 ^= w6 ^ n6; + H7 ^= w7 ^ n7; + } + + protected byte[] padBuffer() + { + // [WHIRLPOOL] p. 6: + // "...padded with a 1-bit, then with as few 0-bits as necessary to + // obtain a bit string whose length is an odd multiple of 256, and + // finally with the 256-bit right-justified binary representation of L." + // in this implementation we use 'count' as the number of bytes hashed + // so far. hence the minimal number of bytes added to the message proper + // are 33 (1 for the 1-bit followed by the 0-bits and the encoding of + // the count framed in a 256-bit block). our formula is then: + // count + 33 + padding = 0 (mod BLOCK_SIZE) + int n = (int) ((count + 33) % BLOCK_SIZE); + int padding = n == 0 ? 33 : BLOCK_SIZE - n + 33; + + byte[] result = new byte[padding]; + + // padding is always binary 1 followed by binary 0s + result[0] = (byte) 0x80; + + // save (right justified) the number of bits hashed + long bits = count * 8; + int i = padding - 8; + result[i++] = (byte) (bits >>> 56); + result[i++] = (byte) (bits >>> 48); + result[i++] = (byte) (bits >>> 40); + result[i++] = (byte) (bits >>> 32); + result[i++] = (byte) (bits >>> 24); + result[i++] = (byte) (bits >>> 16); + result[i++] = (byte) (bits >>> 8); + result[i] = (byte) bits; + + return result; + } + + protected byte[] getResult() + { + // apply inverse mu to the context + byte[] result = new byte[] { (byte) (H0 >>> 56), (byte) (H0 >>> 48), + (byte) (H0 >>> 40), (byte) (H0 >>> 32), + (byte) (H0 >>> 24), (byte) (H0 >>> 16), + (byte) (H0 >>> 8), (byte) H0, + (byte) (H1 >>> 56), (byte) (H1 >>> 48), + (byte) (H1 >>> 40), (byte) (H1 >>> 32), + (byte) (H1 >>> 24), (byte) (H1 >>> 16), + (byte) (H1 >>> 8), (byte) H1, + (byte) (H2 >>> 56), (byte) (H2 >>> 48), + (byte) (H2 >>> 40), (byte) (H2 >>> 32), + (byte) (H2 >>> 24), (byte) (H2 >>> 16), + (byte) (H2 >>> 8), (byte) H2, + (byte) (H3 >>> 56), (byte) (H3 >>> 48), + (byte) (H3 >>> 40), (byte) (H3 >>> 32), + (byte) (H3 >>> 24), (byte) (H3 >>> 16), + (byte) (H3 >>> 8), (byte) H3, + (byte) (H4 >>> 56), (byte) (H4 >>> 48), + (byte) (H4 >>> 40), (byte) (H4 >>> 32), + (byte) (H4 >>> 24), (byte) (H4 >>> 16), + (byte) (H4 >>> 8), (byte) H4, + (byte) (H5 >>> 56), (byte) (H5 >>> 48), + (byte) (H5 >>> 40), (byte) (H5 >>> 32), + (byte) (H5 >>> 24), (byte) (H5 >>> 16), + (byte) (H5 >>> 8), (byte) H5, + (byte) (H6 >>> 56), (byte) (H6 >>> 48), + (byte) (H6 >>> 40), (byte) (H6 >>> 32), + (byte) (H6 >>> 24), (byte) (H6 >>> 16), + (byte) (H6 >>> 8), (byte) H6, + (byte) (H7 >>> 56), (byte) (H7 >>> 48), + (byte) (H7 >>> 40), (byte) (H7 >>> 32), + (byte) (H7 >>> 24), (byte) (H7 >>> 16), + (byte) (H7 >>> 8), (byte) H7 }; + + return result; + } + + protected void resetContext() + { + H0 = H1 = H2 = H3 = H4 = H5 = H6 = H7 = 0L; + } + + public boolean selfTest() + { + if (valid == null) + { + valid = new Boolean( + DIGEST0.equals(Util.toString(new Whirlpool().digest()))); + } + return valid.booleanValue(); + } +} diff --git a/libjava/classpath/gnu/java/security/jce/hash/HavalSpi.java b/libjava/classpath/gnu/java/security/jce/hash/HavalSpi.java new file mode 100644 index 00000000000..e127779efb4 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/hash/HavalSpi.java @@ -0,0 +1,68 @@ +/* HavalSpi.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.hash; + +import gnu.java.security.Registry; + +/** + * The implementation of the <code>HAVAL</code> <i>Service Provider Interface</i> + * (<b>SPI</b>) Adapter.<p> + * + * @version Revision: $ + */ +public class HavalSpi extends MessageDigestAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public HavalSpi() + { + super(Registry.HAVAL_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/hash/MD2Spi.java b/libjava/classpath/gnu/java/security/jce/hash/MD2Spi.java new file mode 100644 index 00000000000..5b6b0e1e1d7 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/hash/MD2Spi.java @@ -0,0 +1,69 @@ +/* MD2Spi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.hash; + +import gnu.java.security.Registry; + +/** + * <p>The implementation of the MD2 <i>Service Provider Interface</i> + * (<b>SPI</b>) adapter.</p> + * + * @version $Revision: 1.1 $ + */ +public class MD2Spi extends MessageDigestAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial 0-arguments constructor. */ + public MD2Spi() + { + super(Registry.MD2_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/hash/MD4Spi.java b/libjava/classpath/gnu/java/security/jce/hash/MD4Spi.java new file mode 100644 index 00000000000..8be44993400 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/hash/MD4Spi.java @@ -0,0 +1,69 @@ +/* MD4Spi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.hash; + +import gnu.java.security.Registry; + +/** + * <p>The implementation of the MD4 <i>Service Provider Interface</i> + * (<b>SPI</b>) adapter.</p> + * + * @version $Revision: 1.1 $ + */ +public class MD4Spi extends MessageDigestAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial 0-arguments constructor. */ + public MD4Spi() + { + super(Registry.MD4_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/hash/MD5Spi.java b/libjava/classpath/gnu/java/security/jce/hash/MD5Spi.java new file mode 100644 index 00000000000..92fb6ab3864 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/hash/MD5Spi.java @@ -0,0 +1,68 @@ +/* MD5Spi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.hash; + +import gnu.java.security.Registry; + +/** + * The implementation of the MD5 <i>Service Provider Interface</i> (<b>SPI</b>) + * adapter.<p> + * + * @version $Revision: 1.1 $ + */ +public class MD5Spi extends MessageDigestAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public MD5Spi() + { + super(Registry.MD5_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/hash/MessageDigestAdapter.java b/libjava/classpath/gnu/java/security/jce/hash/MessageDigestAdapter.java new file mode 100644 index 00000000000..9b8a73d55fd --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/hash/MessageDigestAdapter.java @@ -0,0 +1,147 @@ +/* MessageDigestAdapter.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.hash; + +import gnu.java.security.hash.IMessageDigest; +import gnu.java.security.hash.HashFactory; + +import java.security.DigestException; +import java.security.MessageDigestSpi; + +/** + * The implementation of a generic {@link java.security.MessageDigest} adapter + * class to wrap gnu.crypto hash instances.<p> + * + * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) for the + * {@link java.security.MessageDigest} class, which provides the functionality + * of a message digest algorithm, such as MD5 or SHA. Message digests are secure + * one-way hash functions that take arbitrary-sized data and output a fixed- + * length hash value.<p> + * + * All the abstract methods in the {@link java.security.MessageDigestSpi} class + * are implemented by this class and all its sub-classes.<p> + * + * All the implementations which subclass this object, and which are serviced by + * the GNU Crypto provider implement the {@link java.lang.Cloneable} interface.<p> + * + * @version $Revision: 1.1 $ + */ +class MessageDigestAdapter extends MessageDigestSpi implements Cloneable +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** Our underlying hash instance. */ + private IMessageDigest adaptee; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Trivial protected constructor. + * + * @param mdName the canonical name of the hash algorithm. + */ + protected MessageDigestAdapter(String mdName) + { + this(HashFactory.getInstance(mdName)); + } + + /** + * Private constructor for cloning purposes. + * + * @param adaptee a clone of the underlying hash algorithm instance. + */ + private MessageDigestAdapter(IMessageDigest adaptee) + { + super(); + + this.adaptee = adaptee; + } + + // Class methods + // ------------------------------------------------------------------------- + + // java.security.MessageDigestSpi interface implementation + // ------------------------------------------------------------------------- + + public Object clone() + { + return new MessageDigestAdapter((IMessageDigest) adaptee.clone()); + } + + public int engineGetDigestLength() + { + return adaptee.hashSize(); + } + + public void engineUpdate(byte input) + { + adaptee.update(input); + } + + public void engineUpdate(byte[] input, int offset, int len) + { + adaptee.update(input, offset, len); + } + + public byte[] engineDigest() + { + return adaptee.digest(); + } + + public int engineDigest(byte[] buf, int offset, int len) + throws DigestException + { + int result = adaptee.hashSize(); + if (len < result) + { + throw new DigestException(); + } + byte[] md = adaptee.digest(); + System.arraycopy(md, 0, buf, offset, result); + return result; + } + + public void engineReset() + { + adaptee.reset(); + } +} diff --git a/libjava/classpath/gnu/java/security/jce/hash/RipeMD128Spi.java b/libjava/classpath/gnu/java/security/jce/hash/RipeMD128Spi.java new file mode 100644 index 00000000000..b8e90d4bfb4 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/hash/RipeMD128Spi.java @@ -0,0 +1,68 @@ +/* RipeMD128Spi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.hash; + +import gnu.java.security.Registry; + +/** + * The implementation of the RIPEMD-128 <i>Service Provider Interface</i> + * (<b>SPI</b>) adapter.<p> + * + * @version $Revision: 1.1 $ + */ +public class RipeMD128Spi extends MessageDigestAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public RipeMD128Spi() + { + super(Registry.RIPEMD128_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/hash/RipeMD160Spi.java b/libjava/classpath/gnu/java/security/jce/hash/RipeMD160Spi.java new file mode 100644 index 00000000000..49615e2fcc8 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/hash/RipeMD160Spi.java @@ -0,0 +1,68 @@ +/* RipeMD160Spi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.hash; + +import gnu.java.security.Registry; + +/** + * The implementation of the RIPEMD-160 <i>Service Provider Interface</i> + * (<b>SPI</b>) adapter.<p> + * + * @version $Revision: 1.1 $ + */ +public class RipeMD160Spi extends MessageDigestAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public RipeMD160Spi() + { + super(Registry.RIPEMD160_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/hash/Sha160Spi.java b/libjava/classpath/gnu/java/security/jce/hash/Sha160Spi.java new file mode 100644 index 00000000000..a9b72634d78 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/hash/Sha160Spi.java @@ -0,0 +1,68 @@ +/* Sha160Spi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.hash; + +import gnu.java.security.Registry; + +/** + * The implementation of the SHA-1 (160-bit) <i>Service Provider Interface</i> + * (<b>SPI</b>) adapter.<p> + * + * @version $Revision: 1.1 $ + */ +public class Sha160Spi extends MessageDigestAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public Sha160Spi() + { + super(Registry.SHA160_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/hash/Sha256Spi.java b/libjava/classpath/gnu/java/security/jce/hash/Sha256Spi.java new file mode 100644 index 00000000000..9eeaebdeaec --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/hash/Sha256Spi.java @@ -0,0 +1,68 @@ +/* Sha256Spi.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.hash; + +import gnu.java.security.Registry; + +/** + * <p>The implementation of the SHA-2-1 (256-bit) <i>Service Provider Interface</i> + * (<b>SPI</b>) adapter.</p> + * + * @version $Revision: 1.1 $ + */ +public class Sha256Spi extends MessageDigestAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public Sha256Spi() + { + super(Registry.SHA256_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/hash/Sha384Spi.java b/libjava/classpath/gnu/java/security/jce/hash/Sha384Spi.java new file mode 100644 index 00000000000..96e1e6eb0ab --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/hash/Sha384Spi.java @@ -0,0 +1,68 @@ +/* Sha384Spi.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.hash; + +import gnu.java.security.Registry; + +/** + * <p>The implementation of the SHA-2-2 (384-bit) <i>Service Provider Interface</i> + * (<b>SPI</b>) adapter.</p> + * + * @version $Revision: 1.1 $ + */ +public class Sha384Spi extends MessageDigestAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public Sha384Spi() + { + super(Registry.SHA384_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/hash/Sha512Spi.java b/libjava/classpath/gnu/java/security/jce/hash/Sha512Spi.java new file mode 100644 index 00000000000..75c617046fc --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/hash/Sha512Spi.java @@ -0,0 +1,68 @@ +/* Sha512Spi.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.hash; + +import gnu.java.security.Registry; + +/** + * <p>The implementation of the SHA-2-3 (512-bit) <i>Service Provider Interface</i> + * (<b>SPI</b>) adapter.</p> + * + * @version $Revision: 1.1 $ + */ +public class Sha512Spi extends MessageDigestAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public Sha512Spi() + { + super(Registry.SHA512_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/hash/TigerSpi.java b/libjava/classpath/gnu/java/security/jce/hash/TigerSpi.java new file mode 100644 index 00000000000..b355d78d05c --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/hash/TigerSpi.java @@ -0,0 +1,69 @@ +/* TigerSpi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.hash; + +import gnu.java.security.Registry; + +/** + * <p>The implementation of the Tiger <i>Service Provider Interface</i> + * (<b>SPI</b>) adapter.</p> + * + * @version $Revision: 1.1 $ + */ +public class TigerSpi extends MessageDigestAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial 0-arguments constructor. */ + public TigerSpi() + { + super(Registry.TIGER_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/hash/WhirlpoolSpi.java b/libjava/classpath/gnu/java/security/jce/hash/WhirlpoolSpi.java new file mode 100644 index 00000000000..e42e74ddb36 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/hash/WhirlpoolSpi.java @@ -0,0 +1,68 @@ +/* WhirlpoolSpi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.hash; + +import gnu.java.security.Registry; + +/** + * The implementation of the Whirlpool <i>Service Provider Interface</i> + * (<b>SPI</b>) adapter.<p> + * + * @version $Revision: 1.1 $ + */ +public class WhirlpoolSpi extends MessageDigestAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public WhirlpoolSpi() + { + super(Registry.WHIRLPOOL_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/prng/HavalRandomSpi.java b/libjava/classpath/gnu/java/security/jce/prng/HavalRandomSpi.java new file mode 100644 index 00000000000..0c39a37fd1b --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/prng/HavalRandomSpi.java @@ -0,0 +1,66 @@ +/* HavalRandomSpi.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.prng; + +import gnu.java.security.Registry; + +/** + * The implementation of the HAVAL-based SecureRandom <i>Service Provider + * Interface</i> (<b>SPI</b>) Adapter.<p> + */ +public class HavalRandomSpi extends SecureRandomAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public HavalRandomSpi() + { + super(Registry.HAVAL_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/prng/MD2RandomSpi.java b/libjava/classpath/gnu/java/security/jce/prng/MD2RandomSpi.java new file mode 100644 index 00000000000..72a7f4873e4 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/prng/MD2RandomSpi.java @@ -0,0 +1,66 @@ +/* MD2RandomSpi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.prng; + +import gnu.java.security.Registry; + +/** + * The implementation of the MD2-based SecureRandom <i>Service Provider + * Interface</i> (<b>SPI</b>) adapter.<p> + */ +public class MD2RandomSpi extends SecureRandomAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public MD2RandomSpi() + { + super(Registry.MD2_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/prng/MD4RandomSpi.java b/libjava/classpath/gnu/java/security/jce/prng/MD4RandomSpi.java new file mode 100644 index 00000000000..f5f98f8f39b --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/prng/MD4RandomSpi.java @@ -0,0 +1,66 @@ +/* MD4RandomSpi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.prng; + +import gnu.java.security.Registry; + +/** + * The implementation of the MD4-based SecureRandom <i>Service Provider + * Interface</i> (<b>SPI</b>) adapter.<p> + */ +public class MD4RandomSpi extends SecureRandomAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public MD4RandomSpi() + { + super(Registry.MD4_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/prng/MD5RandomSpi.java b/libjava/classpath/gnu/java/security/jce/prng/MD5RandomSpi.java new file mode 100644 index 00000000000..0181247bc5e --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/prng/MD5RandomSpi.java @@ -0,0 +1,66 @@ +/* MD5RandomSpi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.prng; + +import gnu.java.security.Registry; + +/** + * The implementation of the MD5-based SecureRandom <i>Service Provider + * Interface</i> (<b>SPI</b>) adapter.<p> + */ +public class MD5RandomSpi extends SecureRandomAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public MD5RandomSpi() + { + super(Registry.MD5_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/prng/RipeMD128RandomSpi.java b/libjava/classpath/gnu/java/security/jce/prng/RipeMD128RandomSpi.java new file mode 100644 index 00000000000..5580716a491 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/prng/RipeMD128RandomSpi.java @@ -0,0 +1,66 @@ +/* RipeMD128RandomSpi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.prng; + +import gnu.java.security.Registry; + +/** + * <p>The implementation of the RIPEMD128-based SecureRandom <i>Service Provider + * Interface</i> (<b>SPI</b>) adapter.<p> + */ +public class RipeMD128RandomSpi extends SecureRandomAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public RipeMD128RandomSpi() + { + super(Registry.RIPEMD128_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/prng/RipeMD160RandomSpi.java b/libjava/classpath/gnu/java/security/jce/prng/RipeMD160RandomSpi.java new file mode 100644 index 00000000000..734fe824a4c --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/prng/RipeMD160RandomSpi.java @@ -0,0 +1,66 @@ +/* RipeMD160RandomSpi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.prng; + +import gnu.java.security.Registry; + +/** + * The implementation of the RIPEMD160-based SecureRandom <i>Service Provider + * Interface</i> (<b>SPI</b>) adapter.<p> + */ +public class RipeMD160RandomSpi extends SecureRandomAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public RipeMD160RandomSpi() + { + super(Registry.RIPEMD160_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/prng/SecureRandomAdapter.java b/libjava/classpath/gnu/java/security/jce/prng/SecureRandomAdapter.java new file mode 100644 index 00000000000..e7cb7209103 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/prng/SecureRandomAdapter.java @@ -0,0 +1,126 @@ +/* SecureRandomAdapter.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.prng; + +import gnu.java.security.prng.LimitReachedException; +import gnu.java.security.prng.MDGenerator; + +import java.security.SecureRandomSpi; +import java.util.HashMap; + +/** + * <p>The implementation of a generic {@link java.security.SecureRandom} adapter + * class to wrap gnu.crypto prng instances based on Message Digest algorithms.</p> + * + * <p>This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) for + * the {@link java.security.SecureRandom} class, which provides the + * functionality of a cryptographically strong pseudo-random number generator.</p> + * + * <p>All the abstract methods in the {@link SecureRandomSpi} class are + * implemented by this class and all its sub-classes.</p> + */ +abstract class SecureRandomAdapter extends SecureRandomSpi +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** Our underlying prng instance. */ + private MDGenerator adaptee = new MDGenerator(); + + /** The name of the message digest algorithm used by the adaptee. */ + private String mdName; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * <p>Trivial protected constructor.</p> + * + * @param mdName the canonical name of the underlying hash algorithm. + */ + protected SecureRandomAdapter(String mdName) + { + super(); + + this.mdName = mdName; + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // java.security.SecureRandomSpi interface implementation ------------------ + + public byte[] engineGenerateSeed(int numBytes) + { + if (numBytes < 1) + { + return new byte[0]; + } + byte[] result = new byte[numBytes]; + this.engineNextBytes(result); + return result; + } + + public void engineNextBytes(byte[] bytes) + { + if (!adaptee.isInitialised()) + { + this.engineSetSeed(new byte[0]); + } + try + { + adaptee.nextBytes(bytes, 0, bytes.length); + } + catch (LimitReachedException ignored) + { + } + } + + public void engineSetSeed(byte[] seed) + { + HashMap attributes = new HashMap(); + attributes.put(MDGenerator.MD_NAME, mdName); + attributes.put(MDGenerator.SEEED, seed); + adaptee.init(attributes); + } +} diff --git a/libjava/classpath/gnu/java/security/jce/prng/Sha160RandomSpi.java b/libjava/classpath/gnu/java/security/jce/prng/Sha160RandomSpi.java new file mode 100644 index 00000000000..c93b02d3fb8 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/prng/Sha160RandomSpi.java @@ -0,0 +1,66 @@ +/* Sha160RandomSpi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.prng; + +import gnu.java.security.Registry; + +/** + * The implementation of the SHA1-based SecureRandom <i>Service Provider + * Interface</i> (<b>SPI</b>) adapter.<p> + */ +public class Sha160RandomSpi extends SecureRandomAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public Sha160RandomSpi() + { + super(Registry.SHA160_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/prng/Sha256RandomSpi.java b/libjava/classpath/gnu/java/security/jce/prng/Sha256RandomSpi.java new file mode 100644 index 00000000000..736996430e1 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/prng/Sha256RandomSpi.java @@ -0,0 +1,66 @@ +/* Sha256RandomSpi.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.prng; + +import gnu.java.security.Registry; + +/** + * <p>The implementation of the SHA-256 based SecureRandom <i>Service Provider + * Interface</i> (<b>SPI</b>) adapter.</p> + */ +public class Sha256RandomSpi extends SecureRandomAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public Sha256RandomSpi() + { + super(Registry.SHA256_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/prng/Sha384RandomSpi.java b/libjava/classpath/gnu/java/security/jce/prng/Sha384RandomSpi.java new file mode 100644 index 00000000000..afbf19303c8 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/prng/Sha384RandomSpi.java @@ -0,0 +1,66 @@ +/* Sha384RandomSpi.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.prng; + +import gnu.java.security.Registry; + +/** + * <p>The implementation of the SHA-384 based SecureRandom <i>Service Provider + * Interface</i> (<b>SPI</b>) adapter.</p> + */ +public class Sha384RandomSpi extends SecureRandomAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public Sha384RandomSpi() + { + super(Registry.SHA384_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/prng/Sha512RandomSpi.java b/libjava/classpath/gnu/java/security/jce/prng/Sha512RandomSpi.java new file mode 100644 index 00000000000..b2b33776008 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/prng/Sha512RandomSpi.java @@ -0,0 +1,66 @@ +/* Sha512RandomSpi.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.prng; + +import gnu.java.security.Registry; + +/** + * <p>The implementation of the SHA-512 based SecureRandom <i>Service Provider + * Interface</i> (<b>SPI</b>) adapter.</p> + */ +public class Sha512RandomSpi extends SecureRandomAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public Sha512RandomSpi() + { + super(Registry.SHA512_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/prng/TigerRandomSpi.java b/libjava/classpath/gnu/java/security/jce/prng/TigerRandomSpi.java new file mode 100644 index 00000000000..b4795b98ecc --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/prng/TigerRandomSpi.java @@ -0,0 +1,66 @@ +/* TigerRandomSpi.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.prng; + +import gnu.java.security.Registry; + +/** + * The implementation of the Tiger based SecureRandom <i>Service Provider + * Interface</i> (<b>SPI</b>) adapter.<p> + */ +public class TigerRandomSpi extends SecureRandomAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public TigerRandomSpi() + { + super(Registry.TIGER_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/prng/WhirlpoolRandomSpi.java b/libjava/classpath/gnu/java/security/jce/prng/WhirlpoolRandomSpi.java new file mode 100644 index 00000000000..f327f9df2c7 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/prng/WhirlpoolRandomSpi.java @@ -0,0 +1,66 @@ +/* WhirlpoolRandomSpi.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.prng; + +import gnu.java.security.Registry; + +/** + * The implementation of the Whirlpool-based SecureRandom <i>Service Provider + * Interface</i> (<b>SPI</b>) adapter.<p> + */ +public class WhirlpoolRandomSpi extends SecureRandomAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public WhirlpoolRandomSpi() + { + super(Registry.WHIRLPOOL_HASH); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/sig/DSSKeyFactory.java b/libjava/classpath/gnu/java/security/jce/sig/DSSKeyFactory.java new file mode 100644 index 00000000000..bb4d85c899d --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/DSSKeyFactory.java @@ -0,0 +1,238 @@ +/* DSSKeyFactory.java -- JCE DSA key factory Adapter + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.Registry; +import gnu.java.security.key.dss.DSSKeyPairPKCS8Codec; +import gnu.java.security.key.dss.DSSKeyPairX509Codec; +import gnu.java.security.key.dss.DSSPrivateKey; +import gnu.java.security.key.dss.DSSPublicKey; + +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactorySpi; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.interfaces.DSAPrivateKey; +import java.security.interfaces.DSAPublicKey; +import java.security.spec.DSAPrivateKeySpec; +import java.security.spec.DSAPublicKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +/** + * DSA key factory. + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public class DSSKeyFactory extends KeyFactorySpi +{ + // implicit 0-arguments constructor + + protected PublicKey engineGeneratePublic(KeySpec keySpec) + throws InvalidKeySpecException + { + if (keySpec instanceof DSAPublicKeySpec) + { + DSAPublicKeySpec spec = (DSAPublicKeySpec) keySpec; + BigInteger p = spec.getP(); + BigInteger q = spec.getQ(); + BigInteger g = spec.getG(); + BigInteger y = spec.getY(); + return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y); + } + + if (keySpec instanceof X509EncodedKeySpec) + { + X509EncodedKeySpec spec = (X509EncodedKeySpec) keySpec; + byte[] encoded = spec.getEncoded(); + PublicKey result; + try + { + result = new DSSKeyPairX509Codec().decodePublicKey(encoded); + return result; + } + catch (RuntimeException x) + { + InvalidKeySpecException y = new InvalidKeySpecException(); + y.initCause(x); + throw y; + } + } + + throw new InvalidKeySpecException("Unsupported (public) key specification"); + } + + protected PrivateKey engineGeneratePrivate(KeySpec keySpec) + throws InvalidKeySpecException + { + if (keySpec instanceof DSAPrivateKeySpec) + { + DSAPrivateKeySpec spec = (DSAPrivateKeySpec) keySpec; + BigInteger p = spec.getP(); + BigInteger q = spec.getQ(); + BigInteger g = spec.getG(); + BigInteger x = spec.getX(); + return new DSSPrivateKey(Registry.PKCS8_ENCODING_ID, p, q, g, x); + } + + if (keySpec instanceof PKCS8EncodedKeySpec) + { + PKCS8EncodedKeySpec spec = (PKCS8EncodedKeySpec) keySpec; + byte[] encoded = spec.getEncoded(); + PrivateKey result; + try + { + result = new DSSKeyPairPKCS8Codec().decodePrivateKey(encoded); + return result; + } + catch (RuntimeException x) + { + InvalidKeySpecException y = new InvalidKeySpecException(); + y.initCause(x); + throw y; + } + } + + throw new InvalidKeySpecException("Unsupported (private) key specification"); + } + + protected KeySpec engineGetKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException + { + if (key instanceof DSAPublicKey) + { + if (keySpec.isAssignableFrom(DSAPublicKeySpec.class)) + { + DSAPublicKey dsaKey = (DSAPublicKey) key; + BigInteger p = dsaKey.getParams().getP(); + BigInteger q = dsaKey.getParams().getQ(); + BigInteger g = dsaKey.getParams().getG(); + BigInteger y = dsaKey.getY(); + return new DSAPublicKeySpec(y, p, q, g); + } + + if (keySpec.isAssignableFrom(X509EncodedKeySpec.class)) + { + if (key instanceof DSSPublicKey) + { + DSSPublicKey dssKey = (DSSPublicKey) key; + byte[] encoded = dssKey.getEncoded(Registry.X509_ENCODING_ID); + return new X509EncodedKeySpec(encoded); + } + + if (Registry.X509_ENCODING_SORT_NAME.equalsIgnoreCase(key.getFormat())) + { + byte[] encoded = key.getEncoded(); + return new X509EncodedKeySpec(encoded); + } + + throw new InvalidKeySpecException("Wrong key type or unsupported (public) key specification"); + } + + throw new InvalidKeySpecException("Unsupported (public) key specification"); + } + + if (key instanceof DSAPrivateKey) + { + if (keySpec.isAssignableFrom(DSAPrivateKeySpec.class)) + { + DSAPrivateKey dsaKey = (DSAPrivateKey) key; + BigInteger p = dsaKey.getParams().getP(); + BigInteger q = dsaKey.getParams().getQ(); + BigInteger g = dsaKey.getParams().getG(); + BigInteger x = dsaKey.getX(); + return new DSAPrivateKeySpec(x, p, q, g); + } + + if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class)) + { + if (key instanceof DSSPrivateKey) + { + DSSPrivateKey dssKey = (DSSPrivateKey) key; + byte[] encoded = dssKey.getEncoded(Registry.PKCS8_ENCODING_ID); + return new PKCS8EncodedKeySpec(encoded); + } + + if (Registry.PKCS8_ENCODING_SHORT_NAME.equalsIgnoreCase(key.getFormat())) + { + byte[] encoded = key.getEncoded(); + return new PKCS8EncodedKeySpec(encoded); + } + + throw new InvalidKeySpecException("Wrong key type or unsupported (private) key specification"); + } + + throw new InvalidKeySpecException("Unsupported (private) key specification"); + } + + throw new InvalidKeySpecException("Wrong key type or unsupported key specification"); + } + + protected Key engineTranslateKey(Key key) throws InvalidKeyException + { + if ((key instanceof DSSPublicKey) || (key instanceof DSSPrivateKey)) + return key; + + if (key instanceof DSAPublicKey) + { + DSAPublicKey dsaKey = (DSAPublicKey) key; + BigInteger p = dsaKey.getParams().getP(); + BigInteger q = dsaKey.getParams().getQ(); + BigInteger g = dsaKey.getParams().getG(); + BigInteger y = dsaKey.getY(); + return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y); + } + + if (key instanceof DSAPrivateKey) + { + DSAPrivateKey dsaKey = (DSAPrivateKey) key; + BigInteger p = dsaKey.getParams().getP(); + BigInteger q = dsaKey.getParams().getQ(); + BigInteger g = dsaKey.getParams().getG(); + BigInteger x = dsaKey.getX(); + return new DSSPrivateKey(Registry.PKCS8_ENCODING_ID, p, q, g, x); + } + + throw new InvalidKeyException("Wrong key type"); + } +} diff --git a/libjava/classpath/gnu/java/security/jce/sig/DSSKeyPairGeneratorSpi.java b/libjava/classpath/gnu/java/security/jce/sig/DSSKeyPairGeneratorSpi.java new file mode 100644 index 00000000000..97e9594f6a5 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/DSSKeyPairGeneratorSpi.java @@ -0,0 +1,169 @@ +/* DSSKeyPairGeneratorSpi.java -- + Copyright 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.Registry; +import gnu.java.security.key.dss.DSSKeyPairGenerator; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidParameterException; +import java.security.SecureRandom; +import java.security.interfaces.DSAKeyPairGenerator; +import java.security.interfaces.DSAParams; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.DSAParameterSpec; +import java.util.HashMap; + +/** + * The implementation of a {@link java.security.KeyPairGenerator} adapter class + * to wrap gnu.crypto DSS keypair generator instances.<p> + * + * In case the client does not explicitly initialize the KeyPairGenerator (via + * a call to an <code>initialize()</code> method), the GNU Crypto provider + * uses a default <i>modulus</i> size (keysize) of 1024 bits.<p> + * + * @version $Revision: 1.3 $ + */ +public class DSSKeyPairGeneratorSpi extends KeyPairGeneratorAdapter implements + DSAKeyPairGenerator +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public DSSKeyPairGeneratorSpi() + { + super(Registry.DSS_KPG); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + public void initialize(int keysize, SecureRandom random) + { + this.initialize(keysize, false, random); + } + + public void initialize(AlgorithmParameterSpec params, SecureRandom random) + throws InvalidAlgorithmParameterException + { + HashMap attributes = new HashMap(); + if (params != null) + { + if (!(params instanceof DSAParameterSpec)) + throw new InvalidAlgorithmParameterException( + "Parameters argument is not a non-null instance, or " + + "sub-instance, of java.security.spec.DSAParameterSpec"); + + attributes.put(DSSKeyPairGenerator.DSS_PARAMETERS, params); + } + + if (random != null) + { + attributes.put(DSSKeyPairGenerator.SOURCE_OF_RANDOMNESS, random); + } + + attributes.put(DSSKeyPairGenerator.PREFERRED_ENCODING_FORMAT, + new Integer(Registry.ASN1_ENCODING_ID)); + try + { + adaptee.setup(attributes); + } + catch (IllegalArgumentException x) + { + InvalidAlgorithmParameterException y = + new InvalidAlgorithmParameterException(); + y.initCause(x); + throw y; + } + } + + // java.security.interfaces.DSAKeyPairGenerator interface implementation ----- + + public void initialize(DSAParams params, SecureRandom random) + throws InvalidParameterException + { + if (params == null || !(params instanceof DSAParameterSpec)) + throw new InvalidParameterException( + "Parameters argument is either null or is not an instance, or " + + "sub-instance, of java.security.spec.DSAParameterSpec"); + DSAParameterSpec spec = (DSAParameterSpec) params; + try + { + this.initialize((AlgorithmParameterSpec) spec, random); + } + catch (InvalidAlgorithmParameterException x) + { + InvalidParameterException y = new InvalidParameterException(); + y.initCause(x); + throw y; + } + } + + public void initialize(int modlen, boolean genParams, SecureRandom random) + throws InvalidParameterException + { + HashMap attributes = new HashMap(); + attributes.put(DSSKeyPairGenerator.MODULUS_LENGTH, new Integer(modlen)); + if (random != null) + attributes.put(DSSKeyPairGenerator.SOURCE_OF_RANDOMNESS, random); + + attributes.put(DSSKeyPairGenerator.USE_DEFAULTS, + Boolean.valueOf(!genParams)); + attributes.put(DSSKeyPairGenerator.STRICT_DEFAULTS, Boolean.TRUE); + attributes.put(DSSKeyPairGenerator.PREFERRED_ENCODING_FORMAT, + new Integer(Registry.ASN1_ENCODING_ID)); + try + { + adaptee.setup(attributes); + } + catch (IllegalArgumentException x) + { + InvalidParameterException y = new InvalidParameterException(); + y.initCause(x); + throw y; + } + } +} diff --git a/libjava/classpath/gnu/java/security/jce/sig/DSSParameters.java b/libjava/classpath/gnu/java/security/jce/sig/DSSParameters.java new file mode 100644 index 00000000000..ba1f414faea --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/DSSParameters.java @@ -0,0 +1,220 @@ +/* DSSParameters.java -- DSS parameters DAO + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.Registry; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.der.DERWriter; +import gnu.java.security.util.DerUtil; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.AlgorithmParametersSpi; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.DSAParameterSpec; +import java.security.spec.InvalidParameterSpecException; +import java.util.ArrayList; + +/** + * A JCE-specific Data Access Object (DAO) for DSS parameters. + */ +public class DSSParameters + extends AlgorithmParametersSpi +{ + /** + * A prime modulus, where <code>2<sup>L-1</sup> < p < 2<sup>L</sup></code> + * for <code>512 <= L <= 1024</code> and <code>L</code> a multiple of + * <code>64</code>. + */ + private BigInteger p; + + /** + * A prime divisor of <code>p - 1</code>, where <code>2<sup>159</sup> < q + * < 2<sup>160</sup></code>. + */ + private BigInteger q; + + /** + * <code>g = h<sup>(p-1)</sup>/q mod p</code>, where <code>h</code> is any + * integer with <code>1 < h < p - 1</code> such that <code>h<sup> + * (p-1)</sup>/q mod p > 1</code> (<code>g</code> has order <code>q mod p + * </code>). + */ + private BigInteger g; + + // default 0-arguments constructor + + protected void engineInit(AlgorithmParameterSpec spec) + throws InvalidParameterSpecException + { + if (! (spec instanceof DSAParameterSpec)) + throw new InvalidParameterSpecException("Wrong AlgorithmParameterSpec type: " + + spec.getClass().getName()); + DSAParameterSpec dsaSpec = (DSAParameterSpec) spec; + p = dsaSpec.getP(); + q = dsaSpec.getQ(); + g = dsaSpec.getG(); + } + + /** + * Decodes the set of DSS parameters as per RFC-2459; i.e. the DER-encoded + * form of the following ASN.1 construct: + * + * <pre> + * DssParams ::= SEQUENCE { + * p INTEGER, + * q INTEGER, + * g INTEGER + * } + * </pre> + */ + protected void engineInit(byte[] params) throws IOException + { + DERReader der = new DERReader(params); + + DERValue derParams = der.read(); + DerUtil.checkIsConstructed(derParams, "Wrong DSS Parameters field"); + + DERValue val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong P field"); + p = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong Q field"); + q = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong G field"); + g = (BigInteger) val.getValue(); + } + + protected void engineInit(byte[] params, String format) throws IOException + { + if (format != null) + { + format = format.trim(); + if (format.length() == 0) + throw new IOException("Format MUST NOT be an empty string"); + + if (! format.equalsIgnoreCase(Registry.ASN1_ENCODING_SHORT_NAME)) + throw new IOException("Unknown or unsupported format: " + format); + } + + engineInit(params); + } + + protected AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec) + throws InvalidParameterSpecException + { + if (! paramSpec.isAssignableFrom(DSAParameterSpec.class)) + throw new InvalidParameterSpecException("Wrong AlgorithmParameterSpec type: " + + paramSpec.getName()); + return new DSAParameterSpec(p, q, g); + } + + /** + * Encodes the set of DSS parameters as per RFC-2459; i.e. as the DER-encoded + * form of the following ASN.1 construct: + * + * <pre> + * DssParams ::= SEQUENCE { + * p INTEGER, + * q INTEGER, + * g INTEGER + * } + * </pre> + */ + protected byte[] engineGetEncoded() throws IOException + { + DERValue derP = new DERValue(DER.INTEGER, p); + DERValue derQ = new DERValue(DER.INTEGER, q); + DERValue derG = new DERValue(DER.INTEGER, g); + + ArrayList params = new ArrayList(3); + params.add(derP); + params.add(derQ); + params.add(derG); + DERValue derParams = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, params); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + DERWriter.write(baos, derParams); + byte[] result = baos.toByteArray(); + + return result; + } + + protected byte[] engineGetEncoded(String format) throws IOException + { + if (format != null) + { + format = format.trim(); + if (format.length() == 0) + throw new IOException("Format MUST NOT be an empty string"); + + if (! format.equalsIgnoreCase(Registry.ASN1_ENCODING_SHORT_NAME)) + throw new IOException("Unknown or unsupported format: " + format); + } + + return engineGetEncoded(); + } + + protected String engineToString() + { + StringBuffer sb = new StringBuffer("p="); + if (p == null) + sb.append("???"); + else + sb.append("0x").append(p.toString(16)); + + sb.append(", q="); + if (q == null) + sb.append("???"); + else + sb.append("0x").append(q.toString(16)); + + sb.append(", g="); + if (g == null) + sb.append("???"); + else + sb.append("0x").append(g.toString(16)); + + return sb.toString(); + } +} diff --git a/libjava/classpath/gnu/java/security/jce/sig/DSSParametersGenerator.java b/libjava/classpath/gnu/java/security/jce/sig/DSSParametersGenerator.java new file mode 100644 index 00000000000..09c13861042 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/DSSParametersGenerator.java @@ -0,0 +1,125 @@ +/* DSSParametersGenerator.java -- JCE Adapter for a generator of DSS parameters + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.Registry; +import gnu.java.security.key.dss.DSSKeyPairGenerator; +import gnu.java.security.key.dss.FIPS186; +import gnu.java.security.provider.Gnu; + +import java.math.BigInteger; +import java.security.AlgorithmParameterGeneratorSpi; +import java.security.AlgorithmParameters; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.DSAParameterSpec; +import java.security.spec.InvalidParameterSpecException; + +/** + * A JCE Adapter for a generator of DSS parameters. + */ +public class DSSParametersGenerator + extends AlgorithmParameterGeneratorSpi +{ + private static final Provider GNU = new Gnu(); + + /** Size of the public modulus in bits. */ + private int modulusLength = -1; + + /** User specified source of randomness. */ + private SecureRandom rnd; + + /** Our concrete DSS parameters generator. */ + private FIPS186 fips; + + // default 0-arguments constructor + + protected void engineInit(int size, SecureRandom random) + { + if ((size % 64) != 0 || size < 512 || size > 1024) + throw new InvalidParameterException("Modulus size/length (in bits) MUST " + + "be a multiple of 64, greater than " + + "or equal to 512, and less than or " + + "equal to 1024"); + this.modulusLength = size; + this.rnd = random; + } + + protected void engineInit(AlgorithmParameterSpec spec, SecureRandom random) + throws InvalidAlgorithmParameterException + { + if (! (spec instanceof DSAParameterSpec)) + throw new InvalidAlgorithmParameterException("Wrong AlgorithmParameterSpec type: " + + spec.getClass().getName()); + DSAParameterSpec dsaSpec = (DSAParameterSpec) spec; + BigInteger p = dsaSpec.getP(); + int size = p.bitLength(); + this.engineInit(size, random); + } + + protected AlgorithmParameters engineGenerateParameters() + { + if (modulusLength < 1) + modulusLength = DSSKeyPairGenerator.DEFAULT_MODULUS_LENGTH; + + fips = new FIPS186(modulusLength, rnd); + BigInteger[] params = fips.generateParameters(); + BigInteger p = params[3]; + BigInteger q = params[2]; + BigInteger g = params[5]; + DSAParameterSpec spec = new DSAParameterSpec(p, q, g); + AlgorithmParameters result = null; + try + { + result = AlgorithmParameters.getInstance(Registry.DSS_KPG, GNU); + result.init(spec); + } + catch (NoSuchAlgorithmException ignore) + { + } + catch (InvalidParameterSpecException ignore) + { + } + return result; + } +} diff --git a/libjava/classpath/gnu/java/security/jce/sig/DSSRawSignatureSpi.java b/libjava/classpath/gnu/java/security/jce/sig/DSSRawSignatureSpi.java new file mode 100644 index 00000000000..16e4ddd4edc --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/DSSRawSignatureSpi.java @@ -0,0 +1,70 @@ +/* DSSRawSignatureSpi.java -- + Copyright 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.Registry; +import gnu.java.security.sig.dss.DSSSignatureRawCodec; + +/** + * The implementation of <i>Service Provider Interface</i> (<b>SPI</b>) adapter + * for the DSS (Digital Signature Standard) signature scheme, encoded and/or + * decoded in RAW format.<p> + * + * @version $Revision: 1.1 $ + */ +public class DSSRawSignatureSpi extends SignatureAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public DSSRawSignatureSpi() + { + super(Registry.DSS_SIG, new DSSSignatureRawCodec()); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/jce/sig/EncodedKeyFactory.java b/libjava/classpath/gnu/java/security/jce/sig/EncodedKeyFactory.java new file mode 100644 index 00000000000..60152c279fa --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/EncodedKeyFactory.java @@ -0,0 +1,453 @@ +/* EncodedKeyFactory.java -- JCE Encoded key factory Adapter + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.Registry; +import gnu.java.security.key.dss.DSSPrivateKey; +import gnu.java.security.key.dss.DSSPublicKey; +import gnu.java.security.key.rsa.GnuRSAPrivateKey; +import gnu.java.security.key.rsa.GnuRSAPublicKey; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.InvalidParameterException; +import java.security.Key; +import java.security.KeyFactorySpi; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.DSAPrivateKeySpec; +import java.security.spec.DSAPublicKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.crypto.interfaces.DHPrivateKey; +import javax.crypto.interfaces.DHPublicKey; +import javax.crypto.spec.DHPrivateKeySpec; +import javax.crypto.spec.DHPublicKeySpec; + +/** + * A factory for keys encoded in either the X.509 format (for public keys) or + * the PKCS#8 format (for private keys). + */ +public class EncodedKeyFactory + extends KeyFactorySpi +{ + private static final Logger log = Logger.getLogger(EncodedKeyFactory.class.getName()); + + // implicit 0-arguments constructor + + // Class methods + // -------------------------------------------------------------------------- + + private static Object invokeConstructor(String className, Object[] params) + throws InvalidKeySpecException + { + Class clazz = getConcreteClass(className); + try + { + Constructor ctor = getConcreteCtor(clazz); + Object result = ctor.newInstance(params); + return result; + } + catch (InstantiationException x) + { + InvalidKeySpecException y = new InvalidKeySpecException(); + y.initCause(x); + throw y; + } + catch (IllegalAccessException x) + { + InvalidKeySpecException y = new InvalidKeySpecException(); + y.initCause(y); + throw y; + } + catch (InvocationTargetException x) + { + InvalidKeySpecException y = new InvalidKeySpecException(); + y.initCause(x); + throw y; + } + } + + private static Class getConcreteClass(String className) + throws InvalidKeySpecException + { + try + { + Class result = Class.forName(className); + return result; + } + catch (ClassNotFoundException x) + { + InvalidKeySpecException y = new InvalidKeySpecException(); + y.initCause(x); + throw y; + } + } + + private static Constructor getConcreteCtor(Class clazz) + throws InvalidKeySpecException + { + try + { + Constructor result = clazz.getConstructor(new Class[] {int.class, + BigInteger.class, + BigInteger.class, + BigInteger.class, + BigInteger.class}); + return result; + } + catch (NoSuchMethodException x) + { + InvalidKeySpecException y = new InvalidKeySpecException(); + y.initCause(x); + throw y; + } + } + + private static Object invokeValueOf(String className, byte[] encoded) + throws InvalidKeySpecException + { + Class clazz = getConcreteClass(className); + try + { + Method valueOf = getValueOfMethod(clazz); + Object result = valueOf.invoke(null, new Object[] { encoded }); + return result; + } + catch (IllegalAccessException x) + { + InvalidKeySpecException y = new InvalidKeySpecException(); + y.initCause(x); + throw y; + } + catch (InvocationTargetException x) + { + InvalidKeySpecException y = new InvalidKeySpecException(); + y.initCause(x); + throw y; + } + } + + private static Method getValueOfMethod(Class clazz) + throws InvalidKeySpecException + { + try + { + Method result = clazz.getMethod("valueOf", new Class[] {byte[].class}); + return result; + } + catch (NoSuchMethodException x) + { + InvalidKeySpecException y = new InvalidKeySpecException(); + y.initCause(x); + throw y; + } + } + + // Instance methods + // -------------------------------------------------------------------------- + + protected PublicKey engineGeneratePublic(KeySpec keySpec) + throws InvalidKeySpecException + { + log.entering(this.getClass().getName(), "engineGeneratePublic()", keySpec); + + PublicKey result = null; + if (keySpec instanceof DSAPublicKeySpec) + result = decodeDSSPublicKey((DSAPublicKeySpec) keySpec); + else if (keySpec instanceof RSAPublicKeySpec) + result = decodeRSAPublicKey((RSAPublicKeySpec) keySpec); + else if (keySpec instanceof DHPublicKeySpec) + result = decodeDHPublicKey((DHPublicKeySpec) keySpec); + else + { + if (! (keySpec instanceof X509EncodedKeySpec)) + throw new InvalidKeySpecException("Unsupported key specification"); + + byte[] input = ((X509EncodedKeySpec) keySpec).getEncoded(); + boolean ok = false; + // try DSS + try + { + result = DSSPublicKey.valueOf(input); + ok = true; + } + catch (InvalidParameterException ignored) + { + log.log(Level.FINE, "Exception in DSSPublicKey.valueOf(). Ignore", + ignored); + } + + if (! ok) // try RSA + try + { + result = GnuRSAPublicKey.valueOf(input); + ok = true; + } + catch (InvalidParameterException ignored) + { + log.log(Level.FINE, + "Exception in GnuRSAPublicKey.valueOf(). Ignore", + ignored); + } + + if (! ok) // try DH + result = decodeDHPublicKey(input); + } + + log.exiting(this.getClass().getName(), "engineGeneratePublic()", result); + return result; + } + + protected PrivateKey engineGeneratePrivate(KeySpec keySpec) + throws InvalidKeySpecException + { + log.entering(this.getClass().getName(), "engineGeneratePrivate()", keySpec); + + PrivateKey result = null; + if (keySpec instanceof DSAPrivateKeySpec) + result = decodeDSSPrivateKey((DSAPrivateKeySpec) keySpec); + else if (keySpec instanceof RSAPrivateCrtKeySpec) + result = decodeRSAPrivateKey((RSAPrivateCrtKeySpec) keySpec); + else if (keySpec instanceof DHPrivateKeySpec) + result = decodeDHPrivateKey((DHPrivateKeySpec) keySpec); + else + { + if (! (keySpec instanceof PKCS8EncodedKeySpec)) + throw new InvalidKeySpecException("Unsupported key specification"); + + byte[] input = ((PKCS8EncodedKeySpec) keySpec).getEncoded(); + boolean ok = false; + // try DSS + try + { + result = DSSPrivateKey.valueOf(input); + ok = true; + } + catch (InvalidParameterException ignored) + { + log.log(Level.FINE, "Exception in DSSPrivateKey.valueOf(). Ignore", + ignored); + } + + if (! ok) // try RSA + try + { + result = GnuRSAPrivateKey.valueOf(input); + ok = true; + } + catch (InvalidParameterException ignored) + { + log.log(Level.FINE, + "Exception in GnuRSAPrivateKey.valueOf(). Ignore", + ignored); + } + + if (! ok) // try DH + result = decodeDHPrivateKey(input); + } + + log.exiting(this.getClass().getName(), "engineGeneratePrivate()", result); + return result; + } + + protected KeySpec engineGetKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException + { + if (key instanceof PublicKey + && Registry.X509_ENCODING_SORT_NAME.equalsIgnoreCase(key.getFormat()) + && keySpec.isAssignableFrom(X509EncodedKeySpec.class)) + return new X509EncodedKeySpec(key.getEncoded()); + + if (key instanceof PrivateKey + && Registry.PKCS8_ENCODING_SHORT_NAME.equalsIgnoreCase(key.getFormat()) + && keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class)) + return new PKCS8EncodedKeySpec(key.getEncoded()); + + throw new InvalidKeySpecException("Unsupported format or invalid key spec class"); + } + + protected Key engineTranslateKey(Key key) throws InvalidKeyException + { + throw new InvalidKeyException("Key translation not supported"); + } + + /** + * @param spec an instance of {@link DSAPublicKeySpec} to decode. + * @return an instance of {@link DSSPublicKey} constructed from the + * information in the designated key-specification. + */ + private DSSPublicKey decodeDSSPublicKey(DSAPublicKeySpec spec) + { + BigInteger p = spec.getP(); + BigInteger q = spec.getQ(); + BigInteger g = spec.getG(); + BigInteger y = spec.getY(); + return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y); + } + + /** + * @param spec an instance of {@link RSAPublicKeySpec} to decode. + * @return an instance of {@link GnuRSAPublicKey} constructed from the + * information in the designated key-specification. + */ + private GnuRSAPublicKey decodeRSAPublicKey(RSAPublicKeySpec spec) + { + BigInteger n = spec.getModulus(); + BigInteger e = spec.getPublicExponent(); + return new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e); + } + + /** + * @param spec an instance of {@link DHPublicKeySpec} to decode. + * @return an instance of a {@link DHPublicKey} constructed from the + * information in the designated key-specification. + * @throws InvalidKeySpecException if no concrete implementation of the + * {@link DHPublicKey} interface exists at run-time, or if an + * exception occurs during its instantiation. + */ + private DHPublicKey decodeDHPublicKey(DHPublicKeySpec spec) + throws InvalidKeySpecException + { + BigInteger p = spec.getP(); + BigInteger g = spec.getG(); + BigInteger y = spec.getY(); + Object[] params = new Object[] {new Integer(Registry.X509_ENCODING_ID), + null, p, g, y}; + Object obj = invokeConstructor("gnu.javax.crypto.key.dh.GnuDHPublicKey", + params); + return (DHPublicKey) obj; + } + + /** + * @param encoded the bytes to decode. + * @return an instance of a {@link DHPublicKey} constructed from the + * information in the designated key-specification. + * @throws InvalidKeySpecException if no concrete implementation of the + * {@link DHPublicKey} interface exists at run-time, or if an + * exception occurs during its instantiation. + */ + private DHPublicKey decodeDHPublicKey(byte[] encoded) + throws InvalidKeySpecException + { + Object obj = invokeValueOf("gnu.javax.crypto.key.dh.GnuDHPublicKey", + encoded); + return (DHPublicKey) obj; + } + + /** + * @param spec an instance of {@link DSAPrivateKeySpec} to decode. + * @return an instance of {@link DSSPrivateKey} constructed from the + * information in the designated key-specification. + */ + private PrivateKey decodeDSSPrivateKey(DSAPrivateKeySpec spec) + { + BigInteger p = spec.getP(); + BigInteger q = spec.getQ(); + BigInteger g = spec.getG(); + BigInteger x = spec.getX(); + return new DSSPrivateKey(Registry.PKCS8_ENCODING_ID, p, q, g, x); + } + + /** + * @param spec an instance of {@link RSAPrivateCrtKeySpec} to decode. + * @return an instance of {@link GnuRSAPrivateKey} constructed from the + * information in the designated key-specification. + */ + private PrivateKey decodeRSAPrivateKey(RSAPrivateCrtKeySpec spec) + { + BigInteger n = spec.getModulus(); + BigInteger e = spec.getPublicExponent(); + BigInteger d = spec.getPrivateExponent(); + BigInteger p = spec.getPrimeP(); + BigInteger q = spec.getPrimeQ(); + BigInteger dP = spec.getPrimeExponentP(); + BigInteger dQ = spec.getPrimeExponentQ(); + BigInteger qInv = spec.getCrtCoefficient(); + return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID, + n, e, d, p, q, dP, dQ, qInv); + } + + /** + * @param spec an instance of {@link DHPrivateKeySpec} to decode. + * @return an instance of a {@link DHPrivateKey} constructed from the + * information in the designated key-specification. + * @throws InvalidKeySpecException if no concrete implementation of the + * {@link DHPrivateKey} interface exists at run-time, or if an + * exception occurs during its instantiation. + */ + private DHPrivateKey decodeDHPrivateKey(DHPrivateKeySpec spec) + throws InvalidKeySpecException + { + BigInteger p = spec.getP(); + BigInteger g = spec.getG(); + BigInteger x = spec.getX(); + Object[] params = new Object[] {new Integer(Registry.PKCS8_ENCODING_ID), + null, p, g, x}; + Object obj = invokeConstructor("gnu.javax.crypto.key.dh.GnuDHPrivateKey", + params); + return (DHPrivateKey) obj; + } + + /** + * @param encoded the bytes to decode. + * @return an instance of a {@link DHPrivateKey} constructed from the + * information in the designated key-specification. + * @throws InvalidKeySpecException if no concrete implementation of the + * {@link DHPrivateKey} interface exists at run-time, or if an + * exception occurs during its instantiation. + */ + private DHPrivateKey decodeDHPrivateKey(byte[] encoded) + throws InvalidKeySpecException + { + Object obj = invokeValueOf("gnu.javax.crypto.key.dh.GnuDHPrivateKey", + encoded); + return (DHPrivateKey) obj; + } +} diff --git a/libjava/classpath/gnu/java/security/jce/sig/KeyPairGeneratorAdapter.java b/libjava/classpath/gnu/java/security/jce/sig/KeyPairGeneratorAdapter.java new file mode 100644 index 00000000000..60268299188 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/KeyPairGeneratorAdapter.java @@ -0,0 +1,109 @@ +/* KeyPairGeneratorAdapter.java -- + Copyright 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.key.IKeyPairGenerator; +import gnu.java.security.key.KeyPairGeneratorFactory; + +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; + +/** + * The implementation of a generic {@link java.security.KeyPairGenerator} + * adapter class to wrap gnu.crypto keypair generator instances.<p> + * + * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) for the + * {@link java.security.KeyPairGenerator} class, which is used to generate pairs + * of public and private keys.<p> + * + * All the abstract methods in the {@link java.security.KeyPairGeneratorSpi} + * class are implemented by this class and all its sub-classes.<p> + * + * In case the client does not explicitly initialize the KeyPairGenerator (via + * a call to an <code>initialize()</code> method), the GNU Crypto provider + * supplies (and document) default values to be used. For example, the GNU + * Crypto provider uses a default <i>modulus</i> size (keysize) of 1024 bits for + * the DSS (Digital Signature Standard) a.k.a <i>DSA</i>.<p> + * + * @version $Revision: 1.3 $ + */ +public abstract class KeyPairGeneratorAdapter extends KeyPairGenerator +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** Our underlying keypair instance. */ + protected IKeyPairGenerator adaptee; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Trivial protected constructor. + * + * @param kpgName the canonical name of the keypair generator algorithm. + */ + protected KeyPairGeneratorAdapter(String kpgName) + { + super(kpgName); + + this.adaptee = KeyPairGeneratorFactory.getInstance(kpgName); + } + + // Class methods + // ------------------------------------------------------------------------- + + // java.security.KeyPairGeneratorSpi interface implementation + // ------------------------------------------------------------------------- + + public abstract void initialize(int keysize, SecureRandom random); + + public abstract void initialize(AlgorithmParameterSpec params, + SecureRandom random) + throws InvalidAlgorithmParameterException; + + public KeyPair generateKeyPair() + { + return adaptee.generate(); + } +} diff --git a/libjava/classpath/gnu/java/security/provider/MD2withRSA.java b/libjava/classpath/gnu/java/security/jce/sig/MD2withRSA.java index a72ae5588dc..353be218555 100644 --- a/libjava/classpath/gnu/java/security/provider/MD2withRSA.java +++ b/libjava/classpath/gnu/java/security/jce/sig/MD2withRSA.java @@ -1,5 +1,5 @@ -/* MD2withRSA.java -- MD2 with RSA encryption signatures. - Copyright (C) 2004 Free Software Foundation, Inc. +/* MD2WithRSA.java -- RSA PKCS1 with MD2 JCE signature Adapter + Copyright (C) 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -36,19 +36,21 @@ obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -package gnu.java.security.provider; +package gnu.java.security.jce.sig; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; +import gnu.java.security.Registry; +import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec; -public class MD2withRSA extends RSA +/** + * A JCE Adapter for the RSA PKCS1 (v1.5) signature with MD2 hash and X.509 + * encoding format. + */ +public class MD2withRSA + extends SignatureAdapter { - - // Constructor. - // ------------------------------------------------------------------------- - - public MD2withRSA() throws NoSuchAlgorithmException + public MD2withRSA() { - super(MessageDigest.getInstance("MD2"), DIGEST_ALGORITHM.getChild(2)); + super(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.MD2_HASH, + new RSAPKCS1V1_5SignatureX509Codec()); } } diff --git a/libjava/classpath/gnu/java/security/provider/MD5withRSA.java b/libjava/classpath/gnu/java/security/jce/sig/MD5withRSA.java index 721d897ed24..42c481b0a6d 100644 --- a/libjava/classpath/gnu/java/security/provider/MD5withRSA.java +++ b/libjava/classpath/gnu/java/security/jce/sig/MD5withRSA.java @@ -1,5 +1,5 @@ -/* MD5withRSA.java -- MD5 with RSA encryption signatures. - Copyright (C) 2004 Free Software Foundation, Inc. +/* MD5withRSA.java -- RSA PKCS1 with MD5 JCE signature Adapter + Copyright (C) 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -36,19 +36,21 @@ obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -package gnu.java.security.provider; +package gnu.java.security.jce.sig; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; +import gnu.java.security.Registry; +import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec; -public class MD5withRSA extends RSA +/** + * A JCE Adapter for the RSA PKCS1 (v1.5) signature with MD5 hash and X.509 + * encoding format. + */ +public class MD5withRSA + extends SignatureAdapter { - - // Constructor. - // ------------------------------------------------------------------------- - - public MD5withRSA() throws NoSuchAlgorithmException + public MD5withRSA() { - super(MessageDigest.getInstance("MD5"), DIGEST_ALGORITHM.getChild(5)); + super(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.MD5_HASH, + new RSAPKCS1V1_5SignatureX509Codec()); } } diff --git a/libjava/classpath/gnu/java/security/jce/sig/RSAKeyFactory.java b/libjava/classpath/gnu/java/security/jce/sig/RSAKeyFactory.java new file mode 100644 index 00000000000..fecf54cb8e9 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/RSAKeyFactory.java @@ -0,0 +1,265 @@ +/* RSAKeyFactory.java -- RSA key-factory JCE Adapter + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.Registry; +import gnu.java.security.key.rsa.GnuRSAPrivateKey; +import gnu.java.security.key.rsa.GnuRSAPublicKey; +import gnu.java.security.key.rsa.RSAKeyPairPKCS8Codec; +import gnu.java.security.key.rsa.RSAKeyPairX509Codec; + +import java.math.BigInteger; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactorySpi; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPrivateKeySpec; +import java.security.spec.RSAPublicKeySpec; +import java.security.spec.X509EncodedKeySpec; + +public class RSAKeyFactory + extends KeyFactorySpi +{ + // implicit 0-arguments constructor + + protected PublicKey engineGeneratePublic(KeySpec keySpec) + throws InvalidKeySpecException + { + if (keySpec instanceof RSAPublicKeySpec) + { + RSAPublicKeySpec spec = (RSAPublicKeySpec) keySpec; + BigInteger n = spec.getModulus(); + BigInteger e = spec.getPublicExponent(); + return new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e); + } + + if (keySpec instanceof X509EncodedKeySpec) + { + X509EncodedKeySpec spec = (X509EncodedKeySpec) keySpec; + byte[] encoded = spec.getEncoded(); + PublicKey result; + try + { + result = new RSAKeyPairX509Codec().decodePublicKey(encoded); + } + catch (RuntimeException x) + { + InvalidKeySpecException y = new InvalidKeySpecException(); + y.initCause(x); + throw y; + } + } + + throw new InvalidKeySpecException("Unsupported (public) key specification"); + } + + protected PrivateKey engineGeneratePrivate(KeySpec keySpec) + throws InvalidKeySpecException + { + if (keySpec instanceof RSAPrivateCrtKeySpec) + { + RSAPrivateCrtKeySpec spec = (RSAPrivateCrtKeySpec) keySpec; + BigInteger n = spec.getModulus(); + BigInteger e = spec.getPublicExponent(); + BigInteger d = spec.getPrivateExponent(); + BigInteger p = spec.getPrimeP(); + BigInteger q = spec.getPrimeQ(); + BigInteger dP = spec.getPrimeExponentP(); + BigInteger dQ = spec.getPrimeExponentQ(); + BigInteger qInv = spec.getCrtCoefficient(); + return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID, + n, e, d, p, q, dP, dQ, qInv); + } + +// if (keySpec instanceof RSAPrivateKeySpec) +// { +// RSAPrivateKeySpec spec = (RSAPrivateKeySpec) keySpec; +// BigInteger n = spec.getModulus(); +// BigInteger d = spec.getPrivateExponent(); +// return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID, +// n, null, d, null, null, null, null, null); +// } + + if (keySpec instanceof PKCS8EncodedKeySpec) + { + PKCS8EncodedKeySpec spec = (PKCS8EncodedKeySpec) keySpec; + byte[] encoded = spec.getEncoded(); + PrivateKey result; + try + { + result = new RSAKeyPairPKCS8Codec().decodePrivateKey(encoded); + } + catch (RuntimeException x) + { + InvalidKeySpecException y = new InvalidKeySpecException(); + y.initCause(x); + throw y; + } + } + + throw new InvalidKeySpecException("Unsupported (private) key specification"); + } + + protected KeySpec engineGetKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException + { + if (key instanceof RSAPublicKey) + { + if (keySpec.isAssignableFrom(RSAPublicKeySpec.class)) + { + RSAPublicKey rsaKey = (RSAPublicKey) key; + BigInteger n = rsaKey.getModulus(); + BigInteger e = rsaKey.getPublicExponent(); + return new RSAPublicKeySpec(n, e); + } + + if (keySpec.isAssignableFrom(X509EncodedKeySpec.class)) + { + if (key instanceof GnuRSAPublicKey) + { + GnuRSAPublicKey rsaKey = (GnuRSAPublicKey) key; + byte[] encoded = rsaKey.getEncoded(Registry.X509_ENCODING_ID); + return new X509EncodedKeySpec(encoded); + } + + if (Registry.X509_ENCODING_SORT_NAME.equalsIgnoreCase(key.getFormat())) + { + byte[] encoded = key.getEncoded(); + return new X509EncodedKeySpec(encoded); + } + + throw new InvalidKeySpecException("Wrong key type or unsupported (public) key specification"); + } + + throw new InvalidKeySpecException("Unsupported (public) key specification"); + } + + if ((key instanceof RSAPrivateCrtKey) + && keySpec.isAssignableFrom(RSAPrivateCrtKeySpec.class)) + { + RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key; + BigInteger n = rsaKey.getModulus(); + BigInteger e = rsaKey.getPublicExponent(); + BigInteger d = rsaKey.getPrivateExponent(); + BigInteger p = rsaKey.getPrimeP(); + BigInteger q = rsaKey.getPrimeQ(); + BigInteger dP = rsaKey.getPrimeExponentP(); + BigInteger dQ = rsaKey.getPrimeExponentQ(); + BigInteger qInv = rsaKey.getCrtCoefficient(); + return new RSAPrivateCrtKeySpec(n, e, d, p, q, dP, dQ, qInv); + } + + if ((key instanceof RSAPrivateKey) + && keySpec.isAssignableFrom(RSAPrivateKeySpec.class)) + { + RSAPrivateKey rsaKey = (RSAPrivateKey) key; + BigInteger n = rsaKey.getModulus(); + BigInteger d = rsaKey.getPrivateExponent(); + return new RSAPrivateKeySpec(n, d); + } + + if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class)) + { + if (key instanceof GnuRSAPrivateKey) + { + GnuRSAPrivateKey rsaKey = (GnuRSAPrivateKey) key; + byte[] encoded = rsaKey.getEncoded(Registry.PKCS8_ENCODING_ID); + return new PKCS8EncodedKeySpec(encoded); + } + + if (Registry.PKCS8_ENCODING_SHORT_NAME.equalsIgnoreCase(key.getFormat())) + { + byte[] encoded = key.getEncoded(); + return new PKCS8EncodedKeySpec(encoded); + } + + throw new InvalidKeySpecException("Wrong key type or unsupported (private) key specification"); + } + + throw new InvalidKeySpecException("Wrong key type or unsupported key specification"); + } + + protected Key engineTranslateKey(Key key) throws InvalidKeyException + { + if ((key instanceof GnuRSAPublicKey) || (key instanceof GnuRSAPrivateKey)) + return key; + + if (key instanceof RSAPublicKey) + { + RSAPublicKey rsaKey = (RSAPublicKey) key; + BigInteger n = rsaKey.getModulus(); + BigInteger e = rsaKey.getPublicExponent(); + return new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e); + } + + if (key instanceof RSAPrivateCrtKey) + { + RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key; + BigInteger n = rsaKey.getModulus(); + BigInteger e = rsaKey.getPublicExponent(); + BigInteger d = rsaKey.getPrivateExponent(); + BigInteger p = rsaKey.getPrimeP(); + BigInteger q = rsaKey.getPrimeQ(); + BigInteger dP = rsaKey.getPrimeExponentP(); + BigInteger dQ = rsaKey.getPrimeExponentQ(); + BigInteger qInv = rsaKey.getCrtCoefficient(); + return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID, + n, e, d, p, q, dP, dQ, qInv); + } + +// if (key instanceof RSAPrivateKey) +// { +// RSAPrivateKey rsaKey = (RSAPrivateKey) key; +// BigInteger n = rsaKey.getModulus(); +// BigInteger d = rsaKey.getPrivateExponent(); +// return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID, +// n, null, d, null, null, null, null, null); +// } + + throw new InvalidKeyException("Unsupported key type"); + } +} diff --git a/libjava/classpath/gnu/java/security/jce/sig/RSAKeyPairGeneratorSpi.java b/libjava/classpath/gnu/java/security/jce/sig/RSAKeyPairGeneratorSpi.java new file mode 100644 index 00000000000..24dc7c50177 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/RSAKeyPairGeneratorSpi.java @@ -0,0 +1,115 @@ +/* RSAKeyPairGeneratorSpi.java -- JCE RSA KeyPairGenerator Adapter + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.Registry; +import gnu.java.security.key.rsa.RSAKeyPairGenerator; + +import java.security.InvalidAlgorithmParameterException; +import java.security.SecureRandom; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.RSAKeyGenParameterSpec; +import java.util.HashMap; + +/** + * The implementation of a {@link java.security.KeyPairGenerator} adapter class + * to wrap gnu.crypto RSA keypair generator instances.<p> + * + * In case the client does not explicitly initialize the KeyPairGenerator (via + * a call to an <code>initialize()</code> method), the GNU Crypto provider + * uses a default <i>modulus</i> size (keysize) of 1024 bits.<p> + */ +public class RSAKeyPairGeneratorSpi extends KeyPairGeneratorAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public RSAKeyPairGeneratorSpi() + { + super(Registry.RSA_KPG); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + public void initialize(int keysize, SecureRandom random) + { + HashMap attributes = new HashMap(); + attributes.put(RSAKeyPairGenerator.MODULUS_LENGTH, new Integer(keysize)); + if (random != null) + { + attributes.put(RSAKeyPairGenerator.SOURCE_OF_RANDOMNESS, random); + } + + attributes.put(RSAKeyPairGenerator.PREFERRED_ENCODING_FORMAT, + new Integer(Registry.ASN1_ENCODING_ID)); + adaptee.setup(attributes); + } + + public void initialize(AlgorithmParameterSpec params, SecureRandom random) + throws InvalidAlgorithmParameterException + { + HashMap attributes = new HashMap(); + if (params != null) + { + if (!(params instanceof RSAKeyGenParameterSpec)) + { + throw new InvalidAlgorithmParameterException("params"); + } + + attributes.put(RSAKeyPairGenerator.RSA_PARAMETERS, params); + } + + if (random != null) + { + attributes.put(RSAKeyPairGenerator.SOURCE_OF_RANDOMNESS, random); + } + + attributes.put(RSAKeyPairGenerator.PREFERRED_ENCODING_FORMAT, + new Integer(Registry.ASN1_ENCODING_ID)); + adaptee.setup(attributes); + } +} diff --git a/libjava/classpath/gnu/java/security/jce/sig/RSAPSSRawSignatureSpi.java b/libjava/classpath/gnu/java/security/jce/sig/RSAPSSRawSignatureSpi.java new file mode 100644 index 00000000000..e44b8adf14d --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/RSAPSSRawSignatureSpi.java @@ -0,0 +1,69 @@ +/* RSAPSSRawSignatureSpi.java -- + Copyright 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.Registry; +import gnu.java.security.sig.rsa.RSAPSSSignatureRawCodec; + +/** + * The implementation of <i>Service Provider Interface</i> (<b>SPI</b>) adapter + * for the RSA-PSS signature scheme, encoded and/or decoded in RAW format.<p> + * + * @version $Revision: 1.1 $ + */ +public class RSAPSSRawSignatureSpi extends SignatureAdapter +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public RSAPSSRawSignatureSpi() + { + super(Registry.RSA_PSS_SIG, new RSAPSSSignatureRawCodec()); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/provider/MD4withRSA.java b/libjava/classpath/gnu/java/security/jce/sig/SHA160withDSS.java index 76a6a1ad033..c55139f4658 100644 --- a/libjava/classpath/gnu/java/security/provider/MD4withRSA.java +++ b/libjava/classpath/gnu/java/security/jce/sig/SHA160withDSS.java @@ -1,5 +1,5 @@ -/* MD4withRSA.java -- MD4 with RSA encryption signatures. - Copyright (C) 2004 Free Software Foundation, Inc. +/* SHA160withDSS.java -- JCE Adapter for DSS with SHA1 signatures + Copyright (C) 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -36,19 +36,19 @@ obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -package gnu.java.security.provider; +package gnu.java.security.jce.sig; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; +import gnu.java.security.Registry; +import gnu.java.security.sig.dss.DSSSignatureX509Codec; -public class MD4withRSA extends RSA +/** + * A JCE Adapter for providing X.509 formatted DSS with SHA1 signatures. + */ +public class SHA160withDSS + extends SignatureAdapter { - - // Constructor. - // ------------------------------------------------------------------------- - - public MD4withRSA() throws NoSuchAlgorithmException + public SHA160withDSS() { - super(MessageDigest.getInstance("MD4"), DIGEST_ALGORITHM.getChild(4)); + super(Registry.DSS_SIG, new DSSSignatureX509Codec()); } } diff --git a/libjava/classpath/gnu/java/security/provider/SHA1withRSA.java b/libjava/classpath/gnu/java/security/jce/sig/SHA160withRSA.java index 0e63fdeeb52..d3b2054e0ea 100644 --- a/libjava/classpath/gnu/java/security/provider/SHA1withRSA.java +++ b/libjava/classpath/gnu/java/security/jce/sig/SHA160withRSA.java @@ -1,5 +1,5 @@ -/* SHA1withRSA.java -- SHA-1 with RSA encryption signatures. - Copyright (C) 2004 Free Software Foundation, Inc. +/* SHA160withRSA.java -- RSA PKCS1 with SHA160 JCE signature Adapter + Copyright (C) 2006 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -36,26 +36,21 @@ obligated to do so. If you do not wish to do so, delete this exception statement from your version. */ -package gnu.java.security.provider; +package gnu.java.security.jce.sig; -import gnu.java.security.OID; +import gnu.java.security.Registry; +import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - -public class SHA1withRSA extends RSA +/** + * A JCE Adapter for the RSA PKCS1 (v1.5) signature with SHA160 hash and X.509 + * encoding format. + */ +public class SHA160withRSA + extends SignatureAdapter { - - // Constant. - // ------------------------------------------------------------------------- - - private static final OID SHA1 = new OID("1.3.14.3.2.26"); - - // Constructor. - // ------------------------------------------------------------------------- - - public SHA1withRSA() throws NoSuchAlgorithmException + public SHA160withRSA() { - super(MessageDigest.getInstance("SHA-160"), SHA1); + super(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.SHA160_HASH, + new RSAPKCS1V1_5SignatureX509Codec()); } } diff --git a/libjava/classpath/gnu/java/security/jce/sig/SHA256withRSA.java b/libjava/classpath/gnu/java/security/jce/sig/SHA256withRSA.java new file mode 100644 index 00000000000..d21888b5993 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/SHA256withRSA.java @@ -0,0 +1,56 @@ +/* SHA256withRSA.java -- RSA PKCS1 with SHA256 JCE signature Adapter + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.Registry; +import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec; + +/** + * A JCE Adapter for the RSA PKCS1 (v1.5) signature with SHA256 hash and X.509 + * encoding format. + */ +public class SHA256withRSA + extends SignatureAdapter +{ + public SHA256withRSA() + { + super(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.SHA256_HASH, + new RSAPKCS1V1_5SignatureX509Codec()); + } +} diff --git a/libjava/classpath/gnu/java/security/jce/sig/SHA384withRSA.java b/libjava/classpath/gnu/java/security/jce/sig/SHA384withRSA.java new file mode 100644 index 00000000000..5495ec1caa0 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/SHA384withRSA.java @@ -0,0 +1,56 @@ +/* SHA384withRSA.java -- RSA PKCS1 with SHA384 JCE signature Adapter + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.Registry; +import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec; + +/** + * A JCE Adapter for the RSA PKCS1 (v1.5) signature with SHA384 hash and X.509 + * encoding format. + */ +public class SHA384withRSA + extends SignatureAdapter +{ + public SHA384withRSA() + { + super(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.SHA384_HASH, + new RSAPKCS1V1_5SignatureX509Codec()); + } +} diff --git a/libjava/classpath/gnu/java/security/jce/sig/SHA512withRSA.java b/libjava/classpath/gnu/java/security/jce/sig/SHA512withRSA.java new file mode 100644 index 00000000000..f7632290ab6 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/SHA512withRSA.java @@ -0,0 +1,56 @@ +/* SHA512withRSA.java -- RSA PKCS1 with SHA512 JCE signature Adapter + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.Registry; +import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec; + +/** + * A JCE Adapter for the RSA PKCS1 (v1.5) signature with SHA512 hash and X.509 + * encoding format. + */ +public class SHA512withRSA + extends SignatureAdapter +{ + public SHA512withRSA() + { + super(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.SHA512_HASH, + new RSAPKCS1V1_5SignatureX509Codec()); + } +} diff --git a/libjava/classpath/gnu/java/security/jce/sig/SignatureAdapter.java b/libjava/classpath/gnu/java/security/jce/sig/SignatureAdapter.java new file mode 100644 index 00000000000..6cb7c7c7128 --- /dev/null +++ b/libjava/classpath/gnu/java/security/jce/sig/SignatureAdapter.java @@ -0,0 +1,263 @@ +/* SignatureAdapter.java -- + Copyright 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.jce.sig; + +import gnu.java.security.sig.BaseSignature; +import gnu.java.security.sig.ISignature; +import gnu.java.security.sig.ISignatureCodec; +import gnu.java.security.sig.SignatureFactory; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.InvalidParameterException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.SignatureException; +import java.security.SignatureSpi; +import java.security.spec.AlgorithmParameterSpec; +import java.util.HashMap; +import java.util.logging.Logger; + +/** + * The implementation of a generic {@link java.security.Signature} adapter class + * to wrap gnu.crypto signature instances.<p> + * + * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>) for the + * {@link java.security.Signature} class, which provides 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 the {@link java.security.SignatureSpi} class are + * implemented by this class and all its sub-classes.<p> + * + * All the implementations which subclass this object, and which are serviced by + * the GNU Crypto provider implement the {@link java.lang.Cloneable} interface.<p> + * + * @version $Revision: 1.2 $ + */ +class SignatureAdapter extends SignatureSpi implements Cloneable +{ + private static final Logger log = Logger.getLogger(SignatureAdapter.class.getName()); + + // Constants and variables + // ------------------------------------------------------------------------- + + /** Our underlying signature instance. */ + private ISignature adaptee; + + /** Our underlying signature encoder/decoder engine. */ + private ISignatureCodec codec; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Trivial protected constructor.<p> + * + * @param sigName the canonical name of the signature scheme. + * @param codec the signature codec engine to use with this scheme. + */ + protected SignatureAdapter(String sigName, ISignatureCodec codec) + { + this(SignatureFactory.getInstance(sigName), codec); + } + + /** + * Private constructor for cloning purposes.<p> + * + * @param adaptee a clone of the underlying signature scheme instance. + * @param codec the signature codec engine to use with this scheme. + */ + private SignatureAdapter(ISignature adaptee, ISignatureCodec codec) + { + super(); + + this.adaptee = adaptee; + this.codec = codec; + } + + // Class methods + // ------------------------------------------------------------------------- + + // java.security.SignatureSpi interface implementation + // ------------------------------------------------------------------------- + + public Object clone() + { + return new SignatureAdapter((ISignature) adaptee.clone(), codec); + } + + public void engineInitVerify(PublicKey publicKey) throws InvalidKeyException + { + HashMap attributes = new HashMap(); + attributes.put(BaseSignature.VERIFIER_KEY, publicKey); + try + { + adaptee.setupVerify(attributes); + } + catch (IllegalArgumentException x) + { + throw new InvalidKeyException(String.valueOf(x)); + } + } + + public void engineInitSign(PrivateKey privateKey) throws InvalidKeyException + { + HashMap attributes = new HashMap(); + attributes.put(BaseSignature.SIGNER_KEY, privateKey); + try + { + adaptee.setupSign(attributes); + } + catch (IllegalArgumentException x) + { + throw new InvalidKeyException(String.valueOf(x)); + } + } + + public void engineInitSign(PrivateKey privateKey, SecureRandom random) + throws InvalidKeyException + { + HashMap attributes = new HashMap(); + attributes.put(BaseSignature.SIGNER_KEY, privateKey); + attributes.put(BaseSignature.SOURCE_OF_RANDOMNESS, random); + try + { + adaptee.setupSign(attributes); + } + catch (IllegalArgumentException x) + { + throw new InvalidKeyException(String.valueOf(x)); + } + } + + public void engineUpdate(byte b) throws SignatureException + { + try + { + adaptee.update(b); + } + catch (IllegalStateException x) + { + throw new SignatureException(String.valueOf(x)); + } + } + + public void engineUpdate(byte[] b, int off, int len) + throws SignatureException + { + try + { + adaptee.update(b, off, len); + } + catch (IllegalStateException x) + { + throw new SignatureException(String.valueOf(x)); + } + } + + public byte[] engineSign() throws SignatureException + { + Object signature = null; + try + { + signature = adaptee.sign(); + } + catch (IllegalStateException x) + { + throw new SignatureException(String.valueOf(x)); + } + + byte[] result = codec.encodeSignature(signature); + return result; + } + + public int engineSign(byte[] outbuf, int offset, int len) + throws SignatureException + { + byte[] signature = this.engineSign(); + int result = signature.length; + if (result > len) + { + throw new SignatureException("len"); + } + + System.arraycopy(signature, 0, outbuf, offset, result); + return result; + } + + public boolean engineVerify(byte[] sigBytes) throws SignatureException + { + log.entering("SignatureAdapter", "engineVerify"); + + Object signature = codec.decodeSignature(sigBytes); + boolean result = false; + try + { + result = adaptee.verify(signature); + } + catch (IllegalStateException x) + { + throw new SignatureException(String.valueOf(x)); + } + + log.exiting("SignatureAdapter", "engineVerify", new Boolean(result)); + return result; + } + + // Deprecated. Replaced by engineSetParameter. + public void engineSetParameter(String param, Object value) + throws InvalidParameterException + { + throw new InvalidParameterException("deprecated"); + } + + public void engineSetParameter(AlgorithmParameterSpec params) + throws InvalidAlgorithmParameterException + { + } + + // Deprecated + public Object engineGetParameter(String param) + throws InvalidParameterException + { + throw new InvalidParameterException("deprecated"); + } +} diff --git a/libjava/classpath/gnu/java/security/key/IKeyPairCodec.java b/libjava/classpath/gnu/java/security/key/IKeyPairCodec.java new file mode 100644 index 00000000000..c64f928574b --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/IKeyPairCodec.java @@ -0,0 +1,132 @@ +/* IKeyPairCodec.java -- + Copyright 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key; + +import gnu.java.security.Registry; + +import java.security.PrivateKey; +import java.security.PublicKey; + +/** + * <p>The visible methods of an object that knows how to encode and decode + * cryptographic asymmetric keypairs. Codecs are useful for (a) externalising + * public and private keys for storage and on-the-wire transmission, as well as + * (b) re-creating their internal Java representation from external sources.</p> + * + * @version $Revision: 1.2 $ + */ +public interface IKeyPairCodec +{ + // Constants + // ------------------------------------------------------------------------- + + /** Constant identifying the <i>Raw</i> encoding format. */ + int RAW_FORMAT = Registry.RAW_ENCODING_ID; + + /** Constant identifying the <i>X.509</i> encoding format. */ + int X509_FORMAT = Registry.X509_ENCODING_ID; + + /** Constant identifying the <i>PKCS#8</i> encoding format. */ + int PKCS8_FORMAT = Registry.PKCS8_ENCODING_ID; + + /** + * Constant identifying the <i>ASN.1</i> encoding format: a combined encoding + * of <i>X.509</i> for public keys, and <i>PKCS#8</i> for private ones. + */ + int ASN1_FORMAT = Registry.ASN1_ENCODING_ID; + + // Method(s) + // ------------------------------------------------------------------------- + + /** + * <p>Returns the unique identifier (within this library) of the format used + * to externalise public and private keys.</p> + * + * @return the identifier of the format, the object supports. + */ + int getFormatID(); + + /** + * <p>Encodes an instance of a public key for storage or transmission purposes.</p> + * + * @param key the non-null key to encode. + * @return a byte sequence representing the encoding of the designated key + * according to the format supported by this codec. + * @exception IllegalArgumentException if the designated key is not supported + * by this codec. + */ + byte[] encodePublicKey(PublicKey key); + + /** + * <p>Encodes an instance of a private key for storage or transmission purposes.</p> + * + * @param key the non-null key to encode. + * @return a byte sequence representing the encoding of the designated key + * according to the format supported by this codec. + * @exception IllegalArgumentException if the designated key is not supported + * by this codec. + */ + byte[] encodePrivateKey(PrivateKey key); + + /** + * <p>Decodes an instance of an external public key into its native Java + * representation.</p> + * + * @param input the source of the externalised key to decode. + * @return a concrete instance of a public key, reconstructed from the + * designated input. + * @exception IllegalArgumentException if the designated input does not + * contain a known representation of a public key for the format supported by + * the concrete codec. + */ + PublicKey decodePublicKey(byte[] input); + + /** + * <p>Decodes an instance of an external private key into its native Java + * representation.</p> + * + * @param input the source of the externalised key to decode. + * @return a concrete instance of a private key, reconstructed from the + * designated input. + * @exception IllegalArgumentException if the designated input does not + * contain a known representation of a private key for the format supported + * by the concrete codec. + */ + PrivateKey decodePrivateKey(byte[] input); +} diff --git a/libjava/classpath/gnu/java/security/key/IKeyPairGenerator.java b/libjava/classpath/gnu/java/security/key/IKeyPairGenerator.java new file mode 100644 index 00000000000..219863d33eb --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/IKeyPairGenerator.java @@ -0,0 +1,82 @@ +/* IKeyPairGenerator.java -- + Copyright 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key; + +import java.security.KeyPair; +import java.util.Map; + +/** + * The visible methods of every asymmetric keypair generator.<p> + * + * @version $Revision: 1.1 $ + */ +public interface IKeyPairGenerator +{ + + // Constants + // ------------------------------------------------------------------------- + + // Methods + // ------------------------------------------------------------------------- + + /** + * Returns the canonical name of this keypair generator.<p> + * + * @return the canonical name of this instance. + */ + String name(); + + /** + * [Re]-initialises this instance for use with a given set of attributes.<p> + * + * @param attributes a map of name/value pairs to use for setting up the + * instance. + * @exception IllegalArgumentException if at least one of the mandatory + * attributes is missing or an invalid value was specified. + */ + void setup(Map attributes); + + /** + * Generates a new keypair based on the attributes used to configure the + * instance. + * + * @return a new keypair. + */ + KeyPair generate(); +} diff --git a/libjava/classpath/gnu/java/security/key/KeyPairCodecFactory.java b/libjava/classpath/gnu/java/security/key/KeyPairCodecFactory.java new file mode 100644 index 00000000000..1a8b8aa0388 --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/KeyPairCodecFactory.java @@ -0,0 +1,362 @@ +/* KeyPairCodecFactory.java -- + Copyright 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key; + +import gnu.java.security.Registry; +import gnu.java.security.key.dss.DSSKeyPairPKCS8Codec; +import gnu.java.security.key.dss.DSSKeyPairRawCodec; +import gnu.java.security.key.dss.DSSKeyPairX509Codec; +import gnu.java.security.key.dss.DSSPrivateKey; +import gnu.java.security.key.dss.DSSPublicKey; +import gnu.java.security.key.rsa.GnuRSAPrivateKey; +import gnu.java.security.key.rsa.GnuRSAPublicKey; +import gnu.java.security.key.rsa.RSAKeyPairPKCS8Codec; +import gnu.java.security.key.rsa.RSAKeyPairRawCodec; +import gnu.java.security.key.rsa.RSAKeyPairX509Codec; +import gnu.java.security.util.FormatUtil; + +import java.lang.reflect.Constructor; +import java.security.Key; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * A <i>Factory</i> class to instantiate key encoder/decoder instances. + */ +public class KeyPairCodecFactory +{ + private static Set names; + + /** Trivial constructor to enforce Singleton pattern. */ + private KeyPairCodecFactory() + { + super(); + } + + /** + * Returns the appropriate codec given a composed key-pair generator algorithm + * and an encoding format. A composed name is formed by the concatenation of + * the canonical key-pair algorithm name, the forward slash character + * <code>/</code> and the canonical name of the encoding format. + * <p> + * <b>IMPORTANT</b>: For backward compatibility, when the encoding format + * name is missing, the Raw encoding format is assumed. When this is the case + * the trailing forward slash is discarded from the name. + * + * @param name the case-insensitive key codec name. + * @return an instance of the keypair codec, or <code>null</code> if none + * found. + */ + public static IKeyPairCodec getInstance(String name) + { + if (name == null) + return null; + + name = name.trim(); + if (name.length() == 0) + return null; + + if (name.startsWith("/")) + return null; + + if (name.endsWith("/")) + return getInstance(name.substring(0, name.length() - 1), + Registry.RAW_ENCODING_ID); + + int i = name.indexOf("/"); + if (i == -1) + return getInstance(name, Registry.RAW_ENCODING_ID); + + String kpgName = name.substring(0, i); + String formatName = name.substring(i + 1); + return getInstance(kpgName, formatName); + } + + /** + * Returns an instance of a keypair codec given the canonical name of the + * key-pair algorithm, and the name of the encoding format to use when + * externalizing the keys. + * + * @param name the case-insensitive key-pair algorithm name. + * @param format the name of the encoding format to use when externalizing the + * keys generated by the key-pair algorithm. + * @return an instance of the key-pair codec, or <code>null</code> if none + * found. + */ + public static IKeyPairCodec getInstance(String name, String format) + { + int formatID = FormatUtil.getFormatID(format); + if (formatID == 0) + return null; + + return getInstance(name, formatID); + } + + /** + * Returns an instance of a keypair codec given the canonical name of the + * key-pair algorithm, and the identifier of the format to use when + * externalizing the keys. + * + * @param name the case-insensitive key-pair algorithm name. + * @param formatID the identifier of the format to use when externalizing the + * keys generated by the key-pair algorithm. + * @return an instance of the key-pair codec, or <code>null</code> if none + * found. + */ + public static IKeyPairCodec getInstance(String name, int formatID) + { + if (name == null) + return null; + + name = name.trim(); + switch (formatID) + { + case Registry.RAW_ENCODING_ID: + return getRawCodec(name); + case Registry.X509_ENCODING_ID: + return getX509Codec(name); + case Registry.PKCS8_ENCODING_ID: + return getPKCS8Codec(name); + } + + return null; + } + + /** + * Returns an instance of a keypair codec given a key. + * + * @param key the key to encode. + * @return an instance of the keypair codec, or <code>null</code> if none + * found. + */ + public static IKeyPairCodec getInstance(Key key) + { + if (key == null) + return null; + + String format = key.getFormat(); + int formatID = FormatUtil.getFormatID(format); + if (formatID == 0) + return null; + + switch (formatID) + { + case Registry.RAW_ENCODING_ID: + return getRawCodec(key); + case Registry.X509_ENCODING_ID: + return getX509Codec(key); + case Registry.PKCS8_ENCODING_ID: + return getPKCS8Codec(key); + } + + return null; + } + + /** + * Returns a {@link Set} of supported key-pair codec names. + * + * @return a {@link Set} of the names of supported key-pair codec (Strings). + */ + public static synchronized final Set getNames() + { + if (names == null) + { + HashSet hs = new HashSet(); + hs.add(Registry.DSS_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME); + hs.add(Registry.DSS_KPG + "/" + Registry.X509_ENCODING_SORT_NAME); + hs.add(Registry.DSS_KPG + "/" + Registry.PKCS8_ENCODING_SHORT_NAME); + hs.add(Registry.RSA_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME); + hs.add(Registry.RSA_KPG + "/" + Registry.X509_ENCODING_SORT_NAME); + hs.add(Registry.RSA_KPG + "/" + Registry.PKCS8_ENCODING_SHORT_NAME); + hs.add(Registry.DH_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME); + hs.add(Registry.SRP_KPG + "/" + Registry.RAW_ENCODING_SHORT_NAME); + + names = Collections.unmodifiableSet(hs); + } + + return names; + } + + private static IKeyPairCodec makeInstance (String clazz) + { + try + { + Class c = Class.forName (clazz); + Constructor ctor = c.getConstructor (new Class[0]); + return (IKeyPairCodec) ctor.newInstance (new Object[0]); + } + catch (Exception x) + { + IllegalArgumentException iae = + new IllegalArgumentException ("strong crypto key codec not available: " + + clazz); + iae.initCause (x); + throw iae; + } + } + + private static boolean matches (Object o, String clazz) + { + try + { + Class c = Class.forName (clazz); + return c.isAssignableFrom (o.getClass ()); + } + catch (Exception x) + { + // Can't match. + return false; + } + } + + /** + * @param name the trimmed name of a key-pair algorithm. + * @return a Raw format codec for the designated key-pair algorithm, or + * <code>null</code> if none exists. + */ + private static IKeyPairCodec getRawCodec(String name) + { + IKeyPairCodec result = null; + if (name.equalsIgnoreCase(Registry.DSA_KPG) + || name.equals(Registry.DSS_KPG)) + result = new DSSKeyPairRawCodec(); + else if (name.equalsIgnoreCase(Registry.RSA_KPG)) + result = new RSAKeyPairRawCodec(); + else if (name.equalsIgnoreCase(Registry.DH_KPG)) + result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairRawCodec"); + else if (name.equalsIgnoreCase(Registry.SRP_KPG)) + result = makeInstance("gnu.javax.crypto.key.srp6.SRPKeyPairRawCodec"); + + return result; + } + + /** + * @param name the trimmed name of a key-pair algorithm. + * @return a X.509 format codec for the designated key-pair algorithm, or + * <code>null</code> if none exists. + */ + private static IKeyPairCodec getX509Codec(String name) + { + IKeyPairCodec result = null; + if (name.equalsIgnoreCase(Registry.DSA_KPG) + || name.equals(Registry.DSS_KPG)) + result = new DSSKeyPairX509Codec(); + else if (name.equalsIgnoreCase(Registry.RSA_KPG)) + result = new RSAKeyPairX509Codec(); + else if (name.equalsIgnoreCase(Registry.DH_KPG)) + result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairX509Codec"); + + return result; + } + + /** + * @param name the trimmed name of a key-pair algorithm. + * @return a PKCS#8 format codec for the designated key-pair algorithm, or + * <code>null</code> if none exists. + */ + private static IKeyPairCodec getPKCS8Codec(String name) + { + IKeyPairCodec result = null; + if (name.equalsIgnoreCase(Registry.DSA_KPG) + || name.equals(Registry.DSS_KPG)) + result = new DSSKeyPairPKCS8Codec(); + else if (name.equalsIgnoreCase(Registry.RSA_KPG)) + result = new RSAKeyPairPKCS8Codec(); + else if (name.equalsIgnoreCase(Registry.DH_KPG)) + result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairPKCS8Codec"); + + return result; + } + + /** + * @param key a {@link Key} for which we want to return a Raw codec. + * @return the Raw codec corresponding to the key, or <code>null</code> if + * none exists for this key. + */ + private static IKeyPairCodec getRawCodec(Key key) + { + IKeyPairCodec result = null; + if ((key instanceof DSSPublicKey) || (key instanceof DSSPrivateKey)) + result = new DSSKeyPairRawCodec(); + else if ((key instanceof GnuRSAPublicKey) + || (key instanceof GnuRSAPrivateKey)) + result = new RSAKeyPairRawCodec(); + else if (matches(key, "gnu.javax.crypto.key.dh.GnuDHPublicKey") + || matches(key, "gnu.javax.crypto.key.dh.GnuDHPrivateKey")) + result = makeInstance("gnu.javax.crypto.key.dh.DHKeyPairRawCodec"); + else if (matches(key, "gnu.javax.crypto.key.srp6.SRPPublicKey") + || matches(key, "gnu.javax.crypto.key.srp6.SRPPrivateKey")) + result = makeInstance("gnu.javax.crypto.key.srp6.SRPKeyPairRawCodec"); + + return result; + } + + /** + * @param key a {@link Key} for which we want to return an X.509 codec. + * @return the X.509 codec corresponding to the key, or <code>null</code> if + * none exists for this key. + */ + private static IKeyPairCodec getX509Codec(Key key) + { + IKeyPairCodec result = null; + if (key instanceof DSSPublicKey) + result = new DSSKeyPairX509Codec(); + else if (key instanceof GnuRSAPublicKey) + result = new RSAKeyPairX509Codec(); + + return result; + } + + /** + * @param key a {@link Key} for which we want to return a PKCS#8 codec. + * @return the PKCS#8 codec corresponding to the key, or <code>null</code> if + * none exists for this key. + */ + private static IKeyPairCodec getPKCS8Codec(Key key) + { + IKeyPairCodec result = null; + if (key instanceof DSSPrivateKey) + result = new DSSKeyPairPKCS8Codec(); + else if (key instanceof GnuRSAPrivateKey) + result = new RSAKeyPairPKCS8Codec(); + + return result; + } +} diff --git a/libjava/classpath/gnu/java/security/key/KeyPairGeneratorFactory.java b/libjava/classpath/gnu/java/security/key/KeyPairGeneratorFactory.java new file mode 100644 index 00000000000..edcc186e2c7 --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/KeyPairGeneratorFactory.java @@ -0,0 +1,148 @@ +/* KeyPairGeneratorFactory.java -- + Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key; + +import gnu.java.security.Registry; +import gnu.java.security.key.dss.DSSKeyPairGenerator; +import gnu.java.security.key.rsa.RSAKeyPairGenerator; + +import java.lang.reflect.Constructor; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * <p>A Factory to instantiate asymmetric keypair generators.</p> + * + * @version $Revision: 1.1 $ + */ +public class KeyPairGeneratorFactory +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial constructor to enforce Singleton pattern. */ + private KeyPairGeneratorFactory() + { + super(); + } + + // Class methods + // ------------------------------------------------------------------------- + + /** + * <p>Returns an instance of a keypair generator given its name.</p> + * + * @param name the case-insensitive key generator name. + * @return an instance of the keypair generator, or <code>null</code> if none + * found. + */ + public static IKeyPairGenerator getInstance(String name) + { + if (name == null) + { + return null; + } + + name = name.trim(); + IKeyPairGenerator result = null; + if (name.equalsIgnoreCase(Registry.DSA_KPG) + || name.equals(Registry.DSS_KPG)) + { + result = new DSSKeyPairGenerator(); + } + else if (name.equalsIgnoreCase(Registry.RSA_KPG)) + { + result = new RSAKeyPairGenerator(); + } + else if (name.equalsIgnoreCase(Registry.DH_KPG)) + { + result = makeInstance ("gnu.javax.crypto.key.dh.GnuDHKeyPairGenerator"); + } + else if (name.equalsIgnoreCase(Registry.SRP_KPG)) + { + result = makeInstance ("gnu.javax.crypto.key.srp6.SRPKeyPairGenerator"); + } + + return result; + } + + /** + * <p>Returns a {@link Set} of keypair generator names supported by this + * <i>Factory</i>. Those keypair generators may be used in conjunction with + * the digital signature schemes with appendix supported by this library.</p> + * + * @return a {@link Set} of keypair generator names (Strings). + */ + public static final Set getNames() + { + HashSet hs = new HashSet(); + hs.add(Registry.DSS_KPG); + hs.add(Registry.RSA_KPG); + hs.add(Registry.DH_KPG); + hs.add(Registry.SRP_KPG); + + return Collections.unmodifiableSet(hs); + } + + private static IKeyPairGenerator makeInstance (String clazz) + { + try + { + Class c = Class.forName (clazz); + Constructor ctor = c.getConstructor (new Class[0]); + return (IKeyPairGenerator) ctor.newInstance (new Object[0]); + } + catch (Exception x) + { + IllegalArgumentException iae = + new IllegalArgumentException ("strong crypto key pair generator not available: " + + clazz); + iae.initCause (x); + throw iae; + } + } + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/key/dss/DSSKey.java b/libjava/classpath/gnu/java/security/key/dss/DSSKey.java new file mode 100644 index 00000000000..428cab1e78e --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/dss/DSSKey.java @@ -0,0 +1,182 @@ +/* DSSKey.java -- + Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key.dss; + +import gnu.java.security.Registry; +import gnu.java.security.util.FormatUtil; + +import java.math.BigInteger; +import java.security.Key; +import java.security.interfaces.DSAKey; +import java.security.interfaces.DSAParams; +import java.security.spec.DSAParameterSpec; + +/** + * <p>A base asbtract class for both public and private DSS (Digital Signature + * Standard) keys. It encapsulates the three DSS numbers: <code>p</code>, + * <code>q</code> and <code>g</code>.</p> + * + * <p>According to the JDK, cryptographic <i>Keys</i> all have a <i>format</i>. + * The format used in this implementation is called <i>Raw</i>, and basically + * consists of the raw byte sequences of algorithm parameters. The exact order + * of the byte sequences and the implementation details are given in each of + * the relevant <code>getEncoded()</code> methods of each of the private and + * public keys.</p> + * + * @version $Revision: 1.4 $ + * @see DSSPrivateKey#getEncoded + * @see DSSPublicKey#getEncoded + */ +public abstract class DSSKey implements Key, DSAKey +{ + // Constants and variables + // ------------------------------------------------------------------------- + + /** + * A prime modulus, where <code>2<sup>L-1</sup> < p < 2<sup>L</sup></code> + * for <code>512 <= L <= 1024</code> and <code>L</code> a multiple of + * <code>64</code>. + */ + protected final BigInteger p; + + /** + * A prime divisor of <code>p - 1</code>, where <code>2<sup>159</sup> < q + * < 2<sup>160</sup></code>. + */ + protected final BigInteger q; + + /** + * <code>g = h<sup>(p-1)</sup>/q mod p</code>, where <code>h</code> is any + * integer with <code>1 < h < p - 1</code> such that <code>h<sup> + * (p-1)</sup>/q mod p > 1</code> (<code>g</code> has order <code>q mod p + * </code>). + */ + protected final BigInteger g; + + /** + * Identifier of the default encoding format to use when externalizing the + * key material. + */ + protected final int defaultFormat; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Trivial protected constructor. + * + * @param defaultFormat the identifier of the encoding format to use by + * default when externalizing the key. + * @param p the DSS parameter <code>p</code>. + * @param q the DSS parameter <code>q</code>. + * @param g the DSS parameter <code>g</code>. + */ + protected DSSKey(int defaultFormat, BigInteger p, BigInteger q, BigInteger g) + { + super(); + + this.defaultFormat = defaultFormat <= 0 ? Registry.RAW_ENCODING_ID + : defaultFormat; + this.p = p; + this.q = q; + this.g = g; + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // java.security.interfaces.DSAKey interface implementation ---------------- + + public DSAParams getParams() + { + return new DSAParameterSpec(p, q, g); + } + + // java.security.Key interface implementation ------------------------------ + + public String getAlgorithm() + { + return Registry.DSS_KPG; + } + + /** @deprecated see getEncoded(int). */ + public byte[] getEncoded() + { + return getEncoded(defaultFormat); + } + + public String getFormat() + { + return FormatUtil.getEncodingShortName(defaultFormat); + } + + // Other instance methods -------------------------------------------------- + + /** + * <p>Returns <code>true</code> if the designated object is an instance of + * {@link DSAKey} and has the same DSS (Digital Signature Standard) parameter + * values as this one.</p> + * + * @param obj the other non-null DSS key to compare to. + * @return <code>true</code> if the designated object is of the same type and + * value as this one. + */ + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + if (!(obj instanceof DSAKey)) + { + return false; + } + DSAKey that = (DSAKey) obj; + return p.equals(that.getParams().getP()) + && q.equals(that.getParams().getQ()) + && g.equals(that.getParams().getG()); + } + + // abstract methods to be implemented by subclasses ------------------------ + + public abstract byte[] getEncoded(int format); +} diff --git a/libjava/classpath/gnu/java/security/key/dss/DSSKeyPairGenerator.java b/libjava/classpath/gnu/java/security/key/dss/DSSKeyPairGenerator.java new file mode 100644 index 00000000000..5aa746147eb --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/dss/DSSKeyPairGenerator.java @@ -0,0 +1,445 @@ +/* DSSKeyPairGenerator.java -- + Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key.dss; + +import gnu.java.security.Registry; +import gnu.java.security.hash.Sha160; +import gnu.java.security.key.IKeyPairGenerator; +import gnu.java.security.util.PRNG; + +import java.io.PrintWriter; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.spec.DSAParameterSpec; +import java.util.Map; + +/** + * <p>A key-pair generator for asymetric keys to use in conjunction with the DSS + * (Digital Signature Standard).</p> + * + * References:<br> + * <a href="http://www.itl.nist.gov/fipspubs/fip186.htm">Digital Signature + * Standard (DSS)</a>, Federal Information Processing Standards Publication 186. + * National Institute of Standards and Technology. + */ +public class DSSKeyPairGenerator implements IKeyPairGenerator +{ + + // Debugging methods and variables + // ------------------------------------------------------------------------- + + private static final String NAME = "dss"; + + private static final boolean DEBUG = false; + + private static final int debuglevel = 5; + + private static final PrintWriter err = new PrintWriter(System.out, true); + + private static void debug(String s) + { + err.println(">>> " + NAME + ": " + s); + } + + // Constants and variables + // ------------------------------------------------------------------------- + + /** The BigInteger constant 2. */ + private static final BigInteger TWO = new BigInteger("2"); + + /** Property name of the length (Integer) of the modulus (p) of a DSS key. */ + public static final String MODULUS_LENGTH = "gnu.crypto.dss.L"; + + /** + * Property name of the Boolean indicating wether or not to use default pre- + * computed values of <code>p</code>, <code>q</code> and <code>g</code> for + * a given modulus length. The ultimate behaviour of this generator with + * regard to using pre-computed parameter sets will depend on the value of + * this property and of the following one {@link #STRICT_DEFAULTS}: + * + * <ol> + * <li>If this property is {@link Boolean#FALSE} then this generator + * will accept being setup for generating parameters for any modulus length + * provided the modulus length is between <code>512</code> and + * <code>1024</code>, and is of the form <code>512 + 64 * n</code>. In + * addition, a new paramter set will always be generated; i.e. no pre- + * computed values are used.</li> + * + * <li>If this property is {@link Boolean#TRUE} and the value of + * {@link #STRICT_DEFAULTS} is also {@link Boolean#TRUE} then this generator + * will only accept being setup for generating parameters for modulus + * lengths of <code>512</code>, <code>768</code> and <code>1024</code>. Any + * other value, of the modulus length, even if between <code>512</code> and + * <code>1024</code>, and of the form <code>512 + 64 * n</code>, will cause + * an {@link IllegalArgumentException} to be thrown. When those modulus + * length (<code>512</code>, <code>768</code>, and <code>1024</code>) are + * specified, the paramter set is always the same.</li> + * + * <li>Finally, if this property is {@link Boolean#TRUE} and the value of + * {@link #STRICT_DEFAULTS} is {@link Boolean#FALSE} then this generator + * will behave as in point 1 above, except that it will use pre-computed + * values when possible; i.e. the modulus length is one of <code>512</code>, + * <code>768</code>, or <code>1024</code>.</li> + * </ol> + * + * The default value of this property is {@link Boolean#TRUE}. + */ + public static final String USE_DEFAULTS = "gnu.crypto.dss.use.defaults"; + + /** + * Property name of the Boolean indicating wether or not to generate new + * parameters, even if the modulus length <i>L</i> is not one of the pre- + * computed defaults (value {@link Boolean#FALSE}), or throw an exception + * (value {@link Boolean#TRUE}) -- the exception in this case is an + * {@link IllegalArgumentException}. The default value for this property is + * {@link Boolean#FALSE}. The ultimate behaviour of this generator will + * depend on the values of this and {@link #USE_DEFAULTS} properties -- see + * {@link #USE_DEFAULTS} for more information. + */ + public static final String STRICT_DEFAULTS = "gnu.crypto.dss.strict.defaults"; + + /** + * Property name of an optional {@link SecureRandom} instance to use. The + * default is to use a classloader singleton from {@link PRNG}. + */ + public static final String SOURCE_OF_RANDOMNESS = "gnu.crypto.dss.prng"; + + /** + * Property name of an optional {@link DSAParameterSpec} instance to use for + * this generator's <code>p</code>, <code>q</code>, and <code>g</code> values. + * The default is to generate these values or use pre-computed ones, + * depending on the value of the <code>USE_DEFAULTS</code> attribute. + */ + public static final String DSS_PARAMETERS = "gnu.crypto.dss.params"; + + /** + * Property name of the preferred encoding format to use when externalizing + * generated instance of key-pairs from this generator. The property is taken + * to be an {@link Integer} that encapsulates an encoding format identifier. + */ + public static final String PREFERRED_ENCODING_FORMAT = "gnu.crypto.dss.encoding"; + + /** Default value for the modulus length. */ + public static final int DEFAULT_MODULUS_LENGTH = 1024; + + /** Default encoding format to use when none was specified. */ + private static final int DEFAULT_ENCODING_FORMAT = Registry.RAW_ENCODING_ID; + + /** Initial SHS context. */ + private static final int[] T_SHS = new int[] { 0x67452301, 0xEFCDAB89, + 0x98BADCFE, 0x10325476, + 0xC3D2E1F0 }; + + // from jdk1.3.1/docs/guide/security/CryptoSpec.html#AppB + public static final DSAParameterSpec KEY_PARAMS_512 = new DSAParameterSpec( + new BigInteger( + "fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae" + + "01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17", + 16), + new BigInteger( + "962eddcc369cba8ebb260ee6b6a126d9346e38c5", + 16), + new BigInteger( + "678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e" + + "35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4", + 16)); + + public static final DSAParameterSpec KEY_PARAMS_768 = new DSAParameterSpec( + new BigInteger( + "e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5d8901419" + + "22d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a22219d470bce7d77" + + "7d4a21fbe9c270b57f607002f3cef8393694cf45ee3688c11a8c56ab127a3daf", + 16), + new BigInteger( + "9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", + 16), + new BigInteger( + "30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7a31d23c4" + + "dbbcbe06174544401a5b2c020965d8c2bd2171d3668445771f74ba084d2029d8" + + "3c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a7064f316933a346d3f529252", + 16)); + + public static final DSAParameterSpec KEY_PARAMS_1024 = new DSAParameterSpec( + new BigInteger( + "fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669" + + "455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b7" + + "6b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb" + + "83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", + 16), + new BigInteger( + "9760508f15230bccb292b982a2eb840bf0581cf5", + 16), + new BigInteger( + "f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d078267" + + "5159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e1" + + "3c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243b" + + "cca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", + 16)); + + private static final BigInteger TWO_POW_160 = TWO.pow(160); + + /** The length of the modulus of DSS keys generated by this instance. */ + private int L; + + /** The optional {@link SecureRandom} instance to use. */ + private SecureRandom rnd = null; + + private BigInteger seed; + + private BigInteger counter; + + private BigInteger p; + + private BigInteger q; + + private BigInteger e; + + private BigInteger g; + + private BigInteger XKEY; + + /** Our default source of randomness. */ + private PRNG prng = null; + + /** Preferred encoding format of generated keys. */ + private int preferredFormat; + + // Constructor(s) + // ------------------------------------------------------------------------- + + // implicit 0-arguments constructor + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // gnu.crypto.key.IKeyPairGenerator interface implementation --------------- + + public String name() + { + return Registry.DSS_KPG; + } + + /** + * <p>Configures this instance.</p> + * + * @param attributes the map of name/value pairs to use. + * @exception IllegalArgumentException if the designated MODULUS_LENGTH + * value is not greater than 512, less than 1024 and not of the form + * <code>512 + 64j</code>. + */ + public void setup(Map attributes) + { + // find out the modulus length + Integer l = (Integer) attributes.get(MODULUS_LENGTH); + L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue()); + if ((L % 64) != 0 || L < 512 || L > 1024) + throw new IllegalArgumentException(MODULUS_LENGTH); + + // should we use the default pre-computed params? + Boolean useDefaults = (Boolean) attributes.get(USE_DEFAULTS); + if (useDefaults == null) + { + useDefaults = Boolean.TRUE; + } + + Boolean strictDefaults = (Boolean) attributes.get(STRICT_DEFAULTS); + if (strictDefaults == null) + strictDefaults = Boolean.FALSE; + + // are we given a set of DSA params or we shall use/generate our own? + DSAParameterSpec params = (DSAParameterSpec) attributes.get(DSS_PARAMETERS); + if (params != null) + { + p = params.getP(); + q = params.getQ(); + g = params.getG(); + } + else if (useDefaults.equals(Boolean.TRUE)) + { + switch (L) + { + case 512: + p = KEY_PARAMS_512.getP(); + q = KEY_PARAMS_512.getQ(); + g = KEY_PARAMS_512.getG(); + break; + case 768: + p = KEY_PARAMS_768.getP(); + q = KEY_PARAMS_768.getQ(); + g = KEY_PARAMS_768.getG(); + break; + case 1024: + p = KEY_PARAMS_1024.getP(); + q = KEY_PARAMS_1024.getQ(); + g = KEY_PARAMS_1024.getG(); + break; + default: + if (strictDefaults.equals(Boolean.TRUE)) + throw new IllegalArgumentException( + "Does not provide default parameters for " + L + + "-bit modulus length"); + else + { + p = null; + q = null; + g = null; + } + } + } + else + { + p = null; + q = null; + g = null; + } + + // do we have a SecureRandom, or should we use our own? + rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS); + + // what is the preferred encoding format + Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT); + preferredFormat = formatID == null + ? DEFAULT_ENCODING_FORMAT + : formatID.intValue(); + + // set the seed-key + byte[] kb = new byte[20]; // we need 160 bits of randomness + nextRandomBytes(kb); + XKEY = new BigInteger(1, kb).setBit(159).setBit(0); + } + + public KeyPair generate() + { + if (p == null) + { + BigInteger[] params = new FIPS186(L, rnd).generateParameters(); + seed = params[FIPS186.DSA_PARAMS_SEED]; + counter = params[FIPS186.DSA_PARAMS_COUNTER]; + q = params[FIPS186.DSA_PARAMS_Q]; + p = params[FIPS186.DSA_PARAMS_P]; + e = params[FIPS186.DSA_PARAMS_E]; + g = params[FIPS186.DSA_PARAMS_G]; + if (DEBUG && debuglevel > 0) + { + debug("seed: " + seed.toString(16)); + debug("counter: " + counter.intValue()); + debug("q: " + q.toString(16)); + debug("p: " + p.toString(16)); + debug("e: " + e.toString(16)); + debug("g: " + g.toString(16)); + } + } + + BigInteger x = nextX(); + BigInteger y = g.modPow(x, p); + + PublicKey pubK = new DSSPublicKey(preferredFormat, p, q, g, y); + PrivateKey secK = new DSSPrivateKey(preferredFormat, p, q, g, x); + + return new KeyPair(pubK, secK); + } + + // Other instance methods -------------------------------------------------- + + /** + * <p>This method applies the following algorithm described in 3.1 of + * FIPS-186:</p> + * + * <ol> + * <li>XSEED = optional user input.</li> + * <li>XVAL = (XKEY + XSEED) mod 2<sup>b</sup>.</li> + * <li>x = G(t, XVAL) mod q.</li> + * <li>XKEY = (1 + XKEY + x) mod 2<sup>b</sup>.</li> + * </ol> + * + * <p>Where <code>b</code> is the length of a secret b-bit seed-key (XKEY).</p> + * + * <p>Note that in this implementation, XSEED, the optional user input, is + * always zero.</p> + */ + private synchronized BigInteger nextX() + { + byte[] xk = XKEY.toByteArray(); + byte[] in = new byte[64]; // 512-bit block for SHS + System.arraycopy(xk, 0, in, 0, xk.length); + + int[] H = Sha160.G(T_SHS[0], T_SHS[1], T_SHS[2], T_SHS[3], T_SHS[4], in, 0); + byte[] h = new byte[20]; + for (int i = 0, j = 0; i < 5; i++) + { + h[j++] = (byte) (H[i] >>> 24); + h[j++] = (byte) (H[i] >>> 16); + h[j++] = (byte) (H[i] >>> 8); + h[j++] = (byte) H[i]; + } + BigInteger result = new BigInteger(1, h).mod(q); + XKEY = XKEY.add(result).add(BigInteger.ONE).mod(TWO_POW_160); + + return result; + } + + /** + * <p>Fills the designated byte array with random data.</p> + * + * @param buffer the byte array to fill with random data. + */ + private void nextRandomBytes(byte[] buffer) + { + if (rnd != null) + { + rnd.nextBytes(buffer); + } + else + getDefaultPRNG().nextBytes(buffer); + } + + private PRNG getDefaultPRNG() + { + if (prng == null) + prng = PRNG.getInstance(); + + return prng; + } +} diff --git a/libjava/classpath/gnu/java/security/key/dss/DSSKeyPairPKCS8Codec.java b/libjava/classpath/gnu/java/security/key/dss/DSSKeyPairPKCS8Codec.java new file mode 100644 index 00000000000..30e30bd144d --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/dss/DSSKeyPairPKCS8Codec.java @@ -0,0 +1,235 @@ +/* DSSKeyPairPKCS8Codec.java -- PKCS#8 Encoding/Decoding handler + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.key.dss; + +import gnu.java.security.OID; +import gnu.java.security.Registry; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.der.DERWriter; +import gnu.java.security.key.IKeyPairCodec; +import gnu.java.security.util.DerUtil; +import gnu.java.security.util.Util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.InvalidParameterException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.ArrayList; + +/** + * An implementation of an {@link IKeyPairCodec} that knows how to encode / + * decode PKCS#8 ASN.1 external representation of DSS private keys. + * + * @author Casey Marshall (rsdio@metastatic.org) + */ +public class DSSKeyPairPKCS8Codec + implements IKeyPairCodec +{ + private static final OID DSA_ALG_OID = new OID(Registry.DSA_OID_STRING); + + // implicit 0-arguments constructor + + public int getFormatID() + { + return PKCS8_FORMAT; + } + + /** + * @throws InvalidParameterException ALWAYS. + */ + public byte[] encodePublicKey(PublicKey key) + { + throw new InvalidParameterException("Wrong format for public keys"); + } + + /** + * Returns the PKCS#8 ASN.1 <i>PrivateKeyInfo</i> representation of a DSA + * private key. The ASN.1 specification is as follows: + * + * <pre> + * PrivateKeyInfo ::= SEQUENCE { + * version INTEGER, -- MUST be 0 + * privateKeyAlgorithm AlgorithmIdentifier, + * privateKey OCTET STRING + * } + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DssParams ::= SEQUENCE { + * p INTEGER, + * q INTEGER, + * g INTEGER + * } + * </pre> + * + * @return the DER encoded form of the ASN.1 representation of the + * <i>PrivateKeyInfo</i> field in an X.509 certificate. + * @throw InvalidParameterException if an error occurs during the marshalling + * process. + */ + public byte[] encodePrivateKey(PrivateKey key) + { + if (! (key instanceof DSSPrivateKey)) + throw new InvalidParameterException("Wrong key type"); + + DERValue derVersion = new DERValue(DER.INTEGER, BigInteger.ZERO); + + DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, DSA_ALG_OID); + + DSSPrivateKey pk = (DSSPrivateKey) key; + BigInteger p = pk.getParams().getP(); + BigInteger q = pk.getParams().getQ(); + BigInteger g = pk.getParams().getG(); + BigInteger x = pk.getX(); + + ArrayList params = new ArrayList(3); + params.add(new DERValue(DER.INTEGER, p)); + params.add(new DERValue(DER.INTEGER, q)); + params.add(new DERValue(DER.INTEGER, g)); + DERValue derParams = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, params); + + ArrayList algorithmID = new ArrayList(2); + algorithmID.add(derOID); + algorithmID.add(derParams); + DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + algorithmID); + + DERValue derPrivateKey = new DERValue(DER.OCTET_STRING, Util.trim(x)); + + ArrayList pki = new ArrayList(3); + pki.add(derVersion); + pki.add(derAlgorithmID); + pki.add(derPrivateKey); + DERValue derPKI = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, pki); + + byte[] result; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try + { + DERWriter.write(baos, derPKI); + result = baos.toByteArray(); + } + catch (IOException e) + { + InvalidParameterException y = new InvalidParameterException(); + y.initCause(e); + throw y; + } + + return result; + } + + /** + * @throws InvalidParameterException ALWAYS. + */ + public PublicKey decodePublicKey(byte[] input) + { + throw new InvalidParameterException("Wrong format for public keys"); + } + + /** + * @param input the byte array to unmarshall into a valid DSS + * {@link PrivateKey} instance. MUST NOT be null. + * @return a new instance of a {@link DSSPrivateKey} decoded from the + * <i>PrivateKeyInfo</i> material fed as <code>input</code>. + * @throw InvalidParameterException if an exception occurs during the + * unmarshalling process. + */ + public PrivateKey decodePrivateKey(byte[] input) + { + if (input == null) + throw new InvalidParameterException("Input bytes MUST NOT be null"); + + BigInteger version, p, q, g, x; + DERReader der = new DERReader(input); + try + { + DERValue derPKI = der.read(); + DerUtil.checkIsConstructed(derPKI, "Wrong PrivateKeyInfo field"); + + DERValue derVersion = der.read(); + if (! (derVersion.getValue() instanceof BigInteger)) + throw new InvalidParameterException("Wrong Version field"); + + version = (BigInteger) derVersion.getValue(); + if (version.compareTo(BigInteger.ZERO) != 0) + throw new InvalidParameterException("Unexpected Version: " + version); + + DERValue derAlgoritmID = der.read(); + DerUtil.checkIsConstructed(derAlgoritmID, "Wrong AlgorithmIdentifier field"); + + DERValue derOID = der.read(); + OID algOID = (OID) derOID.getValue(); + if (! algOID.equals(DSA_ALG_OID)) + throw new InvalidParameterException("Unexpected OID: " + algOID); + + DERValue derParams = der.read(); + DerUtil.checkIsConstructed(derParams, "Wrong DSS Parameters field"); + + DERValue val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong P field"); + p = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong Q field"); + q = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong G field"); + g = (BigInteger) val.getValue(); + + val = der.read(); + byte[] xBytes = (byte[]) val.getValue(); + x = new BigInteger(1, xBytes); + } + catch (IOException e) + { + InvalidParameterException y = new InvalidParameterException(); + y.initCause(e); + throw y; + } + + return new DSSPrivateKey(Registry.PKCS8_ENCODING_ID, p, q, g, x); + } +} diff --git a/libjava/classpath/gnu/java/security/key/dss/DSSKeyPairRawCodec.java b/libjava/classpath/gnu/java/security/key/dss/DSSKeyPairRawCodec.java new file mode 100644 index 00000000000..86e5b0bef7e --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/dss/DSSKeyPairRawCodec.java @@ -0,0 +1,383 @@ +/* DSSKeyPairRawCodec.java -- + Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key.dss; + +import gnu.java.security.Registry; +import gnu.java.security.key.IKeyPairCodec; + +import java.io.ByteArrayOutputStream; +import java.math.BigInteger; +import java.security.PrivateKey; +import java.security.PublicKey; + +/** + * <p>An object that implements the {@link IKeyPairCodec} operations for the + * <i>Raw</i> format to use with DSS keypairs.</p> + * + * @version $Revision: 1.1 $ + */ +public class DSSKeyPairRawCodec implements IKeyPairCodec +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + // implicit 0-arguments constructor + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // gnu.crypto.keys.IKeyPairCodec interface implementation ------------------ + + public int getFormatID() + { + return RAW_FORMAT; + } + + /** + * <p>Returns the encoded form of the designated DSS (Digital Signature + * Standard) public key according to the <i>Raw</i> format supported by + * this library.</p> + * + * <p>The <i>Raw</i> format for a DSA public key, in this implementation, is + * a byte sequence consisting of the following:</p> + * <ol> + * <li>4-byte magic consisting of the value of the literal + * {@link Registry#MAGIC_RAW_DSS_PUBLIC_KEY},<li> + * <li>1-byte version consisting of the constant: 0x01,</li> + * <li>4-byte count of following bytes representing the DSA parameter + * <code>p</code> in internet order,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the DSA parameter + * <code>p</code>,</li> + * <li>4-byte count of following bytes representing the DSA parameter + * <code>q</code>,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the DSA parameter + * <code>q</code>,</li> + * <li>4-byte count of following bytes representing the DSA parameter + * <code>g</code>,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the DSA parameter + * <code>g</code>,</li> + * <li>4-byte count of following bytes representing the DSA parameter + * <code>y</code>,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the DSA parameter + * <code>y</code>,</li> + * </ol> + * + * @param key the key to encode. + * @return the <i>Raw</i> format encoding of the designated key. + * @throws IllegalArgumentException if the designated key is not a DSS + * (Digital Signature Standard) one. + * @see Registry#MAGIC_RAW_DSS_PUBLIC_KEY + */ + public byte[] encodePublicKey(PublicKey key) + { + if (!(key instanceof DSSPublicKey)) + { + throw new IllegalArgumentException("key"); + } + + DSSPublicKey dssKey = (DSSPublicKey) key; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + // magic + baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[0]); + baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[1]); + baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[2]); + baos.write(Registry.MAGIC_RAW_DSS_PUBLIC_KEY[3]); + + // version + baos.write(0x01); + + // p + byte[] buffer = dssKey.getParams().getP().toByteArray(); + int length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + // q + buffer = dssKey.getParams().getQ().toByteArray(); + length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + // g + buffer = dssKey.getParams().getG().toByteArray(); + length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + // y + buffer = dssKey.getY().toByteArray(); + length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + return baos.toByteArray(); + } + + public PublicKey decodePublicKey(byte[] k) + { + // magic + if (k[0] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[0] + || k[1] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[1] + || k[2] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[2] + || k[3] != Registry.MAGIC_RAW_DSS_PUBLIC_KEY[3]) + { + throw new IllegalArgumentException("magic"); + } + + // version + if (k[4] != 0x01) + { + throw new IllegalArgumentException("version"); + } + int i = 5; + + int l; + byte[] buffer; + + // p + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger p = new BigInteger(1, buffer); + + // q + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger q = new BigInteger(1, buffer); + + // g + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger g = new BigInteger(1, buffer); + + // y + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger y = new BigInteger(1, buffer); + + return new DSSPublicKey(p, q, g, y); + } + + /** + * <p>Returns the encoded form of the designated DSS (Digital Signature + * Standard) private key according to the <i>Raw</i> format supported by + * this library.</p> + * + * <p>The <i>Raw</i> format for a DSA private key, in this implementation, is + * a byte sequence consisting of the following:</p> + * <ol> + * <li>4-byte magic consisting of the value of the literal + * {@link Registry#MAGIC_RAW_DSS_PRIVATE_KEY},<li> + * <li>1-byte version consisting of the constant: 0x01,</li> + * <li>4-byte count of following bytes representing the DSA parameter + * <code>p</code> in internet order,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the DSA parameter + * <code>p</code>,</li> + * <li>4-byte count of following bytes representing the DSA parameter + * <code>q</code>,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the DSA parameter + * <code>q</code>,</li> + * <li>4-byte count of following bytes representing the DSA parameter + * <code>g</code>,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the DSA parameter + * <code>g</code>,</li> + * <li>4-byte count of following bytes representing the DSA parameter + * <code>x</code>,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the DSA parameter + * <code>x</code>,</li> + * </ol> + * + * @param key the key to encode. + * @return the <i>Raw</i> format encoding of the designated key. + * @throws IllegalArgumentException if the designated key is not a DSS + * (Digital Signature Standard) one. + */ + public byte[] encodePrivateKey(PrivateKey key) + { + if (!(key instanceof DSSPrivateKey)) + { + throw new IllegalArgumentException("key"); + } + + DSSPrivateKey dssKey = (DSSPrivateKey) key; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + // magic + baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[0]); + baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[1]); + baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[2]); + baos.write(Registry.MAGIC_RAW_DSS_PRIVATE_KEY[3]); + + // version + baos.write(0x01); + + // p + byte[] buffer = dssKey.getParams().getP().toByteArray(); + int length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + // q + buffer = dssKey.getParams().getQ().toByteArray(); + length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + // g + buffer = dssKey.getParams().getG().toByteArray(); + length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + // x + buffer = dssKey.getX().toByteArray(); + length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + return baos.toByteArray(); + } + + public PrivateKey decodePrivateKey(byte[] k) + { + // magic + if (k[0] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[0] + || k[1] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[1] + || k[2] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[2] + || k[3] != Registry.MAGIC_RAW_DSS_PRIVATE_KEY[3]) + { + throw new IllegalArgumentException("magic"); + } + + // version + if (k[4] != 0x01) + { + throw new IllegalArgumentException("version"); + } + int i = 5; + + int l; + byte[] buffer; + + // p + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger p = new BigInteger(1, buffer); + + // q + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger q = new BigInteger(1, buffer); + + // g + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger g = new BigInteger(1, buffer); + + // x + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger x = new BigInteger(1, buffer); + + return new DSSPrivateKey(p, q, g, x); + } +} diff --git a/libjava/classpath/gnu/java/security/key/dss/DSSKeyPairX509Codec.java b/libjava/classpath/gnu/java/security/key/dss/DSSKeyPairX509Codec.java new file mode 100644 index 00000000000..516ef92afd5 --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/dss/DSSKeyPairX509Codec.java @@ -0,0 +1,248 @@ +/* DSSKeyPairX509Codec.java -- X.509 Encoding/Decoding handler + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.key.dss; + +import gnu.java.security.OID; +import gnu.java.security.Registry; +import gnu.java.security.der.BitString; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.der.DERWriter; +import gnu.java.security.key.IKeyPairCodec; +import gnu.java.security.util.DerUtil; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.InvalidParameterException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.ArrayList; + +/** + * An implementation of an {@link IKeyPairCodec} that knows how to encode / + * decode X.509 ASN.1 external representation of DSS public keys. + */ +public class DSSKeyPairX509Codec + implements IKeyPairCodec +{ + private static final OID DSA_ALG_OID = new OID(Registry.DSA_OID_STRING); + + // implicit 0-arguments constructor + + public int getFormatID() + { + return X509_FORMAT; + } + + /** + * Returns the X.509 ASN.1 <i>SubjectPublicKeyInfo</i> representation of a + * DSA public key. The ASN.1 specification, as defined in RFC-3280, and + * RFC-2459, is as follows: + * + * <pre> + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING + * } + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * + * DssParams ::= SEQUENCE { + * p INTEGER, + * q INTEGER, + * g INTEGER + * } + * </pre> + * + * <p>The <i>subjectPublicKey</i> field, which is a BIT STRING, contains the + * DER-encoded form of the DSA public key as an INTEGER.</p> + * + * <pre> + * DSAPublicKey ::= INTEGER -- public key, Y + * </pre> + * + * @param key the {@link PublicKey} instance to encode. MUST be an instance of + * {@link DSSPublicKey}. + * @return the ASN.1 representation of the <i>SubjectPublicKeyInfo</i> in an + * X.509 certificate. + * @throw InvalidParameterException if <code>key</code> is not an instance + * of {@link DSSPublicKey} or if an exception occurs during the + * marshalling process. + */ + public byte[] encodePublicKey(PublicKey key) + { + if (! (key instanceof DSSPublicKey)) + throw new InvalidParameterException("key"); + + DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, DSA_ALG_OID); + + DSSPublicKey dssKey = (DSSPublicKey) key; + BigInteger p = dssKey.getParams().getP(); + BigInteger q = dssKey.getParams().getQ(); + BigInteger g = dssKey.getParams().getG(); + BigInteger y = dssKey.getY(); + + DERValue derP = new DERValue(DER.INTEGER, p); + DERValue derQ = new DERValue(DER.INTEGER, q); + DERValue derG = new DERValue(DER.INTEGER, g); + + ArrayList params = new ArrayList(3); + params.add(derP); + params.add(derQ); + params.add(derG); + DERValue derParams = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, params); + + ArrayList algorithmID = new ArrayList(2); + algorithmID.add(derOID); + algorithmID.add(derParams); + DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + algorithmID); + + DERValue derDSAPublicKey = new DERValue(DER.INTEGER, y); + byte[] yBytes = derDSAPublicKey.getEncoded(); + DERValue derSPK = new DERValue(DER.BIT_STRING, new BitString(yBytes)); + + ArrayList spki = new ArrayList(2); + spki.add(derAlgorithmID); + spki.add(derSPK); + DERValue derSPKI = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, spki); + + byte[] result; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try + { + DERWriter.write(baos, derSPKI); + result = baos.toByteArray(); + } + catch (IOException x) + { + InvalidParameterException e = new InvalidParameterException(); + e.initCause(x); + throw e; + } + + return result; + } + + /** + * @throws InvalidParameterException ALWAYS. + */ + public byte[] encodePrivateKey(PrivateKey key) + { + throw new InvalidParameterException("Wrong format for private keys"); + } + + /** + * @param input the byte array to unmarshall into a valid DSS + * {@link PublicKey} instance. MUST NOT be null. + * @return a new instance of a {@link DSSPublicKey} decoded from the + * <i>SubjectPublicKeyInfo</i> material in an X.509 certificate. + * @throw InvalidParameterException if an exception occurs during the + * unmarshalling process. + */ + public PublicKey decodePublicKey(byte[] input) + { + if (input == null) + throw new InvalidParameterException("Input bytes MUST NOT be null"); + + BigInteger p, g, q, y; + DERReader der = new DERReader(input); + try + { + DERValue derSPKI = der.read(); + DerUtil.checkIsConstructed(derSPKI, "Wrong SubjectPublicKeyInfo field"); + + DERValue derAlgorithmID = der.read(); + DerUtil.checkIsConstructed(derAlgorithmID, "Wrong AlgorithmIdentifier field"); + + DERValue derOID = der.read(); + if (! (derOID.getValue() instanceof OID)) + throw new InvalidParameterException("Wrong Algorithm field"); + + OID algOID = (OID) derOID.getValue(); + if (! algOID.equals(DSA_ALG_OID)) + throw new InvalidParameterException("Unexpected OID: " + algOID); + + DERValue derParams = der.read(); + DerUtil.checkIsConstructed(derParams, "Wrong DSS Parameters field"); + + DERValue val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong P field"); + p = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong Q field"); + q = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong G field"); + g = (BigInteger) val.getValue(); + + val = der.read(); + if (! (val.getValue() instanceof BitString)) + throw new InvalidParameterException("Wrong SubjectPublicKey field"); + + byte[] yBytes = ((BitString) val.getValue()).toByteArray(); + + DERReader dsaPub = new DERReader(yBytes); + val = dsaPub.read(); + DerUtil.checkIsBigInteger(val, "Wrong Y field"); + y = (BigInteger) val.getValue(); + } + catch (IOException x) + { + InvalidParameterException e = new InvalidParameterException(); + e.initCause(x); + throw e; + } + + return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y); + } + + /** + * @throws InvalidParameterException ALWAYS. + */ + public PrivateKey decodePrivateKey(byte[] input) + { + throw new InvalidParameterException("Wrong format for private keys"); + } +} diff --git a/libjava/classpath/gnu/java/security/key/dss/DSSPrivateKey.java b/libjava/classpath/gnu/java/security/key/dss/DSSPrivateKey.java new file mode 100644 index 00000000000..c81eb93b078 --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/dss/DSSPrivateKey.java @@ -0,0 +1,201 @@ +/* DSSPrivateKey.java -- + Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key.dss; + +import gnu.java.security.Registry; +import gnu.java.security.key.IKeyPairCodec; + +import java.math.BigInteger; +import java.security.PrivateKey; +import java.security.interfaces.DSAPrivateKey; + +/** + * <p>An object that embodies a DSS (Digital Signature Standard) private key.</p> + * + * @version $Revision: 1.2 $ + * @see #getEncoded + */ +public class DSSPrivateKey extends DSSKey implements PrivateKey, DSAPrivateKey +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** + * <p>A randomly or pseudorandomly generated integer with <code>0 < x < + * q</code>.</p> + */ + private final BigInteger x; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Convenience constructor. Calls the constructor with 5 arguments passing + * {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred + * encoding format. + * + * @param p the public modulus. + * @param q the public prime divisor of <code>p-1</code>. + * @param g a generator of the unique cyclic group <code>Z<sup>*</sup> + * <sub>p</sub></code>. + * @param x the private key part. + */ + public DSSPrivateKey(BigInteger p, BigInteger q, BigInteger g, BigInteger x) + { + this(Registry.RAW_ENCODING_ID, p, q, g, x); + } + + /** + * Constructs a new instance of a <code>DSSPrivateKey</code> given the + * designated arguments. + * + * @param preferredFormat the indetifier of the preferred encoding format to + * use when externalizing this key. + * @param p the public modulus. + * @param q the public prime divisor of <code>p-1</code>. + * @param g a generator of the unique cyclic group <code>Z<sup>*</sup> + * <sub>p</sub></code>. + * @param x the private key part. + */ + public DSSPrivateKey(int preferredFormat, BigInteger p, BigInteger q, + BigInteger g, BigInteger x) + { + super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.PKCS8_ENCODING_ID + : preferredFormat, + p, q, g); + + this.x = x; + } + + // Class methods + // ------------------------------------------------------------------------- + + /** + * A class method that takes the output of the <code>encodePrivateKey()</code> + * method of a DSS keypair codec object (an instance implementing + * {@link gnu.java.security.key.IKeyPairCodec} for DSS keys, and re-constructs + * an instance of this object. + * + * @param k the contents of a previously encoded instance of this object. + * @exception ArrayIndexOutOfBoundsException if there is not enough bytes, in + * <code>k</code>, to represent a valid encoding of an + * instance of this object. + * @exception IllegalArgumentException if the byte sequence does not represent + * a valid encoding of an instance of this object. + */ + public static DSSPrivateKey valueOf(byte[] k) + { + // try RAW codec + if (k[0] == Registry.MAGIC_RAW_DSS_PRIVATE_KEY[0]) + try + { + return (DSSPrivateKey) new DSSKeyPairRawCodec().decodePrivateKey(k); + } + catch (IllegalArgumentException ignored) + { + } + + // try PKCS#8 codec + return (DSSPrivateKey) new DSSKeyPairPKCS8Codec().decodePrivateKey(k); + } + + // Instance methods + // ------------------------------------------------------------------------- + + // java.security.interfaces.DSAPrivateKey interface implementation --------- + + public BigInteger getX() + { + return x; + } + + // Other instance methods -------------------------------------------------- + + /** + * <p>Returns the encoded form of this private key according to the + * designated format.</p> + * + * @param format the desired format identifier of the resulting encoding. + * @return the byte sequence encoding this key according to the designated + * format. + * @exception IllegalArgumentException if the format is not supported. + * @see DSSKeyPairRawCodec + */ + public byte[] getEncoded(int format) + { + byte[] result; + switch (format) + { + case IKeyPairCodec.RAW_FORMAT: + result = new DSSKeyPairRawCodec().encodePrivateKey(this); + break; + case IKeyPairCodec.PKCS8_FORMAT: + result = new DSSKeyPairPKCS8Codec().encodePrivateKey(this); + break; + default: + throw new IllegalArgumentException("Unsupported encoding format: " + + format); + } + return result; + } + + /** + * <p>Returns <code>true</code> if the designated object is an instance of + * {@link DSAPrivateKey} and has the same DSS (Digital Signature Standard) + * parameter values as this one.</p> + * + * @param obj the other non-null DSS key to compare to. + * @return <code>true</code> if the designated object is of the same type and + * value as this one. + */ + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + if (!(obj instanceof DSAPrivateKey)) + { + return false; + } + DSAPrivateKey that = (DSAPrivateKey) obj; + return super.equals(that) && x.equals(that.getX()); + } +} diff --git a/libjava/classpath/gnu/java/security/key/dss/DSSPublicKey.java b/libjava/classpath/gnu/java/security/key/dss/DSSPublicKey.java new file mode 100644 index 00000000000..93bb6402203 --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/dss/DSSPublicKey.java @@ -0,0 +1,201 @@ +/* DSSPublicKey.java -- + Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key.dss; + +import gnu.java.security.Registry; +import gnu.java.security.key.IKeyPairCodec; + +import java.math.BigInteger; +import java.security.PublicKey; +import java.security.interfaces.DSAPublicKey; + +/** + * <p>An object that embodies a DSS (Digital Signature Standard) public key.</p> + * + * @version $Revision: 1.2 $ + * @see #getEncoded + */ +public class DSSPublicKey extends DSSKey implements PublicKey, DSAPublicKey +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** + * <code>y = g<sup>x</sup> mod p</code> where <code>x</code> is the private + * part of the DSA key. + */ + private final BigInteger y; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Conveience constructor. Calls the constructor with 5 arguments passing + * {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred + * encoding format. + * + * @param p the public modulus. + * @param q the public prime divisor of <code>p-1</code>. + * @param g a generator of the unique cyclic group <code>Z<sup>*</sup> + * <sub>p</sub></code>. + * @param y the public key part. + */ + public DSSPublicKey(BigInteger p, BigInteger q, BigInteger g, BigInteger y) + { + this(Registry.RAW_ENCODING_ID, p, q, g, y); + } + + /** + * Constructs a new instance of <code>DSSPublicKey</code> given the designated + * arguments. + * + * @param preferredFormat the identifier of the preferred encoding format to + * use when externalizing this key. + * @param p the public modulus. + * @param q the public prime divisor of <code>p-1</code>. + * @param g a generator of the unique cyclic group <code>Z<sup>*</sup> + * <sub>p</sub></code>. + * @param y the public key part. + */ + public DSSPublicKey(int preferredFormat, BigInteger p, BigInteger q, + BigInteger g, BigInteger y) + { + super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.X509_ENCODING_ID + : preferredFormat, + p, q, g); + + this.y = y; + } + + // Class methods + // ------------------------------------------------------------------------- + + /** + * A class method that takes the output of the <code>encodePublicKey()</code> + * method of a DSS keypair codec object (an instance implementing + * {@link gnu.java.security.key.IKeyPairCodec} for DSS keys, and re-constructs + * an instance of this object. + * + * @param k the contents of a previously encoded instance of this object. + * @exception ArrayIndexOutOfBoundsException if there is not enough bytes, in + * <code>k</code>, to represent a valid encoding of an + * instance of this object. + * @exception IllegalArgumentException if the byte sequence does not represent + * a valid encoding of an instance of this object. + */ + public static DSSPublicKey valueOf(byte[] k) + { + // try RAW codec + if (k[0] == Registry.MAGIC_RAW_DSS_PUBLIC_KEY[0]) + try + { + return (DSSPublicKey) new DSSKeyPairRawCodec().decodePublicKey(k); + } + catch (IllegalArgumentException ignored) + { + } + + // try X.509 codec + return (DSSPublicKey) new DSSKeyPairX509Codec().decodePublicKey(k); + } + + // Instance methods + // ------------------------------------------------------------------------- + + // java.security.interfaces.DSAPublicKey interface implementation ---------- + + public BigInteger getY() + { + return y; + } + + // Other instance methods -------------------------------------------------- + + /** + * <p>Returns the encoded form of this public key according to the designated + * format.</p> + * + * @param format the desired format identifier of the resulting encoding. + * @return the byte sequence encoding this key according to the designated + * format. + * @exception IllegalArgumentException if the format is not supported. + * @see DSSKeyPairRawCodec + */ + public byte[] getEncoded(int format) + { + byte[] result; + switch (format) + { + case IKeyPairCodec.RAW_FORMAT: + result = new DSSKeyPairRawCodec().encodePublicKey(this); + break; + case IKeyPairCodec.X509_FORMAT: + result = new DSSKeyPairX509Codec().encodePublicKey(this); + break; + default: + throw new IllegalArgumentException("Unsupported encoding format: " + + format); + } + return result; + } + + /** + * <p>Returns <code>true</code> if the designated object is an instance of + * {@link DSAPublicKey} and has the same DSS (Digital Signature Standard) + * parameter values as this one.</p> + * + * @param obj the other non-null DSS key to compare to. + * @return <code>true</code> if the designated object is of the same type and + * value as this one. + */ + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + if (!(obj instanceof DSAPublicKey)) + { + return false; + } + DSAPublicKey that = (DSAPublicKey) obj; + return super.equals(that) && y.equals(that.getY()); + } +} diff --git a/libjava/classpath/gnu/java/security/key/dss/FIPS186.java b/libjava/classpath/gnu/java/security/key/dss/FIPS186.java new file mode 100644 index 00000000000..74be626f58e --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/dss/FIPS186.java @@ -0,0 +1,296 @@ +/* FIPS186.java -- + Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key.dss; + +import gnu.java.security.hash.Sha160; +import gnu.java.security.util.PRNG; +import gnu.java.security.util.Prime2; + +import java.math.BigInteger; +import java.security.SecureRandom; + +/** + * <p>An implementation of the DSA parameters generation as described in + * FIPS-186.</p> + * + * References:<br> + * <a href="http://www.itl.nist.gov/fipspubs/fip186.htm">Digital Signature + * Standard (DSS)</a>, Federal Information Processing Standards Publication 186. + * National Institute of Standards and Technology. + * + * @version $Revision: 1.2 $ + */ +public class FIPS186 +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + public static final int DSA_PARAMS_SEED = 0; + + public static final int DSA_PARAMS_COUNTER = 1; + + public static final int DSA_PARAMS_Q = 2; + + public static final int DSA_PARAMS_P = 3; + + public static final int DSA_PARAMS_E = 4; + + public static final int DSA_PARAMS_G = 5; + + /** The BigInteger constant 2. */ + private static final BigInteger TWO = new BigInteger("2"); + + private static final BigInteger TWO_POW_160 = TWO.pow(160); + + /** The SHA instance to use. */ + private Sha160 sha = new Sha160(); + + /** The length of the modulus of DSS keys generated by this instance. */ + private int L; + + /** The optional {@link SecureRandom} instance to use. */ + private SecureRandom rnd = null; + + /** Our default source of randomness. */ + private PRNG prng = null; + + // Constructor(s) + // ------------------------------------------------------------------------- + + public FIPS186(int L, SecureRandom rnd) + { + super(); + + this.L = L; + this.rnd = rnd; + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + /** + * This method generates the DSS <code>p</code>, <code>q</code>, and + * <code>g</code> parameters only when <code>L</code> (the modulus length) + * is not one of the following: <code>512</code>, <code>768</code> and + * <code>1024</code>. For those values of <code>L</code>, this implementation + * uses pre-computed values of <code>p</code>, <code>q</code>, and + * <code>g</code> given in the document <i>CryptoSpec</i> included in the + * security guide documentation of the standard JDK distribution.<p> + * + * The DSS requires two primes , <code>p</code> and <code>q</code>, + * satisfying the following three conditions: + * + * <ul> + * <li><code>2<sup>159</sup> < q < 2<sup>160</sup></code></li> + * <li><code>2<sup>L-1</sup> < p < 2<sup>L</sup></code> for a + * specified <code>L</code>, where <code>L = 512 + 64j</code> for some + * <code>0 <= j <= 8</code></li> + * <li>q divides p - 1.</li> + * </ul> + * + * The algorithm used to find these primes is as described in FIPS-186, + * section 2.2: GENERATION OF PRIMES. This prime generation scheme starts by + * using the {@link Sha160} and a user supplied <i>SEED</i> + * to construct a prime, <code>q</code>, in the range 2<sup>159</sup> < q + * < 2<sup>160</sup>. Once this is accomplished, the same <i>SEED</i> + * value is used to construct an <code>X</code> in the range <code>2<sup>L-1 + * </sup> < X < 2<sup>L</sup>. The prime, <code>p</code>, is then + * formed by rounding <code>X</code> to a number congruent to <code>1 mod + * 2q</code>. In this implementation we use the same <i>SEED</i> value given + * in FIPS-186, Appendix 5. + */ + public BigInteger[] generateParameters() + { + int counter, offset; + BigInteger SEED, alpha, U, q, OFFSET, SEED_PLUS_OFFSET, W, X, p, c, g; + byte[] a, u; + byte[] kb = new byte[20]; // to hold 160 bits of randomness + + // Let L-1 = n*160 + b, where b and n are integers and 0 <= b < 160. + int b = (L - 1) % 160; + int n = (L - 1 - b) / 160; + BigInteger[] V = new BigInteger[n + 1]; + algorithm: while (true) + { + step1: while (true) + { + // 1. Choose an arbitrary sequence of at least 160 bits and + // call it SEED. + nextRandomBytes(kb); + SEED = new BigInteger(1, kb).setBit(159).setBit(0); + // Let g be the length of SEED in bits. here always 160 + // 2. Compute: U = SHA[SEED] XOR SHA[(SEED+1) mod 2**g] + alpha = SEED.add(BigInteger.ONE).mod(TWO_POW_160); + synchronized (sha) + { + a = SEED.toByteArray(); + sha.update(a, 0, a.length); + a = sha.digest(); + u = alpha.toByteArray(); + sha.update(u, 0, u.length); + u = sha.digest(); + } + for (int i = 0; i < a.length; i++) + { + a[i] ^= u[i]; + } + U = new BigInteger(1, a); + // 3. Form q from U by setting the most significant bit (the + // 2**159 bit) and the least significant bit to 1. In terms of + // boolean operations, q = U OR 2**159 OR 1. Note that + // 2**159 < q < 2**160. + q = U.setBit(159).setBit(0); + // 4. Use a robust primality testing algorithm to test whether + // q is prime(1). A robust primality test is one where the + // probability of a non-prime number passing the test is at + // most 1/2**80. + // 5. If q is not prime, go to step 1. + if (Prime2.isProbablePrime(q)) + { + break step1; + } + } // step1 + + // 6. Let counter = 0 and offset = 2. + counter = 0; + offset = 2; + step7: while (true) + { + OFFSET = BigInteger.valueOf(offset & 0xFFFFFFFFL); + SEED_PLUS_OFFSET = SEED.add(OFFSET); + // 7. For k = 0,...,n let V[k] = SHA[(SEED + offset + k) mod 2**g]. + synchronized (sha) + { + for (int k = 0; k <= n; k++) + { + a = SEED_PLUS_OFFSET.add( + BigInteger.valueOf(k & 0xFFFFFFFFL)).mod( + TWO_POW_160).toByteArray(); + sha.update(a, 0, a.length); + V[k] = new BigInteger(1, sha.digest()); + } + } + // 8. Let W be the integer: + // V[0]+V[1]*2**160+...+V[n-1]*2**((n-1)*160)+(V[n]mod2**b)*2**(n*160) + // and let : X = W + 2**(L-1). + // Note that 0 <= W < 2**(L-1) and hence 2**(L-1) <= X < 2**L. + W = V[0]; + for (int k = 1; k < n; k++) + { + W = W.add(V[k].multiply(TWO.pow(k * 160))); + } + W = W.add(V[n].mod(TWO.pow(b)).multiply(TWO.pow(n * 160))); + X = W.add(TWO.pow(L - 1)); + // 9. Let c = X mod 2q and set p = X - (c - 1). + // Note that p is congruent to 1 mod 2q. + c = X.mod(TWO.multiply(q)); + p = X.subtract(c.subtract(BigInteger.ONE)); + // 10. If p < 2**(L-1), then go to step 13. + if (p.compareTo(TWO.pow(L - 1)) >= 0) + { + // 11. Perform a robust primality test on p. + // 12. If p passes the test performed in step 11, go to step 15. + if (Prime2.isProbablePrime(p)) + { + break algorithm; + } + } + // 13. Let counter = counter + 1 and offset = offset + n + 1. + counter++; + offset += n + 1; + // 14. If counter >= 4096 go to step 1, otherwise go to step 7. + if (counter >= 4096) + { + continue algorithm; + } + } // step7 + } // algorithm + + // compute g. from FIPS-186, Appendix 4: + // 1. Generate p and q as specified in Appendix 2. + // 2. Let e = (p - 1) / q + BigInteger e = p.subtract(BigInteger.ONE).divide(q); + BigInteger h = TWO; + BigInteger p_minus_1 = p.subtract(BigInteger.ONE); + g = TWO; + // 3. Set h = any integer, where 1 < h < p - 1 and + // h differs from any value previously tried + for (; h.compareTo(p_minus_1) < 0; h = h.add(BigInteger.ONE)) + { + // 4. Set g = h**e mod p + g = h.modPow(e, p); + // 5. If g = 1, go to step 3 + if (!g.equals(BigInteger.ONE)) + { + break; + } + } + + return new BigInteger[] { SEED, BigInteger.valueOf(counter), q, p, e, g }; + } + + // helper methods ---------------------------------------------------------- + + /** + * Fills the designated byte array with random data. + * + * @param buffer the byte array to fill with random data. + */ + private void nextRandomBytes(byte[] buffer) + { + if (rnd != null) + { + rnd.nextBytes(buffer); + } + else + getDefaultPRNG().nextBytes(buffer); + } + + private PRNG getDefaultPRNG() + { + if (prng == null) + prng = PRNG.getInstance(); + + return prng; + } +} diff --git a/libjava/classpath/gnu/java/security/key/rsa/GnuRSAKey.java b/libjava/classpath/gnu/java/security/key/rsa/GnuRSAKey.java new file mode 100644 index 00000000000..72cd808d43b --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/rsa/GnuRSAKey.java @@ -0,0 +1,181 @@ +/* GnuRSAKey.java -- + Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key.rsa; + +import gnu.java.security.Registry; +import gnu.java.security.key.IKeyPairCodec; +import gnu.java.security.util.FormatUtil; + +import java.math.BigInteger; +import java.security.Key; +import java.security.interfaces.RSAKey; + +/** + * <p>A base asbtract class for both public and private RSA keys.</p> + * + * @version $Revision: 1.3 $ + */ +public abstract class GnuRSAKey implements Key, RSAKey +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** The public modulus of an RSA key pair. */ + private final BigInteger n; + + /** The public exponent of an RSA key pair. */ + private final BigInteger e; + + /** + * Identifier of the default encoding format to use when externalizing the + * key material. + */ + protected final int defaultFormat; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Trivial protected constructor. + * + * @param defaultFormat the identifier of the encoding format to use by + * default when externalizing the key. + * @param n the public modulus <code>n</code>. + * @param e the public exponent <code>e</code>. + */ + protected GnuRSAKey(int defaultFormat, BigInteger n, BigInteger e) + { + super(); + + this.defaultFormat = defaultFormat <= 0 ? Registry.RAW_ENCODING_ID + : defaultFormat; + this.n = n; + this.e = e; + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // java.security.interfaces.RSAKey interface implementation ---------------- + + public BigInteger getModulus() + { + return getN(); + } + + // java.security.Key interface implementation ------------------------------ + + public String getAlgorithm() + { + return Registry.RSA_KPG; + } + + /** @deprecated see getEncoded(int). */ + public byte[] getEncoded() + { + return getEncoded(IKeyPairCodec.RAW_FORMAT); + } + + public String getFormat() + { + return FormatUtil.getEncodingShortName(defaultFormat); + } + + // Other instance methods -------------------------------------------------- + + /** + * <p>Returns the modulus <code>n</code>.</p> + * + * @return the modulus <code>n</code>. + */ + public BigInteger getN() + { + return n; + } + + /** + * <p>Returns the public exponent <code>e</code>.</p> + * + * @return the public exponent <code>e</code>. + */ + public BigInteger getPublicExponent() + { + return getE(); + } + + /** + * <p>Same as {@link #getPublicExponent()}.</p> + * + * @return the public exponent <code>e</code>. + */ + public BigInteger getE() + { + return e; + } + + /** + * <p>Returns <code>true</code> if the designated object is an instance of + * {@link RSAKey} and has the same RSA parameter values as this one.</p> + * + * @param obj the other non-null RSA key to compare to. + * @return <code>true</code> if the designated object is of the same type and + * value as this one. + */ + public boolean equals(final Object obj) + { + if (obj == null) + { + return false; + } + if (!(obj instanceof RSAKey)) + { + return false; + } + final RSAKey that = (RSAKey) obj; + return n.equals(that.getModulus()); + } + + // abstract methods to be implemented by subclasses ------------------------ + + public abstract byte[] getEncoded(int format); +} diff --git a/libjava/classpath/gnu/java/security/key/rsa/GnuRSAPrivateKey.java b/libjava/classpath/gnu/java/security/key/rsa/GnuRSAPrivateKey.java new file mode 100644 index 00000000000..f8acaa50df7 --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/rsa/GnuRSAPrivateKey.java @@ -0,0 +1,299 @@ +/* GnuRSAPrivateKey.java -- + Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key.rsa; + +import gnu.java.security.Registry; +import gnu.java.security.key.IKeyPairCodec; + +import java.math.BigInteger; +import java.security.PrivateKey; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.interfaces.RSAPrivateKey; + +/** + * <p>An object that embodies an RSA private key.</p> + * + * <p>References:</p> + * <ol> + * <li><a href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip"> + * RSA-PSS Signature Scheme with Appendix, part B.</a><br> + * Primitive specification and supporting documentation.<br> + * Jakob Jonsson and Burt Kaliski.</li> + * </ol> + * + * @version $Revision: 1.3 $ + */ +public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey, + RSAPrivateCrtKey +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** The first prime divisor of the modulus. */ + private final BigInteger p; + + /** The second prime divisor of the modulus. */ + private final BigInteger q; + + /** The public exponent of an RSA key. */ + // private final BigInteger e; + /** The private exponent of an RSA private key. */ + private final BigInteger d; + + /** The first factor's exponent. */ + private final BigInteger dP; + + /** The second factor's exponent. */ + private final BigInteger dQ; + + /** The CRT (Chinese Remainder Theorem) coefficient. */ + private final BigInteger qInv; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Convenience constructor. Calls the constructor with 5 arguments passing + * {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred + * encoding format. + * + * @param p the modulus first prime divisor. + * @param q the modulus second prime divisor. + * @param e the public exponent. + * @param d the private exponent. + */ + public GnuRSAPrivateKey(BigInteger p, BigInteger q, BigInteger e, + BigInteger d) + { + this(Registry.RAW_ENCODING_ID, p, q, e, d); + } + + /** + * Constructs a new instance of a <code>GnuRSAPrivateKey</code> given the + * designated arguments. + * + * @param preferredFormat the indetifier of the preferred encoding format to + * use when externalizing this key. + * @param p the modulus first prime divisor. + * @param q the modulus second prime divisor. + * @param e the public exponent. + * @param d the private exponent. + */ + public GnuRSAPrivateKey(int preferredFormat, BigInteger p, BigInteger q, + BigInteger e, BigInteger d) + { + this(preferredFormat, p.multiply(q), e, d, p, q, + e.modInverse(p.subtract(BigInteger.ONE)), + e.modInverse(q.subtract(BigInteger.ONE)), + q.modInverse(p)); + } + + /** + * Constructs a new instance of a <code>GnuRSAPrivateKey</code> given the + * designated arguments. + * + * @param preferredFormat the indetifier of the preferred encoding format to + * use when externalizing this key. + * @param n the public modulus, which is also the product of <code>p</code> + * and <code>q</code>. + * @param e the public exponent. + * @param d the private exponent. + * @param p the modulus first prime divisor. + * @param q the modulus second prime divisor. + * @param dP the first prime's exponen. A positive integer less than + * <code>p</code> and <code>q</code>, satisfying <code>e * dP = 1 (mod p-1) + * </code>. + * @param dQ the second prime's exponent. A positive integer less than + * <code>p</code> and <code>q</code>, satisfying <code>e * dQ = 1 (mod p-1) + * </code>. + * @param qInv the Chinese Remainder Theorem coefiicient. A positive integer + * less than <code>p</code>, satisfying <code>q * qInv = 1 (mod p)</code>. + */ + public GnuRSAPrivateKey(int preferredFormat, BigInteger n, BigInteger e, + BigInteger d, BigInteger p, BigInteger q, + BigInteger dP, BigInteger dQ, BigInteger qInv) + { + super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.PKCS8_ENCODING_ID + : preferredFormat, + n, e); + + this.d = d; + this.p = p; + this.q = q; + // the exponents dP and dQ are positive integers less than p and q + // respectively satisfying + // e * dP = 1 (mod p-1); + // e * dQ = 1 (mod q-1), + this.dP = dP; + this.dQ = dQ; + // the CRT coefficient qInv is a positive integer less than p satisfying + // q * qInv = 1 (mod p). + this.qInv = qInv; + } + + // Class methods + // ------------------------------------------------------------------------- + + /** + * A class method that takes the output of the <code>encodePrivateKey()</code> + * method of an RSA keypair codec object (an instance implementing + * {@link IKeyPairCodec} for RSA keys, and re-constructs an instance of this + * object. + * + * @param k the contents of a previously encoded instance of this object. + * @throws ArrayIndexOutOfBoundsException if there is not enough bytes, in + * <code>k</code>, to represent a valid encoding of an instance + * of this object. + * @throws IllegalArgumentException if the byte sequence does not represent a + * valid encoding of an instance of this object. + */ + public static GnuRSAPrivateKey valueOf(final byte[] k) + { + // try RAW codec + if (k[0] == Registry.MAGIC_RAW_RSA_PRIVATE_KEY[0]) + try + { + return (GnuRSAPrivateKey) new RSAKeyPairRawCodec().decodePrivateKey(k); + } + catch (IllegalArgumentException ignored) + { + } + + // try PKCS#8 codec + return (GnuRSAPrivateKey) new RSAKeyPairPKCS8Codec().decodePrivateKey(k); + } + + // Instance methods + // ------------------------------------------------------------------------- + + public BigInteger getPrimeP() + { + return p; + } + + public BigInteger getPrimeQ() + { + return q; + } + + public BigInteger getPrimeExponentP() + { + return dP; + } + + public BigInteger getPrimeExponentQ() + { + return dQ; + } + + public BigInteger getCrtCoefficient() + { + return qInv; + } + + // java.security.interfaces.RSAPrivateKey interface implementation --------- + + public BigInteger getPrivateExponent() + { + return d; + } + + // Other instance methods -------------------------------------------------- + + /** + * Returns the encoded form of this private key according to the + * designated format. + * + * @param format the desired format identifier of the resulting encoding. + * @return the byte sequence encoding this key according to the designated + * format. + * @throws IllegalArgumentException if the format is not supported. + * @see RSAKeyPairRawCodec + * @see RSAKeyPairPKCS8Codec + */ + public byte[] getEncoded(int format) + { + final byte[] result; + switch (format) + { + case IKeyPairCodec.RAW_FORMAT: + result = new RSAKeyPairRawCodec().encodePrivateKey(this); + break; + case IKeyPairCodec.PKCS8_FORMAT: + result = new RSAKeyPairPKCS8Codec().encodePrivateKey(this); + break; + default: + throw new IllegalArgumentException("Unsupported encoding format: " + + format); + } + return result; + } + + /** + * <p>Returns <code>true</code> if the designated object is an instance of + * this class and has the same RSA parameter values as this one.</p> + * + * @param obj the other non-null RSA key to compare to. + * @return <code>true</code> if the designated object is of the same type + * and value as this one. + */ + public boolean equals(final Object obj) + { + if (obj == null) + { + return false; + } + if (obj instanceof RSAPrivateKey) + { + final RSAPrivateKey that = (RSAPrivateKey) obj; + return super.equals(that) && d.equals(that.getPrivateExponent()); + } + if (obj instanceof RSAPrivateCrtKey) + { + final RSAPrivateCrtKey that = (RSAPrivateCrtKey) obj; + return super.equals(that) && p.equals(that.getPrimeP()) + && q.equals(that.getPrimeQ()) + && dP.equals(that.getPrimeExponentP()) + && dQ.equals(that.getPrimeExponentQ()) + && qInv.equals(that.getCrtCoefficient()); + } + return false; + } +} diff --git a/libjava/classpath/gnu/java/security/key/rsa/GnuRSAPublicKey.java b/libjava/classpath/gnu/java/security/key/rsa/GnuRSAPublicKey.java new file mode 100644 index 00000000000..f49027ca621 --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/rsa/GnuRSAPublicKey.java @@ -0,0 +1,185 @@ +/* GnuRSAPublicKey.java -- + Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key.rsa; + +import gnu.java.security.Registry; +import gnu.java.security.key.IKeyPairCodec; + +import java.math.BigInteger; +import java.security.PublicKey; +import java.security.interfaces.RSAPublicKey; + +/** + * <p>An object that encapsulates an RSA public key.</p> + * + * <p>References:</p> + * <ol> + * <li><a href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip"> + * RSA-PSS Signature Scheme with Appendix, part B.</a><br> + * Primitive specification and supporting documentation.<br> + * Jakob Jonsson and Burt Kaliski.</li> + * </ol> + * + * @version $Revision: 1.2 $ + */ +public class GnuRSAPublicKey extends GnuRSAKey implements PublicKey, + RSAPublicKey +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Conveience constructor. Calls the constructor with 3 arguments passing + * {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred + * encoding format. + * + * @param n the modulus. + * @param e the public exponent. + */ + public GnuRSAPublicKey(final BigInteger n, final BigInteger e) + { + this(Registry.RAW_ENCODING_ID, n, e); + } + + /** + * Constructs a new instance of <code>GnuRSAPublicKey</code> given the + * designated arguments. + * + * @param preferredFormat the identifier of the preferred encoding format to + * use when externalizing this key. + * @param n the modulus. + * @param e the public exponent. + */ + public GnuRSAPublicKey(int preferredFormat, BigInteger n, BigInteger e) + { + super(preferredFormat == Registry.ASN1_ENCODING_ID ? Registry.X509_ENCODING_ID + : preferredFormat, + n, e); + } + + // Class methods + // ------------------------------------------------------------------------- + + /** + * A class method that takes the output of the <code>encodePublicKey()</code> + * method of an RSA keypair codec object (an instance implementing + * {@link IKeyPairCodec} for RSA keys, and re-constructs an instance of this + * object. + * + * @param k the contents of a previously encoded instance of this object. + * @throws ArrayIndexOutOfBoundsException if there is not enough bytes, in + * <code>k</code>, to represent a valid encoding of an instance + * of this object. + * @throws IllegalArgumentException if the byte sequence does not represent a + * valid encoding of an instance of this object. + */ + public static GnuRSAPublicKey valueOf(final byte[] k) + { + // try RAW codec + if (k[0] == Registry.MAGIC_RAW_RSA_PUBLIC_KEY[0]) + try + { + return (GnuRSAPublicKey) new RSAKeyPairRawCodec().decodePublicKey(k); + } + catch (IllegalArgumentException ignored) + { + } + + // try X.509 codec + return (GnuRSAPublicKey) new RSAKeyPairX509Codec().decodePublicKey(k); + } + + // Instance methods + // ------------------------------------------------------------------------- + + /** + * <p>Returns the encoded form of this public key according to the designated + * format.</p> + * + * @param format the desired format identifier of the resulting encoding. + * @return the byte sequence encoding this key according to the designated + * format. + * @throws IllegalArgumentException if the format is not supported. + * @see RSAKeyPairRawCodec + */ + public byte[] getEncoded(final int format) + { + final byte[] result; + switch (format) + { + case IKeyPairCodec.RAW_FORMAT: + result = new RSAKeyPairRawCodec().encodePublicKey(this); + break; + case IKeyPairCodec.X509_FORMAT: + result = new RSAKeyPairX509Codec().encodePublicKey(this); + break; + default: + throw new IllegalArgumentException("Unsupported encoding format: " + + format); + } + return result; + } + + /** + * <p>Returns <code>true</code> if the designated object is an instance of + * this class and has the same RSA parameter values as this one.</p> + * + * @param obj the other non-null RSA key to compare to. + * @return <code>true</code> if the designated object is of the same type and + * value as this one. + */ + public boolean equals(final Object obj) + { + if (obj == null) + { + return false; + } + if (!(obj instanceof RSAPublicKey)) + { + return false; + } + final RSAPublicKey that = (RSAPublicKey) obj; + return super.equals(that) + && getPublicExponent().equals(that.getPublicExponent()); + } +} diff --git a/libjava/classpath/gnu/java/security/key/rsa/RSAKeyPairGenerator.java b/libjava/classpath/gnu/java/security/key/rsa/RSAKeyPairGenerator.java new file mode 100644 index 00000000000..9c7338f662a --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/rsa/RSAKeyPairGenerator.java @@ -0,0 +1,264 @@ +/* RSAKeyPairGenerator.java -- + Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key.rsa; + +import gnu.java.security.Registry; +import gnu.java.security.key.IKeyPairGenerator; +import gnu.java.security.util.PRNG; +import gnu.java.security.util.Prime2; + +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.spec.RSAKeyGenParameterSpec; +import java.util.Map; + +/** + * <p>A key-pair generator for asymetric keys to use in conjunction with the RSA + * scheme.</p> + * + * <p>Reference:</p> + * <ol> + * <li><a href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip"> + * RSA-PSS Signature Scheme with Appendix</a>, part B. Primitive + * specification and supporting documentation. Jakob Jonsson and Burt Kaliski. + * </li> + * <li><a href="http://www.cacr.math.uwaterloo.ca/hac/">Handbook of Applied + * Cryptography</a>, Alfred J. Menezes, Paul C. van Oorschot and Scott A. + * Vanstone. Section 11.3 RSA and related signature schemes.</li> + * </ol> + */ +public class RSAKeyPairGenerator implements IKeyPairGenerator +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** The BigInteger constant 1. */ + private static final BigInteger ONE = BigInteger.ONE; + + /** The BigInteger constant 2. */ + private static final BigInteger TWO = BigInteger.valueOf(2L); + + /** Property name of the length (Integer) of the modulus of an RSA key. */ + public static final String MODULUS_LENGTH = "gnu.crypto.rsa.L"; + + /** + * Property name of an optional {@link SecureRandom} instance to use. The + * default is to use a classloader singleton from {@link PRNG}. + */ + public static final String SOURCE_OF_RANDOMNESS = "gnu.crypto.rsa.prng"; + + /** + * Property name of an optional {@link RSAKeyGenParameterSpec} instance to + * use for this generator's <code>n</code>, and <code>e</code> values. The + * default is to generate <code>n</code> and use a fixed value for + * <code>e</.code> (Fermat's F4 number). + */ + public static final String RSA_PARAMETERS = "gnu.crypto.rsa.params"; + + /** + * Property name of the preferred encoding format to use when externalizing + * generated instance of key-pairs from this generator. The property is taken + * to be an {@link Integer} that encapsulates an encoding format identifier. + */ + public static final String PREFERRED_ENCODING_FORMAT = "gnu.crypto.rsa.encoding"; + + /** Default value for the modulus length. */ + private static final int DEFAULT_MODULUS_LENGTH = 1024; + + /** Default encoding format to use when none was specified. */ + private static final int DEFAULT_ENCODING_FORMAT = Registry.RAW_ENCODING_ID; + + /** The desired bit length of the modulus. */ + private int L; + + /** + * This implementation uses, by default, Fermat's F4 number as the public + * exponent. + */ + private BigInteger e = BigInteger.valueOf(65537L); + + /** The optional {@link SecureRandom} instance to use. */ + private SecureRandom rnd = null; + + /** Our default source of randomness. */ + private PRNG prng = null; + + /** Preferred encoding format of generated keys. */ + private int preferredFormat; + + // Constructor(s) + // ------------------------------------------------------------------------- + + // implicit 0-arguments constructor + + // Class methods + // ------------------------------------------------------------------------- + + // gnu.crypto.key.IKeyPairGenerator interface implementation --------------- + + public String name() + { + return Registry.RSA_KPG; + } + + /** + * <p>Configures this instance.</p> + * + * @param attributes the map of name/value pairs to use. + * @exception IllegalArgumentException if the designated MODULUS_LENGTH + * value is less than 1024. + */ + public void setup(Map attributes) + { + // do we have a SecureRandom, or should we use our own? + rnd = (SecureRandom) attributes.get(SOURCE_OF_RANDOMNESS); + + // are we given a set of RSA params or we shall use our own? + RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) attributes.get(RSA_PARAMETERS); + + // find out the modulus length + if (params != null) + { + L = params.getKeysize(); + e = params.getPublicExponent(); + } + else + { + Integer l = (Integer) attributes.get(MODULUS_LENGTH); + L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue()); + } + + if (L < 1024) + { + throw new IllegalArgumentException(MODULUS_LENGTH); + } + + // what is the preferred encoding format + Integer formatID = (Integer) attributes.get(PREFERRED_ENCODING_FORMAT); + preferredFormat = formatID == null ? DEFAULT_ENCODING_FORMAT + : formatID.intValue(); + } + + /** + * <p>The algorithm used here is described in <i>nessie-pss-B.pdf</i> + * document which is part of the RSA-PSS submission to NESSIE.</p> + * + * @return an RSA keypair. + */ + public KeyPair generate() + { + BigInteger p, q, n, d; + + // 1. Generate a prime p in the interval [2**(M-1), 2**M - 1], where + // M = CEILING(L/2), and such that GCD(p, e) = 1 + int M = (L + 1) / 2; + BigInteger lower = TWO.pow(M - 1); + BigInteger upper = TWO.pow(M).subtract(ONE); + byte[] kb = new byte[(M + 7) / 8]; // enough bytes to frame M bits + step1: while (true) + { + nextRandomBytes(kb); + p = new BigInteger(1, kb).setBit(0); + if (p.compareTo(lower) >= 0 && p.compareTo(upper) <= 0 + && Prime2.isProbablePrime(p) && p.gcd(e).equals(ONE)) + { + break step1; + } + } + + // 2. Generate a prime q such that the product of p and q is an L-bit + // number, and such that GCD(q, e) = 1 + step2: while (true) + { + nextRandomBytes(kb); + q = new BigInteger(1, kb).setBit(0); + n = p.multiply(q); + if (n.bitLength() == L && Prime2.isProbablePrime(q) + && q.gcd(e).equals(ONE)) + { + break step2; + } + + // TODO: test for p != q + } + + // TODO: ensure p < q + + // 3. Put n = pq. The public key is (n, e). + // 4. Compute the parameters necessary for the private key K (see + // Section 2.2). + BigInteger phi = p.subtract(ONE).multiply(q.subtract(ONE)); + d = e.modInverse(phi); + + // 5. Output the public key and the private key. + PublicKey pubK = new GnuRSAPublicKey(preferredFormat, n, e); + PrivateKey secK = new GnuRSAPrivateKey(preferredFormat, p, q, e, d); + + return new KeyPair(pubK, secK); + } + + // helper methods ---------------------------------------------------------- + + /** + * <p>Fills the designated byte array with random data.</p> + * + * @param buffer the byte array to fill with random data. + */ + private void nextRandomBytes(byte[] buffer) + { + if (rnd != null) + { + rnd.nextBytes(buffer); + } + else + getDefaultPRNG().nextBytes(buffer); + } + + private PRNG getDefaultPRNG() + { + if (prng == null) + prng = PRNG.getInstance(); + + return prng; + } +} diff --git a/libjava/classpath/gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java b/libjava/classpath/gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java new file mode 100644 index 00000000000..a7f65b61012 --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/rsa/RSAKeyPairPKCS8Codec.java @@ -0,0 +1,284 @@ +/* RSAKeyPairPKCS8Codec.java -- PKCS#8 Encoding/Decoding handler + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.key.rsa; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.InvalidParameterException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.ArrayList; + +import gnu.java.security.OID; +import gnu.java.security.Registry; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.der.DERWriter; +import gnu.java.security.key.IKeyPairCodec; +import gnu.java.security.util.DerUtil; + +/** + * An implementation of an {@link IKeyPairCodec} that knows how to encode / + * decode PKCS#8 ASN.1 external representation of RSA private keys. + */ +public class RSAKeyPairPKCS8Codec + implements IKeyPairCodec +{ + private static final OID RSA_ALG_OID = new OID(Registry.RSA_OID_STRING); + + // implicit 0-arguments constructor + + public int getFormatID() + { + return PKCS8_FORMAT; + } + + /** + * @throws InvalidParameterException ALWAYS. + */ + public byte[] encodePublicKey(PublicKey key) + { + throw new InvalidParameterException("Wrong format for public keys"); + } + + /** + * Returns the PKCS#8 ASN.1 <i>PrivateKeyInfo</i> representation of an RSA + * private key. The ASN.1 specification is as follows: + * + * <pre> + * PrivateKeyInfo ::= SEQUENCE { + * version INTEGER, -- MUST be 0 + * privateKeyAlgorithm AlgorithmIdentifier, + * privateKey OCTET STRING + * } + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * </pre> + * + * <p>The <i>privateKey</i> field, which is an OCTET STRING, contains the + * DER-encoded form of the RSA private key defined as:</p> + * + * <pre> + * RSAPrivateKey ::= SEQUENCE { + * version INTEGER, -- MUST be 0 + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * privateExponent INTEGER, -- d + * prime1 INTEGER, -- p + * prime2 INTEGER, -- q + * exponent1 INTEGER, -- d mod (p-1) + * exponent2 INTEGER, -- d mod (q-1) + * coefficient INTEGER, -- (inverse of q) mod p + * } + * </pre> + * + * @return the DER encoded form of the ASN.1 representation of the + * <i>PrivateKeyInfo</i> field for an RSA {@link PrivateKey}.. + * @throw InvalidParameterException if an error occurs during the marshalling + * process. + */ + public byte[] encodePrivateKey(PrivateKey key) + { + if (! (key instanceof GnuRSAPrivateKey)) + throw new InvalidParameterException("Wrong key type"); + + GnuRSAPrivateKey pk = (GnuRSAPrivateKey) key; + BigInteger n = pk.getN(); + BigInteger e = pk.getE(); + BigInteger d = pk.getPrivateExponent(); + BigInteger p = pk.getPrimeP(); + BigInteger q = pk.getPrimeQ(); + BigInteger dP = pk.getPrimeExponentP(); + BigInteger dQ = pk.getPrimeExponentQ(); + BigInteger qInv = pk.getCrtCoefficient(); + + DERValue derVersion = new DERValue(DER.INTEGER, BigInteger.ZERO); + + DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, RSA_ALG_OID); + + ArrayList algorithmID = new ArrayList(1); + algorithmID.add(derOID); + DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + algorithmID); + + DERValue derRSAVersion = new DERValue(DER.INTEGER, BigInteger.ZERO); + DERValue derN = new DERValue(DER.INTEGER, n); + DERValue derE = new DERValue(DER.INTEGER, e); + DERValue derD = new DERValue(DER.INTEGER, d); + DERValue derP = new DERValue(DER.INTEGER, p); + DERValue derQ = new DERValue(DER.INTEGER, q); + DERValue derDP = new DERValue(DER.INTEGER, dP); + DERValue derDQ = new DERValue(DER.INTEGER, dQ); + DERValue derQInv = new DERValue(DER.INTEGER, qInv); + + ArrayList rsaPrivateKey = new ArrayList(); + rsaPrivateKey.add(derRSAVersion); + rsaPrivateKey.add(derN); + rsaPrivateKey.add(derE); + rsaPrivateKey.add(derD); + rsaPrivateKey.add(derP); + rsaPrivateKey.add(derQ); + rsaPrivateKey.add(derDP); + rsaPrivateKey.add(derDQ); + rsaPrivateKey.add(derQInv); + DERValue derRSAPrivateKey = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + rsaPrivateKey); + byte[] pkBytes = derRSAPrivateKey.getEncoded(); + DERValue derPrivateKey = new DERValue(DER.OCTET_STRING, pkBytes); + + ArrayList pki = new ArrayList(3); + pki.add(derVersion); + pki.add(derAlgorithmID); + pki.add(derPrivateKey); + DERValue derPKI = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, pki); + + byte[] result; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try + { + DERWriter.write(baos, derPKI); + result = baos.toByteArray(); + } + catch (IOException x) + { + InvalidParameterException y = new InvalidParameterException(); + y.initCause(x); + throw y; + } + + return result; + } + + /** + * @throws InvalidParameterException ALWAYS. + */ + public PublicKey decodePublicKey(byte[] input) + { + throw new InvalidParameterException("Wrong format for public keys"); + } + + /** + * @param input the byte array to unmarshall into a valid RSA + * {@link PrivateKey} instance. MUST NOT be null. + * @return a new instance of a {@link GnuRSAPrivateKey} decoded from the + * <i>PrivateKeyInfo</i> material fed as <code>input</code>. + * @throw InvalidParameterException if an exception occurs during the + * unmarshalling process. + */ + public PrivateKey decodePrivateKey(byte[] input) + { + if (input == null) + throw new InvalidParameterException("Input bytes MUST NOT be null"); + + BigInteger version, n, e, d, p, q, dP, dQ, qInv; + DERReader der = new DERReader(input); + try + { + DERValue derPKI = der.read(); + DerUtil.checkIsConstructed(derPKI, "Wrong PrivateKeyInfo field"); + + DERValue derVersion = der.read(); + DerUtil.checkIsBigInteger(derVersion, "Wrong Version field"); + version = (BigInteger) derVersion.getValue(); + if (version.compareTo(BigInteger.ZERO) != 0) + throw new InvalidParameterException("Unexpected Version: " + version); + + DERValue derAlgoritmID = der.read(); + DerUtil.checkIsConstructed(derAlgoritmID, "Wrong AlgorithmIdentifier field"); + + DERValue derOID = der.read(); + OID algOID = (OID) derOID.getValue(); + if (! algOID.equals(RSA_ALG_OID)) + throw new InvalidParameterException("Unexpected OID: " + algOID); + + DERValue val = der.read(); + byte[] pkBytes = (byte[]) val.getValue(); + + der = new DERReader(pkBytes); + DERValue derRSAPrivateKey = der.read(); + DerUtil.checkIsConstructed(derRSAPrivateKey, "Wrong RSAPrivateKey field"); + + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong RSAPrivateKey Version field"); + version = (BigInteger) val.getValue(); + if (version.compareTo(BigInteger.ZERO) != 0) + throw new InvalidParameterException("Unexpected RSAPrivateKey Version: " + + version); + + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong modulus field"); + n = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong publicExponent field"); + e = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong privateExponent field"); + d = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong prime1 field"); + p = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong prime2 field"); + q = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong exponent1 field"); + dP = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong exponent2 field"); + dQ = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong coefficient field"); + qInv = (BigInteger) val.getValue(); + } + catch (IOException x) + { + InvalidParameterException y = new InvalidParameterException(); + y.initCause(x); + throw y; + } + + return new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID, n, e, d, p, q, + dP, dQ, qInv); + } +} diff --git a/libjava/classpath/gnu/java/security/key/rsa/RSAKeyPairRawCodec.java b/libjava/classpath/gnu/java/security/key/rsa/RSAKeyPairRawCodec.java new file mode 100644 index 00000000000..fb7cea99edd --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/rsa/RSAKeyPairRawCodec.java @@ -0,0 +1,332 @@ +/* RSAKeyPairRawCodec.java -- + Copyright 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.key.rsa; + +import gnu.java.security.Registry; +import gnu.java.security.key.IKeyPairCodec; + +import java.io.ByteArrayOutputStream; +import java.math.BigInteger; +import java.security.PrivateKey; +import java.security.PublicKey; + +/** + * <p>An object that implements the {@link IKeyPairCodec} interface for the + * <i>Raw</i> format to use with RSA keypairs.</p> + * + * @version $Revision: 1.1 $ + */ +public class RSAKeyPairRawCodec implements IKeyPairCodec +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + // implicit 0-arguments constructor + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // gnu.crypto.key.IKeyPairCodec interface implementation ------------------- + + public int getFormatID() + { + return RAW_FORMAT; + } + + /** + * <p>Returns the encoded form of the designated RSA public key according to + * the <i>Raw</i> format supported by this library.</p> + * + * <p>The <i>Raw</i> format for an RSA public key, in this implementation, is + * a byte sequence consisting of the following:</p> + * + * <ol> + * <li>4-byte magic consisting of the value of the literal + * {@link Registry#MAGIC_RAW_RSA_PUBLIC_KEY},<li> + * <li>1-byte version consisting of the constant: 0x01,</li> + * <li>4-byte count of following bytes representing the RSA parameter + * <code>n</code> (the modulus) in internet order,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the RSA parameter <code>n</code>,</li> + * <li>4-byte count of following bytes representing the RSA parameter + * <code>e</code> (the public exponent) in internet order,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the RSA parameter <code>e</code>.</li> + * </ol> + * + * @param key the key to encode. + * @return the <i>Raw</i> format encoding of the designated key. + * @exception IllegalArgumentException if the designated key is not an RSA + * one. + */ + public byte[] encodePublicKey(PublicKey key) + { + if (!(key instanceof GnuRSAPublicKey)) + { + throw new IllegalArgumentException("key"); + } + + GnuRSAPublicKey rsaKey = (GnuRSAPublicKey) key; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + // magic + baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[0]); + baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[1]); + baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[2]); + baos.write(Registry.MAGIC_RAW_RSA_PUBLIC_KEY[3]); + + // version + baos.write(0x01); + + // n + byte[] buffer = rsaKey.getModulus().toByteArray(); + int length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + // e + buffer = rsaKey.getPublicExponent().toByteArray(); + length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + return baos.toByteArray(); + } + + public PublicKey decodePublicKey(byte[] k) + { + // magic + if (k[0] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[0] + || k[1] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[1] + || k[2] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[2] + || k[3] != Registry.MAGIC_RAW_RSA_PUBLIC_KEY[3]) + { + throw new IllegalArgumentException("magic"); + } + + // version + if (k[4] != 0x01) + { + throw new IllegalArgumentException("version"); + } + int i = 5; + + int l; + byte[] buffer; + + // n + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger n = new BigInteger(1, buffer); + + // e + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger e = new BigInteger(1, buffer); + + return new GnuRSAPublicKey(n, e); + } + + /** + * <p>Returns the encoded form of the designated RSA private key according to + * the <i>Raw</i> format supported by this library.</p> + * + * <p>The <i>Raw</i> format for an RSA private key, in this implementation, + * is a byte sequence consisting of the following:</p> + * + * <ol> + * <li>4-byte magic consisting of the value of the literal + * {@link Registry#MAGIC_RAW_RSA_PRIVATE_KEY},<li> + * <li>1-byte version consisting of the constant: 0x01,</li> + * <li>4-byte count of following bytes representing the RSA parameter + * <code>p</code> (the first prime factor of the modulus) in internet + * order,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the RSA parameter <code>p</code>,</li> + * <li>4-byte count of following bytes representing the RSA parameter + * <code>q</code> (the second prime factor of the modulus) in internet + * order,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the RSA parameter <code>q</code>,</li> + * <li>4-byte count of following bytes representing the RSA parameter + * <code>e</code> (the public exponent) in internet order,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the RSA parameter <code>e</code>,</li> + * <li>4-byte count of following bytes representing the RSA parameter + * <code>d</code> (the private exponent) in internet order,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the RSA parameter <code>d</code>,</li> + * </ol> + * + * @param key the key to encode. + * @return the <i>Raw</i> format encoding of the designated key. + */ + public byte[] encodePrivateKey(PrivateKey key) + { + if (!(key instanceof GnuRSAPrivateKey)) + { + throw new IllegalArgumentException("key"); + } + + GnuRSAPrivateKey rsaKey = (GnuRSAPrivateKey) key; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + // magic + baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[0]); + baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[1]); + baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[2]); + baos.write(Registry.MAGIC_RAW_RSA_PRIVATE_KEY[3]); + + // version + baos.write(0x01); + + // p + byte[] buffer = rsaKey.getPrimeP().toByteArray(); + int length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + // q + buffer = rsaKey.getPrimeQ().toByteArray(); + length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + // e + buffer = rsaKey.getPublicExponent().toByteArray(); + length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + // d + buffer = rsaKey.getPrivateExponent().toByteArray(); + length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + return baos.toByteArray(); + } + + public PrivateKey decodePrivateKey(byte[] k) + { + // magic + if (k[0] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[0] + || k[1] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[1] + || k[2] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[2] + || k[3] != Registry.MAGIC_RAW_RSA_PRIVATE_KEY[3]) + { + throw new IllegalArgumentException("magic"); + } + + // version + if (k[4] != 0x01) + { + throw new IllegalArgumentException("version"); + } + int i = 5; + + int l; + byte[] buffer; + + // p + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger p = new BigInteger(1, buffer); + + // q + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger q = new BigInteger(1, buffer); + + // e + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger e = new BigInteger(1, buffer); + + // d + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger d = new BigInteger(1, buffer); + + return new GnuRSAPrivateKey(p, q, e, d); + } +} diff --git a/libjava/classpath/gnu/java/security/key/rsa/RSAKeyPairX509Codec.java b/libjava/classpath/gnu/java/security/key/rsa/RSAKeyPairX509Codec.java new file mode 100644 index 00000000000..1c362784b35 --- /dev/null +++ b/libjava/classpath/gnu/java/security/key/rsa/RSAKeyPairX509Codec.java @@ -0,0 +1,248 @@ +/* RSAKeyPairX509Codec.java -- X.509 Encoding/Decoding handler + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.key.rsa; + +import gnu.java.security.OID; +import gnu.java.security.Registry; +import gnu.java.security.der.BitString; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.der.DERWriter; +import gnu.java.security.key.IKeyPairCodec; +import gnu.java.security.util.DerUtil; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.InvalidParameterException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.ArrayList; +import java.util.logging.Logger; + +/** + * An implementation of an {@link IKeyPairCodec} that knows how to encode / + * decode X.509 ASN.1 external representation of RSA public keys. + */ +public class RSAKeyPairX509Codec + implements IKeyPairCodec +{ + private static final Logger log = Logger.getLogger(RSAKeyPairX509Codec.class.getName()); + private static final OID RSA_ALG_OID = new OID(Registry.RSA_OID_STRING); + + // implicit 0-arguments constructor + + public int getFormatID() + { + return X509_FORMAT; + } + + /** + * Returns the X.509 ASN.1 <i>SubjectPublicKeyInfo</i> representation of an + * RSA public key. The ASN.1 specification, as defined in RFC-3280, and + * RFC-2459, is as follows: + * + * <pre> + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING + * } + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL + * } + * </pre> + * <p> + * As indicated in RFC-2459: "The parameters field shall have ASN.1 type NULL + * for this algorithm identifier.". + * <p> + * The <i>subjectPublicKey</i> field, which is a BIT STRING, contains the + * DER-encoded form of the RSA public key defined as: + * + * <pre> + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER -- e + * } + * </pre> + * + * @param key the {@link PublicKey} instance to encode. MUST be an instance of + * {@link GnuRSAPublicKey}. + * @return the ASN.1 representation of the <i>SubjectPublicKeyInfo</i> in an + * X.509 certificate. + * @throw InvalidParameterException if <code>key</code> is not an instance + * of {@link GnuRSAPublicKey} or if an exception occurs during the + * marshalling process. + */ + public byte[] encodePublicKey(PublicKey key) + { + log.entering(this.getClass().getName(), "encodePublicKey()", key); + + if (! (key instanceof GnuRSAPublicKey)) + throw new InvalidParameterException("key"); + + DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, RSA_ALG_OID); + + GnuRSAPublicKey rsaKey = (GnuRSAPublicKey) key; + BigInteger n = rsaKey.getN(); + BigInteger e = rsaKey.getE(); + + DERValue derN = new DERValue(DER.INTEGER, n); + DERValue derE = new DERValue(DER.INTEGER, e); + + ArrayList algorithmID = new ArrayList(1); + algorithmID.add(derOID); + DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + algorithmID); + + ArrayList publicKey = new ArrayList(2); + publicKey.add(derN); + publicKey.add(derE); + DERValue derPublicKey = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + publicKey); + byte[] spkBytes = derPublicKey.getEncoded(); + DERValue derSPK = new DERValue(DER.BIT_STRING, new BitString(spkBytes)); + + ArrayList spki = new ArrayList(2); + spki.add(derAlgorithmID); + spki.add(derSPK); + DERValue derSPKI = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, spki); + + byte[] result; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try + { + DERWriter.write(baos, derSPKI); + result = baos.toByteArray(); + } + catch (IOException x) + { + InvalidParameterException y = new InvalidParameterException(); + y.initCause(x); + throw y; + } + + log.exiting(this.getClass().getName(), "encodePublicKey()", result); + return result; + } + + /** + * @throws InvalidParameterException ALWAYS. + */ + public byte[] encodePrivateKey(PrivateKey key) + { + throw new InvalidParameterException("Wrong format for private keys"); + } + + /** + * @param input the byte array to unmarshall into a valid RSA + * {@link PublicKey} instance. MUST NOT be null. + * @return a new instance of a {@link GnuRSAPublicKey} decoded from the + * <i>SubjectPublicKeyInfo</i> material in an X.509 certificate. + * @throw InvalidParameterException if an exception occurs during the + * unmarshalling process. + */ + public PublicKey decodePublicKey(byte[] input) + { + log.entering(this.getClass().getName(), "decodePublicKey()", input); + + if (input == null) + throw new InvalidParameterException("Input bytes MUST NOT be null"); + + BigInteger n, e; + DERReader der = new DERReader(input); + try + { + DERValue derSPKI = der.read(); + DerUtil.checkIsConstructed(derSPKI, "Wrong SubjectPublicKeyInfo field"); + + DERValue derAlgorithmID = der.read(); + DerUtil.checkIsConstructed(derAlgorithmID, "Wrong AlgorithmIdentifier field"); + + DERValue derOID = der.read(); + if (! (derOID.getValue() instanceof OID)) + throw new InvalidParameterException("Wrong Algorithm field"); + + OID algOID = (OID) derOID.getValue(); + if (! algOID.equals(RSA_ALG_OID)) + throw new InvalidParameterException("Unexpected OID: " + algOID); + + // rfc-2459 states that this field is OPTIONAL but NULL if/when present + DERValue val = der.read(); + if (val.getTag() == DER.NULL) + val = der.read(); + + if (! (val.getValue() instanceof BitString)) + throw new InvalidParameterException("Wrong SubjectPublicKey field"); + + byte[] spkBytes = ((BitString) val.getValue()).toByteArray(); + + der = new DERReader(spkBytes); + val = der.read(); + DerUtil.checkIsConstructed(derAlgorithmID, "Wrong subjectPublicKey field"); + + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong modulus field"); + n = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong publicExponent field"); + e = (BigInteger) val.getValue(); + } + catch (IOException x) + { + InvalidParameterException y = new InvalidParameterException(); + y.initCause(x); + throw y; + } + + PublicKey result = new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e); + log.exiting(this.getClass().getName(), "decodePublicKey()", result); + return result; + } + + /** + * @throws InvalidParameterException ALWAYS. + */ + public PrivateKey decodePrivateKey(byte[] input) + { + throw new InvalidParameterException("Wrong format for private keys"); + } +} diff --git a/libjava/classpath/gnu/java/security/prng/BasePRNG.java b/libjava/classpath/gnu/java/security/prng/BasePRNG.java new file mode 100644 index 00000000000..fe815d7004e --- /dev/null +++ b/libjava/classpath/gnu/java/security/prng/BasePRNG.java @@ -0,0 +1,199 @@ +/* BasePRNG.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.prng; + +import java.util.Map; + +/** + * <p>An abstract class to facilitate implementing PRNG algorithms.</p> + */ +public abstract class BasePRNG implements IRandom +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** The canonical name prefix of the PRNG algorithm. */ + protected String name; + + /** Indicate if this instance has already been initialised or not. */ + protected boolean initialised; + + /** A temporary buffer to serve random bytes. */ + protected byte[] buffer; + + /** The index into buffer of where the next byte will come from. */ + protected int ndx; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * <p>Trivial constructor for use by concrete subclasses.</p> + * + * @param name the canonical name of this instance. + */ + protected BasePRNG(String name) + { + super(); + + this.name = name; + initialised = false; + buffer = new byte[0]; + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // IRandom interface implementation ---------------------------------------- + + public String name() + { + return name; + } + + public void init(Map attributes) + { + this.setup(attributes); + + ndx = 0; + initialised = true; + } + + public byte nextByte() throws IllegalStateException, LimitReachedException + { + if (!initialised) + { + throw new IllegalStateException(); + } + return nextByteInternal(); + } + + public void nextBytes(byte[] out) throws IllegalStateException, + LimitReachedException + { + nextBytes(out, 0, out.length); + } + + public void nextBytes(byte[] out, int offset, int length) + throws IllegalStateException, LimitReachedException + { + if (!initialised) + throw new IllegalStateException("not initialized"); + + if (length == 0) + return; + + if (offset < 0 || length < 0 || offset + length > out.length) + throw new ArrayIndexOutOfBoundsException("offset=" + offset + " length=" + + length + " limit=" + + out.length); + + if (ndx >= buffer.length) + { + fillBlock(); + ndx = 0; + } + int count = 0; + while (count < length) + { + int amount = Math.min(buffer.length - ndx, length - count); + System.arraycopy(buffer, ndx, out, offset + count, amount); + count += amount; + ndx += amount; + if (ndx >= buffer.length) + { + fillBlock(); + ndx = 0; + } + } + } + + public void addRandomByte(byte b) + { + throw new UnsupportedOperationException("random state is non-modifiable"); + } + + public void addRandomBytes(byte[] buffer) + { + addRandomBytes(buffer, 0, buffer.length); + } + + public void addRandomBytes(byte[] buffer, int offset, int length) + { + throw new UnsupportedOperationException("random state is non-modifiable"); + } + + // Instance methods + // ------------------------------------------------------------------------- + + public boolean isInitialised() + { + return initialised; + } + + private byte nextByteInternal() throws LimitReachedException + { + if (ndx >= buffer.length) + { + this.fillBlock(); + ndx = 0; + } + + return buffer[ndx++]; + } + + // abstract methods to implement by subclasses ----------------------------- + + public Object clone() throws CloneNotSupportedException + { + BasePRNG result = (BasePRNG) super.clone(); + if (this.buffer != null) + result.buffer = (byte[]) this.buffer.clone(); + + return result; + } + + public abstract void setup(Map attributes); + + public abstract void fillBlock() throws LimitReachedException; +} diff --git a/libjava/classpath/gnu/java/security/prng/EntropySource.java b/libjava/classpath/gnu/java/security/prng/EntropySource.java new file mode 100644 index 00000000000..260c668f8df --- /dev/null +++ b/libjava/classpath/gnu/java/security/prng/EntropySource.java @@ -0,0 +1,62 @@ +/* EntropySource.java -- + Copyright (C) 2004, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.prng; + +/** + * A generic interface for adding random bytes to an entropy pool. + */ +public interface EntropySource +{ + + /** + * Returns the estimated quality of this source. This value should be + * between 0 and 100 (the running quality is computed as a percentage, + * 100 percent being perfect-quality). + * + * @return The quality. + */ + double quality(); + + /** + * Returns a new buffer with the next random bytes to add. + * + * @return The next random bytes. + */ + byte[] nextBytes(); +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/java/security/prng/IRandom.java b/libjava/classpath/gnu/java/security/prng/IRandom.java new file mode 100644 index 00000000000..2c89e7ad56f --- /dev/null +++ b/libjava/classpath/gnu/java/security/prng/IRandom.java @@ -0,0 +1,180 @@ +/* IRandom.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.prng; + +import java.util.Map; + +/** + * <p>The basic visible methods of any pseudo-random number generator.</p> + * + * <p>The [HAC] defines a PRNG (as implemented in this library) as follows:</p> + * + * <ul> + * <li>"5.6 Definition: A pseudorandom bit generator (PRBG) is said to pass + * the <em>next-bit test</em> if there is no polynomial-time algorithm which, + * on input of the first <code>L</code> bits of an output sequence <code>S</code>, + * can predict the <code>(L+1)</code>st bit of <code>S</code> with a + * probability significantly grater than <code>1/2</code>."</li> + * + * <li>"5.8 Definition: A PRBG that passes the <em>next-bit test</em> + * (possibly under some plausible but unproved mathematical assumption such + * as the intractability of factoring integers) is called a + * <em>cryptographically secure pseudorandom bit generator</em> (CSPRBG)."</li> + * </ul> + * + * <p><b>IMPLEMENTATION NOTE</b>: Although all the concrete classes in this + * package implement the {@link Cloneable} interface, it is important to note + * here that such an operation, for those algorithms that use an underlting + * symmetric key block cipher, <b>DOES NOT</b> clone any session key material + * that may have been used in initialising the source PRNG (the instance to be + * cloned). Instead a clone of an already initialised PRNG, that uses and + * underlying symmetric key block cipher, is another instance with a clone of + * the same cipher that operates with the <b>same block size</b> but without any + * knowledge of neither key material nor key size.</p> + * + * <p>References:</p> + * + * <ol> + * <li><a href="http://www.cacr.math.uwaterloo.ca/hac">[HAC]</a>: Handbook of + * Applied Cryptography.<br> + * CRC Press, Inc. ISBN 0-8493-8523-7, 1997<br> + * Menezes, A., van Oorschot, P. and S. Vanstone.</li> + * </ol> + */ +public interface IRandom extends Cloneable +{ + + // Constants + // ------------------------------------------------------------------------- + + // Methods + // ------------------------------------------------------------------------- + + /** + * <p>Returns the canonical name of this instance.</p> + * + * @return the canonical name of this instance. */ + String name(); + + /** + * <p>Initialises the pseudo-random number generator scheme with the + * appropriate attributes.</p> + * + * @param attributes a set of name-value pairs that describe the desired + * future instance behaviour. + * @exception IllegalArgumentException if at least one of the defined name/ + * value pairs contains invalid data. + */ + void init(Map attributes); + + /** + * <p>Returns the next 8 bits of random data generated from this instance.</p> + * + * @return the next 8 bits of random data generated from this instance. + * @exception IllegalStateException if the instance is not yet initialised. + * @exception LimitReachedException if this instance has reached its + * theoretical limit for generating non-repetitive pseudo-random data. + */ + byte nextByte() throws IllegalStateException, LimitReachedException; + + /** + * <p>Fills the designated byte array, starting from byte at index + * <code>offset</code>, for a maximum of <code>length</code> bytes with the + * output of this generator instance. + * + * @param out the placeholder to contain the generated random bytes. + * @param offset the starting index in <i>out</i> to consider. This method + * does nothing if this parameter is not within <code>0</code> and + * <code>out.length</code>. + * @param length the maximum number of required random bytes. This method + * does nothing if this parameter is less than <code>1</code>. + * @exception IllegalStateException if the instance is not yet initialised. + * @exception LimitReachedException if this instance has reached its + * theoretical limit for generating non-repetitive pseudo-random data. + */ + void nextBytes(byte[] out, int offset, int length) + throws IllegalStateException, LimitReachedException; + + /** + * <p>Supplement, or possibly replace, the random state of this PRNG with + * a random byte.</p> + * + * <p>Implementations are not required to implement this method in any + * meaningful way; this may be a no-operation, and implementations may + * throw an {@link UnsupportedOperationException}.</p> + * + * @param b The byte to add. + */ + void addRandomByte(byte b); + + /** + * <p>Supplement, or possibly replace, the random state of this PRNG with + * a sequence of new random bytes.</p> + * + * <p>Implementations are not required to implement this method in any + * meaningful way; this may be a no-operation, and implementations may + * throw an {@link UnsupportedOperationException}.</p> + * + * @param in The buffer of new random bytes to add. + */ + void addRandomBytes(byte[] in); + + /** + * <p>Supplement, or possibly replace, the random state of this PRNG with + * a sequence of new random bytes.</p> + * + * <p>Implementations are not required to implement this method in any + * meaningful way; this may be a no-operation, and implementations may + * throw an {@link UnsupportedOperationException}.</p> + * + * @param in The buffer of new random bytes to add. + * @param offset The offset from whence to begin reading random bytes. + * @param length The number of random bytes to add. + * @exception IndexOutOfBoundsException If <i>offset</i>, <i>length</i>, + * or <i>offset</i>+<i>length</i> is out of bounds. + */ + void addRandomBytes(byte[] in, int offset, int length); + + /** + * <p>Returns a clone copy of this instance.</p> + * + * @return a clone copy of this instance. + */ + Object clone() throws CloneNotSupportedException; +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/java/security/prng/LimitReachedException.java b/libjava/classpath/gnu/java/security/prng/LimitReachedException.java new file mode 100644 index 00000000000..2fd8bfa7fd1 --- /dev/null +++ b/libjava/classpath/gnu/java/security/prng/LimitReachedException.java @@ -0,0 +1,69 @@ +/* LimitReachedException.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.prng; + +/** + * A checked exception that indicates that a pseudo random number generated has + * reached its theoretical limit in generating random bytes. + */ +public class LimitReachedException extends Exception +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + public LimitReachedException() + { + super(); + } + + public LimitReachedException(String msg) + { + super(msg); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instant methods + // ------------------------------------------------------------------------- +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/java/security/prng/MDGenerator.java b/libjava/classpath/gnu/java/security/prng/MDGenerator.java new file mode 100644 index 00000000000..255647d1c5f --- /dev/null +++ b/libjava/classpath/gnu/java/security/prng/MDGenerator.java @@ -0,0 +1,135 @@ +/* MDGenerator.java -- + Copyright (C) 2001, 2002, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.prng; + +import gnu.java.security.Registry; +import gnu.java.security.hash.HashFactory; +import gnu.java.security.hash.IMessageDigest; + +import java.util.Map; + +/** + * <p>A simple pseudo-random number generator that relies on a hash algorithm, + * that (a) starts its operation by hashing a <code>seed</code>, and then (b) + * continuously re-hashing its output. If no hash algorithm name is specified + * in the {@link Map} of attributes used to initialise the instance then the + * SHA-160 algorithm is used as the underlying hash function. Also, if no + * <code>seed</code> is given, an empty octet sequence is used.</p> + */ +public class MDGenerator extends BasePRNG implements Cloneable +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** Property name of underlying hash algorithm for this generator. */ + public static final String MD_NAME = "gnu.crypto.prng.md.hash.name"; + + /** Property name of seed material. */ + public static final String SEEED = "gnu.crypto.prng.md.seed"; + + /** The underlying hash instance. */ + private IMessageDigest md; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial 0-arguments constructor. */ + public MDGenerator() + { + super(Registry.MD_PRNG); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // Implementation of abstract methods in BaseRandom ------------------------ + + public void setup(Map attributes) + { + // find out which hash to use + String underlyingMD = (String) attributes.get(MD_NAME); + if (underlyingMD == null) + { + if (md == null) + { // happy birthday + // ensure we have a reliable implementation of this hash + md = HashFactory.getInstance(Registry.SHA160_HASH); + } + else + { // a clone. reset it for reuse + md.reset(); + } + } + else + { // ensure we have a reliable implementation of this hash + md = HashFactory.getInstance(underlyingMD); + } + + // get the seeed + byte[] seed = (byte[]) attributes.get(SEEED); + if (seed == null) + { + seed = new byte[0]; + } + + md.update(seed, 0, seed.length); + } + + public void fillBlock() throws LimitReachedException + { + IMessageDigest mdc = (IMessageDigest) md.clone(); + buffer = mdc.digest(); + md.update(buffer, 0, buffer.length); + } + + // Cloneable interface implementation --------------------------------------- + + public Object clone() throws CloneNotSupportedException + { + MDGenerator result = (MDGenerator) super.clone(); + if (this.md != null) + result.md = (IMessageDigest) this.md.clone(); + + return result; + } +} diff --git a/libjava/classpath/gnu/java/security/prng/PRNGFactory.java b/libjava/classpath/gnu/java/security/prng/PRNGFactory.java new file mode 100644 index 00000000000..8b5141456e6 --- /dev/null +++ b/libjava/classpath/gnu/java/security/prng/PRNGFactory.java @@ -0,0 +1,109 @@ +/* PRNGFactory.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.prng; + +import gnu.java.security.Registry; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * <p>A Factory to instantiate pseudo random number generators.</p> + */ +public class PRNGFactory implements Registry +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial constructor to enforce <i>Singleton</i> pattern. */ + protected PRNGFactory() + { + } + + // Class methods + // ------------------------------------------------------------------------- + + /** + * <p>Returns an instance of a padding algorithm given its name.</p> + * + * @param prng the case-insensitive name of the PRNG. + * @return an instance of the pseudo-random number generator. + * @exception InternalError if the implementation does not pass its self- + * test. + */ + public static final IRandom getInstance(String prng) + { + if (prng == null) + { + return null; + } + + prng = prng.trim(); + IRandom result = null; + if (prng.equalsIgnoreCase(MD_PRNG)) + { + result = new MDGenerator(); + } + + return result; + } + + /** + * <p>Returns a {@link Set} of names of padding algorithms supported by this + * <i>Factory</i>.</p> + * + * @return a {@link Set} of pseudo-random number generator algorithm names + * (Strings). + */ + public static final Set getNames() + { + HashSet hs = new HashSet(); + hs.add(MD_PRNG); + return Collections.unmodifiableSet(hs); + } + + // Instance methods + // ------------------------------------------------------------------------- +} diff --git a/libjava/classpath/gnu/java/security/prng/RandomEvent.java b/libjava/classpath/gnu/java/security/prng/RandomEvent.java new file mode 100644 index 00000000000..c07062125dc --- /dev/null +++ b/libjava/classpath/gnu/java/security/prng/RandomEvent.java @@ -0,0 +1,82 @@ +/* RandomEvent.java -- an event with random data. + Copyright (C) 2004, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.prng; + +import java.util.EventObject; + +/** + * An interface for entropy accumulators that will be notified of random + * events. + */ +public class RandomEvent extends EventObject +{ + + private final byte sourceNumber; + + private final byte poolNumber; + + private final byte[] data; + + public RandomEvent(Object source, byte sourceNumber, byte poolNumber, + byte[] data) + { + super(source); + this.sourceNumber = sourceNumber; + this.poolNumber = poolNumber; + if (data.length == 0 || data.length > 32) + throw new IllegalArgumentException( + "random events take between 1 and 32 bytes of data"); + this.data = (byte[]) data.clone(); + } + + public byte getSourceNumber() + { + return sourceNumber; + } + + public byte getPoolNumber() + { + return poolNumber; + } + + public byte[] getData() + { + return data; + } +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/java/security/prng/RandomEventListener.java b/libjava/classpath/gnu/java/security/prng/RandomEventListener.java new file mode 100644 index 00000000000..1dc14619fe9 --- /dev/null +++ b/libjava/classpath/gnu/java/security/prng/RandomEventListener.java @@ -0,0 +1,50 @@ +/* RandomEventListener.java -- + Copyright (C) 2004, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.prng; + +import java.util.EventListener; + +/** + * An interface for entropy accumulators that will be notified of random + * events. + */ +public interface RandomEventListener extends EventListener +{ + void addRandomEvent(RandomEvent event); +}
\ No newline at end of file diff --git a/libjava/classpath/gnu/java/security/provider/DSAKeyFactory.java b/libjava/classpath/gnu/java/security/provider/DSAKeyFactory.java deleted file mode 100644 index 7e154e27473..00000000000 --- a/libjava/classpath/gnu/java/security/provider/DSAKeyFactory.java +++ /dev/null @@ -1,134 +0,0 @@ -/* DSAKeyFactory.java -- DSA key factory. - Copyright (C) 2003 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.KeyFactorySpi; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.interfaces.DSAPrivateKey; -import java.security.interfaces.DSAPublicKey; -import java.security.spec.DSAPrivateKeySpec; -import java.security.spec.DSAPublicKeySpec; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.KeySpec; - -/** - * DSA key factory. - * - * @author Casey Marshall (rsdio@metastatic.org) - */ -public class DSAKeyFactory extends KeyFactorySpi -{ - - // Constructor. - // ------------------------------------------------------------------------ - - public DSAKeyFactory() - { - super(); - } - - // Instance methods. - // ------------------------------------------------------------------------ - - protected PrivateKey engineGeneratePrivate(KeySpec keySpec) - throws InvalidKeySpecException - { - if (!(keySpec instanceof DSAPrivateKeySpec)) - throw new InvalidKeySpecException(); - return new GnuDSAPrivateKey( - ((DSAPrivateKeySpec) keySpec).getX(), - ((DSAPrivateKeySpec) keySpec).getP(), - ((DSAPrivateKeySpec) keySpec).getQ(), - ((DSAPrivateKeySpec) keySpec).getG()); - } - - protected PublicKey engineGeneratePublic(KeySpec keySpec) - throws InvalidKeySpecException - { - if (!(keySpec instanceof DSAPublicKeySpec)) - throw new InvalidKeySpecException(); - return new GnuDSAPublicKey( - ((DSAPublicKeySpec) keySpec).getY(), - ((DSAPublicKeySpec) keySpec).getP(), - ((DSAPublicKeySpec) keySpec).getQ(), - ((DSAPublicKeySpec) keySpec).getG()); - } - - protected KeySpec engineGetKeySpec(Key key, Class keySpec) - throws InvalidKeySpecException - { - if ((key instanceof DSAPublicKey) && - keySpec.isAssignableFrom(DSAPublicKeySpec.class)) - { - return new DSAPublicKeySpec(((DSAPublicKey) key).getY(), - ((DSAPublicKey) key).getParams().getP(), - ((DSAPublicKey) key).getParams().getQ(), - ((DSAPublicKey) key).getParams().getG()); - } - if ((key instanceof DSAPrivateKey) && - keySpec.isAssignableFrom(DSAPrivateKeySpec.class)) - { - return new DSAPrivateKeySpec(((DSAPrivateKey) key).getX(), - ((DSAPrivateKey) key).getParams().getP(), - ((DSAPrivateKey) key).getParams().getQ(), - ((DSAPrivateKey) key).getParams().getG()); - } - throw new InvalidKeySpecException(); - } - - protected Key engineTranslateKey(Key key) throws InvalidKeyException - { - if ((key instanceof GnuDSAPublicKey) || (key instanceof GnuDSAPrivateKey)) - return key; - if (key instanceof DSAPublicKey) - return new GnuDSAPublicKey(((DSAPublicKey) key).getY(), - ((DSAPublicKey) key).getParams().getP(), - ((DSAPublicKey) key).getParams().getQ(), - ((DSAPublicKey) key).getParams().getG()); - if (key instanceof DSAPrivateKey) - return new GnuDSAPrivateKey(((DSAPrivateKey) key).getX(), - ((DSAPrivateKey) key).getParams().getP(), - ((DSAPrivateKey) key).getParams().getQ(), - ((DSAPrivateKey) key).getParams().getG()); - throw new InvalidKeyException(); - } -} diff --git a/libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java b/libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java deleted file mode 100644 index ddd1800a717..00000000000 --- a/libjava/classpath/gnu/java/security/provider/DSAKeyPairGenerator.java +++ /dev/null @@ -1,194 +0,0 @@ -/* GnuDSAKeyPairGenerator.java --- Gnu DSA Key Pair Generator - Copyright (C) 1999, 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import java.math.BigInteger; -import java.security.AlgorithmParameterGenerator; -import java.security.AlgorithmParameters; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidParameterException; -import java.security.KeyPair; -import java.security.KeyPairGeneratorSpi; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.interfaces.DSAParams; -import java.security.spec.AlgorithmParameterSpec; -import java.security.spec.DSAParameterSpec; -import java.security.spec.InvalidParameterSpecException; -import java.util.Random; - -public class DSAKeyPairGenerator extends KeyPairGeneratorSpi - implements java.security.interfaces.DSAKeyPairGenerator -{ -int keysize; -SecureRandom random; -private BigInteger q = null; // the small prime -private BigInteger p = null; // the big prime -private BigInteger g = null; - -public DSAKeyPairGenerator() -{ - keysize = 1024; - getDefaults (); -} - -public void initialize(int keysize, SecureRandom random) -{ - initialize (keysize, false, random); -} - -public void initialize(AlgorithmParameterSpec params, - SecureRandom random) - throws InvalidAlgorithmParameterException -{ - if( !( params instanceof DSAParameterSpec ) ) - throw new InvalidAlgorithmParameterException("Must be DSAParameterSpec"); - - try - { - initialize ((DSAParams) params, random); - } - catch (InvalidParameterException ipe) - { - InvalidAlgorithmParameterException iape = - new InvalidAlgorithmParameterException(); - iape.initCause (ipe); - throw iape; - } -} - -public void initialize (DSAParams params, SecureRandom random) -{ - DSAParameterSpec dsaparameterspec = (DSAParameterSpec)params; - if (dsaparameterspec.getP() == null - || dsaparameterspec.getQ() == null - || dsaparameterspec.getG() == null) - { - throw new InvalidParameterException ("none of p, q, or g may be null"); - } - p = dsaparameterspec.getP(); - q = dsaparameterspec.getQ(); - g = dsaparameterspec.getG(); - this.random = random; -} - -public void initialize(int modlen, boolean genParams, SecureRandom random) - throws InvalidParameterException -{ - if( ((modlen % 64) != 0) || (modlen < 512) || (modlen > 1024) ) - throw new InvalidParameterException(); - - this.keysize = modlen; - this.random = random; - if (this.random == null) - { - this.random = new SecureRandom (); - } - if (genParams) - { - try - { - AlgorithmParameterGenerator apgDSA = AlgorithmParameterGenerator.getInstance("DSA"); - apgDSA.init (modlen, random); - AlgorithmParameters apDSA = apgDSA.generateParameters(); - DSAParameterSpec dsaparameterspec = (DSAParameterSpec)apDSA.getParameterSpec( DSAParameterSpec.class ); - p = dsaparameterspec.getP(); - q = dsaparameterspec.getQ(); - g = dsaparameterspec.getG(); - } - catch (NoSuchAlgorithmException nsae) - { - InvalidParameterException ipe = - new InvalidParameterException ("can't generate DSA parameters"); - ipe.initCause (nsae); - throw ipe; - } - catch (InvalidParameterSpecException ipse) - { - InvalidParameterException ipe = - new InvalidParameterException ("can't generate DSA parameters"); - ipe.initCause (ipse); - throw ipe; - } - } - else if (!getDefaults ()) - { - throw new InvalidParameterException ("unsupported key size: " + modlen); - } -} - -public KeyPair generateKeyPair() -{ - if (random == null) - { - random = new SecureRandom (); - } - - BigInteger x = new BigInteger( 159, random ); - - BigInteger y = g.modPow( x, p ); - - return new KeyPair( new GnuDSAPublicKey(y,p,q,g), new GnuDSAPrivateKey(x,p,q,g)); - //return new KeyPair( public, private ); -} - -//These constants are Sun's Constants copied from the -//Cryptography Specification -private boolean getDefaults() -{ - if( keysize == 512) { - p = new BigInteger("fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e17", 16); - q = new BigInteger("962eddcc369cba8ebb260ee6b6a126d9346e38c5", 16); - g = new BigInteger("678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4", 16); - return true; - } else if( keysize == 768) { - p = new BigInteger("e9e642599d355f37c97ffd3567120b8e25c9cd43e927b3a9670fbec5d890141922d2c3b3ad2480093799869d1e846aab49fab0ad26d2ce6a22219d470bce7d777d4a21fbe9c270b57f607002f3cef8393694cf45ee3688c11a8c56ab127a3daf", 16); - q = new BigInteger("9cdbd84c9f1ac2f38d0f80f42ab952e7338bf511", 16); - g = new BigInteger("30470ad5a005fb14ce2d9dcd87e38bc7d1b1c5facbaecbe95f190aa7a31d23c4dbbcbe06174544401a5b2c020965d8c2bd2171d3668445771f74ba084d2029d83c1c158547f3a9f1a2715be23d51ae4d3e5a1f6a7064f316933a346d3f529252", 16); - return true; - } else if( keysize == 1024) { - p = new BigInteger("fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7", 16); - q = new BigInteger("9760508f15230bccb292b982a2eb840bf0581cf5", 16); - g = new BigInteger("f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a", 16); - return true; - } - return false; -} - -} diff --git a/libjava/classpath/gnu/java/security/provider/DSAParameters.java b/libjava/classpath/gnu/java/security/provider/DSAParameters.java deleted file mode 100644 index 77d648956ee..00000000000 --- a/libjava/classpath/gnu/java/security/provider/DSAParameters.java +++ /dev/null @@ -1,150 +0,0 @@ -/* DSAParameters.java --- DSA Parameters Implementation - Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import gnu.java.io.ASN1ParsingException; -import gnu.java.security.der.DER; -import gnu.java.security.der.DERReader; -import gnu.java.security.der.DERValue; -import gnu.java.security.der.DERWriter; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.security.AlgorithmParametersSpi; -import java.security.spec.AlgorithmParameterSpec; -import java.security.spec.DSAParameterSpec; -import java.security.spec.InvalidParameterSpecException; -import java.util.ArrayList; - -/* - ASN.1 Encoding for DSA from rfc2459 - - id-dsa ID ::= { iso(1) member-body(2) us(840) x9-57(10040) - x9cm(4) 1 } - - Dss-Parms ::= SEQUENCE { - p INTEGER, - q INTEGER, - g INTEGER } - -*/ -public class DSAParameters extends AlgorithmParametersSpi -{ -private BigInteger q; // the small prime -private BigInteger p; // the big prime -private BigInteger g; - - -public void engineInit(AlgorithmParameterSpec paramSpec) - throws InvalidParameterSpecException -{ - if( paramSpec instanceof DSAParameterSpec ) { - DSAParameterSpec dsaParamSpec = (DSAParameterSpec)paramSpec; - p = dsaParamSpec.getP(); - q = dsaParamSpec.getQ(); - g = dsaParamSpec.getG(); - } - else - throw new InvalidParameterSpecException("Only accepts DSAParameterSpec"); -} - -public void engineInit(byte[] params) - throws IOException -{ - DERReader in = new DERReader(params); - DERValue val = in.read(); - if (val.getValue() != DER.CONSTRUCTED_VALUE) - throw new ASN1ParsingException("badly formed parameters"); - try - { - p = (BigInteger) in.read().getValue(); - q = (BigInteger) in.read().getValue(); - g = (BigInteger) in.read().getValue(); - } - catch (Exception x) - { - throw new ASN1ParsingException("badly formed parameters"); - } -} - -public void engineInit(byte[] params, String format) - throws IOException -{ - if( !format.equals("ASN.1") ) - throw new IOException("Invalid Format: Only accepts ASN.1"); - engineInit( params ); -} - -public AlgorithmParameterSpec engineGetParameterSpec(Class paramSpec) - throws InvalidParameterSpecException -{ - if( paramSpec.isAssignableFrom(DSAParameterSpec.class) ) - return new DSAParameterSpec(p, q, g); - else - throw new InvalidParameterSpecException("Only accepts DSAParameterSpec"); -} - -public byte[] engineGetEncoded() - throws IOException -{ - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - ArrayList seq = new ArrayList(3); - seq.add(new DERValue(DER.INTEGER, p)); - seq.add(new DERValue(DER.INTEGER, q)); - seq.add(new DERValue(DER.INTEGER, g)); - DERWriter.write(bout, new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, seq)); - return bout.toByteArray(); -} - - -public byte[] engineGetEncoded(String format) - throws IOException -{ - if( !format.equals("ASN.1") ) - throw new IOException("Invalid Format: Only accepts ASN.1"); - return engineGetEncoded(); -} - -public String engineToString() -{ - return ("q: " + q + " p: " + p + " g: " + g); -} - -} diff --git a/libjava/classpath/gnu/java/security/provider/DSASignature.java b/libjava/classpath/gnu/java/security/provider/DSASignature.java deleted file mode 100644 index 1d3875d28e3..00000000000 --- a/libjava/classpath/gnu/java/security/provider/DSASignature.java +++ /dev/null @@ -1,251 +0,0 @@ -/* DSASignature.java -- - Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import gnu.java.security.der.DER; -import gnu.java.security.der.DERReader; -import gnu.java.security.der.DERValue; -import gnu.java.security.der.DERWriter; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.InvalidParameterException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.SignatureException; -import java.security.SignatureSpi; -import java.security.interfaces.DSAPrivateKey; -import java.security.interfaces.DSAPublicKey; -import java.security.spec.AlgorithmParameterSpec; -import java.util.ArrayList; -import java.util.Random; - -public class DSASignature extends SignatureSpi -{ - private DSAPublicKey publicKey; - private DSAPrivateKey privateKey; - private final MessageDigest digest; - private final SecureRandom random; - - public DSASignature() throws NoSuchAlgorithmException - { - random = new SecureRandom(); - digest = MessageDigest.getInstance ("SHA1"); - } - - private void init() - { - digest.reset(); - } - - public void engineInitVerify (PublicKey publicKey) - throws InvalidKeyException - { - if (publicKey instanceof DSAPublicKey) - this.publicKey = (DSAPublicKey) publicKey; - else - throw new InvalidKeyException(); - init(); - } - - public void engineInitSign (PrivateKey privateKey) - throws InvalidKeyException - { - if (privateKey instanceof DSAPrivateKey) - this.privateKey = (DSAPrivateKey) privateKey; - else - throw new InvalidKeyException ("not a DSA private key"); - - init(); - } - - public void engineInitSign (PrivateKey privateKey, - SecureRandom random) - throws InvalidKeyException - { - if (privateKey instanceof DSAPrivateKey) - this.privateKey = (DSAPrivateKey) privateKey; - else - throw new InvalidKeyException ("not a DSA private key"); - - appRandom = random; - init(); - } - - public void engineUpdate(byte b) - throws SignatureException - { - digest.update (b); - } - - public void engineUpdate (byte[] b, int off, int len) - throws SignatureException - { - digest.update (b, off, len); - } - - public byte[] engineSign() throws SignatureException - { - if (privateKey == null) - throw new SignatureException ("not initialized for signing"); - - try - { - BigInteger g = privateKey.getParams().getG(); - BigInteger p = privateKey.getParams().getP(); - BigInteger q = privateKey.getParams().getQ(); - - BigInteger x = privateKey.getX(); - - BigInteger k = new BigInteger (159, appRandom != null ? appRandom : random); - - BigInteger r = g.modPow(k, p); - r = r.mod(q); - - byte bytes[] = digest.digest(); - BigInteger sha = new BigInteger (1, bytes); - - BigInteger s = sha.add (x.multiply (r)); - s = s.multiply (k.modInverse(q)).mod (q); - - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - ArrayList seq = new ArrayList (2); - seq.add(0, new DERValue (DER.INTEGER, r)); - seq.add(1, new DERValue (DER.INTEGER, s)); - DERWriter.write (bout, new DERValue (DER.CONSTRUCTED | DER.SEQUENCE, seq)); - return bout.toByteArray(); - } - catch (IOException ioe) - { - SignatureException se = new SignatureException(); - se.initCause (ioe); - throw se; - } - catch (ArithmeticException ae) - { - SignatureException se = new SignatureException(); - se.initCause (ae); - throw se; - } - } - - public int engineSign (byte[] outbuf, int offset, int len) - throws SignatureException - { - byte tmp[] = engineSign(); - if (tmp.length > len) - throw new SignatureException ("output buffer too short"); - System.arraycopy (tmp, 0, outbuf, offset, tmp.length); - return tmp.length; - } - - public boolean engineVerify (byte[] sigBytes) - throws SignatureException - { - // Decode sigBytes from ASN.1 DER encoding - try - { - DERReader in = new DERReader (sigBytes); - DERValue val = in.read(); - if (!val.isConstructed()) - throw new SignatureException ("badly formed signature"); - BigInteger r = (BigInteger) in.read().getValue(); - BigInteger s = (BigInteger) in.read().getValue(); - - BigInteger g = publicKey.getParams().getG(); - BigInteger p = publicKey.getParams().getP(); - BigInteger q = publicKey.getParams().getQ(); - - BigInteger y = publicKey.getY(); - - BigInteger w = s.modInverse (q); - - byte bytes[] = digest.digest(); - BigInteger sha = new BigInteger (1, bytes); - - BigInteger u1 = w.multiply (sha).mod ( q ); - - BigInteger u2 = r.multiply (w).mod(q); - - BigInteger v = g.modPow (u1, p).multiply (y.modPow (u2, p)).mod (p).mod (q); - - if (v.equals (r)) - return true; - else - return false; - } - catch (IOException ioe) - { - SignatureException se = new SignatureException ("badly formed signature"); - se.initCause (ioe); - throw se; - } - } - - public void engineSetParameter (String param, - Object value) - throws InvalidParameterException - { - throw new InvalidParameterException(); - } - - public void engineSetParameter (AlgorithmParameterSpec params) - throws InvalidAlgorithmParameterException - { - throw new InvalidParameterException(); - - } - - public Object engineGetParameter (String param) - throws InvalidParameterException - { - throw new InvalidParameterException(); - } - - public Object clone() throws CloneNotSupportedException - { - return super.clone(); - } -} diff --git a/libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyFactoryImpl.java b/libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyFactoryImpl.java deleted file mode 100644 index 591fc688cc0..00000000000 --- a/libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyFactoryImpl.java +++ /dev/null @@ -1,123 +0,0 @@ -/* DiffieHellmanKeyFactoryImpl.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import gnu.javax.crypto.GnuDHPrivateKey; - -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.KeyFactorySpi; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.KeySpec; - -import javax.crypto.spec.DHParameterSpec; -import javax.crypto.spec.DHPrivateKeySpec; -import javax.crypto.spec.DHPublicKeySpec; - -import javax.crypto.interfaces.DHPrivateKey; -import javax.crypto.interfaces.DHPublicKey; - -public class DiffieHellmanKeyFactoryImpl extends KeyFactorySpi -{ - protected PrivateKey engineGeneratePrivate (final KeySpec spec) - throws InvalidKeySpecException - { - if (spec instanceof DHPrivateKeySpec) - { - DHPrivateKeySpec dh = (DHPrivateKeySpec) spec; - return new GnuDHPrivateKey (dh.getX (), - new DHParameterSpec (dh.getP (), dh.getG ())); - } - throw new InvalidKeySpecException (); - } - - protected PublicKey engineGeneratePublic (final KeySpec spec) - throws InvalidKeySpecException - { - if (spec instanceof DHPublicKeySpec) - { - DHPublicKeySpec dh = (DHPublicKeySpec) spec; - return new GnuDHPublicKey (new DHParameterSpec (dh.getP (), dh.getG ()), - dh.getY(), null); - } - throw new InvalidKeySpecException (); - } - - protected KeySpec engineGetKeySpec (final Key key, final Class specClass) - throws InvalidKeySpecException - { - if (key instanceof DHPrivateKey) - { - if (DHPrivateKeySpec.class.isAssignableFrom (specClass)) - { - DHParameterSpec params = ((DHPrivateKey) key).getParams (); - return new DHPrivateKeySpec (((DHPrivateKey) key).getX (), - params.getP (), params.getG ()); - } - } - if (key instanceof DHPublicKey) - { - if (DHPublicKeySpec.class.isAssignableFrom (specClass)) - { - DHParameterSpec params = ((DHPublicKey) key).getParams (); - return new DHPublicKeySpec (((DHPublicKey) key).getY (), - params.getP (), params.getG ()); - } - } - throw new InvalidKeySpecException (); - } - - protected Key engineTranslateKey (final Key key) - throws InvalidKeyException - { - if (key instanceof DHPrivateKey) - { - return new GnuDHPrivateKey (((DHPrivateKey) key).getX (), - ((DHPrivateKey) key).getParams ()); - } - if (key instanceof DHPublicKey) - { - return new GnuDHPublicKey (((DHPublicKey) key).getParams (), - ((DHPublicKey) key).getY (), null); - } - throw new InvalidKeyException (); - } -} diff --git a/libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyPairGeneratorImpl.java b/libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyPairGeneratorImpl.java deleted file mode 100644 index 1b68d274fa8..00000000000 --- a/libjava/classpath/gnu/java/security/provider/DiffieHellmanKeyPairGeneratorImpl.java +++ /dev/null @@ -1,86 +0,0 @@ -/* DiffieHellmanKeyPairGeneratorImpl.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import gnu.javax.crypto.GnuDHPrivateKey; - -import java.math.BigInteger; - -import java.security.KeyPair; -import java.security.KeyPairGeneratorSpi; -import java.security.SecureRandom; -import java.security.spec.AlgorithmParameterSpec; - -import javax.crypto.spec.DHParameterSpec; - -public class DiffieHellmanKeyPairGeneratorImpl extends KeyPairGeneratorSpi -{ - private SecureRandom random; - private DHParameterSpec params; - - public KeyPair generateKeyPair () - { - if (params == null || random == null) - throw new IllegalStateException ("not initialized"); - byte[] buf = new byte[(params.getP ().bitLength() >>> 3)]; - random.nextBytes (buf); - BigInteger x = new BigInteger (1, buf); - BigInteger y = params.getG ().modPow (x, params.getP ()); - GnuDHPublicKey pub = new GnuDHPublicKey (params, y, null); - GnuDHPrivateKey priv = new GnuDHPrivateKey (x, params); - - return new KeyPair (pub, priv); - } - - public void initialize (final int keysize, final SecureRandom random) - { - throw new UnsupportedOperationException ("key generation without parameters not supported"); - } - - public void initialize (final AlgorithmParameterSpec params, - final SecureRandom random) - { - if (!(params instanceof DHParameterSpec)) - throw new IllegalArgumentException ("expecting Diffie-Hellman parameters"); - this.params = (DHParameterSpec) params; - this.random = random; - if (this.random == null) - this.random = new SecureRandom (); - } -} diff --git a/libjava/classpath/gnu/java/security/provider/EncodedKeyFactory.java b/libjava/classpath/gnu/java/security/provider/EncodedKeyFactory.java deleted file mode 100644 index 2bf0fff809e..00000000000 --- a/libjava/classpath/gnu/java/security/provider/EncodedKeyFactory.java +++ /dev/null @@ -1,303 +0,0 @@ -/* EncodedKeyFactory.java -- encoded key factory. - Copyright (C) 2004 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import gnu.java.security.OID; -import gnu.java.security.der.BitString; -import gnu.java.security.der.DERReader; -import gnu.java.security.der.DERValue; - -import java.io.IOException; -import java.math.BigInteger; -import java.security.AlgorithmParameters; -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.KeyFactorySpi; -import java.security.NoSuchAlgorithmException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.spec.DSAParameterSpec; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.InvalidParameterSpecException; -import java.security.spec.KeySpec; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.RSAPrivateCrtKeySpec; -import java.security.spec.RSAPublicKeySpec; -import java.security.spec.X509EncodedKeySpec; - -import javax.crypto.spec.DHParameterSpec; - -/** - * A factory for keys encoded in either the X.509 format (for public - * keys) or the PKCS#8 format (for private keys). - * - * @author Casey Marshall (rsdio@metastatic.org) - */ -public class EncodedKeyFactory extends KeyFactorySpi -{ - - // Constants. - // ------------------------------------------------------------------------ - - private static final OID ID_DSA = new OID("1.2.840.10040.4.1"); - private static final OID ID_RSA = new OID("1.2.840.113549.1.1.1"); - private static final OID ID_DH = new OID("1.2.840.10046.2.1"); - - // Instance methods. - // ------------------------------------------------------------------------ - - public PublicKey engineGeneratePublic(KeySpec spec) - throws InvalidKeySpecException - { - if (!(spec instanceof X509EncodedKeySpec)) - throw new InvalidKeySpecException("only supports X.509 key specs"); - DERReader der = new DERReader(((X509EncodedKeySpec) spec).getEncoded()); - try - { - DERValue spki = der.read(); - if (!spki.isConstructed()) - { - throw new InvalidKeySpecException("malformed encoded key"); - } - DERValue alg = der.read(); - if (!alg.isConstructed()) - { - throw new InvalidKeySpecException("malformed encoded key"); - } - DERValue val = der.read(); - if (!(val.getValue() instanceof OID)) - { - throw new InvalidKeySpecException("malformed encoded key"); - } - OID algId = (OID) val.getValue(); - byte[] algParams = null; - if (alg.getLength() > val.getEncodedLength()) - { - val = der.read(); - algParams = val.getEncoded(); - if (val.isConstructed()) - der.skip(val.getLength()); - } - val = der.read(); - if (!(val.getValue() instanceof BitString)) - { - throw new InvalidKeySpecException("malformed encoded key"); - } - byte[] publicKey = ((BitString) val.getValue()).toByteArray(); - if (algId.equals(ID_DSA)) - { - BigInteger p = null, g = null, q = null, Y; - if (algParams != null) - { - DERReader dsaParams = new DERReader(algParams); - val = dsaParams.read(); - if (!val.isConstructed()) - throw new InvalidKeySpecException("malformed DSA parameters"); - val = dsaParams.read(); - if (!(val.getValue() instanceof BigInteger)) - throw new InvalidKeySpecException("malformed DSA parameters"); - p = (BigInteger) val.getValue(); - val = dsaParams.read(); - if (!(val.getValue() instanceof BigInteger)) - throw new InvalidKeySpecException("malformed DSA parameters"); - q = (BigInteger) val.getValue(); - val = dsaParams.read(); - if (!(val.getValue() instanceof BigInteger)) - throw new InvalidKeySpecException("malformed DSA parameters"); - g = (BigInteger) val.getValue(); - } - DERReader dsaPub = new DERReader(publicKey); - val = dsaPub.read(); - if (!(val.getValue() instanceof BigInteger)) - throw new InvalidKeySpecException("malformed DSA parameters"); - Y = (BigInteger) val.getValue(); - return new GnuDSAPublicKey(Y, p, q, g); - } - else if (algId.equals(ID_RSA)) - { - DERReader rsaParams = new DERReader(publicKey); - if (!rsaParams.read().isConstructed()) - { - throw new InvalidKeySpecException("malformed encoded key"); - } - return new GnuRSAPublicKey(new RSAPublicKeySpec( - (BigInteger) rsaParams.read().getValue(), - (BigInteger) rsaParams.read().getValue())); - } - else if (algId.equals(ID_DH)) - { - if (algParams == null) - throw new InvalidKeySpecException("missing DH parameters"); - DERReader dhParams = new DERReader(algParams); - val = dhParams.read(); - BigInteger p, g, q, Y; - if (!val.isConstructed()) - throw new InvalidKeySpecException("malformed DH parameters"); - val = dhParams.read(); - if (!(val.getValue() instanceof BigInteger)) - throw new InvalidKeySpecException("malformed DH parameters"); - p = (BigInteger) val.getValue(); - val = dhParams.read(); - if (!(val.getValue() instanceof BigInteger)) - throw new InvalidKeySpecException("malformed DH parameters"); - g = (BigInteger) val.getValue(); - val = dhParams.read(); - if (!(val.getValue() instanceof BigInteger)) - throw new InvalidKeySpecException("malformed DH parameters"); - q = (BigInteger) val.getValue(); - DERReader dhPub = new DERReader(publicKey); - val = dhPub.read(); - if (!(val.getValue() instanceof BigInteger)) - throw new InvalidKeySpecException("malformed DH parameters"); - Y = (BigInteger) val.getValue(); - return (PublicKey) new GnuDHPublicKey(new DHParameterSpec(p, g), Y, q); - } - else - throw new InvalidKeySpecException("unknown algorithm: " + algId); - } - catch (IOException ioe) - { - throw new InvalidKeySpecException(ioe.getMessage()); - } - } - - public PrivateKey engineGeneratePrivate(KeySpec spec) - throws InvalidKeySpecException - { - if (!(spec instanceof PKCS8EncodedKeySpec)) - { - throw new InvalidKeySpecException("only supports PKCS8 key specs"); - } - DERReader der = new DERReader(((PKCS8EncodedKeySpec) spec).getEncoded()); - try - { - DERValue pki = der.read(); - if (!pki.isConstructed()) - { - throw new InvalidKeySpecException("malformed encoded key"); - } - DERValue val = der.read(); - if (!(val.getValue() instanceof BigInteger)) - { - throw new InvalidKeySpecException("malformed encoded key"); - } - DERValue alg = der.read(); - if (!alg.isConstructed()) - { - throw new InvalidKeySpecException("malformed encoded key"); - } - val = der.read(); - if (!(val.getValue() instanceof OID)) - { - throw new InvalidKeySpecException("malformed encoded key"); - } - OID algId = (OID) val.getValue(); - byte[] algParams = null; - if (alg.getLength() > val.getEncodedLength()) - { - val = der.read(); - algParams = val.getEncoded(); - if (val.isConstructed()) - der.skip(val.getLength()); - } - byte[] privateKey = (byte[]) der.read().getValue(); - if (algId.equals(ID_DSA)) - { - if (algParams == null) - { - throw new InvalidKeySpecException("missing DSA parameters"); - } - AlgorithmParameters params = AlgorithmParameters.getInstance("DSA"); - params.init(algParams); - DSAParameterSpec dsaSpec = (DSAParameterSpec) - params.getParameterSpec(DSAParameterSpec.class); - DERReader dsaPriv = new DERReader(privateKey); - return new GnuDSAPrivateKey((BigInteger) dsaPriv.read().getValue(), - dsaSpec.getP(), dsaSpec.getQ(), dsaSpec.getG()); - } - else if (algId.equals(ID_RSA)) - { - DERReader rsaParams = new DERReader(privateKey); - if (!rsaParams.read().isConstructed()) - throw new InvalidKeySpecException("malformed encoded key"); - return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec( - (BigInteger) rsaParams.read().getValue(), // n - (BigInteger) rsaParams.read().getValue(), // e - (BigInteger) rsaParams.read().getValue(), // d - (BigInteger) rsaParams.read().getValue(), // p - (BigInteger) rsaParams.read().getValue(), // q - (BigInteger) rsaParams.read().getValue(), // d mod (p - 1) - (BigInteger) rsaParams.read().getValue(), // d mod (q - 1) - (BigInteger) rsaParams.read().getValue())); // (inv q) mod p - } - else - throw new InvalidKeySpecException("unknown algorithm: " + algId); - } - catch (InvalidParameterSpecException iapse) - { - throw new InvalidKeySpecException(iapse.getMessage()); - } - catch (NoSuchAlgorithmException nsae) - { - throw new InvalidKeySpecException(nsae.getMessage()); - } - catch (IOException ioe) - { - throw new InvalidKeySpecException(ioe.getMessage()); - } - } - - public KeySpec engineGetKeySpec(Key key, Class speClass) - throws InvalidKeySpecException - { - if ((key instanceof PrivateKey) && key.getFormat().equals("PKCS#8") - && speClass.isAssignableFrom(PKCS8EncodedKeySpec.class)) - return new PKCS8EncodedKeySpec(key.getEncoded()); - else if ((key instanceof PublicKey) && key.getFormat().equals("X.509") - && speClass.isAssignableFrom(X509EncodedKeySpec.class)) - return new X509EncodedKeySpec(key.getEncoded()); - else - throw new InvalidKeySpecException(); - } - - public Key engineTranslateKey(Key key) throws InvalidKeyException - { - throw new InvalidKeyException("translating keys not supported"); - } -} diff --git a/libjava/classpath/gnu/java/security/provider/Gnu.java b/libjava/classpath/gnu/java/security/provider/Gnu.java index e553bbcbd8a..06135664427 100644 --- a/libjava/classpath/gnu/java/security/provider/Gnu.java +++ b/libjava/classpath/gnu/java/security/provider/Gnu.java @@ -57,105 +57,209 @@ public final class Gnu extends Provider // we automatically get all the implementation classes. // Signature - put("Signature.SHA1withDSA", - gnu.java.security.provider.DSASignature.class.getName()); - - put("Alg.Alias.Signature.DSS", "SHA1withDSA"); - put("Alg.Alias.Signature.DSA", "SHA1withDSA"); - put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA"); - put("Alg.Alias.Signature.DSAwithSHA", "SHA1withDSA"); - put("Alg.Alias.Signature.DSAwithSHA1", "SHA1withDSA"); - put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA"); - put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA"); - put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA"); - put("Alg.Alias.Signature.OID.1.2.840.10040.4.3", "SHA1withDSA"); - put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA1withDSA"); - put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA1withDSA"); - put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA1withDSA"); - - put("Signature.MD2withRSA", MD2withRSA.class.getName()); + put("Signature.SHA160withDSS", + gnu.java.security.jce.sig.SHA160withDSS.class.getName()); + put("Alg.Alias.Signature.SHA1withDSA", "SHA160withDSS"); + put("Alg.Alias.Signature.DSS", "SHA160withDSS"); + put("Alg.Alias.Signature.DSA", "SHA160withDSS"); + put("Alg.Alias.Signature.SHAwithDSA", "SHA160withDSS"); + put("Alg.Alias.Signature.DSAwithSHA", "SHA160withDSS"); + put("Alg.Alias.Signature.DSAwithSHA1", "SHA160withDSS"); + put("Alg.Alias.Signature.SHA/DSA", "SHA160withDSS"); + put("Alg.Alias.Signature.SHA-1/DSA", "SHA160withDSS"); + put("Alg.Alias.Signature.SHA1/DSA", "SHA160withDSS"); + put("Alg.Alias.Signature.OID.1.2.840.10040.4.3", "SHA160withDSS"); + put("Alg.Alias.Signature.1.2.840.10040.4.3", "SHA160withDSS"); + put("Alg.Alias.Signature.1.3.14.3.2.13", "SHA160withDSS"); + put("Alg.Alias.Signature.1.3.14.3.2.27", "SHA160withDSS"); + + put("Signature.MD2withRSA", + gnu.java.security.jce.sig.MD2withRSA.class.getName()); put("Signature.MD2withRSA ImplementedIn", "Software"); put("Alg.Alias.Signature.md2WithRSAEncryption", "MD2withRSA"); put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.2", "MD2withRSA"); put("Alg.Alias.Signature.1.2.840.113549.1.1.2", "MD2withRSA"); - put("Signature.MD4withRSA", MD4withRSA.class.getName()); - put("Signature.MD4withRSA ImplementedIn", "Software"); - put("Alg.Alias.Signature.md4WithRSAEncryption", "MD4withRSA"); - put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.3", "MD4withRSA"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.3", "MD4withRSA"); - - put("Signature.MD5withRSA", MD5withRSA.class.getName()); + put("Signature.MD5withRSA", + gnu.java.security.jce.sig.MD5withRSA.class.getName()); put("Signature.MD5withRSA ImplementedIn", "Software"); put("Alg.Alias.Signature.md5WithRSAEncryption", "MD5withRSA"); put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.4", "MD5withRSA"); put("Alg.Alias.Signature.1.2.840.113549.1.1.4", "MD5withRSA"); - put("Signature.SHA1withRSA", SHA1withRSA.class.getName()); - put("Signature.SHA1withRSA ImplementedIn", "Software"); - put("Alg.Alias.Signature.sha-1WithRSAEncryption", "SHA1withRSA"); - put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", "SHA1withRSA"); - put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA1withRSA"); + put("Signature.SHA160withRSA", + gnu.java.security.jce.sig.SHA160withRSA.class.getName()); + put("Signature.SHA160withRSA ImplementedIn", "Software"); + put("Alg.Alias.Signature.sha-1WithRSAEncryption", "SHA160withRSA"); + put("Alg.Alias.Signature.sha-160WithRSAEncryption", "SHA160withRSA"); + put("Alg.Alias.Signature.sha1WithRSAEncryption", "SHA160withRSA"); + put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.5", "SHA160withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.5", "SHA160withRSA"); + put("Alg.Alias.Signature.SHA1withRSA", "SHA160withRSA"); + + put("Signature.SHA256withRSA", + gnu.java.security.jce.sig.SHA256withRSA.class.getName()); + put("Signature.SHA160withRSA ImplementedIn", "Software"); + put("Alg.Alias.Signature.sha256WithRSAEncryption", "SHA256withRSA"); + put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.11", "SHA256withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.11", "SHA256withRSA"); + + put("Signature.SHA384withRSA", + gnu.java.security.jce.sig.SHA384withRSA.class.getName()); + put("Signature.SHA160withRSA ImplementedIn", "Software"); + put("Alg.Alias.Signature.sha384WithRSAEncryption", "SHA384withRSA"); + put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.12", "SHA384withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.12", "SHA384withRSA"); + + put("Signature.SHA512withRSA", + gnu.java.security.jce.sig.SHA512withRSA.class.getName()); + put("Signature.SHA160withRSA ImplementedIn", "Software"); + put("Alg.Alias.Signature.sha512WithRSAEncryption", "SHA512withRSA"); + put("Alg.Alias.Signature.OID.1.2.840.113549.1.1.13", "SHA512withRSA"); + put("Alg.Alias.Signature.1.2.840.113549.1.1.13", "SHA512withRSA"); + + put("Signature.DSS/RAW", + gnu.java.security.jce.sig.DSSRawSignatureSpi.class.getName()); + put("Signature.DSS/RAW KeySize", "1024"); + put("Signature.DSS/RAW ImplementedIn", "Software"); + + put("Signature.RSA-PSS/RAW", + gnu.java.security.jce.sig.RSAPSSRawSignatureSpi.class.getName()); + put("Signature.RSA-PSS/RAW KeySize", "1024"); + put("Signature.RSA-PSS/RAW ImplementedIn", "Software"); // Key Pair Generator - put("KeyPairGenerator.DSA", - gnu.java.security.provider.DSAKeyPairGenerator.class.getName()); - put("KeyPairGenerator.DiffieHellman", DiffieHellmanKeyPairGeneratorImpl.class.getName ()); - - put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSA"); - put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSA"); - put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSA"); - put("Alg.Alias.KeyPairGenerator.DH", "DiffieHellman"); + put("KeyPairGenerator.DSS", + gnu.java.security.jce.sig.DSSKeyPairGeneratorSpi.class.getName()); + put("KeyPairGenerator.DSS KeySize", "1024"); + put("KeyPairGenerator.DSS ImplementedIn", "Software"); + put("Alg.Alias.KeyPairGenerator.DSA", "DSS"); + put("Alg.Alias.KeyPairGenerator.OID.1.2.840.10040.4.1", "DSS"); + put("Alg.Alias.KeyPairGenerator.1.2.840.10040.4.1", "DSS"); + put("Alg.Alias.KeyPairGenerator.1.3.14.3.2.12", "DSS"); + + put("KeyPairGenerator.RSA", + gnu.java.security.jce.sig.RSAKeyPairGeneratorSpi.class.getName()); + put("KeyPairGenerator.RSA KeySize", "1024"); + put("KeyPairGenerator.RSA ImplementedIn", "Software"); // Key Factory - put("KeyFactory.DSA", - gnu.java.security.provider.DSAKeyFactory.class.getName()); - - put("KeyFactory.Encoded", EncodedKeyFactory.class.getName()); + put("KeyFactory.DSS", + gnu.java.security.jce.sig.DSSKeyFactory.class.getName()); + put("Alg.Alias.KeyFactory.DSA", "DSS"); + put("Alg.Alias.KeyFactory.OID.1.2.840.10040.4.1", "DSS"); + put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSS"); + put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSS"); + + put("KeyFactory.RSA", + gnu.java.security.jce.sig.RSAKeyFactory.class.getName()); + + put("KeyFactory.Encoded", + gnu.java.security.jce.sig.EncodedKeyFactory.class.getName()); put("KeyFactory.Encoded ImplementedIn", "Software"); put("Alg.Alias.KeyFactory.X.509", "Encoded"); put("Alg.Alias.KeyFactory.X509", "Encoded"); put("Alg.Alias.KeyFactory.PKCS#8", "Encoded"); put("Alg.Alias.KeyFactory.PKCS8", "Encoded"); - put("KeyFactory.RSA", RSAKeyFactory.class.getName()); - - put("Alg.Alias.KeyFactory.OID.1.2.840.10040.4.1", "DSA"); - put("Alg.Alias.KeyFactory.1.2.840.10040.4.1", "DSA"); - put("Alg.Alias.KeyFactory.1.3.14.3.2.12", "DSA"); - - put("KeyFactory.DiffieHellman", DiffieHellmanKeyFactoryImpl.class.getName()); - put("Alg.Alias.KeyFactory.DH", "DiffieHellman"); - - // Message Digests - put("MessageDigest.SHA", gnu.java.security.provider.SHA.class.getName()); - put("MessageDigest.MD5", gnu.java.security.provider.MD5.class.getName()); - - // Format "Alias", "Actual Name" - put("Alg.Alias.MessageDigest.SHA1", "SHA"); - put("Alg.Alias.MessageDigest.SHA-1", "SHA"); - put("Alg.Alias.MessageDigest.SHA-160", "SHA"); + put("MessageDigest.HAVAL", gnu.java.security.jce.hash.HavalSpi.class.getName()); + put("MessageDigest.HAVAL ImplementedIn", "Software"); + put("MessageDigest.MD2", gnu.java.security.jce.hash.MD2Spi.class.getName()); + put("MessageDigest.MD2 ImplementedIn", "Software"); + put("MessageDigest.MD4", gnu.java.security.jce.hash.MD4Spi.class.getName()); + put("MessageDigest.MD4 ImplementedIn", "Software"); + put("MessageDigest.MD5", gnu.java.security.jce.hash.MD5Spi.class.getName()); + put("MessageDigest.MD5 ImplementedIn", "Software"); + put("MessageDigest.RIPEMD128", gnu.java.security.jce.hash.RipeMD128Spi.class.getName()); + put("MessageDigest.RIPEMD128 ImplementedIn", "Software"); + put("MessageDigest.RIPEMD160", gnu.java.security.jce.hash.RipeMD160Spi.class.getName()); + put("MessageDigest.RIPEMD160 ImplementedIn", "Software"); + put("MessageDigest.SHA-160", gnu.java.security.jce.hash.Sha160Spi.class.getName()); + put("MessageDigest.SHA-160 ImplementedIn", "Software"); + put("MessageDigest.SHA-256", gnu.java.security.jce.hash.Sha256Spi.class.getName()); + put("MessageDigest.SHA-256 ImplementedIn", "Software"); + put("MessageDigest.SHA-384", gnu.java.security.jce.hash.Sha384Spi.class.getName()); + put("MessageDigest.SHA-384 ImplementedIn", "Software"); + put("MessageDigest.SHA-512", gnu.java.security.jce.hash.Sha512Spi.class.getName()); + put("MessageDigest.SHA-512 ImplementedIn", "Software"); + put("MessageDigest.TIGER", gnu.java.security.jce.hash.TigerSpi.class.getName()); + put("MessageDigest.TIGER ImplementedIn", "Software"); + put("MessageDigest.WHIRLPOOL", gnu.java.security.jce.hash.WhirlpoolSpi.class.getName()); + put("MessageDigest.WHIRLPOOL ImplementedIn", "Software"); + + put("Alg.Alias.MessageDigest.SHS", "SHA-160"); + put("Alg.Alias.MessageDigest.SHA", "SHA-160"); + put("Alg.Alias.MessageDigest.SHA1", "SHA-160"); + put("Alg.Alias.MessageDigest.SHA-1", "SHA-160"); + put("Alg.Alias.MessageDigest.SHA2-256", "SHA-256"); + put("Alg.Alias.MessageDigest.SHA2-384", "SHA-384"); + put("Alg.Alias.MessageDigest.SHA2-512", "SHA-512"); + put("Alg.Alias.MessageDigest.SHA256", "SHA-256"); + put("Alg.Alias.MessageDigest.SHA384", "SHA-384"); + put("Alg.Alias.MessageDigest.SHA512", "SHA-512"); + put("Alg.Alias.MessageDigest.RIPEMD-160", "RIPEMD160"); + put("Alg.Alias.MessageDigest.RIPEMD-128", "RIPEMD128"); + put("Alg.Alias.MessageDigest.OID.1.2.840.11359.2.2", "MD2"); + put("Alg.Alias.MessageDigest.1.2.840.11359.2.2", "MD2"); + put("Alg.Alias.MessageDigest.OID.1.2.840.11359.2.5", "MD5"); + put("Alg.Alias.MessageDigest.1.2.840.11359.2.5", "MD5"); + put("Alg.Alias.MessageDigest.OID.1.3.14.3.2.26", "SHA1"); + put("Alg.Alias.MessageDigest.1.3.14.3.2.26", "SHA1"); // Algorithm Parameters - put("AlgorithmParameters.DSA", - gnu.java.security.provider.DSAParameters.class.getName()); - - put("Alg.Alias.AlgorithmParameters.DSS", "DSA"); - put("Alg.Alias.AlgorithmParameters.SHAwithDSA", "DSA"); - put("Alg.Alias.AlgorithmParameters.OID.1.2.840.10040.4.3", "DSA"); - put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.3", "DSA"); + put("AlgorithmParameters.DSS", + gnu.java.security.jce.sig.DSSParameters.class.getName()); + put("Alg.Alias.AlgorithmParameters.DSA", "DSS"); + put("Alg.Alias.AlgorithmParameters.SHAwithDSA", "DSS"); + put("Alg.Alias.AlgorithmParameters.OID.1.2.840.10040.4.3", "DSS"); + put("Alg.Alias.AlgorithmParameters.1.2.840.10040.4.3", "DSS"); // Algorithm Parameter Generator put("AlgorithmParameterGenerator.DSA", - gnu.java.security.provider.DSAParameterGenerator.class.getName()); + gnu.java.security.jce.sig.DSSParametersGenerator.class.getName()); + put("Alg.Alias.AlgorithmParameterGenerator.DSA", "DSS"); // SecureRandom put("SecureRandom.SHA1PRNG", - gnu.java.security.provider.SHA1PRNG.class.getName()); + gnu.java.security.jce.prng.Sha160RandomSpi.class.getName()); + + put("SecureRandom.MD2PRNG", gnu.java.security.jce.prng.MD2RandomSpi.class.getName()); + put("SecureRandom.MD2PRNG ImplementedIn", "Software"); + put("SecureRandom.MD4PRNG", gnu.java.security.jce.prng.MD4RandomSpi.class.getName()); + put("SecureRandom.MD4PRNG ImplementedIn", "Software"); + put("SecureRandom.MD5PRNG", gnu.java.security.jce.prng.MD5RandomSpi.class.getName()); + put("SecureRandom.MD5PRNG ImplementedIn", "Software"); + put("SecureRandom.RIPEMD128PRNG", gnu.java.security.jce.prng.RipeMD128RandomSpi.class.getName()); + put("SecureRandom.RIPEMD128PRNG ImplementedIn", "Software"); + put("SecureRandom.RIPEMD160PRNG", gnu.java.security.jce.prng.RipeMD160RandomSpi.class.getName()); + put("SecureRandom.RIPEMD160PRNG ImplementedIn", "Software"); + put("SecureRandom.SHA-160PRNG", gnu.java.security.jce.prng.Sha160RandomSpi.class.getName()); + put("SecureRandom.SHA-160PRNG ImplementedIn", "Software"); + put("SecureRandom.SHA-256PRNG", gnu.java.security.jce.prng.Sha256RandomSpi.class.getName()); + put("SecureRandom.SHA-256PRNG ImplementedIn", "Software"); + put("SecureRandom.SHA-384PRNG", gnu.java.security.jce.prng.Sha384RandomSpi.class.getName()); + put("SecureRandom.SHA-384PRNG ImplementedIn", "Software"); + put("SecureRandom.SHA-512PRNG", gnu.java.security.jce.prng.Sha512RandomSpi.class.getName()); + put("SecureRandom.SHA-512PRNG ImplementedIn", "Software"); + put("SecureRandom.TIGERPRNG", gnu.java.security.jce.prng.TigerRandomSpi.class.getName()); + put("SecureRandom.TIGERPRNG ImplementedIn", "Software"); + put("SecureRandom.HAVALPRNG", gnu.java.security.jce.prng.HavalRandomSpi.class.getName()); + put("SecureRandom.HAVALPRNG ImplementedIn", "Software"); + put("SecureRandom.WHIRLPOOLPRNG", gnu.java.security.jce.prng.WhirlpoolRandomSpi.class.getName()); + put("SecureRandom.WHIRLPOOLPRNG ImplementedIn", "Software"); + + put("Alg.Alias.SecureRandom.SHA-1PRNG", "SHA-160PRNG"); + put("Alg.Alias.SecureRandom.SHA1PRNG", "SHA-160PRNG"); + put("Alg.Alias.SecureRandom.SHAPRNG", "SHA-160PRNG"); + put("Alg.Alias.SecureRandom.SHA-256PRNG", "SHA-256PRNG"); + put("Alg.Alias.SecureRandom.SHA-2-1PRNG", "SHA-256PRNG"); + put("Alg.Alias.SecureRandom.SHA-384PRNG", "SHA-384PRNG"); + put("Alg.Alias.SecureRandom.SHA-2-2PRNG", "SHA-384PRNG"); + put("Alg.Alias.SecureRandom.SHA-512PRNG", "SHA-512PRNG"); + put("Alg.Alias.SecureRandom.SHA-2-3PRNG", "SHA-512PRNG"); // CertificateFactory put("CertificateFactory.X509", X509CertificateFactory.class.getName()); - put("CertificateFactory.X509 ImplementedIn", "Software"); put("Alg.Alias.CertificateFactory.X.509", "X509"); @@ -166,14 +270,6 @@ public final class Gnu extends Provider // CertStore put("CertStore.Collection", CollectionCertStoreImpl.class.getName()); - // KeyAgreement - put("KeyAgreement.DiffieHellman", gnu.javax.crypto.DiffieHellmanImpl.class.getName()); - put("Alg.Alias.KeyAgreement.DH", "DiffieHellman"); - - // Cipher - put("Cipher.RSAES-PKCS1-v1_5", gnu.javax.crypto.RSACipherImpl.class.getName()); - put("Alg.Alias.Cipher.RSA", "RSAES-PKCS1-v1_5"); - return null; } }); diff --git a/libjava/classpath/gnu/java/security/provider/GnuDHPublicKey.java b/libjava/classpath/gnu/java/security/provider/GnuDHPublicKey.java deleted file mode 100644 index 6e13f6bf20f..00000000000 --- a/libjava/classpath/gnu/java/security/provider/GnuDHPublicKey.java +++ /dev/null @@ -1,115 +0,0 @@ -/* GnuDHPublicKey.java -- A Diffie-Hellman public key. - Copyright (C) 2004 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import gnu.java.security.OID; -import gnu.java.security.der.BitString; -import gnu.java.security.der.DER; -import gnu.java.security.der.DERValue; - -import java.math.BigInteger; -import java.util.ArrayList; - -import javax.crypto.interfaces.DHPublicKey; -import javax.crypto.spec.DHParameterSpec; - -public class GnuDHPublicKey implements DHPublicKey -{ - - // Fields. - // ------------------------------------------------------------------------- - - private byte[] encoded; - private final DHParameterSpec params; - private final BigInteger Y; - private final BigInteger q; - - // Constructor. - // ------------------------------------------------------------------------- - - public GnuDHPublicKey(DHParameterSpec params, BigInteger Y, BigInteger q) - { - this.params = params; - this.Y = Y; - this.q = q; - } - - // Instance methods. - // ------------------------------------------------------------------------- - - public BigInteger getY() - { - return Y; - } - - public DHParameterSpec getParams() - { - return params; - } - - public String getAlgorithm() - { - return "DH"; - } - - public String getFormat() - { - return "X.509"; - } - - public byte[] getEncoded() - { - if (encoded != null) - return (byte[]) encoded.clone(); - ArrayList spki = new ArrayList(2); - ArrayList alg = new ArrayList(2); - alg.add(new DERValue(DER.OBJECT_IDENTIFIER, new OID("1.2.840.10046.2.1"))); - ArrayList param = new ArrayList(3); - param.add(new DERValue(DER.INTEGER, params.getP())); - param.add(new DERValue(DER.INTEGER, params.getG())); - param.add(new DERValue(DER.INTEGER, q)); - alg.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, param)); - spki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg)); - spki.add(new DERValue(DER.BIT_STRING, new BitString(Y.toByteArray()))); - encoded = new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, spki).getEncoded(); - if (encoded != null) - return (byte[]) encoded.clone(); - return null; - } -} diff --git a/libjava/classpath/gnu/java/security/provider/GnuDSAPrivateKey.java b/libjava/classpath/gnu/java/security/provider/GnuDSAPrivateKey.java deleted file mode 100644 index aac2faab229..00000000000 --- a/libjava/classpath/gnu/java/security/provider/GnuDSAPrivateKey.java +++ /dev/null @@ -1,147 +0,0 @@ -/* GnuDSAPrivateKey.java --- Gnu DSA Private Key - Copyright (C) 1999,2003,2004 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import gnu.java.security.OID; -import gnu.java.security.der.DER; -import gnu.java.security.der.DERValue; -import gnu.java.security.der.DERWriter; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.security.interfaces.DSAParams; -import java.security.interfaces.DSAPrivateKey; -import java.security.spec.DSAParameterSpec; -import java.util.ArrayList; - -public class GnuDSAPrivateKey implements DSAPrivateKey -{ - private byte[] encodedKey; - BigInteger x; - BigInteger p; - BigInteger q; - BigInteger g; - - public GnuDSAPrivateKey(BigInteger x, BigInteger p, BigInteger q, BigInteger g ) - { - this.x = x; - this.p = p; - this.q = q; - this.g = g; - } - - public String getAlgorithm() - { - return "DSA"; - } - - public String getFormat() - { - return "PKCS#8"; - } - - /** - * Encodes this key as a <code>PrivateKeyInfo</code>, as described in - * PKCS #8. The ASN.1 specification for this structure is: - * - * <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> - * - * <p>DSA private keys (in Classpath at least) have no attributes. - */ - public byte[] getEncoded() - { - if (encodedKey != null) - return (byte[]) encodedKey.clone(); - try - { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ArrayList pki = new ArrayList(3); - pki.add(new DERValue(DER.INTEGER, BigInteger.ZERO)); - ArrayList algId = new ArrayList(2); - algId.add(new DERValue(DER.OBJECT_IDENTIFIER, - new OID("1.2.840.10040.4.1"))); - ArrayList algParams = new ArrayList(3); - algParams.add(new DERValue(DER.INTEGER, p)); - algParams.add(new DERValue(DER.INTEGER, q)); - algParams.add(new DERValue(DER.INTEGER, g)); - algId.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, algParams)); - pki.add(new DERValue(DER.OCTET_STRING, x.toByteArray())); - DERWriter.write(out, new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, pki)); - return (byte[]) (encodedKey = out.toByteArray()).clone(); - } - catch (IOException ioe) - { - return null; - } - } - - public DSAParams getParams() - { - return (DSAParams)(new DSAParameterSpec(p,q,g)); - } - - public BigInteger getX() - { - return x; - } - - public String toString() - { - return "GnuDSAPrivateKey: x=" - + (x != null ? x.toString(16) : "null") + " p=" - + (p != null ? p.toString(16) : "null") + " q=" - + (q != null ? q.toString(16) : "null") + " g=" - + (g != null ? g.toString(16) : "null"); - } -} diff --git a/libjava/classpath/gnu/java/security/provider/GnuDSAPublicKey.java b/libjava/classpath/gnu/java/security/provider/GnuDSAPublicKey.java deleted file mode 100644 index 41195fa992c..00000000000 --- a/libjava/classpath/gnu/java/security/provider/GnuDSAPublicKey.java +++ /dev/null @@ -1,137 +0,0 @@ -/* GnuDSAPublicKey.java --- Gnu DSA Public Key - Copyright (C) 1999,2003,2004 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import gnu.java.security.OID; -import gnu.java.security.der.BitString; -import gnu.java.security.der.DER; -import gnu.java.security.der.DERValue; -import gnu.java.security.der.DERWriter; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.security.interfaces.DSAParams; -import java.security.interfaces.DSAPublicKey; -import java.security.spec.DSAParameterSpec; -import java.util.ArrayList; - -public class GnuDSAPublicKey implements DSAPublicKey -{ - private byte[] encodedKey; - BigInteger y; - BigInteger p; - BigInteger q; - BigInteger g; - - public GnuDSAPublicKey(BigInteger y, BigInteger p, BigInteger q, BigInteger g ) - { - this.y = y; - this.p = p; - this.q = q; - this.g = g; - } - - public String getAlgorithm() - { - return "DSA"; - } - - public String getFormat() - { - return "X.509"; - } - - /** - * The encoded form of DSA public keys is: - * - * <blockquote><pre> - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING } - * </pre></blockquote> - */ - public byte[] getEncoded() - { - if (encodedKey != null) - return (byte[]) encodedKey.clone(); - try - { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - ArrayList spki = new ArrayList(2); - ArrayList alg = new ArrayList(2); - alg.add(new DERValue(DER.OBJECT_IDENTIFIER, - new OID("1.2.840.113549.1.1.1"))); - ArrayList params = new ArrayList(3); - params.add(new DERValue(DER.INTEGER, p)); - params.add(new DERValue(DER.INTEGER, q)); - params.add(new DERValue(DER.INTEGER, g)); - alg.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, params)); - spki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg)); - spki.add(new DERValue(DER.BIT_STRING, new BitString(y.toByteArray()))); - DERWriter.write(out, new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, spki)); - return (byte[]) (encodedKey = out.toByteArray()).clone(); - } - catch (IOException ioe) - { - return null; - } - } - - public DSAParams getParams() - { - if (p == null || q == null || g == null) - return null; - return (DSAParams)(new DSAParameterSpec(p,q,g)); - } - - public BigInteger getY() - { - return y; - } - - public String toString() - { - return - "GnuDSAPublicKey: y=" + (y != null ? y.toString(16) : "(null)") + - " p=" + (p != null ? p.toString(16) : "(null)") + - " q=" + (q != null ? q.toString(16) : "(null)") + - " g=" + (g != null ? g.toString(16) : "(null)"); - } -} diff --git a/libjava/classpath/gnu/java/security/provider/GnuRSAPrivateKey.java b/libjava/classpath/gnu/java/security/provider/GnuRSAPrivateKey.java deleted file mode 100644 index b09fc88bc5c..00000000000 --- a/libjava/classpath/gnu/java/security/provider/GnuRSAPrivateKey.java +++ /dev/null @@ -1,164 +0,0 @@ -/* GnuRSAPrivateKey.java -- GNU RSA private key. - Copyright (C) 2004 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import gnu.java.security.OID; -import gnu.java.security.der.DER; -import gnu.java.security.der.DERValue; - -import java.math.BigInteger; -import java.security.interfaces.RSAPrivateCrtKey; -import java.security.spec.RSAPrivateCrtKeySpec; -import java.util.ArrayList; - -class GnuRSAPrivateKey implements RSAPrivateCrtKey -{ - - // Fields. - // ------------------------------------------------------------------------- - - private final RSAPrivateCrtKeySpec spec; - private byte[] encodedKey; - - // Constructor. - // ------------------------------------------------------------------------- - - public GnuRSAPrivateKey(RSAPrivateCrtKeySpec spec) - { - this.spec = spec; - } - - // Instance methods. - // ------------------------------------------------------------------------- - - public BigInteger getModulus() - { - return spec.getModulus(); - } - - public BigInteger getPrivateExponent() - { - return spec.getPrivateExponent(); - } - - public BigInteger getCrtCoefficient() - { - return spec.getCrtCoefficient(); - } - - public BigInteger getPrimeExponentP() - { - return spec.getPrimeExponentP(); - } - - public BigInteger getPrimeExponentQ() - { - return spec.getPrimeExponentQ(); - } - - public BigInteger getPrimeP() - { - return spec.getPrimeP(); - } - - public BigInteger getPrimeQ() - { - return spec.getPrimeQ(); - } - - public BigInteger getPublicExponent() - { - return spec.getPublicExponent(); - } - - public String getAlgorithm() - { - return "RSA"; - } - - public String getFormat() - { - return "PKCS#8"; - } - - /** - * The encoded form is: - * - * <pre> - * RSAPrivateKey ::= SEQUENCE { - * version Version, - * modulus INTEGER, -- n - * publicExponent INTEGER, -- e - * privateExponent INTEGER, -- d - * prime1 INTEGER, -- p - * prime2 INTEGER, -- q - * exponent1 INTEGER, -- d mod (p-1) - * exponent2 INTEGER, -- d mod (q-1) - * coefficient INTEGER -- (inverse of q) mod p } - * </pre> - * - * <p>Which is in turn encoded in a PrivateKeyInfo structure from PKCS#8. - */ - public byte[] getEncoded() - { - if (encodedKey != null) - return (byte[]) encodedKey.clone(); - ArrayList key = new ArrayList(9); - key.add(new DERValue(DER.INTEGER, BigInteger.ZERO)); - key.add(new DERValue(DER.INTEGER, getModulus())); - key.add(new DERValue(DER.INTEGER, getPublicExponent())); - key.add(new DERValue(DER.INTEGER, getPrivateExponent())); - key.add(new DERValue(DER.INTEGER, getPrimeP())); - key.add(new DERValue(DER.INTEGER, getPrimeQ())); - key.add(new DERValue(DER.INTEGER, getPrimeExponentP())); - key.add(new DERValue(DER.INTEGER, getPrimeExponentQ())); - key.add(new DERValue(DER.INTEGER, getCrtCoefficient())); - DERValue pk = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, key); - ArrayList pki = new ArrayList(3); - pki.add(new DERValue(DER.INTEGER, BigInteger.ZERO)); - ArrayList alg = new ArrayList(2); - alg.add(new DERValue(DER.OBJECT_IDENTIFIER, - new OID("1.2.840.113549.1.1.1"))); - alg.add(new DERValue(DER.NULL, null)); - pki.add(new DERValue(DER.CONSTRUCTED|DER.SEQUENCE, alg)); - pki.add(new DERValue(DER.OCTET_STRING, pk.getEncoded())); - encodedKey = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, pki).getEncoded(); - return (byte[]) encodedKey.clone(); - } -} diff --git a/libjava/classpath/gnu/java/security/provider/GnuRSAPublicKey.java b/libjava/classpath/gnu/java/security/provider/GnuRSAPublicKey.java deleted file mode 100644 index a35e761c066..00000000000 --- a/libjava/classpath/gnu/java/security/provider/GnuRSAPublicKey.java +++ /dev/null @@ -1,109 +0,0 @@ -/* GnuRSAPublicKey.java -- GNU RSA public key. - Copyright (C) 2004 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import gnu.java.security.OID; -import gnu.java.security.der.BitString; -import gnu.java.security.der.DER; -import gnu.java.security.der.DERValue; - -import java.math.BigInteger; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.RSAPublicKeySpec; -import java.util.ArrayList; - -class GnuRSAPublicKey implements RSAPublicKey -{ - - // Fields. - // ------------------------------------------------------------------------- - - private final RSAPublicKeySpec spec; - private byte[] encodedKey; - - // Constructor. - // ------------------------------------------------------------------------- - - public GnuRSAPublicKey(RSAPublicKeySpec spec) - { - this.spec = spec; - } - - // Instance methods. - // ------------------------------------------------------------------------- - - public BigInteger getModulus() - { - return spec.getModulus(); - } - - public BigInteger getPublicExponent() - { - return spec.getPublicExponent(); - } - - public String getAlgorithm() - { - return "RSA"; - } - - public String getFormat() - { - return "X.509"; - } - - public byte[] getEncoded() - { - if (encodedKey != null) - return (byte[]) encodedKey.clone(); - ArrayList key = new ArrayList(2); - key.add(new DERValue(DER.INTEGER, getModulus())); - key.add(new DERValue(DER.INTEGER, getPublicExponent())); - DERValue rsapk = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, key); - ArrayList alg = new ArrayList(2); - alg.add(new DERValue(DER.OBJECT_IDENTIFIER, - new OID("1.2.840.113549.1.1.1"))); - alg.add(new DERValue(DER.NULL, null)); - ArrayList spki = new ArrayList(2); - spki.add(new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, alg)); - spki.add(new DERValue(DER.BIT_STRING, new BitString(rsapk.getEncoded()))); - encodedKey = new DERValue(DER.SEQUENCE|DER.CONSTRUCTED, spki).getEncoded(); - return (byte[]) encodedKey.clone(); - } -} diff --git a/libjava/classpath/gnu/java/security/provider/MD5.java b/libjava/classpath/gnu/java/security/provider/MD5.java deleted file mode 100644 index 1534eb91089..00000000000 --- a/libjava/classpath/gnu/java/security/provider/MD5.java +++ /dev/null @@ -1,338 +0,0 @@ -/* MD5.java -- Class implementing the MD5 algorithm as specified in RFC1321. - Copyright (C) 1999, 2002 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; -import java.security.MessageDigest; - -/** - This class implements the MD5 algorithm as described in RFC1321. - - @see java.security.MessageDigest -*/ -public class MD5 extends MessageDigest implements Cloneable -{ - private final int W[] = new int[16]; - private long bytecount; - private int A; - private int B; - private int C; - private int D; - - public MD5() - { - super("MD5"); - engineReset (); - } - - public Object clone() - { - return new MD5 (this); - } - - private MD5 (MD5 copy) - { - this (); - bytecount = copy.bytecount; - A = copy.A; - B = copy.B; - C = copy.C; - D = copy.D; - System.arraycopy (copy.W, 0, W, 0, 16); - } - - public int engineGetDigestLength() - { - return 16; - } - - // Intialize the A,B,C,D needed for the hash - public void engineReset() - { - bytecount = 0; - A = 0x67452301; - B = 0xefcdab89; - C = 0x98badcfe; - D = 0x10325476; - for(int i = 0; i < 16; i++) - W[i] = 0; - } - - public void engineUpdate (byte b) - { - int i = (int)bytecount % 64; - int shift = (3 - i % 4) * 8; - int idx = i / 4; - - // if you could index ints, this would be: W[idx][shift/8] = b - W[idx] = (W[idx] & ~(0xff << shift)) | ((b & 0xff) << shift); - - // if we've filled up a block, then process it - if ((++ bytecount) % 64 == 0) - munch (); - } - - public void engineUpdate (byte bytes[], int off, int len) - { - if (len < 0) - throw new ArrayIndexOutOfBoundsException (); - - int end = off + len; - while (off < end) - engineUpdate (bytes[off++]); - } - - public byte[] engineDigest() - { - long bitcount = bytecount * 8; - engineUpdate ((byte)0x80); // 10000000 in binary; the start of the padding - - // add the rest of the padding to fill this block out, but leave 8 - // bytes to put in the original bytecount - while ((int)bytecount % 64 != 56) - engineUpdate ((byte)0); - - // add the length of the original, unpadded block to the end of - // the padding - W[14] = SWAP((int)(0xffffffff & bitcount)); - W[15] = SWAP((int)(0xffffffff & (bitcount >>> 32))); - bytecount += 8; - - // digest the fully padded block - munch (); - - A = SWAP(A); - B = SWAP(B); - C = SWAP(C); - D = SWAP(D); - byte[] result = new byte[] {(byte)(A >>> 24), (byte)(A >>> 16), - (byte)(A >>> 8), (byte)A, - (byte)(B >>> 24), (byte)(B >>> 16), - (byte)(B >>> 8), (byte)B, - (byte)(C >>> 24), (byte)(C >>> 16), - (byte)(C >>> 8), (byte)C, - (byte)(D >>> 24), (byte)(D >>> 16), - (byte)(D >>> 8), (byte)D}; - - engineReset (); - return result; - } - - private int F( int X, int Y, int Z) - { - return ((X & Y) | (~X & Z)); - } - - private int G( int X, int Y, int Z) - { - return ((X & Z) | (Y & ~Z)); - } - - private int H( int X, int Y, int Z) - { - return (X ^ Y ^ Z); - } - - private int I( int X, int Y, int Z) - { - return (Y ^ (X | ~Z)); - } - - private int rotateLeft( int i, int count) - { - //Taken from FIPS 180-1 - return ( (i << count) | (i >>> (32 - count)) ) ; - } - - /* Round 1. */ - private int FF( int a, int b, int c, int d, int k, int s, int i) - { - /* Let [abcd k s i] denote the operation */ - a += F(b,c,d) + k + i; - return b + rotateLeft(a, s); - } - /* Round 2. */ - private int GG( int a, int b, int c, int d, int k, int s, int i) - { - /* Let [abcd k s i] denote the operation */ - a += G(b,c,d) + k + i; - return b + rotateLeft(a, s); - } - /* Round 3. */ - private int HH( int a, int b, int c, int d, int k, int s, int i) - { - /* Let [abcd k s t] denote the operation */ - a += H(b,c,d) + k + i; - return b + rotateLeft(a, s); - } - - /* Round 4. */ - private int II( int a, int b, int c, int d, int k, int s, int i) - { - /* Let [abcd k s t] denote the operation */ - a += I(b,c,d) + k + i; - return b + rotateLeft(a, s); - } - - private int SWAP(int n) - { - //Copied from md5.c in FSF Gnu Privacy Guard 0.9.2 - return (( (0xff & n) << 24) | ((n & 0xff00) << 8) | ((n >>> 8) & 0xff00) | (n >>> 24)); - } - - private void munch() - { - int AA,BB,CC,DD, j; - int X[] = new int[16]; - - /* Copy block i into X. */ - for(j = 0; j < 16; j++) - X[j] = SWAP(W[j]); - - /* Save A as AA, B as BB, C as CC, and D as DD. */ - AA = A; - BB = B; - CC = C; - DD = D; - - /* The hex constants are from md5.c - in FSF Gnu Privacy Guard 0.9.2 */ - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ - /* Do the following 16 operations. */ - A = FF(A,B,C,D, X[0], 7, 0xd76aa478); - D = FF(D,A,B,C, X[1], 12, 0xe8c7b756); - C = FF(C,D,A,B, X[2], 17, 0x242070db); - B = FF(B,C,D,A, X[3], 22, 0xc1bdceee); - - A = FF(A,B,C,D, X[4], 7, 0xf57c0faf); - D = FF(D,A,B,C, X[5], 12, 0x4787c62a); - C = FF(C,D,A,B, X[6], 17, 0xa8304613); - B = FF(B,C,D,A, X[7], 22, 0xfd469501); - - A = FF(A,B,C,D, X[8], 7, 0x698098d8); - D = FF(D,A,B,C, X[9], 12, 0x8b44f7af); - C = FF(C,D,A,B, X[10], 17, 0xffff5bb1); - B = FF(B,C,D,A, X[11], 22, 0x895cd7be); - - A = FF(A,B,C,D, X[12], 7, 0x6b901122); - D = FF(D,A,B,C, X[13], 12, 0xfd987193); - C = FF(C,D,A,B, X[14], 17, 0xa679438e); - B = FF(B,C,D,A, X[15], 22, 0x49b40821); - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ - /* Do the following 16 operations. */ - A = GG(A,B,C,D, X[1], 5, 0xf61e2562); - D = GG(D,A,B,C, X[6], 9, 0xc040b340); - C = GG(C,D,A,B, X[11], 14, 0x265e5a51); - B = GG(B,C,D,A, X[0], 20, 0xe9b6c7aa); - - A = GG(A,B,C,D, X[5], 5, 0xd62f105d); - D = GG(D,A,B,C, X[10], 9, 0x02441453); - C = GG(C,D,A,B, X[15], 14, 0xd8a1e681); - B = GG(B,C,D,A, X[4], 20, 0xe7d3fbc8); - - A = GG(A,B,C,D, X[9], 5, 0x21e1cde6); - D = GG(D,A,B,C, X[14], 9, 0xc33707d6); - C = GG(C,D,A,B, X[3], 14, 0xf4d50d87); - B = GG(B,C,D,A, X[8], 20, 0x455a14ed); - - A = GG(A,B,C,D, X[13], 5, 0xa9e3e905); - D = GG(D,A,B,C, X[2], 9, 0xfcefa3f8); - C = GG(C,D,A,B, X[7], 14, 0x676f02d9); - B = GG(B,C,D,A, X[12], 20, 0x8d2a4c8a); - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ - /* Do the following 16 operations. */ - A = HH(A,B,C,D, X[5], 4, 0xfffa3942); - D = HH(D,A,B,C, X[8], 11, 0x8771f681); - C = HH(C,D,A,B, X[11], 16, 0x6d9d6122); - B = HH(B,C,D,A, X[14], 23, 0xfde5380c); - - A = HH(A,B,C,D, X[1], 4, 0xa4beea44); - D = HH(D,A,B,C, X[4], 11, 0x4bdecfa9); - C = HH(C,D,A,B, X[7], 16, 0xf6bb4b60); - B = HH(B,C,D,A, X[10], 23, 0xbebfbc70); - - A = HH(A,B,C,D, X[13], 4, 0x289b7ec6); - D = HH(D,A,B,C, X[0], 11, 0xeaa127fa); - C = HH(C,D,A,B, X[3], 16, 0xd4ef3085); - B = HH(B,C,D,A, X[6], 23, 0x04881d05); - - A = HH(A,B,C,D, X[9], 4, 0xd9d4d039); - D = HH(D,A,B,C, X[12], 11, 0xe6db99e5); - C = HH(C,D,A,B, X[15], 16, 0x1fa27cf8); - B = HH(B,C,D,A, X[2], 23, 0xc4ac5665); - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ - /* Do the following 16 operations. */ - A = II(A,B,C,D, X[0], 6, 0xf4292244); - D = II(D,A,B,C, X[7], 10, 0x432aff97); - C = II(C,D,A,B, X[14], 15, 0xab9423a7); - B = II(B,C,D,A, X[5], 21, 0xfc93a039); - - A = II(A,B,C,D, X[12], 6, 0x655b59c3); - D = II(D,A,B,C, X[3], 10, 0x8f0ccc92); - C = II(C,D,A,B, X[10], 15, 0xffeff47d); - B = II(B,C,D,A, X[1], 21, 0x85845dd1); - - A = II(A,B,C,D, X[8], 6, 0x6fa87e4f); - D = II(D,A,B,C, X[15], 10, 0xfe2ce6e0); - C = II(C,D,A,B, X[6], 15, 0xa3014314); - B = II(B,C,D,A, X[13], 21, 0x4e0811a1); - - A = II(A,B,C,D, X[4], 6, 0xf7537e82); - D = II(D,A,B,C, X[11], 10, 0xbd3af235); - C = II(C,D,A,B, X[2], 15, 0x2ad7d2bb); - B = II(B,C,D,A, X[9], 21, 0xeb86d391); - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - A = A + AA; - B = B + BB; - C = C + CC; - D = D + DD; - } -} diff --git a/libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java b/libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java index ab8943443ec..880163731f1 100644 --- a/libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java +++ b/libjava/classpath/gnu/java/security/provider/PKIXCertPathValidatorImpl.java @@ -39,6 +39,8 @@ exception statement from your version. */ package gnu.java.security.provider; import gnu.java.security.OID; +import gnu.java.security.Registry; +import gnu.java.security.key.dss.DSSPublicKey; import gnu.java.security.x509.GnuPKIExtension; import gnu.java.security.x509.PolicyNodeImpl; import gnu.java.security.x509.X509CRLSelectorImpl; @@ -241,8 +243,11 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi if (!(prevKey instanceof DSAPublicKey)) throw new InvalidKeyException("DSA keys not chainable"); dsa = ((DSAPublicKey) prevKey).getParams(); - pubKey = new GnuDSAPublicKey(((DSAPublicKey) pubKey).getY(), - dsa.getP(), dsa.getQ(), dsa.getG()); + pubKey = new DSSPublicKey(Registry.X509_ENCODING_ID, + dsa.getP(), + dsa.getQ(), + dsa.getG(), + ((DSAPublicKey) pubKey).getY()); } } if (sigProvider == null) diff --git a/libjava/classpath/gnu/java/security/provider/RSA.java b/libjava/classpath/gnu/java/security/provider/RSA.java deleted file mode 100644 index c3cfbbf79f1..00000000000 --- a/libjava/classpath/gnu/java/security/provider/RSA.java +++ /dev/null @@ -1,311 +0,0 @@ -/* RSA.java -- RSA PKCS#1 signatures. - Copyright (C) 2004 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import gnu.java.security.OID; -import gnu.java.security.der.DER; -import gnu.java.security.der.DERReader; -import gnu.java.security.der.DERValue; -import gnu.java.security.der.DERWriter; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.math.BigInteger; -import java.security.InvalidKeyException; -import java.security.MessageDigest; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.SecureRandom; -import java.security.SignatureException; -import java.security.SignatureSpi; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; -import java.util.ArrayList; - -public abstract class RSA extends SignatureSpi implements Cloneable -{ - - // Constants and fields. - // ------------------------------------------------------------------------- - - /** - * digestAlgorithm OBJECT IDENTIFIER ::= - * { iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) } - */ - protected static final OID DIGEST_ALGORITHM = new OID("1.2.840.113549.2"); - - protected final OID digestAlgorithm; - protected final MessageDigest md; - protected RSAPrivateKey signerKey; - protected RSAPublicKey verifierKey; - - // Constructor. - // ------------------------------------------------------------------------- - - protected RSA(MessageDigest md, OID digestAlgorithm) - { - super(); - this.md = md; - this.digestAlgorithm = digestAlgorithm; - } - - // Instance methods. - // ------------------------------------------------------------------------- - - public Object clone() throws CloneNotSupportedException - { - return super.clone(); - } - - protected Object engineGetParameter(String param) - { - throw new UnsupportedOperationException("deprecated"); - } - - protected void engineSetParameter(String param, Object value) - { - throw new UnsupportedOperationException("deprecated"); - } - - protected void engineInitSign(PrivateKey privateKey) - throws InvalidKeyException - { - if (!(privateKey instanceof RSAPrivateKey)) - throw new InvalidKeyException(); - verifierKey = null; - signerKey = (RSAPrivateKey) privateKey; - } - - protected void engineInitSign(PrivateKey privateKey, SecureRandom random) - throws InvalidKeyException - { - // This class does not need random bytes. - engineInitSign(privateKey); - } - - protected void engineInitVerify(PublicKey publicKey) - throws InvalidKeyException - { - if (!(publicKey instanceof RSAPublicKey)) - throw new InvalidKeyException(); - signerKey = null; - verifierKey = (RSAPublicKey) publicKey; - } - - protected void engineUpdate(byte b) throws SignatureException - { - if (signerKey == null && verifierKey == null) - throw new SignatureException("not initialized"); - md.update(b); - } - - protected void engineUpdate(byte[] buf, int off, int len) - throws SignatureException - { - if (signerKey == null && verifierKey == null) - throw new SignatureException("not initialized"); - md.update(buf, off, len); - } - - protected byte[] engineSign() throws SignatureException - { - if (signerKey == null) - throw new SignatureException("not initialized for signing"); - // - // The signature will be the RSA encrypted BER representation of - // the following: - // - // DigestInfo ::= SEQUENCE { - // digestAlgorithm DigestAlgorithmIdentifier, - // digest Digest } - // - // DigestAlgorithmIdentifier ::= AlgorithmIdentifier - // - // Digest ::= OCTET STRING - // - ArrayList digestAlg = new ArrayList(2); - digestAlg.add(new DERValue(DER.OBJECT_IDENTIFIER, digestAlgorithm)); - digestAlg.add(new DERValue(DER.NULL, null)); - ArrayList digestInfo = new ArrayList(2); - digestInfo.add(new DERValue(DER.SEQUENCE, digestAlg)); - digestInfo.add(new DERValue(DER.OCTET_STRING, md.digest())); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - try - { - DERWriter.write(out, new DERValue(DER.SEQUENCE, digestInfo)); - } - catch (IOException ioe) - { - throw new SignatureException(ioe.toString()); - } - byte[] buf = out.toByteArray(); - md.reset(); - - // k = octect length of the modulus. - int k = signerKey.getModulus().bitLength(); - k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1); - if (buf.length < k - 3) - { - throw new SignatureException("RSA modulus too small"); - } - byte[] d = new byte[k]; - - // Padding type 1: - // 00 | 01 | FF | ... | FF | 00 | D - d[1] = 0x01; - for (int i = 2; i < k - buf.length - 1; i++) - d[i] = (byte) 0xFF; - System.arraycopy(buf, 0, d, k - buf.length, buf.length); - - BigInteger eb = new BigInteger(d); - - byte[] ed = eb.modPow(signerKey.getPrivateExponent(), - signerKey.getModulus()).toByteArray(); - - // Ensure output is k octets long. - if (ed.length < k) - { - byte[] b = new byte[k]; - System.arraycopy(eb, 0, b, k - ed.length, ed.length); - ed = b; - } - else if (ed.length > k) - { - if (ed.length != k + 1) - { - throw new SignatureException("modPow result is larger than the modulus"); - } - // Maybe an extra 00 octect. - byte[] b = new byte[k]; - System.arraycopy(ed, 1, b, 0, k); - ed = b; - } - - return ed; - } - - protected int engineSign(byte[] out, int off, int len) - throws SignatureException - { - if (out == null || off < 0 || len < 0 || off+len > out.length) - throw new SignatureException("illegal output argument"); - byte[] result = engineSign(); - if (result.length > len) - throw new SignatureException("not enough space for signature"); - System.arraycopy(result, 0, out, off, result.length); - return result.length; - } - - protected boolean engineVerify(byte[] sig) throws SignatureException - { - if (verifierKey == null) - throw new SignatureException("not initialized for verifying"); - if (sig == null) - throw new SignatureException("no signature specified"); - int k = verifierKey.getModulus().bitLength(); - k = (k >>> 3) + ((k & 7) == 0 ? 0 : 1); - if (sig.length != k) - throw new SignatureException("signature is the wrong size (expecting " - + k + " bytes, got " + sig.length + ")"); - BigInteger ed = new BigInteger(1, sig); - byte[] eb = ed.modPow(verifierKey.getPublicExponent(), - verifierKey.getModulus()).toByteArray(); - - int i = 0; - if (eb[0] == 0x00) - { - for (i = 1; i < eb.length && eb[i] == 0x00; i++); - if (i == 1) - throw new SignatureException("wrong RSA padding"); - i--; - } - else if (eb[0] == 0x01) - { - for (i = 1; i < eb.length && eb[i] != 0x00; i++) - if (eb[i] != (byte) 0xFF) - throw new IllegalArgumentException("wrong RSA padding"); - } - else - throw new SignatureException("wrong RSA padding type"); - - byte[] d = new byte[eb.length-i-1]; - System.arraycopy(eb, i+1, d, 0, eb.length-i-1); - - DERReader der = new DERReader(d); - try - { - DERValue val = der.read(); - if (val.getTag() != DER.SEQUENCE) - throw new SignatureException("failed to parse DigestInfo"); - val = der.read(); - if (val.getTag() != DER.SEQUENCE) - throw new SignatureException("failed to parse DigestAlgorithmIdentifier"); - boolean sequenceIsBer = val.getLength() == 0; - val = der.read(); - if (val.getTag() != DER.OBJECT_IDENTIFIER) - throw new SignatureException("failed to parse object identifier"); - if (!val.getValue().equals(digestAlgorithm)) - throw new SignatureException("digest algorithms do not match"); - val = der.read(); - // We should never see parameters here, since they are never used. - if (val.getTag() != DER.NULL) - throw new SignatureException("cannot handle digest parameters"); - if (sequenceIsBer) - der.skip(1); // end-of-sequence byte. - val = der.read(); - if (val.getTag() != DER.OCTET_STRING) - throw new SignatureException("failed to parse Digest"); - return MessageDigest.isEqual(md.digest(), (byte[]) val.getValue()); - } - catch (IOException ioe) - { - throw new SignatureException(ioe.toString()); - } - } - - protected boolean engineVerify(byte[] sig, int off, int len) - throws SignatureException - { - if (sig == null || off < 0 || len < 0 || off+len > sig.length) - throw new SignatureException("illegal parameter"); - byte[] buf = new byte[len]; - System.arraycopy(sig, off, buf, 0, len); - return engineVerify(buf); - } -} diff --git a/libjava/classpath/gnu/java/security/provider/RSAKeyFactory.java b/libjava/classpath/gnu/java/security/provider/RSAKeyFactory.java deleted file mode 100644 index d13cbe510a1..00000000000 --- a/libjava/classpath/gnu/java/security/provider/RSAKeyFactory.java +++ /dev/null @@ -1,181 +0,0 @@ -/* RSAKeyFactory.java -- RSA key factory. - Copyright (C) 2004 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import java.security.InvalidKeyException; -import java.security.Key; -import java.security.KeyFactorySpi; -import java.security.PrivateKey; -import java.security.PublicKey; - -import java.security.interfaces.RSAPrivateCrtKey; -import java.security.interfaces.RSAPrivateKey; -import java.security.interfaces.RSAPublicKey; - -import java.security.spec.InvalidKeySpecException; -import java.security.spec.KeySpec; -import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.RSAPrivateCrtKeySpec; -import java.security.spec.RSAPrivateKeySpec; -import java.security.spec.RSAPublicKeySpec; -import java.security.spec.X509EncodedKeySpec; - -public class RSAKeyFactory extends KeyFactorySpi -{ - - // Default constructor. - // ------------------------------------------------------------------------- - - // Instance methods. - // ------------------------------------------------------------------------- - - protected PrivateKey engineGeneratePrivate(KeySpec spec) - throws InvalidKeySpecException - { - if (spec instanceof RSAPrivateCrtKeySpec) - { - return new GnuRSAPrivateKey((RSAPrivateCrtKeySpec) spec); - } - if (spec instanceof RSAPrivateKeySpec) - { - return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec( - ((RSAPrivateKeySpec) spec).getModulus(), null, - ((RSAPrivateKeySpec) spec).getPrivateExponent(), null, - null, null, null, null)); - } - if (spec instanceof PKCS8EncodedKeySpec) - { - EncodedKeyFactory ekf = new EncodedKeyFactory(); - PrivateKey pk = ekf.engineGeneratePrivate(spec); - if (pk instanceof RSAPrivateKey) - return pk; - } - throw new InvalidKeySpecException(); - } - - protected PublicKey engineGeneratePublic(KeySpec spec) - throws InvalidKeySpecException - { - if (spec instanceof RSAPublicKeySpec) - { - return new GnuRSAPublicKey((RSAPublicKeySpec) spec); - } - if (spec instanceof X509EncodedKeySpec) - { - EncodedKeyFactory ekf = new EncodedKeyFactory(); - PublicKey pk = ekf.engineGeneratePublic(spec); - if (pk instanceof RSAPublicKey) - return pk; - } - throw new InvalidKeySpecException(); - } - - protected KeySpec engineGetKeySpec(Key key, Class keySpec) - throws InvalidKeySpecException - { - if (keySpec.isAssignableFrom(RSAPrivateCrtKeySpec.class) - && (key instanceof RSAPrivateCrtKey)) - { - return new RSAPrivateCrtKeySpec( - ((RSAPrivateCrtKey) key).getModulus(), - ((RSAPrivateCrtKey) key).getPublicExponent(), - ((RSAPrivateCrtKey) key).getPrivateExponent(), - ((RSAPrivateCrtKey) key).getPrimeP(), - ((RSAPrivateCrtKey) key).getPrimeQ(), - ((RSAPrivateCrtKey) key).getPrimeExponentP(), - ((RSAPrivateCrtKey) key).getPrimeExponentQ(), - ((RSAPrivateCrtKey) key).getCrtCoefficient()); - } - if (keySpec.isAssignableFrom(RSAPrivateKeySpec.class) - && (key instanceof RSAPrivateKey)) - { - return new RSAPrivateKeySpec( - ((RSAPrivateCrtKey) key).getModulus(), - ((RSAPrivateCrtKey) key).getPrivateExponent()); - } - if (keySpec.isAssignableFrom(RSAPublicKeySpec.class) - && (key instanceof RSAPublicKey)) - { - return new RSAPublicKeySpec( - ((RSAPrivateCrtKey) key).getModulus(), - ((RSAPrivateCrtKey) key).getPublicExponent()); - } - if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class) - && key.getFormat().equalsIgnoreCase("PKCS#8")) - { - return new PKCS8EncodedKeySpec(key.getEncoded()); - } - if (keySpec.isAssignableFrom(X509EncodedKeySpec.class) - && key.getFormat().equalsIgnoreCase("X.509")) - { - return new X509EncodedKeySpec(key.getEncoded()); - } - throw new InvalidKeySpecException(); - } - - protected Key engineTranslateKey(Key key) throws InvalidKeyException - { - if (key instanceof RSAPrivateCrtKey) - { - return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec( - ((RSAPrivateCrtKey) key).getModulus(), - ((RSAPrivateCrtKey) key).getPublicExponent(), - ((RSAPrivateCrtKey) key).getPrivateExponent(), - ((RSAPrivateCrtKey) key).getPrimeP(), - ((RSAPrivateCrtKey) key).getPrimeQ(), - ((RSAPrivateCrtKey) key).getPrimeExponentP(), - ((RSAPrivateCrtKey) key).getPrimeExponentQ(), - ((RSAPrivateCrtKey) key).getCrtCoefficient())); - } - if (key instanceof RSAPrivateKey) - { - return new GnuRSAPrivateKey(new RSAPrivateCrtKeySpec( - ((RSAPrivateKey) key).getModulus(), null, - ((RSAPrivateKey) key).getPrivateExponent(), null, - null, null, null, null)); - } - if (key instanceof RSAPublicKey) - { - return new GnuRSAPublicKey(new RSAPublicKeySpec( - ((RSAPrivateCrtKey) key).getModulus(), - ((RSAPrivateCrtKey) key).getPublicExponent())); - } - throw new InvalidKeyException(); - } -} diff --git a/libjava/classpath/gnu/java/security/provider/SHA.java b/libjava/classpath/gnu/java/security/provider/SHA.java deleted file mode 100644 index e3b09bc5603..00000000000 --- a/libjava/classpath/gnu/java/security/provider/SHA.java +++ /dev/null @@ -1,242 +0,0 @@ -/* SHA.java -- Class implementing the SHA-1 algorithm as specified in [1]. - Copyright (C) 1999, 2000, 2002 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import java.security.MessageDigest; - -/** - This class implements the SHA-1 algorithm as described in [1]. - - [1] Federal Information Processing Standards Publication 180-1. - Specifications for the Secure Hash Standard. April 17, 1995. - - @see java.security.MessageDigest -*/ -public class SHA extends MessageDigest implements Cloneable -{ - public SHA () - { - super("SHA"); - engineReset (); - } - - public int engineGetDigestLength() - { - return 20; - } - - public void engineUpdate (byte b) - { - int i = ((int)bytecount) & 0x3f; //wgs - int shift = (3 - i % 4) << 3; - int idx = i / 4; - - i = (int)b; - W[idx] = (W[idx] & ~(0xff << shift)) | ((i & 0xff) << shift); - - // if we've filled up a block, then process it - if (((++bytecount) & 0x3f) == 0) - munch (); - } - - // This could be optimized. - public void engineUpdate (byte bytes[], int off, int len) - { - if (len < 0) - throw new ArrayIndexOutOfBoundsException (); - - int end = off + len; - while (off < end) - engineUpdate (bytes[off++]); - } - - public void engineReset () - { - bytecount = 0; - // magic numbers from [1] p. 10. - H0 = 0x67452301; - H1 = 0xefcdab89; - H2 = 0x98badcfe; - H3 = 0x10325476; - H4 = 0xc3d2e1f0; - } - - public byte[] engineDigest () - { - long bitcount = bytecount << 3; - engineUpdate ((byte)0x80); // 10000000 in binary; the start of the padding - - // add the rest of the padding to fill this block out, but leave 8 - // bytes to put in the original bytecount - while ((bytecount & 0x3f) != 56) - engineUpdate ((byte)0); - - // add the length of the original, unpadded block to the end of - // the padding - W[14] = (int)(bitcount >>> 32); - W[15] = (int)bitcount; - bytecount += 8; - - // digest the fully padded block - munch (); - - 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}; - - engineReset (); - return result; - } - - // Process a single block. This is pretty much copied verbatim from - // [1] pp. 9, 10. - private void munch () - { - for (int t = 16; t < 80; ++ t) - { - int Wt = W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]; - W[t] = Wt << 1 | Wt >>> 31; - } - - int A = H0; - int B = H1; - int C = H2; - int D = H3; - int E = H4; - - for (int t = 0; t < 20; ++ t) - { - int TEMP = (A << 5 | A >>> 27) // S^5(A) - + ((B & C) | (~B & D)) // f_t(B,C,D) - + E + W[t] - + 0x5a827999; // K_t - - E = D; - D = C; - C = B << 30 | B >>> 2; // S^30(B) - B = A; - A = TEMP; - } - - for (int t = 20; t < 40; ++ t) - { - int TEMP = (A << 5 | A >>> 27) // S^5(A) - + (B ^ C ^ D) // f_t(B,C,D) - + E + W[t] - + 0x6ed9eba1; // K_t - - E = D; - D = C; - C = B << 30 | B >>> 2; // S^30(B) - B = A; - A = TEMP; - } - - for (int t = 40; t < 60; ++ t) - { - int TEMP = (A << 5 | A >>> 27) // S^5(A) - + (B & C | B & D | C & D) // f_t(B,C,D) - + E + W[t] - + 0x8f1bbcdc; // K_t - - E = D; - D = C; - C = B << 30 | B >>> 2; // S^30(B) - B = A; - A = TEMP; - } - - for (int t = 60; t < 80; ++ t) - { - int TEMP = (A << 5 | A >>> 27) // S^5(A) - + (B ^ C ^ D) // f_t(B,C,D) - + E + W[t] - + 0xca62c1d6; // K_t - - E = D; - D = C; - C = B << 30 | B >>> 2; // S^30(B) - B = A; - A = TEMP; - } - - H0 += A; - H1 += B; - H2 += C; - H3 += D; - H4 += E; - - // Reset W by clearing it. - for (int t = 0; t < 80; ++ t) - W[t] = 0; - } - - public Object clone () - { - return new SHA (this); - } - - private SHA (SHA copy) - { - this (); - bytecount = copy.bytecount; - H0 = copy.H0; - H1 = copy.H1; - H2 = copy.H2; - H3 = copy.H3; - H4 = copy.H4; - System.arraycopy (copy.W, 0, W, 0, 80); - } - - private final int W[] = new int[80]; - private long bytecount; - private int H0; - private int H1; - private int H2; - private int H3; - private int H4; -} diff --git a/libjava/classpath/gnu/java/security/provider/SHA1PRNG.java b/libjava/classpath/gnu/java/security/provider/SHA1PRNG.java deleted file mode 100644 index e4058e3079b..00000000000 --- a/libjava/classpath/gnu/java/security/provider/SHA1PRNG.java +++ /dev/null @@ -1,137 +0,0 @@ -/* SHA1PRNG.java --- Secure Random SPI SHA1PRNG - Copyright (C) 1999, 2001, 2003, 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ - - -package gnu.java.security.provider; - -import java.io.Serializable; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandomSpi; -import java.util.Random; - -public class SHA1PRNG extends SecureRandomSpi implements Serializable -{ - MessageDigest digest; - byte seed[]; - byte data[]; - int seedpos; - int datapos; - private boolean seeded = false; // set to true when we seed this - /** - * The size of seed. - */ - private static final int SEED_SIZE = 20; - /** - * The size of data. - */ - private static final int DATA_SIZE = 40; - - /** - * Create a new SHA-1 pseudo-random number generator. - */ - public SHA1PRNG() - { - try { - digest = MessageDigest.getInstance("SHA"); - } catch ( NoSuchAlgorithmException nsae) { -// System.out.println("Failed to find SHA Message Digest: " + nsae); -// nsae.printStackTrace(); - throw new InternalError ("no SHA implementation found"); - } - - seed = new byte[SEED_SIZE]; - seedpos = 0; - data = new byte[DATA_SIZE]; - datapos = SEED_SIZE; // try to force hashing a first block - } - - public void engineSetSeed(byte[] seed) - { - for(int i = 0; i < seed.length; i++) - this.seed[seedpos++ % SEED_SIZE] ^= seed[i]; - seedpos %= SEED_SIZE; - - } - - public void engineNextBytes(byte[] bytes) - { - ensureIsSeeded (); - int loc = 0; - while (loc < bytes.length) - { - int copy = Math.min (bytes.length - loc, SEED_SIZE - datapos); - - if (copy > 0) - { - System.arraycopy (data, datapos, bytes, loc, copy); - datapos += copy; - loc += copy; - } - else - { - // No data ready for copying, so refill our buffer. - System.arraycopy( seed, 0, data, SEED_SIZE, SEED_SIZE); - byte[] digestdata = digest.digest( data ); - System.arraycopy( digestdata, 0, data, 0, SEED_SIZE); - datapos = 0; - } - } - } - - public byte[] engineGenerateSeed(int numBytes) - { - byte tmp[] = new byte[numBytes]; - - engineNextBytes( tmp ); - return tmp; - } - - private void ensureIsSeeded() - { - if (!seeded) - { - new Random(0L).nextBytes(seed); - - byte[] digestdata = digest.digest(data); - System.arraycopy(digestdata, 0, data, 0, SEED_SIZE); - - seeded = true; - } - } - -} diff --git a/libjava/classpath/gnu/java/security/sig/BaseSignature.java b/libjava/classpath/gnu/java/security/sig/BaseSignature.java new file mode 100644 index 00000000000..dd964d4819d --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/BaseSignature.java @@ -0,0 +1,261 @@ +/* BaseSignature.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.sig; + +import gnu.java.security.hash.IMessageDigest; +import gnu.java.security.prng.IRandom; +import gnu.java.security.prng.LimitReachedException; +import gnu.java.security.util.PRNG; + +import java.security.PrivateKey; +import java.security.PublicKey; +import java.util.Map; +import java.util.Random; + +/** + * <p>A base abstract class to facilitate implementations of concrete + * Signatures.</p> + */ +public abstract class BaseSignature implements ISignature +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** The canonical name of this signature scheme. */ + protected String schemeName; + + /** The underlying message digest instance for this signature scheme. */ + protected IMessageDigest md; + + /** The public key to use when verifying signatures. */ + protected PublicKey publicKey; + + /** The private key to use when generating signatures (signing). */ + protected PrivateKey privateKey; + + /** The optional {@link Random} instance to use. */ + private Random rnd; + + /** The optional {@link IRandom} instance to use. */ + private IRandom irnd; + + /** Our default source of randomness. */ + private PRNG prng = null; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Trivial constructor. + * + * @param schemeName the name of this signature scheme. + * @param md the underlying instance of the message digest algorithm. + * @throws IllegalArgumentException if the designated hash instance is + * <code>null</code>. + */ + protected BaseSignature(String schemeName, IMessageDigest md) + { + super(); + + this.schemeName = schemeName; + if (md == null) + throw new IllegalArgumentException("Message digest MUST NOT be null"); + + this.md = md; + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // gnu.crypto.sig.ISignature interface implementation ---------------------- + + public String name() + { + return schemeName + "-" + md.name(); + } + + public void setupVerify(Map attributes) throws IllegalArgumentException + { + setup(attributes); + + // do we have a public key? + PublicKey key = (PublicKey) attributes.get(VERIFIER_KEY); + if (key != null) + { + setupForVerification(key); + } + } + + public void setupSign(Map attributes) throws IllegalArgumentException + { + setup(attributes); + + // do we have a private key? + PrivateKey key = (PrivateKey) attributes.get(SIGNER_KEY); + if (key != null) + { + setupForSigning(key); + } + } + + public void update(byte b) + { + if (md == null) + { + throw new IllegalStateException(); + } + md.update(b); + } + + public void update(byte[] b, int off, int len) + { + if (md == null) + { + throw new IllegalStateException(); + } + md.update(b, off, len); + } + + public Object sign() + { + if (md == null || privateKey == null) + { + throw new IllegalStateException(); + } + + return generateSignature(); + } + + public boolean verify(Object sig) + { + if (md == null || publicKey == null) + { + throw new IllegalStateException(); + } + + return verifySignature(sig); + } + + // abstract methods to be implemented by concrete subclasses --------------- + + public abstract Object clone(); + + protected abstract void setupForVerification(PublicKey key) + throws IllegalArgumentException; + + protected abstract void setupForSigning(PrivateKey key) + throws IllegalArgumentException; + + protected abstract Object generateSignature() throws IllegalStateException; + + protected abstract boolean verifySignature(Object signature) + throws IllegalStateException; + + // Other instance methods -------------------------------------------------- + + /** Initialises the internal fields of this instance. */ + protected void init() + { + md.reset(); + rnd = null; + irnd = null; + publicKey = null; + privateKey = null; + } + + /** + * <p>Fills the designated byte array with random data.</p> + * + * @param buffer the byte array to fill with random data. + */ + protected void nextRandomBytes(byte[] buffer) + { + if (rnd != null) + { + rnd.nextBytes(buffer); + } + else if (irnd != null) + { + try + { + irnd.nextBytes(buffer, 0, buffer.length); + } + catch (IllegalStateException x) + { + throw new RuntimeException("nextRandomBytes(): " + + String.valueOf(x)); + } + catch (LimitReachedException x) + { + throw new RuntimeException("nextRandomBytes(): " + + String.valueOf(x)); + } + } + else + getDefaultPRNG().nextBytes(buffer); + } + + private void setup(Map attributes) + { + init(); + + // do we have a Random or SecureRandom, or should we use our own? + Object obj = attributes.get(SOURCE_OF_RANDOMNESS); + if (obj instanceof Random) + { + rnd = (Random) obj; + } + else if (obj instanceof IRandom) + { + irnd = (IRandom) obj; + } + } + + private PRNG getDefaultPRNG() + { + if (prng == null) + prng = PRNG.getInstance(); + + return prng; + } +} diff --git a/libjava/classpath/gnu/java/security/sig/ISignature.java b/libjava/classpath/gnu/java/security/sig/ISignature.java new file mode 100644 index 00000000000..77653ee3722 --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/ISignature.java @@ -0,0 +1,169 @@ +/* ISignature.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.sig; + +import java.util.Map; + +/** + * <p>The visible methods of every signature-with-appendix scheme.</p> + * + * <p>The Handbook of Applied Cryptography (HAC), by A. Menezes & al. states: + * "Digital signature schemes which require the message as input to the + * verification algorithm are called <i>digital signature schemes with + * appendix</i>. ... They rely on cryptographic hash functions rather than + * customised redundancy functions, and are less prone to existential forgery + * attacks."</p> + * + * <p>References:</p> + * <ol> + * <li><a href="http://www.cacr.math.uwaterloo.ca/hac/">Handbook of Applied + * Cryptography</a>, Alfred J. Menezes, Paul C. van Oorschot and Scott A. + * Vanstone. Section 11.2.2 Digital signature schemes with appendix.</li> + * </ol> + * + * @version $Revision: 1.1 $ + */ +public interface ISignature extends Cloneable +{ + + // Constants + // ------------------------------------------------------------------------- + + /** Property name of the verifier's public key. */ + public static final String VERIFIER_KEY = "gnu.crypto.sig.public.key"; + + /** Property name of the signer's private key. */ + public static final String SIGNER_KEY = "gnu.crypto.sig.private.key"; + + /** + * Property name of an optional {@link java.security.SecureRandom}, + * {@link java.util.Random}, or {@link gnu.crypto.prng.IRandom} instance to + * use. The default is to use a classloader singleton from + * {@link gnu.crypto.util.PRNG}. + */ + public static final String SOURCE_OF_RANDOMNESS = "gnu.crypto.sig.prng"; + + // Methods + // ------------------------------------------------------------------------- + + /** + * <p>Returns the canonical name of this signature scheme.</p> + * + * @return the canonical name of this instance. + */ + String name(); + + /** + * <p>Initialises this instance for signature verification.</p> + * + * @param attributes the attributes to use for setting up this instance. + * @throws IllegalArgumentException if the designated public key is not + * appropriate for this signature scheme. + * @see #SOURCE_OF_RANDOMNESS + * @see #VERIFIER_KEY + */ + void setupVerify(Map attributes) throws IllegalArgumentException; + + /** + * <p>Initialises this instance for signature generation.</p> + * + * @param attributes the attributes to use for setting up this instance. + * @throws IllegalArgumentException if the designated private key is not + * appropriate for this signature scheme. + * @see #SOURCE_OF_RANDOMNESS + * @see #SIGNER_KEY + */ + void setupSign(Map attributes) throws IllegalArgumentException; + + /** + * <p>Digests one byte of a message for signing or verification purposes.</p> + * + * @param b the message byte to digest. + * @throws IllegalStateException if this instance was not setup for + * signature generation/verification. + */ + void update(byte b) throws IllegalStateException; + + /** + * <p>Digests a sequence of bytes from a message for signing or verification + * purposes.</p> + * + * @param buffer the byte sequence to consider. + * @param offset the byte poisition in <code>buffer</code> of the first byte + * to consider. + * @param length the number of bytes in <code>buffer</code> starting from the + * byte at index <code>offset</code> to digest. + * @throws IllegalStateException if this instance was not setup for + * signature generation/verification. + */ + void update(byte[] buffer, int offset, int length) + throws IllegalStateException; + + /** + * <p>Terminates a signature generation phase by digesting and processing the + * context of the underlying message digest algorithm instance.</p> + * + * @return a {@link Object} representing the native output of the signature + * scheme implementation. + * @throws IllegalStateException if this instance was not setup for + * signature generation. + */ + Object sign() throws IllegalStateException; + + /** + * <p>Terminates a signature verification phase by digesting and processing + * the context of the underlying message digest algorithm instance.</p> + * + * @param signature a native signature object previously generated by an + * invocation of the <code>sign()</code> method. + * @return <code>true</code> iff the outpout of the verification phase + * confirms that the designated signature object has been generated using the + * corresponding public key of the recepient. + * @throws IllegalStateException if this instance was not setup for + * signature verification. + */ + boolean verify(Object signature) throws IllegalStateException; + + /** + * <p>Returns a clone copy of this instance.</p> + * + * @return a clone copy of this instance. + */ + Object clone(); +} diff --git a/libjava/classpath/gnu/java/security/sig/ISignatureCodec.java b/libjava/classpath/gnu/java/security/sig/ISignatureCodec.java new file mode 100644 index 00000000000..119eca5fd0d --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/ISignatureCodec.java @@ -0,0 +1,68 @@ +/* ISignatureCodec.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.sig; + +import gnu.java.security.Registry; + +/** + * <p>The visible methods of an object that knows how to encode and decode + * cryptographic signatures. Codecs are useful for (a) externalising signature + * output data for storage and on-the-wire transmission, as well as (b) re- + * creating their internal Java representation from external sources.</p> + * + * @version $Revision: 1.1 $ + */ +public interface ISignatureCodec +{ + + // Constants + // ------------------------------------------------------------------------- + + /** Constant identifying the <i>Raw</i> encoding format. */ + int RAW_FORMAT = Registry.RAW_ENCODING_ID; + + // Method(s) + // ------------------------------------------------------------------------- + + int getFormatID(); + + byte[] encodeSignature(Object signature); + + Object decodeSignature(byte[] input); +} diff --git a/libjava/classpath/gnu/java/security/sig/SignatureCodecFactory.java b/libjava/classpath/gnu/java/security/sig/SignatureCodecFactory.java new file mode 100644 index 00000000000..c5b2ccd4bc8 --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/SignatureCodecFactory.java @@ -0,0 +1,226 @@ +/* SignatureCodecFactory.java -- Factory to instantiate Signature codecs + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.sig; + +import gnu.java.security.Registry; +import gnu.java.security.hash.HashFactory; +import gnu.java.security.sig.dss.DSSSignatureRawCodec; +import gnu.java.security.sig.dss.DSSSignatureX509Codec; +import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureRawCodec; +import gnu.java.security.sig.rsa.RSAPKCS1V1_5SignatureX509Codec; +import gnu.java.security.sig.rsa.RSAPSSSignatureRawCodec; +import gnu.java.security.util.FormatUtil; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * A <i>Factory</i> class to instantiate Signature codecs. + */ +public class SignatureCodecFactory +{ + private static Set names; + + /** Trivial constructor to enforce Singleton pattern. */ + private SignatureCodecFactory() + { + super(); + } + + /** + * Returns the appropriate codec given a composed signature algorithm and an + * encoding format. A composed name is formed by the concatenation of the + * canonical signature algorithm name, the forward slash character + * <code>/</code> and the canonical name of the encoding format. + * <p> + * When the encoding format name is missing, the Raw encoding format is + * assumed. When this is the case the trailing forward slash is discarded from + * the name. + * + * @param name the case-insensitive, possibly composed, signature codec name. + * @return an instance of the signaturecodec, or <code>null</code> if none + * found. + */ + public static ISignatureCodec getInstance(String name) + { + if (name == null) + return null; + + name = name.trim(); + if (name.length() == 0) + return null; + + if (name.startsWith("/")) + return null; + + if (name.endsWith("/")) + return getInstance(name.substring(0, name.length() - 1), + Registry.RAW_ENCODING_ID); + + int i = name.indexOf("/"); + if (i == - 1) + return getInstance(name, Registry.RAW_ENCODING_ID); + + String sigName = name.substring(0, i); + String formatName = name.substring(i + 1); + return getInstance(sigName, formatName); + } + + /** + * Returns an instance of a signature codec given the canonical name of the + * signature algorithm, and that of the encoding format. + * + * @param name the case-insensitive signature algorithm name. + * @param format the name of the format to use when encodigng/decoding + * signatures generated by the named algorithm. + * @return an instance of the signature codec, or <code>null</code> if none + * found. + */ + public static ISignatureCodec getInstance(String name, String format) + { + int formatID = FormatUtil.getFormatID(format); + if (formatID == 0) + return null; + + return getInstance(name, formatID); + } + + /** + * Returns an instance of a signature codec given the canonical name of the + * signature algorithm, and the identifier of the format to use when + * encoding/decoding signatures generated by that algorithm. + * + * @param name the case-insensitive signature algorithm name. + * @param formatID the identifier of the format to use when encoding / + * decoding signatures generated by the designated algorithm. + * @return an instance of the signature codec, or <code>null</code> if none + * found. + */ + public static ISignatureCodec getInstance(String name, int formatID) + { + if (name == null) + return null; + + name = name.trim(); + switch (formatID) + { + case Registry.RAW_ENCODING_ID: + return getRawCodec(name); + case Registry.X509_ENCODING_ID: + return getX509Codec(name); + } + + return null; + } + + /** + * Returns a {@link Set} of supported signature codec names. + * + * @return a {@link Set} of the names of supported signature codec (Strings). + */ + public static synchronized final Set getNames() + { + if (names == null) + { + HashSet hs = new HashSet(); + hs.add(Registry.DSS_SIG + "/" + Registry.RAW_ENCODING_SHORT_NAME); + hs.add(Registry.DSS_SIG + "/" + Registry.X509_ENCODING_SORT_NAME); + Set hashNames = HashFactory.getNames(); + for (Iterator it = hashNames.iterator(); it.hasNext();) + { + String mdName = (String) it.next(); + String name = Registry.RSA_PKCS1_V1_5_SIG + "-" + mdName; + hs.add(name + "/" + Registry.RAW_ENCODING_SHORT_NAME); + hs.add(name + "/" + Registry.X509_ENCODING_SORT_NAME); + name = Registry.RSA_PSS_SIG + "-" + mdName; + hs.add(name + "/" + Registry.RAW_ENCODING_SHORT_NAME); + } + + names = Collections.unmodifiableSet(hs); + } + + return names; + } + + /** + * @param name the trimmed name of a signature algorithm. + * @return a Raw format codec for the designated signature algorithm, or + * <code>null</code> if none exists. + */ + private static ISignatureCodec getRawCodec(String name) + { + ISignatureCodec result = null; + if (name.equalsIgnoreCase(Registry.DSA_SIG) + || name.equalsIgnoreCase(Registry.DSS_SIG)) + result = new DSSSignatureRawCodec(); + else + { + name = name.toLowerCase(); + if (name.startsWith(Registry.RSA_PKCS1_V1_5_SIG)) + result = new RSAPKCS1V1_5SignatureRawCodec(); + else if (name.startsWith(Registry.RSA_PSS_SIG)) + result = new RSAPSSSignatureRawCodec(); + } + + return result; + } + + /** + * @param name the trimmed name of a signature algorithm. + * @return a X.509 format codec for the designated signature algorithm, or + * <code>null</code> if none exists. + */ + private static ISignatureCodec getX509Codec(String name) + { + ISignatureCodec result = null; + if (name.equalsIgnoreCase(Registry.DSA_SIG) + || name.equalsIgnoreCase(Registry.DSS_SIG)) + result = new DSSSignatureX509Codec(); + else + { + name = name.toLowerCase(); + if (name.startsWith(Registry.RSA_PKCS1_V1_5_SIG)) + result = new RSAPKCS1V1_5SignatureX509Codec(); + } + + return result; + } +} diff --git a/libjava/classpath/gnu/java/security/sig/SignatureFactory.java b/libjava/classpath/gnu/java/security/sig/SignatureFactory.java new file mode 100644 index 00000000000..d5bd728ad8a --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/SignatureFactory.java @@ -0,0 +1,113 @@ +/* SignatureFactory.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.sig; + +import gnu.java.security.Registry; +import gnu.java.security.sig.dss.DSSSignature; +import gnu.java.security.sig.rsa.RSASignatureFactory; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * A Factory to instantiate signature-with-appendix handlers. + */ +public class SignatureFactory +{ + private static Set names; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial constructor to enforce Singleton pattern. */ + private SignatureFactory() + { + super(); + } + + // Class methods + // ------------------------------------------------------------------------- + + /** + * Returns an instance of a signature-with-appendix scheme given its name. + * + * @param ssa the case-insensitive signature-with-appendix scheme name. + * @return an instance of the scheme, or <code>null</code> if none found. + */ + public static final ISignature getInstance(String ssa) + { + if (ssa == null) + { + return null; + } + + ssa = ssa.trim(); + ssa = ssa.toLowerCase(); + ISignature result = null; + if (ssa.equalsIgnoreCase(Registry.DSA_SIG) || ssa.equals(Registry.DSS_SIG)) + { + result = new DSSSignature(); + } + else if (ssa.startsWith(Registry.RSA_SIG_PREFIX)) + result = RSASignatureFactory.getInstance(ssa); + + return result; + } + + /** + * Returns a {@link Set} of signature-with-appendix scheme names supported + * by this <i>Factory</i>. + * + * @return a {@link Set} of signature-with-appendix scheme names (Strings). + */ + public static synchronized final Set getNames() + { + if (names == null) + { + HashSet hs = new HashSet(); + hs.add(Registry.DSS_SIG); + hs.addAll(RSASignatureFactory.getNames()); + + names = Collections.unmodifiableSet(hs); + } + + return names; + } +} diff --git a/libjava/classpath/gnu/java/security/sig/dss/DSSSignature.java b/libjava/classpath/gnu/java/security/sig/dss/DSSSignature.java new file mode 100644 index 00000000000..6bedfaefa3a --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/dss/DSSSignature.java @@ -0,0 +1,347 @@ +/* DSSSignature.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.sig.dss; + +import gnu.java.security.Registry; +import gnu.java.security.hash.IMessageDigest; +import gnu.java.security.hash.Sha160; +import gnu.java.security.prng.IRandom; +import gnu.java.security.sig.BaseSignature; +import gnu.java.security.sig.ISignature; + +import java.math.BigInteger; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.interfaces.DSAPrivateKey; +import java.security.interfaces.DSAPublicKey; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; + +/** + * <p>The DSS (Digital Signature Standard) algorithm makes use of the following + * parameters:</p> + * + * <ol> + * <li>p: A prime modulus, where <code>2<sup>L-1</sup> < p < 2<sup>L</sup> + * </code> for <code>512 <= L <= 1024</code> and <code>L</code> a + * multiple of <code>64</code>.</li> + * <li>q: A prime divisor of <code>p - 1</code>, where <code>2<sup>159</sup> + * < q < 2<sup>160</sup></code>.</li> + * <li>g: Where <code>g = h<sup>(p-1)</sup>/q mod p</code>, where + * <code>h</code> is any integer with <code>1 < h < p - 1</code> such + * that <code>h<sup> (p-1)</sup>/q mod p > 1</code> (<code>g</code> has order + * <code>q mod p</code>).</li> + * <li>x: A randomly or pseudorandomly generated integer with <code>0 < x + * < q</code>.</li> + * <li>y: <code>y = g<sup>x</sup> mod p</code>.</li> + * <li>k: A randomly or pseudorandomly generated integer with <code>0 < k + * < q</code>.</li> + * </ol> + * + * <p>The integers <code>p</code>, <code>q</code>, and <code>g</code> can be + * public and can be common to a group of users. A user's private and public + * keys are <code>x</code> and <code>y</code>, respectively. They are normally + * fixed for a period of time. Parameters <code>x</code> and <code>k</code> are + * used for signature generation only, and must be kept secret. Parameter + * <code>k</code> must be regenerated for each signature.</p> + * + * <p>The signature of a message <code>M</code> is the pair of numbers <code>r</code> + * and <code>s</code> computed according to the equations below:</p> + * + * <ul> + * <li><code>r = (g<sup>k</sup> mod p) mod q</code> and</li> + * <li><code>s = (k<sup>-1</sup>(SHA(M) + xr)) mod q</code>.</li> + * </ul> + * + * <p>In the above, <code>k<sup>-1</sup></code> is the multiplicative inverse of + * <code>k</code>, <code>mod q</code>; i.e., <code>(k<sup>-1</sup> k) mod q = 1 + * </code> and <code>0 < k-1 < q</code>. The value of <code>SHA(M)</code> + * is a 160-bit string output by the Secure Hash Algorithm specified in FIPS 180. + * For use in computing <code>s</code>, this string must be converted to an + * integer.</p> + * + * <p>As an option, one may wish to check if <code>r == 0</code> or <code>s == 0 + * </code>. If either <code>r == 0</code> or <code>s == 0</code>, a new value + * of <code>k</code> should be generated and the signature should be + * recalculated (it is extremely unlikely that <code>r == 0</code> or <code>s == + * 0</code> if signatures are generated properly).</p> + * + * <p>The signature is transmitted along with the message to the verifier.</p> + * + * <p>References:</p> + * <ol> + * <li><a href="http://www.itl.nist.gov/fipspubs/fip186.htm">Digital + * Signature Standard (DSS)</a>, Federal Information Processing Standards + * Publication 186. National Institute of Standards and Technology.</li> + * </ol> + * + * @version $Revision: 1.1 $ + */ +public class DSSSignature extends BaseSignature +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial 0-arguments constructor. */ + public DSSSignature() + { + super(Registry.DSS_SIG, new Sha160()); + } + + /** Private constructor for cloning purposes. */ + private DSSSignature(DSSSignature that) + { + this(); + + this.publicKey = that.publicKey; + this.privateKey = that.privateKey; + this.md = (IMessageDigest) that.md.clone(); + } + + // Class methods + // ------------------------------------------------------------------------- + + public static final BigInteger[] sign(final DSAPrivateKey k, final byte[] h) + { + final DSSSignature sig = new DSSSignature(); + final Map attributes = new HashMap(); + attributes.put(ISignature.SIGNER_KEY, k); + sig.setupSign(attributes); + + return sig.computeRS(h); + } + + public static final BigInteger[] sign(final DSAPrivateKey k, final byte[] h, + Random rnd) + { + final DSSSignature sig = new DSSSignature(); + final Map attributes = new HashMap(); + attributes.put(ISignature.SIGNER_KEY, k); + if (rnd != null) + { + attributes.put(ISignature.SOURCE_OF_RANDOMNESS, rnd); + } + sig.setupSign(attributes); + + return sig.computeRS(h); + } + + public static final BigInteger[] sign(final DSAPrivateKey k, final byte[] h, + IRandom irnd) + { + final DSSSignature sig = new DSSSignature(); + final Map attributes = new HashMap(); + attributes.put(ISignature.SIGNER_KEY, k); + if (irnd != null) + { + attributes.put(ISignature.SOURCE_OF_RANDOMNESS, irnd); + } + sig.setupSign(attributes); + + return sig.computeRS(h); + } + + public static final boolean verify(final DSAPublicKey k, final byte[] h, + final BigInteger[] rs) + { + final DSSSignature sig = new DSSSignature(); + final Map attributes = new HashMap(); + attributes.put(ISignature.VERIFIER_KEY, k); + sig.setupVerify(attributes); + + return sig.checkRS(rs, h); + } + + // Implementation of abstract methods in superclass + // ------------------------------------------------------------------------- + + public Object clone() + { + return new DSSSignature(this); + } + + protected void setupForVerification(PublicKey k) + throws IllegalArgumentException + { + if (!(k instanceof DSAPublicKey)) + { + throw new IllegalArgumentException(); + } + this.publicKey = k; + } + + protected void setupForSigning(PrivateKey k) throws IllegalArgumentException + { + if (!(k instanceof DSAPrivateKey)) + { + throw new IllegalArgumentException(); + } + this.privateKey = k; + } + + protected Object generateSignature() throws IllegalStateException + { + // BigInteger p = ((DSAPrivateKey) privateKey).getParams().getP(); + // BigInteger q = ((DSAPrivateKey) privateKey).getParams().getQ(); + // BigInteger g = ((DSAPrivateKey) privateKey).getParams().getG(); + // BigInteger x = ((DSAPrivateKey) privateKey).getX(); + // BigInteger m = new BigInteger(1, md.digest()); + // BigInteger k, r, s; + // + // byte[] kb = new byte[20]; // we'll use 159 bits only + // while (true) { + // this.nextRandomBytes(kb); + // k = new BigInteger(1, kb); + // k.clearBit(159); + // r = g.modPow(k, p).mod(q); + // if (r.equals(BigInteger.ZERO)) { + // continue; + // } + // s = m.add(x.multiply(r)).multiply(k.modInverse(q)).mod(q); + // if (s.equals(BigInteger.ZERO)) { + // continue; + // } + // break; + // } + final BigInteger[] rs = computeRS(md.digest()); + + // return encodeSignature(r, s); + return encodeSignature(rs[0], rs[1]); + } + + protected boolean verifySignature(Object sig) throws IllegalStateException + { + final BigInteger[] rs = decodeSignature(sig); + // BigInteger r = rs[0]; + // BigInteger s = rs[1]; + // + // BigInteger g = ((DSAPublicKey) publicKey).getParams().getG(); + // BigInteger p = ((DSAPublicKey) publicKey).getParams().getP(); + // BigInteger q = ((DSAPublicKey) publicKey).getParams().getQ(); + // BigInteger y = ((DSAPublicKey) publicKey).getY(); + // BigInteger w = s.modInverse(q); + // + // byte bytes[] = md.digest(); + // BigInteger u1 = w.multiply(new BigInteger(1, bytes)).mod(q); + // BigInteger u2 = r.multiply(w).mod(q); + // + // BigInteger v = g.modPow(u1, p).multiply(y.modPow(u2, p)).mod(p).mod(q); + // return v.equals(r); + return checkRS(rs, md.digest()); + } + + // Other instance methods + // ------------------------------------------------------------------------- + + /** + * Returns the output of a signature generation phase.<p> + * + * @return an object encapsulating the DSS signature pair <code>r</code> and + * <code>s</code>. + */ + private Object encodeSignature(BigInteger r, BigInteger s) + { + return new BigInteger[] { r, s }; + } + + /** + * Returns the output of a previously generated signature object as a pair + * of {@link java.math.BigInteger}.<p> + * + * @return the DSS signature pair <code>r</code> and <code>s</code>. + */ + private BigInteger[] decodeSignature(Object signature) + { + return (BigInteger[]) signature; + } + + private BigInteger[] computeRS(final byte[] digestBytes) + { + final BigInteger p = ((DSAPrivateKey) privateKey).getParams().getP(); + final BigInteger q = ((DSAPrivateKey) privateKey).getParams().getQ(); + final BigInteger g = ((DSAPrivateKey) privateKey).getParams().getG(); + final BigInteger x = ((DSAPrivateKey) privateKey).getX(); + final BigInteger m = new BigInteger(1, digestBytes); + BigInteger k, r, s; + + final byte[] kb = new byte[20]; // we'll use 159 bits only + while (true) + { + this.nextRandomBytes(kb); + k = new BigInteger(1, kb); + k.clearBit(159); + r = g.modPow(k, p).mod(q); + if (r.equals(BigInteger.ZERO)) + { + continue; + } + s = m.add(x.multiply(r)).multiply(k.modInverse(q)).mod(q); + if (s.equals(BigInteger.ZERO)) + { + continue; + } + break; + } + + return new BigInteger[] { r, s }; + } + + private boolean checkRS(final BigInteger[] rs, final byte[] digestBytes) + { + final BigInteger r = rs[0]; + final BigInteger s = rs[1]; + + final BigInteger g = ((DSAPublicKey) publicKey).getParams().getG(); + final BigInteger p = ((DSAPublicKey) publicKey).getParams().getP(); + final BigInteger q = ((DSAPublicKey) publicKey).getParams().getQ(); + final BigInteger y = ((DSAPublicKey) publicKey).getY(); + final BigInteger w = s.modInverse(q); + + final BigInteger u1 = w.multiply(new BigInteger(1, digestBytes)).mod(q); + final BigInteger u2 = r.multiply(w).mod(q); + + final BigInteger v = g.modPow(u1, p).multiply(y.modPow(u2, p)).mod(p).mod(q); + return v.equals(r); + } +} diff --git a/libjava/classpath/gnu/java/security/sig/dss/DSSSignatureRawCodec.java b/libjava/classpath/gnu/java/security/sig/dss/DSSSignatureRawCodec.java new file mode 100644 index 00000000000..02f6b1ddc41 --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/dss/DSSSignatureRawCodec.java @@ -0,0 +1,191 @@ +/* DSSSignatureRawCodec.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.sig.dss; + +import gnu.java.security.Registry; +import gnu.java.security.sig.ISignatureCodec; + +import java.io.ByteArrayOutputStream; +import java.math.BigInteger; + +/** + * <p>An object that implements the {@link ISignatureCodec} operations for the + * <i>Raw</i> format to use with DSS signatures.</p> + * + * @version $Revision: 1.1 $ + */ +public class DSSSignatureRawCodec implements ISignatureCodec +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + // implicit 0-arguments constructor + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // gnu.crypto.sig.ISignatureCodec interface implementation ----------------- + + public int getFormatID() + { + return RAW_FORMAT; + } + + /** + * <p>Returns the encoded form of the designated DSS (Digital Signature + * Standard) signature object according to the <i>Raw</i> format supported by + * this library.</p> + * + * <p>The <i>Raw</i> format for a DSA signature, in this implementation, is a + * byte sequence consisting of the following:</p> + * + * <ol> + * <li>4-byte magic consisting of the value of the literal + * {@link Registry#MAGIC_RAW_DSS_SIGNATURE},</li> + * <li>1-byte version consisting of the constant: 0x01,</li> + * <li>4-byte count of following bytes representing the DSS parameter + * <code>r</code> in internet order,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the DSS parameter <code>r</code>,</li> + * <li>4-byte count of following bytes representing the DSS parameter + * <code>s</code>,</li> + * <li>n-bytes representation of a {@link BigInteger} obtained by invoking + * the <code>toByteArray()</code> method on the DSS parameter <code>s</code>.</li> + * </ol> + * + * @param signature the signature to encode, consisting of the two DSS + * parameters <code>r</code> and <code>s</code> as a {@link java.math.BigInteger} + * array. + * @return the <i>Raw</i> format encoding of the designated signature. + * @exception IllegalArgumentException if the designated signature is not a + * DSS (Digital Signature Standard) one. + */ + public byte[] encodeSignature(Object signature) + { + BigInteger r, s; + try + { + BigInteger[] sig = (BigInteger[]) signature; + r = sig[0]; + s = sig[1]; + } + catch (Exception x) + { + throw new IllegalArgumentException("key"); + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + // magic + baos.write(Registry.MAGIC_RAW_DSS_SIGNATURE[0]); + baos.write(Registry.MAGIC_RAW_DSS_SIGNATURE[1]); + baos.write(Registry.MAGIC_RAW_DSS_SIGNATURE[2]); + baos.write(Registry.MAGIC_RAW_DSS_SIGNATURE[3]); + + // version + baos.write(0x01); + + // r + byte[] buffer = r.toByteArray(); + int length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + // s + buffer = s.toByteArray(); + length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + return baos.toByteArray(); + } + + public Object decodeSignature(byte[] k) + { + // magic + if (k[0] != Registry.MAGIC_RAW_DSS_SIGNATURE[0] + || k[1] != Registry.MAGIC_RAW_DSS_SIGNATURE[1] + || k[2] != Registry.MAGIC_RAW_DSS_SIGNATURE[2] + || k[3] != Registry.MAGIC_RAW_DSS_SIGNATURE[3]) + { + throw new IllegalArgumentException("magic"); + } + + // version + if (k[4] != 0x01) + { + throw new IllegalArgumentException("version"); + } + + int i = 5; + int l; + byte[] buffer; + + // r + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger r = new BigInteger(1, buffer); + + // s + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + buffer = new byte[l]; + System.arraycopy(k, i, buffer, 0, l); + i += l; + BigInteger s = new BigInteger(1, buffer); + + return new BigInteger[] { r, s }; + } +} diff --git a/libjava/classpath/gnu/java/security/sig/dss/DSSSignatureX509Codec.java b/libjava/classpath/gnu/java/security/sig/dss/DSSSignatureX509Codec.java new file mode 100644 index 00000000000..0fdb754a982 --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/dss/DSSSignatureX509Codec.java @@ -0,0 +1,193 @@ +/* DSSSignatureX509Codec.java -- X.509 encoder/decoder for DSS signatures + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.sig.dss; + +import gnu.java.security.Registry; +import gnu.java.security.der.DER; +import gnu.java.security.der.DERReader; +import gnu.java.security.der.DERValue; +import gnu.java.security.der.DERWriter; +import gnu.java.security.sig.ISignatureCodec; +import gnu.java.security.util.DerUtil; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.math.BigInteger; +import java.security.InvalidParameterException; +import java.util.ArrayList; + +/** + * An implementation of an {@link ISignatureCodec} that knows to encode and + * decode DSS signatures into the raw bytes which would constitute a DER-encoded + * form of the ASN.1 structure defined in RFC-2459, and RFC-2313 as described in + * the next paragraphs. + * <p> + * Digital signatures when transmitted in an X.509 certificates are encoded + * in DER (Distinguished Encoding Rules) as a BIT STRING; i.e. + * + * <pre> + * Certificate ::= SEQUENCE { + * tbsCertificate TBSCertificate, + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING + * } + * </pre> + * <p> + * The output of the encoder, and the input of the decoder, of this codec are + * then the <i>raw</i> bytes of such a BIT STRING; i.e. not the DER-encoded + * form itself. + * <p> + * RFC-2459 states that, for the Digital Signature Standard (DSS), which + * generates two MPIs, commonly called <code>r</code> and <code>s</code>, as the + * result of digitally signing a message, these two numbers will be transferred + * as the following ASN.1 structure: + * + * <pre> + * Dss-Sig-Value ::= SEQUENCE { + * r INTEGER, + * s INTEGER + * } + * </pre> + * <p> + * Client code that needs to build a DER BIT STRING <b>MUST</b> construct such + * an ASN.1 value. The following is an example of how to do this: + * <p> + * <pre> + * ... + * import gnu.java.security.der.BitString; + * import gnu.java.security.der.DER; + * import gnu.java.security.der.DERValue; + * ... + * DERValue bitString = new DERValue(DER.BIT_STRING, new BitString(sigBytes)); + * ... + * </pre> + */ +public class DSSSignatureX509Codec + implements ISignatureCodec +{ + // implicit 0-arguments constructor + + public int getFormatID() + { + return Registry.X509_ENCODING_ID; + } + + /** + * Encodes a DSS Signature output as the <i>signature</i> raw bytes which can + * be used to construct an ASN.1 DER-encoded BIT STRING as defined in the + * documentation of this class. + * + * @param signature the output of the DSS signature algorithm; i.e. the value + * returned by the invocation of + * {@link gnu.java.security.sig.ISignature#sign()} method. In the + * case of a DSS signature this is an array of two MPIs called + * <code>r</code> and <code>s</code>. + * @return the raw bytes of a DSS signature which could be then used as the + * contents of a BIT STRING as per rfc-2459. + * @throws InvalidParameterException if an exception occurs during the + * marshalling process. + */ + public byte[] encodeSignature(Object signature) + { + BigInteger[] rs = (BigInteger[]) signature; + + DERValue derR = new DERValue(DER.INTEGER, rs[0]); + DERValue derS = new DERValue(DER.INTEGER, rs[1]); + + ArrayList dssSigValue = new ArrayList(2); + dssSigValue.add(derR); + dssSigValue.add(derS); + DERValue derDssSigValue = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, + dssSigValue); + byte[] result; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try + { + DERWriter.write(baos, derDssSigValue); + result = baos.toByteArray(); + } + catch (IOException x) + { + InvalidParameterException y = new InvalidParameterException(); + y.initCause(x); + throw y; + } + + return result; + } + + /** + * Decodes a <i>signature</i> as defined in the documentation of this class. + * + * @param input the byte array to unmarshall into a valid DSS signature + * instance; i.e. an array of two MPIs. MUST NOT be null. + * @return an array of two MPIs, <code>r</code> and <code>s</code> in this + * order, decoded from the designated <code>input</code>. + * @throw InvalidParameterException if an exception occurs during the + * unmarshalling process. + */ + public Object decodeSignature(byte[] input) + { + if (input == null) + throw new InvalidParameterException("Input bytes MUST NOT be null"); + + BigInteger r, s; + DERReader der = new DERReader(input); + try + { + DERValue derDssSigValue = der.read(); + DerUtil.checkIsConstructed(derDssSigValue, "Wrong Dss-Sig-Value field"); + + DERValue val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong R field"); + r = (BigInteger) val.getValue(); + val = der.read(); + DerUtil.checkIsBigInteger(val, "Wrong S field"); + s = (BigInteger) val.getValue(); + } + catch (IOException x) + { + InvalidParameterException y = new InvalidParameterException(); + y.initCause(x); + throw y; + } + + return new BigInteger[] { r, s }; + } +} diff --git a/libjava/classpath/gnu/java/security/sig/rsa/EME_PKCS1_V1_5.java b/libjava/classpath/gnu/java/security/sig/rsa/EME_PKCS1_V1_5.java new file mode 100644 index 00000000000..efe580d5167 --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/rsa/EME_PKCS1_V1_5.java @@ -0,0 +1,306 @@ +/* EME_PKCS1_V1_5.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.sig.rsa; + +import gnu.java.security.prng.IRandom; +import gnu.java.security.prng.LimitReachedException; +import gnu.java.security.util.PRNG; + +import java.io.ByteArrayOutputStream; +import java.security.interfaces.RSAKey; +import java.util.Random; + +/** + * <p>An implementation of the EME-PKCS1-V1.5 encoding and decoding methods.</p> + * + * <p>EME-PKCS1-V1.5 is parameterised by the entity <code>k</code> which is the + * byte count of an RSA public shared modulus.</p> + * + * <p>References:</p> + * <ol> + * <li><a href="http://www.ietf.org/rfc/rfc3447.txt">Public-Key Cryptography + * Standards (PKCS) #1:</a><br> + * RSA Cryptography Specifications Version 2.1.<br> + * Jakob Jonsson and Burt Kaliski.</li> + * </ol> + */ +public class EME_PKCS1_V1_5 +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + private int k; + + private ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + /** Our default source of randomness. */ + private PRNG prng = PRNG.getInstance(); + + // Constructor(s) + // ------------------------------------------------------------------------- + + private EME_PKCS1_V1_5(final int k) + { + super(); + + this.k = k; + } + + // Class methods + // ------------------------------------------------------------------------- + + public static final EME_PKCS1_V1_5 getInstance(final int k) + { + if (k < 0) + { + throw new IllegalArgumentException("k must be a positive integer"); + } + return new EME_PKCS1_V1_5(k); + } + + public static final EME_PKCS1_V1_5 getInstance(final RSAKey key) + { + final int modBits = key.getModulus().bitLength(); + final int k = (modBits + 7) / 8; + return EME_PKCS1_V1_5.getInstance(k); + } + + // Instance methods + // ------------------------------------------------------------------------- + + /** + * <p>Generates an octet string <code>PS</code> of length <code>k - mLen - + * 3</code> consisting of pseudo-randomly generated nonzero octets. The + * length of <code>PS</code> will be at least eight octets.</p> + * + * <p>The method then concatenates <code>PS</code>, the message <code>M</code>, + * and other padding to form an encoded message <code>EM</code> of length + * <code>k</code> octets as:</p> + * + * <pre> + * EM = 0x00 || 0x02 || PS || 0x00 || M. + * </pre> + * + * <p>This method uses a default PRNG to obtain the padding bytes.</p> + * + * @param M the message to encode. + * @return the encoded message <code>EM</code>. + */ + public byte[] encode(final byte[] M) + { + // a. Generate an octet string PS of length k - mLen - 3 consisting + // of pseudo-randomly generated nonzero octets. The length of PS + // will be at least eight octets. + final byte[] PS = new byte[k - M.length - 3]; + + // FIXME. This should be configurable, somehow. + prng.nextBytes(PS); + int i = 0; + for (; i < PS.length; i++) + { + if (PS[i] == 0) + PS[i] = 1; + } + // b. Concatenate PS, the message M, and other padding to form an + // encoded message EM of length k octets as + // + // EM = 0x00 || 0x02 || PS || 0x00 || M. + return assembleEM(PS, M); + } + + /** + * <p>Similar to {@link #encode(byte[])} method, except that the source of + * randomness to use for obtaining the padding bytes (an instance of + * {@link IRandom}) is given as a parameter.</p> + * + * @param M the message to encode. + * @param irnd the {@link IRandom} instance to use as a source of randomness. + * @return the encoded message <code>EM</code>. + */ + public byte[] encode(final byte[] M, final IRandom irnd) + { + final byte[] PS = new byte[k - M.length - 3]; + try + { + irnd.nextBytes(PS, 0, PS.length); + int i = 0; + outer: while (true) + { + for (; i < PS.length; i++) + { + if (PS[i] == 0x00) + { + System.arraycopy(PS, i + 1, PS, i, PS.length - i - 1); + irnd.nextBytes(PS, PS.length - 1, 1); + continue outer; + } + } + break; + } + } + catch (IllegalStateException x) + { + throw new RuntimeException("encode(): " + String.valueOf(x)); + } + catch (LimitReachedException x) + { + throw new RuntimeException("encode(): " + String.valueOf(x)); + } + + return assembleEM(PS, M); + } + + /** + * <p>Similar to the {@link #encode(byte[], IRandom)} method, except that + * the source of randmoness is an instance of {@link Random}. + * + * @param M the message to encode. + * @param rnd the {@link Random} instance to use as a source of randomness. + * @return the encoded message <code>EM</code>. + */ + public byte[] encode(final byte[] M, final Random rnd) + { + final byte[] PS = new byte[k - M.length - 3]; + rnd.nextBytes(PS); + int i = 0; + outer: while (true) + { + for (; i < PS.length; i++) + { + if (PS[i] == 0x00) + { + System.arraycopy(PS, i + 1, PS, i, PS.length - i - 1); + PS[PS.length - 1] = (byte) rnd.nextInt(); + continue outer; + } + } + break; + } + + return assembleEM(PS, M); + } + + /** + * <p>Separate the encoded message <code>EM</code> into an octet string + * <code>PS</code> consisting of nonzero octets and a message <code>M</code> + * as:</p> + * + * <pre> + * EM = 0x00 || 0x02 || PS || 0x00 || M. + * </pre> + * + * <p>If the first octet of <code>EM</code> does not have hexadecimal value + * <code>0x00</code>, if the second octet of <code>EM</code> does not have + * hexadecimal value <code>0x02</code>, if there is no octet with hexadecimal + * value <code>0x00</code> to separate <code>PS</code> from <code>M</code>, + * or if the length of <code>PS</code> is less than <code>8</code> octets, + * output "decryption error" and stop.</p> + + * @param EM the designated encoded message. + * @return the decoded message <code>M</code> framed in the designated + * <code>EM</code> value. + * @throws IllegalArgumentException if the length of the designated entity + * <code>EM</code> is different than <code>k</code> (the length in bytes of + * the public shared modulus), or if any of the conditions described above + * is detected. + */ + public byte[] decode(final byte[] EM) + { + // Separate the encoded message EM into an + // octet string PS consisting of nonzero octets and a message M as + // + // EM = 0x00 || 0x02 || PS || 0x00 || M. + // + // If the first octet of EM does not have hexadecimal value 0x00, if + // the second octet of EM does not have hexadecimal value 0x02, if + // there is no octet with hexadecimal value 0x00 to separate PS from + // M, or if the length of PS is less than 8 octets, output + // "decryption error" and stop. (See the note below.) + final int emLen = EM.length; + if (emLen != k) + { + throw new IllegalArgumentException("decryption error"); + } + if (EM[0] != 0x00) + { + throw new IllegalArgumentException("decryption error"); + } + if (EM[1] != 0x02) + { + throw new IllegalArgumentException("decryption error"); + } + int i = 2; + for (; i < emLen; i++) + { + if (EM[i] == 0x00) + { + break; + } + } + if (i >= emLen || i < 11) + { + throw new IllegalArgumentException("decryption error"); + } + i++; + final byte[] result = new byte[emLen - i]; + System.arraycopy(EM, i, result, 0, result.length); + return result; + } + + // helper methods ---------------------------------------------------------- + + private byte[] assembleEM(final byte[] PS, final byte[] M) + { + // b. Concatenate PS, the message M, and other padding to form an + // encoded message EM of length k octets as + // + // EM = 0x00 || 0x02 || PS || 0x00 || M. + baos.reset(); + baos.write(0x00); + baos.write(0x02); + baos.write(PS, 0, PS.length); + baos.write(0x00); + baos.write(M, 0, M.length); + final byte[] result = baos.toByteArray(); + baos.reset(); + + return result; + } +} diff --git a/libjava/classpath/gnu/java/security/sig/rsa/EMSA_PKCS1_V1_5.java b/libjava/classpath/gnu/java/security/sig/rsa/EMSA_PKCS1_V1_5.java new file mode 100644 index 00000000000..2ea8a304a9c --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/rsa/EMSA_PKCS1_V1_5.java @@ -0,0 +1,299 @@ +/* EMSA_PKCS1_V1_5.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.sig.rsa; + +import gnu.java.security.Registry; +import gnu.java.security.hash.HashFactory; +import gnu.java.security.hash.IMessageDigest; + +import java.io.ByteArrayOutputStream; + +/** + * <p>An implementation of the EMSA-PKCS1-V1.5 encoding scheme.</p> + * + * <p>EMSA-PKCS1-V1.5 is parameterised by the choice of hash function Hash and + * hLen which denotes the length in octets of the hash function output.</p> + * + * <p>References:</p> + * <ol> + * <li><a href="http://www.ietf.org/rfc/rfc3447.txt">Public-Key Cryptography + * Standards (PKCS) #1:</a><br> + * RSA Cryptography Specifications Version 2.1.<br> + * Jakob Jonsson and Burt Kaliski.</li> + * </ol> + * + * @version $Revision: 1.2 $ + */ +public class EMSA_PKCS1_V1_5 implements Cloneable +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /* Notes. + 1. For the six hash functions mentioned in Appendix B.1, the DER encoding + T of the DigestInfo value is equal to the following: + + MD2: (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 02 05 00 04 10 || H + MD5: (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04 10 || H + SHA-1: (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H + SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 || H + SHA-384: (0x)30 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00 04 30 || H + SHA-512: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40 || H + */ + private static final byte[] MD2_PREFIX = { (byte) 0x30, (byte) 0x20, + (byte) 0x30, (byte) 0x0c, + (byte) 0x06, (byte) 0x08, + (byte) 0x2a, (byte) 0x86, + (byte) 0x48, (byte) 0x86, + (byte) 0xf7, (byte) 0x0d, + (byte) 0x02, (byte) 0x02, + (byte) 0x05, (byte) 0x00, + (byte) 0x04, (byte) 0x10 }; + + private static final byte[] MD5_PREFIX = { (byte) 0x30, (byte) 0x20, + (byte) 0x30, (byte) 0x0c, + (byte) 0x06, (byte) 0x08, + (byte) 0x2a, (byte) 0x86, + (byte) 0x48, (byte) 0x86, + (byte) 0xf7, (byte) 0x0d, + (byte) 0x02, (byte) 0x05, + (byte) 0x05, (byte) 0x00, + (byte) 0x04, (byte) 0x10 }; + + private static final byte[] SHA160_PREFIX = { (byte) 0x30, (byte) 0x21, + (byte) 0x30, (byte) 0x09, + (byte) 0x06, (byte) 0x05, + (byte) 0x2b, (byte) 0x0e, + (byte) 0x03, (byte) 0x02, + (byte) 0x1a, (byte) 0x05, + (byte) 0x00, (byte) 0x04, + (byte) 0x14 }; + + private static final byte[] SHA256_PREFIX = { (byte) 0x30, (byte) 0x31, + (byte) 0x30, (byte) 0x0d, + (byte) 0x06, (byte) 0x09, + (byte) 0x60, (byte) 0x86, + (byte) 0x48, (byte) 0x01, + (byte) 0x65, (byte) 0x03, + (byte) 0x04, (byte) 0x02, + (byte) 0x01, (byte) 0x05, + (byte) 0x00, (byte) 0x04, + (byte) 0x20 }; + + private static final byte[] SHA384_PREFIX = { (byte) 0x30, (byte) 0x41, + (byte) 0x30, (byte) 0x0d, + (byte) 0x06, (byte) 0x09, + (byte) 0x60, (byte) 0x86, + (byte) 0x48, (byte) 0x01, + (byte) 0x65, (byte) 0x03, + (byte) 0x04, (byte) 0x02, + (byte) 0x02, (byte) 0x05, + (byte) 0x00, (byte) 0x04, + (byte) 0x30 }; + + private static final byte[] SHA512_PREFIX = { (byte) 0x30, (byte) 0x51, + (byte) 0x30, (byte) 0x0d, + (byte) 0x06, (byte) 0x09, + (byte) 0x60, (byte) 0x86, + (byte) 0x48, (byte) 0x01, + (byte) 0x65, (byte) 0x03, + (byte) 0x04, (byte) 0x02, + (byte) 0x03, (byte) 0x05, + (byte) 0x00, (byte) 0x04, + (byte) 0x40 }; + + /** The underlying hash function to use with this instance. */ + private IMessageDigest hash; + + /** The output size of the hash function in octets. */ + private int hLen; // TODO: field not used!!! investigate + + /** The DER part of DigestInfo not containing the hash value itself. */ + private byte[] prefix; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * <p>Trivial private constructor to enforce use through Factory method.</p> + * + * @param hash the message digest instance to use with this scheme instance. + */ + private EMSA_PKCS1_V1_5(final IMessageDigest hash) + { + super(); + + this.hash = hash; + hLen = hash.hashSize(); + final String name = hash.name(); + if (name.equals(Registry.MD2_HASH)) + { + prefix = MD2_PREFIX; + } + else if (name.equals(Registry.MD5_HASH)) + { + prefix = MD5_PREFIX; + } + else if (name.equals(Registry.SHA160_HASH)) + { + prefix = SHA160_PREFIX; + } + else if (name.equals(Registry.SHA256_HASH)) + { + prefix = SHA256_PREFIX; + } + else if (name.equals(Registry.SHA384_HASH)) + { + prefix = SHA384_PREFIX; + } + else if (name.equals(Registry.SHA512_HASH)) + { + prefix = SHA512_PREFIX; + } + else + { + throw new UnsupportedOperationException(); // should not happen + } + } + + // Class methods + // ------------------------------------------------------------------------- + + /** + * <p>Returns an instance of this object given a designated name of a hash + * function.</p> + * + * @param mdName the canonical name of a hash function. + * @return an instance of this object configured for use with the designated + * options. + * @throws UnsupportedOperationException if the hash function is not + * implemented or does not have an ID listed in RFC-3447. + */ + public static final EMSA_PKCS1_V1_5 getInstance(final String mdName) + { + final IMessageDigest hash = HashFactory.getInstance(mdName); + final String name = hash.name(); + if (!(name.equals(Registry.MD2_HASH) || name.equals(Registry.MD5_HASH) + || name.equals(Registry.SHA160_HASH) + || name.equals(Registry.SHA256_HASH) + || name.equals(Registry.SHA384_HASH) || name.equals(Registry.SHA512_HASH))) + { + throw new UnsupportedOperationException("hash with no OID: " + name); + } + return new EMSA_PKCS1_V1_5(hash); + } + + // Instance methods + // ------------------------------------------------------------------------- + + // Cloneable interface implementation -------------------------------------- + + public Object clone() + { + return getInstance(hash.name()); + } + + // own methods ------------------------------------------------------------- + + /** + * <p>Frames the hash of a message, along with an ID of the hash function in + * a DER sequence according to the specifications of EMSA-PKCS1-V1.5 as + * described in RFC-3447 (see class documentation).</p> + * + * @param mHash the byte sequence resulting from applying the message digest + * algorithm Hash to the message <i>M</i>. + * @param emLen intended length in octets of the encoded message, at least + * <code>tLen + 11</code>, where <code>tLen</code> is the octet length of the + * DER encoding <code>T</code> of a certain value computed during the + * encoding operation. + * @return encoded message, an octet string of length <code>emLen</code>. + * @throws IllegalArgumentException if the message is too long, or if the + * intended encoded message length is too short. + */ + public byte[] encode(final byte[] mHash, final int emLen) + { + // 1. Apply the hash function to the message M to produce a hash value + // H: H = Hash(M). + // If the hash function outputs "message too long," output "message + // too long" and stop. + // 2. Encode the algorithm ID for the hash function and the hash value + // into an ASN.1 value of type DigestInfo (see Appendix A.2.4) with + // the Distinguished Encoding Rules (DER), where the type DigestInfo + // has the syntax + // DigestInfo ::= SEQUENCE { + // digestAlgorithm AlgorithmIdentifier, + // digest OCTET STRING + // } + // The first field identifies the hash function and the second contains + // the hash value. Let T be the DER encoding of the DigestInfo value + // (see the notes below) and let tLen be the length in octets of T. + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + baos.write(prefix, 0, prefix.length); + baos.write(mHash, 0, mHash.length); + final byte[] T = baos.toByteArray(); + final int tLen = T.length; + // 3. If emLen < tLen + 11, output "intended encoded message length too + // short" and stop. + if (emLen < tLen + 11) + { + throw new IllegalArgumentException("emLen too short"); + } + // 4. Generate an octet string PS consisting of emLen - tLen - 3 octets + // with hexadecimal value 0xff. The length of PS will be at least 8 + // octets. + final byte[] PS = new byte[emLen - tLen - 3]; + for (int i = 0; i < PS.length; i++) + { + PS[i] = (byte) 0xFF; + } + // 5. Concatenate PS, the DER encoding T, and other padding to form the + // encoded message EM as: EM = 0x00 || 0x01 || PS || 0x00 || T. + baos.reset(); + baos.write(0x00); + baos.write(0x01); + baos.write(PS, 0, PS.length); + baos.write(0x00); + baos.write(T, 0, tLen); + final byte[] result = baos.toByteArray(); + baos.reset(); + // 6. Output EM. + return result; + } +} diff --git a/libjava/classpath/gnu/java/security/sig/rsa/EMSA_PSS.java b/libjava/classpath/gnu/java/security/sig/rsa/EMSA_PSS.java new file mode 100644 index 00000000000..d11a861b52e --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/rsa/EMSA_PSS.java @@ -0,0 +1,432 @@ +/* EMSA_PSS.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.sig.rsa; + +import gnu.java.security.hash.HashFactory; +import gnu.java.security.hash.IMessageDigest; +import gnu.java.security.util.Util; + +import java.io.PrintWriter; +import java.util.Arrays; + +/** + * <p>An implementation of the EMSA-PSS encoding/decoding scheme.</p> + * + * <p>EMSA-PSS coincides with EMSA4 in IEEE P1363a D5 except that EMSA-PSS acts + * on octet strings and not on bit strings. In particular, the bit lengths of + * the hash and the salt must be multiples of 8 in EMSA-PSS. Moreover, EMSA4 + * outputs an integer of a desired bit length rather than an octet string.</p> + * + * <p>EMSA-PSS is parameterized by the choice of hash function Hash and mask + * generation function MGF. In this submission, MGF is based on a Hash + * definition that coincides with the corresponding definitions in IEEE Std + * 1363-2000, PKCS #1 v2.0, and the draft ANSI X9.44. In PKCS #1 v2.0 and the + * draft ANSI X9.44, the recommended hash function is SHA-1, while IEEE Std + * 1363-2000 recommends SHA-1 and RIPEMD-160.</p> + * + * <p>References:</p> + * <ol> + * <li><a href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip"> + * RSA-PSS Signature Scheme with Appendix, part B.</a><br> + * Primitive specification and supporting documentation.<br> + * Jakob Jonsson and Burt Kaliski.</li> + * </ol> + * + * @version $Revision: 1.1 $ + */ +public class EMSA_PSS implements Cloneable +{ + + // Debugging methods and variables + // ------------------------------------------------------------------------- + + private static final String NAME = "emsa-pss"; + + private static final boolean DEBUG = false; + + private static final int debuglevel = 5; + + private static final PrintWriter err = new PrintWriter(System.out, true); + + private static void debug(String s) + { + err.println(">>> " + NAME + ": " + s); + } + + // Constants and variables + // ------------------------------------------------------------------------- + + /** The underlying hash function to use with this instance. */ + private IMessageDigest hash; + + /** The output size of the hash function in octets. */ + private int hLen; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * <p>Trivial private constructor to enforce use through Factory method.</p> + * + * @param hash the message digest instance to use with this scheme instance. + */ + private EMSA_PSS(IMessageDigest hash) + { + super(); + + this.hash = hash; + hLen = hash.hashSize(); + } + + // Class methods + // ------------------------------------------------------------------------- + + /** + * <p>Returns an instance of this object given a designated name of a hash + * function.</p> + * + * @param mdName the canonical name of a hash function. + * @return an instance of this object configured for use with the designated + * options. + */ + public static EMSA_PSS getInstance(String mdName) + { + IMessageDigest hash = HashFactory.getInstance(mdName); + return new EMSA_PSS(hash); + } + + // Instance methods + // ------------------------------------------------------------------------- + + // Cloneable interface implementation -------------------------------------- + + public Object clone() + { + return getInstance(hash.name()); + } + + // own methods ------------------------------------------------------------- + + /** + * <p>The encoding operation EMSA-PSS-Encode computes the hash of a message + * <code>M</code> using a hash function and maps the result to an encoded + * message <code>EM</code> of a specified length using a mask generation + * function.</p> + * + * @param mHash the byte sequence resulting from applying the message digest + * algorithm Hash to the message <i>M</i>. + * @param emBits the maximal bit length of the integer OS2IP(EM), at least + * <code>8.hLen + 8.sLen + 9</code>. + * @param salt the salt to use when encoding the output. + * @return the encoded message <code>EM</code>, an octet string of length + * <code>emLen = CEILING(emBits / 8)</code>. + * @exception IllegalArgumentException if an exception occurs. + * + */ + public byte[] encode(byte[] mHash, int emBits, byte[] salt) + { + int sLen = salt.length; + + // 1. If the length of M is greater than the input limitation for the hash + // function (2**61 - 1 octets for SHA-1) then output "message too long" + // and stop. + // 2. Let mHash = Hash(M), an octet string of length hLen. + if (hLen != mHash.length) + { + throw new IllegalArgumentException("wrong hash"); + } + // 3. If emBits < 8.hLen + 8.sLen + 9, output 'encoding error' and stop. + if (emBits < (8 * hLen + 8 * sLen + 9)) + { + throw new IllegalArgumentException("encoding error"); + } + int emLen = (emBits + 7) / 8; + // 4. Generate a random octet string salt of length sLen; if sLen = 0, + // then salt is the empty string. + // ...passed as argument to accomodate JCE + // 5. Let M0 = 00 00 00 00 00 00 00 00 || mHash || salt; + // M0 is an octet string of length 8 + hLen + sLen with eight initial zero + // octets. + // 6. Let H = Hash(M0), an octet string of length hLen. + byte[] H; + int i; + synchronized (hash) + { + for (i = 0; i < 8; i++) + { + hash.update((byte) 0x00); + } + hash.update(mHash, 0, hLen); + hash.update(salt, 0, sLen); + H = hash.digest(); + } + // 7. Generate an octet string PS consisting of emLen - sLen - hLen - 2 + // zero octets. The length of PS may be 0. + // 8. Let DB = PS || 01 || salt. + byte[] DB = new byte[emLen - sLen - hLen - 2 + 1 + sLen]; + DB[emLen - sLen - hLen - 2] = 0x01; + System.arraycopy(salt, 0, DB, emLen - sLen - hLen - 1, sLen); + // 9. Let dbMask = MGF(H, emLen - hLen - 1). + byte[] dbMask = MGF(H, emLen - hLen - 1); + if (DEBUG && debuglevel > 8) + { + debug("dbMask (encode): " + Util.toString(dbMask)); + debug("DB (encode): " + Util.toString(DB)); + } + // 10. Let maskedDB = DB XOR dbMask. + for (i = 0; i < DB.length; i++) + { + DB[i] = (byte) (DB[i] ^ dbMask[i]); + } + // 11. Set the leftmost 8emLen - emBits bits of the leftmost octet in + // maskedDB to zero. + DB[0] &= (0xFF >>> (8 * emLen - emBits)); + // 12. Let EM = maskedDB || H || bc, where bc is the single octet with + // hexadecimal value 0xBC. + byte[] result = new byte[emLen]; + System.arraycopy(DB, 0, result, 0, emLen - hLen - 1); + System.arraycopy(H, 0, result, emLen - hLen - 1, hLen); + result[emLen - 1] = (byte) 0xBC; + // 13. Output EM. + return result; + } + + /** + * <p>The decoding operation EMSA-PSS-Decode recovers the message hash from + * an encoded message <code>EM</code> and compares it to the hash of + * <code>M</code>.</p> + * + * @param mHash the byte sequence resulting from applying the message digest + * algorithm Hash to the message <i>M</i>. + * @param EM the <i>encoded message</i>, an octet string of length + * <code>emLen = CEILING(emBits/8). + * @param emBits the maximal bit length of the integer OS2IP(EM), at least + * <code>8.hLen + 8.sLen + 9</code>. + * @param sLen the length, in octets, of the expected salt. + * @return <code>true</code> if the result of the verification was + * <i>consistent</i> with the expected reseult; and <code>false</code> if the + * result was <i>inconsistent</i>. + * @exception IllegalArgumentException if an exception occurs. + */ + public boolean decode(byte[] mHash, byte[] EM, int emBits, int sLen) + { + if (DEBUG && debuglevel > 8) + { + debug("mHash: " + Util.toString(mHash)); + debug("EM: " + Util.toString(EM)); + debug("emBits: " + String.valueOf(emBits)); + debug("sLen: " + String.valueOf(sLen)); + } + if (sLen < 0) + { + throw new IllegalArgumentException("sLen"); + } + + // 1. If the length of M is greater than the input limitation for the hash + // function (2**61 ? 1 octets for SHA-1) then output 'inconsistent' and + // stop. + // 2. Let mHash = Hash(M), an octet string of length hLen. + if (hLen != mHash.length) + { + if (DEBUG && debuglevel > 8) + { + debug("hLen != mHash.length; hLen: " + String.valueOf(hLen)); + } + throw new IllegalArgumentException("wrong hash"); + } + // 3. If emBits < 8.hLen + 8.sLen + 9, output 'decoding error' and stop. + if (emBits < (8 * hLen + 8 * sLen + 9)) + { + if (DEBUG && debuglevel > 8) + { + debug("emBits < (8hLen + 8sLen + 9); sLen: " + String.valueOf(sLen)); + } + throw new IllegalArgumentException("decoding error"); + } + int emLen = (emBits + 7) / 8; + // 4. If the rightmost octet of EM does not have hexadecimal value bc, + // output 'inconsistent' and stop. + if ((EM[EM.length - 1] & 0xFF) != 0xBC) + { + if (DEBUG && debuglevel > 8) + { + debug("EM does not end with 0xBC"); + } + return false; + } + // 5. Let maskedDB be the leftmost emLen ? hLen ? 1 octets of EM, and let + // H be the next hLen octets. + // 6. If the leftmost 8.emLen ? emBits bits of the leftmost octet in + // maskedDB are not all equal to zero, output 'inconsistent' and stop. + if ((EM[0] & (0xFF << (8 - (8 * emLen - emBits)))) != 0) + { + if (DEBUG && debuglevel > 8) + { + debug("Leftmost 8emLen - emBits bits of EM are not 0s"); + } + return false; + } + byte[] DB = new byte[emLen - hLen - 1]; + byte[] H = new byte[hLen]; + System.arraycopy(EM, 0, DB, 0, emLen - hLen - 1); + System.arraycopy(EM, emLen - hLen - 1, H, 0, hLen); + // 7. Let dbMask = MGF(H, emLen ? hLen ? 1). + byte[] dbMask = MGF(H, emLen - hLen - 1); + // 8. Let DB = maskedDB XOR dbMask. + int i; + for (i = 0; i < DB.length; i++) + { + DB[i] = (byte) (DB[i] ^ dbMask[i]); + } + // 9. Set the leftmost 8.emLen ? emBits bits of DB to zero. + DB[0] &= (0xFF >>> (8 * emLen - emBits)); + if (DEBUG && debuglevel > 8) + { + debug("dbMask (decode): " + Util.toString(dbMask)); + debug("DB (decode): " + Util.toString(DB)); + } + // 10. If the emLen -hLen -sLen -2 leftmost octets of DB are not zero or + // if the octet at position emLen -hLen -sLen -1 is not equal to 0x01, + // output 'inconsistent' and stop. + // IMPORTANT (rsn): this is an error in the specs, the index of the 0x01 + // byte should be emLen -hLen -sLen -2 and not -1! authors have been + // advised + for (i = 0; i < (emLen - hLen - sLen - 2); i++) + { + if (DB[i] != 0) + { + if (DEBUG && debuglevel > 8) + { + debug("DB[" + String.valueOf(i) + "] != 0x00"); + } + return false; + } + } + if (DB[i] != 0x01) + { // i == emLen -hLen -sLen -2 + if (DEBUG && debuglevel > 8) + { + debug("DB's byte at position (emLen -hLen -sLen -2); i.e. " + + String.valueOf(i) + " is not 0x01"); + } + return false; + } + // 11. Let salt be the last sLen octets of DB. + byte[] salt = new byte[sLen]; + System.arraycopy(DB, DB.length - sLen, salt, 0, sLen); + // 12. Let M0 = 00 00 00 00 00 00 00 00 || mHash || salt; + // M0 is an octet string of length 8 + hLen + sLen with eight initial + // zero octets. + // 13. Let H0 = Hash(M0), an octet string of length hLen. + byte[] H0; + synchronized (hash) + { + for (i = 0; i < 8; i++) + { + hash.update((byte) 0x00); + } + hash.update(mHash, 0, hLen); + hash.update(salt, 0, sLen); + H0 = hash.digest(); + } + // 14. If H = H0, output 'consistent.' Otherwise, output 'inconsistent.' + return Arrays.equals(H, H0); + } + + // helper methods ---------------------------------------------------------- + + /** + * <p>A mask generation function takes an octet string of variable length + * and a desired output length as input, and outputs an octet string of the + * desired length. There may be restrictions on the length of the input and + * output octet strings, but such bounds are generally very large. Mask + * generation functions are deterministic; the octet string output is + * completely determined by the input octet string. The output of a mask + * generation function should be pseudorandom, that is, it should be + * infeasible to predict, given one part of the output but not the input, + * another part of the output. The provable security of RSA-PSS relies on + * the random nature of the output of the mask generation function, which in + * turn relies on the random nature of the underlying hash function.</p> + * + * @param Z a seed. + * @param l the desired output length in octets. + * @return the mask. + * @exception IllegalArgumentException if the desired output length is too + * long. + */ + private byte[] MGF(byte[] Z, int l) + { + // 1. If l > (2**32).hLen, output 'mask too long' and stop. + if (l < 1 || (l & 0xFFFFFFFFL) > ((hLen & 0xFFFFFFFFL) << 32L)) + { + throw new IllegalArgumentException("mask too long"); + } + // 2. Let T be the empty octet string. + byte[] result = new byte[l]; + // 3. For i = 0 to CEILING(l/hLen) ? 1, do + int limit = ((l + hLen - 1) / hLen) - 1; + IMessageDigest hashZ = null; + hashZ = (IMessageDigest) hash.clone(); + hashZ.digest(); + hashZ.update(Z, 0, Z.length); + IMessageDigest hashZC = null; + byte[] t; + int sofar = 0; + int length; + for (int i = 0; i < limit; i++) + { + // 3.1 Convert i to an octet string C of length 4 with the primitive + // I2OSP: C = I2OSP(i, 4). + // 3.2 Concatenate the hash of the seed Z and C to the octet string T: + // T = T || Hash(Z || C) + hashZC = (IMessageDigest) hashZ.clone(); + hashZC.update((byte) (i >>> 24)); + hashZC.update((byte) (i >>> 16)); + hashZC.update((byte) (i >>> 8)); + hashZC.update((byte) i); + t = hashZC.digest(); + length = l - sofar; + length = (length > hLen ? hLen : length); + System.arraycopy(t, 0, result, sofar, length); + sofar += length; + } + // 4. Output the leading l octets of T as the octet string mask. + return result; + } +} diff --git a/libjava/classpath/gnu/java/security/sig/rsa/RSA.java b/libjava/classpath/gnu/java/security/sig/rsa/RSA.java new file mode 100644 index 00000000000..7d1707e195d --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/rsa/RSA.java @@ -0,0 +1,356 @@ +/* RSA.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.sig.rsa; + +import gnu.java.security.Properties; +import gnu.java.security.util.PRNG; + +import java.math.BigInteger; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; + +/** + * <p>Utility methods related to the RSA algorithm.</p> + * + * <p>References:</p> + * <ol> + * <li><a href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip"> + * RSA-PSS Signature Scheme with Appendix, part B.</a><br> + * Primitive specification and supporting documentation.<br> + * Jakob Jonsson and Burt Kaliski.</li> + * + * <li><a href="http://www.ietf.org/rfc/rfc3447.txt">Public-Key Cryptography + * Standards (PKCS) #1:</a><br> + * RSA Cryptography Specifications Version 2.1.<br> + * Jakob Jonsson and Burt Kaliski.</li> + * + * <li><a href="http://crypto.stanford.edu/~dabo/abstracts/ssl-timing.html"> + * Remote timing attacks are practical</a><br> + * D. Boneh and D. Brumley.</li> + * </ol> + */ +public class RSA +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + private static final BigInteger ZERO = BigInteger.ZERO; + + private static final BigInteger ONE = BigInteger.ONE; + + /** Our default source of randomness. */ + private static final PRNG prng = PRNG.getInstance(); + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial private constructor to enforce Singleton pattern. */ + private RSA() + { + super(); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Signature and verification methods -------------------------------------- + + /** + * <p>An implementation of the <b>RSASP</b> method: Assuming that the + * designated RSA private key is a valid one, this method computes a + * <i>signature representative</i> for a designated <i>message + * representative</i> signed by the holder of the designated RSA private + * key.<p> + * + * @param K the RSA private key. + * @param m the <i>message representative</i>: an integer between + * <code>0</code> and <code>n - 1</code>, where <code>n</code> is the RSA + * <i>modulus</i>. + * @return the <i>signature representative</i>, an integer between + * <code>0</code> and <code>n - 1</code>, where <code>n</code> is the RSA + * <i>modulus</i>. + * @throws ClassCastException if <code>K</code> is not an RSA one. + * @throws IllegalArgumentException if <code>m</code> (the <i>message + * representative</i>) is out of range. + */ + public static final BigInteger sign(final PrivateKey K, final BigInteger m) + { + try + { + return RSADP((RSAPrivateKey) K, m); + } + catch (IllegalArgumentException x) + { + throw new IllegalArgumentException( + "message representative out of range"); + } + } + + /** + * <p>An implementation of the <b>RSAVP</b> method: Assuming that the + * designated RSA public key is a valid one, this method computes a + * <i>message representative</i> for the designated <i>signature + * representative</i> generated by an RSA private key, for a message + * intended for the holder of the designated RSA public key.</p> + * + * @param K the RSA public key. + * @param s the <i>signature representative</i>, an integer between + * <code>0</code> and <code>n - 1</code>, where <code>n</code> is the RSA + * <i>modulus</i>. + * @return a <i>message representative</i>: an integer between <code>0</code> + * and <code>n - 1</code>, where <code>n</code> is the RSA <i>modulus</i>. + * @throws ClassCastException if <code>K</code> is not an RSA one. + * @throws IllegalArgumentException if <code>s</code> (the <i>signature + * representative</i>) is out of range. + */ + public static final BigInteger verify(final PublicKey K, final BigInteger s) + { + try + { + return RSAEP((RSAPublicKey) K, s); + } + catch (IllegalArgumentException x) + { + throw new IllegalArgumentException( + "signature representative out of range"); + } + } + + // Encryption and decryption methods --------------------------------------- + + /** + * <p>An implementation of the <code>RSAEP</code> algorithm.</p> + * + * @param K the recipient's RSA public key. + * @param m the message representative as an MPI. + * @return the resulting MPI --an MPI between <code>0</code> and + * <code>n - 1</code> (<code>n</code> being the public shared modulus)-- that + * will eventually be padded with an appropriate framing/padding scheme. + * @throws ClassCastException if <code>K</code> is not an RSA one. + * @throws IllegalArgumentException if <code>m</code>, the message + * representative is not between <code>0</code> and <code>n - 1</code> + * (<code>n</code> being the public shared modulus). + */ + public static final BigInteger encrypt(final PublicKey K, final BigInteger m) + { + try + { + return RSAEP((RSAPublicKey) K, m); + } + catch (IllegalArgumentException x) + { + throw new IllegalArgumentException( + "message representative out of range"); + } + } + + /** + * <p>An implementation of the <code>RSADP</code> algorithm.</p> + * + * @param K the recipient's RSA private key. + * @param c the ciphertext representative as an MPI. + * @return the message representative, an MPI between <code>0</code> and + * <code>n - 1</code> (<code>n</code> being the shared public modulus). + * @throws ClassCastException if <code>K</code> is not an RSA one. + * @throws IllegalArgumentException if <code>c</code>, the ciphertext + * representative is not between <code>0</code> and <code>n - 1</code> + * (<code>n</code> being the shared public modulus). + */ + public static final BigInteger decrypt(final PrivateKey K, final BigInteger c) + { + try + { + return RSADP((RSAPrivateKey) K, c); + } + catch (IllegalArgumentException x) + { + throw new IllegalArgumentException( + "ciphertext representative out of range"); + } + } + + // Conversion methods ------------------------------------------------------ + + /** + * <p>Converts a <i>multi-precision integer</i> (MPI) <code>s</code> into an + * octet sequence of length <code>k</code>.</p> + * + * @param s the multi-precision integer to convert. + * @param k the length of the output. + * @return the result of the transform. + * @exception IllegalArgumentException if the length in octets of meaningful + * bytes of <code>s</code> is greater than <code>k</code>. + */ + public static final byte[] I2OSP(final BigInteger s, final int k) + { + byte[] result = s.toByteArray(); + if (result.length < k) + { + final byte[] newResult = new byte[k]; + System.arraycopy(result, 0, newResult, k - result.length, result.length); + result = newResult; + } + else if (result.length > k) + { // leftmost extra bytes should all be 0 + final int limit = result.length - k; + for (int i = 0; i < limit; i++) + { + if (result[i] != 0x00) + { + throw new IllegalArgumentException("integer too large"); + } + } + final byte[] newResult = new byte[k]; + System.arraycopy(result, limit, newResult, 0, k); + result = newResult; + } + return result; + } + + // helper methods ---------------------------------------------------------- + + private static final BigInteger RSAEP(final RSAPublicKey K, final BigInteger m) + { + // 1. If the representative m is not between 0 and n - 1, output + // "representative out of range" and stop. + final BigInteger n = K.getModulus(); + if (m.compareTo(ZERO) < 0 || m.compareTo(n.subtract(ONE)) > 0) + { + throw new IllegalArgumentException(); + } + // 2. Let c = m^e mod n. + final BigInteger e = K.getPublicExponent(); + final BigInteger result = m.modPow(e, n); + // 3. Output c. + return result; + } + + private static final BigInteger RSADP(final RSAPrivateKey K, BigInteger c) + { + // 1. If the representative c is not between 0 and n - 1, output + // "representative out of range" and stop. + final BigInteger n = K.getModulus(); + if (c.compareTo(ZERO) < 0 || c.compareTo(n.subtract(ONE)) > 0) + { + throw new IllegalArgumentException(); + } + + // 2. The representative m is computed as follows. + BigInteger result; + if (!(K instanceof RSAPrivateCrtKey)) + { + // a. If the first form (n, d) of K is used, let m = c^d mod n. + final BigInteger d = K.getPrivateExponent(); + result = c.modPow(d, n); + } + else + { + // from [3] p.13 --see class docs: + // The RSA blinding operation calculates x = (r^e) * g mod n before + // decryption, where r is random, e is the RSA encryption exponent, and + // g is the ciphertext to be decrypted. x is then decrypted as normal, + // followed by division by r, i.e. (x^e) / r mod n. Since r is random, + // x is random and timing the decryption should not reveal information + // about the key. Note that r should be a new random number for every + // decryption. + final boolean rsaBlinding = Properties.doRSABlinding(); + BigInteger r = null; + BigInteger e = null; + if (rsaBlinding) + { // pre-decryption + r = newR(n); + e = ((RSAPrivateCrtKey) K).getPublicExponent(); + final BigInteger x = r.modPow(e, n).multiply(c).mod(n); + c = x; + } + + // b. If the second form (p, q, dP, dQ, qInv) and (r_i, d_i, t_i) + // of K is used, proceed as follows: + final BigInteger p = ((RSAPrivateCrtKey) K).getPrimeP(); + final BigInteger q = ((RSAPrivateCrtKey) K).getPrimeQ(); + final BigInteger dP = ((RSAPrivateCrtKey) K).getPrimeExponentP(); + final BigInteger dQ = ((RSAPrivateCrtKey) K).getPrimeExponentQ(); + final BigInteger qInv = ((RSAPrivateCrtKey) K).getCrtCoefficient(); + + // i. Let m_1 = c^dP mod p and m_2 = c^dQ mod q. + final BigInteger m_1 = c.modPow(dP, p); + final BigInteger m_2 = c.modPow(dQ, q); + // ii. If u > 2, let m_i = c^(d_i) mod r_i, i = 3, ..., u. + // iii. Let h = (m_1 - m_2) * qInv mod p. + final BigInteger h = m_1.subtract(m_2).multiply(qInv).mod(p); + // iv. Let m = m_2 + q * h. + result = m_2.add(q.multiply(h)); + + if (rsaBlinding) + { // post-decryption + result = result.multiply(r.modInverse(n)).mod(n); + } + } + + // 3. Output m + return result; + } + + /** + * <p>Returns a random MPI with a random bit-length of the form <code>8b</code>, + * where <code>b</code> is in the range <code>[32..64]</code>.</p> + * + * @return a random MPI whose length in bytes is between 32 and 64 inclusive. + */ + private static final BigInteger newR(final BigInteger N) + { + final int upper = (N.bitLength() + 7) / 8; + final int lower = upper / 2; + final byte[] bl = new byte[1]; + int b; + do + { + prng.nextBytes(bl); + b = bl[0] & 0xFF; + } + while (b < lower || b > upper); + final byte[] buffer = new byte[b]; // 256-bit MPI + prng.nextBytes(buffer); + return new BigInteger(1, buffer); + } +} diff --git a/libjava/classpath/gnu/java/security/sig/rsa/RSAPKCS1V1_5Signature.java b/libjava/classpath/gnu/java/security/sig/rsa/RSAPKCS1V1_5Signature.java new file mode 100644 index 00000000000..d4b69a7a18f --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/rsa/RSAPKCS1V1_5Signature.java @@ -0,0 +1,247 @@ +/* RSAPKCS1V1_5Signature.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.sig.rsa; + +import gnu.java.security.Registry; +import gnu.java.security.hash.HashFactory; +import gnu.java.security.hash.IMessageDigest; +import gnu.java.security.sig.BaseSignature; + +import java.math.BigInteger; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; +import java.util.Arrays; + +/** + * <p>The RSA-PKCS1-V1.5 signature scheme is a digital signature scheme with + * appendix (SSA) combining the RSA algorithm with the EMSA-PKCS1-v1_5 encoding + * method.</p> + * + * <p>References:</p> + * <ol> + * <li><a href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip"> + * RSA-PSS Signature Scheme with Appendix, part B.</a><br> + * Primitive specification and supporting documentation.<br> + * Jakob Jonsson and Burt Kaliski.</li> + * + * <li><a href="http://www.ietf.org/rfc/rfc3447.txt">Public-Key Cryptography + * Standards (PKCS) #1:</a><br> + * RSA Cryptography Specifications Version 2.1.<br> + * Jakob Jonsson and Burt Kaliski.</li> + * </ol> + * + * @version $Revision: 1.2 $ + */ +public class RSAPKCS1V1_5Signature extends BaseSignature +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + /** The underlying EMSA-PKCS1-v1.5 instance for this object. */ + private EMSA_PKCS1_V1_5 pkcs1; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Default 0-arguments constructor. Uses SHA-1 as the default hash. + */ + public RSAPKCS1V1_5Signature() + { + this(Registry.SHA160_HASH); + } + + /** + * <p>Constructs an instance of this object using the designated message + * digest algorithm as its underlying hash function.</p> + * + * @param mdName the canonical name of the underlying hash function. + */ + public RSAPKCS1V1_5Signature(final String mdName) + { + this(HashFactory.getInstance(mdName)); + } + + public RSAPKCS1V1_5Signature(IMessageDigest md) + { + super(Registry.RSA_PKCS1_V1_5_SIG, md); + + pkcs1 = EMSA_PKCS1_V1_5.getInstance(md.name()); + } + + /** Private constructor for cloning purposes. */ + private RSAPKCS1V1_5Signature(final RSAPKCS1V1_5Signature that) + { + this(that.md.name()); + + this.publicKey = that.publicKey; + this.privateKey = that.privateKey; + this.md = (IMessageDigest) that.md.clone(); + this.pkcs1 = (EMSA_PKCS1_V1_5) that.pkcs1.clone(); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // Implementation of abstract methods in superclass ------------------------ + + public Object clone() + { + return new RSAPKCS1V1_5Signature(this); + } + + protected void setupForVerification(final PublicKey k) + throws IllegalArgumentException + { + if (!(k instanceof RSAPublicKey)) + { + throw new IllegalArgumentException(); + } + publicKey = k; + } + + protected void setupForSigning(final PrivateKey k) + throws IllegalArgumentException + { + if (!(k instanceof RSAPrivateKey)) + { + throw new IllegalArgumentException(); + } + privateKey = k; + } + + protected Object generateSignature() throws IllegalStateException + { + // 1. EMSA-PKCS1-v1_5 encoding: Apply the EMSA-PKCS1-v1_5 encoding + // operation (Section 9.2) to the message M to produce an encoded + // message EM of length k octets: + // + // EM = EMSA-PKCS1-V1_5-ENCODE (M, k). + // + // If the encoding operation outputs "message too long," output + // "message too long" and stop. If the encoding operation outputs + // "intended encoded message length too short," output "RSA modulus + // too short" and stop. + final int modBits = ((RSAPrivateKey) privateKey).getModulus().bitLength(); + final int k = (modBits + 7) / 8; + final byte[] EM = pkcs1.encode(md.digest(), k); + + // 2. RSA signature: + // a. Convert the encoded message EM to an integer message epresentative + // m (see Section 4.2): m = OS2IP (EM). + final BigInteger m = new BigInteger(1, EM); + // b. Apply the RSASP1 signature primitive (Section 5.2.1) to the RSA + // private key K and the message representative m to produce an + // integer signature representative s: s = RSASP1 (K, m). + final BigInteger s = RSA.sign(privateKey, m); + // c. Convert the signature representative s to a signature S of length + // k octets (see Section 4.1): S = I2OSP (s, k). + // 3. Output the signature S. + return RSA.I2OSP(s, k); + } + + protected boolean verifySignature(final Object sig) + throws IllegalStateException + { + if (publicKey == null) + { + throw new IllegalStateException(); + } + final byte[] S = (byte[]) sig; + // 1. Length checking: If the length of the signature S is not k octets, + // output "invalid signature" and stop. + final int modBits = ((RSAPublicKey) publicKey).getModulus().bitLength(); + final int k = (modBits + 7) / 8; + if (S.length != k) + { + return false; + } + // 2. RSA verification: + // a. Convert the signature S to an integer signature representative + // s (see Section 4.2): s = OS2IP (S). + final BigInteger s = new BigInteger(1, S); + // b. Apply the RSAVP1 verification primitive (Section 5.2.2) to the + // RSA public key (n, e) and the signature representative s to + // produce an integer message representative m: + // m = RSAVP1 ((n, e), s). + // If RSAVP1 outputs "signature representative out of range," + // output "invalid signature" and stop. + final BigInteger m; + try + { + m = RSA.verify(publicKey, s); + } + catch (IllegalArgumentException x) + { + return false; + } + // c. Convert the message representative m to an encoded message EM + // of length k octets (see Section 4.1): EM = I2OSP (m, k). + // If I2OSP outputs "integer too large," output "invalid signature" + // and stop. + final byte[] EM; + try + { + EM = RSA.I2OSP(m, k); + } + catch (IllegalArgumentException x) + { + return false; + } + // 3. EMSA-PKCS1-v1_5 encoding: Apply the EMSA-PKCS1-v1_5 encoding + // operation (Section 9.2) to the message M to produce a second + // encoded message EM' of length k octets: + // EM' = EMSA-PKCS1-V1_5-ENCODE (M, k). + // If the encoding operation outputs "message too long," output + // "message too long" and stop. If the encoding operation outputs + // "intended encoded message length too short," output "RSA modulus + // too short" and stop. + final byte[] EMp = pkcs1.encode(md.digest(), k); + // 4. Compare the encoded message EM and the second encoded message EM'. + // If they are the same, output "valid signature"; otherwise, output + // "invalid signature." + return Arrays.equals(EM, EMp); + } +} diff --git a/libjava/classpath/gnu/java/security/sig/rsa/RSAPKCS1V1_5SignatureRawCodec.java b/libjava/classpath/gnu/java/security/sig/rsa/RSAPKCS1V1_5SignatureRawCodec.java new file mode 100644 index 00000000000..68c1edaa6b1 --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/rsa/RSAPKCS1V1_5SignatureRawCodec.java @@ -0,0 +1,153 @@ +/* RSAPKCS1V1_5SignatureRawCodec.java -- Raw RSA PKCS1 v1.5 signature codeec + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.sig.rsa; + +import java.io.ByteArrayOutputStream; + +import gnu.java.security.Registry; +import gnu.java.security.sig.ISignatureCodec; + +/** + * An object that implements the {@link ISignatureCodec} operations for the + * <i>Raw</i> format to use with RSA-PKCS#1 v1.5 signatures. + */ +public class RSAPKCS1V1_5SignatureRawCodec + implements ISignatureCodec +{ + public int getFormatID() + { + return RAW_FORMAT; + } + + /** + * Returns the encoded form of the designated RSA-PKCS#1 (v1.5) signature + * object according to the <i>Raw</i> format supported by this library. + * <p> + * The <i>Raw</i> format for such a signature, in this implementation, is a + * byte sequence consisting of the following: + * <p> + * <ol> + * <li>4-byte magic consisting of the value of the literal + * {@link Registry#MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE}, + * <li> + * <li>1-byte version consisting of the constant: 0x01,</li> + * <li>4-byte count of following bytes representing the RSA-PKCS#1 (v1.5) + * signature bytes in internet order,</li> + * <li>the RSA-PKCS#1 (v1.5) signature bytes in internet order.</li> + * </ol> + * + * @param signature the signature to encode, consisting of the output of the + * <code>sign()</code> method of a {@link RSAPKCS1V1_5Signature} + * instance --a byte array. + * @return the <i>Raw</i> format encoding of the designated signature. + * @exception IllegalArgumentException if the designated signature is not an + * RSA-PKCS#1 (v1.5) one. + */ + public byte[] encodeSignature(Object signature) + { + byte[] buffer; + try + { + buffer = (byte[]) signature; + } + catch (Exception x) + { + throw new IllegalArgumentException("Signature/codec mismatch"); + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + // magic + baos.write(Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[0]); + baos.write(Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[1]); + baos.write(Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[2]); + baos.write(Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[3]); + + // version + baos.write(0x01); + + // signature bytes + int length = buffer.length; + baos.write( length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write( length & 0xFF); + baos.write(buffer, 0, length); + + return baos.toByteArray(); + } + + /** + * Returns the decoded object from a designated input assumed to have been + * generated by the {@link #encodeSignature(Object)} method. + * + * @param input the input bytes of a previously Raw-encoded RSA PKCS1 (v1.5) + * signature. + * @return the signature object. + * @throws IllegalArgumentException if the designated input does not start + * with the right <i>magic</i> characters, or if the <i>version</i> + * is not supported. + */ + public Object decodeSignature(byte[] input) + { + // magic + if (input[0] != Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[0] + || input[1] != Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[1] + || input[2] != Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[2] + || input[3] != Registry.MAGIC_RAW_RSA_PKCS1V1_5_SIGNATURE[3]) + throw new IllegalArgumentException("Signature/codec mismatch"); + + // version + if (input[4] != 0x01) + throw new IllegalArgumentException("Wrong or unsupported format version"); + + int i = 5; + int l; + + // signature bytes + l = input[i++] << 24 + | (input[i++] & 0xFF) << 16 + | (input[i++] & 0xFF) << 8 + | (input[i++] & 0xFF); + byte[] result = new byte[l]; + System.arraycopy(input, i, result, 0, l); + + return result; + } +} diff --git a/libjava/classpath/gnu/java/security/sig/rsa/RSAPKCS1V1_5SignatureX509Codec.java b/libjava/classpath/gnu/java/security/sig/rsa/RSAPKCS1V1_5SignatureX509Codec.java new file mode 100644 index 00000000000..3cb375602a0 --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/rsa/RSAPKCS1V1_5SignatureX509Codec.java @@ -0,0 +1,128 @@ +/* RSAPSSSignatureX509Codec.java -- X.509 encoder/decoder for RSA signatures + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.sig.rsa; + +import gnu.java.security.Registry; +import gnu.java.security.sig.ISignatureCodec; + +import java.security.InvalidParameterException; + +/** + * An implementation of an {@link ISignatureCodec} that knows to encode and + * decode RSA PKCS1 (v1.5) signatures into the raw bytes which would constitute + * a DER-encoded form of the ASN.1 structure defined in RFC-2459, and RFC-2313 + * as described in the next paragraphs. + * <p> + * Digital signatures when transmitted in an X.509 certificates are encoded + * in DER (Distinguished Encoding Rules) as a BIT STRING; i.e. + * + * <pre> + * Certificate ::= SEQUENCE { + * tbsCertificate TBSCertificate, + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING + * } + * </pre> + * <p> + * The output of the encoder, and the input of the decoder, of this codec are + * then the <i>raw</i> bytes of such a BIT STRING; i.e. not the DER-encoded + * form itself. + * <p> + * Our implementation of the RSA PKCS1 signature algorithm outputs a byte array + * as the result of generating a digital signature, in accordance with RFC-2313. + * As a consequence, the encoder and decoder of this codec, simply pass through + * such a byte array. + * <p> + * Client code that needs to build a DER BIT STRING <b>MUST</b> construct such + * an ASN.1 value. The following is an example of how to do this: + * <p> + * <pre> + * ... + * import gnu.java.security.der.BitString; + * import gnu.java.security.der.DER; + * import gnu.java.security.der.DERValue; + * ... + * DERValue bitString = new DERValue(DER.BIT_STRING, new BitString(sigBytes)); + * ... + * </pre> + */ +public class RSAPKCS1V1_5SignatureX509Codec + implements ISignatureCodec +{ + // default 0-arguments constructor + + public int getFormatID() + { + return Registry.X509_ENCODING_ID; + } + + /** + * Encodes an RSA Signature output as a <i>signature</i> BIT STRING as + * defined in the documentation of this class. + * + * @param signature the output of the RSA PKCS1 (v1.5) signature algorithm; + * i.e. the value returned by the invocation of + * {@link gnu.java.security.sig.ISignature#sign()} method. In the + * case of the RSA PKCS1 (v1.5) signature this is an array of bytes. + * @return the raw bytes of an RSA signature which could be then used as the + * contents of a BIT STRING as per rfc-2459. + */ + public byte[] encodeSignature(Object signature) + { + byte[] result = (byte[]) signature; + return result; + } + + /** + * Decodes a <i>signature</i> as defined in the documentation of this class. + * + * @param input the byte array to unmarshall into a valid RSA PKCS1 (v1.5) + * signature instance; i.e. a byte array. MUST NOT be null. + * @return an array of raw bytes decoded from the designated input. In the + * case of RSA PKCS1 (v1.5) this is the same as the input. + * @throw InvalidParameterException if the <code>input</code> array is null. + */ + public Object decodeSignature(byte[] input) + { + if (input == null) + throw new InvalidParameterException("Input bytes MUST NOT be null"); + + return input; + } +} diff --git a/libjava/classpath/gnu/java/security/sig/rsa/RSAPSSSignature.java b/libjava/classpath/gnu/java/security/sig/rsa/RSAPSSSignature.java new file mode 100644 index 00000000000..95a6653f393 --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/rsa/RSAPSSSignature.java @@ -0,0 +1,348 @@ +/* RSAPSSSignature.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.sig.rsa; + +import gnu.java.security.Registry; +import gnu.java.security.hash.HashFactory; +import gnu.java.security.hash.IMessageDigest; +import gnu.java.security.sig.BaseSignature; +import gnu.java.security.util.Util; + +import java.io.PrintWriter; +import java.math.BigInteger; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.interfaces.RSAPrivateKey; +import java.security.interfaces.RSAPublicKey; + +/** + * <p>The RSA-PSS signature scheme is a public-key encryption scheme combining + * the RSA algorithm with the Probabilistic Signature Scheme (PSS) encoding + * method.</p> + * + * <p>The inventors of RSA are Ronald L. Rivest, Adi Shamir, and Leonard Adleman, + * while the inventors of the PSS encoding method are Mihir Bellare and Phillip + * Rogaway. During efforts to adopt RSA-PSS into the P1363a standards effort, + * certain adaptations to the original version of RSA-PSS were made by Mihir + * Bellare and Phillip Rogaway and also by Burt Kaliski (the editor of IEEE + * P1363a) to facilitate implementation and integration into existing protocols.</p> + * + * <p>References:</pr> + * <ol> + * <li><a href="http://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/rsa-pss.zip"> + * RSA-PSS Signature Scheme with Appendix, part B.</a><br> + * Primitive specification and supporting documentation.<br> + * Jakob Jonsson and Burt Kaliski.</li> + * </ol> + * + * @version $Revision: 1.2 $ + */ +public class RSAPSSSignature extends BaseSignature +{ + + // Debugging methods and variables + // ------------------------------------------------------------------------- + + private static final String NAME = "rsa-pss"; + + private static final boolean DEBUG = false; + + private static final int debuglevel = 1; + + private static final PrintWriter err = new PrintWriter(System.out, true); + + private static void debug(String s) + { + err.println(">>> " + NAME + ": " + s); + } + + // Constants and variables + // ------------------------------------------------------------------------- + + /** The underlying EMSA-PSS instance for this object. */ + private EMSA_PSS pss; + + /** The desired length in octets of the EMSA-PSS salt. */ + private int sLen; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** + * Default 0-arguments constructor. Uses SHA-1 as the default hash and a + * 0-octet <i>salt</i>. + */ + public RSAPSSSignature() + { + this(Registry.SHA160_HASH, 0); + } + + /** + * <p>Constructs an instance of this object using the designated message + * digest algorithm as its underlying hash function, and having 0-octet + * <i>salt</i>.</p> + * + * @param mdName the canonical name of the underlying hash function. + */ + public RSAPSSSignature(String mdName) + { + this(mdName, 0); + } + + /** + * <p>Constructs an instance of this object using the designated message + * digest algorithm as its underlying hash function.</p> + * + * @param mdName the canonical name of the underlying hash function. + * @param sLen the desired length in octets of the salt to use for encoding / + * decoding signatures. + */ + public RSAPSSSignature(String mdName, int sLen) + { + this(HashFactory.getInstance(mdName), sLen); + } + + public RSAPSSSignature(IMessageDigest md, int sLen) + { + super(Registry.RSA_PSS_SIG, md); + + pss = EMSA_PSS.getInstance(md.name()); + this.sLen = sLen; + } + + /** Private constructor for cloning purposes. */ + private RSAPSSSignature(RSAPSSSignature that) + { + this(that.md.name(), that.sLen); + + this.publicKey = that.publicKey; + this.privateKey = that.privateKey; + this.md = (IMessageDigest) that.md.clone(); + this.pss = (EMSA_PSS) that.pss.clone(); + } + + // Class methods + // ------------------------------------------------------------------------- + + // Instance methods + // ------------------------------------------------------------------------- + + // Implementation of abstract methods in superclass ------------------------ + + public Object clone() + { + return new RSAPSSSignature(this); + } + + protected void setupForVerification(PublicKey k) + throws IllegalArgumentException + { + if (!(k instanceof RSAPublicKey)) + { + throw new IllegalArgumentException(); + } + publicKey = (RSAPublicKey) k; + } + + protected void setupForSigning(PrivateKey k) throws IllegalArgumentException + { + if (!(k instanceof RSAPrivateKey)) + { + throw new IllegalArgumentException(); + } + privateKey = (RSAPrivateKey) k; + } + + protected Object generateSignature() throws IllegalStateException + { + // 1. Apply the EMSA-PSS encoding operation to the message M to produce an + // encoded message EM of length CEILING((modBits ? 1)/8) octets such + // that the bit length of the integer OS2IP(EM) is at most modBits ? 1: + // EM = EMSA-PSS-Encode(M,modBits ? 1). + // Note that the octet length of EM will be one less than k if + // modBits ? 1 is divisible by 8. If the encoding operation outputs + // 'message too long' or 'encoding error,' then output 'message too + // long' or 'encoding error' and stop. + int modBits = ((RSAPrivateKey) privateKey).getModulus().bitLength(); + byte[] salt = new byte[sLen]; + this.nextRandomBytes(salt); + byte[] EM = pss.encode(md.digest(), modBits - 1, salt); + if (DEBUG && debuglevel > 8) + { + debug("EM (sign): " + Util.toString(EM)); + } + // 2. Convert the encoded message EM to an integer message representative + // m (see Section 1.2.2): m = OS2IP(EM). + BigInteger m = new BigInteger(1, EM); + // 3. Apply the RSASP signature primitive to the public key K and the + // message representative m to produce an integer signature + // representative s: s = RSASP(K,m). + BigInteger s = RSA.sign(privateKey, m); + // 4. Convert the signature representative s to a signature S of length k + // octets (see Section 1.2.1): S = I2OSP(s, k). + // 5. Output the signature S. + int k = (modBits + 7) / 8; + // return encodeSignature(s, k); + return RSA.I2OSP(s, k); + } + + protected boolean verifySignature(Object sig) throws IllegalStateException + { + if (publicKey == null) + { + throw new IllegalStateException(); + } + // byte[] S = decodeSignature(sig); + byte[] S = (byte[]) sig; + // 1. If the length of the signature S is not k octets, output 'signature + // invalid' and stop. + int modBits = ((RSAPublicKey) publicKey).getModulus().bitLength(); + int k = (modBits + 7) / 8; + if (S.length != k) + { + return false; + } + // 2. Convert the signature S to an integer signature representative s: + // s = OS2IP(S). + BigInteger s = new BigInteger(1, S); + // 3. Apply the RSAVP verification primitive to the public key (n, e) and + // the signature representative s to produce an integer message + // representative m: m = RSAVP((n, e), s). + // If RSAVP outputs 'signature representative out of range,' then + // output 'signature invalid' and stop. + BigInteger m = null; + try + { + m = RSA.verify(publicKey, s); + } + catch (IllegalArgumentException x) + { + return false; + } + // 4. Convert the message representative m to an encoded message EM of + // length emLen = CEILING((modBits - 1)/8) octets, where modBits is + // equal to the bit length of the modulus: EM = I2OSP(m, emLen). + // Note that emLen will be one less than k if modBits - 1 is divisible + // by 8. If I2OSP outputs 'integer too large,' then output 'signature + // invalid' and stop. + int emBits = modBits - 1; + int emLen = (emBits + 7) / 8; + byte[] EM = m.toByteArray(); + if (DEBUG && debuglevel > 8) + { + debug("EM (verify): " + Util.toString(EM)); + } + if (EM.length > emLen) + { + return false; + } + else if (EM.length < emLen) + { + byte[] newEM = new byte[emLen]; + System.arraycopy(EM, 0, newEM, emLen - EM.length, EM.length); + EM = newEM; + } + // 5. Apply the EMSA-PSS decoding operation to the message M and the + // encoded message EM: Result = EMSA-PSS-Decode(M, EM, emBits). If + // Result = 'consistent,' output 'signature verified.' Otherwise, + // output 'signature invalid.' + byte[] mHash = md.digest(); + boolean result = false; + try + { + result = pss.decode(mHash, EM, emBits, sLen); + } + catch (IllegalArgumentException x) + { + result = false; + } + return result; + } + + // Other instance methods -------------------------------------------------- + + /** + * Converts the <i>signature representative</i> <code>s</code> to a signature + * <code>S</code> of length <code>k</code> octets; i.e. + * <code>S = I2OSP(s, k)</code>, where <code>k = CEILING(modBits/8)</code>. + * + * @param s the <i>signature representative</i>. + * @param k the length of the output. + * @return the signature as an octet sequence. + * @exception IllegalArgumentException if the length in octets of meaningful + * bytes of <code>s</code> is greater than <code>k</code>, implying that + * <code>s</code> is not less than the RSA <i>modulus</i>. + */ + // private Object encodeSignature(BigInteger s, int k) { + // if (DEBUG && debuglevel > 8) { + // debug("s.bitLength(): "+String.valueOf(s.bitLength())); + // debug("k: "+String.valueOf(k)); + // } + // byte[] result = s.toByteArray(); + // if (DEBUG && debuglevel > 8) { + // debug("s: "+Util.toString(result)); + // debug("s (bytes): "+String.valueOf(result.length)); + // } + // if (result.length < k) { + // byte[] newResult = new byte[k]; + // System.arraycopy(result, 0, newResult, k-result.length, result.length); + // result = newResult; + // } else if (result.length > k) { // leftmost extra bytes should all be 0 + // int limit = result.length - k; + // for (int i = 0; i < limit; i++) { + // if (result[i] != 0x00) { + // throw new IllegalArgumentException("integer too large"); + // } + // } + // byte[] newResult = new byte[k]; + // System.arraycopy(result, limit, newResult, 0, k); + // result = newResult; + // } + // return result; + // } + /** + * Returns the output of a previously generated signature object as an octet + * sequence.<p> + * + * @return the octet sequence <code>S</code>. + */ + // private byte[] decodeSignature(Object signature) { + // return (byte[]) signature; + // } +} diff --git a/libjava/classpath/gnu/java/security/sig/rsa/RSAPSSSignatureRawCodec.java b/libjava/classpath/gnu/java/security/sig/rsa/RSAPSSSignatureRawCodec.java new file mode 100644 index 00000000000..64a972ca366 --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/rsa/RSAPSSSignatureRawCodec.java @@ -0,0 +1,159 @@ +/* RSAPSSSignatureRawCodec.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.sig.rsa; + +import gnu.java.security.Registry; +import gnu.java.security.sig.ISignatureCodec; + +import java.io.ByteArrayOutputStream; + +/** + * <p>An object that implements the {@link gnu.crypto.sig.ISignatureCodec} + * operations for the <i>Raw</i> format to use with RSA-PSS signatures.</p> + * + * @version $Revision: 1.1 $ + */ +public class RSAPSSSignatureRawCodec implements ISignatureCodec +{ + + // Constants and variables + // ------------------------------------------------------------------------- + + // Constructor(s) + // ------------------------------------------------------------------------- + + // implicit 0-arguments constructor + + // Class methods + // ------------------------------------------------------------------------- + + // gnu.crypto.keys.IKeyPairCodec interface implementation + // ------------------------------------------------------------------------- + + public int getFormatID() + { + return RAW_FORMAT; + } + + /** + * <p>Returns the encoded form of the designated RSA-PSS signature object + * according to the <i>Raw</i> format supported by this library.</p> + * + * <p>The <i>Raw</i> format for an RSA-PSS signature, in this implementation, + * is a byte sequence consisting of the following:</p> + * + * <ol> + * <li>4-byte magic consisting of the value of the literal + * {@link Registry#MAGIC_RAW_RSA_PSS_SIGNATURE},<li> + * <li>1-byte version consisting of the constant: 0x01,</li> + * <li>4-byte count of following bytes representing the RSA-PSS signature + * bytes in internet order,</li> + * <li>the RSA-PSS signature bytes in internet order.</li> + * </ol> + * + * @param signature the signature to encode, consisting of the output of the + * <code>sign()</code> method of a {@link RSAPSSSignature} instance --a byte + * array. + * @return the <i>Raw</i> format encoding of the designated signature. + * @exception IllegalArgumentException if the designated signature is not an + * RSA-PSS one. + */ + public byte[] encodeSignature(Object signature) + { + byte[] buffer; + try + { + buffer = (byte[]) signature; + } + catch (Exception x) + { + throw new IllegalArgumentException("key"); + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + + // magic + baos.write(Registry.MAGIC_RAW_RSA_PSS_SIGNATURE[0]); + baos.write(Registry.MAGIC_RAW_RSA_PSS_SIGNATURE[1]); + baos.write(Registry.MAGIC_RAW_RSA_PSS_SIGNATURE[2]); + baos.write(Registry.MAGIC_RAW_RSA_PSS_SIGNATURE[3]); + + // version + baos.write(0x01); + + // signature bytes + int length = buffer.length; + baos.write(length >>> 24); + baos.write((length >>> 16) & 0xFF); + baos.write((length >>> 8) & 0xFF); + baos.write(length & 0xFF); + baos.write(buffer, 0, length); + + return baos.toByteArray(); + } + + public Object decodeSignature(byte[] k) + { + // magic + if (k[0] != Registry.MAGIC_RAW_RSA_PSS_SIGNATURE[0] + || k[1] != Registry.MAGIC_RAW_RSA_PSS_SIGNATURE[1] + || k[2] != Registry.MAGIC_RAW_RSA_PSS_SIGNATURE[2] + || k[3] != Registry.MAGIC_RAW_RSA_PSS_SIGNATURE[3]) + { + throw new IllegalArgumentException("magic"); + } + + // version + if (k[4] != 0x01) + { + throw new IllegalArgumentException("version"); + } + + int i = 5; + int l; + + // signature bytes + l = k[i++] << 24 | (k[i++] & 0xFF) << 16 | (k[i++] & 0xFF) << 8 + | (k[i++] & 0xFF); + byte[] result = new byte[l]; + System.arraycopy(k, i, result, 0, l); + + return result; + } +} diff --git a/libjava/classpath/gnu/java/security/sig/rsa/RSASignatureFactory.java b/libjava/classpath/gnu/java/security/sig/rsa/RSASignatureFactory.java new file mode 100644 index 00000000000..b8e12caf769 --- /dev/null +++ b/libjava/classpath/gnu/java/security/sig/rsa/RSASignatureFactory.java @@ -0,0 +1,176 @@ +/* RSASignatureFactory.java -- A Factory class to instantiate RSA Signatures + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.sig.rsa; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import gnu.java.security.Registry; +import gnu.java.security.hash.HashFactory; +import gnu.java.security.hash.IMessageDigest; +import gnu.java.security.sig.ISignature; + +/** + * A Factory class to instantiate RSA Signature classes. + */ +public class RSASignatureFactory +{ + private static Set names; + + /** + * Private constructor to enforce usage through Factory (class) methods. + */ + private RSASignatureFactory() + { + super(); + } + + /** + * Returns a new instance of an RSA Signature given its name. The name of an + * RSA Signature always starts with <code>rsa-</code>, followed by either + * <code>pss</code> or <code>pkcs1_v1.5</code>. An optional message digest + * name, to be used with the RSA signature may be specified by appending the + * hyphen chanaracter <code>-</code> followed by the canonical message digest + * algorithm name. When no message digest algorithm name is given, SHA-160 is + * used. + * + * @param name the composite RSA signature name. + * @return a new instance of an RSA Signature algorithm implementation. + * Returns <code>null</code> if the given name does not correspond to any + * supported RSA Signature encoding and message digest combination. + */ + public static final ISignature getInstance(String name) + { + if (name == null) + return null; + + name = name.trim(); + if (name.length() == 0) + return null; + + name = name.toLowerCase(); + if (! name.startsWith(Registry.RSA_SIG_PREFIX)) + return null; + + name = name.substring(Registry.RSA_SIG_PREFIX.length()).trim(); + if (name.startsWith(Registry.RSA_PSS_ENCODING)) + return getPSSSignature(name); + else if (name.startsWith(Registry.RSA_PKCS1_V1_5_ENCODING)) + return getPKCS1Signature(name); + else + return null; + } + + /** + * Returns a {@link Set} of names of <i>RSA</i> signatures supported by this + * <i>Factory</i>. + * + * @return a {@link Set} of RSA Signature algorithm names (Strings). + */ + public static synchronized final Set getNames() + { + if (names == null) + { + Set hashNames = HashFactory.getNames(); + HashSet hs = new HashSet(); + for (Iterator it = hashNames.iterator(); it.hasNext();) + { + String mdName = (String) it.next(); + hs.add(Registry.RSA_PSS_SIG + "-" + mdName); + } + + hs.add(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.MD2_HASH); + hs.add(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.MD5_HASH); + hs.add(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.SHA160_HASH); + hs.add(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.SHA256_HASH); + hs.add(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.SHA384_HASH); + hs.add(Registry.RSA_PKCS1_V1_5_SIG + "-" + Registry.SHA512_HASH); + + names = Collections.unmodifiableSet(hs); + } + + return names; + } + + private static final ISignature getPSSSignature(String name) + { + name = name.substring(Registry.RSA_PSS_ENCODING.length()).trim(); + // remove the hyphen if found at the beginning + if (name.startsWith("-")) + name = name.substring(1).trim(); + + IMessageDigest md; + if (name.length() == 0) + md = HashFactory.getInstance(Registry.SHA160_HASH); + else + { + // check if there is such a hash + md = HashFactory.getInstance(name); + if (md == null) + return null; + } + + ISignature result = new RSAPSSSignature(md, 0); + return result; + } + + private static final ISignature getPKCS1Signature(String name) + { + name = name.substring(Registry.RSA_PKCS1_V1_5_ENCODING.length()).trim(); + // remove the hyphen if found at the beginning + if (name.startsWith("-")) + name = name.substring(1).trim(); + + IMessageDigest md; + if (name.length() == 0) + md = HashFactory.getInstance(Registry.SHA160_HASH); + else + { + // check if there is such a hash + md = HashFactory.getInstance(name); + if (md == null) + return null; + } + + ISignature result = new RSAPKCS1V1_5Signature(md); + return result; + } +} diff --git a/libjava/classpath/gnu/java/security/util/Base64.java b/libjava/classpath/gnu/java/security/util/Base64.java new file mode 100644 index 00000000000..f9998c38f48 --- /dev/null +++ b/libjava/classpath/gnu/java/security/util/Base64.java @@ -0,0 +1,396 @@ +/* Base64.java -- + Copyright (C) 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.util; + +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; + +/** + * Most of this implementation is from Robert Harder's public domain Base64 + * code (version 1.4.1 available from <http://iharder.net/xmlizable>). + */ +public class Base64 +{ + + // Debugging methods and variables + // ------------------------------------------------------------------------- + + private static final String NAME = "Base64"; + + private static final boolean DEBUG = true; + + private static final int debuglevel = 9; + + private static final PrintWriter err = new PrintWriter(System.out, true); + + private static void debug(String s) + { + err.println(">>> " + NAME + ": " + s); + } + + // Constants and variables + // ------------------------------------------------------------------------- + + /** Maximum line length (76) of Base64 output. */ + private static final int MAX_LINE_LENGTH = 76; + + /** The new line character (\n) as one byte. */ + private static final byte NEW_LINE = (byte) '\n'; + + /** The equals sign (=) as a byte. */ + private static final byte EQUALS_SIGN = (byte) '='; + + private static final byte WHITE_SPACE_ENC = -5; // white space in encoding + + private static final byte EQUALS_SIGN_ENC = -1; // equals sign in encoding + + /** The 64 valid Base64 values. */ + private static final byte[] ALPHABET = { (byte) 'A', (byte) 'B', (byte) 'C', + (byte) 'D', (byte) 'E', (byte) 'F', + (byte) 'G', (byte) 'H', (byte) 'I', + (byte) 'J', (byte) 'K', (byte) 'L', + (byte) 'M', (byte) 'N', (byte) 'O', + (byte) 'P', (byte) 'Q', (byte) 'R', + (byte) 'S', (byte) 'T', (byte) 'U', + (byte) 'V', (byte) 'W', (byte) 'X', + (byte) 'Y', (byte) 'Z', (byte) 'a', + (byte) 'b', (byte) 'c', (byte) 'd', + (byte) 'e', (byte) 'f', (byte) 'g', + (byte) 'h', (byte) 'i', (byte) 'j', + (byte) 'k', (byte) 'l', (byte) 'm', + (byte) 'n', (byte) 'o', (byte) 'p', + (byte) 'q', (byte) 'r', (byte) 's', + (byte) 't', (byte) 'u', (byte) 'v', + (byte) 'w', (byte) 'x', (byte) 'y', + (byte) 'z', (byte) '0', (byte) '1', + (byte) '2', (byte) '3', (byte) '4', + (byte) '5', (byte) '6', (byte) '7', + (byte) '8', (byte) '9', (byte) '+', + (byte) '/' }; + + /** + * Translates a Base64 value to either its 6-bit reconstruction value or a + * negative number indicating some other meaning. + */ + private static final byte[] DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, + -9, // Decimal 33 - 42 + 62, // Plus sign at decimal 43 + -9, -9, -9, // Decimal 44 - 46 + 63, // Slash at decimal 47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, // Letters 'A' through 'N' + 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, // Letters 'O' through 'Z' + -9, -9, -9, -9, -9, -9, // Decimal 91 - 96 + 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, // Letters 'a' through 'm' + 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, // Letters 'n' through 'z' + -9, -9, -9, -9 // Decimal 123 - 126 + }; + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial private ctor to enfore Singleton pattern. */ + private Base64() + { + super(); + } + + // Class methods + // ------------------------------------------------------------------------- + + /** + * Encodes a byte array into Base64 notation. Equivalent to calling + * <code>encode(source, 0, source.length)</code>. + * + * @param src the data to convert. + */ + public static final String encode(final byte[] src) + { + return encode(src, 0, src.length, true); + } + + /** + * Encodes a byte array into Base64 notation. + * + * @param src the data to convert. + * @param off offset in array where conversion should begin. + * @param len length of data to convert. + * @param breakLines break lines at 80 characters or less. + */ + public static final String encode(final byte[] src, final int off, + final int len, final boolean breakLines) + { + final int len43 = len * 4 / 3; + final byte[] outBuff = new byte[len43 // Main 4:3 + + ((len % 3) > 0 ? 4 : 0) // Account for padding + + (breakLines ? (len43 / MAX_LINE_LENGTH) + : 0)]; // New lines + int d = 0; + int e = 0; + final int len2 = len - 2; + int lineLength = 0; + for (; d < len2; d += 3, e += 4) + { + encode3to4(src, d + off, 3, outBuff, e); + lineLength += 4; + if (breakLines && lineLength == MAX_LINE_LENGTH) + { + outBuff[e + 4] = NEW_LINE; + e++; + lineLength = 0; + } + } + + if (d < len) + { // padding needed + encode3to4(src, d + off, len - d, outBuff, e); + e += 4; + } + + return new String(outBuff, 0, e); + } + + /** + * Decodes data from Base64 notation. + * + * @param s the string to decode. + * @return the decoded data. + */ + public static final byte[] decode(final String s) + throws UnsupportedEncodingException + { + final byte[] bytes; + bytes = s.getBytes("US-ASCII"); + return decode(bytes, 0, bytes.length); + } + + /** + * Decodes Base64 content in byte array format and returns the decoded byte + * array. + * + * @param src the Base64 encoded data. + * @param off the offset of where to begin decoding. + * @param len the length of characters to decode. + * @return the decoded data. + * @throws IllegalArgumentException if <code>src</code> contains an illegal + * Base-64 character. + */ + public static byte[] decode(final byte[] src, final int off, final int len) + { + final int len34 = len * 3 / 4; + final byte[] outBuff = new byte[len34]; // Upper limit on size of output + int outBuffPosn = 0; + final byte[] b4 = new byte[4]; + int b4Posn = 0; + int i; + byte sbiCrop, sbiDecode; + for (i = off; i < off + len; i++) + { + sbiCrop = (byte) (src[i] & 0x7F); // Only the low seven bits + sbiDecode = DECODABET[sbiCrop]; + if (sbiDecode >= WHITE_SPACE_ENC) + { // White space, Equals sign or better + if (sbiDecode >= EQUALS_SIGN_ENC) + { + b4[b4Posn++] = sbiCrop; + if (b4Posn > 3) + { + outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn); + b4Posn = 0; + // If that was the equals sign, break out of 'for' loop + if (sbiCrop == EQUALS_SIGN) + break; + } // end if: quartet built + } // end if: equals sign or better + } + else + { + throw new IllegalArgumentException("Illegal BASE-64 character at #" + + i + ": " + src[i] + + "(decimal)"); + } + } + + final byte[] result = new byte[outBuffPosn]; + System.arraycopy(outBuff, 0, result, 0, outBuffPosn); + return result; + } + + /** + * <p>Encodes up to three bytes of the array <code>src</code> and writes + * the resulting four Base64 bytes to <code>dest</code>. The source and + * destination arrays can be manipulated anywhere along their length by + * specifying <code>sOffset</code> and <code>dOffset</code>.</p> + * + * <p>This method does not check to make sure the arrays are large enough to + * accomodate <code>sOffset + 3</code> for the <code>src</code> array or + * <code>dOffset + 4</code> for the <code>dest</code> array. The actual + * number of significant bytes in the input array is given by + * <code>numBytes</code>.</p> + * + * @param src the array to convert. + * @param sOffset the index where conversion begins. + * @param numBytes the number of significant bytes in your array. + * @param dest the array to hold the conversion. + * @param dOffset the index where output will be put. + * @return the <code>destination</code> array. + */ + private static final byte[] encode3to4(final byte[] src, final int sOffset, + final int numBytes, final byte[] dest, + final int dOffset) + { + // 1 2 3 + // 01234567890123456789012345678901 Bit position + // --------000000001111111122222222 Array position from threeBytes + // --------| || || || | Six bit groups to index ALPHABET + // >>18 >>12 >> 6 >> 0 Right shift necessary + // 0x3F 0x3F 0x3F Additional AND + + // Create buffer with zero-padding if there are only one or two + // significant bytes passed in the array. + // We have to shift left 24 in order to flush out the 1's that appear + // when Java treats a value as negative that is cast from a byte to an int. + final int inBuff = (numBytes > 0 ? ((src[sOffset] << 24) >>> 8) : 0) + | (numBytes > 1 ? ((src[sOffset + 1] << 24) >>> 16) : 0) + | (numBytes > 2 ? ((src[sOffset + 2] << 24) >>> 24) : 0); + switch (numBytes) + { + case 3: + dest[dOffset] = ALPHABET[(inBuff >>> 18)]; + dest[dOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3F]; + dest[dOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3F]; + dest[dOffset + 3] = ALPHABET[(inBuff) & 0x3F]; + break; + case 2: + dest[dOffset] = ALPHABET[(inBuff >>> 18)]; + dest[dOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3F]; + dest[dOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3F]; + dest[dOffset + 3] = EQUALS_SIGN; + break; + case 1: + dest[dOffset] = ALPHABET[(inBuff >>> 18)]; + dest[dOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3F]; + dest[dOffset + 2] = EQUALS_SIGN; + dest[dOffset + 3] = EQUALS_SIGN; + break; + } + return dest; + } + + /** + * <p>Decodes four bytes from array <code>src</code> and writes the + * resulting bytes (up to three of them) to <code>dest</code>.</p> + * + * <p>The source and destination arrays can be manipulated anywhere along + * their length by specifying <code>sOffset</code> and <code>dOffset</code>. + * </p> + * + * <p>This method does not check to make sure your arrays are large enough + * to accomodate <code>sOffset + 4</code> for the <code>src</code> array or + * <code>dOffset + 3</code> for the <code>dest</code> array. This method + * returns the actual number of bytes that were converted from the Base64 + * encoding.</p> + * + * @param src the array to convert. + * @param sOffset the index where conversion begins. + * @param dest the array to hold the conversion. + * @param dOffset the index where output will be put. + * @return the number of decoded bytes converted. + */ + private static final int decode4to3(final byte[] src, final int sOffset, + final byte[] dest, final int dOffset) + { + if (src[sOffset + 2] == EQUALS_SIGN) + { // Example: Dk== + final int outBuff = ((DECODABET[src[sOffset]] & 0xFF) << 18) + | ((DECODABET[src[sOffset + 1]] & 0xFF) << 12); + dest[dOffset] = (byte) (outBuff >>> 16); + return 1; + } + + if (src[sOffset + 3] == EQUALS_SIGN) + { // Example: DkL= + final int outBuff = ((DECODABET[src[sOffset]] & 0xFF) << 18) + | ((DECODABET[src[sOffset + 1]] & 0xFF) << 12) + | ((DECODABET[src[sOffset + 2]] & 0xFF) << 6); + dest[dOffset] = (byte) (outBuff >>> 16); + dest[dOffset + 1] = (byte) (outBuff >>> 8); + return 2; + } + + try + { // Example: DkLE + final int outBuff = ((DECODABET[src[sOffset]] & 0xFF) << 18) + | ((DECODABET[src[sOffset + 1]] & 0xFF) << 12) + | ((DECODABET[src[sOffset + 2]] & 0xFF) << 6) + | ((DECODABET[src[sOffset + 3]] & 0xFF)); + dest[dOffset] = (byte) (outBuff >> 16); + dest[dOffset + 1] = (byte) (outBuff >> 8); + dest[dOffset + 2] = (byte) outBuff; + return 3; + } + catch (Exception x) + { + if (DEBUG && debuglevel > 8) + { + debug("" + src[sOffset] + ": " + (DECODABET[src[sOffset]])); + debug("" + src[sOffset + 1] + ": " + (DECODABET[src[sOffset + 1]])); + debug("" + src[sOffset + 2] + ": " + (DECODABET[src[sOffset + 2]])); + debug("" + src[sOffset + 3] + ": " + (DECODABET[src[sOffset + 3]])); + } + return -1; + } + } +} diff --git a/libjava/classpath/gnu/java/security/util/DerUtil.java b/libjava/classpath/gnu/java/security/util/DerUtil.java new file mode 100644 index 00000000000..26232ba9843 --- /dev/null +++ b/libjava/classpath/gnu/java/security/util/DerUtil.java @@ -0,0 +1,64 @@ +/* DerUtil.java -- Utility methods for DER read/write operations + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.util; + +import gnu.java.security.der.DEREncodingException; +import gnu.java.security.der.DERValue; + +import java.math.BigInteger; + +/** + * Utility methods for DER encoding handling. + */ +public abstract class DerUtil +{ + public static final void checkIsConstructed(DERValue v, String msg) + throws DEREncodingException + { + if (! v.isConstructed()) + throw new DEREncodingException(msg); + } + + public static final void checkIsBigInteger(DERValue v, String msg) + throws DEREncodingException + { + if (! (v.getValue() instanceof BigInteger)) + throw new DEREncodingException(msg); + } +} diff --git a/libjava/classpath/gnu/java/security/util/ExpirableObject.java b/libjava/classpath/gnu/java/security/util/ExpirableObject.java new file mode 100644 index 00000000000..2d4452015af --- /dev/null +++ b/libjava/classpath/gnu/java/security/util/ExpirableObject.java @@ -0,0 +1,172 @@ +/* ExpirableObject.java -- an object that is automatically destroyed. + Copyright (C) 2004, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.util; + +import java.util.Timer; +import java.util.TimerTask; + +import javax.security.auth.DestroyFailedException; +import javax.security.auth.Destroyable; + +/** + * The base class for objects with sensitive data that are automatically + * destroyed after a timeout elapses. On creation, an object that extends + * this class will automatically be added to a {@link Timer} object that, + * once a timeout elapses, will automatically call the {@link + * Destroyable#destroy()} method. + * + * <p>Concrete subclasses must implement the {@link doDestroy()} method + * instead of {@link Destroyable#destroy()}; the behavior of that method + * should match exactly the behavior desired of <code>destroy()</code>. + * + * <p>Note that if a {@link DestroyFailedException} occurs when the timeout + * expires, it will not be reported. + * + * @see Destroyable + */ +public abstract class ExpirableObject implements Destroyable +{ + + // Constants and fields. + // ------------------------------------------------------------------------- + + /** + * The default timeout, used in the default constructor. + */ + public static final long DEFAULT_TIMEOUT = 3600000L; + + /** + * The timer that expires instances. + */ + private static final Timer EXPIRER = new Timer(true); + + /** + * A reference to the task that will destroy this object when the timeout + * expires. + */ + private final Destroyer destroyer; + + // Constructors. + // ------------------------------------------------------------------------- + + /** + * Create a new expirable object that will expire after one hour. + */ + protected ExpirableObject() + { + this(DEFAULT_TIMEOUT); + } + + /** + * Create a new expirable object that will expire after the specified + * timeout. + * + * @param delay The delay before expiration. + * @throws IllegalArgumentException If <i>delay</i> is negative, or if + * <code>delay + System.currentTimeMillis()</code> is negative. + */ + protected ExpirableObject(final long delay) + { + destroyer = new Destroyer(this); + EXPIRER.schedule(destroyer, delay); + } + + // Instance methods. + // ------------------------------------------------------------------------- + + /** + * Destroys this object. This method calls {@link doDestroy}, then, if + * no exception is thrown, cancels the task that would destroy this object + * when the timeout is reached. + * + * @throws DestroyFailedException If this operation fails. + */ + public final void destroy() throws DestroyFailedException + { + doDestroy(); + destroyer.cancel(); + } + + /** + * Subclasses must implement this method instead of the {@link + * Destroyable#destroy()} method. + * + * @throws DestroyFailedException If this operation fails. + */ + protected abstract void doDestroy() throws DestroyFailedException; + + // Inner classes. + // ------------------------------------------------------------------------- + + /** + * The task that destroys the target when the timeout elapses. + */ + private final class Destroyer extends TimerTask + { + + // Fields. + // ----------------------------------------------------------------------- + + private final ExpirableObject target; + + // Constructor. + // ----------------------------------------------------------------------- + + Destroyer(final ExpirableObject target) + { + super(); + this.target = target; + } + + // Instance methods. + // ----------------------------------------------------------------------- + + public void run() + { + try + { + if (!target.isDestroyed()) + target.doDestroy(); + } + catch (DestroyFailedException dfe) + { + } + } + } +} diff --git a/libjava/classpath/gnu/java/security/util/FormatUtil.java b/libjava/classpath/gnu/java/security/util/FormatUtil.java new file mode 100644 index 00000000000..eed669cc3a4 --- /dev/null +++ b/libjava/classpath/gnu/java/security/util/FormatUtil.java @@ -0,0 +1,140 @@ +/* FormatUtil.java -- Encoding and decoding format utility methods + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.util; + +import gnu.java.security.Registry; + +/** + * Encoding and decoding format utility methods. + */ +public class FormatUtil +{ + /** Trivial constructor to enforce Singleton pattern. */ + private FormatUtil() + { + super(); + } + + /** + * Returns the fully qualified name of the designated encoding ID. + * + * @param formatID the unique identifier of the encoding format. + * @return the fully qualified name of the designated format. Returns + * <code>null</code> if no such encoding format is known. + */ + public static final String getEncodingName(int formatID) + { + String result = null; + switch (formatID) + { + case Registry.RAW_ENCODING_ID: + result = Registry.RAW_ENCODING; + break; + case Registry.X509_ENCODING_ID: + result = Registry.X509_ENCODING; + break; + case Registry.PKCS8_ENCODING_ID: + result = Registry.PKCS8_ENCODING; + break; + case Registry.ASN1_ENCODING_ID: + result = Registry.ASN1_ENCODING; + break; + } + + return result; + } + + /** + * Returns the short name of the designated encoding ID. This is used by the + * JCE Adapters. + * + * @param formatID the unique identifier of the encoding format. + * @return the short name of the designated format. Returns <code>null</code> + * if no such encoding format is known. + */ + public static final String getEncodingShortName(int formatID) + { + String result = null; + switch (formatID) + { + case Registry.RAW_ENCODING_ID: + result = Registry.RAW_ENCODING_SHORT_NAME; + break; + case Registry.X509_ENCODING_ID: + result = Registry.X509_ENCODING_SORT_NAME; + break; + case Registry.PKCS8_ENCODING_ID: + result = Registry.PKCS8_ENCODING_SHORT_NAME; + break; + case Registry.ASN1_ENCODING_ID: + result = Registry.ASN1_ENCODING_SHORT_NAME; + break; + } + + return result; + } + + /** + * Returns the identifier of the encoding format given its short name. + * + * @param name the case-insensitive canonical short name of an encoding + * format. + * @return the identifier of the designated encoding format, or <code>0</code> + * if the name does not correspond to any known format. + */ + public static final int getFormatID(String name) + { + if (name == null) + return 0; + + name = name.trim(); + if (name.length() == 0) + return 0; + + int result = 0; + if (name.equalsIgnoreCase(Registry.RAW_ENCODING_SHORT_NAME)) + result = Registry.RAW_ENCODING_ID; + else if (name.equalsIgnoreCase(Registry.X509_ENCODING_SORT_NAME)) + result = Registry.X509_ENCODING_ID; + else if (name.equalsIgnoreCase(Registry.PKCS8_ENCODING_SHORT_NAME)) + result = Registry.PKCS8_ENCODING_ID; + + return result; + } +} diff --git a/libjava/classpath/gnu/java/security/util/PRNG.java b/libjava/classpath/gnu/java/security/util/PRNG.java new file mode 100644 index 00000000000..138cc6bcb0c --- /dev/null +++ b/libjava/classpath/gnu/java/security/util/PRNG.java @@ -0,0 +1,156 @@ +/* PRNG.java -- A Utility methods for default source of randomness + Copyright (C) 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath 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 Classpath 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 GNU Classpath; 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. */ + + +package gnu.java.security.util; + +import java.util.HashMap; + +import gnu.java.security.prng.IRandom; +import gnu.java.security.prng.LimitReachedException; +import gnu.java.security.prng.MDGenerator; + +/** + * A useful hash-based (SHA) pseudo-random number generator used + * throughout this library. + * + * @see MDGenerator + */ +public class PRNG +{ + // Constans and fields + // -------------------------------------------------------------------------- + + /** The underlying {@link IRandom}. */ + private IRandom delegate; + + // Constructor(s) + // -------------------------------------------------------------------------- + + /** + * Private constructor to enforce using the Factory method. + * + * @param delegate + * the undelying {@link IRandom} object used. + */ + private PRNG(IRandom delegate) + { + super(); + + this.delegate = delegate; + } + + // Class methods + // -------------------------------------------------------------------------- + + public static final PRNG getInstance() + { + IRandom delegate = new MDGenerator(); + try + { + HashMap map = new HashMap(); + // initialise it with a seed + long t = System.currentTimeMillis(); + byte[] seed = new byte[] { + (byte) (t >>> 56), (byte) (t >>> 48), + (byte) (t >>> 40), (byte) (t >>> 32), + (byte) (t >>> 24), (byte) (t >>> 16), + (byte) (t >>> 8), (byte) t}; + map.put(MDGenerator.SEEED, seed); + delegate.init(map); // default is to use SHA-1 hash + } + catch (Exception x) + { + throw new ExceptionInInitializerError(x); + } + + return new PRNG(delegate); + } + + // Instance methods + // -------------------------------------------------------------------------- + + /** + * Completely fills the designated <code>buffer</code> with random data + * generated by the underlying delegate. + * + * @param buffer + * the place holder of random bytes generated by the underlying + * delegate. On output, the contents of <code>buffer</code> are + * replaced with pseudo-random data, iff the <code>buffer</code> + * size is not zero. + */ + public void nextBytes(byte[] buffer) + { + nextBytes(buffer, 0, buffer.length); + } + + /** + * Fills the designated <code>buffer</code>, starting from byte at position + * <code>offset</code> with, at most, <code>length</code> bytes of random + * data generated by the underlying delegate. + * + * @see IRandom#nextBytes + */ + public void nextBytes(byte[] buffer, int offset, int length) + { + try + { + delegate.nextBytes(buffer, offset, length); + } + catch (LimitReachedException x) // re-initialise with a seed + { + try + { + HashMap map = new HashMap(); + long t = System.currentTimeMillis(); + byte[] seed = new byte[] { + (byte)(t >>> 56), (byte)(t >>> 48), + (byte)(t >>> 40), (byte)(t >>> 32), + (byte)(t >>> 24), (byte)(t >>> 16), + (byte)(t >>> 8), (byte) t }; + map.put(MDGenerator.SEEED, seed); + delegate.init(map); // default is to use SHA-1 hash + delegate.nextBytes(buffer, offset, length); + } + catch (Exception y) + { + throw new ExceptionInInitializerError(y); + } + } + } +} diff --git a/libjava/classpath/gnu/java/security/util/Prime2.java b/libjava/classpath/gnu/java/security/util/Prime2.java new file mode 100644 index 00000000000..6e46f5fcadc --- /dev/null +++ b/libjava/classpath/gnu/java/security/util/Prime2.java @@ -0,0 +1,417 @@ +/* Prime2.java -- + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.util; + +import java.io.PrintWriter; +import java.lang.ref.WeakReference; +import java.math.BigInteger; +import java.util.Map; +import java.util.WeakHashMap; + +/** + * <p>A collection of prime number related utilities used in this library.</p> + */ +public class Prime2 +{ + + // Debugging methods and variables + // ------------------------------------------------------------------------- + + private static final String NAME = "prime"; + + private static final boolean DEBUG = false; + + private static final int debuglevel = 5; + + private static final PrintWriter err = new PrintWriter(System.out, true); + + private static void debug(String s) + { + err.println(">>> " + NAME + ": " + s); + } + + // Constants and variables + // ------------------------------------------------------------------------- + + private static final int DEFAULT_CERTAINTY = 20; // XXX is this a good value? + + private static final BigInteger ZERO = BigInteger.ZERO; + + private static final BigInteger ONE = BigInteger.ONE; + + private static final BigInteger TWO = BigInteger.valueOf(2L); + + /** + * The first SMALL_PRIME primes: Algorithm P, section 1.3.2, The Art of + * Computer Programming, Donald E. Knuth. + */ + private static final int SMALL_PRIME_COUNT = 1000; + + private static final BigInteger[] SMALL_PRIME = new BigInteger[SMALL_PRIME_COUNT]; + static + { + long time = -System.currentTimeMillis(); + SMALL_PRIME[0] = TWO; + int N = 3; + int J = 0; + int prime; + P2: while (true) + { + SMALL_PRIME[++J] = BigInteger.valueOf(N); + if (J >= 999) + { + break P2; + } + P4: while (true) + { + N += 2; + P6: for (int K = 1; true; K++) + { + prime = SMALL_PRIME[K].intValue(); + if ((N % prime) == 0) + { + continue P4; + } + else if ((N / prime) <= prime) + { + continue P2; + } + } + } + } + time += System.currentTimeMillis(); + if (DEBUG && debuglevel > 8) + { + StringBuffer sb; + for (int i = 0; i < (SMALL_PRIME_COUNT / 10); i++) + { + sb = new StringBuffer(); + for (int j = 0; j < 10; j++) + { + sb.append(String.valueOf(SMALL_PRIME[i * 10 + j])).append(" "); + } + debug(sb.toString()); + } + } + if (DEBUG && debuglevel > 4) + { + debug("Generating first " + String.valueOf(SMALL_PRIME_COUNT) + + " primes took: " + String.valueOf(time) + " ms."); + } + } + + private static final Map knownPrimes = new WeakHashMap(); + + // Constructor(s) + // ------------------------------------------------------------------------- + + /** Trivial constructor to enforce Singleton pattern. */ + private Prime2() + { + super(); + } + + // Class methods + // ------------------------------------------------------------------------- + + /** + * <p>Trial division for the first 1000 small primes.</p> + * + * <p>Returns <code>true</code> if at least one small prime, among the first + * 1000 ones, was found to divide the designated number. Retuens <code>false</code> + * otherwise.</p> + * + * @param w the number to test. + * @return <code>true</code> if at least one small prime was found to divide + * the designated number. + */ + public static boolean hasSmallPrimeDivisor(BigInteger w) + { + BigInteger prime; + for (int i = 0; i < SMALL_PRIME_COUNT; i++) + { + prime = SMALL_PRIME[i]; + if (w.mod(prime).equals(ZERO)) + { + if (DEBUG && debuglevel > 4) + { + debug(prime.toString(16) + " | " + w.toString(16) + "..."); + } + return true; + } + } + if (DEBUG && debuglevel > 4) + { + debug(w.toString(16) + " has no small prime divisors..."); + } + return false; + } + + /** + * <p>Java port of Colin Plumb primality test (Euler Criterion) + * implementation for a base of 2 --from bnlib-1.1 release, function + * primeTest() in prime.c. this is his comments.</p> + * + * <p>"Now, check that bn is prime. If it passes to the base 2, it's prime + * beyond all reasonable doubt, and everything else is just gravy, but it + * gives people warm fuzzies to do it.</p> + * + * <p>This starts with verifying Euler's criterion for a base of 2. This is + * the fastest pseudoprimality test that I know of, saving a modular squaring + * over a Fermat test, as well as being stronger. 7/8 of the time, it's as + * strong as a strong pseudoprimality test, too. (The exception being when + * <code>bn == 1 mod 8</code> and <code>2</code> is a quartic residue, i.e. + * <code>bn</code> is of the form <code>a^2 + (8*b)^2</code>.) The precise + * series of tricks used here is not documented anywhere, so here's an + * explanation. Euler's criterion states that if <code>p</code> is prime + * then <code>a^((p-1)/2)</code> is congruent to <code>Jacobi(a,p)</code>, + * modulo <code>p</code>. <code>Jacobi(a, p)</code> is a function which is + * <code>+1</code> if a is a square modulo <code>p</code>, and <code>-1</code> + * if it is not. For <code>a = 2</code>, this is particularly simple. It's + * <code>+1</code> if <code>p == +/-1 (mod 8)</code>, and <code>-1</code> if + * <code>m == +/-3 (mod 8)</code>. If <code>p == 3 (mod 4)</code>, then all + * a strong test does is compute <code>2^((p-1)/2)</code>. and see if it's + * <code>+1</code> or <code>-1</code>. (Euler's criterion says <i>which</i> + * it should be.) If <code>p == 5 (mod 8)</code>, then <code>2^((p-1)/2)</code> + * is <code>-1</code>, so the initial step in a strong test, looking at + * <code>2^((p-1)/4)</code>, is wasted --you're not going to find a + * <code>+/-1</code> before then if it <b>is</b> prime, and it shouldn't + * have either of those values if it isn't. So don't bother.</p> + * + * <p>The remaining case is <code>p == 1 (mod 8)</code>. In this case, we + * expect <code>2^((p-1)/2) == 1 (mod p)</code>, so we expect that the + * square root of this, <code>2^((p-1)/4)</code>, will be <code>+/-1 (mod p) + * </code>. Evaluating this saves us a modular squaring 1/4 of the time. If + * it's <code>-1</code>, a strong pseudoprimality test would call <code>p</code> + * prime as well. Only if the result is <code>+1</code>, indicating that + * <code>2</code> is not only a quadratic residue, but a quartic one as well, + * does a strong pseudoprimality test verify more things than this test does. + * Good enough.</p> + * + * <p>We could back that down another step, looking at <code>2^((p-1)/8)</code> + * if there was a cheap way to determine if <code>2</code> were expected to + * be a quartic residue or not. Dirichlet proved that <code>2</code> is a + * quadratic residue iff <code>p</code> is of the form <code>a^2 + (8*b^2)</code>. + * All primes <code>== 1 (mod 4)</code> can be expressed as <code>a^2 + + * (2*b)^2</code>, but I see no cheap way to evaluate this condition."</p> + * + * @param bn the number to test. + * @return <code>true</code> iff the designated number passes Euler criterion + * as implemented by Colin Plumb in his <i>bnlib</i> version 1.1. + */ + public static boolean passEulerCriterion(final BigInteger bn) + { + BigInteger bn_minus_one = bn.subtract(ONE); + BigInteger e = bn_minus_one; + // l is the 3 least-significant bits of e + int l = e.and(BigInteger.valueOf(7L)).intValue(); + int j = 1; // Where to start in prime array for strong prime tests + BigInteger a; + int k; + + if (l != 0) + { + e = e.shiftRight(1); + a = TWO.modPow(e, bn); + if (l == 6) // bn == 7 mod 8, expect +1 + { + if (a.bitLength() != 1) + { + debugBI("Fails Euler criterion #1", bn); + return false; // Not prime + } + k = 1; + } + else // bn == 3 or 5 mod 8, expect -1 == bn-1 + { + a = a.add(ONE); + if (a.compareTo(bn) != 0) + { + debugBI("Fails Euler criterion #2", bn); + return false; // Not prime + } + k = 1; + if ((l & 4) != 0) // bn == 5 mod 8, make odd for strong tests + { + e = e.shiftRight(1); + k = 2; + } + } + } + else // bn == 1 mod 8, expect 2^((bn-1)/4) == +/-1 mod bn + { + e = e.shiftRight(2); + a = TWO.modPow(e, bn); + if (a.bitLength() == 1) + j = 0; // Re-do strong prime test to base 2 + else + { + a = a.add(ONE); + if (a.compareTo(bn) != 0) + { + debugBI("Fails Euler criterion #3", bn); + return false; // Not prime + } + } + // bnMakeOdd(n) = d * 2^s. Replaces n with d and returns s. + k = e.getLowestSetBit(); + e = e.shiftRight(k); + k += 2; + } + // It's prime! Now go on to confirmation tests + + // Now, e = (bn-1)/2^k is odd. k >= 1, and has a given value with + // probability 2^-k, so its expected value is 2. j = 1 in the usual case + // when the previous test was as good as a strong prime test, but 1/8 of + // the time, j = 0 because the strong prime test to the base 2 needs to + // be re-done. + for (int i = j; i < 7; i++) // try only the first 7 primes + { + a = SMALL_PRIME[i]; + a = a.modPow(e, bn); + if (a.bitLength() == 1) + continue; // Passed this test + + l = k; + while (true) + { +// a = a.add(ONE); +// if (a.compareTo(w) == 0) { // Was result bn-1? + if (a.compareTo(bn_minus_one) == 0) // Was result bn-1? + break; // Prime + + if (--l == 0) // Reached end, not -1? luck? + { + debugBI("Fails Euler criterion #4", bn); + return false; // Failed, not prime + } + // This portion is executed, on average, once +// a = a.subtract(ONE); // Put a back where it was + a = a.modPow(TWO, bn); + if (a.bitLength() == 1) + { + debugBI("Fails Euler criterion #5", bn); + return false; // Failed, not prime + } + } + // It worked (to the base primes[i]) + } + debugBI("Passes Euler criterion", bn); + return true; + } + + public static boolean isProbablePrime(BigInteger w) + { + return isProbablePrime(w, DEFAULT_CERTAINTY); + } + + /** + * Wrapper around {@link BigInteger#isProbablePrime(int)} with few pre-checks. + * + * @param w the integer to test. + * @param certainty the certainty with which to compute the test. + */ + public static boolean isProbablePrime(BigInteger w, int certainty) + { + // Nonnumbers are not prime. + if (w == null) + return false; + + // eliminate trivial cases when w == 0 or 1 + if (w.equals(ZERO) || w.equals(ONE)) + return false; + + // Test if w is a known small prime. + for (int i = 0; i < SMALL_PRIME_COUNT; i++) + if (w.equals(SMALL_PRIME[i])) + { + if (DEBUG && debuglevel > 4) + debug(w.toString(16) + " is a small prime"); + return true; + } + + // Check if it's already a known prime + WeakReference obj = (WeakReference) knownPrimes.get(w); + if (obj != null && w.equals(obj.get())) + { + if (DEBUG && debuglevel > 4) + debug("found in known primes"); + return true; + } + + // trial division with first 1000 primes + if (hasSmallPrimeDivisor(w)) + { + if (DEBUG && debuglevel > 4) + debug(w.toString(16) + " has a small prime divisor. Rejected..."); + return false; + } + +// Euler's criterion. +// if (passEulerCriterion(w)) { +// if (DEBUG && debuglevel > 4) { +// debug(w.toString(16)+" passes Euler's criterion..."); +// } +// } else { +// if (DEBUG && debuglevel > 4) { +// debug(w.toString(16)+" fails Euler's criterion. Rejected..."); +// } +// return false; +// } +// +// if (DEBUG && debuglevel > 4) +// { +// debug(w.toString(16) + " is probable prime. Accepted..."); +// } + + boolean result = w.isProbablePrime(certainty); + if (result && certainty > 0) // store it in the known primes weak hash-map + knownPrimes.put(w, new WeakReference(w)); + + return result; + } + + // helper methods ----------------------------------------------------------- + + private static final void debugBI(String msg, BigInteger bn) + { + if (DEBUG && debuglevel > 4) + debug("*** " + msg + ": 0x" + bn.toString(16)); + } +} diff --git a/libjava/classpath/gnu/java/security/util/Sequence.java b/libjava/classpath/gnu/java/security/util/Sequence.java new file mode 100644 index 00000000000..5edc7942ef9 --- /dev/null +++ b/libjava/classpath/gnu/java/security/util/Sequence.java @@ -0,0 +1,149 @@ +/* Sequence.java -- a sequence of integers. + Copyright (C) 2004, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.util; + +import java.util.AbstractList; +import java.util.LinkedList; + +/** + * A monotonic sequence of integers in the finite field 2<sup>32</sup>. + */ +public final class Sequence extends AbstractList +{ + + // Field. + // ------------------------------------------------------------------------ + + private final Integer[] sequence; + + // Constructor. + // ------------------------------------------------------------------------ + + /** + * Create a sequence of integers from 0 to <i>end</i>, with an increment + * of 1. If <i>end</i> is less than 0, then the sequence will wrap around + * through all positive integers then negative integers until the end + * value is reached. Naturally, this will result in an enormous object, + * so don't do this. + * + * @param end The ending value. + */ + public Sequence(int end) + { + this(0, end, 1); + } + + /** + * Create a sequence of integers from <i>start</i> to <i>end</i>, with an + * increment of 1. If <i>end</i> is less than <i>start</i>, then the sequence + * will wrap around until the end value is reached. Naturally, this will + * result in an enormous object, so don't do this. + * + * @param start The starting value. + * @param end The ending value. + */ + public Sequence(int start, int end) + { + this(start, end, 1); + } + + /** + * Create a sequence of integers from <i>start</i> to <i>end</i>, with an + * increment of <i>span</i>. If <i>end</i> is less than <i>start</i>, then + * the sequence will wrap around until the end value is reached. Naturally, + * this will result in an enormous object, so don't do this. + * + * <p><i>span</i> can be negative, resulting in a decresing sequence. + * + * <p>If <i>span</i> is 0, then the sequence will contain {<i>start</i>, + * <i>end</i>} if <i>start</i> != <i>end</i>, or just the singleton + * <i>start</i> if <i>start</i> == <i>end</i>. + * + * @param start The starting value. + * @param end The ending value. + * @param span The increment value. + */ + public Sequence(int start, int end, int span) + { + if (span == 0) + { + if (start != end) + { + sequence = new Integer[] { new Integer(start), new Integer(end) }; + } + else + { + sequence = new Integer[] { new Integer(start) }; + } + } + else + { + LinkedList l = new LinkedList(); + for (int i = start; i != end; i += span) + { + l.add(new Integer(i)); + } + l.add(new Integer(end)); + sequence = (Integer[]) l.toArray(new Integer[l.size()]); + } + } + + // Instance methods. + // ------------------------------------------------------------------------ + + public Object get(int index) + { + if (index < 0 || index >= size()) + { + throw new IndexOutOfBoundsException("index=" + index + ", size=" + + size()); + } + return sequence[index]; + } + + public int size() + { + return sequence.length; + } + + public Object[] toArray() + { + return (Object[]) sequence.clone(); + } +} diff --git a/libjava/classpath/gnu/java/security/util/SimpleList.java b/libjava/classpath/gnu/java/security/util/SimpleList.java new file mode 100644 index 00000000000..b2525c4b8e2 --- /dev/null +++ b/libjava/classpath/gnu/java/security/util/SimpleList.java @@ -0,0 +1,171 @@ +/* SimpleList.java -- simple way to make tuples. + Copyright (C) 2004, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.util; + +import java.util.AbstractList; +import java.util.Collection; +import java.util.Iterator; + +/** + * A simple way to create immutable n-tuples. This class can be created with + * up to four elements specified via one of the constructors, or with a + * collection of arbitrary size. + */ +public final class SimpleList extends AbstractList +{ + + // Fields. + // ------------------------------------------------------------------------ + + private final Object[] elements; + + // Constructors. + // ------------------------------------------------------------------------ + + /** + * Create a singleton list. + * + * @param e1 The first element. + */ + public SimpleList(final Object element) + { + elements = new Object[1]; + elements[0] = element; + } + + /** + * Create an ordered pair (2-tuple). + * + * @param e1 The first element. + * @param e2 The second element. + */ + public SimpleList(final Object e1, final Object e2) + { + elements = new Object[2]; + elements[0] = e1; + elements[1] = e2; + } + + /** + * Create a 3-tuple. + * + * @param e1 The first element. + * @param e2 The second element. + * @param e3 The third element. + */ + public SimpleList(final Object e1, final Object e2, final Object e3) + { + elements = new Object[3]; + elements[0] = e1; + elements[1] = e2; + elements[2] = e3; + } + + /** + * Create a 4-tuple. + * + * @param e1 The first element. + * @param e2 The second element. + * @param e3 The third element. + * @param e4 The fourth element. + */ + public SimpleList(final Object e1, final Object e2, final Object e3, + final Object e4) + { + elements = new Object[4]; + elements[0] = e1; + elements[1] = e2; + elements[2] = e3; + elements[3] = e4; + } + + /** + * Create the empty list. + */ + public SimpleList() + { + elements = null; + } + + /** + * Create an n-tuple of arbitrary size. Even if the supplied collection has + * no natural order, the created n-tuple will have the order that the + * elements are returned by the collection's iterator. + * + * @param c The collection. + */ + public SimpleList(Collection c) + { + elements = new Object[c.size()]; + int i = 0; + for (Iterator it = c.iterator(); it.hasNext() && i < elements.length;) + { + elements[i++] = it.next(); + } + } + + // Instance methods. + // ------------------------------------------------------------------------ + + public int size() + { + if (elements == null) + return 0; + return elements.length; + } + + public Object get(int index) + { + if (elements == null) + { + throw new IndexOutOfBoundsException("list is empty"); + } + if (index < 0 || index >= elements.length) + { + throw new IndexOutOfBoundsException("index=" + index + ", size=" + + size()); + } + return elements[index]; + } + + public String toString() + { + return SimpleList.class.getName() + "(" + size() + ") " + super.toString(); + } +} diff --git a/libjava/classpath/gnu/java/security/util/Util.java b/libjava/classpath/gnu/java/security/util/Util.java new file mode 100644 index 00000000000..53f8e3c2cca --- /dev/null +++ b/libjava/classpath/gnu/java/security/util/Util.java @@ -0,0 +1,692 @@ +/* Util.java -- various utility routines. + Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + +This file is a part of GNU Classpath. + +GNU Classpath 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 of the License, or (at +your option) any later version. + +GNU Classpath 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 GNU Classpath; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, 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. */ + + +package gnu.java.security.util; + +import java.math.BigInteger; + +/** + * <p>A collection of utility methods used throughout this project.</p> + * + * @version $Revision: 1.1 $ + */ +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)); + } +} diff --git a/libjava/classpath/gnu/java/security/x509/X509Certificate.java b/libjava/classpath/gnu/java/security/x509/X509Certificate.java index 14ac43a25e6..cf0161701cc 100644 --- a/libjava/classpath/gnu/java/security/x509/X509Certificate.java +++ b/libjava/classpath/gnu/java/security/x509/X509Certificate.java @@ -40,7 +40,6 @@ package gnu.java.security.x509; import gnu.classpath.debug.Component; import gnu.classpath.debug.SystemLogger; - import gnu.java.security.OID; import gnu.java.security.der.BitString; import gnu.java.security.der.DER; @@ -88,8 +87,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; - -import java.util.logging.Level; import java.util.logging.Logger; import javax.security.auth.x500.X500Principal; @@ -661,10 +658,7 @@ public class X509Certificate extends java.security.cert.X509Certificate der.skip(spki.getLength()); logger.log (Component.X509, "read subjectPublicKey == {0}", subjectKey); - if (version > 1) - { - val = der.read(); - } + val = der.read(); if (version >= 2 && val.getTagClass() != DER.UNIVERSAL && val.getTag() == 1) { byte[] b = (byte[]) val.getValue(); diff --git a/libjava/classpath/gnu/java/security/x509/ext/GeneralNames.java b/libjava/classpath/gnu/java/security/x509/ext/GeneralNames.java index e92aedaefd0..dae94cd9f35 100644 --- a/libjava/classpath/gnu/java/security/x509/ext/GeneralNames.java +++ b/libjava/classpath/gnu/java/security/x509/ext/GeneralNames.java @@ -52,6 +52,8 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import javax.security.auth.x500.X500Principal; + public class GeneralNames { @@ -81,12 +83,14 @@ public class GeneralNames if (!nameList.isConstructed()) throw new IOException("malformed GeneralNames"); int len = 0; + int i = 0; while (len < nameList.getLength()) { DERValue name = der.read(); List namePair = new ArrayList(2); - if (name.getTagClass() != DER.APPLICATION) - throw new IOException("malformed GeneralName"); + int tagClass = name.getTagClass(); + if (tagClass != DER.CONTEXT) + throw new IOException("malformed GeneralName: Tag class is " + tagClass); namePair.add(new Integer(name.getTag())); DERValue val = null; switch (name.getTag()) @@ -99,6 +103,15 @@ public class GeneralNames break; case OTHER_NAME: + // MUST return the encoded bytes of the OID/OctetString sequence + byte[] anotherName = name.getEncoded(); + anotherName[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE); + namePair.add(anotherName); + // DERReader goes back on Constructed things so we need to skip over them + DERValue skip = der.read(); // skip OID + skip = der.read(); // skip Octet String + break; + case EDI_PARTY_NAME: namePair.add(name.getValue()); break; @@ -106,7 +119,9 @@ public class GeneralNames case DIRECTORY_NAME: byte[] b = name.getEncoded(); b[0] = (byte) (DER.CONSTRUCTED|DER.SEQUENCE); - namePair.add(new X500DistinguishedName(b).toString()); + DERReader r = new DERReader (b); + r.read (); + namePair.add(new X500Principal(r.read ().getEncoded ()).toString()); break; case IP_ADDRESS: |