You are viewing a plain text version of this content. The canonical link for it is here.
Posted to juice-svn@xml.apache.org by ra...@apache.org on 2006/01/13 18:12:16 UTC

svn commit: r368789 - /incubator/juice/java/src/org/apache/security/jce/SHA1withDSA.java

Author: raul
Date: Fri Jan 13 09:12:09 2006
New Revision: 368789

URL: http://svn.apache.org/viewcvs?rev=368789&view=rev
Log:
Initial version faked.

Added:
    incubator/juice/java/src/org/apache/security/jce/SHA1withDSA.java

Added: incubator/juice/java/src/org/apache/security/jce/SHA1withDSA.java
URL: http://svn.apache.org/viewcvs/incubator/juice/java/src/org/apache/security/jce/SHA1withDSA.java?rev=368789&view=auto
==============================================================================
--- incubator/juice/java/src/org/apache/security/jce/SHA1withDSA.java (added)
+++ incubator/juice/java/src/org/apache/security/jce/SHA1withDSA.java Fri Jan 13 09:12:09 2006
@@ -0,0 +1,226 @@
+/* 
+ * Copyright 2002-2004 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * imitations under the License.
+ */
+
+package org.apache.security.jce;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SignatureException;
+import java.security.SignatureSpi;
+import java.security.interfaces.DSAKey;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+
+import sun.security.util.DerOutputStream;
+import sun.security.util.DerValue;
+import sun.security.util.ObjectIdentifier;
+
+/**
+ * @author Walter Hoehn
+ * @author Noah Levitt
+ */
+public class SHA1withDSA extends SignatureSpi {
+
+	private static final int UNINITIALIZED = 0;
+	private static final int SIGN = 1;
+	private static final int VERIFY = 2;
+
+	private int initialization = UNINITIALIZED;
+
+	private MessageDigest digest;
+	private RSA cipher;
+
+	public SHA1withDSA() throws NoSuchAlgorithmException {
+
+		super();
+
+		digest = MessageDigest.getInstance("SHA-1", new org.apache.security.jce.Provider());
+		cipher = new org.apache.security.jce.RSA();
+
+		// Use this instead to get Cipher through the JCE interface... if we
+		// ever get a cert from Sun
+		//cipher = Cipher.getInstance("RSA/PKCS1PADDING");
+	}
+
+	protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
+
+		if (!(privateKey instanceof RSAPrivateKey)) {
+			throw new InvalidKeyException("Supplied key is not an RSA private key.");
+		}
+
+		initialization = SIGN;
+		cipher.engineInit(Cipher.ENCRYPT_MODE, privateKey, null);
+		digest.reset();
+	}
+
+	protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
+
+		if (!(publicKey instanceof RSAPublicKey)) {
+			throw new InvalidKeyException("Supplied key is not an RSA public key.");
+		}
+
+		initialization = VERIFY;
+		cipher.engineInit(Cipher.DECRYPT_MODE, publicKey, null);
+		digest.reset();
+	}
+
+	protected byte[] engineSign() throws SignatureException {
+
+		if (initialization != SIGN) {
+			throw new SignatureException("Signature engine not initialized for signing.");
+		}
+
+		byte[] hash = digest.digest();
+
+		try {
+
+			//Format the hash in DER
+			DerOutputStream derOutStream = new DerOutputStream();
+			derOutStream.putNull();
+
+			DerOutputStream middle = new DerOutputStream();
+			middle.write(DerValue.tag_Sequence, derOutStream);
+			middle.putOctetString(hash);
+
+			DerOutputStream outer = new DerOutputStream();
+			outer.write(DerValue.tag_Sequence, middle);
+
+			byte[] bytes = outer.toByteArray();
+
+			//Encrypt the DER
+			return cipher.engineDoFinal(bytes, 0, bytes.length);
+	
+		} catch (IOException e) {
+			throw new SignatureException(e.toString());
+		} catch (IllegalBlockSizeException e) {
+			throw new SignatureException(e.toString());
+		}
+	}
+
+	protected boolean engineVerify(byte[] signature) throws SignatureException {
+
+		if (initialization != VERIFY) {
+			throw new SignatureException("Signature engine not initialized for verification.");
+		}
+
+		//Get a hash of the input data
+		byte[] myHash = digest.digest();
+
+		byte[] decryptedSignature;
+		byte[] hashFromSignature;
+
+		try {
+			//Decrypt the signature
+			decryptedSignature = cipher.engineDoFinal(signature, 0, signature.length);
+
+			//Parse the DER to get the relevant data
+			DerValue outer = new DerValue(decryptedSignature);
+			if (outer.tag != DerValue.tag_Sequence) {
+				throw new SignatureException("Incorrect DER encoding of hash.");
+			}
+
+			if (outer.data.available() == 0) {
+				throw new SignatureException("Incorrect DER encoding of hash.");
+			}
+			DerValue middleSequence = outer.data.getDerValue();
+
+			if (outer.data.available() == 0) {
+				throw new SignatureException("Incorrect DER encoding of hash.");
+			}
+
+			if (middleSequence.tag != DerValue.tag_Sequence) {
+				throw new SignatureException("Incorrect DER encoding of hash.");
+			}
+
+			if (middleSequence.data.available() == 0) {
+				throw new SignatureException("Incorrect DER encoding of hash.");
+			}
+			DerValue algorithm = middleSequence.data.getDerValue();
+			if (algorithm.tag != DerValue.tag_ObjectId) {
+				throw new SignatureException("Incorrect DER encoding of hash.");
+			}
+
+
+
+			//Pull out the stored hash from the signature
+			DerValue storedHash = outer.data.getDerValue();
+			if (storedHash.tag != DerValue.tag_OctetString) {
+				throw new SignatureException("Incorrect DER encoding of hash.");
+			}
+			hashFromSignature = storedHash.getOctetString();
+
+		} catch (IOException e) {
+			throw new SignatureException(e.toString());
+		} catch (IllegalBlockSizeException e) {
+			throw new SignatureException(e.toString());
+		}
+
+		//OK, finally... do the actual compare
+		return Arrays.equals(myHash, hashFromSignature);
+
+	}
+
+	protected void engineUpdate(byte input) {
+		digest.update(input);
+	}
+
+	protected void engineUpdate(byte[] input, int offset, int len) {
+		digest.update(input, offset, len);
+	}
+
+	/**
+	 * @deprecated
+	 */
+	protected void engineSetParameter(String param, Object value) {
+		throw new UnsupportedOperationException("engineSetParameter unsupported");
+	}
+
+	/**
+	 * @deprecated
+	 */
+	protected Object engineGetParameter(String param) {
+		throw new UnsupportedOperationException("engineSetParameter unsupported");		
+	}
+	class PointerToInt {
+		int holder;
+		public void setPtr(int i) {
+			holder=i;
+		}
+		public int getPtr(int i) {
+			return i;
+		}
+	};
+	private native long  DSA_new();
+	private native int DSA_size(/*DSA **/long dsa);
+	private native void   DSA_free(/*DSA **/long dsa);
+	private native long /*BIGNUM **/BN_bin2bn(byte []s);
+	private native long /*BN_CTX **/BN_CTX_new();
+	private native long BN_CTX_free(/*BN_CTX **/long ctx);
+	private native int    DSA_sign(int dummy, byte[] dgst, int len,
+	                      byte []sigret, /*int **/ PointerToInt siglen, /*DSA **/ long dsa);
+	private native int    DSA_verify(int dummy, byte dgst[], int len,
+	                       byte [] sigbuf, int siglen, /*DSA **/long dsa);
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: juice-svn-unsubscribe@xml.apache.org
For additional commands, e-mail: juice-svn-help@xml.apache.org