Imported GNU Classpath 0.92

2006-08-14  Mark Wielaard  <mark@klomp.org>

       Imported GNU Classpath 0.92
       * HACKING: Add more importing hints. Update automake version
       requirement.

       * configure.ac (gconf-peer): New enable AC argument.
       Add --disable-gconf-peer and --enable-default-preferences-peer
       to classpath configure when gconf is disabled.
       * scripts/makemake.tcl: Set gnu/java/util/prefs/gconf and
       gnu/java/awt/dnd/peer/gtk to bc. Classify
       gnu/java/security/Configuration.java as generated source file.

       * gnu/java/lang/management/VMGarbageCollectorMXBeanImpl.java,
       gnu/java/lang/management/VMMemoryPoolMXBeanImpl.java,
       gnu/java/lang/management/VMClassLoadingMXBeanImpl.java,
       gnu/java/lang/management/VMRuntimeMXBeanImpl.java,
       gnu/java/lang/management/VMMemoryManagerMXBeanImpl.java,
       gnu/java/lang/management/VMThreadMXBeanImpl.java,
       gnu/java/lang/management/VMMemoryMXBeanImpl.java,
       gnu/java/lang/management/VMCompilationMXBeanImpl.java: New VM stub
       classes.
       * java/lang/management/VMManagementFactory.java: Likewise.
       * java/net/VMURLConnection.java: Likewise.
       * gnu/java/nio/VMChannel.java: Likewise.

       * java/lang/Thread.java (getState): Add stub implementation.
       * java/lang/Class.java (isEnum): Likewise.
       * java/lang/Class.h (isEnum): Likewise.

       * gnu/awt/xlib/XToolkit.java (getClasspathTextLayoutPeer): Removed.

       * javax/naming/spi/NamingManager.java: New override for StackWalker
       functionality.

       * configure, sources.am, Makefile.in, gcj/Makefile.in,
       include/Makefile.in, testsuite/Makefile.in: Regenerated.

