/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* The Digital Signature Standard (using the Digital Signature
* Algorithm), as described in fips186 of the National Instute of
* Standards and Technology (NIST), using fips180-1 (SHA-1).
*
* This file contains both the signature implementation for the
* commonly used SHA1withDSA (DSS) as well as RawDSA, used by TLS
* among others. RawDSA expects the 20 byte SHA-1 digest as input
* via update rather than the original data like other signature
* implementations.
*
* @author Benjamin Renaud
*
* @since 1.1
*
* @see DSAPublicKey
* @see DSAPrivateKey
*/
/* Are we debugging? */
private static final boolean debug = false;
/* The parameter object */
/* algorithm parameters */
/* The public key, if any */
/* The private key, if any */
/* The random seed used to generate k */
private int[] Kseed;
/* The random seed used to generate k (specified by application) */
private byte[] KseedAsByteArray;
/*
* The random seed used to generate k
* (prevent the same Kseed from being used twice in a row
*/
private int[] previousKseed;
/* The RNG used to output a seed for generating k */
/**
* Construct a blank DSA object. It must be
* initialized before being usable for signing or verifying.
*/
DSA() {
super();
}
/**
* Return the 20 byte hash value and reset the digest.
*/
/**
* Reset the digest.
*/
abstract void resetDigest();
/**
* Standard SHA1withDSA implementation.
*/
/* The SHA hash for the data */
}
/**
* Update a byte to be signed or verified.
*/
protected void engineUpdate(byte b) {
}
/**
* Update an array of bytes to be signed or verified.
*/
}
}
byte[] getDigest() {
}
void resetDigest() {
}
}
/**
* RawDSA implementation.
*
* RawDSA requires the data to be exactly 20 bytes long. If it is
* not, a SignatureException is thrown when sign()/verify() is called
* per JCA spec.
*/
// length of the SHA-1 digest (20 bytes)
// 20 byte digest buffer
private final byte[] digestBuffer;
// offset into the buffer
private int ofs;
public RawDSA() {
digestBuffer = new byte[SHA1_LEN];
}
protected void engineUpdate(byte b) {
return;
}
digestBuffer[ofs++] = b;
}
return;
}
}
throw new SignatureException
("Data for RawDSA must be exactly 20 bytes long");
}
ofs = 0;
return digestBuffer;
}
void resetDigest() {
ofs = 0;
}
}
/**
* Initialize the DSA object with a DSA private key.
*
* @param privateKey the DSA private key
*
* @exception InvalidKeyException if the key is not a valid DSA private
* key.
*/
throws InvalidKeyException {
throw new InvalidKeyException("not a DSA private key: " +
}
}
/**
* Initialize the DSA object with a DSA public key.
*
* @param publicKey the DSA public key.
*
* @exception InvalidKeyException if the key is not a valid DSA public
* key.
*/
throws InvalidKeyException {
throw new InvalidKeyException("not a DSA public key: " +
}
}
resetDigest();
}
/**
* Sign all the data thus far updated. The signature is formatted
* according to the Canonical Encoding Rules, returned as a DER
* sequence of Integer, r and s.
*
* @return a signature block formatted according to the Canonical
* Encoding Rules.
*
* @exception SignatureException if the signature object was not
* properly initialized, or if another exception occurs.
*
* @see sun.security.DSA#engineUpdate
* @see sun.security.DSA#engineVerify
*/
try {
outseq.putInteger(r);
outseq.putInteger(s);
outseq.toByteArray());
return result.toByteArray();
} catch (IOException e) {
throw new SignatureException("error encoding signature");
}
}
/**
* Verify all the data thus far updated.
*
* @param signature the alledged signature, encoded using the
* Canonical Encoding Rules, as a sequence of integers, r and s.
*
* @exception SignatureException if the signature object was not
* properly initialized, or if another exception occurs.
*
* @see sun.security.DSA#engineUpdate
* @see sun.security.DSA#engineSign
*/
throws SignatureException {
}
/**
* Verify all the data thus far updated.
*
* @param signature the alledged signature, encoded using the
* Canonical Encoding Rules, as a sequence of integers, r and s.
*
* @param offset the offset to start from in the array of bytes.
*
* @param length the number of bytes to use, starting at offset.
*
* @exception SignatureException if the signature object was not
* properly initialized, or if another exception occurs.
*
* @see sun.security.DSA#engineUpdate
* @see sun.security.DSA#engineSign
*/
throws SignatureException {
BigInteger r = null;
BigInteger s = null;
// first decode the signature.
try {
} catch (IOException e) {
throw new SignatureException("invalid encoding for signature");
}
// some implementations do not correctly encode values in the ASN.1
// 2's complement format. force r and s to be positive in order to
// to validate those signatures
if (r.signum() < 0) {
}
if (s.signum() < 0) {
}
return v.equals(r);
} else {
throw new SignatureException("invalid signature: out of range values");
}
}
BigInteger k) {
}
BigInteger s = x.multiply(r);
return s.remainder(q);
}
BigInteger g, BigInteger s) {
return s.modInverse(q);
}
throws SignatureException {
}
/*
* Please read bug report 4044247 for an alternative, faster,
* NON-FIPS approved method to generate K
*/
BigInteger k = null;
// The application specified a Kseed for us to use.
// Note that we do not allow usage of the same Kseed twice in a row
return k;
}
}
// The application did not specify a Kseed for us to use.
// We'll generate a new Kseed by getting random bytes from
// a SecureRandom object.
while (true) {
int[] seed = new int[5];
for (int i = 0; i < 5; i++)
return k;
}
}
}
// Use the application-specified SecureRandom Object if provided.
// Otherwise, use our default SecureRandom Object.
if (signingRandom == null) {
} else {
}
}
return signingRandom;
}
/**
* Compute k for a DSA signature.
*
* @param seed the seed for generating k. This seed should be
* secure. This is what is refered to as the KSEED in the DSA
* specification.
*
* @param g the g parameter from the DSA key pair.
*/
// check out t in the spec.
int[] t = { 0xEFCDAB89, 0x98BADCFE, 0x10325476,
0xC3D2E1F0, 0x67452301 };
//
int k = tmp[i];
for (int j = 0; j < 4; j++) {
}
}
return k;
}
// Constants for each round
/**
* Computes set 1 thru 7 of SHA-1 on m1. */
int[] W = new int[80];
int temp = 0;
for (int t = 16; t <= 79; t++){
}
int a = h[0],b = h[1],c = h[2], d = h[3], e = h[4];
for (int i = 0; i < 20; i++) {
((b&c)|((~b)&d))+ e + W[i] + round1_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
// Round 2
for (int i = 20; i < 40; i++) {
(b ^ c ^ d) + e + W[i] + round2_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
// Round 3
for (int i = 40; i < 60; i++) {
((b&c)|(b&d)|(c&d)) + e + W[i] + round3_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
// Round 4
for (int i = 60; i < 80; i++) {
(b ^ c ^ d) + e + W[i] + round4_kt;
e = d;
d = c;
c = ((b<<30) | (b>>>(32-30)));
b = a;
a = temp;
}
int[] md = new int[5];
return md;
}
/**
* This implementation recognizes the following parameter:<dl>
*
* <dt><tt>Kseed</tt>
*
* <dd>a byte array.
*
* </dl>
*
* @deprecated
*/
if (param instanceof byte[]) {
KseedAsByteArray = (byte[])param;
} else {
throw new InvalidParameterException("Kseed not a byte array");
}
} else {
throw new InvalidParameterException("invalid parameter");
}
}
/**
* Return the value of the requested parameter. Recognized
* parameters are:
*
* <dl>
*
* <dt><tt>Kseed</tt>
*
* <dd>a byte array.
*
* </dl>
*
* @return the value of the requested parameter.
*
* @see java.security.SignatureEngine
*
* @deprecated
*/
return KseedAsByteArray;
} else {
return null;
}
}
/**
* Set the algorithm object.
*/
throw new InvalidKeyException("DSA public key lacks parameters");
}
}
/**
* Return a human readable rendition of the engine.
*/
} else {
printable += "\n\t P, Q or G not initialized.";
}
}
printable += "\n\tUNINIIALIZED";
}
return printable;
}
/*
* Utility routine for converting a byte array into an int array
*/
int j = 0;
byte[] newBA;
// guarantee that the incoming byteArray is a multiple of 4
// (pad with 0's)
switch (mod) {
}
// copy each set of 4 bytes in the byte array into an integer
j++;
}
return newSeed;
}
if (debug) {
e.printStackTrace();
}
}
if (debug) {
}
}
}