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:
@@ -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@;
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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> < p < 2<sup>L</sup></code>
|
||||
* for <code>512 <= L <= 1024</code> and <code>L</code> a multiple of
|
||||
* A prime modulus, where
|
||||
* <code>2<sup>L-1</sup> < p < 2<sup>L</sup></code> for
|
||||
* <code>512 <= L <= 1024</code> and <code>L</code> a multiple of
|
||||
* <code>64</code>.
|
||||
*/
|
||||
protected final BigInteger p;
|
||||
|
||||
/**
|
||||
* A prime divisor of <code>p - 1</code>, where <code>2<sup>159</sup> < q
|
||||
* A prime divisor of <code>p - 1</code>, where
|
||||
* <code>2<sup>159</sup> < q
|
||||
* < 2<sup>160</sup></code>.
|
||||
*/
|
||||
protected final BigInteger q;
|
||||
|
||||
/**
|
||||
* <code>g = h<sup>(p-1)</sup>/q mod p</code>, where <code>h</code> is any
|
||||
* integer with <code>1 < h < p - 1</code> such that <code>h<sup>
|
||||
* (p-1)</sup>/q mod p > 1</code> (<code>g</code> has order <code>q mod p
|
||||
* <code>g = h<sup>(p-1)</sup>/q mod p</code>, where <code>h</code> is
|
||||
* any integer with <code>1 < h < p - 1</code> such that <code>h<sup>
|
||||
* (p-1)</sup>/q mod p > 1</code> (<code>g</code>
|
||||
* has order <code>q mod p
|
||||
* </code>).
|
||||
*/
|
||||
protected final BigInteger g;
|
||||
|
||||
/**
|
||||
* Identifier of the default encoding format to use when externalizing the
|
||||
* key material.
|
||||
* 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 < x <
|
||||
* q</code>.</p>
|
||||
* A randomly or pseudorandomly generated integer with <code>0 < x <
|
||||
* 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> < q < 2<sup>160</sup></code></li>
|
||||
* <li><code>2<sup>L-1</sup> < p < 2<sup>L</sup></code> for a
|
||||
* specified <code>L</code>, where <code>L = 512 + 64j</code> for some
|
||||
* <code>0 <= j <= 8</code></li>
|
||||
* <li>q divides p - 1.</li>
|
||||
* <li><code>2<sup>159</sup> < q < 2<sup>160</sup></code></li>
|
||||
* <li><code>2<sup>L-1</sup> < p < 2<sup>L</sup></code> for a
|
||||
* specified <code>L</code>, where <code>L = 512 + 64j</code> for some
|
||||
* <code>0 <= j <= 8</code></li>
|
||||
* <li>q divides p - 1.</li>
|
||||
* </ul>
|
||||
*
|
||||
* The algorithm used to find these primes is as described in FIPS-186,
|
||||
* section 2.2: GENERATION OF PRIMES. This prime generation scheme starts by
|
||||
* using the {@link Sha160} and a user supplied <i>SEED</i>
|
||||
* to construct a prime, <code>q</code>, in the range 2<sup>159</sup> < q
|
||||
* < 2<sup>160</sup>. Once this is accomplished, the same <i>SEED</i>
|
||||
* value is used to construct an <code>X</code> in the range <code>2<sup>L-1
|
||||
* using the {@link Sha160} and a user supplied <i>SEED</i> to construct a
|
||||
* prime, <code>q</code>, in the range 2<sup>159</sup> < q < 2<sup>160</sup>.
|
||||
* Once this is accomplished, the same <i>SEED</i> value is used to construct
|
||||
* an <code>X</code> in the range <code>2<sup>L-1
|
||||
* </sup> < X < 2<sup>L</sup>. The prime, <code>p</code>, is then
|
||||
* formed by rounding <code>X</code> to a number congruent to <code>1 mod
|
||||
* 2q</code>. In this implementation we use the same <i>SEED</i> value given
|
||||
@@ -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 & al. states:
|
||||
* The visible methods of every signature-with-appendix scheme.
|
||||
* <p>
|
||||
* The Handbook of Applied Cryptography (HAC), by A. Menezes & al. states:
|
||||
* "Digital signature schemes which require the message as input to the
|
||||
* verification algorithm are called <i>digital signature schemes with
|
||||
* appendix</i>. ... They rely on cryptographic hash functions rather than
|
||||
* customised redundancy functions, and are less prone to existential forgery
|
||||
* attacks."</p>
|
||||
*
|
||||
* <p>References:</p>
|
||||
* 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> < p < 2<sup>L</sup>
|
||||
* </code> for <code>512 <= L <= 1024</code> and <code>L</code> a
|
||||
* multiple of <code>64</code>.</li>
|
||||
* <li>q: A prime divisor of <code>p - 1</code>, where <code>2<sup>159</sup>
|
||||
* <li>p: A prime modulus, where
|
||||
* <code>2<sup>L-1</sup> < p < 2<sup>L</sup> </code> for <code>512 <= L
|
||||
* <= 1024</code> and <code>L</code> a multiple of <code>64</code>.</li>
|
||||
* <li>q: A prime divisor of <code>p - 1</code>, where <code>2<sup>159</sup>
|
||||
* < q < 2<sup>160</sup></code>.</li>
|
||||
* <li>g: Where <code>g = h<sup>(p-1)</sup>/q mod p</code>, where
|
||||
* <code>h</code> is any integer with <code>1 < h < p - 1</code> such
|
||||
* that <code>h<sup> (p-1)</sup>/q mod p > 1</code> (<code>g</code> has order
|
||||
* <code>q mod p</code>).</li>
|
||||
* <li>x: A randomly or pseudorandomly generated integer with <code>0 < x
|
||||
* <li>g: Where <code>g = h<sup>(p-1)</sup>/q mod p</code>, where
|
||||
* <code>h</code> is any integer with <code>1 < h < p - 1</code> such
|
||||
* that <code>h<sup> (p-1)</sup>/q mod p > 1</code> (<code>g</code> has order
|
||||
* <code>q mod p</code>).</li>
|
||||
* <li>x: A randomly or pseudorandomly generated integer with <code>0 < x
|
||||
* < q</code>.</li>
|
||||
* <li>y: <code>y = g<sup>x</sup> mod p</code>.</li>
|
||||
* <li>k: A randomly or pseudorandomly generated integer with <code>0 < k
|
||||
* <li>y: <code>y = g<sup>x</sup> mod p</code>.</li>
|
||||
* <li>k: A randomly or pseudorandomly generated integer with <code>0 < k
|
||||
* < q</code>.</li>
|
||||
* </ol>
|
||||
*
|
||||
* <p>The integers <code>p</code>, <code>q</code>, and <code>g</code> can be
|
||||
* <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 < k-1 < q</code>. The value of <code>SHA(M)</code>
|
||||
* is a 160-bit string output by the Secure Hash Algorithm specified in FIPS 180.
|
||||
* For use in computing <code>s</code>, this string must be converted to an
|
||||
* integer.</p>
|
||||
*
|
||||
* <p>As an option, one may wish to check if <code>r == 0</code> or <code>s == 0
|
||||
* </code>. If either <code>r == 0</code> or <code>s == 0</code>, a new value
|
||||
* of <code>k</code> should be generated and the signature should be
|
||||
* recalculated (it is extremely unlikely that <code>r == 0</code> or <code>s ==
|
||||
* 0</code> if signatures are generated properly).</p>
|
||||
*
|
||||
* <p>The signature is transmitted along with the message to the verifier.</p>
|
||||
*
|
||||
* <p>References:</p>
|
||||
* <p>
|
||||
* In the above, <code>k<sup>-1</sup></code> is the multiplicative inverse of
|
||||
* <code>k</code>, <code>mod q</code>; i.e., <code>(k<sup>-1</sup> k) mod q =
|
||||
* 1</code> and <code>0 < k-1 < q</code>. The value of <code>SHA(M)</code>
|
||||
* is a 160-bit string output by the Secure Hash Algorithm specified in FIPS
|
||||
* 180. For use in computing <code>s</code>, this string must be converted to
|
||||
* an integer.
|
||||
* <p>
|
||||
* 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
Reference in New Issue
Block a user