From-SVN: r116139
This commit is contained in:
Mark Wielaard
2006-08-14 23:12:35 +00:00
parent abab460491
commit ac1ed908de
1294 changed files with 99479 additions and 35933 deletions
@@ -0,0 +1,56 @@
/* Configuration.java --
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;
/**
* This file defines compile-time constants that can be accessed by
* our crypto code. All crypto code should use and define such
* constants here instead of using the gnu.classpath.Configuration class.
*/
public interface Configuration
{
/**
* The value of DEBUG is substituted according to whether the
* "--enable-debug" argument was passed to configure. Code
* which is made conditional based on the value of this flag - typically
* code that generates debugging output - will be removed by the optimizer
* in a non-debug build.
*/
boolean DEBUG = @LIBDEBUG@;
}
+43 -19
View File
@@ -42,6 +42,7 @@ import java.lang.reflect.InvocationTargetException;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.util.Enumeration;
/**
* Generic implementation of the getInstance methods in the various
@@ -141,26 +142,49 @@ public final class Engine
|| provider == null || initArgs == null)
throw new IllegalArgumentException();
// If there is no property "service.algorithm"
if (provider.getProperty(service + "." + algorithm) == null)
{
// Iterate through aliases, until we find the class name or resolve
// too many aliases.
String alias = null;
int count = 0;
while ((alias = provider.getProperty(
ALG_ALIAS + service + "." + algorithm)) != null)
{
if (algorithm.equals(alias)) // Refers to itself!
break;
algorithm = alias;
if (count++ > MAX_ALIASES)
throw new NoSuchAlgorithmException("too many aliases");
}
if (provider.getProperty(service + "." + algorithm) == null)
throw new NoSuchAlgorithmException(algorithm);
}
Enumeration enumer = provider.propertyNames();
String key;
String alias;
int count = 0;
boolean algorithmFound = false;
while (enumer.hasMoreElements())
{
key = (String) enumer.nextElement();
if (key.equalsIgnoreCase(service + "." + algorithm))
{
// remove the service portion from the key
algorithm = key.substring(service.length() + 1);
algorithmFound = true;
break;
}
else if (key.equalsIgnoreCase(ALG_ALIAS + service + "." + algorithm))
{
alias = (String) provider.getProperty(key);
if (! algorithm.equalsIgnoreCase(alias)) // does not refer to itself
{
algorithm = alias;
if (count++ > MAX_ALIASES)
throw new NoSuchAlgorithmException("too many aliases");
// need to reset enumeration to now look for the alias
enumer = provider.propertyNames();
}
}
}
if (! algorithmFound)
{
throw new NoSuchAlgorithmException(algorithm);
}
// Find and instantiate the implementation.
Class clazz = null;
ClassLoader loader = provider.getClass().getClassLoader();
+14 -13
View File
@@ -1,5 +1,5 @@
/* OID.java -- numeric representation of an object identifier
Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -71,6 +71,9 @@ public class OID implements Cloneable, Comparable, java.io.Serializable
// Fields.
// ------------------------------------------------------------------------
/* Serial version id for serialization. */
static final long serialVersionUID = 5722492029044597779L;
/**
* The numeric ID structure.
*/
@@ -211,7 +214,6 @@ public class OID implements Cloneable, Comparable, java.io.Serializable
/**
* Construct a new OID from the given DER bytes.
*
* @param root The root OID.
* @param encoded The encoded relative OID.
* @param relative The relative flag.
*/
@@ -230,13 +232,6 @@ public class OID implements Cloneable, Comparable, java.io.Serializable
}
}
/**
* Our private constructor.
*/
private OID()
{
}
// Instance methods.
// ------------------------------------------------------------------------
@@ -326,10 +321,16 @@ public class OID implements Cloneable, Comparable, java.io.Serializable
*/
public Object clone()
{
OID oid = new OID();
oid.components = this.components;
oid.strRep = this.strRep;
return oid;
try
{
return super.clone();
}
catch (CloneNotSupportedException cnse)
{
InternalError ie = new InternalError();
ie.initCause(cnse);
throw ie;
}
}
/* Nice idea, but possibly too expensive for whatever benefit it
@@ -1,5 +1,5 @@
/* PolicyFile.java -- policy file reader
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -37,9 +37,9 @@ exception statement from your version. */
package gnu.java.security;
import gnu.classpath.SystemProperties;
import gnu.classpath.debug.Component;
import gnu.classpath.debug.SystemLogger;
import gnu.java.security.action.GetPropertyAction;
import java.io.File;
import java.io.IOException;
@@ -148,16 +148,17 @@ public final class PolicyFile extends Policy
// Constants and fields.
// -------------------------------------------------------------------------
private static final Logger logger = SystemLogger.SYSTEM;
protected static final Logger logger = SystemLogger.SYSTEM;
// Added to cut redundant AccessController.doPrivileged calls
private static GetPropertyAction prop = new GetPropertyAction("file.seperator");
private static final String fs = (String) AccessController.doPrivileged(prop);
private static final String DEFAULT_POLICY =
SystemProperties.getProperty("java.home")
+ SystemProperties.getProperty("file.separator") + "lib"
+ SystemProperties.getProperty("file.separator") + "security"
+ SystemProperties.getProperty("file.separator") + "java.policy";
(String) AccessController.doPrivileged(prop.setParameters("java.home"))
+ fs + "lib" + fs + "security" + fs + "java.policy";
private static final String DEFAULT_USER_POLICY =
SystemProperties.getProperty ("user.home") +
SystemProperties.getProperty ("file.separator") + ".java.policy";
(String) AccessController.doPrivileged(prop.setParameters("user.home")) +
fs + ".java.policy";
private final Map cs2pc;
@@ -216,7 +217,7 @@ public final class PolicyFile extends Policy
String allow = Security.getProperty ("policy.allowSystemProperty");
if (allow == null || Boolean.getBoolean (allow))
{
String s = SystemProperties.getProperty ("java.security.policy");
String s = System.getProperty ("java.security.policy");
logger.log (Component.POLICY, "java.security.policy={0}", s);
if (s != null)
{
@@ -38,38 +38,23 @@ exception statement from your version. */
package gnu.java.security;
import gnu.java.security.Configuration;
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;
import java.util.logging.Logger;
/**
* <p>A global object containing build-specific properties that affect the
* behaviour of the generated binaries from this library.</p>
* A global object containing build-specific properties that affect the
* behaviour of the generated binaries from this library.
*/
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
// -------------------------------------------------------------------------
private static final Logger log = Logger.getLogger(Properties.class.getName());
public static final String VERSION = "gnu.crypto.version";
@@ -95,9 +80,6 @@ public final class Properties
private boolean doRSABlinding = true;
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial constructor to enforce Singleton pattern. */
private Properties()
{
@@ -105,18 +87,15 @@ public final class Properties
init();
}
// Class methods
// -------------------------------------------------------------------------
/**
* <p>Returns the string representation of the library global configuration
* property with the designated <code>key</code>.</p>
*
* Returns the string representation of the library global configuration
* property with the designated <code>key</code>.
*
* @param key the case-insensitive, non-null and non-empty name of a
* configuration property.
* 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.
* <code>null</code> if such property is not yet set, or
* <code>key</code> is empty.
*/
public static final synchronized String getProperty(String key)
{
@@ -132,13 +111,13 @@ public final class Properties
}
/**
* <p>Sets the value of a designated library global configuration property,
* to a string representation of what should be a legal value.</p>
*
* Sets the value of a designated library global configuration property, to a
* string representation of what should be a legal value.
*
* @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>.
* 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)
{
@@ -169,13 +148,14 @@ public final class Properties
}
/**
* <p>A convenience method that returns, as a boolean, the library global
* 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.
* Generator produces, or not, the same bit stream when instantiated.
*
* @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()
{
@@ -186,15 +166,15 @@ public final class Properties
}
/**
* <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.
* 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.
*
* @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()
{
@@ -205,13 +185,14 @@ public final class Properties
}
/**
* <p>A convenience method that returns, as a boolean, the library global
* 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>
*
* does, or not, blinding against timing attacks.
*
* @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.
* blinding operation. Returns <code>false</code> if the RSA
* decryption primitive does not include the additional blinding
* operation.
*/
public static final synchronized boolean doRSABlinding()
{
@@ -222,11 +203,11 @@ public final class Properties
}
/**
* <p>A convenience method to set the global property for reproducibility of
* the default PRNG bit stream output.</p>
*
* A convenience method to set the global property for reproducibility of the
* default PRNG bit stream output.
*
* @param value if <code>true</code> then the default PRNG bit stream output
* is the same with every invocation of the VM.
* is the same with every invocation of the VM.
*/
public static final synchronized void setReproducible(final boolean value)
{
@@ -238,12 +219,12 @@ public final class Properties
}
/**
* <p>A convenience method to set the global property for checking for weak
* and semi-weak cipher keys.</p>
*
* A convenience method to set the global property for checking for weak and
* semi-weak cipher keys.
*
* @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.
* invoke additional checks for weak and semi-weak key values that
* may get generated.
*/
public static final synchronized void setCheckForWeakKeys(final boolean value)
{
@@ -255,11 +236,11 @@ public final class Properties
}
/**
* <p>A convenience method to set the global property fo adding a blinding
* operation when executing the RSA decryption primitive.</p>
*
* A convenience method to set the global property fo adding a blinding
* operation when executing the RSA decryption primitive.
*
* @param value if <code>true</code> then the code for performing the RSA
* decryption primitive will include a blinding operation.
* decryption primitive will include a blinding operation.
*/
public static final synchronized void setDoRSABlinding(final boolean value)
{
@@ -277,15 +258,12 @@ public final class 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
@@ -300,9 +278,8 @@ public final class Properties
}
catch (SecurityException se)
{
if (DEBUG)
debug("Reading property " + PROPERTIES_FILE
+ " not allowed. Ignored.");
if (Configuration.DEBUG)
log.fine("Reading property " + PROPERTIES_FILE + " not allowed. Ignored.");
}
if (propFile != null)
{
@@ -316,27 +293,24 @@ public final class Properties
}
catch (IOException ioe)
{
if (DEBUG)
debug("IO error reading " + propFile + ": " + ioe.getMessage());
if (Configuration.DEBUG)
log.fine("IO error reading " + propFile + ": " + ioe.getMessage());
}
catch (SecurityException se)
{
if (DEBUG)
debug("Security error reading " + propFile + ": "
+ se.getMessage());
if (Configuration.DEBUG)
log.fine("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 = Boolean.valueOf((String) props.get(REPRODUCIBLE_PRNG)).booleanValue();
checkForWeakKeys = Boolean.valueOf((String) props.get(CHECK_WEAK_KEYS)).booleanValue();
doRSABlinding = Boolean.valueOf((String) props.get(DO_RSA_BLINDING)).booleanValue();
// This does not change.
props.put(VERSION, Registry.VERSION_STRING);
}
@@ -350,24 +324,24 @@ public final class Properties
}
catch (SecurityException x)
{
if (DEBUG)
debug("SecurityManager forbids reading system properties. Ignored");
if (Configuration.DEBUG)
log.fine("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
// 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 + "'");
if (Configuration.DEBUG)
log.fine("Setting " + name + " to '" + s + "'");
props.put(name, s);
}
else
{
if (DEBUG)
debug("Invalid value for -D" + name + ": " + s + ". Ignored");
if (Configuration.DEBUG)
log.fine("Invalid value for -D" + name + ": " + s + ". Ignored");
}
}
}
@@ -44,10 +44,6 @@ package gnu.java.security;
*/
public interface Registry
{
// Constants
// -------------------------------------------------------------------------
/** The name of our Providers. */
String GNU_SECURITY = "GNU";
String GNU_CRYPTO = "GNU-CRYPTO";
@@ -93,6 +89,18 @@ public interface Registry
String CAST_128_CIPHER = "cast-128";
// Key Wrapping Algorithm names and synonyms ...............................
String KWA_PREFIX = "kw-";
String AES_KWA = KWA_PREFIX + AES_CIPHER;
String AES128_KWA = AES_KWA + "128";
String AES192_KWA = AES_KWA + "192";
String AES256_KWA = AES_KWA + "256";
String RIJNDAEL_KWA = KWA_PREFIX + RIJNDAEL_CIPHER;
String TRIPLEDES_KWA = KWA_PREFIX + TRIPLEDES_CIPHER;
String DESEDE_KWA = KWA_PREFIX + DESEDE_CIPHER;
// Message digest algorithms and synonyms...................................
String WHIRLPOOL_HASH = "whirlpool";
@@ -177,6 +185,9 @@ public interface Registry
/** TLSv1 padding scheme. */
String TLS1_PAD = "tls1";
/** ISO 10126-2 padding scheme. */
String ISO10126_PAD = "iso10126";
// Pseudo-random number generators..........................................
/** (Apparently) RC4 keystream PRNG. */
@@ -300,38 +311,38 @@ public interface Registry
// 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_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_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_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_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_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_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_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_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_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_PUBLIC_KEY = new byte[] {
0x47, RAW_ENCODING_ID, 0x53, 0x50 };
byte[] MAGIC_RAW_SRP_PRIVATE_KEY = new byte[] { 0x47, RAW_ENCODING_ID, 0x53,
0x70 };
byte[] MAGIC_RAW_SRP_PRIVATE_KEY = new byte[] {
0x47, RAW_ENCODING_ID, 0x53, 0x70 };
// SASL Property names .....................................................
@@ -344,8 +355,7 @@ public interface Registry
String SASL_PASSWORD = SASL_PREFIX + ".password";
/** Name of authentication information provider packages. */
String SASL_AUTH_INFO_PROVIDER_PKGS = SASL_PREFIX
+ ".auth.info.provider.pkgs";
String SASL_AUTH_INFO_PROVIDER_PKGS = SASL_PREFIX + ".auth.info.provider.pkgs";
/** SASL authorization ID. */
String SASL_AUTHORISATION_ID = SASL_PREFIX + ".authorisation.ID";
@@ -452,7 +462,4 @@ public interface Registry
int GKR_CIPHER_AES_128_OFB = 0;
int GKR_CIPHER_AES_128_CBC = 1;
// Methods
// -------------------------------------------------------------------------
}
@@ -39,14 +39,11 @@ exception statement from your version. */
package gnu.java.security.hash;
/**
* <p>A base abstract class to facilitate hash implementations.</p>
* A base abstract class to facilitate hash implementations.
*/
public abstract class BaseHash implements IMessageDigest
public abstract class BaseHash
implements IMessageDigest
{
// Constants and variables
// -------------------------------------------------------------------------
/** The canonical name prefix of the hash. */
protected String name;
@@ -62,12 +59,9 @@ public abstract class BaseHash implements IMessageDigest
/** Temporary input buffer. */
protected byte[] buffer;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* <p>Trivial constructor for use by concrete subclasses.</p>
*
* Trivial constructor for use by concrete subclasses.
*
* @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.
@@ -84,14 +78,6 @@ public abstract class BaseHash implements IMessageDigest
resetContext();
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// IMessageDigest interface implementation ---------------------------------
public String name()
{
return name;
@@ -114,9 +100,7 @@ public abstract class BaseHash implements IMessageDigest
count++;
buffer[i] = b;
if (i == (blockSize - 1))
{
transform(buffer, 0);
}
transform(buffer, 0);
}
public void update(byte[] b)
@@ -136,16 +120,13 @@ public abstract class BaseHash implements IMessageDigest
System.arraycopy(b, offset, buffer, n, partLen);
transform(buffer, 0);
for (i = partLen; i + blockSize - 1 < len; i += blockSize)
{
transform(b, offset + i);
}
transform(b, offset + i);
n = 0;
}
if (i < len)
{
System.arraycopy(b, offset + i, buffer, n, len - i);
}
System.arraycopy(b, offset + i, buffer, n, len - i);
}
public byte[] digest()
@@ -163,31 +144,27 @@ public abstract class BaseHash implements IMessageDigest
{ // reset this instance for future re-use
count = 0L;
for (int i = 0; i < blockSize;)
{
buffer[i++] = 0;
}
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>
*
* Returns the byte array to use as padding before completing a hash
* operation.
*
* @return the bytes to pad the remaining bytes in the buffer before
* completing a hash operation.
* completing a hash operation.
*/
protected abstract byte[] padBuffer();
/**
* <p>Constructs the result from the contents of the current context.</p>
*
* Constructs the result from the contents of the current context.
*
* @return the output of the completed hash operation.
*/
protected abstract byte[] getResult();
@@ -196,11 +173,11 @@ public abstract class BaseHash implements IMessageDigest
protected abstract void resetContext();
/**
* <p>The block digest transformation per se.</p>
*
* The block digest transformation per se.
*
* @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.
* input buffer.
*/
protected abstract void transform(byte[] in, int offset);
}
@@ -45,113 +45,73 @@ import java.util.HashSet;
import java.util.Set;
/**
* <p>A <i>Factory</i> to instantiate message digest algorithm instances.</p>
* A <i>Factory</i> to instantiate message digest algorithm instances.
*/
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>
*
* Return an instance of a hash algorithm given its name.
*
* @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.
* test.
*/
public static IMessageDigest getInstance(String name)
{
if (name == null)
{
return null;
}
return null;
name = name.trim();
IMessageDigest result = null;
if (name.equalsIgnoreCase(Registry.WHIRLPOOL_HASH))
{
result = new Whirlpool();
}
result = new Whirlpool();
else if (name.equalsIgnoreCase(Registry.RIPEMD128_HASH)
|| name.equalsIgnoreCase(Registry.RIPEMD_128_HASH))
{
result = new RipeMD128();
}
result = new RipeMD128();
else if (name.equalsIgnoreCase(Registry.RIPEMD160_HASH)
|| name.equalsIgnoreCase(Registry.RIPEMD_160_HASH))
{
result = new RipeMD160();
}
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();
}
result = new Sha160();
else if (name.equalsIgnoreCase(Registry.SHA256_HASH))
{
result = new Sha256();
}
result = new Sha256();
else if (name.equalsIgnoreCase(Registry.SHA384_HASH))
{
result = new Sha384();
}
result = new Sha384();
else if (name.equalsIgnoreCase(Registry.SHA512_HASH))
{
result = new Sha512();
}
result = new Sha512();
else if (name.equalsIgnoreCase(Registry.TIGER_HASH))
{
result = new Tiger();
}
result = new Tiger();
else if (name.equalsIgnoreCase(Registry.HAVAL_HASH))
{
result = new Haval();
}
result = new Haval();
else if (name.equalsIgnoreCase(Registry.MD5_HASH))
{
result = new MD5();
}
result = new MD5();
else if (name.equalsIgnoreCase(Registry.MD4_HASH))
{
result = new MD4();
}
result = new MD4();
else if (name.equalsIgnoreCase(Registry.MD2_HASH))
{
result = new MD2();
}
result = new MD2();
else if (name.equalsIgnoreCase(Registry.HAVAL_HASH))
{
result = new Haval();
}
result = new Haval();
if (result != null && !result.selfTest())
{
throw new InternalError(result.name());
}
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>
*
* Returns a {@link Set} of names of hash algorithms supported by this
* <i>Factory</i>.
*
* @return a {@link Set} of hash names (Strings).
*/
public static final Set getNames()
@@ -172,7 +132,4 @@ public class HashFactory
return Collections.unmodifiableSet(hs);
}
// Instance methods
// -------------------------------------------------------------------------
}
@@ -42,25 +42,21 @@ 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>
*
* 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>
* References:
* <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>
* <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
public class Haval
extends BaseHash
{
// Constants and variables
// -------------------------------------------------------------------------
public static final int HAVAL_VERSION = 1;
public static final int HAVAL_128_BIT = 16;
@@ -88,20 +84,18 @@ public class Haval extends BaseHash
/**
* Number of HAVAL rounds. Allowed values are integers in the range <code>3
* .. 5</code>. The default is <code>3</code>.
* .. 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>
* 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.
*/
public Haval()
{
@@ -109,9 +103,9 @@ public class Haval extends BaseHash
}
/**
* <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>
*
* Calls the constructor with two arguments using the designated output size,
* and {@link #HAVAL_3_ROUND} for the value of number of rounds.
*
* @param size the output size in bytes of this instance.
* @throws IllegalArgumentException if the designated output size is invalid.
* @see #HAVAL_128_BIT
@@ -126,16 +120,16 @@ public class Haval extends BaseHash
}
/**
* <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>
*
* 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.
*
* @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.
* or if the number of rounds is invalid.
* @see #HAVAL_128_BIT
* @see #HAVAL_160_BIT
* @see #HAVAL_192_BIT
@@ -149,24 +143,24 @@ public class Haval extends BaseHash
{
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 (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
if (rounds != HAVAL_3_ROUND
&& rounds != HAVAL_4_ROUND
&& rounds != HAVAL_5_ROUND)
{
throw new IllegalArgumentException("Invalid HAVAL number of rounds");
}
throw new IllegalArgumentException("Invalid HAVAL number of rounds");
this.rounds = rounds;
}
/**
* <p>Private constructor for cloning purposes.</p>
*
* Private constructor for cloning purposes.
*
* @param md the instance to clone.
*/
private Haval(Haval md)
@@ -185,93 +179,142 @@ public class Haval extends BaseHash
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 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);
@@ -458,7 +501,6 @@ public class Haval extends BaseHash
t0 = FF5(t0, t7, t6, t5, t4, t3, t2, t1, X15, 0x409F60C4);
}
}
h7 += t7;
h6 += t6;
h5 += t5;
@@ -471,30 +513,30 @@ public class Haval extends BaseHash
protected byte[] padBuffer()
{
// pad out to 118 mod 128. other 10 bytes have special use.
int n = (int) (count % BLOCK_SIZE);
// 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);
int sigByte = (bl & 0x03) << 6;
sigByte |= (rounds & 0x07) << 3;
sigByte |= HAVAL_VERSION & 0x07;
result[padding++] = (byte) sigByte;
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);
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;
}
@@ -505,49 +547,48 @@ public class Haval extends BaseHash
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[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[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[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[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[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;
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;
}
@@ -567,13 +608,12 @@ public class Haval extends BaseHash
{
if (valid == null)
{
valid = Boolean.valueOf(DIGEST0.equals(Util.toString(new Haval().digest())));
String d = Util.toString(new Haval().digest());
valid = Boolean.valueOf(DIGEST0.equals(d));
}
return valid.booleanValue();
}
// helper methods ----------------------------------------------------------
/** Tailors the last output. */
private void tailorDigestBits()
{
@@ -581,17 +621,25 @@ public class Haval extends BaseHash
switch (hashSize)
{
case HAVAL_128_BIT:
t = (h7 & 0x000000FF) | (h6 & 0xFF000000) | (h5 & 0x00FF0000)
| (h4 & 0x0000FF00);
t = (h7 & 0x000000FF)
| (h6 & 0xFF000000)
| (h5 & 0x00FF0000)
| (h4 & 0x0000FF00);
h0 += t >>> 8 | t << 24;
t = (h7 & 0x0000FF00) | (h6 & 0x000000FF) | (h5 & 0xFF000000)
| (h4 & 0x00FF0000);
t = (h7 & 0x0000FF00)
| (h6 & 0x000000FF)
| (h5 & 0xFF000000)
| (h4 & 0x00FF0000);
h1 += t >>> 16 | t << 16;
t = (h7 & 0x00FF0000) | (h6 & 0x0000FF00) | (h5 & 0x000000FF)
| (h4 & 0xFF000000);
t = (h7 & 0x00FF0000)
| (h6 & 0x0000FF00)
| (h5 & 0x000000FF)
| (h4 & 0xFF000000);
h2 += t >>> 24 | t << 8;
t = (h7 & 0xFF000000) | (h6 & 0x00FF0000) | (h5 & 0x0000FF00)
| (h4 & 0x000000FF);
t = (h7 & 0xFF000000)
| (h6 & 0x00FF0000)
| (h5 & 0x0000FF00)
| (h4 & 0x000000FF);
h3 += t;
break;
case HAVAL_160_BIT:
@@ -625,9 +673,9 @@ public class Haval extends BaseHash
h1 += ((h7 >>> 22) & 0x1F);
h2 += ((h7 >>> 18) & 0x0F);
h3 += ((h7 >>> 13) & 0x1F);
h4 += ((h7 >>> 9) & 0x0F);
h5 += ((h7 >>> 4) & 0x1F);
h6 += (h7 & 0x0F);
h4 += ((h7 >>> 9) & 0x0F);
h5 += ((h7 >>> 4) & 0x1F);
h6 += (h7 & 0x0F);
}
}
@@ -748,8 +796,8 @@ public class Haval extends BaseHash
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;
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)
@@ -39,64 +39,56 @@ 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>
* The basic visible methods of any hash algorithm.
* <p>
* A hash (or message digest) algorithm produces its output by iterating a basic
* compression function on blocks of data.
*/
public interface IMessageDigest extends Cloneable
public interface IMessageDigest
extends Cloneable
{
// Constants
// -------------------------------------------------------------------------
// Methods
// -------------------------------------------------------------------------
/**
* <p>Returns the canonical name of this algorithm.</p>
*
* Returns the canonical name of this algorithm.
*
* @return the canonical name of this instance.
*/
String name();
/**
* <p>Returns the output length in bytes of this message digest algorithm.</p>
*
* Returns the output length in bytes of this message digest algorithm.
*
* @return the output length in bytes of this message digest algorithm.
*/
int hashSize();
/**
* <p>Returns the algorithm's (inner) block size in bytes.</p>
*
* Returns the algorithm's (inner) block size in bytes.
*
* @return the algorithm's inner block size in bytes.
*/
int blockSize();
/**
* <p>Continues a message digest operation using the input byte.</p>
*
* Continues a message digest operation using the input byte.
*
* @param b the input byte to digest.
*/
void update(byte b);
/**
* <p>Continues a message digest operation, by filling the buffer, processing
* 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>
*
* count, and buffering the remaining bytes in buffer for the next operation.
*
* @param in the input block.
*/
void update(byte[] in);
/**
* <p>Continues a message digest operation, by filling the buffer, processing
* 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>
*
* count, and buffering the remaining bytes in buffer for the next operation.
*
* @param in the input block.
* @param offset start of meaningful bytes in input block.
* @param length number of bytes, in input block, to consider.
@@ -104,31 +96,31 @@ public interface IMessageDigest extends Cloneable
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>
*
* Completes the message digest by performing final operations such as padding
* and resetting the instance.
*
* @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>
* Resets the current context of this instance clearing any eventually cached
* intermediary values.
*/
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.
* A basic test. Ensures that the digest of a pre-determined message is equal
* to a known pre-computed value.
*
* @return <code>true</code> if the implementation passes a basic self-test.
* Returns <code>false</code> otherwise.
*/
boolean selfTest();
/**
* <p>Returns a clone copy of this instance.</p>
*
* Returns a clone copy of this instance.
*
* @return a clone copy of this instance.
*/
Object clone();
+59 -104
View File
@@ -42,13 +42,12 @@ 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>
*
* An implementation of the MD2 message digest algorithm.
* <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>
* References:
* <ol>
* <li>The <a href="http://www.ietf.org/rfc/rfc1319.txt">MD2</a>
* Message-Digest Algorithm.<br>
@@ -57,12 +56,9 @@ import gnu.java.security.util.Util;
* under section RFC 1319.</li>
* </ol>
*/
public class MD2 extends BaseHash
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;
@@ -70,34 +66,39 @@ public class MD2 extends BaseHash
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 };
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";
@@ -114,9 +115,6 @@ public class MD2 extends BaseHash
*/
private byte[] work;
// Constructor(s)
// -------------------------------------------------------------------------
/** Creates a new MD2 digest ready for use. */
public MD2()
{
@@ -124,7 +122,7 @@ public class MD2 extends BaseHash
}
/**
* <p>Private constructor used for cloning.</p>
* Private constructor used for cloning.
*
* @param md2 the instance to clone.
*/
@@ -135,38 +133,23 @@ public class MD2 extends BaseHash
// 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];
}
result[i] = work[i];
return result;
}
@@ -181,17 +164,18 @@ public class MD2 extends BaseHash
{
if (valid == null)
{
valid = Boolean.valueOf(DIGEST0.equals(Util.toString(new MD2().digest())));
String d = Util.toString(new MD2().digest());
valid = Boolean.valueOf(DIGEST0.equals(d));
}
return valid.booleanValue();
}
/**
* <p>Generates an array of padding bytes. The padding is defined as
* 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>
* the last block was completely full).
*
* @return the bytes to pad the remaining bytes in the buffer before
* completing a hash operation.
@@ -200,47 +184,26 @@ public class MD2 extends BaseHash
{
int length = BLOCK_LENGTH - (int) (count % BLOCK_LENGTH);
if (length == 0)
{
length = BLOCK_LENGTH;
}
length = BLOCK_LENGTH;
byte[] pad = new byte[length];
for (int i = 0; i < length; i++)
{
pad[i] = (byte) length;
}
pad[i] = (byte) length;
return pad;
}
/**
* <p>Adds <code>BLOCK_LENGTH</code> bytes to the running digest.</p>
* Adds <code>BLOCK_LENGTH</code> bytes to the running digest.
*
* @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.
@@ -251,20 +214,17 @@ public class MD2 extends BaseHash
{
byte b = in[off + i];
work[BLOCK_LENGTH + i] = b;
work[BLOCK_LENGTH * 2 + i] = (byte) (work[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]);
t = (byte)(work[j] ^ PI[t & 0xFF]);
work[j] = t;
}
// t = (byte)((t + i) & 0xFF);
t = (byte) (t + i);
t = (byte)(t + i);
}
}
@@ -278,24 +238,19 @@ public class MD2 extends BaseHash
{
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]);
work[BLOCK_LENGTH * 2 + i] = (byte)(work[i] ^ b);
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]);
t = (byte)(work[j] ^ PI[t & 0xFF]);
work[j] = t;
}
// t = (byte)((t + i) & 0xFF);
t = (byte) (t + i);
t = (byte)(t + i);
}
}
}
@@ -42,14 +42,13 @@ 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}
* An implementation of Ron Rivest's MD4 message digest algorithm.
* <p>
* MD4 was the precursor to the stronger {@link gnu.java.security.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>
*
* in use in various applications. It is slightly faster than MD5.
* <p>
* References:
* <ol>
* <li>The <a href="http://www.ietf.org/rfc/rfc1320.txt">MD4</a>
* Message-Digest Algorithm.<br>
@@ -58,12 +57,9 @@ import gnu.java.security.util.Util;
*
* @author Casey Marshall (rsdio@metastatic.org)
*/
public class MD4 extends BaseHash
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;
@@ -86,13 +82,9 @@ public class MD4 extends BaseHash
private int a, b, c, d;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* <p>Public constructor. Initializes the chaining variables, sets the byte
* 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()
{
@@ -100,7 +92,7 @@ public class MD4 extends BaseHash
}
/**
* <p>Trivial private constructor for cloning purposes.</p>
* Trivial private constructor for cloning purposes.
*
* @param that the instance to clone.
*/
@@ -116,30 +108,18 @@ public class MD4 extends BaseHash
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;
return new byte[] {
(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) };
}
protected void resetContext()
@@ -154,68 +134,97 @@ public class MD4 extends BaseHash
{
if (valid == null)
{
valid = Boolean.valueOf(DIGEST0.equals(Util.toString(new MD4().digest())));
String d = Util.toString(new MD4().digest());
valid = Boolean.valueOf(DIGEST0.equals(d));
}
return valid.booleanValue();
}
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_LENGTH);
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);
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 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;
@@ -42,26 +42,22 @@ import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>The MD5 message-digest algorithm takes as input a message of arbitrary
* 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>
*
* message having a given prespecified target message digest.
* <p>
* References:
* <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
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";
@@ -72,9 +68,6 @@ public class MD5 extends BaseHash
/** 128-bit interim result. */
private int h0, h1, h2, h3;
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public MD5()
{
@@ -82,7 +75,7 @@ public class MD5 extends BaseHash
}
/**
* <p>Private constructor for cloning purposes.</p>
* Private constructor for cloning purposes.
*
* @param md the instance to clone.
*/
@@ -98,61 +91,81 @@ public class MD5 extends BaseHash
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 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;
@@ -310,39 +323,31 @@ public class MD5 extends BaseHash
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
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);
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;
return 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) };
}
protected void resetContext()
@@ -358,7 +363,8 @@ public class MD5 extends BaseHash
{
if (valid == null)
{
valid = Boolean.valueOf(DIGEST0.equals(Util.toString(new MD5().digest())));
String d = Util.toString(new MD5().digest());
valid = Boolean.valueOf(DIGEST0.equals(d));
}
return valid.booleanValue();
}
@@ -42,54 +42,48 @@ import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>RIPEMD-128 is a 128-bit message digest.</p>
*
* <p>References:</p>
*
* RIPEMD-128 is a 128-bit message digest.
* <p>
* References:
* <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
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[] 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 };
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[] 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 };
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;
@@ -100,9 +94,6 @@ public class RipeMD128 extends BaseHash
/** 512 bits work buffer = 16 x 32-bit words */
private int[] X = new int[16];
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public RipeMD128()
{
@@ -110,7 +101,7 @@ public class RipeMD128 extends BaseHash
}
/**
* <p>Private constructor for cloning purposes.</p>
* Private constructor for cloning purposes.
*
* @param md the instance to clone.
*/
@@ -126,40 +117,26 @@ public class RipeMD128 extends BaseHash
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.
// 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;
}
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
for (i = 0; i < 16; i++) // rounds 0...15
{
s = S[i];
T = A + (B ^ C ^ D) + X[i];
A = D;
@@ -174,9 +151,8 @@ public class RipeMD128 extends BaseHash
Cp = Bp;
Bp = T << s | T >>> (32 - s);
}
for (; i < 32; i++)
{ // rounds 16...31
for (; i < 32; i++) // rounds 16...31
{
s = S[i];
T = A + ((B & C) | (~B & D)) + X[R[i]] + 0x5A827999;
A = D;
@@ -191,9 +167,8 @@ public class RipeMD128 extends BaseHash
Cp = Bp;
Bp = T << s | T >>> (32 - s);
}
for (; i < 48; i++)
{ // rounds 32...47
for (; i < 48; i++) // rounds 32...47
{
s = S[i];
T = A + ((B | ~C) ^ D) + X[R[i]] + 0x6ED9EBA1;
A = D;
@@ -208,9 +183,8 @@ public class RipeMD128 extends BaseHash
Cp = Bp;
Bp = T << s | T >>> (32 - s);
}
for (; i < 64; i++)
{ // rounds 48...63
for (; i < 64; i++) // rounds 48...63
{
s = S[i];
T = A + ((B & D) | (C & ~D)) + X[R[i]] + 0x8F1BBCDC;
A = D;
@@ -225,7 +199,6 @@ public class RipeMD128 extends BaseHash
Cp = Bp;
Bp = T << s | T >>> (32 - s);
}
T = h1 + C + Dp;
h1 = h2 + D + Ap;
h2 = h3 + A + Bp;
@@ -235,39 +208,32 @@ public class RipeMD128 extends BaseHash
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
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);
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;
return 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)
};
}
protected void resetContext()
@@ -283,8 +249,8 @@ public class RipeMD128 extends BaseHash
{
if (valid == null)
{
valid = Boolean.valueOf
(DIGEST0.equals(Util.toString(new RipeMD128().digest())));
String d = Util.toString(new RipeMD128().digest());
valid = Boolean.valueOf(DIGEST0.equals(d));
}
return valid.booleanValue();
}
@@ -42,59 +42,51 @@ import gnu.java.security.Registry;
import gnu.java.security.util.Util;
/**
* <p>RIPEMD-160 is a 160-bit message digest.</p>
*
* <p>References:</p>
*
* RIPEMD-160 is a 160-bit message digest.
* <p>
* References:
* <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
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[] 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 };
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[] 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 };
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;
@@ -105,9 +97,6 @@ public class RipeMD160 extends BaseHash
/** 512 bits work buffer = 16 x 32-bit words */
private int[] X = new int[16];
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public RipeMD160()
{
@@ -115,7 +104,7 @@ public class RipeMD160 extends BaseHash
}
/**
* <p>Private constructor for cloning purposes.</p>
* Private constructor for cloning purposes.
*
* @param md the instance to clone.
*/
@@ -132,40 +121,27 @@ public class RipeMD160 extends BaseHash
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;
}
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
for (i = 0; i < 16; i++) // rounds 0...15
{
s = S[i];
T = A + (B ^ C ^ D) + X[i];
A = E;
@@ -182,9 +158,8 @@ public class RipeMD160 extends BaseHash
Cp = Bp;
Bp = (T << s | T >>> (32 - s)) + Ap;
}
for (; i < 32; i++)
{ // rounds 16...31
for (; i < 32; i++) // rounds 16...31
{
s = S[i];
T = A + ((B & C) | (~B & D)) + X[R[i]] + 0x5A827999;
A = E;
@@ -201,9 +176,8 @@ public class RipeMD160 extends BaseHash
Cp = Bp;
Bp = (T << s | T >>> (32 - s)) + Ap;
}
for (; i < 48; i++)
{ // rounds 32...47
for (; i < 48; i++) // rounds 32...47
{
s = S[i];
T = A + ((B | ~C) ^ D) + X[R[i]] + 0x6ED9EBA1;
A = E;
@@ -220,9 +194,8 @@ public class RipeMD160 extends BaseHash
Cp = Bp;
Bp = (T << s | T >>> (32 - s)) + Ap;
}
for (; i < 64; i++)
{ // rounds 48...63
for (; i < 64; i++) // rounds 48...63
{
s = S[i];
T = A + ((B & D) | (C & ~D)) + X[R[i]] + 0x8F1BBCDC;
A = E;
@@ -239,9 +212,8 @@ public class RipeMD160 extends BaseHash
Cp = Bp;
Bp = (T << s | T >>> (32 - s)) + Ap;
}
for (; i < 80; i++)
{ // rounds 64...79
for (; i < 80; i++) // rounds 64...79
{
s = S[i];
T = A + (B ^ (C | ~D)) + X[R[i]] + 0xA953FD4E;
A = E;
@@ -258,7 +230,6 @@ public class RipeMD160 extends BaseHash
Cp = Bp;
Bp = (T << s | T >>> (32 - s)) + Ap;
}
T = h1 + C + Dp;
h1 = h2 + D + Ep;
h2 = h3 + E + Ap;
@@ -269,41 +240,33 @@ public class RipeMD160 extends BaseHash
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
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);
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;
return 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)
};
}
protected void resetContext()
@@ -320,8 +283,8 @@ public class RipeMD160 extends BaseHash
{
if (valid == null)
{
valid = Boolean.valueOf
(DIGEST0.equals(Util.toString(new RipeMD160().digest())));
String d = Util.toString(new RipeMD160().digest());
valid = Boolean.valueOf(DIGEST0.equals(d));
}
return valid.booleanValue();
}
@@ -42,7 +42,7 @@ 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
* 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
@@ -51,15 +51,14 @@ import gnu.java.security.util.Util;
* 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
* a different message digest, and the signature will fail to verify.
* <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>
*
* message digest.
* <p>
* References:
* <ol>
* <li><a href="http://www.itl.nist.gov/fipspubs/fip180-1.htm">SECURE HASH
* STANDARD</a><br>
@@ -67,12 +66,9 @@ import gnu.java.security.util.Util;
* </li>
* </ol>
*/
public class Sha160 extends BaseHash
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";
@@ -85,9 +81,6 @@ public class Sha160 extends BaseHash
/** 160-bit interim result. */
private int h0, h1, h2, h3, h4;
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public Sha160()
{
@@ -95,7 +88,7 @@ public class Sha160 extends BaseHash
}
/**
* <p>Private constructor for cloning purposes.</p>
* Private constructor for cloning purposes.
*
* @param md the instance to clone.
*/
@@ -112,58 +105,20 @@ public class Sha160 extends BaseHash
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];
@@ -173,41 +128,32 @@ public class Sha160 extends BaseHash
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
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;
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;
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 };
}
protected void resetContext()
@@ -234,11 +180,9 @@ public class Sha160 extends BaseHash
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)
private static synchronized final int[] sha(int hh0, int hh1, int hh2,
int hh3, int hh4, byte[] in,
int offset)
{
int A = hh0;
int B = hh1;
@@ -246,20 +190,17 @@ public class Sha160 extends BaseHash
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);
}
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++)
for (r = 0; r < 20; r++) // rounds 0-19
{
T = (A << 5 | A >>> 27) + ((B & C) | (~B & D)) + E + w[r] + 0x5A827999;
E = D;
@@ -268,9 +209,7 @@ public class Sha160 extends BaseHash
B = A;
A = T;
}
// rounds 20-39
for (r = 20; r < 40; r++)
for (r = 20; r < 40; r++) // rounds 20-39
{
T = (A << 5 | A >>> 27) + (B ^ C ^ D) + E + w[r] + 0x6ED9EBA1;
E = D;
@@ -279,21 +218,16 @@ public class Sha160 extends BaseHash
B = A;
A = T;
}
// rounds 40-59
for (r = 40; r < 60; r++)
for (r = 40; r < 60; r++) // rounds 40-59
{
T = (A << 5 | A >>> 27) + (B & C | B & D | C & D) + E + w[r]
+ 0x8F1BBCDC;
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++)
for (r = 60; r < 80; r++) // rounds 60-79
{
T = (A << 5 | A >>> 27) + (B ^ C ^ D) + E + w[r] + 0xCA62C1D6;
E = D;
@@ -302,7 +236,6 @@ public class Sha160 extends BaseHash
B = A;
A = T;
}
return new int[] { hh0 + A, hh1 + B, hh2 + C, hh3 + D, hh4 + E };
}
}
@@ -42,46 +42,41 @@ 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>
* Implementation of SHA2-1 [SHA-256] per the IETF Draft Specification.
* <p>
* References:
* <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
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[] 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 String DIGEST0 =
"BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD";
private static final int[] w = new int[64];
@@ -91,9 +86,6 @@ public class Sha256 extends BaseHash
/** 256-bit interim result. */
private int h0, h1, h2, h3, h4, h5, h6, h7;
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public Sha256()
{
@@ -101,7 +93,7 @@ public class Sha256 extends BaseHash
}
/**
* <p>Private constructor for cloning purposes.</p>
* Private constructor for cloning purposes.
*
* @param md the instance to clone.
*/
@@ -121,31 +113,20 @@ public class Sha256 extends BaseHash
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];
@@ -158,41 +139,35 @@ public class Sha256 extends BaseHash
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
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;
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 };
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()
@@ -219,13 +194,10 @@ public class Sha256 extends BaseHash
String result = Util.toString(md.digest());
valid = Boolean.valueOf(DIGEST0.equals(result));
}
return valid.booleanValue();
}
// SHA specific methods ----------------------------------------------------
private static final synchronized int[] sha(int hh0, int hh1, int hh2,
private static synchronized final int[] sha(int hh0, int hh1, int hh2,
int hh3, int hh4, int hh5,
int hh6, int hh7, byte[] in,
int offset)
@@ -239,29 +211,31 @@ public class Sha256 extends BaseHash
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));
}
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];
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]);
+ (((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 >>> 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)));
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;
@@ -271,8 +245,8 @@ public class Sha256 extends BaseHash
B = A;
A = T + T2;
}
return new int[] { hh0 + A, hh1 + B, hh2 + C, hh3 + D, hh4 + E, hh5 + F,
hh6 + G, hh7 + H };
return new int[] {
hh0 + A, hh1 + B, hh2 + C, hh3 + D,
hh4 + E, hh5 + F, hh6 + G, hh7 + H };
}
}
@@ -42,66 +42,52 @@ 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>
* Implementation of SHA2-2 [SHA-384] per the IETF Draft Specification.
* <p>
* References:
* <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
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 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 String DIGEST0 =
"CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED"
+ "8086072BA1E7CC2358BAECA134C825A7";
private static final long[] w = new long[80];
@@ -111,9 +97,6 @@ public class Sha384 extends BaseHash
/** 512-bit interim result. */
private long h0, h1, h2, h3, h4, h5, h6, h7;
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public Sha384()
{
@@ -121,7 +104,7 @@ public class Sha384 extends BaseHash
}
/**
* <p>Private constructor for cloning purposes.</p>
* Private constructor for cloning purposes.
*
* @param md the instance to clone.
*/
@@ -141,9 +124,6 @@ public class Sha384 extends BaseHash
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)
@@ -151,22 +131,14 @@ public class Sha384 extends BaseHash
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];
@@ -179,57 +151,41 @@ public class Sha384 extends BaseHash
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
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;
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
};
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 };
}
protected void resetContext()
@@ -259,9 +215,7 @@ public class Sha384 extends BaseHash
return valid.booleanValue();
}
// SHA specific methods ----------------------------------------------------
private static final synchronized long[] sha(long hh0, long hh1, long hh2,
private static synchronized final long[] sha(long hh0, long hh1, long hh2,
long hh3, long hh4, long hh5,
long hh6, long hh7, byte[] in,
int offset)
@@ -276,35 +230,38 @@ public class Sha384 extends BaseHash
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);
}
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))
+ (((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 >>> 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)))
T2 = (((A >>> 28) | (A << 36))
^ ((A >>> 34) | (A << 30))
^ ((A >>> 39) | (A << 25)))
+ ((A & B) ^ (A & C) ^ (B & C));
H = G;
G = F;
@@ -315,8 +272,8 @@ public class Sha384 extends BaseHash
B = A;
A = T + T2;
}
return new long[] { hh0 + A, hh1 + B, hh2 + C, hh3 + D, hh4 + E, hh5 + F,
hh6 + G, hh7 + H };
return new long[] {
hh0 + A, hh1 + B, hh2 + C, hh3 + D,
hh4 + E, hh5 + F, hh6 + G, hh7 + H };
}
}
@@ -42,66 +42,52 @@ 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>
* Implementation of SHA2-3 [SHA-512] per the IETF Draft Specification.
* <p>
* References:
* <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
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 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 String DIGEST0 =
"DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A"
+ "2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F";
private static final long[] w = new long[80];
@@ -111,9 +97,6 @@ public class Sha512 extends BaseHash
/** 512-bit interim result. */
private long h0, h1, h2, h3, h4, h5, h6, h7;
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public Sha512()
{
@@ -121,7 +104,7 @@ public class Sha512 extends BaseHash
}
/**
* <p>Private constructor for cloning purposes.</p>
* Private constructor for cloning purposes.
*
* @param md the instance to clone.
*/
@@ -141,9 +124,6 @@ public class Sha512 extends BaseHash
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)
@@ -151,22 +131,14 @@ public class Sha512 extends BaseHash
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];
@@ -179,59 +151,45 @@ public class Sha512 extends BaseHash
protected byte[] padBuffer()
{
int n = (int) (count % BLOCK_SIZE);
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;
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 };
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()
@@ -261,9 +219,7 @@ public class Sha512 extends BaseHash
return valid.booleanValue();
}
// SHA specific methods ----------------------------------------------------
private static final synchronized long[] sha(long hh0, long hh1, long hh2,
private static synchronized final long[] sha(long hh0, long hh1, long hh2,
long hh3, long hh4, long hh5,
long hh6, long hh7, byte[] in,
int offset)
@@ -278,33 +234,36 @@ public class Sha512 extends BaseHash
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);
}
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))
+ (((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 >>> 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)))
T2 = (((A >>> 28) | (A << 36))
^ ((A >>> 34) | (A << 30))
^ ((A >>> 39) | (A << 25)))
+ ((A & B) ^ (A & C) ^ (B & C));
H = G;
G = F;
@@ -315,8 +274,8 @@ public class Sha512 extends BaseHash
B = A;
A = T + T2;
}
return new long[] { hh0 + A, hh1 + B, hh2 + C, hh3 + D, hh4 + E, hh5 + F,
hh6 + G, hh7 + H };
return new long[] {
hh0 + A, hh1 + B, hh2 + C, hh3 + D,
hh4 + E, hh5 + F, hh6 + G, hh7 + H };
}
}
File diff suppressed because it is too large Load Diff
@@ -38,9 +38,12 @@ exception statement from your version. */
package gnu.java.security.hash;
import gnu.java.security.Configuration;
import gnu.java.security.Registry;
import gnu.java.security.util.Util;
import java.util.logging.Logger;
/**
* 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
@@ -59,18 +62,10 @@ import gnu.java.security.util.Util;
* <a href="mailto:vincent.rijmen@iaik.tugraz.at">Vincent Rijmen</a>.</li>
* </ol>
*/
public final class Whirlpool extends BaseHash
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 Logger log = Logger.getLogger(Whirlpool.class.getName());
private static final int BLOCK_SIZE = 64; // inner block size in bytes
/** The digest of the 0-bit long message. */
@@ -83,22 +78,22 @@ public final class Whirlpool extends BaseHash
/** Whirlpool S-box; p. 19. */
private static final String S_box = // 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";
"\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";
/** The 64-bit lookup tables; section 7.1 p. 13. */
private static final long[] T0 = new long[256];
@@ -130,12 +125,9 @@ public final class Whirlpool extends BaseHash
/** 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 s1, s2, s4, s5, s8, s9, t;
@@ -171,7 +163,6 @@ public final class Whirlpool extends BaseHash
T6[i] = t >>> 48 | t << 16;
T7[i] = t >>> 56 | t << 8;
}
for (r = 0, i = 0; r < R; )
rc[r++] = (T0[i++] & 0xFF00000000000000L)
^ (T1[i++] & 0x00FF000000000000L)
@@ -181,103 +172,91 @@ public final class Whirlpool extends BaseHash
^ (T5[i++] & 0x0000000000FF0000L)
^ (T6[i++] & 0x000000000000FF00L)
^ (T7[i++] & 0x00000000000000FFL);
time = System.currentTimeMillis() - time;
if (DEBUG && debuglevel > 8)
if (Configuration.DEBUG)
{
System.out.println("==========");
System.out.println();
System.out.println("Static data");
System.out.println();
System.out.println();
System.out.println("T0[]:");
log.fine("Static data");
log.fine("T0[]:");
StringBuilder sb;
for (i = 0; i < 64; i++)
{
sb = new StringBuilder();
for (j = 0; j < 4; j++)
System.out.print("0x" + Util.toString(T0[i * 4 + j]) + ", ");
sb.append("0x").append(Util.toString(T0[i * 4 + j])).append(", ");
System.out.println();
log.fine(sb.toString());
}
System.out.println();
System.out.println("T1[]:");
log.fine("T1[]:");
for (i = 0; i < 64; i++)
{
sb = new StringBuilder();
for (j = 0; j < 4; j++)
System.out.print("0x" + Util.toString(T1[i * 4 + j]) + ", ");
sb.append("0x").append(Util.toString(T1[i * 4 + j])).append(", ");
System.out.println();
log.fine(sb.toString());
}
System.out.println();
System.out.println("T2[]:");
log.fine("T2[]:");
for (i = 0; i < 64; i++)
{
sb = new StringBuilder();
for (j = 0; j < 4; j++)
System.out.print("0x" + Util.toString(T2[i * 4 + j]) + ", ");
sb.append("0x").append(Util.toString(T2[i * 4 + j])).append(", ");
System.out.println();
log.fine(sb.toString());
}
System.out.println();
System.out.println("T3[]:");
log.fine("T3[]:");
for (i = 0; i < 64; i++)
{
sb = new StringBuilder();
for (j = 0; j < 4; j++)
System.out.print("0x" + Util.toString(T3[i * 4 + j]) + ", ");
sb.append("0x").append(Util.toString(T3[i * 4 + j])).append(", ");
System.out.println();
log.fine(sb.toString());
}
System.out.println();
System.out.println("T4[]:");
log.fine("\nT4[]:");
for (i = 0; i < 64; i++)
{
sb = new StringBuilder();
for (j = 0; j < 4; j++)
System.out.print("0x" + Util.toString(T4[i * 4 + j]) + ", ");
sb.append("0x").append(Util.toString(T4[i * 4 + j])).append(", ");
System.out.println();
log.fine(sb.toString());
}
System.out.println();
System.out.println("T5[]:");
log.fine("T5[]:");
for (i = 0; i < 64; i++)
{
sb = new StringBuilder();
for (j = 0; j < 4; j++)
System.out.print("0x" + Util.toString(T5[i * 4 + j]) + ", ");
sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
System.out.println();
log.fine(sb.toString());
}
System.out.println();
System.out.println("T6[]:");
log.fine("T6[]:");
for (i = 0; i < 64; i++)
{
sb = new StringBuilder();
for (j = 0; j < 4; j++)
System.out.print("0x" + Util.toString(T5[i * 4 + j]) + ", ");
sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
System.out.println();
log.fine(sb.toString());
}
System.out.println();
System.out.println("T7[]:");
log.fine("T7[]:");
for (i = 0; i < 64; i++)
{
sb = new StringBuilder();
for (j = 0; j < 4; j++)
System.out.print("0x" + Util.toString(T5[i * 4 + j]) + ", ");
sb.append("0x").append(Util.toString(T5[i * 4 + j])).append(", ");
System.out.println();
log.fine(sb.toString());
}
System.out.println();
System.out.println("rc[]:");
log.fine("rc[]:");
for (i = 0; i < R; i++)
System.out.println("0x" + Util.toString(rc[i]));
log.fine("0x" + Util.toString(rc[i]));
System.out.println();
System.out.println();
System.out.println("Total initialization time: " + time + " ms.");
System.out.println();
log.fine("Total initialization time: " + time + " ms.");
}
}
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public Whirlpool()
{
@@ -285,7 +264,7 @@ public final class Whirlpool extends BaseHash
}
/**
* <p>Private constructor for cloning purposes.</p>
* Private constructor for cloning purposes.
*
* @param md the instance to clone.
*/
@@ -305,21 +284,11 @@ public final class Whirlpool extends BaseHash
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
@@ -387,7 +356,6 @@ public final class Whirlpool extends BaseHash
| (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;
@@ -397,7 +365,6 @@ public final class Whirlpool extends BaseHash
k05 = H5;
k06 = H6;
k07 = H7;
nn0 = n0 ^ k00;
nn1 = n1 ^ k01;
nn2 = n2 ^ k02;
@@ -406,10 +373,8 @@ public final class Whirlpool extends BaseHash
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]
@@ -478,7 +443,6 @@ public final class Whirlpool extends BaseHash
^ T5[(int)((k02 >> 16) & 0xFFL)]
^ T6[(int)((k01 >> 8) & 0xFFL)]
^ T7[(int)( k00 & 0xFFL)];
k00 = Kr0;
k01 = Kr1;
k02 = Kr2;
@@ -487,7 +451,6 @@ public final class Whirlpool extends BaseHash
k05 = Kr5;
k06 = Kr6;
k07 = Kr7;
// 2. incrementally compute the cipher output
w0 = T0[(int)((nn0 >> 56) & 0xFFL)]
^ T1[(int)((nn7 >> 48) & 0xFFL)]
@@ -553,7 +516,6 @@ public final class Whirlpool extends BaseHash
^ T5[(int)((nn2 >> 16) & 0xFFL)]
^ T6[(int)((nn1 >> 8) & 0xFFL)]
^ T7[(int)( nn0 & 0xFFL)] ^ Kr7;
nn0 = w0;
nn1 = w1;
nn2 = w2;
@@ -563,7 +525,6 @@ public final class Whirlpool extends BaseHash
nn6 = w6;
nn7 = w7;
}
// apply the Miyaguchi-Preneel hash scheme
H0 ^= w0 ^ n0;
H1 ^= w1 ^ n1;
@@ -588,12 +549,9 @@ public final class Whirlpool extends BaseHash
// 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;
@@ -605,14 +563,13 @@ public final class Whirlpool extends BaseHash
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[] {
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),
@@ -628,10 +585,8 @@ public final class Whirlpool extends BaseHash
(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
};
(byte)(H7 >>> 24), (byte)(H7 >>> 16), (byte)(H7 >>> 8), (byte) H7 };
return result;
}
protected void resetContext()
@@ -642,8 +597,10 @@ public final class Whirlpool extends BaseHash
public boolean selfTest()
{
if (valid == null)
valid = Boolean.valueOf(DIGEST0.equals(Util.toString(new Whirlpool().digest())));
{
String d = Util.toString(new Whirlpool().digest());
valid = Boolean.valueOf(DIGEST0.equals(d));
}
return valid.booleanValue();
}
}
@@ -41,26 +41,14 @@ 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>
* The implementation of the HAVAL <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.
*/
public class HavalSpi extends MessageDigestAdapter
public class HavalSpi
extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public HavalSpi()
{
super(Registry.HAVAL_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -41,27 +41,15 @@ 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>
* The implementation of the MD2 <i>Service Provider Interface</i> (<b>SPI</b>)
* adapter.
*/
public class MD2Spi extends MessageDigestAdapter
public class MD2Spi
extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public MD2Spi()
{
super(Registry.MD2_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -41,27 +41,15 @@ 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>
* The implementation of the MD4 <i>Service Provider Interface</i> (<b>SPI</b>)
* adapter.
*/
public class MD4Spi extends MessageDigestAdapter
public class MD4Spi
extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public MD4Spi()
{
super(Registry.MD4_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -42,25 +42,13 @@ import gnu.java.security.Registry;
/**
* The implementation of the MD5 <i>Service Provider Interface</i> (<b>SPI</b>)
* adapter.<p>
* adapter.
*/
public class MD5Spi extends MessageDigestAdapter
public class MD5Spi
extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public MD5Spi()
{
super(Registry.MD5_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -46,35 +46,30 @@ 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>
*
* class to wrap GNU 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 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>
* the GNU provider implement the {@link Cloneable} interface.
*/
class MessageDigestAdapter extends MessageDigestSpi implements Cloneable
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)
@@ -84,7 +79,7 @@ class MessageDigestAdapter extends MessageDigestSpi implements Cloneable
/**
* Private constructor for cloning purposes.
*
*
* @param adaptee a clone of the underlying hash algorithm instance.
*/
private MessageDigestAdapter(IMessageDigest adaptee)
@@ -94,12 +89,6 @@ class MessageDigestAdapter extends MessageDigestSpi implements Cloneable
this.adaptee = adaptee;
}
// Class methods
// -------------------------------------------------------------------------
// java.security.MessageDigestSpi interface implementation
// -------------------------------------------------------------------------
public Object clone()
{
return new MessageDigestAdapter((IMessageDigest) adaptee.clone());
@@ -130,9 +119,8 @@ class MessageDigestAdapter extends MessageDigestSpi implements Cloneable
{
int result = adaptee.hashSize();
if (len < result)
{
throw new DigestException();
}
throw new DigestException();
byte[] md = adaptee.digest();
System.arraycopy(md, 0, buf, offset, result);
return result;
@@ -42,25 +42,13 @@ import gnu.java.security.Registry;
/**
* The implementation of the RIPEMD-128 <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.<p>
* (<b>SPI</b>) adapter.
*/
public class RipeMD128Spi extends MessageDigestAdapter
public class RipeMD128Spi
extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public RipeMD128Spi()
{
super(Registry.RIPEMD128_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -42,25 +42,13 @@ import gnu.java.security.Registry;
/**
* The implementation of the RIPEMD-160 <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.<p>
* (<b>SPI</b>) adapter.
*/
public class RipeMD160Spi extends MessageDigestAdapter
public class RipeMD160Spi
extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public RipeMD160Spi()
{
super(Registry.RIPEMD160_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -42,25 +42,13 @@ import gnu.java.security.Registry;
/**
* The implementation of the SHA-1 (160-bit) <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.<p>
* (<b>SPI</b>) adapter.
*/
public class Sha160Spi extends MessageDigestAdapter
public class Sha160Spi
extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha160Spi()
{
super(Registry.SHA160_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -41,26 +41,14 @@ 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>
* The implementation of the SHA-2-1 (256-bit) <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.
*/
public class Sha256Spi extends MessageDigestAdapter
public class Sha256Spi
extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha256Spi()
{
super(Registry.SHA256_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -41,26 +41,14 @@ 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>
* The implementation of the SHA-2-2 (384-bit) <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.
*/
public class Sha384Spi extends MessageDigestAdapter
public class Sha384Spi
extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha384Spi()
{
super(Registry.SHA384_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -41,26 +41,14 @@ 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>
* The implementation of the SHA-2-3 (512-bit) <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.
*/
public class Sha512Spi extends MessageDigestAdapter
public class Sha512Spi
extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha512Spi()
{
super(Registry.SHA512_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -41,27 +41,15 @@ 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>
* The implementation of the Tiger <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.
*/
public class TigerSpi extends MessageDigestAdapter
public class TigerSpi
extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public TigerSpi()
{
super(Registry.TIGER_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -42,25 +42,13 @@ import gnu.java.security.Registry;
/**
* The implementation of the Whirlpool <i>Service Provider Interface</i>
* (<b>SPI</b>) adapter.<p>
* (<b>SPI</b>) adapter.
*/
public class WhirlpoolSpi extends MessageDigestAdapter
public class WhirlpoolSpi
extends MessageDigestAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public WhirlpoolSpi()
{
super(Registry.WHIRLPOOL_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -42,25 +42,13 @@ import gnu.java.security.Registry;
/**
* The implementation of the HAVAL-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) Adapter.<p>
* Interface</i> (<b>SPI</b>) adapter.
*/
public class HavalRandomSpi extends SecureRandomAdapter
public class HavalRandomSpi
extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public HavalRandomSpi()
{
super(Registry.HAVAL_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -42,25 +42,13 @@ import gnu.java.security.Registry;
/**
* The implementation of the MD2-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
* Interface</i> (<b>SPI</b>) adapter.
*/
public class MD2RandomSpi extends SecureRandomAdapter
public class MD2RandomSpi
extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public MD2RandomSpi()
{
super(Registry.MD2_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -42,25 +42,13 @@ import gnu.java.security.Registry;
/**
* The implementation of the MD4-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
* Interface</i> (<b>SPI</b>) adapter.
*/
public class MD4RandomSpi extends SecureRandomAdapter
public class MD4RandomSpi
extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public MD4RandomSpi()
{
super(Registry.MD4_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -42,25 +42,13 @@ import gnu.java.security.Registry;
/**
* The implementation of the MD5-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
* Interface</i> (<b>SPI</b>) adapter.
*/
public class MD5RandomSpi extends SecureRandomAdapter
public class MD5RandomSpi
extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public MD5RandomSpi()
{
super(Registry.MD5_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -41,26 +41,14 @@ 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>
* The implementation of the RIPEMD128-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.
*/
public class RipeMD128RandomSpi extends SecureRandomAdapter
public class RipeMD128RandomSpi
extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public RipeMD128RandomSpi()
{
super(Registry.RIPEMD128_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -42,25 +42,13 @@ import gnu.java.security.Registry;
/**
* The implementation of the RIPEMD160-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
* Interface</i> (<b>SPI</b>) adapter.
*/
public class RipeMD160RandomSpi extends SecureRandomAdapter
public class RipeMD160RandomSpi
extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public RipeMD160RandomSpi()
{
super(Registry.RIPEMD160_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -45,34 +45,28 @@ import java.security.SecureRandomSpi;
import java.util.Collections;
/**
* <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 implementation of a generic {@link java.security.SecureRandom} adapter
* class to wrap GNU PRNG instances based on Message Digest algorithms.
* <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>
* functionality of a cryptographically strong pseudo-random number generator.
* <p>
* All the abstract methods in the {@link SecureRandomSpi} class are implemented
* by this class and all its sub-classes.
*/
abstract class SecureRandomAdapter extends SecureRandomSpi
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>
*
* Trivial protected constructor.
*
* @param mdName the canonical name of the underlying hash algorithm.
*/
protected SecureRandomAdapter(String mdName)
@@ -80,23 +74,14 @@ abstract class SecureRandomAdapter extends SecureRandomSpi
super();
this.mdName = mdName;
adaptee.init (Collections.singletonMap (MDGenerator.MD_NAME, mdName));
adaptee.init(Collections.singletonMap(MDGenerator.MD_NAME, mdName));
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// java.security.SecureRandomSpi interface implementation ------------------
public byte[] engineGenerateSeed(int numBytes)
{
if (numBytes < 1)
{
return new byte[0];
}
return new byte[0];
byte[] result = new byte[numBytes];
this.engineNextBytes(result);
return result;
@@ -104,10 +89,8 @@ abstract class SecureRandomAdapter extends SecureRandomSpi
public void engineNextBytes(byte[] bytes)
{
if (!adaptee.isInitialised())
{
this.engineSetSeed(new byte[0]);
}
if (! adaptee.isInitialised())
this.engineSetSeed(new byte[0]);
try
{
adaptee.nextBytes(bytes, 0, bytes.length);
@@ -119,6 +102,6 @@ abstract class SecureRandomAdapter extends SecureRandomSpi
public void engineSetSeed(byte[] seed)
{
adaptee.addRandomBytes (seed);
adaptee.addRandomBytes(seed);
}
}
@@ -42,25 +42,13 @@ import gnu.java.security.Registry;
/**
* The implementation of the SHA1-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
* Interface</i> (<b>SPI</b>) adapter.
*/
public class Sha160RandomSpi extends SecureRandomAdapter
public class Sha160RandomSpi
extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha160RandomSpi()
{
super(Registry.SHA160_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -41,26 +41,14 @@ 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>
* The implementation of the SHA-256 based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.
*/
public class Sha256RandomSpi extends SecureRandomAdapter
public class Sha256RandomSpi
extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha256RandomSpi()
{
super(Registry.SHA256_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -41,26 +41,14 @@ 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>
* The implementation of the SHA-384 based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.
*/
public class Sha384RandomSpi extends SecureRandomAdapter
public class Sha384RandomSpi
extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha384RandomSpi()
{
super(Registry.SHA384_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -41,26 +41,14 @@ 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>
* The implementation of the SHA-512 based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.
*/
public class Sha512RandomSpi extends SecureRandomAdapter
public class Sha512RandomSpi
extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public Sha512RandomSpi()
{
super(Registry.SHA512_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -42,25 +42,13 @@ import gnu.java.security.Registry;
/**
* The implementation of the Tiger based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
* Interface</i> (<b>SPI</b>) adapter.
*/
public class TigerRandomSpi extends SecureRandomAdapter
public class TigerRandomSpi
extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public TigerRandomSpi()
{
super(Registry.TIGER_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -42,25 +42,13 @@ import gnu.java.security.Registry;
/**
* The implementation of the Whirlpool-based SecureRandom <i>Service Provider
* Interface</i> (<b>SPI</b>) adapter.<p>
* Interface</i> (<b>SPI</b>) adapter.
*/
public class WhirlpoolRandomSpi extends SecureRandomAdapter
public class WhirlpoolRandomSpi
extends SecureRandomAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public WhirlpoolRandomSpi()
{
super(Registry.WHIRLPOOL_HASH);
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -61,10 +61,11 @@ import java.security.spec.X509EncodedKeySpec;
/**
* DSA key factory.
*
*
* @author Casey Marshall (rsdio@metastatic.org)
*/
public class DSSKeyFactory extends KeyFactorySpi
public class DSSKeyFactory
extends KeyFactorySpi
{
// implicit 0-arguments constructor
@@ -80,7 +81,6 @@ public class DSSKeyFactory extends KeyFactorySpi
BigInteger y = spec.getY();
return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y);
}
if (keySpec instanceof X509EncodedKeySpec)
{
X509EncodedKeySpec spec = (X509EncodedKeySpec) keySpec;
@@ -93,12 +93,9 @@ public class DSSKeyFactory extends KeyFactorySpi
}
catch (RuntimeException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
throw new InvalidKeySpecException(x.getMessage(), x);
}
}
throw new InvalidKeySpecException("Unsupported (public) key specification");
}
@@ -114,7 +111,6 @@ public class DSSKeyFactory extends KeyFactorySpi
BigInteger x = spec.getX();
return new DSSPrivateKey(Registry.PKCS8_ENCODING_ID, p, q, g, x);
}
if (keySpec instanceof PKCS8EncodedKeySpec)
{
PKCS8EncodedKeySpec spec = (PKCS8EncodedKeySpec) keySpec;
@@ -127,12 +123,9 @@ public class DSSKeyFactory extends KeyFactorySpi
}
catch (RuntimeException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
throw new InvalidKeySpecException(x.getMessage(), x);
}
}
throw new InvalidKeySpecException("Unsupported (private) key specification");
}
@@ -150,7 +143,6 @@ public class DSSKeyFactory extends KeyFactorySpi
BigInteger y = dsaKey.getY();
return new DSAPublicKeySpec(y, p, q, g);
}
if (keySpec.isAssignableFrom(X509EncodedKeySpec.class))
{
if (key instanceof DSSPublicKey)
@@ -159,19 +151,16 @@ public class DSSKeyFactory extends KeyFactorySpi
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(
"Wrong key type or unsupported (public) key specification");
}
throw new InvalidKeySpecException("Unsupported (public) key specification");
}
if (key instanceof DSAPrivateKey)
{
if (keySpec.isAssignableFrom(DSAPrivateKeySpec.class))
@@ -183,7 +172,6 @@ public class DSSKeyFactory extends KeyFactorySpi
BigInteger x = dsaKey.getX();
return new DSAPrivateKeySpec(x, p, q, g);
}
if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class))
{
if (key instanceof DSSPrivateKey)
@@ -192,19 +180,16 @@ public class DSSKeyFactory extends KeyFactorySpi
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(
"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");
}
@@ -222,7 +207,6 @@ public class DSSKeyFactory extends KeyFactorySpi
BigInteger y = dsaKey.getY();
return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y);
}
if (key instanceof DSAPrivateKey)
{
DSAPrivateKey dsaKey = (DSAPrivateKey) key;
@@ -232,7 +216,6 @@ public class DSSKeyFactory extends KeyFactorySpi
BigInteger x = dsaKey.getX();
return new DSSPrivateKey(Registry.PKCS8_ENCODING_ID, p, q, g, x);
}
throw new InvalidKeyException("Wrong key type");
}
}
@@ -52,33 +52,21 @@ 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>
* to wrap GNU 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 provider uses a
* default <i>modulus</i> size (keysize) of 1024 bits.
*/
public class DSSKeyPairGeneratorSpi extends KeyPairGeneratorAdapter implements
DSAKeyPairGenerator
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);
@@ -90,43 +78,34 @@ public class DSSKeyPairGeneratorSpi extends KeyPairGeneratorAdapter implements
HashMap attributes = new HashMap();
if (params != null)
{
if (!(params instanceof DSAParameterSpec))
if (! (params instanceof DSAParameterSpec))
throw new InvalidAlgorithmParameterException(
"Parameters argument is not a non-null instance, or " +
"sub-instance, of java.security.spec.DSAParameterSpec");
"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.SOURCE_OF_RANDOMNESS, random);
attributes.put(DSSKeyPairGenerator.PREFERRED_ENCODING_FORMAT,
new Integer(Registry.ASN1_ENCODING_ID));
Integer.valueOf(Registry.ASN1_ENCODING_ID));
try
{
adaptee.setup(attributes);
}
catch (IllegalArgumentException x)
{
InvalidAlgorithmParameterException y =
new InvalidAlgorithmParameterException();
y.initCause(x);
throw y;
throw new InvalidAlgorithmParameterException(x.getMessage(), x);
}
}
// 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");
"Parameters argument is either null or is not an instance, or "
+ "sub-instance, of java.security.spec.DSAParameterSpec");
DSAParameterSpec spec = (DSAParameterSpec) params;
try
{
@@ -134,7 +113,7 @@ public class DSSKeyPairGeneratorSpi extends KeyPairGeneratorAdapter implements
}
catch (InvalidAlgorithmParameterException x)
{
InvalidParameterException y = new InvalidParameterException();
InvalidParameterException y = new InvalidParameterException(x.getMessage());
y.initCause(x);
throw y;
}
@@ -144,22 +123,22 @@ public class DSSKeyPairGeneratorSpi extends KeyPairGeneratorAdapter implements
throws InvalidParameterException
{
HashMap attributes = new HashMap();
attributes.put(DSSKeyPairGenerator.MODULUS_LENGTH, new Integer(modlen));
attributes.put(DSSKeyPairGenerator.MODULUS_LENGTH, Integer.valueOf(modlen));
if (random != null)
attributes.put(DSSKeyPairGenerator.SOURCE_OF_RANDOMNESS, random);
attributes.put(DSSKeyPairGenerator.USE_DEFAULTS,
Boolean.valueOf(!genParams));
Boolean.valueOf(! genParams));
attributes.put(DSSKeyPairGenerator.STRICT_DEFAULTS, Boolean.TRUE);
attributes.put(DSSKeyPairGenerator.PREFERRED_ENCODING_FORMAT,
new Integer(Registry.ASN1_ENCODING_ID));
Integer.valueOf(Registry.ASN1_ENCODING_ID));
try
{
adaptee.setup(attributes);
}
catch (IllegalArgumentException x)
{
InvalidParameterException y = new InvalidParameterException();
InvalidParameterException y = new InvalidParameterException(x.getMessage());
y.initCause(x);
throw y;
}
@@ -136,7 +136,6 @@ public class DSSParameters
if (! format.equalsIgnoreCase(Registry.ASN1_ENCODING_SHORT_NAME))
throw new IOException("Unknown or unsupported format: " + format);
}
engineInit(params);
}
@@ -191,7 +190,6 @@ public class DSSParameters
if (! format.equalsIgnoreCase(Registry.ASN1_ENCODING_SHORT_NAME))
throw new IOException("Unknown or unsupported format: " + format);
}
return engineGetEncoded();
}
@@ -42,27 +42,15 @@ 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>
* 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.
*/
public class DSSRawSignatureSpi extends SignatureAdapter
public class DSSRawSignatureSpi
extends SignatureAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public DSSRawSignatureSpi()
{
super(Registry.DSS_SIG, new DSSSignatureRawCodec());
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -38,6 +38,7 @@ exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Configuration;
import gnu.java.security.Registry;
import gnu.java.security.key.dss.DSSPrivateKey;
import gnu.java.security.key.dss.DSSPublicKey;
@@ -79,11 +80,6 @@ public class EncodedKeyFactory
{
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
{
@@ -96,21 +92,15 @@ public class EncodedKeyFactory
}
catch (InstantiationException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
throw new InvalidKeySpecException(x.getMessage(), x);
}
catch (IllegalAccessException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(y);
throw y;
throw new InvalidKeySpecException(x.getMessage(), x);
}
catch (InvocationTargetException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
throw new InvalidKeySpecException(x.getMessage(), x);
}
}
@@ -124,9 +114,7 @@ public class EncodedKeyFactory
}
catch (ClassNotFoundException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
throw new InvalidKeySpecException(x.getMessage(), x);
}
}
@@ -144,9 +132,7 @@ public class EncodedKeyFactory
}
catch (NoSuchMethodException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
throw new InvalidKeySpecException(x.getMessage(), x);
}
}
@@ -162,15 +148,11 @@ public class EncodedKeyFactory
}
catch (IllegalAccessException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
throw new InvalidKeySpecException(x.getMessage(), x);
}
catch (InvocationTargetException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
throw new InvalidKeySpecException(x.getMessage(), x);
}
}
@@ -184,20 +166,15 @@ public class EncodedKeyFactory
}
catch (NoSuchMethodException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
throw new InvalidKeySpecException(x.getMessage(), x);
}
}
// Instance methods
// --------------------------------------------------------------------------
protected PublicKey engineGeneratePublic(KeySpec keySpec)
throws InvalidKeySpecException
{
log.entering(this.getClass().getName(), "engineGeneratePublic()", keySpec);
if (Configuration.DEBUG)
log.entering(this.getClass().getName(), "engineGeneratePublic()", keySpec);
PublicKey result = null;
if (keySpec instanceof DSAPublicKeySpec)
result = decodeDSSPublicKey((DSAPublicKeySpec) keySpec);
@@ -220,10 +197,10 @@ public class EncodedKeyFactory
}
catch (InvalidParameterException ignored)
{
log.log(Level.FINE, "Exception in DSSPublicKey.valueOf(). Ignore",
ignored);
if (Configuration.DEBUG)
log.log(Level.FINE, "Exception in DSSPublicKey.valueOf(). Ignore",
ignored);
}
if (! ok) // try RSA
try
{
@@ -232,24 +209,24 @@ public class EncodedKeyFactory
}
catch (InvalidParameterException ignored)
{
log.log(Level.FINE,
"Exception in GnuRSAPublicKey.valueOf(). Ignore",
ignored);
if (Configuration.DEBUG)
log.log(Level.FINE,
"Exception in GnuRSAPublicKey.valueOf(). Ignore",
ignored);
}
if (! ok) // try DH
result = decodeDHPublicKey(input);
}
log.exiting(this.getClass().getName(), "engineGeneratePublic()", result);
if (Configuration.DEBUG)
log.exiting(this.getClass().getName(), "engineGeneratePublic()", result);
return result;
}
protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
throws InvalidKeySpecException
{
log.entering(this.getClass().getName(), "engineGeneratePrivate()", keySpec);
if (Configuration.DEBUG)
log.entering(this.getClass().getName(), "engineGeneratePrivate()", keySpec);
PrivateKey result = null;
if (keySpec instanceof DSAPrivateKeySpec)
result = decodeDSSPrivateKey((DSAPrivateKeySpec) keySpec);
@@ -272,10 +249,10 @@ public class EncodedKeyFactory
}
catch (InvalidParameterException ignored)
{
log.log(Level.FINE, "Exception in DSSPrivateKey.valueOf(). Ignore",
ignored);
if (Configuration.DEBUG)
log.log(Level.FINE, "Exception in DSSPrivateKey.valueOf(). Ignore",
ignored);
}
if (! ok) // try RSA
try
{
@@ -284,16 +261,16 @@ public class EncodedKeyFactory
}
catch (InvalidParameterException ignored)
{
log.log(Level.FINE,
"Exception in GnuRSAPrivateKey.valueOf(). Ignore",
ignored);
if (Configuration.DEBUG)
log.log(Level.FINE,
"Exception in GnuRSAPrivateKey.valueOf(). Ignore",
ignored);
}
if (! ok) // try DH
result = decodeDHPrivateKey(input);
}
log.exiting(this.getClass().getName(), "engineGeneratePrivate()", result);
if (Configuration.DEBUG)
log.exiting(this.getClass().getName(), "engineGeneratePrivate()", result);
return result;
}
@@ -321,7 +298,7 @@ public class EncodedKeyFactory
/**
* @param spec an instance of {@link DSAPublicKeySpec} to decode.
* @return an instance of {@link DSSPublicKey} constructed from the
* information in the designated key-specification.
* information in the designated key-specification.
*/
private DSSPublicKey decodeDSSPublicKey(DSAPublicKeySpec spec)
{
@@ -335,7 +312,7 @@ public class EncodedKeyFactory
/**
* @param spec an instance of {@link RSAPublicKeySpec} to decode.
* @return an instance of {@link GnuRSAPublicKey} constructed from the
* information in the designated key-specification.
* information in the designated key-specification.
*/
private GnuRSAPublicKey decodeRSAPublicKey(RSAPublicKeySpec spec)
{
@@ -358,7 +335,7 @@ public class EncodedKeyFactory
BigInteger p = spec.getP();
BigInteger g = spec.getG();
BigInteger y = spec.getY();
Object[] params = new Object[] {new Integer(Registry.X509_ENCODING_ID),
Object[] params = new Object[] {Integer.valueOf(Registry.X509_ENCODING_ID),
null, p, g, y};
Object obj = invokeConstructor("gnu.javax.crypto.key.dh.GnuDHPublicKey",
params);
@@ -384,7 +361,7 @@ public class EncodedKeyFactory
/**
* @param spec an instance of {@link DSAPrivateKeySpec} to decode.
* @return an instance of {@link DSSPrivateKey} constructed from the
* information in the designated key-specification.
* information in the designated key-specification.
*/
private PrivateKey decodeDSSPrivateKey(DSAPrivateKeySpec spec)
{
@@ -398,7 +375,7 @@ public class EncodedKeyFactory
/**
* @param spec an instance of {@link RSAPrivateCrtKeySpec} to decode.
* @return an instance of {@link GnuRSAPrivateKey} constructed from the
* information in the designated key-specification.
* information in the designated key-specification.
*/
private PrivateKey decodeRSAPrivateKey(RSAPrivateCrtKeySpec spec)
{
@@ -428,7 +405,7 @@ public class EncodedKeyFactory
BigInteger p = spec.getP();
BigInteger g = spec.getG();
BigInteger x = spec.getX();
Object[] params = new Object[] {new Integer(Registry.PKCS8_ENCODING_ID),
Object[] params = new Object[] {Integer.valueOf(Registry.PKCS8_ENCODING_ID),
null, p, g, x};
Object obj = invokeConstructor("gnu.javax.crypto.key.dh.GnuDHPrivateKey",
params);
@@ -49,36 +49,30 @@ 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>
*
* adapter class to wrap GNU 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>
* 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 provider supplies
* (and document) default values to be used. For example, the GNU provider uses
* a default <i>modulus</i> size (keysize) of 1024 bits for the DSS (Digital
* Signature Standard) a.k.a <i>DSA</i>.
*/
public abstract class KeyPairGeneratorAdapter extends KeyPairGenerator
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)
@@ -88,12 +82,6 @@ public abstract class KeyPairGeneratorAdapter extends KeyPairGenerator
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,
@@ -76,7 +76,6 @@ public class RSAKeyFactory
BigInteger e = spec.getPublicExponent();
return new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e);
}
if (keySpec instanceof X509EncodedKeySpec)
{
X509EncodedKeySpec spec = (X509EncodedKeySpec) keySpec;
@@ -88,12 +87,9 @@ public class RSAKeyFactory
}
catch (RuntimeException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
throw new InvalidKeySpecException(x.getMessage(), x);
}
}
throw new InvalidKeySpecException("Unsupported (public) key specification");
}
@@ -114,16 +110,6 @@ public class RSAKeyFactory
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;
@@ -135,12 +121,9 @@ public class RSAKeyFactory
}
catch (RuntimeException x)
{
InvalidKeySpecException y = new InvalidKeySpecException();
y.initCause(x);
throw y;
throw new InvalidKeySpecException(x.getMessage(), x);
}
}
throw new InvalidKeySpecException("Unsupported (private) key specification");
}
@@ -156,7 +139,6 @@ public class RSAKeyFactory
BigInteger e = rsaKey.getPublicExponent();
return new RSAPublicKeySpec(n, e);
}
if (keySpec.isAssignableFrom(X509EncodedKeySpec.class))
{
if (key instanceof GnuRSAPublicKey)
@@ -171,13 +153,11 @@ public class RSAKeyFactory
byte[] encoded = key.getEncoded();
return new X509EncodedKeySpec(encoded);
}
throw new InvalidKeySpecException("Wrong key type or unsupported (public) key specification");
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))
{
@@ -192,7 +172,6 @@ public class RSAKeyFactory
BigInteger qInv = rsaKey.getCrtCoefficient();
return new RSAPrivateCrtKeySpec(n, e, d, p, q, dP, dQ, qInv);
}
if ((key instanceof RSAPrivateKey)
&& keySpec.isAssignableFrom(RSAPrivateKeySpec.class))
{
@@ -201,7 +180,6 @@ public class RSAKeyFactory
BigInteger d = rsaKey.getPrivateExponent();
return new RSAPrivateKeySpec(n, d);
}
if (keySpec.isAssignableFrom(PKCS8EncodedKeySpec.class))
{
if (key instanceof GnuRSAPrivateKey)
@@ -210,17 +188,16 @@ public class RSAKeyFactory
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 (private) key specification");
}
throw new InvalidKeySpecException("Wrong key type or unsupported key specification");
throw new InvalidKeySpecException(
"Wrong key type or unsupported key specification");
}
protected Key engineTranslateKey(Key key) throws InvalidKeyException
@@ -235,7 +212,6 @@ public class RSAKeyFactory
BigInteger e = rsaKey.getPublicExponent();
return new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e);
}
if (key instanceof RSAPrivateCrtKey)
{
RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey) key;
@@ -250,16 +226,6 @@ public class RSAKeyFactory
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");
}
}
@@ -49,43 +49,29 @@ 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>
* to wrap GNU 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 provider uses a
* default <i>modulus</i> size (keysize) of 1024 bits.
*/
public class RSAKeyPairGeneratorSpi extends KeyPairGeneratorAdapter
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));
attributes.put(RSAKeyPairGenerator.MODULUS_LENGTH, Integer.valueOf(keysize));
if (random != null)
{
attributes.put(RSAKeyPairGenerator.SOURCE_OF_RANDOMNESS, random);
}
attributes.put(RSAKeyPairGenerator.SOURCE_OF_RANDOMNESS, random);
attributes.put(RSAKeyPairGenerator.PREFERRED_ENCODING_FORMAT,
new Integer(Registry.ASN1_ENCODING_ID));
Integer.valueOf(Registry.ASN1_ENCODING_ID));
adaptee.setup(attributes);
}
@@ -95,21 +81,16 @@ public class RSAKeyPairGeneratorSpi extends KeyPairGeneratorAdapter
HashMap attributes = new HashMap();
if (params != null)
{
if (!(params instanceof RSAKeyGenParameterSpec))
{
throw new InvalidAlgorithmParameterException("params");
}
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.SOURCE_OF_RANDOMNESS, random);
attributes.put(RSAKeyPairGenerator.PREFERRED_ENCODING_FORMAT,
new Integer(Registry.ASN1_ENCODING_ID));
Integer.valueOf(Registry.ASN1_ENCODING_ID));
adaptee.setup(attributes);
}
}
@@ -42,26 +42,15 @@ 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>
* 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.
*/
public class RSAPSSRawSignatureSpi extends SignatureAdapter
public class RSAPSSRawSignatureSpi
extends SignatureAdapter
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public RSAPSSRawSignatureSpi()
{
super(Registry.RSA_PSS_SIG, new RSAPSSSignatureRawCodec());
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
}
@@ -38,6 +38,7 @@ exception statement from your version. */
package gnu.java.security.jce.sig;
import gnu.java.security.Configuration;
import gnu.java.security.sig.BaseSignature;
import gnu.java.security.sig.ISignature;
import gnu.java.security.sig.ISignatureCodec;
@@ -57,38 +58,34 @@ 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>
*
* to wrap GNU 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 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>
* the GNU provider implement the {@link Cloneable} interface.
*/
class SignatureAdapter extends SignatureSpi implements Cloneable
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>
*
* Trivial protected constructor.
*
* @param sigName the canonical name of the signature scheme.
* @param codec the signature codec engine to use with this scheme.
*/
@@ -98,8 +95,8 @@ class SignatureAdapter extends SignatureSpi implements Cloneable
}
/**
* Private constructor for cloning purposes.<p>
*
* Private constructor for cloning purposes.
*
* @param adaptee a clone of the underlying signature scheme instance.
* @param codec the signature codec engine to use with this scheme.
*/
@@ -111,12 +108,6 @@ class SignatureAdapter extends SignatureSpi implements Cloneable
this.codec = codec;
}
// Class methods
// -------------------------------------------------------------------------
// java.security.SignatureSpi interface implementation
// -------------------------------------------------------------------------
public Object clone()
{
return new SignatureAdapter((ISignature) adaptee.clone(), codec);
@@ -132,7 +123,7 @@ class SignatureAdapter extends SignatureSpi implements Cloneable
}
catch (IllegalArgumentException x)
{
throw new InvalidKeyException(String.valueOf(x));
throw new InvalidKeyException(x.getMessage(), x);
}
}
@@ -146,7 +137,7 @@ class SignatureAdapter extends SignatureSpi implements Cloneable
}
catch (IllegalArgumentException x)
{
throw new InvalidKeyException(String.valueOf(x));
throw new InvalidKeyException(x.getMessage(), x);
}
}
@@ -162,7 +153,7 @@ class SignatureAdapter extends SignatureSpi implements Cloneable
}
catch (IllegalArgumentException x)
{
throw new InvalidKeyException(String.valueOf(x));
throw new InvalidKeyException(x.getMessage(), x);
}
}
@@ -174,7 +165,7 @@ class SignatureAdapter extends SignatureSpi implements Cloneable
}
catch (IllegalStateException x)
{
throw new SignatureException(String.valueOf(x));
throw new SignatureException(x.getMessage(), x);
}
}
@@ -187,7 +178,7 @@ class SignatureAdapter extends SignatureSpi implements Cloneable
}
catch (IllegalStateException x)
{
throw new SignatureException(String.valueOf(x));
throw new SignatureException(x.getMessage(), x);
}
}
@@ -200,9 +191,8 @@ class SignatureAdapter extends SignatureSpi implements Cloneable
}
catch (IllegalStateException x)
{
throw new SignatureException(String.valueOf(x));
throw new SignatureException(x.getMessage(), x);
}
byte[] result = codec.encodeSignature(signature);
return result;
}
@@ -213,9 +203,7 @@ class SignatureAdapter extends SignatureSpi implements Cloneable
byte[] signature = this.engineSign();
int result = signature.length;
if (result > len)
{
throw new SignatureException("len");
}
throw new SignatureException("Not enough room to store signature");
System.arraycopy(signature, 0, outbuf, offset, result);
return result;
@@ -223,8 +211,8 @@ class SignatureAdapter extends SignatureSpi implements Cloneable
public boolean engineVerify(byte[] sigBytes) throws SignatureException
{
log.entering("SignatureAdapter", "engineVerify");
if (Configuration.DEBUG)
log.entering(this.getClass().getName(), "engineVerify");
Object signature = codec.decodeSignature(sigBytes);
boolean result = false;
try
@@ -233,10 +221,11 @@ class SignatureAdapter extends SignatureSpi implements Cloneable
}
catch (IllegalStateException x)
{
throw new SignatureException(String.valueOf(x));
throw new SignatureException(x.getMessage(), x);
}
log.exiting("SignatureAdapter", "engineVerify", new Boolean(result));
if (Configuration.DEBUG)
log.exiting(this.getClass().getName(), "engineVerify",
Boolean.valueOf(result));
return result;
}
@@ -44,16 +44,13 @@ import java.security.PrivateKey;
import java.security.PublicKey;
/**
* <p>The visible methods of an object that knows how to encode and decode
* 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>
* (b) re-creating their internal Java representation from external sources.
*/
public interface IKeyPairCodec
{
// Constants
// -------------------------------------------------------------------------
/** Constant identifying the <i>Raw</i> encoding format. */
int RAW_FORMAT = Registry.RAW_ENCODING_ID;
@@ -69,62 +66,59 @@ public interface IKeyPairCodec
*/
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>
*
* Returns the unique identifier (within this library) of the format used to
* externalise public and private keys.
*
* @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>
*
* Encodes an instance of a public key for storage or transmission purposes.
*
* @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.
* according to the format supported by this codec.
* @exception IllegalArgumentException if the designated key is not supported
* by this codec.
* by this codec.
*/
byte[] encodePublicKey(PublicKey key);
/**
* <p>Encodes an instance of a private key for storage or transmission purposes.</p>
*
* Encodes an instance of a private key for storage or transmission purposes.
*
* @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.
* according to the format supported by this codec.
* @exception IllegalArgumentException if the designated key is not supported
* by this codec.
* by this codec.
*/
byte[] encodePrivateKey(PrivateKey key);
/**
* <p>Decodes an instance of an external public key into its native Java
* representation.</p>
*
* Decodes an instance of an external public key into its native Java
* representation.
*
* @param input the source of the externalised key to decode.
* @return a concrete instance of a public key, reconstructed from the
* designated input.
* 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.
* 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>
*
* Decodes an instance of an external private key into its native Java
* representation.
*
* @param input the source of the externalised key to decode.
* @return a concrete instance of a private key, reconstructed from the
* designated input.
* 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.
* contain a known representation of a private key for the format
* supported by the concrete codec.
*/
PrivateKey decodePrivateKey(byte[] input);
}
@@ -42,38 +42,31 @@ import java.security.KeyPair;
import java.util.Map;
/**
* The visible methods of every asymmetric keypair generator.<p>
* The visible methods of every asymmetric keypair generator.
*/
public interface IKeyPairGenerator
{
// Constants
// -------------------------------------------------------------------------
// Methods
// -------------------------------------------------------------------------
/**
* Returns the canonical name of this keypair generator.<p>
*
* Returns the canonical name of this keypair generator.
*
* @return the canonical name of this instance.
*/
String name();
/**
* [Re]-initialises this instance for use with a given set of attributes.<p>
*
* [Re]-initialises this instance for use with a given set of attributes.
*
* @param attributes a map of name/value pairs to use for setting up the
* instance.
* instance.
* @exception IllegalArgumentException if at least one of the mandatory
* attributes is missing or an invalid value was specified.
* 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();
@@ -207,10 +207,8 @@ public class KeyPairCodecFactory
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;
}
@@ -48,68 +48,48 @@ import java.util.HashSet;
import java.util.Set;
/**
* <p>A Factory to instantiate asymmetric keypair generators.</p>
* A Factory to instantiate asymmetric keypair generators.
*/
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>
*
* Returns an instance of a keypair generator given its name.
*
* @param name the case-insensitive key generator name.
* @return an instance of the keypair generator, or <code>null</code> if none
* found.
* @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;
}
return null;
name = name.trim();
IKeyPairGenerator result = null;
if (name.equalsIgnoreCase(Registry.DSA_KPG)
|| name.equalsIgnoreCase(Registry.DSS_KPG))
{
result = new DSSKeyPairGenerator();
}
result = new DSSKeyPairGenerator();
else if (name.equalsIgnoreCase(Registry.RSA_KPG))
{
result = new RSAKeyPairGenerator();
}
result = new RSAKeyPairGenerator();
else if (name.equalsIgnoreCase(Registry.DH_KPG))
{
result = makeInstance ("gnu.javax.crypto.key.dh.GnuDHKeyPairGenerator");
}
result = makeInstance("gnu.javax.crypto.key.dh.GnuDHKeyPairGenerator");
else if (name.equalsIgnoreCase(Registry.SRP_KPG))
{
result = makeInstance ("gnu.javax.crypto.key.srp6.SRPKeyPairGenerator");
}
result = makeInstance("gnu.javax.crypto.key.srp6.SRPKeyPairGenerator");
return result;
}
/**
* <p>Returns a {@link Set} of keypair generator names supported by this
* 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>
*
* the digital signature schemes with appendix supported by this library.
*
* @return a {@link Set} of keypair generator names (Strings).
*/
public static final Set getNames()
@@ -120,26 +100,21 @@ public class KeyPairGeneratorFactory
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)
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]);
Class c = Class.forName(clazz);
Constructor ctor = c.getConstructor(new Class[0]);
return (IKeyPairGenerator) ctor.newInstance(new Object[0]);
}
catch (Exception x)
{
throw new IllegalArgumentException(
"strong crypto key pair generator not available: " + clazz,
x);
"strong crypto key pair generator not available: " + clazz, x);
}
}
// Instance methods
// -------------------------------------------------------------------------
}
@@ -38,74 +38,77 @@ exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.classpath.SystemProperties;
import gnu.java.security.Registry;
import gnu.java.security.action.GetPropertyAction;
import gnu.java.security.util.FormatUtil;
import java.math.BigInteger;
import java.security.AccessController;
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
* 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>.
* <code>q</code> and <code>g</code>.
* <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>
*
* 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>
* <b>IMPORTANT</b>: Under certain circumstances (e.g. in an X.509 certificate
* with inherited AlgorithmIdentifier's parameters of a SubjectPublicKeyInfo
* element) these three MPIs may be <code>null</code>.
*
* @see DSSPrivateKey#getEncoded
* @see DSSPublicKey#getEncoded
*/
public abstract class DSSKey implements Key, DSAKey
public abstract class DSSKey
implements Key, DSAKey
{
// Constants and variables
// -------------------------------------------------------------------------
/**
* A prime modulus, where <code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup></code>
* for <code>512 &lt;= L &lt;= 1024</code> and <code>L</code> a multiple of
* A prime modulus, where
* <code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup></code> for
* <code>512 &lt;= L &lt;= 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> &lt; q
* A prime divisor of <code>p - 1</code>, where
* <code>2<sup>159</sup> &lt; q
* &lt; 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 &lt; h &lt; 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>g = h<sup>(p-1)</sup>/q mod p</code>, where <code>h</code> is
* any integer with <code>1 &lt; h &lt; 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.
* Identifier of the default encoding format to use when externalizing the key
* material.
*/
protected final int defaultFormat;
/** String representation of this key. Cached for speed. */
private transient String str;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Trivial protected constructor.
*
* @param defaultFormat the identifier of the encoding format to use by
* default when externalizing the key.
* 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>.
@@ -121,21 +124,11 @@ public abstract class DSSKey implements Key, DSAKey
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;
@@ -152,27 +145,31 @@ public abstract class DSSKey implements Key, DSAKey
return FormatUtil.getEncodingShortName(defaultFormat);
}
// Other instance methods --------------------------------------------------
/**
* <p>Returns <code>true</code> if the designated object is an instance of
* 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>
*
* values as this one.
* <p>
* Always returns <code>false</code> if the MPIs of this key are
* <i>inherited</i>. This may be the case when the key is re-constructed from
* an X.509 certificate with absent or NULL AlgorithmIdentifier's parameters
* field.
*
* @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.
* @return <code>true</code> if the designated object is of the same type
* and value as this one.
*/
public boolean equals(Object obj)
{
if (hasInheritedParameters())
return false;
if (obj == null)
{
return false;
}
if (!(obj instanceof DSAKey))
{
return false;
}
return false;
if (! (obj instanceof DSAKey))
return false;
DSAKey that = (DSAKey) obj;
return p.equals(that.getParams().getP())
&& q.equals(that.getParams().getQ())
@@ -183,19 +180,32 @@ public abstract class DSSKey implements Key, DSAKey
{
if (str == null)
{
String ls = SystemProperties.getProperty("line.separator");
str = new StringBuilder().append(ls)
.append("defaultFormat=").append(defaultFormat).append(",").append(ls)
.append("p=0x").append(p.toString(16)).append(",").append(ls)
.append("q=0x").append(q.toString(16)).append(",").append(ls)
.append("g=0x").append(g.toString(16))
.toString();
String ls = (String) AccessController.doPrivileged(new GetPropertyAction("line.separator"));
StringBuilder sb = new StringBuilder(ls)
.append("defaultFormat=").append(defaultFormat).append(",")
.append(ls);
if (hasInheritedParameters())
sb.append("p=inherited,").append(ls)
.append("q=inherited,").append(ls)
.append("g=inherited");
else
sb.append("p=0x").append(p.toString(16)).append(",").append(ls)
.append("q=0x").append(q.toString(16)).append(",").append(ls)
.append("g=0x").append(g.toString(16));
str = sb.toString();
}
return str;
}
// abstract methods to be implemented by subclasses ------------------------
public abstract byte[] getEncoded(int format);
/**
* @return <code>true</code> if <code>p</code>, <code>q</code> and
* <code>g</code> are all <code>null</code>. Returns
* <code>false</code> otherwise.
*/
public boolean hasInheritedParameters()
{
return p == null && q == null && g == null;
}
}
@@ -38,12 +38,12 @@ exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.java.security.Configuration;
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;
@@ -51,76 +51,57 @@ import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.DSAParameterSpec;
import java.util.Map;
import java.util.logging.Logger;
/**
* <p>A key-pair generator for asymetric keys to use in conjunction with the DSS
* (Digital Signature Standard).</p>
*
* References:<br>
* A key-pair generator for asymetric keys to use in conjunction with the DSS
* (Digital Signature Standard).
* <p>
* References:
* <p>
* <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.
* Standard (DSS)</a>, Federal Information Processing Standards Publication
* 186. National Institute of Standards and Technology.
*/
public class DSSKeyPairGenerator implements IKeyPairGenerator
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
// -------------------------------------------------------------------------
private static final Logger log = Logger.getLogger(DSSKeyPairGenerator.class.getName());
/** The BigInteger constant 2. */
private static final BigInteger TWO = new BigInteger("2");
private static final BigInteger TWO = BigInteger.valueOf(2L);
/** 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
* 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>
* <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";
@@ -145,8 +126,8 @@ public class DSSKeyPairGenerator implements IKeyPairGenerator
/**
* 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,
* 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";
@@ -165,55 +146,41 @@ public class DSSKeyPairGenerator implements IKeyPairGenerator
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 };
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));
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));
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));
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);
@@ -243,31 +210,18 @@ public class DSSKeyPairGenerator implements IKeyPairGenerator
/** 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>
*
* Configures this instance.
*
* @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>.
* @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)
{
@@ -280,9 +234,7 @@ public class DSSKeyPairGenerator implements IKeyPairGenerator
// should we use the default pre-computed params?
Boolean useDefaults = (Boolean) attributes.get(USE_DEFAULTS);
if (useDefaults == null)
{
useDefaults = Boolean.TRUE;
}
useDefaults = Boolean.TRUE;
Boolean strictDefaults = (Boolean) attributes.get(STRICT_DEFAULTS);
if (strictDefaults == null)
@@ -334,16 +286,12 @@ public class DSSKeyPairGenerator implements IKeyPairGenerator
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();
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);
@@ -361,76 +309,65 @@ public class DSSKeyPairGenerator implements IKeyPairGenerator
p = params[FIPS186.DSA_PARAMS_P];
e = params[FIPS186.DSA_PARAMS_E];
g = params[FIPS186.DSA_PARAMS_G];
if (DEBUG && debuglevel > 0)
if (Configuration.DEBUG)
{
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));
log.fine("seed: " + seed.toString(16));
log.fine("counter: " + counter.intValue());
log.fine("q: " + q.toString(16));
log.fine("p: " + p.toString(16));
log.fine("e: " + e.toString(16));
log.fine("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>
*
* This method applies the following algorithm described in 3.1 of FIPS-186:
* <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>
* <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>
* <p>
* Where <code>b</code> is the length of a secret b-bit seed-key (XKEY).
* <p>
* Note that in this implementation, XSEED, the optional user input, is always
* zero.
*/
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] >>> 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>
*
* 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);
}
rnd.nextBytes(buffer);
else
getDefaultPRNG().nextBytes(buffer);
}
@@ -38,6 +38,7 @@ exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.java.security.Configuration;
import gnu.java.security.OID;
import gnu.java.security.Registry;
import gnu.java.security.der.DER;
@@ -158,11 +159,10 @@ public class DSSKeyPairPKCS8Codec
}
catch (IOException e)
{
InvalidParameterException y = new InvalidParameterException();
InvalidParameterException y = new InvalidParameterException(e.getMessage());
y.initCause(e);
throw y;
}
return result;
}
@@ -184,8 +184,8 @@ public class DSSKeyPairPKCS8Codec
*/
public PrivateKey decodePrivateKey(byte[] input)
{
log.entering("DSSKeyPairPKCS8Codec", "decodePrivateKey");
if (Configuration.DEBUG)
log.entering(this.getClass().getName(), "decodePrivateKey");
if (input == null)
throw new InvalidParameterException("Input bytes MUST NOT be null");
@@ -226,9 +226,11 @@ public class DSSKeyPairPKCS8Codec
g = (BigInteger) val.getValue();
val = der.read();
log.finest("val = " + val);
if (Configuration.DEBUG)
log.fine("val = " + val);
byte[] xBytes = (byte[]) val.getValue();
log.finest(Util.dumpString(xBytes, "xBytes: "));
if (Configuration.DEBUG)
log.fine(Util.dumpString(xBytes, "xBytes: "));
DERReader der2 = new DERReader(xBytes);
val = der2.read();
DerUtil.checkIsBigInteger(val, "Wrong X field");
@@ -236,12 +238,12 @@ public class DSSKeyPairPKCS8Codec
}
catch (IOException e)
{
InvalidParameterException y = new InvalidParameterException();
InvalidParameterException y = new InvalidParameterException(e.getMessage());
y.initCause(e);
throw y;
}
log.exiting("DSSKeyPairPKCS8Codec", "decodePrivateKey");
if (Configuration.DEBUG)
log.exiting(this.getClass().getName(), "decodePrivateKey");
return new DSSPrivateKey(Registry.PKCS8_ENCODING_ID, p, q, g, x);
}
}
@@ -47,91 +47,72 @@ 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>
* An object that implements the {@link IKeyPairCodec} operations for the
* <i>Raw</i> format to use with DSS keypairs.
*/
public class DSSKeyPairRawCodec implements IKeyPairCodec
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>
* 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>
* The <i>Raw</i> format for a DSA public key, in this implementation, is a
* byte sequence consisting of the following:
* <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>
* <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.
* (Digital Signature Standard) one.
* @see Registry#MAGIC_RAW_DSS_PUBLIC_KEY
*/
public byte[] encodePublicKey(PublicKey key)
{
if (!(key instanceof DSSPublicKey))
{
throw new IllegalArgumentException("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;
@@ -140,7 +121,6 @@ public class DSSKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// q
buffer = dssKey.getParams().getQ().toByteArray();
length = buffer.length;
@@ -149,7 +129,6 @@ public class DSSKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// g
buffer = dssKey.getParams().getG().toByteArray();
length = buffer.length;
@@ -158,7 +137,6 @@ public class DSSKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// y
buffer = dssKey.getY().toByteArray();
length = buffer.length;
@@ -167,7 +145,6 @@ public class DSSKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
return baos.toByteArray();
}
@@ -178,112 +155,106 @@ public class DSSKeyPairRawCodec implements IKeyPairCodec
|| 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");
}
throw new IllegalArgumentException("magic");
// version
if (k[4] != 0x01)
{
throw new IllegalArgumentException("version");
}
int i = 5;
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);
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);
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);
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);
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>
* 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>
* The <i>Raw</i> format for a DSA private key, in this implementation, is a
* byte sequence consisting of the following:
* <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>
* <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.
* (Digital Signature Standard) one.
*/
public byte[] encodePrivateKey(PrivateKey key)
{
if (!(key instanceof DSSPrivateKey))
{
throw new IllegalArgumentException("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;
@@ -292,7 +263,6 @@ public class DSSKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// q
buffer = dssKey.getParams().getQ().toByteArray();
length = buffer.length;
@@ -301,7 +271,6 @@ public class DSSKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// g
buffer = dssKey.getParams().getG().toByteArray();
length = buffer.length;
@@ -310,7 +279,6 @@ public class DSSKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// x
buffer = dssKey.getX().toByteArray();
length = buffer.length;
@@ -319,7 +287,6 @@ public class DSSKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
return baos.toByteArray();
}
@@ -330,52 +297,51 @@ public class DSSKeyPairRawCodec implements IKeyPairCodec
|| 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");
}
throw new IllegalArgumentException("magic");
// version
if (k[4] != 0x01)
{
throw new IllegalArgumentException("version");
}
int i = 5;
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);
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);
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);
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);
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);
}
}
@@ -94,9 +94,15 @@ public class DSSKeyPairX509Codec
* 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>
* <p>
* Note that RFC-3280 (page 79) implies that some certificates MAY have an
* absent, or NULL, parameters field in their AlgorithmIdentifier element,
* implying that those parameters MUST be <i>inherited</i> from another
* certificate. This implementation, encodes a <i>NULL</i> element as the DER
* value of the parameters field when such is the case.
* <p>
* The <i>subjectPublicKey</i> field, which is a BIT STRING, contains the
* DER-encoded form of the DSA public key as an INTEGER.
*
* <pre>
* DSAPublicKey ::= INTEGER -- public key, Y
@@ -118,20 +124,25 @@ public class DSSKeyPairX509Codec
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 derParams;
if (dssKey.hasInheritedParameters())
derParams = new DERValue(DER.NULL, null);
else
{
BigInteger p = dssKey.getParams().getP();
BigInteger q = dssKey.getParams().getQ();
BigInteger g = dssKey.getParams().getG();
DERValue derP = new DERValue(DER.INTEGER, p);
DERValue derQ = new DERValue(DER.INTEGER, q);
DERValue derG = new DERValue(DER.INTEGER, g);
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 params = new ArrayList(3);
params.add(derP);
params.add(derQ);
params.add(derG);
derParams = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE, params);
}
ArrayList algorithmID = new ArrayList(2);
algorithmID.add(derOID);
@@ -139,6 +150,7 @@ public class DSSKeyPairX509Codec
DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
algorithmID);
BigInteger y = dssKey.getY();
DERValue derDSAPublicKey = new DERValue(DER.INTEGER, y);
byte[] yBytes = derDSAPublicKey.getEncoded();
DERValue derSPK = new DERValue(DER.BIT_STRING, new BitString(yBytes));
@@ -157,11 +169,10 @@ public class DSSKeyPairX509Codec
}
catch (IOException x)
{
InvalidParameterException e = new InvalidParameterException();
InvalidParameterException e = new InvalidParameterException(x.getMessage());
e.initCause(x);
throw e;
}
return result;
}
@@ -186,7 +197,10 @@ public class DSSKeyPairX509Codec
if (input == null)
throw new InvalidParameterException("Input bytes MUST NOT be null");
BigInteger p, g, q, y;
BigInteger p = null;
BigInteger g = null;
BigInteger q = null;
BigInteger y;
DERReader der = new DERReader(input);
try
{
@@ -204,20 +218,35 @@ public class DSSKeyPairX509Codec
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();
// RFC-3280, page 79 states: "If the subjectPublicKeyInfo field of the
// certificate contains an algorithm field with null parameters or
// parameters are omitted, compare the certificate subjectPublicKey
// algorithm to the working_public_key_algorithm. If the certificate
// subjectPublicKey algorithm and the working_public_key_algorithm are
// different, set the working_public_key_parameters to null."
// in other words, the parameters field of an AlgorithmIdentifier
// element MAY NOT be present at all, or if present MAY be NULL!
// the Mauve test ValidDSAParameterInheritenceTest5, in
// gnu.testlet.java.security.cert.pkix.pkits, is/was failing because
// of this.
if (val.getTag() == DER.NULL)
val = der.read();
else if (val.isConstructed())
{
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();
}
val = der.read();
if (! (val.getValue() instanceof BitString))
throw new InvalidParameterException("Wrong SubjectPublicKey field");
@@ -230,11 +259,10 @@ public class DSSKeyPairX509Codec
}
catch (IOException x)
{
InvalidParameterException e = new InvalidParameterException();
InvalidParameterException e = new InvalidParameterException(x.getMessage());
e.initCause(x);
throw e;
}
return new DSSPublicKey(Registry.X509_ENCODING_ID, p, q, g, y);
}
@@ -38,38 +38,34 @@ exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.classpath.SystemProperties;
import gnu.java.security.Configuration;
import gnu.java.security.Registry;
import gnu.java.security.action.GetPropertyAction;
import gnu.java.security.key.IKeyPairCodec;
import java.math.BigInteger;
import java.security.AccessController;
import java.security.PrivateKey;
import java.security.interfaces.DSAPrivateKey;
/**
* <p>An object that embodies a DSS (Digital Signature Standard) private key.</p>
*
* An object that embodies a DSS (Digital Signature Standard) private key.
*
* @see #getEncoded
*/
public class DSSPrivateKey extends DSSKey implements PrivateKey, DSAPrivateKey
public class DSSPrivateKey
extends DSSKey
implements PrivateKey, DSAPrivateKey
{
// Constants and variables
// -------------------------------------------------------------------------
private static final boolean DEBUG = false;
/**
* <p>A randomly or pseudorandomly generated integer with <code>0 &lt; x &lt;
* q</code>.</p>
* A randomly or pseudorandomly generated integer with <code>0 &lt; x &lt;
* q</code>.
*/
private final BigInteger x;
/** String representation of this key. Cached for speed. */
private transient String str;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Convenience constructor. Calls the constructor with 5 arguments passing
* {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
@@ -104,13 +100,9 @@ public class DSSPrivateKey extends DSSKey implements PrivateKey, DSAPrivateKey
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
@@ -135,30 +127,22 @@ public class DSSPrivateKey extends DSSKey implements PrivateKey, DSAPrivateKey
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>
*
* 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.
* format.
* @exception IllegalArgumentException if the format is not supported.
* @see DSSKeyPairRawCodec
*/
@@ -181,24 +165,22 @@ public class DSSPrivateKey extends DSSKey implements PrivateKey, DSAPrivateKey
}
/**
* <p>Returns <code>true</code> if the designated object is an instance of
* 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>
*
* parameter values as this one.
*
* @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.
* @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;
}
return false;
if (! (obj instanceof DSAPrivateKey))
return false;
DSAPrivateKey that = (DSAPrivateKey) obj;
return super.equals(that) && x.equals(that.getX());
}
@@ -207,13 +189,15 @@ public class DSSPrivateKey extends DSSKey implements PrivateKey, DSAPrivateKey
{
if (str == null)
{
String ls = SystemProperties.getProperty("line.separator");
String ls = (String) AccessController.doPrivileged
(new GetPropertyAction("line.separator"));
str = new StringBuilder(this.getClass().getName()).append("(")
.append(super.toString()).append(",").append(ls)
.append("x=0x").append(DEBUG ? x.toString(16) : "**...*").append(ls)
.append(")").toString();
.append(super.toString()).append(",").append(ls)
.append("x=0x").append(Configuration.DEBUG ? x.toString(16)
: "**...*").append(ls)
.append(")")
.toString();
}
return str;
}
}
@@ -38,36 +38,33 @@ exception statement from your version. */
package gnu.java.security.key.dss;
import gnu.classpath.SystemProperties;
import gnu.java.security.Registry;
import gnu.java.security.action.GetPropertyAction;
import gnu.java.security.key.IKeyPairCodec;
import java.math.BigInteger;
import java.security.AccessController;
import java.security.PublicKey;
import java.security.interfaces.DSAPublicKey;
/**
* <p>An object that embodies a DSS (Digital Signature Standard) public key.</p>
* An object that embodies a DSS (Digital Signature Standard) public key.
*
* @see #getEncoded
*/
public class DSSPublicKey extends DSSKey implements PublicKey, DSAPublicKey
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.
* <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;
/** String representation of this key. Cached for speed. */
private transient String str;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Conveience constructor. Calls the constructor with 5 arguments passing
* {@link Registry#RAW_ENCODING_ID} as the identifier of the preferred
@@ -85,8 +82,8 @@ public class DSSPublicKey extends DSSKey implements PublicKey, DSAPublicKey
}
/**
* Constructs a new instance of <code>DSSPublicKey</code> given the designated
* arguments.
* 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.
@@ -102,13 +99,9 @@ public class DSSPublicKey extends DSSKey implements PublicKey, DSAPublicKey
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
@@ -133,30 +126,22 @@ public class DSSPublicKey extends DSSKey implements PublicKey, DSAPublicKey
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>
* Returns the encoded form of this public 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.
* format.
* @exception IllegalArgumentException if the format is not supported.
* @see DSSKeyPairRawCodec
*/
@@ -179,24 +164,22 @@ public class DSSPublicKey extends DSSKey implements PublicKey, DSAPublicKey
}
/**
* <p>Returns <code>true</code> if the designated object is an instance of
* 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>
* parameter values as this one.
*
* @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.
* @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;
}
return false;
if (! (obj instanceof DSAPublicKey))
return false;
DSAPublicKey that = (DSAPublicKey) obj;
return super.equals(that) && y.equals(that.getY());
}
@@ -205,13 +188,14 @@ public class DSSPublicKey extends DSSKey implements PublicKey, DSAPublicKey
{
if (str == null)
{
String ls = SystemProperties.getProperty("line.separator");
String ls = (String) AccessController.doPrivileged
(new GetPropertyAction("line.separator"));
str = new StringBuilder(this.getClass().getName()).append("(")
.append(super.toString()).append(",").append(ls)
.append("y=0x").append(y.toString(16)).append(ls)
.append(")").toString();
.append(super.toString()).append(",").append(ls)
.append("y=0x").append(y.toString(16)).append(ls)
.append(")")
.toString();
}
return str;
}
}
@@ -40,26 +40,21 @@ 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>
* An implementation of the DSA parameters generation as described in FIPS-186.
* <p>
* References:
* <p>
* <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.
* Standard (DSS)</a>, Federal Information Processing Standards Publication
* 186. National Institute of Standards and Technology.
*/
public class FIPS186
{
// Constants and variables
// -------------------------------------------------------------------------
public static final int DSA_PARAMS_SEED = 0;
public static final int DSA_PARAMS_COUNTER = 1;
@@ -73,7 +68,7 @@ public class FIPS186
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 = BigInteger.valueOf(2L);
private static final BigInteger TWO_POW_160 = TWO.pow(160);
@@ -89,9 +84,6 @@ public class FIPS186
/** Our default source of randomness. */
private PRNG prng = null;
// Constructor(s)
// -------------------------------------------------------------------------
public FIPS186(int L, SecureRandom rnd)
{
super();
@@ -100,38 +92,31 @@ public class FIPS186
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>
*
* <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> &lt; q &lt; 2<sup>160</sup></code></li>
* <li><code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup></code> for a
* specified <code>L</code>, where <code>L = 512 + 64j</code> for some
* <code>0 &lt;= j &lt;= 8</code></li>
* <li>q divides p - 1.</li>
* <li><code>2<sup>159</sup> &lt; q &lt; 2<sup>160</sup></code></li>
* <li><code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup></code> for a
* specified <code>L</code>, where <code>L = 512 + 64j</code> for some
* <code>0 &lt;= j &lt;= 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> &lt; q
* &lt; 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
* 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> &lt; q &lt; 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> &lt; X &lt; 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
@@ -169,9 +154,8 @@ public class FIPS186
u = sha.digest();
}
for (int i = 0; i < a.length; i++)
{
a[i] ^= u[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
@@ -183,12 +167,9 @@ public class FIPS186
// 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;
}
if (q.isProbablePrime(80))
break step1;
} // step1
// 6. Let counter = 0 and offset = 2.
counter = 0;
offset = 2;
@@ -201,9 +182,9 @@ public class FIPS186
{
for (int k = 0; k <= n; k++)
{
a = SEED_PLUS_OFFSET.add(
BigInteger.valueOf(k & 0xFFFFFFFFL)).mod(
TWO_POW_160).toByteArray();
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());
}
@@ -214,9 +195,8 @@ public class FIPS186
// 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[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).
@@ -228,22 +208,17 @@ public class FIPS186
{
// 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;
}
if (p.isProbablePrime(80))
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;
}
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
@@ -258,28 +233,21 @@ public class FIPS186
// 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;
}
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);
}
rnd.nextBytes(buffer);
else
getDefaultPRNG().nextBytes(buffer);
}
@@ -38,23 +38,21 @@ exception statement from your version. */
package gnu.java.security.key.rsa;
import gnu.classpath.SystemProperties;
import gnu.java.security.Registry;
import gnu.java.security.action.GetPropertyAction;
import gnu.java.security.util.FormatUtil;
import java.math.BigInteger;
import java.security.AccessController;
import java.security.Key;
import java.security.interfaces.RSAKey;
/**
* <p>A base asbtract class for both public and private RSA keys.</p>
* A base asbtract class for both public and private RSA keys.
*/
public abstract class GnuRSAKey implements Key, RSAKey
public abstract class GnuRSAKey
implements Key, RSAKey
{
// Constants and variables
// -------------------------------------------------------------------------
/** The public modulus of an RSA key pair. */
private final BigInteger n;
@@ -62,17 +60,14 @@ public abstract class GnuRSAKey implements Key, RSAKey
private final BigInteger e;
/**
* Identifier of the default encoding format to use when externalizing the
* key material.
* Identifier of the default encoding format to use when externalizing the key
* material.
*/
protected final int defaultFormat;
/** String representation of this key. Cached for speed. */
private transient String str;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Trivial protected constructor.
*
@@ -91,21 +86,11 @@ public abstract class GnuRSAKey implements Key, RSAKey
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;
@@ -122,11 +107,9 @@ public abstract class GnuRSAKey implements Key, RSAKey
return FormatUtil.getEncodingShortName(defaultFormat);
}
// Other instance methods --------------------------------------------------
/**
* <p>Returns the modulus <code>n</code>.</p>
*
* Returns the modulus <code>n</code>.
*
* @return the modulus <code>n</code>.
*/
public BigInteger getN()
@@ -135,8 +118,8 @@ public abstract class GnuRSAKey implements Key, RSAKey
}
/**
* <p>Returns the public exponent <code>e</code>.</p>
*
* Returns the public exponent <code>e</code>.
*
* @return the public exponent <code>e</code>.
*/
public BigInteger getPublicExponent()
@@ -145,8 +128,8 @@ public abstract class GnuRSAKey implements Key, RSAKey
}
/**
* <p>Same as {@link #getPublicExponent()}.</p>
*
* Same as {@link #getPublicExponent()}.
*
* @return the public exponent <code>e</code>.
*/
public BigInteger getE()
@@ -155,23 +138,21 @@ public abstract class GnuRSAKey implements Key, RSAKey
}
/**
* <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>
*
* Returns <code>true</code> if the designated object is an instance of
* {@link RSAKey} and has the same RSA parameter values as this one.
*
* @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.
* @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;
}
return false;
if (! (obj instanceof RSAKey))
return false;
final RSAKey that = (RSAKey) obj;
return n.equals(that.getModulus());
}
@@ -180,8 +161,9 @@ public abstract class GnuRSAKey implements Key, RSAKey
{
if (str == null)
{
String ls = SystemProperties.getProperty("line.separator");
str = new StringBuilder().append(ls)
String ls = (String) AccessController.doPrivileged
(new GetPropertyAction("line.separator"));
str = new StringBuilder(ls)
.append("defaultFormat=").append(defaultFormat).append(",").append(ls)
.append("n=0x").append(n.toString(16)).append(",").append(ls)
.append("e=0x").append(e.toString(16))
@@ -190,7 +172,5 @@ public abstract class GnuRSAKey implements Key, RSAKey
return str;
}
// abstract methods to be implemented by subclasses ------------------------
public abstract byte[] getEncoded(int format);
}
@@ -38,42 +38,39 @@ exception statement from your version. */
package gnu.java.security.key.rsa;
import gnu.classpath.SystemProperties;
import gnu.java.security.Configuration;
import gnu.java.security.action.GetPropertyAction;
import gnu.java.security.Registry;
import gnu.java.security.key.IKeyPairCodec;
import java.math.BigInteger;
import java.security.AccessController;
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>
* An object that embodies an RSA private key.
* <p>
* References:
* <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.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>
*/
public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
RSAPrivateCrtKey
public class GnuRSAPrivateKey
extends GnuRSAKey
implements PrivateKey, RSAPrivateCrtKey
{
// Constants and variables
// -------------------------------------------------------------------------
private static final boolean DEBUG = false;
/** 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;
@@ -89,21 +86,17 @@ public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
/** String representation of this key. Cached for speed. */
private transient String str;
// 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)
public GnuRSAPrivateKey(BigInteger p, BigInteger q, BigInteger e, BigInteger d)
{
this(Registry.RAW_ENCODING_ID, p, q, e, d);
}
@@ -122,7 +115,9 @@ public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
public GnuRSAPrivateKey(int preferredFormat, BigInteger p, BigInteger q,
BigInteger e, BigInteger d)
{
this(preferredFormat, p.multiply(q), e, d, p, q,
this(preferredFormat,
p.multiply(q),
e, d, p, q,
e.modInverse(p.subtract(BigInteger.ONE)),
e.modInverse(q.subtract(BigInteger.ONE)),
q.modInverse(p));
@@ -135,19 +130,20 @@ public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
* @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>.
* 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>.
* <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>.
* <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>.
* 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,
@@ -156,24 +152,20 @@ public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
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),
// 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).
// 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
@@ -198,14 +190,10 @@ public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
catch (IllegalArgumentException ignored)
{
}
// try PKCS#8 codec
return (GnuRSAPrivateKey) new RSAKeyPairPKCS8Codec().decodePrivateKey(k);
}
// Instance methods
// -------------------------------------------------------------------------
public BigInteger getPrimeP()
{
return p;
@@ -231,22 +219,18 @@ public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
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.
*
* 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.
* format.
* @throws IllegalArgumentException if the format is not supported.
* @see RSAKeyPairRawCodec
* @see RSAKeyPairPKCS8Codec
@@ -270,19 +254,18 @@ public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
}
/**
* <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>
*
* Returns <code>true</code> if the designated object is an instance of this
* class and has the same RSA parameter values as this one.
*
* @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.
* and value as this one.
*/
public boolean equals(final Object obj)
{
if (obj == null)
{
return false;
}
return false;
if (obj instanceof RSAPrivateKey)
{
final RSAPrivateKey that = (RSAPrivateKey) obj;
@@ -304,16 +287,24 @@ public class GnuRSAPrivateKey extends GnuRSAKey implements PrivateKey,
{
if (str == null)
{
String ls = SystemProperties.getProperty("line.separator");
String ls = (String) AccessController.doPrivileged
(new GetPropertyAction("line.separator"));
str = new StringBuilder(this.getClass().getName()).append("(")
.append(super.toString()).append(",").append(ls)
.append("d=0x").append(DEBUG ? d.toString(16) : "**...*").append(ls)
.append("p=0x").append(DEBUG ? p.toString(16) : "**...*").append(ls)
.append("q=0x").append(DEBUG ? q.toString(16) : "**...*").append(ls)
.append("dP=0x").append(DEBUG ? dP.toString(16) : "**...*").append(ls)
.append("dQ=0x").append(DEBUG ? dQ.toString(16) : "**...*").append(ls)
.append("qInv=0x").append(DEBUG ? qInv.toString(16) : "**...*").append(ls)
.append(")").toString();
.append("d=0x").append(Configuration.DEBUG ? d.toString(16)
: "**...*").append(ls)
.append("p=0x").append(Configuration.DEBUG ? p.toString(16)
: "**...*").append(ls)
.append("q=0x").append(Configuration.DEBUG ? q.toString(16)
: "**...*").append(ls)
.append("dP=0x").append(Configuration.DEBUG ? dP.toString(16)
: "**...*").append(ls)
.append("dQ=0x").append(Configuration.DEBUG ? dQ.toString(16)
: "**...*").append(ls)
.append("qInv=0x").append(Configuration.DEBUG ? qInv.toString(16)
: "**...*").append(ls)
.append(")")
.toString();
}
return str;
}
@@ -38,42 +38,39 @@ exception statement from your version. */
package gnu.java.security.key.rsa;
import gnu.classpath.SystemProperties;
import gnu.java.security.Registry;
import gnu.java.security.action.GetPropertyAction;
import gnu.java.security.key.IKeyPairCodec;
import java.math.BigInteger;
import java.security.AccessController;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
/**
* <p>An object that encapsulates an RSA public key.</p>
*
* <p>References:</p>
* An object that encapsulates an RSA public key.
* <p>
* References:
* <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.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>
*/
public class GnuRSAPublicKey extends GnuRSAKey implements PublicKey,
RSAPublicKey
public class GnuRSAPublicKey
extends GnuRSAKey
implements PublicKey, RSAPublicKey
{
// Constants and variables
// -------------------------------------------------------------------------
/** String representation of this key. Cached for speed. */
private transient String str;
// 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.
*/
@@ -98,9 +95,6 @@ public class GnuRSAPublicKey extends GnuRSAKey implements PublicKey,
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
@@ -125,21 +119,17 @@ public class GnuRSAPublicKey extends GnuRSAKey implements PublicKey,
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>
*
* Returns the encoded form of this public 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.
* format.
* @throws IllegalArgumentException if the format is not supported.
* @see RSAKeyPairRawCodec
*/
@@ -162,23 +152,21 @@ public class GnuRSAPublicKey extends GnuRSAKey implements PublicKey,
}
/**
* <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>
*
* Returns <code>true</code> if the designated object is an instance of this
* class and has the same RSA parameter values as this one.
*
* @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.
* @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;
}
return false;
if (! (obj instanceof RSAPublicKey))
return false;
final RSAPublicKey that = (RSAPublicKey) obj;
return super.equals(that)
&& getPublicExponent().equals(that.getPublicExponent());
@@ -188,10 +176,12 @@ public class GnuRSAPublicKey extends GnuRSAKey implements PublicKey,
{
if (str == null)
{
String ls = SystemProperties.getProperty("line.separator");
String ls = (String) AccessController.doPrivileged
(new GetPropertyAction("line.separator"));
str = new StringBuilder(this.getClass().getName()).append("(")
.append(super.toString()).append(",").append(ls)
.append(")").toString();
.append(")")
.toString();
}
return str;
}
@@ -38,10 +38,10 @@ exception statement from your version. */
package gnu.java.security.key.rsa;
import gnu.java.security.Configuration;
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;
@@ -53,25 +53,23 @@ import java.util.Map;
import java.util.logging.Logger;
/**
* <p>A key-pair generator for asymetric keys to use in conjunction with the RSA
* scheme.</p>
*
* <p>Reference:</p>
* A key-pair generator for asymetric keys to use in conjunction with the RSA
* scheme.
* <p>
* Reference:
* <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>
* <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
public class RSAKeyPairGenerator
implements IKeyPairGenerator
{
// Constants and variables
// -------------------------------------------------------------------------
private static final Logger log = Logger.getLogger(RSAKeyPairGenerator.class.getName());
/** The BigInteger constant 1. */
@@ -90,8 +88,8 @@ public class RSAKeyPairGenerator implements IKeyPairGenerator
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
* 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).
*/
@@ -128,38 +126,28 @@ public class RSAKeyPairGenerator implements IKeyPairGenerator
/** 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>
*
* Configures this instance.
*
* @param attributes the map of name/value pairs to use.
* @exception IllegalArgumentException if the designated MODULUS_LENGTH
* value is less than 1024.
* @exception IllegalArgumentException if the designated MODULUS_LENGTH value
* is less than 1024.
*/
public void setup(Map attributes)
{
log.entering(this.getClass().getName(), "setup", attributes);
if (Configuration.DEBUG)
log.entering(this.getClass().getName(), "setup", 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)
{
@@ -171,32 +159,30 @@ public class RSAKeyPairGenerator implements IKeyPairGenerator
Integer l = (Integer) attributes.get(MODULUS_LENGTH);
L = (l == null ? DEFAULT_MODULUS_LENGTH : l.intValue());
}
if (L < 1024)
{
throw new IllegalArgumentException(MODULUS_LENGTH);
}
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();
log.exiting(this.getClass().getName(), "setup");
if (Configuration.DEBUG)
log.exiting(this.getClass().getName(), "setup");
}
/**
* <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>
*
* <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()
{
log.entering(this.getClass().getName(), "generate");
if (Configuration.DEBUG)
log.entering(this.getClass().getName(), "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;
@@ -208,12 +194,9 @@ public class RSAKeyPairGenerator implements IKeyPairGenerator
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;
}
&& p.isProbablePrime(80) && 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)
@@ -221,45 +204,34 @@ public class RSAKeyPairGenerator implements IKeyPairGenerator
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;
}
if (n.bitLength() == L && q.isProbablePrime(80) && 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);
KeyPair result = new KeyPair(pubK, secK);
log.exiting(this.getClass().getName(), "generate", result);
if (Configuration.DEBUG)
log.exiting(this.getClass().getName(), "generate", result);
return result;
}
// helper methods ----------------------------------------------------------
/**
* <p>Fills the designated byte array with random data.</p>
*
* 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);
}
rnd.nextBytes(buffer);
else
getDefaultPRNG().nextBytes(buffer);
}
@@ -38,15 +38,7 @@ 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 java.util.logging.Logger;
import gnu.java.security.Configuration;
import gnu.java.security.OID;
import gnu.java.security.Registry;
import gnu.java.security.der.DER;
@@ -56,6 +48,15 @@ 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 PKCS#8 ASN.1 external representation of RSA private keys.
@@ -84,7 +85,6 @@ public class RSAKeyPairPKCS8Codec
/**
* 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
@@ -97,10 +97,12 @@ public class RSAKeyPairPKCS8Codec
* 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>
*
* <p>
* As indicated in RFC-2459: "The parameters field shall have ASN.1 type NULL
* for this algorithm identifier.".
* <p>
* The <i>privateKey</i> field, which is an OCTET STRING, contains the
* DER-encoded form of the RSA private key defined as:
* <pre>
* RSAPrivateKey ::= SEQUENCE {
* version INTEGER, -- MUST be 0
@@ -122,8 +124,8 @@ public class RSAKeyPairPKCS8Codec
*/
public byte[] encodePrivateKey(PrivateKey key)
{
log.entering(this.getClass().getName(), "encodePrivateKey()", key);
if (Configuration.DEBUG)
log.entering(this.getClass().getName(), "encodePrivateKey()", key);
if (! (key instanceof GnuRSAPrivateKey))
throw new InvalidParameterException("Wrong key type");
@@ -141,8 +143,9 @@ public class RSAKeyPairPKCS8Codec
DERValue derOID = new DERValue(DER.OBJECT_IDENTIFIER, RSA_ALG_OID);
ArrayList algorithmID = new ArrayList(1);
ArrayList algorithmID = new ArrayList(2);
algorithmID.add(derOID);
algorithmID.add(new DERValue(DER.NULL, null));
DERValue derAlgorithmID = new DERValue(DER.CONSTRUCTED | DER.SEQUENCE,
algorithmID);
@@ -190,8 +193,8 @@ public class RSAKeyPairPKCS8Codec
y.initCause(x);
throw y;
}
log.exiting(this.getClass().getName(), "encodePrivateKey()", result);
if (Configuration.DEBUG)
log.exiting(this.getClass().getName(), "encodePrivateKey()", result);
return result;
}
@@ -213,8 +216,8 @@ public class RSAKeyPairPKCS8Codec
*/
public PrivateKey decodePrivateKey(byte[] input)
{
log.entering(this.getClass().getName(), "decodePrivateKey()", input);
if (Configuration.DEBUG)
log.entering(this.getClass().getName(), "decodePrivateKey()", input);
if (input == null)
throw new InvalidParameterException("Input bytes MUST NOT be null");
@@ -239,9 +242,12 @@ public class RSAKeyPairPKCS8Codec
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();
byte[] pkBytes = (byte[]) val.getValue();
if (val.getTag() == DER.NULL)
val = der.read();
byte[] pkBytes = (byte[]) val.getValue();
der = new DERReader(pkBytes);
DERValue derRSAPrivateKey = der.read();
DerUtil.checkIsConstructed(derRSAPrivateKey, "Wrong RSAPrivateKey field");
@@ -284,10 +290,10 @@ public class RSAKeyPairPKCS8Codec
y.initCause(x);
throw y;
}
PrivateKey result = new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID, n, e,
d, p, q, dP, dQ, qInv);
log.exiting(this.getClass().getName(), "decodePrivateKey()", result);
PrivateKey result = new GnuRSAPrivateKey(Registry.PKCS8_ENCODING_ID,
n, e, d, p, q, dP, dQ, qInv);
if (Configuration.DEBUG)
log.exiting(this.getClass().getName(), "decodePrivateKey()", result);
return result;
}
}
@@ -47,80 +47,60 @@ 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 $
* An object that implements the {@link IKeyPairCodec} interface for the <i>Raw</i>
* format to use with RSA keypairs.
*/
public class RSAKeyPairRawCodec implements IKeyPairCodec
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>
*
* Returns the encoded form of the designated RSA public key according to the
* <i>Raw</i> format supported by this library.
* <p>
* The <i>Raw</i> format for an RSA public key, in this implementation, is a
* byte sequence consisting of the following:
* <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>
* <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.
* one.
*/
public byte[] encodePublicKey(PublicKey key)
{
if (!(key instanceof GnuRSAPublicKey))
{
throw new IllegalArgumentException("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;
@@ -129,7 +109,6 @@ public class RSAKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// e
buffer = rsaKey.getPublicExponent().toByteArray();
length = buffer.length;
@@ -138,7 +117,6 @@ public class RSAKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
return baos.toByteArray();
}
@@ -149,92 +127,87 @@ public class RSAKeyPairRawCodec implements IKeyPairCodec
|| 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");
}
throw new IllegalArgumentException("magic");
// version
if (k[4] != 0x01)
{
throw new IllegalArgumentException("version");
}
int i = 5;
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);
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);
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>
*
* Returns the encoded form of the designated RSA private key according to the
* <i>Raw</i> format supported by this library.
* <p>
* The <i>Raw</i> format for an RSA private key, in this implementation, is a
* byte sequence consisting of the following:
* <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>
* <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");
}
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;
@@ -243,7 +216,6 @@ public class RSAKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// q
buffer = rsaKey.getPrimeQ().toByteArray();
length = buffer.length;
@@ -252,7 +224,6 @@ public class RSAKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// e
buffer = rsaKey.getPublicExponent().toByteArray();
length = buffer.length;
@@ -261,7 +232,6 @@ public class RSAKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
// d
buffer = rsaKey.getPrivateExponent().toByteArray();
length = buffer.length;
@@ -270,7 +240,6 @@ public class RSAKeyPairRawCodec implements IKeyPairCodec
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
return baos.toByteArray();
}
@@ -281,52 +250,51 @@ public class RSAKeyPairRawCodec implements IKeyPairCodec
|| 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");
}
throw new IllegalArgumentException("magic");
// version
if (k[4] != 0x01)
{
throw new IllegalArgumentException("version");
}
int i = 5;
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);
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);
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);
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);
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);
}
}
@@ -38,6 +38,7 @@ exception statement from your version. */
package gnu.java.security.key.rsa;
import gnu.java.security.Configuration;
import gnu.java.security.OID;
import gnu.java.security.Registry;
import gnu.java.security.der.BitString;
@@ -114,8 +115,8 @@ public class RSAKeyPairX509Codec
*/
public byte[] encodePublicKey(PublicKey key)
{
log.entering(this.getClass().getName(), "encodePublicKey()", key);
if (Configuration.DEBUG)
log.entering(this.getClass().getName(), "encodePublicKey()", key);
if (! (key instanceof GnuRSAPublicKey))
throw new InvalidParameterException("key");
@@ -156,12 +157,12 @@ public class RSAKeyPairX509Codec
}
catch (IOException x)
{
InvalidParameterException y = new InvalidParameterException();
InvalidParameterException y = new InvalidParameterException(x.getMessage());
y.initCause(x);
throw y;
}
log.exiting(this.getClass().getName(), "encodePublicKey()", result);
if (Configuration.DEBUG)
log.exiting(this.getClass().getName(), "encodePublicKey()", result);
return result;
}
@@ -183,8 +184,8 @@ public class RSAKeyPairX509Codec
*/
public PublicKey decodePublicKey(byte[] input)
{
log.entering(this.getClass().getName(), "decodePublicKey()", input);
if (Configuration.DEBUG)
log.entering(this.getClass().getName(), "decodePublicKey()", input);
if (input == null)
throw new InvalidParameterException("Input bytes MUST NOT be null");
@@ -229,13 +230,13 @@ public class RSAKeyPairX509Codec
}
catch (IOException x)
{
InvalidParameterException y = new InvalidParameterException();
InvalidParameterException y = new InvalidParameterException(x.getMessage());
y.initCause(x);
throw y;
}
PublicKey result = new GnuRSAPublicKey(Registry.X509_ENCODING_ID, n, e);
log.exiting(this.getClass().getName(), "decodePublicKey()", result);
if (Configuration.DEBUG)
log.exiting(this.getClass().getName(), "decodePublicKey()", result);
return result;
}
@@ -37,6 +37,7 @@ exception statement from your version. */
package gnu.java.security.pkcs;
import gnu.java.security.Configuration;
import gnu.java.security.OID;
import gnu.java.security.ber.BER;
import gnu.java.security.ber.BEREncodingException;
@@ -52,9 +53,7 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.security.cert.CRL;
import java.security.cert.CRLException;
import java.security.cert.Certificate;
@@ -62,7 +61,6 @@ import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -174,21 +172,22 @@ public class PKCS7SignedData
if (!val.isConstructed())
throw new BEREncodingException("malformed SignedData");
log.finest("SignedData: " + val);
if (Configuration.DEBUG)
log.fine("SignedData: " + val);
val = ber.read();
if (val.getTag() != BER.INTEGER)
throw new BEREncodingException("expecting Version");
version = (BigInteger) val.getValue();
log.finest(" Version: " + version);
if (Configuration.DEBUG)
log.fine(" Version: " + version);
digestAlgorithms = new HashSet();
val = ber.read();
if (!val.isConstructed())
throw new BEREncodingException("malformed DigestAlgorithmIdentifiers");
log.finest(" DigestAlgorithmIdentifiers: " + val);
if (Configuration.DEBUG)
log.fine(" DigestAlgorithmIdentifiers: " + val);
int count = 0;
DERValue val2 = ber.read();
while (val2 != BER.END_OF_SEQUENCE &&
@@ -196,14 +195,14 @@ public class PKCS7SignedData
{
if (!val2.isConstructed())
throw new BEREncodingException("malformed AlgorithmIdentifier");
log.finest(" AlgorithmIdentifier: " + val2);
if (Configuration.DEBUG)
log.fine(" AlgorithmIdentifier: " + val2);
count += val2.getEncodedLength();
val2 = ber.read();
if (val2.getTag() != BER.OBJECT_IDENTIFIER)
throw new BEREncodingException("malformed AlgorithmIdentifier");
log.finest(" digestAlgorithmIdentifiers OID: " + val2.getValue());
if (Configuration.DEBUG)
log.fine(" digestAlgorithmIdentifiers OID: " + val2.getValue());
List algId = new ArrayList(2);
algId.add(val2.getValue());
val2 = ber.read();
@@ -224,23 +223,27 @@ public class PKCS7SignedData
else
algId.add(null);
log.finest(" digestAlgorithmIdentifiers params: ");
log.finest(Util.dumpString((byte[]) algId.get(1),
" digestAlgorithmIdentifiers params: "));
if (Configuration.DEBUG)
{
log.fine(" digestAlgorithmIdentifiers params: ");
log.fine(Util.dumpString((byte[]) algId.get(1),
" digestAlgorithmIdentifiers params: "));
}
digestAlgorithms.add(algId);
}
val = ber.read();
if (!val.isConstructed())
throw new BEREncodingException("malformed ContentInfo");
log.finest(" ContentInfo: " + val);
if (Configuration.DEBUG)
log.fine(" ContentInfo: " + val);
val2 = ber.read();
if (val2.getTag() != BER.OBJECT_IDENTIFIER)
throw new BEREncodingException("malformed ContentType");
contentType = (OID) val2.getValue();
log.finest(" ContentType OID: " + contentType);
if (Configuration.DEBUG)
log.fine(" ContentType OID: " + contentType);
if (BERValue.isIndefinite(val)
|| (val.getLength() > 0 && val.getLength() > val2.getEncodedLength()))
{
@@ -252,17 +255,18 @@ public class PKCS7SignedData
val2 = ber.read();
}
}
log.finest(" Content: ");
log.finest(Util.dumpString(content, " Content: "));
if (Configuration.DEBUG)
{
log.fine(" Content: ");
log.fine(Util.dumpString(content, " Content: "));
}
val = ber.read();
if (val.getTag() == 0)
{
if (!val.isConstructed())
throw new BEREncodingException("malformed ExtendedCertificatesAndCertificates");
log.finest(" ExtendedCertificatesAndCertificates: " + val);
if (Configuration.DEBUG)
log.fine(" ExtendedCertificatesAndCertificates: " + val);
count = 0;
val2 = ber.read();
List certs = new LinkedList();
@@ -271,7 +275,8 @@ public class PKCS7SignedData
{
Certificate cert =
x509.generateCertificate(new ByteArrayInputStream(val2.getEncoded()));
log.finest(" Certificate: " + cert);
if (Configuration.DEBUG)
log.fine(" Certificate: " + cert);
certs.add(cert);
count += val2.getEncodedLength();
ber.skip(val2.getLength());
@@ -286,8 +291,8 @@ public class PKCS7SignedData
{
if (!val.isConstructed())
throw new BEREncodingException("malformed CertificateRevocationLists");
log.finest(" CertificateRevocationLists: " + val);
if (Configuration.DEBUG)
log.fine(" CertificateRevocationLists: " + val);
count = 0;
val2 = ber.read();
List crls = new LinkedList();
@@ -295,7 +300,8 @@ public class PKCS7SignedData
(val.getLength() > 0 && val.getLength() > count))
{
CRL crl = x509.generateCRL(new ByteArrayInputStream(val2.getEncoded()));
log.finest(" CRL: " + crl);
if (Configuration.DEBUG)
log.fine(" CRL: " + crl);
crls.add(crl);
count += val2.getEncodedLength();
ber.skip(val2.getLength());
@@ -309,8 +315,8 @@ public class PKCS7SignedData
signerInfos = new HashSet();
if (!val.isConstructed())
throw new BEREncodingException("malformed SignerInfos");
log.finest(" SignerInfos: " + val);
if (Configuration.DEBUG)
log.fine(" SignerInfos: " + val);
// FIXME read this more carefully.
// Since we are just reading a file (probably) we just read until we
@@ -37,6 +37,7 @@ exception statement from your version. */
package gnu.java.security.pkcs;
import gnu.java.security.Configuration;
import gnu.java.security.OID;
import gnu.java.security.ber.BER;
import gnu.java.security.ber.BEREncodingException;
@@ -50,7 +51,6 @@ import gnu.java.security.util.Util;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.logging.Logger;
@@ -101,7 +101,8 @@ public class SignerInfo
public SignerInfo(BERReader ber) throws IOException
{
DERValue val = ber.read();
log.finest("SignerInfo: " + val);
if (Configuration.DEBUG)
log.fine("SignerInfo: " + val);
if (!val.isConstructed())
throw new BEREncodingException("malformed SignerInfo");
@@ -110,13 +111,13 @@ public class SignerInfo
throw new BEREncodingException("malformed Version");
version = (BigInteger) val.getValue();
log.finest(" Version: " + version);
log.fine(" Version: " + version);
val = ber.read();
if (!val.isConstructed())
throw new BEREncodingException("malformed IssuerAndSerialNumber");
log.finest(" IssuerAndSerialNumber: " + val);
if (Configuration.DEBUG)
log.fine(" IssuerAndSerialNumber: " + val);
val = ber.read();
if (!val.isConstructed())
@@ -124,20 +125,22 @@ public class SignerInfo
issuer = new X500Principal(val.getEncoded());
ber.skip(val.getLength());
log.finest(" Issuer: " + issuer);
if (Configuration.DEBUG)
log.fine(" Issuer: " + issuer);
val = ber.read();
if (val.getTag() != BER.INTEGER)
throw new BEREncodingException("malformed SerialNumber");
serialNumber = (BigInteger) val.getValue();
log.finest(" SerialNumber: " + serialNumber);
if (Configuration.DEBUG)
log.fine(" SerialNumber: " + serialNumber);
val = ber.read();
if (!val.isConstructed())
throw new BEREncodingException("malformed DigestAlgorithmIdentifier");
log.finest(" DigestAlgorithmIdentifier: " + val);
if (Configuration.DEBUG)
log.fine(" DigestAlgorithmIdentifier: " + val);
int count = 0;
DERValue val2 = ber.read();
@@ -145,7 +148,8 @@ public class SignerInfo
throw new BEREncodingException("malformed AlgorithmIdentifier");
digestAlgorithmId = (OID) val2.getValue();
log.finest(" digestAlgorithm OID: " + digestAlgorithmId);
if (Configuration.DEBUG)
log.fine(" digestAlgorithm OID: " + digestAlgorithmId);
if (BERValue.isIndefinite(val))
{
@@ -170,10 +174,12 @@ public class SignerInfo
else
digestAlgorithmParams = null;
log.finest(" digestAlgorithm params: ");
log.finest(Util.dumpString(digestAlgorithmParams,
" digestAlgorithm params: "));
if (Configuration.DEBUG)
{
log.fine(" digestAlgorithm params: ");
log.fine(Util.dumpString(digestAlgorithmParams,
" digestAlgorithm params: "));
}
val = ber.read();
if (val.getTag() == 0)
{
@@ -187,21 +193,24 @@ public class SignerInfo
else
authenticatedAttributes = null;
log.finest(" AuthenticatedAttributes: ");
log.finest(Util.dumpString(authenticatedAttributes,
" AuthenticatedAttributes: "));
if (Configuration.DEBUG)
{
log.fine(" AuthenticatedAttributes: ");
log.fine(Util.dumpString(authenticatedAttributes,
" AuthenticatedAttributes: "));
}
if (!val.isConstructed())
throw new BEREncodingException("malformed DigestEncryptionAlgorithmIdentifier");
log.finest(" DigestEncryptionAlgorithmIdentifier: " + val);
if (Configuration.DEBUG)
log.fine(" DigestEncryptionAlgorithmIdentifier: " + val);
count = 0;
val2 = ber.read();
if (val2.getTag() != BER.OBJECT_IDENTIFIER)
throw new BEREncodingException("malformed AlgorithmIdentifier");
digestEncryptionAlgorithmId = (OID) val2.getValue();
log.finest(" digestEncryptionAlgorithm OID: " + digestEncryptionAlgorithmId);
if (Configuration.DEBUG)
log.fine(" digestEncryptionAlgorithm OID: " + digestEncryptionAlgorithmId);
if (BERValue.isIndefinite(val))
{
@@ -226,27 +235,33 @@ public class SignerInfo
else
digestEncryptionAlgorithmParams = null;
log.finest(" digestEncryptionAlgorithm params: ");
log.finest(Util.dumpString(digestEncryptionAlgorithmParams,
" digestEncryptionAlgorithm params: "));
if (Configuration.DEBUG)
{
log.fine(" digestEncryptionAlgorithm params: ");
log.fine(Util.dumpString(digestEncryptionAlgorithmParams,
" digestEncryptionAlgorithm params: "));
}
val = ber.read();
if (val.getTag() != BER.OCTET_STRING)
throw new BEREncodingException("malformed EncryptedDigest");
encryptedDigest = (byte[]) val.getValue();
log.finest(" EncryptedDigest: ");
log.finest(Util.dumpString(encryptedDigest, " EncryptedDigest: "));
if (Configuration.DEBUG)
{
log.fine(" EncryptedDigest: ");
log.fine(Util.dumpString(encryptedDigest, " EncryptedDigest: "));
}
if (ber.peek() == 1)
unauthenticatedAttributes = ber.read().getEncoded();
else
unauthenticatedAttributes = null;
log.finest(" UnauthenticatedAttributes: ");
log.finest(Util.dumpString(unauthenticatedAttributes,
" UnauthenticatedAttributes: "));
if (Configuration.DEBUG)
{
log.fine(" UnauthenticatedAttributes: ");
log.fine(Util.dumpString(unauthenticatedAttributes,
" UnauthenticatedAttributes: "));
}
if (ber.peek() == 0)
ber.read();
}
@@ -41,14 +41,11 @@ package gnu.java.security.prng;
import java.util.Map;
/**
* <p>An abstract class to facilitate implementing PRNG algorithms.</p>
* An abstract class to facilitate implementing PRNG algorithms.
*/
public abstract class BasePRNG implements IRandom
public abstract class BasePRNG
implements IRandom
{
// Constants and variables
// -------------------------------------------------------------------------
/** The canonical name prefix of the PRNG algorithm. */
protected String name;
@@ -61,12 +58,9 @@ public abstract class BasePRNG implements IRandom
/** 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>
*
* Trivial constructor for use by concrete subclasses.
*
* @param name the canonical name of this instance.
*/
protected BasePRNG(String name)
@@ -78,14 +72,6 @@ public abstract class BasePRNG implements IRandom
buffer = new byte[0];
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// IRandom interface implementation ----------------------------------------
public String name()
{
return name;
@@ -101,10 +87,9 @@ public abstract class BasePRNG implements IRandom
public byte nextByte() throws IllegalStateException, LimitReachedException
{
if (!initialised)
{
throw new IllegalStateException();
}
if (! initialised)
throw new IllegalStateException();
return nextByteInternal();
}
@@ -117,7 +102,7 @@ public abstract class BasePRNG implements IRandom
public void nextBytes(byte[] out, int offset, int length)
throws IllegalStateException, LimitReachedException
{
if (!initialised)
if (! initialised)
throw new IllegalStateException("not initialized");
if (length == 0)
@@ -127,7 +112,6 @@ public abstract class BasePRNG implements IRandom
throw new ArrayIndexOutOfBoundsException("offset=" + offset + " length="
+ length + " limit="
+ out.length);
if (ndx >= buffer.length)
{
fillBlock();
@@ -163,9 +147,6 @@ public abstract class BasePRNG implements IRandom
throw new UnsupportedOperationException("random state is non-modifiable");
}
// Instance methods
// -------------------------------------------------------------------------
public boolean isInitialised()
{
return initialised;
@@ -182,8 +163,6 @@ public abstract class BasePRNG implements IRandom
return buffer[ndx++];
}
// abstract methods to implement by subclasses -----------------------------
public Object clone() throws CloneNotSupportedException
{
BasePRNG result = (BasePRNG) super.clone();
@@ -43,7 +43,6 @@ package gnu.java.security.prng;
*/
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,
@@ -41,140 +41,134 @@ 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>
*
* The basic visible methods of any pseudo-random number generator.
* <p>
* The [HAC] defines a PRNG (as implemented in this library) as follows:
* <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>
* <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><sup>st</sup> bit of <code>S</code> with a
* probability significantly greater 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
* <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
* here that such an operation, for those algorithms that use an underlying
* 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
* cloned). Instead a clone of an already initialised PRNG, that uses an
* 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>
*
* the same cipher that operates with the <b>same block size</b> but without
* any knowledge of neither key material nor key size.
* <p>
* References:
* <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>
* <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
public interface IRandom
extends Cloneable
{
// Constants
// -------------------------------------------------------------------------
// Methods
// -------------------------------------------------------------------------
/**
* <p>Returns the canonical name of this instance.</p>
*
* @return the canonical name of this instance. */
* Returns the canonical name of this instance.
*
* @return the canonical name of this instance.
*/
String name();
/**
* <p>Initialises the pseudo-random number generator scheme with the
* appropriate attributes.</p>
*
* Initialises the pseudo-random number generator scheme with the appropriate
* attributes.
*
* @param attributes a set of name-value pairs that describe the desired
* future instance behaviour.
* future instance behaviour.
* @exception IllegalArgumentException if at least one of the defined name/
* value pairs contains invalid data.
* value pairs contains invalid data.
*/
void init(Map attributes);
/**
* <p>Returns the next 8 bits of random data generated from this instance.</p>
*
* Returns the next 8 bits of random data generated from this instance.
*
* @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.
* 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.
*
* 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>.
* 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.
* 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>
*
* Supplement, or possibly replace, the random state of this PRNG with a
* random byte.
* <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}.
*
* @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>
*
* Supplement, or possibly replace, the random state of this PRNG with a
* sequence of new random bytes.
* <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}.
*
* @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>
*
* Supplement, or possibly replace, the random state of this PRNG with a
* sequence of new random bytes.
* <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}.
*
* @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.
* @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>
*
* Returns a clone copy of this instance.
*
* @return a clone copy of this instance.
*/
Object clone() throws CloneNotSupportedException;
}
}
@@ -42,15 +42,9 @@ 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
public class LimitReachedException
extends Exception
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
public LimitReachedException()
{
super();
@@ -60,10 +54,4 @@ public class LimitReachedException extends Exception
{
super(msg);
}
// Class methods
// -------------------------------------------------------------------------
// Instant methods
// -------------------------------------------------------------------------
}
}
@@ -45,19 +45,17 @@ 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
* 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>
* <code>seed</code> is given, an empty octet sequence is used.
*/
public class MDGenerator extends BasePRNG implements Cloneable
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";
@@ -67,23 +65,12 @@ public class MDGenerator extends BasePRNG implements Cloneable
/** 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
@@ -95,22 +82,15 @@ public class MDGenerator extends BasePRNG implements Cloneable
// 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 // a clone. reset it for reuse
md.reset();
}
else
{ // ensure we have a reliable implementation of this hash
md = HashFactory.getInstance(underlyingMD);
}
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];
}
seed = new byte[0];
md.update(seed, 0, seed.length);
}
@@ -122,22 +102,20 @@ public class MDGenerator extends BasePRNG implements Cloneable
md.update(buffer, 0, buffer.length);
}
public void addRandomByte (final byte b)
public void addRandomByte(final byte b)
{
if (md == null)
throw new IllegalStateException ("not initialized");
md.update (b);
throw new IllegalStateException("not initialized");
md.update(b);
}
public void addRandomBytes (final byte[] buf, final int off, final int len)
public void addRandomBytes(final byte[] buf, final int off, final int len)
{
if (md == null)
throw new IllegalStateException ("not initialized");
md.update (buf, off, len);
throw new IllegalStateException("not initialized");
md.update(buf, off, len);
}
// Cloneable interface implementation ---------------------------------------
public Object clone() throws CloneNotSupportedException
{
MDGenerator result = (MDGenerator) super.clone();
@@ -42,60 +42,46 @@ 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>
* A Factory to instantiate pseudo random number generators.
*/
public class PRNGFactory implements Registry
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>
*
* Returns an instance of a padding algorithm given its name.
*
* @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.
* test.
*/
public static final IRandom getInstance(String prng)
{
if (prng == null)
{
return null;
}
return null;
prng = prng.trim();
IRandom result = null;
if (prng.equalsIgnoreCase(MD_PRNG))
{
result = new MDGenerator();
}
result = new MDGenerator();
return result;
}
/**
* <p>Returns a {@link Set} of names of padding algorithms supported by this
* <i>Factory</i>.</p>
*
* Returns a {@link Set} of names of padding algorithms supported by this
* <i>Factory</i>.
*
* @return a {@link Set} of pseudo-random number generator algorithm names
* (Strings).
* (Strings).
*/
public static final Set getNames()
{
@@ -103,7 +89,4 @@ public class PRNGFactory implements Registry
hs.add(MD_PRNG);
return Collections.unmodifiableSet(hs);
}
// Instance methods
// -------------------------------------------------------------------------
}
@@ -41,12 +41,11 @@ package gnu.java.security.prng;
import java.util.EventObject;
/**
* An interface for entropy accumulators that will be notified of random
* events.
* A type for entropy accumulators that will be notified of random events.
*/
public class RandomEvent extends EventObject
public class RandomEvent
extends EventObject
{
private final byte sourceNumber;
private final byte poolNumber;
@@ -61,7 +60,7 @@ public class RandomEvent extends EventObject
this.poolNumber = poolNumber;
if (data.length == 0 || data.length > 32)
throw new IllegalArgumentException(
"random events take between 1 and 32 bytes of data");
"random events take between 1 and 32 bytes of data");
this.data = (byte[]) data.clone();
}
@@ -79,4 +78,4 @@ public class RandomEvent extends EventObject
{
return data;
}
}
}
@@ -41,10 +41,10 @@ package gnu.java.security.prng;
import java.util.EventListener;
/**
* An interface for entropy accumulators that will be notified of random
* events.
* An interface for entropy accumulators that will be notified of random events.
*/
public interface RandomEventListener extends EventListener
public interface RandomEventListener
extends EventListener
{
void addRandomEvent(RandomEvent event);
}
}
@@ -42,12 +42,16 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.Provider;
public final class Gnu extends Provider
public final class Gnu
extends Provider
{
public Gnu()
{
super("GNU", 1.0, "GNU provider v1.0 implementing SHA-1, MD5, DSA, RSA, X.509 Certificates and CRLs, PKIX certificate path validators, Collection cert stores, Diffie-Hellman key agreement and key pair generator");
super("GNU", 1.0,
"GNU provider v1.0 implementing SHA-1, MD5, DSA, RSA, X.509 "
+ "Certificates and CRLs, PKIX certificate path validators, "
+ "Collection cert stores, Diffie-Hellman key agreement and "
+ "key pair generator");
AccessController.doPrivileged (new PrivilegedAction()
{
public Object run()
@@ -163,29 +167,41 @@ public final class Gnu extends Provider
put("Alg.Alias.KeyFactory.PKCS#8", "Encoded");
put("Alg.Alias.KeyFactory.PKCS8", "Encoded");
put("MessageDigest.HAVAL", gnu.java.security.jce.hash.HavalSpi.class.getName());
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
gnu.java.security.jce.hash.WhirlpoolSpi.class.getName());
put("MessageDigest.WHIRLPOOL ImplementedIn", "Software");
put("Alg.Alias.MessageDigest.SHS", "SHA-160");
@@ -224,29 +240,41 @@ public final class Gnu extends Provider
put("SecureRandom.SHA1PRNG",
gnu.java.security.jce.prng.Sha160RandomSpi.class.getName());
put("SecureRandom.MD2PRNG", gnu.java.security.jce.prng.MD2RandomSpi.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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
gnu.java.security.jce.prng.WhirlpoolRandomSpi.class.getName());
put("SecureRandom.WHIRLPOOLPRNG ImplementedIn", "Software");
put("Alg.Alias.SecureRandom.SHA-1PRNG", "SHA-160PRNG");
@@ -1,5 +1,5 @@
/* PKIXCertPathValidatorImpl.java -- PKIX certificate path validator.
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,6 +38,7 @@ exception statement from your version. */
package gnu.java.security.provider;
import gnu.java.security.Configuration;
import gnu.java.security.OID;
import gnu.java.security.Registry;
import gnu.java.security.key.dss.DSSPublicKey;
@@ -81,63 +82,48 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
/**
* An implementation of the Public Key Infrastructure's X.509
* certificate path validation algorithm.
*
* <p>See <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
* Internet X.509 Public Key Infrastructure Certificate and
* Certificate Revocation List (CRL) Profile</a>.
*
* An implementation of the Public Key Infrastructure's X.509 certificate path
* validation algorithm.
* <p>
* See <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
* Public Key Infrastructure Certificate and Certificate Revocation List (CRL)
* Profile</a>.
*
* @author Casey Marshall (rsdio@metastatic.org)
*/
public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
public class PKIXCertPathValidatorImpl
extends CertPathValidatorSpi
{
// Constants.
// -------------------------------------------------------------------------
private static final boolean DEBUG = false;
private static void debug (String msg)
{
System.err.print (">> PKIXCertPathValidatorImpl: ");
System.err.println (msg);
}
private static final Logger log = Logger.getLogger(PKIXCertPathValidatorImpl.class.getName());
public static final String ANY_POLICY = "2.5.29.32.0";
// Constructor.
// -------------------------------------------------------------------------
public PKIXCertPathValidatorImpl()
{
super();
}
// Instance methods.
// -------------------------------------------------------------------------
public CertPathValidatorResult engineValidate(CertPath path,
CertPathParameters params)
throws CertPathValidatorException, InvalidAlgorithmParameterException
throws CertPathValidatorException, InvalidAlgorithmParameterException
{
if (!(params instanceof PKIXParameters))
if (! (params instanceof PKIXParameters))
throw new InvalidAlgorithmParameterException("not a PKIXParameters object");
// First check if the certificate path is valid.
//
// This means that:
//
// (a) for all x in {1, ..., n-1}, the subject of certificate x is
// the issuer of certificate x+1;
// (a) for all x in {1, ..., n-1}, the subject of certificate x is
// the issuer of certificate x+1;
//
// (b) for all x in {1, ..., n}, the certificate was valid at the
// time in question.
// (b) for all x in {1, ..., n}, the certificate was valid at the
// time in question.
//
// Because this is the X.509 algorithm, we also check if all
// cerificates are of type X509Certificate.
PolicyNodeImpl rootNode = new PolicyNodeImpl();
Set initPolicies = ((PKIXParameters) params).getInitialPolicies();
rootNode.setValidPolicy(ANY_POLICY);
@@ -160,7 +146,6 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
{
throw new CertPathValidatorException("invalid certificate path");
}
String sigProvider = ((PKIXParameters) params).getSigProvider();
PublicKey prevKey = null;
Date now = ((PKIXParameters) params).getDate();
@@ -178,7 +163,7 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
throw new CertPathValidatorException(ce.toString());
}
Set uce = getCritExts(p[i]);
for (Iterator check = checks.iterator(); check.hasNext(); )
for (Iterator check = checks.iterator(); check.hasNext();)
{
try
{
@@ -188,23 +173,21 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
{
}
}
PolicyConstraint constr = null;
if (p[i] instanceof GnuPKIExtension)
{
Extension pcx =
((GnuPKIExtension) p[i]).getExtension (PolicyConstraint.ID);
Extension pcx = ((GnuPKIExtension) p[i]).getExtension(PolicyConstraint.ID);
if (pcx != null)
constr = (PolicyConstraint) pcx.getValue();
}
else
{
byte[] pcx = p[i].getExtensionValue (PolicyConstraint.ID.toString());
byte[] pcx = p[i].getExtensionValue(PolicyConstraint.ID.toString());
if (pcx != null)
{
try
{
constr = new PolicyConstraint (pcx);
constr = new PolicyConstraint(pcx);
}
catch (Exception x)
{
@@ -212,14 +195,10 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
}
}
if (constr != null && constr.getRequireExplicitPolicy() >= 0)
{
policyConstraints.add (new int[]
{ p.length-i, constr.getRequireExplicitPolicy() });
}
updatePolicyTree(p[i], rootNode, p.length-i, (PKIXParameters) params,
checkExplicitPolicy (p.length-i, policyConstraints));
policyConstraints.add(new int[] { p.length - i,
constr.getRequireExplicitPolicy() });
updatePolicyTree(p[i], rootNode, p.length - i, (PKIXParameters) params,
checkExplicitPolicy(p.length - i, policyConstraints));
// The rest of the tests involve this cert's relationship with the
// next in the path. If this cert is the end entity, we can stop.
if (i == 0)
@@ -236,36 +215,35 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
// If the DSA public key is missing its parameters, use those
// from the previous cert's key.
if (dsa == null || dsa.getP() == null || dsa.getG() == null
|| dsa.getQ() == null)
|| dsa.getQ() == null)
{
if (prevKey == null)
throw new InvalidKeyException("DSA keys not chainable");
if (!(prevKey instanceof DSAPublicKey))
if (! (prevKey instanceof DSAPublicKey))
throw new InvalidKeyException("DSA keys not chainable");
dsa = ((DSAPublicKey) prevKey).getParams();
pubKey = new DSSPublicKey(Registry.X509_ENCODING_ID,
dsa.getP(),
dsa.getQ(),
dsa.getP(), dsa.getQ(),
dsa.getG(),
((DSAPublicKey) pubKey).getY());
}
}
if (sigProvider == null)
p[i-1].verify(pubKey);
p[i - 1].verify(pubKey);
else
p[i-1].verify(pubKey, sigProvider);
p[i - 1].verify(pubKey, sigProvider);
prevKey = pubKey;
}
catch (Exception e)
{
throw new CertPathValidatorException(e.toString());
}
if (!p[i].getSubjectDN().equals(p[i-1].getIssuerDN()))
if (! p[i].getSubjectDN().equals(p[i - 1].getIssuerDN()))
throw new CertPathValidatorException("issuer DN mismatch");
boolean[] issuerUid = p[i-1].getIssuerUniqueID();
boolean[] issuerUid = p[i - 1].getIssuerUniqueID();
boolean[] subjectUid = p[i].getSubjectUniqueID();
if (issuerUid != null && subjectUid != null)
if (!Arrays.equals(issuerUid, subjectUid))
if (! Arrays.equals(issuerUid, subjectUid))
throw new CertPathValidatorException("UID mismatch");
// Check the certificate against the revocation lists.
@@ -282,7 +260,7 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
}
List certStores = ((PKIXParameters) params).getCertStores();
List crls = new LinkedList();
for (Iterator it = certStores.iterator(); it.hasNext(); )
for (Iterator it = certStores.iterator(); it.hasNext();)
{
CertStore cs = (CertStore) it.next();
try
@@ -297,30 +275,30 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
if (crls.isEmpty())
throw new CertPathValidatorException("no CRLs for issuer");
boolean certOk = false;
for (Iterator it = crls.iterator(); it.hasNext(); )
for (Iterator it = crls.iterator(); it.hasNext();)
{
CRL crl = (CRL) it.next();
if (!(crl instanceof X509CRL))
if (! (crl instanceof X509CRL))
continue;
X509CRL xcrl = (X509CRL) crl;
if (!checkCRL(xcrl, p, now, p[i], pubKey, certStores))
if (! checkCRL(xcrl, p, now, p[i], pubKey, certStores))
continue;
if (xcrl.isRevoked(p[i-1]))
if (xcrl.isRevoked(p[i - 1]))
throw new CertPathValidatorException("certificate is revoked");
else
certOk = true;
}
if (!certOk)
throw new CertPathValidatorException("certificate's validity could not be determined");
if (! certOk)
throw new CertPathValidatorException(
"certificate's validity could not be determined");
}
}
rootNode.setReadOnly();
// Now ensure that the first certificate in the chain was issued
// by a trust anchor.
Exception cause = null;
Set anchors = ((PKIXParameters) params).getTrustAnchors();
for (Iterator i = anchors.iterator(); i.hasNext(); )
for (Iterator i = anchors.iterator(); i.hasNext();)
{
TrustAnchor anchor = (TrustAnchor) i.next();
X509Certificate anchorCert = null;
@@ -338,7 +316,7 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
{
if (anchorCert != null)
anchorCert.checkValidity(now);
p[p.length-1].verify(anchorKey);
p[p.length - 1].verify(anchorKey);
if (anchorCert != null && anchorCert.getBasicConstraints() >= 0
&& anchorCert.getBasicConstraints() < p.length)
continue;
@@ -358,7 +336,7 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
selector.addIssuerName(anchor.getCAName());
List certStores = ((PKIXParameters) params).getCertStores();
List crls = new LinkedList();
for (Iterator it = certStores.iterator(); it.hasNext(); )
for (Iterator it = certStores.iterator(); it.hasNext();)
{
CertStore cs = (CertStore) it.next();
try
@@ -372,10 +350,10 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
}
if (crls.isEmpty())
continue;
for (Iterator it = crls.iterator(); it.hasNext(); )
for (Iterator it = crls.iterator(); it.hasNext();)
{
CRL crl = (CRL) it.next();
if (!(crl instanceof X509CRL))
if (! (crl instanceof X509CRL))
continue;
X509CRL xcrl = (X509CRL) crl;
try
@@ -389,11 +367,10 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
Date nextUpdate = xcrl.getNextUpdate();
if (nextUpdate != null && nextUpdate.compareTo(now) < 0)
continue;
if (xcrl.isRevoked(p[p.length-1]))
if (xcrl.isRevoked(p[p.length - 1]))
throw new CertPathValidatorException("certificate is revoked");
}
}
// The chain is valid; return the result.
return new PKIXCertPathValidatorResult(anchor, rootNode,
p[0].getPublicKey());
@@ -404,44 +381,39 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
continue;
}
}
// The path is not valid.
CertPathValidatorException cpve =
new CertPathValidatorException("path validation failed");
new CertPathValidatorException("path validation failed");
if (cause != null)
cpve.initCause (cause);
cpve.initCause(cause);
throw cpve;
}
// Own methods.
// -------------------------------------------------------------------------
/**
* Check if a given CRL is acceptable for checking the revocation status
* of certificates in the path being checked.
*
* <p>The CRL is accepted iff:</p>
*
* Check if a given CRL is acceptable for checking the revocation status of
* certificates in the path being checked.
* <p>
* The CRL is accepted iff:
* <ol>
* <li>The <i>nextUpdate</i> field (if present) is in the future.</li>
* <li>The CRL does not contain any unsupported critical extensions.</li>
* <li>The CRL is signed by one of the certificates in the path, or,</li>
* <li>The CRL is signed by the given public key and was issued by the
* public key's subject, or,</li>
* <li>The CRL is signed by a certificate in the given cert stores, and
* that cert is signed by one of the certificates in the path.</li>
* <li>The CRL is signed by the given public key and was issued by the public
* key's subject, or,</li>
* <li>The CRL is signed by a certificate in the given cert stores, and that
* cert is signed by one of the certificates in the path.</li>
* </ol>
*
*
* @param crl The CRL being checked.
* @param path The path this CRL is being checked against.
* @param now The value to use as 'now'.
* @param pubKeySubject The subject of the public key.
* @param pubKeyCert The certificate authenticating the public key.
* @param pubKey The public key to check.
* @return True if the CRL is acceptable.
*/
private static boolean checkCRL(X509CRL crl, X509Certificate[] path, Date now,
X509Certificate pubKeyCert, PublicKey pubKey,
List certStores)
private static boolean checkCRL(X509CRL crl, X509Certificate[] path,
Date now, X509Certificate pubKeyCert,
PublicKey pubKey, List certStores)
{
Date nextUpdate = crl.getNextUpdate();
if (nextUpdate != null && nextUpdate.compareTo(now) < 0)
@@ -450,12 +422,12 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
return false;
for (int i = 0; i < path.length; i++)
{
if (!path[i].getSubjectDN().equals(crl.getIssuerDN()))
if (! path[i].getSubjectDN().equals(crl.getIssuerDN()))
continue;
boolean[] keyUsage = path[i].getKeyUsage();
if (keyUsage != null)
{
if (!keyUsage[KeyUsage.CRL_SIGN])
if (! keyUsage[KeyUsage.CRL_SIGN])
continue;
}
try
@@ -474,7 +446,7 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
boolean[] keyUsage = pubKeyCert.getKeyUsage();
if (keyUsage != null)
{
if (!keyUsage[KeyUsage.CRL_SIGN])
if (! keyUsage[KeyUsage.CRL_SIGN])
throw new Exception();
}
crl.verify(pubKey);
@@ -489,7 +461,7 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
X509CertSelectorImpl select = new X509CertSelectorImpl();
select.addSubjectName(crl.getIssuerDN());
List certs = new LinkedList();
for (Iterator it = certStores.iterator(); it.hasNext(); )
for (Iterator it = certStores.iterator(); it.hasNext();)
{
CertStore cs = (CertStore) it.next();
try
@@ -500,17 +472,17 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
{
}
}
for (Iterator it = certs.iterator(); it.hasNext(); )
for (Iterator it = certs.iterator(); it.hasNext();)
{
X509Certificate c = (X509Certificate) it.next();
for (int i = 0; i < path.length; i++)
{
if (!c.getIssuerDN().equals(path[i].getSubjectDN()))
if (! c.getIssuerDN().equals(path[i].getSubjectDN()))
continue;
boolean[] keyUsage = c.getKeyUsage();
if (keyUsage != null)
{
if (!keyUsage[KeyUsage.CRL_SIGN])
if (! keyUsage[KeyUsage.CRL_SIGN])
continue;
}
try
@@ -542,10 +514,10 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
if (cert instanceof GnuPKIExtension)
{
Collection exts = ((GnuPKIExtension) cert).getExtensions();
for (Iterator it = exts.iterator(); it.hasNext(); )
for (Iterator it = exts.iterator(); it.hasNext();)
{
Extension ext = (Extension) it.next();
if (ext.isCritical() && !ext.isSupported())
if (ext.isCritical() && ! ext.isSupported())
s.add(ext.getOid().toString());
}
}
@@ -558,13 +530,13 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
* Perform a basic sanity check on the CA certificate at <code>index</code>.
*/
private static void basicSanity(X509Certificate[] path, int index)
throws CertPathValidatorException
throws CertPathValidatorException
{
X509Certificate cert = path[index];
int pathLen = 0;
for (int i = index - 1; i > 0; i--)
{
if (!path[i].getIssuerDN().equals(path[i].getSubjectDN()))
if (! path[i].getIssuerDN().equals(path[i].getSubjectDN()))
pathLen++;
}
Extension e = null;
@@ -585,25 +557,30 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
if (e == null)
throw new CertPathValidatorException("no basicConstraints");
BasicConstraints bc = (BasicConstraints) e.getValue();
if (!bc.isCA())
throw new CertPathValidatorException("certificate cannot be used to verify signatures");
if (bc.getPathLengthConstraint() >= 0 && bc.getPathLengthConstraint() < pathLen)
if (! bc.isCA())
throw new CertPathValidatorException(
"certificate cannot be used to verify signatures");
if (bc.getPathLengthConstraint() >= 0
&& bc.getPathLengthConstraint() < pathLen)
throw new CertPathValidatorException("path is too long");
boolean[] keyUsage = cert.getKeyUsage();
if (keyUsage != null)
{
if (!keyUsage[KeyUsage.KEY_CERT_SIGN])
throw new CertPathValidatorException("certificate cannot be used to sign certificates");
if (! keyUsage[KeyUsage.KEY_CERT_SIGN])
throw new CertPathValidatorException(
"certificate cannot be used to sign certificates");
}
}
private static void updatePolicyTree(X509Certificate cert, PolicyNodeImpl root,
int depth, PKIXParameters params,
private static void updatePolicyTree(X509Certificate cert,
PolicyNodeImpl root, int depth,
PKIXParameters params,
boolean explicitPolicy)
throws CertPathValidatorException
throws CertPathValidatorException
{
if (DEBUG) debug("updatePolicyTree depth == " + depth);
if (Configuration.DEBUG)
log.fine("updatePolicyTree depth == " + depth);
Set nodes = new HashSet();
LinkedList stack = new LinkedList();
Iterator current = null;
@@ -614,21 +591,24 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
while (current.hasNext())
{
PolicyNodeImpl p = (PolicyNodeImpl) current.next();
if (DEBUG) debug("visiting node == " + p);
if (Configuration.DEBUG)
log.fine("visiting node == " + p);
if (p.getDepth() == depth - 1)
{
if (DEBUG) debug("added node");
if (Configuration.DEBUG)
log.fine("added node");
nodes.add(p);
}
else
{
if (DEBUG) debug("skipped node");
if (Configuration.DEBUG)
log.fine("skipped node");
stack.addLast(current);
current = p.getChildren();
}
}
}
while (!stack.isEmpty());
while (! stack.isEmpty());
Extension e = null;
CertificatePolicies policies = null;
@@ -646,18 +626,23 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
else
cp = Collections.EMPTY_LIST;
boolean match = false;
if (DEBUG) debug("nodes are == " + nodes);
if (DEBUG) debug("cert policies are == " + cp);
for (Iterator it = nodes.iterator(); it.hasNext(); )
if (Configuration.DEBUG)
{
log.fine("nodes are == " + nodes);
log.fine("cert policies are == " + cp);
}
for (Iterator it = nodes.iterator(); it.hasNext();)
{
PolicyNodeImpl parent = (PolicyNodeImpl) it.next();
if (DEBUG) debug("adding policies to " + parent);
for (Iterator it2 = cp.iterator(); it2.hasNext(); )
if (Configuration.DEBUG)
log.fine("adding policies to " + parent);
for (Iterator it2 = cp.iterator(); it2.hasNext();)
{
OID policy = (OID) it2.next();
if (DEBUG) debug("trying to add policy == " + policy);
if (policy.toString().equals(ANY_POLICY) &&
params.isAnyPolicyInhibited())
if (Configuration.DEBUG)
log.fine("trying to add policy == " + policy);
if (policy.toString().equals(ANY_POLICY)
&& params.isAnyPolicyInhibited())
continue;
PolicyNodeImpl child = new PolicyNodeImpl();
child.setValidPolicy(policy.toString());
@@ -672,32 +657,34 @@ public class PKIXCertPathValidatorImpl extends CertPathValidatorSpi
parent.addChild(child);
match = true;
}
else if (ANY_POLICY.equals (policy.toString()))
else if (ANY_POLICY.equals(policy.toString()))
{
parent.addChild (child);
parent.addChild(child);
match = true;
}
if (match && policies != null)
{
List qualifiers = policies.getPolicyQualifierInfos (policy);
List qualifiers = policies.getPolicyQualifierInfos(policy);
if (qualifiers != null)
child.addAllPolicyQualifiers (qualifiers);
child.addAllPolicyQualifiers(qualifiers);
}
}
}
if (!match && (params.isExplicitPolicyRequired() || explicitPolicy))
if (! match && (params.isExplicitPolicyRequired() || explicitPolicy))
throw new CertPathValidatorException("policy tree building failed");
}
private boolean checkExplicitPolicy (int depth, List explicitPolicies)
private boolean checkExplicitPolicy(int depth, List explicitPolicies)
{
if (DEBUG) debug ("checkExplicitPolicy depth=" + depth);
for (Iterator it = explicitPolicies.iterator(); it.hasNext(); )
if (Configuration.DEBUG)
log.fine("checkExplicitPolicy depth=" + depth);
for (Iterator it = explicitPolicies.iterator(); it.hasNext();)
{
int[] i = (int[]) it.next();
int caDepth = i[0];
int limit = i[1];
if (DEBUG) debug (" caDepth=" + caDepth + " limit=" + limit);
if (Configuration.DEBUG)
log.fine(" caDepth=" + caDepth + " limit=" + limit);
if (depth - caDepth >= limit)
return true;
}
@@ -59,30 +59,24 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class X509CertificateFactory extends CertificateFactorySpi
public class X509CertificateFactory
extends CertificateFactorySpi
{
// Constants.
// ------------------------------------------------------------------------
public static final String BEGIN_CERTIFICATE = "-----BEGIN CERTIFICATE-----";
public static final String END_CERTIFICATE = "-----END CERTIFICATE-----";
public static final String BEGIN_X509_CRL = "-----BEGIN X509 CRL-----";
public static final String END_X509_CRL = "-----END X509 CRL-----";
// Constructors.
// ------------------------------------------------------------------------
public static final String END_CERTIFICATE = "-----END CERTIFICATE-----";
public static final String BEGIN_X509_CRL = "-----BEGIN X509 CRL-----";
public static final String END_X509_CRL = "-----END X509 CRL-----";
public X509CertificateFactory()
{
super();
}
// Instance methods.
// ------------------------------------------------------------------------
public Certificate engineGenerateCertificate(InputStream inStream)
throws CertificateException
throws CertificateException
{
try
{
@@ -91,13 +85,13 @@ public class X509CertificateFactory extends CertificateFactorySpi
catch (IOException ioe)
{
CertificateException ce = new CertificateException(ioe.getMessage());
ce.initCause (ioe);
ce.initCause(ioe);
throw ce;
}
}
public Collection engineGenerateCertificates(InputStream inStream)
throws CertificateException
throws CertificateException
{
LinkedList certs = new LinkedList();
while (true)
@@ -113,7 +107,7 @@ public class X509CertificateFactory extends CertificateFactorySpi
catch (IOException ioe)
{
CertificateException ce = new CertificateException(ioe.getMessage());
ce.initCause (ioe);
ce.initCause(ioe);
throw ce;
}
}
@@ -129,13 +123,13 @@ public class X509CertificateFactory extends CertificateFactorySpi
catch (IOException ioe)
{
CRLException crle = new CRLException(ioe.getMessage());
crle.initCause (ioe);
crle.initCause(ioe);
throw crle;
}
}
public Collection engineGenerateCRLs(InputStream inStream)
throws CRLException
throws CRLException
{
LinkedList crls = new LinkedList();
while (true)
@@ -151,7 +145,7 @@ public class X509CertificateFactory extends CertificateFactorySpi
catch (IOException ioe)
{
CRLException crle = new CRLException(ioe.getMessage());
crle.initCause (ioe);
crle.initCause(ioe);
throw crle;
}
}
@@ -164,13 +158,13 @@ public class X509CertificateFactory extends CertificateFactorySpi
}
public CertPath engineGenerateCertPath(InputStream in)
throws CertificateEncodingException
throws CertificateEncodingException
{
return new X509CertPath(in);
}
public CertPath engineGenerateCertPath(InputStream in, String encoding)
throws CertificateEncodingException
throws CertificateEncodingException
{
return new X509CertPath(in, encoding);
}
@@ -180,21 +174,17 @@ public class X509CertificateFactory extends CertificateFactorySpi
return X509CertPath.ENCODINGS.iterator();
}
// Own methods.
// ------------------------------------------------------------------------
private X509Certificate generateCert(InputStream inStream)
throws IOException, CertificateException
throws IOException, CertificateException
{
if (inStream == null)
throw new CertificateException("missing input stream");
if (!inStream.markSupported())
if (! inStream.markSupported())
inStream = new BufferedInputStream(inStream, 8192);
inStream.mark(20);
int i = inStream.read();
if (i == -1)
throw new EOFException();
// If the input is in binary DER format, the first byte MUST be
// 0x30, which stands for the ASN.1 [UNIVERSAL 16], which is the
// UNIVERSAL SEQUENCE, with the CONSTRUCTED bit (0x20) set.
@@ -217,9 +207,9 @@ public class X509CertificateFactory extends CertificateFactorySpi
}
while (i != '\n' && i != '\r');
}
while (!line.toString().equals(BEGIN_CERTIFICATE));
while (! line.toString().equals(BEGIN_CERTIFICATE));
X509Certificate ret = new X509Certificate(
new BufferedInputStream(new Base64InputStream(inStream), 8192));
new BufferedInputStream(new Base64InputStream(inStream), 8192));
line.setLength(0);
line.append('-'); // Base64InputStream will eat this.
do
@@ -232,7 +222,7 @@ public class X509CertificateFactory extends CertificateFactorySpi
}
while (i != '\n' && i != '\r');
// XXX ???
if (!line.toString().equals(END_CERTIFICATE))
if (! line.toString().equals(END_CERTIFICATE))
throw new CertificateException("no end-of-certificate marker");
return ret;
}
@@ -243,18 +233,17 @@ public class X509CertificateFactory extends CertificateFactorySpi
}
}
private X509CRL generateCRL(InputStream inStream)
throws IOException, CRLException
private X509CRL generateCRL(InputStream inStream) throws IOException,
CRLException
{
if (inStream == null)
throw new CRLException("missing input stream");
if (!inStream.markSupported())
if (! inStream.markSupported())
inStream = new BufferedInputStream(inStream, 8192);
inStream.mark(20);
int i = inStream.read();
if (i == -1)
throw new EOFException();
// If the input is in binary DER format, the first byte MUST be
// 0x30, which stands for the ASN.1 [UNIVERSAL 16], which is the
// UNIVERSAL SEQUENCE, with the CONSTRUCTED bit (0x20) set.
@@ -277,9 +266,9 @@ public class X509CertificateFactory extends CertificateFactorySpi
}
while (i != '\n' && i != '\r');
}
while (!line.toString().startsWith(BEGIN_X509_CRL));
while (! line.toString().startsWith(BEGIN_X509_CRL));
X509CRL ret = new X509CRL(
new BufferedInputStream(new Base64InputStream(inStream), 8192));
new BufferedInputStream(new Base64InputStream(inStream), 8192));
line.setLength(0);
line.append('-'); // Base64InputStream will eat this.
do
@@ -292,7 +281,7 @@ public class X509CertificateFactory extends CertificateFactorySpi
}
while (i != '\n' && i != '\r');
// XXX ???
if (!line.toString().startsWith(END_X509_CRL))
if (! line.toString().startsWith(END_X509_CRL))
throw new CRLException("no end-of-CRL marker");
return ret;
}
@@ -49,15 +49,11 @@ import java.util.Map;
import java.util.Random;
/**
* <p>A base abstract class to facilitate implementations of concrete
* Signatures.</p>
* A base abstract class to facilitate implementations of concrete Signatures.
*/
public abstract class BaseSignature implements ISignature
public abstract class BaseSignature
implements ISignature
{
// Constants and variables
// -------------------------------------------------------------------------
/** The canonical name of this signature scheme. */
protected String schemeName;
@@ -79,9 +75,6 @@ public abstract class BaseSignature implements ISignature
/** Our default source of randomness. */
private PRNG prng = null;
// Constructor(s)
// -------------------------------------------------------------------------
/**
* Trivial constructor.
*
@@ -101,14 +94,6 @@ public abstract class BaseSignature implements ISignature
this.md = md;
}
// Class methods
// -------------------------------------------------------------------------
// Instance methods
// -------------------------------------------------------------------------
// gnu.crypto.sig.ISignature interface implementation ----------------------
public String name()
{
return schemeName + "-" + md.name();
@@ -117,51 +102,41 @@ public abstract class BaseSignature implements ISignature
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);
}
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);
}
setupForSigning(key);
}
public void update(byte b)
{
if (md == null)
{
throw new IllegalStateException();
}
throw new IllegalStateException();
md.update(b);
}
public void update(byte[] b, int off, int len)
{
if (md == null)
{
throw new IllegalStateException();
}
throw new IllegalStateException();
md.update(b, off, len);
}
public Object sign()
{
if (md == null || privateKey == null)
{
throw new IllegalStateException();
}
throw new IllegalStateException();
return generateSignature();
}
@@ -169,15 +144,11 @@ public abstract class BaseSignature implements ISignature
public boolean verify(Object sig)
{
if (md == null || publicKey == null)
{
throw new IllegalStateException();
}
throw new IllegalStateException();
return verifySignature(sig);
}
// abstract methods to be implemented by concrete subclasses ---------------
public abstract Object clone();
protected abstract void setupForVerification(PublicKey key)
@@ -191,8 +162,6 @@ public abstract class BaseSignature implements ISignature
protected abstract boolean verifySignature(Object signature)
throws IllegalStateException;
// Other instance methods --------------------------------------------------
/** Initialises the internal fields of this instance. */
protected void init()
{
@@ -204,33 +173,27 @@ public abstract class BaseSignature implements ISignature
}
/**
* <p>Fills the designated byte array with random data.</p>
*
* Fills the designated byte array with random data.
*
* @param buffer the byte array to fill with random data.
*/
protected void nextRandomBytes(byte[] buffer)
{
if (rnd != null)
{
rnd.nextBytes(buffer);
}
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));
}
}
try
{
irnd.nextBytes(buffer, 0, buffer.length);
}
catch (IllegalStateException x)
{
throw new RuntimeException("nextRandomBytes(): " + x);
}
catch (LimitReachedException x)
{
throw new RuntimeException("nextRandomBytes(): " + x);
}
else
getDefaultPRNG().nextBytes(buffer);
}
@@ -238,17 +201,12 @@ public abstract class BaseSignature implements ISignature
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;
}
rnd = (Random) obj;
else if (obj instanceof IRandom)
{
irnd = (IRandom) obj;
}
irnd = (IRandom) obj;
}
private PRNG getDefaultPRNG()
@@ -41,28 +41,24 @@ 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 &amp; al. states:
* The visible methods of every signature-with-appendix scheme.
* <p>
* The Handbook of Applied Cryptography (HAC), by A. Menezes &amp; 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>
* 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>
* References:
* <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>
* <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>
*/
public interface ISignature extends Cloneable
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";
@@ -71,96 +67,93 @@ public interface ISignature extends Cloneable
/**
* 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}.
* {@link java.util.Random}, or {@link gnu.java.security.prng.IRandom}
* instance to use. The default is to use a classloader singleton from
* {@link gnu.java.security.util.PRNG}.
*/
public static final String SOURCE_OF_RANDOMNESS = "gnu.crypto.sig.prng";
// Methods
// -------------------------------------------------------------------------
/**
* <p>Returns the canonical name of this signature scheme.</p>
*
* Returns the canonical name of this signature scheme.
*
* @return the canonical name of this instance.
*/
String name();
/**
* <p>Initialises this instance for signature verification.</p>
*
* Initialises this instance for signature verification.
*
* @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.
* 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>
*
* Initialises this instance for signature generation.
*
* @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.
* 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>
*
* Digests one byte of a message for signing or verification purposes.
*
* @param b the message byte to digest.
* @throws IllegalStateException if this instance was not setup for
* signature generation/verification.
* @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>
*
* Digests a sequence of bytes from a message for signing or verification
* purposes.
*
* @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.
* 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>
*
* Terminates a signature generation phase by digesting and processing the
* context of the underlying message digest algorithm instance.
*
* @return a {@link Object} representing the native output of the signature
* scheme implementation.
* @throws IllegalStateException if this instance was not setup for
* signature generation.
* 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>
*
* Terminates a signature verification phase by digesting and processing the
* context of the underlying message digest algorithm instance.
*
* @param signature a native signature object previously generated by an
* invocation of the <code>sign()</code> method.
* 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.
* 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>
*
* Returns a clone copy of this instance.
*
* @return a clone copy of this instance.
*/
Object clone();
@@ -41,23 +41,16 @@ package gnu.java.security.sig;
import gnu.java.security.Registry;
/**
* <p>The visible methods of an object that knows how to encode and decode
* 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>
* creating their internal Java representation from external sources.
*/
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);
@@ -53,38 +53,28 @@ 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;
}
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();
}
result = new DSSSignature();
else if (ssa.startsWith(Registry.RSA_SIG_PREFIX))
result = RSASignatureFactory.getInstance(ssa);
@@ -92,9 +82,9 @@ public class SignatureFactory
}
/**
* Returns a {@link Set} of signature-with-appendix scheme names supported
* by this <i>Factory</i>.
*
* 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()
@@ -104,10 +94,8 @@ public class SignatureFactory
HashSet hs = new HashSet();
hs.add(Registry.DSS_SIG);
hs.addAll(RSASignatureFactory.getNames());
names = Collections.unmodifiableSet(hs);
}
return names;
}
}
@@ -55,72 +55,65 @@ import java.util.Map;
import java.util.Random;
/**
* <p>The DSS (Digital Signature Standard) algorithm makes use of the following
* parameters:</p>
*
* The DSS (Digital Signature Standard) algorithm makes use of the following
* parameters:
* <ol>
* <li>p: A prime modulus, where <code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup>
* </code> for <code>512 &lt;= L &lt;= 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>
* <li>p: A prime modulus, where
* <code>2<sup>L-1</sup> &lt; p &lt; 2<sup>L</sup> </code> for <code>512 &lt;= L
* &lt;= 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>
* &lt; q &lt; 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 &lt; h &lt; 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 &lt; x
* <li>g: Where <code>g = h<sup>(p-1)</sup>/q mod p</code>, where
* <code>h</code> is any integer with <code>1 &lt; h &lt; 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 &lt; x
* &lt; 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 &lt; k
* <li>y: <code>y = g<sup>x</sup> mod p</code>.</li>
* <li>k: A randomly or pseudorandomly generated integer with <code>0 &lt; k
* &lt; q</code>.</li>
* </ol>
*
* <p>The integers <code>p</code>, <code>q</code>, and <code>g</code> can be
* <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>
*
* 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>
* 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:
* <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>
* <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 &lt; k-1 &lt; 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>
* <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 &lt; k-1 &lt; 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>
* 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>
* The signature is transmitted along with the message to the verifier.
* <p>
* References:
* <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>
* <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>
*/
public class DSSSignature extends BaseSignature
public class DSSSignature
extends BaseSignature
{
// Constants and variables
// -------------------------------------------------------------------------
// Constructor(s)
// -------------------------------------------------------------------------
/** Trivial 0-arguments constructor. */
public DSSSignature()
{
@@ -137,16 +130,12 @@ public class DSSSignature extends BaseSignature
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);
}
@@ -157,11 +146,9 @@ public class DSSSignature extends BaseSignature
final Map attributes = new HashMap();
attributes.put(ISignature.SIGNER_KEY, k);
if (rnd != null)
{
attributes.put(ISignature.SOURCE_OF_RANDOMNESS, rnd);
}
sig.setupSign(attributes);
attributes.put(ISignature.SOURCE_OF_RANDOMNESS, rnd);
sig.setupSign(attributes);
return sig.computeRS(h);
}
@@ -172,11 +159,9 @@ public class DSSSignature extends BaseSignature
final Map attributes = new HashMap();
attributes.put(ISignature.SIGNER_KEY, k);
if (irnd != null)
{
attributes.put(ISignature.SOURCE_OF_RANDOMNESS, irnd);
}
sig.setupSign(attributes);
attributes.put(ISignature.SOURCE_OF_RANDOMNESS, irnd);
sig.setupSign(attributes);
return sig.computeRS(h);
}
@@ -187,13 +172,9 @@ public class DSSSignature extends BaseSignature
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);
@@ -202,81 +183,37 @@ public class DSSSignature extends BaseSignature
protected void setupForVerification(PublicKey k)
throws IllegalArgumentException
{
if (!(k instanceof DSAPublicKey))
{
throw new 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();
}
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>
*
* Returns the output of a signature generation phase.
*
* @return an object encapsulating the DSS signature pair <code>r</code> and
* <code>s</code>.
* <code>s</code>.
*/
private Object encodeSignature(BigInteger r, BigInteger s)
{
@@ -284,9 +221,9 @@ public class DSSSignature extends BaseSignature
}
/**
* Returns the output of a previously generated signature object as a pair
* of {@link java.math.BigInteger}.<p>
*
* Returns the output of a previously generated signature object as a pair of
* {@link java.math.BigInteger}.
*
* @return the DSS signature pair <code>r</code> and <code>s</code>.
*/
private BigInteger[] decodeSignature(Object signature)
@@ -302,7 +239,6 @@ public class DSSSignature extends BaseSignature
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)
{
@@ -311,17 +247,14 @@ public class DSSSignature extends BaseSignature
k.clearBit(159);
r = g.modPow(k, p).mod(q);
if (r.equals(BigInteger.ZERO))
{
continue;
}
continue;
s = m.add(x.multiply(r)).multiply(k.modInverse(q)).mod(q);
if (s.equals(BigInteger.ZERO))
{
continue;
}
continue;
break;
}
return new BigInteger[] { r, s };
}
@@ -329,16 +262,13 @@ public class DSSSignature extends BaseSignature
{
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);
}
@@ -45,61 +45,46 @@ 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>
* An object that implements the {@link ISignatureCodec} operations for the
* <i>Raw</i> format to use with DSS signatures.
*/
public class DSSSignatureRawCodec implements ISignatureCodec
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>
*
* 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>
* The <i>Raw</i> format for a DSA signature, in this implementation, is a
* byte sequence consisting of the following:
* <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>
* <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.
* parameters <code>r</code> and <code>s</code> as a
* {@link 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.
* DSS (Digital Signature Standard) one.
*/
public byte[] encodeSignature(Object signature)
{
@@ -112,38 +97,32 @@ public class DSSSignatureRawCodec implements ISignatureCodec
}
catch (Exception x)
{
throw new IllegalArgumentException("key");
throw new IllegalArgumentException("signature");
}
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 >>> 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 >>> 24);
baos.write((length >>> 16) & 0xFF);
baos.write((length >>> 8) & 0xFF);
baos.write(length & 0xFF);
baos.write(buffer, 0, length);
return baos.toByteArray();
}
@@ -154,36 +133,32 @@ public class DSSSignatureRawCodec implements ISignatureCodec
|| 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");
}
throw new IllegalArgumentException("magic");
// version
if (k[4] != 0x01)
{
throw new IllegalArgumentException("version");
}
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);
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);
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 };
}
}
@@ -47,25 +47,21 @@ 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>
* An implementation of the EME-PKCS1-V1.5 encoding and decoding methods.
* <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>
* References:
* <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>
* <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();
@@ -73,9 +69,6 @@ public class EME_PKCS1_V1_5
/** Our default source of randomness. */
private PRNG prng = PRNG.getInstance();
// Constructor(s)
// -------------------------------------------------------------------------
private EME_PKCS1_V1_5(final int k)
{
super();
@@ -83,15 +76,11 @@ public class EME_PKCS1_V1_5
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");
}
throw new IllegalArgumentException("k must be a positive integer");
return new EME_PKCS1_V1_5(k);
}
@@ -102,34 +91,29 @@ public class EME_PKCS1_V1_5
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>,
* 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>
* 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>
*
* <code>k</code> octets as:
* <pre>
* EM = 0x00 || 0x02 || PS || 0x00 || M.
* EM = 0x00 || 0x02 || PS || 0x00 || M.
* </pre>
*
* <p>This method uses a default PRNG to obtain the padding bytes.</p>
*
* <p>
* This method uses a default PRNG to obtain the padding bytes.
*
* @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.
// 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;
@@ -139,17 +123,17 @@ public class EME_PKCS1_V1_5
PS[i] = 1;
}
// b. Concatenate PS, the message M, and other padding to form an
// encoded message EM of length k octets as
// encoded message EM of length k octets as
//
// EM = 0x00 || 0x02 || PS || 0x00 || M.
// EM = 0x00 || 0x02 || PS || 0x00 || M.
return assembleEM(PS, M);
}
/**
* <p>Similar to {@link #encode(byte[])} method, except that the source of
* 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>
*
* {@link IRandom}) is given as a parameter.
*
* @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>.
@@ -183,14 +167,13 @@ public class EME_PKCS1_V1_5
{
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}.
*
* 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>.
@@ -213,33 +196,31 @@ public class EME_PKCS1_V1_5
}
break;
}
return assembleEM(PS, M);
}
/**
* <p>Separate the encoded message <code>EM</code> into an octet string
* 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>
*
* as:
* <pre>
* EM = 0x00 || 0x02 || PS || 0x00 || M.
* 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>
* <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.
*
* @param EM the designated encoded message.
* @return the decoded message <code>M</code> framed in the designated
* <code>EM</code> value.
* <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.
* <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)
{
@@ -252,46 +233,34 @@ public class EME_PKCS1_V1_5
// 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.)
// "decryption error" and stop. (See the note below.)
final int emLen = EM.length;
if (emLen != k)
{
throw new IllegalArgumentException("decryption error");
}
throw new IllegalArgumentException("decryption error");
if (EM[0] != 0x00)
{
throw new IllegalArgumentException("decryption error");
}
throw new IllegalArgumentException("decryption error");
if (EM[1] != 0x02)
{
throw new IllegalArgumentException("decryption error");
}
throw new IllegalArgumentException("decryption error");
int i = 2;
for (; i < emLen; i++)
{
if (EM[i] == 0x00)
{
break;
}
break;
}
if (i >= emLen || i < 11)
{
throw new IllegalArgumentException("decryption error");
}
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
// encoded message EM of length k octets as
//
// EM = 0x00 || 0x02 || PS || 0x00 || M.
// EM = 0x00 || 0x02 || PS || 0x00 || M.
baos.reset();
baos.write(0x00);
baos.write(0x02);
@@ -300,7 +269,6 @@ public class EME_PKCS1_V1_5
baos.write(M, 0, M.length);
final byte[] result = baos.toByteArray();
baos.reset();
return result;
}
}
@@ -45,12 +45,12 @@ 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>
* An implementation of the EMSA-PKCS1-V1.5 encoding scheme.
* <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>
* References:
* <ol>
* <li><a href="http://www.ietf.org/rfc/rfc3447.txt">Public-Key Cryptography
* Standards (PKCS) #1:</a><br>
@@ -58,12 +58,9 @@ import java.io.ByteArrayOutputStream;
* Jakob Jonsson and Burt Kaliski.</li>
* </ol>
*/
public class EMSA_PKCS1_V1_5 implements Cloneable
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:
@@ -75,67 +72,46 @@ public class EMSA_PKCS1_V1_5 implements Cloneable
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[] 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[] 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[] 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[] 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[] 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 };
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;
@@ -146,11 +122,8 @@ public class EMSA_PKCS1_V1_5 implements Cloneable
/** 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>
* Trivial private constructor to enforce use through Factory method.
*
* @param hash the message digest instance to use with this scheme instance.
*/
@@ -162,41 +135,24 @@ public class EMSA_PKCS1_V1_5 implements Cloneable
hLen = hash.hashSize();
final String name = hash.name();
if (name.equals(Registry.MD2_HASH))
{
prefix = MD2_PREFIX;
}
prefix = MD2_PREFIX;
else if (name.equals(Registry.MD5_HASH))
{
prefix = MD5_PREFIX;
}
prefix = MD5_PREFIX;
else if (name.equals(Registry.SHA160_HASH))
{
prefix = SHA160_PREFIX;
}
prefix = SHA160_PREFIX;
else if (name.equals(Registry.SHA256_HASH))
{
prefix = SHA256_PREFIX;
}
prefix = SHA256_PREFIX;
else if (name.equals(Registry.SHA384_HASH))
{
prefix = SHA384_PREFIX;
}
prefix = SHA384_PREFIX;
else if (name.equals(Registry.SHA512_HASH))
{
prefix = SHA512_PREFIX;
}
prefix = SHA512_PREFIX;
else
{
throw new UnsupportedOperationException(); // should not happen
}
throw new UnsupportedOperationException(); // should not happen
}
// Class methods
// -------------------------------------------------------------------------
/**
* <p>Returns an instance of this object given a designated name of a hash
* function.</p>
* Returns an instance of this object given a designated name of a hash
* function.
*
* @param mdName the canonical name of a hash function.
* @return an instance of this object configured for use with the designated
@@ -208,32 +164,26 @@ public class EMSA_PKCS1_V1_5 implements Cloneable
{
final IMessageDigest hash = HashFactory.getInstance(mdName);
final String name = hash.name();
if (!(name.equals(Registry.MD2_HASH) || name.equals(Registry.MD5_HASH)
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);
}
|| 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
* 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>
* described in RFC-3447 (see class documentation).
*
* @param mHash the byte sequence resulting from applying the message digest
* algorithm Hash to the message <i>M</i>.
@@ -270,17 +220,13 @@ public class EMSA_PKCS1_V1_5 implements Cloneable
// 3. If emLen < tLen + 11, output "intended encoded message length too
// short" and stop.
if (emLen < tLen + 11)
{
throw new IllegalArgumentException("emLen too short");
}
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;
}
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();
@@ -38,57 +38,42 @@ exception statement from your version. */
package gnu.java.security.sig.rsa;
import gnu.java.security.Configuration;
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;
import java.util.logging.Logger;
/**
* <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
* An implementation of the EMSA-PSS encoding/decoding scheme.
* <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>
* 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>
* 1363-2000 recommends SHA-1 and RIPEMD-160.
* <p>
* References:
* <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.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>
*/
public class EMSA_PSS implements Cloneable
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
// -------------------------------------------------------------------------
private static final Logger log = Logger.getLogger(EMSA_PSS.class.getName());
/** The underlying hash function to use with this instance. */
private IMessageDigest hash;
@@ -96,12 +81,9 @@ public class EMSA_PSS implements Cloneable
/** 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>
*
* Trivial private constructor to enforce use through Factory method.
*
* @param hash the message digest instance to use with this scheme instance.
*/
private EMSA_PSS(IMessageDigest hash)
@@ -112,16 +94,13 @@ public class EMSA_PSS implements Cloneable
hLen = hash.hashSize();
}
// Class methods
// -------------------------------------------------------------------------
/**
* <p>Returns an instance of this object given a designated name of a hash
* function.</p>
*
* Returns an instance of this object given a designated name of a hash
* function.
*
* @param mdName the canonical name of a hash function.
* @return an instance of this object configured for use with the designated
* options.
* options.
*/
public static EMSA_PSS getInstance(String mdName)
{
@@ -129,51 +108,38 @@ public class EMSA_PSS implements Cloneable
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
* 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>
*
* function.
*
* @param mHash the byte sequence resulting from applying the message digest
* algorithm Hash to the message <i>M</i>.
* 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>.
* <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>.
* <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");
}
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");
}
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.
@@ -187,9 +153,8 @@ public class EMSA_PSS implements Cloneable
synchronized (hash)
{
for (i = 0; i < 8; i++)
{
hash.update((byte) 0x00);
}
hash.update((byte) 0x00);
hash.update(mHash, 0, hLen);
hash.update(salt, 0, sLen);
H = hash.digest();
@@ -202,16 +167,14 @@ public class EMSA_PSS implements Cloneable
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)
if (Configuration.DEBUG)
{
debug("dbMask (encode): " + Util.toString(dbMask));
debug("DB (encode): " + Util.toString(DB));
log.fine("dbMask (encode): " + Util.toString(dbMask));
log.fine("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]);
}
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));
@@ -226,14 +189,14 @@ public class EMSA_PSS implements Cloneable
}
/**
* <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>
*
* 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>.
*
* @param mHash the byte sequence resulting from applying the message digest
* algorithm Hash to the message <i>M</i>.
* 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).
* <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.
@@ -244,60 +207,50 @@ public class EMSA_PSS implements Cloneable
*/
public boolean decode(byte[] mHash, byte[] EM, int emBits, int sLen)
{
if (DEBUG && debuglevel > 8)
if (Configuration.DEBUG)
{
debug("mHash: " + Util.toString(mHash));
debug("EM: " + Util.toString(EM));
debug("emBits: " + String.valueOf(emBits));
debug("sLen: " + String.valueOf(sLen));
log.fine("mHash: " + Util.toString(mHash));
log.fine("EM: " + Util.toString(EM));
log.fine("emBits: " + String.valueOf(emBits));
log.fine("sLen: " + String.valueOf(sLen));
}
if (sLen < 0)
{
throw new IllegalArgumentException("sLen");
}
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.
// 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));
}
if (Configuration.DEBUG)
log.fine("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));
}
if (Configuration.DEBUG)
log.fine("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.
// output 'inconsistent' and stop.
if ((EM[EM.length - 1] & 0xFF) != 0xBC)
{
if (DEBUG && debuglevel > 8)
{
debug("EM does not end with 0xBC");
}
if (Configuration.DEBUG)
log.fine("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.
// 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.
// 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");
}
if (Configuration.DEBUG)
log.fine("Leftmost 8emLen - emBits bits of EM are not 0s");
return false;
}
byte[] DB = new byte[emLen - hLen - 1];
@@ -309,56 +262,48 @@ public class EMSA_PSS implements Cloneable
// 8. Let DB = maskedDB XOR dbMask.
int i;
for (i = 0; i < DB.length; i++)
{
DB[i] = (byte) (DB[i] ^ dbMask[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)
if (Configuration.DEBUG)
{
debug("dbMask (decode): " + Util.toString(dbMask));
debug("DB (decode): " + Util.toString(DB));
log.fine("dbMask (decode): " + Util.toString(dbMask));
log.fine("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.
// 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
// 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");
}
if (Configuration.DEBUG)
log.fine("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");
}
if (Configuration.DEBUG)
log.fine("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.
// 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((byte) 0x00);
hash.update(mHash, 0, hLen);
hash.update(salt, 0, sLen);
H0 = hash.digest();
@@ -367,34 +312,30 @@ public class EMSA_PSS implements Cloneable
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>
*
* 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.
*
* @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.
* 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");
}
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
@@ -409,14 +350,14 @@ public class EMSA_PSS implements Cloneable
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)
// 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 >>> 24));
hashZC.update((byte)(i >>> 16));
hashZC.update((byte)(i >>> 8));
hashZC.update((byte) i);
t = hashZC.digest();
length = l - sofar;
@@ -49,31 +49,26 @@ import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
/**
* <p>Utility methods related to the RSA algorithm.</p>
*
* <p>References:</p>
* Utility methods related to the RSA algorithm.
* <p>
* References:
* <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>
* <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;
@@ -81,37 +76,28 @@ public class RSA
/** 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>
*
* 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.
*
* @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>.
* <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>.
* <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.
* representative</i>) is out of range.
*/
public static final BigInteger sign(final PrivateKey K, final BigInteger m)
{
@@ -121,27 +107,27 @@ public class RSA
}
catch (IllegalArgumentException x)
{
throw new IllegalArgumentException(
"message representative out of range");
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>
*
* 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.
*
* @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>.
* <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>.
* 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.
* representative</i>) is out of range.
*/
public static final BigInteger verify(final PublicKey K, final BigInteger s)
{
@@ -151,25 +137,24 @@ public class RSA
}
catch (IllegalArgumentException x)
{
throw new IllegalArgumentException(
"signature representative out of range");
throw new IllegalArgumentException("signature representative out of range");
}
}
// Encryption and decryption methods ---------------------------------------
/**
* <p>An implementation of the <code>RSAEP</code> algorithm.</p>
*
* An implementation of the <code>RSAEP</code> algorithm.
*
* @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.
* <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).
* 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)
{
@@ -179,22 +164,23 @@ public class RSA
}
catch (IllegalArgumentException x)
{
throw new IllegalArgumentException(
"message representative out of range");
throw new IllegalArgumentException("message representative out of range");
}
}
/**
* <p>An implementation of the <code>RSADP</code> algorithm.</p>
*
* An implementation of the <code>RSADP</code> algorithm.
*
* @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).
* <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).
* 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)
{
@@ -204,22 +190,19 @@ public class RSA
}
catch (IllegalArgumentException x)
{
throw new IllegalArgumentException(
"ciphertext representative out of range");
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>
*
* Converts a <i>multi-precision integer</i> (MPI) <code>s</code> into an
* octet sequence of length <code>k</code>.
*
* @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>.
* bytes of <code>s</code> is greater than <code>k</code>.
*/
public static final byte[] I2OSP(final BigInteger s, final int k)
{
@@ -236,9 +219,7 @@ public class RSA
for (int i = 0; i < limit; i++)
{
if (result[i] != 0x00)
{
throw new IllegalArgumentException("integer too large");
}
throw new IllegalArgumentException("integer too large");
}
final byte[] newResult = new byte[k];
System.arraycopy(result, limit, newResult, 0, k);
@@ -247,17 +228,13 @@ public class RSA
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.
// "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();
}
throw new IllegalArgumentException();
// 2. Let c = m^e mod n.
final BigInteger e = K.getPublicExponent();
final BigInteger result = m.modPow(e, n);
@@ -268,16 +245,13 @@ public class RSA
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.
// "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();
}
throw new IllegalArgumentException();
// 2. The representative m is computed as follows.
BigInteger result;
if (!(K instanceof RSAPrivateCrtKey))
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();
@@ -303,38 +277,32 @@ public class RSA
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:
// 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.
// 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.
// 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.
// 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);
}
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>
*
* 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>.
*
* @return a random MPI whose length in bytes is between 32 and 64 inclusive.
*/
private static final BigInteger newR(final BigInteger N)
@@ -51,35 +51,29 @@ import java.security.interfaces.RSAPublicKey;
import java.util.Arrays;
/**
* <p>The RSA-PKCS1-V1.5 signature scheme is a digital signature scheme with
* 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>
* method.
* <p>
* References:
* <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://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>
*/
public class RSAPKCS1V1_5Signature extends BaseSignature
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.
*/
@@ -89,9 +83,9 @@ public class RSAPKCS1V1_5Signature extends BaseSignature
}
/**
* <p>Constructs an instance of this object using the designated message
* digest algorithm as its underlying hash function.</p>
*
* Constructs an instance of this object using the designated message digest
* algorithm as its underlying hash function.
*
* @param mdName the canonical name of the underlying hash function.
*/
public RSAPKCS1V1_5Signature(final String mdName)
@@ -117,14 +111,6 @@ public class RSAPKCS1V1_5Signature extends BaseSignature
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);
@@ -133,49 +119,46 @@ public class RSAPKCS1V1_5Signature extends BaseSignature
protected void setupForVerification(final PublicKey k)
throws IllegalArgumentException
{
if (!(k instanceof RSAPublicKey))
{
throw new 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();
}
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:
// 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).
// 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.
// 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).
// 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).
// 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).
// 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);
}
@@ -184,28 +167,24 @@ public class RSAPKCS1V1_5Signature extends BaseSignature
throws IllegalStateException
{
if (publicKey == null)
{
throw new IllegalStateException();
}
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.
// output "invalid signature" and stop.
final int modBits = ((RSAPublicKey) publicKey).getModulus().bitLength();
final int k = (modBits + 7) / 8;
if (S.length != k)
{
return false;
}
return false;
// 2. RSA verification:
// a. Convert the signature S to an integer signature representative
// s (see Section 4.2): s = OS2IP (S).
// 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.
// 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
{
@@ -215,10 +194,10 @@ public class RSAPKCS1V1_5Signature extends BaseSignature
{
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.
// 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
{
@@ -229,17 +208,17 @@ public class RSAPKCS1V1_5Signature extends BaseSignature
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.
// 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."
// If they are the same, output "valid signature"; otherwise, output
// "invalid signature."
return Arrays.equals(EM, EMp);
}
}

Some files were not shown because too many files have changed in this diff Show More