Author: jflesch
Date: 2007-07-27 18:14:06 +0000 (Fri, 27 Jul 2007)
New Revision: 14395
Added:
trunk/apps/Thaw/src/frost/crypt/
trunk/apps/Thaw/src/frost/crypt/FrostCrypt.java
Modified:
trunk/apps/Thaw/src/thaw/core/MainWindow.java
trunk/apps/Thaw/src/thaw/fcp/SHA256Computer.java
trunk/apps/Thaw/src/thaw/i18n/thaw.properties
trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties
trunk/apps/Thaw/src/thaw/plugins/index/Comment.java
trunk/apps/Thaw/src/thaw/plugins/index/DatabaseManager.java
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKMessageParser.java
trunk/apps/Thaw/src/thaw/plugins/signatures/DatabaseManager.java
trunk/apps/Thaw/src/thaw/plugins/signatures/Identity.java
Log:
Replacing DSA (from freenet source code) by RSA (from frost source code and
bouncycastle)
Added: trunk/apps/Thaw/src/frost/crypt/FrostCrypt.java
===================================================================
--- trunk/apps/Thaw/src/frost/crypt/FrostCrypt.java
(rev 0)
+++ trunk/apps/Thaw/src/frost/crypt/FrostCrypt.java 2007-07-27 18:14:06 UTC
(rev 14395)
@@ -0,0 +1,596 @@
+/*
+ FrostCrypt.java / Frost
+ Copyright (C) 2003 Frost Project <jtcfrost.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of
+ the License, or (at your option) any later version.
+
+ This program 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 this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+package frost.crypt;
+
+import java.io.*;
+import java.math.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.security.*;
+import java.security.spec.*;
+import java.util.*;
+import java.util.logging.*;
+
+import javax.crypto.*;
+import javax.crypto.spec.*;
+
+import org.bouncycastle.crypto.*;
+import org.bouncycastle.crypto.digests.*;
+import org.bouncycastle.crypto.engines.*;
+import org.bouncycastle.crypto.generators.*;
+import org.bouncycastle.crypto.params.*;
+import org.bouncycastle.crypto.signers.*;
+import org.bouncycastle.jce.provider.*;
+import org.bouncycastle.util.encoders.*;
+
+/**
+ * Implementation of the crypto layer.
+ */
+public final class FrostCrypt {
+
+ private static final Logger logger =
Logger.getLogger(FrostCrypt.class.getName());
+
+ private PSSSigner signer;
+ private SecureRandom secureRandom = null;
+
+ private KeyGenerator keyGeneratorAES = null;
+
+ public FrostCrypt() {
+ Security.addProvider(new BouncyCastleProvider());
+
+ signer = new PSSSigner(new RSAEngine(), new SHA1Digest(), 16);
+ try {
+ secureRandom = SecureRandom.getInstance("SHA1PRNG");
+ } catch (NoSuchAlgorithmException e) {
+ secureRandom = new SecureRandom();
+ }
+ }
+
+ /**
+ * Generate a new RSA 1024 bit key pair.
+ * @returns String[0] is private key; String[1] is public key
+ */
+ public synchronized String[] generateKeys() {
+
+ RSAKeyPairGenerator keygen = new RSAKeyPairGenerator();
+ keygen.init(
+ new RSAKeyGenerationParameters(
+ new
BigInteger("3490529510847650949147849619903898133417764638493387843990820577"),
+ getSecureRandom(),
+ 1024,
+ 80));
+ //this big integer is the winner of some competition as far as I
remember
+
+ AsymmetricCipherKeyPair keys = keygen.generateKeyPair();
+
+ //extract the keys
+ RSAKeyParameters pubKey = (RSAKeyParameters) keys.getPublic();
+ RSAPrivateCrtKeyParameters privKey = (RSAPrivateCrtKeyParameters)
keys.getPrivate();
+
+ //the return value
+ String[] result = new String[2];
+ StringBuilder temp = new StringBuilder();
+
+ //create the keys
+ temp.append( new
String(Base64.encode(pubKey.getExponent().toByteArray())));
+ temp.append(":");
+ temp.append(new
String(Base64.encode(pubKey.getModulus().toByteArray())));
+ result[1] = temp.toString(); // public key
+
+ //rince and repeat, this time exactly the way its done in the
constructor
+ temp = new StringBuilder();
+ temp.append(new
String(Base64.encode(privKey.getModulus().toByteArray())));
+ temp.append(":");
+ temp.append(new
String(Base64.encode(privKey.getPublicExponent().toByteArray())));
+ temp.append(":");
+ temp.append(new
String(Base64.encode(privKey.getExponent().toByteArray())));
+ temp.append(":");
+ temp.append(new String(Base64.encode(privKey.getP().toByteArray())));
+ temp.append(":");
+ temp.append(new String(Base64.encode(privKey.getQ().toByteArray())));
+ temp.append(":");
+ temp.append(new String(Base64.encode(privKey.getDP().toByteArray())));
+ temp.append(":");
+ temp.append(new String(Base64.encode(privKey.getDQ().toByteArray())));
+ temp.append(":");
+ temp.append(new
String(Base64.encode(privKey.getQInv().toByteArray())));
+ result[0] = temp.toString(); // private key
+
+ return result;
+ }
+
+ /**
+ * Computes the SHA-1 checksum of given message.
+ */
+ public synchronized String digest(String message) {
+ try {
+ SHA1Digest stomach = new SHA1Digest();
+ stomach.reset();
+ byte[] food = message.getBytes("UTF-8");
+ stomach.update(food, 0, food.length);
+ byte[] poop = new byte[64];
+ stomach.doFinal(poop, 0);
+ return (new String(Base64.encode(poop))).substring(0, 27);
+ } catch(UnsupportedEncodingException ex) {
+ logger.log(Level.SEVERE, "UTF-8 encoding is not supported.", ex);
+ }
+ return null;
+ }
+
+ /**
+ * Computes the SHA-1 checksum of given file.
+ */
+ public synchronized String digest(File file) {
+ SHA1Digest stomach = new SHA1Digest();
+ byte[] poop = new byte[64];
+ FileChannel chan = null;
+ try {
+ chan = (new FileInputStream(file)).getChannel();
+ } catch (IOException e) {
+ logger.log(Level.SEVERE, "Exception thrown in digest(File file)",
e);
+ }
+ byte[] temp = new byte[4 * 1024];
+ ByteBuffer _temp = ByteBuffer.wrap(temp);
+ try {
+ while (true) {
+ //if (y >= file.length()) break;
+ //if (y > file.length()) y = file.length();
+ int pos = _temp.position();
+ int read = chan.read(_temp);
+ if (read == -1)
+ break;
+ stomach.update(temp, pos, read);
+ if (_temp.remaining() == 0)
+ _temp.position(0);
+ }
+ chan.close();
+ } catch (IOException e) {
+ logger.log(Level.SEVERE, "Exception thrown in digest(File file)",
e);
+ }
+ stomach.doFinal(poop, 0);
+ return (new String(Base64.encode(poop))).substring(0, 27);
+ }
+
+ public synchronized String encrypt(String what, String publicKey) {
+ try {
+ byte[] whatBytes = what.getBytes("UTF-8");
+ byte[] encryptedBytes = encrypt(whatBytes, publicKey);
+ String result = new String(Base64.encode(encryptedBytes),
"ISO-8859-1");
+ return result;
+ } catch(UnsupportedEncodingException ex) {
+ logger.log(Level.SEVERE, "UTF-8 encoding is not supported.", ex);
+ }
+ return null;
+ }
+
+ /**
+ * Encryption of a byte array.
+ *
+ * We generate a new 128bit AES key and encrypt the content with this key.
+ * Then we RSA encrypt the key with publicKey. RSA ecpects 117 bytes of
input
+ * and generates 128byte of output. So we prepare a byte array of length
117 with
+ * random data and copy the AES key into the front of it. Then we RSA
encrypt this
+ * array and put the result array of 128bytes length into the front of the
AES encrypted
+ * data.
+ *
+ * @returns null if anything failed.
+ */
+ public synchronized byte[] encrypt(byte[] what, String publicKey) {
+
+ byte[] aesKeyBytes = null;
+ Cipher cipherAES = null;
+ Cipher cipherRSA = null;
+
+ int cipherRSAinSize = 0;
+ int cipherRSAoutSize = 0;
+
+ // prepare AES, we need cipherAES and keyBytes
+ aesKeyBytes = generateAESSessionKey(); // 16 bytes
+ if( aesKeyBytes == null ) {
+ return null;
+ }
+ cipherAES = buildCipherAES(Cipher.ENCRYPT_MODE, aesKeyBytes);;
+ if( cipherAES == null ) {
+ return null;
+ }
+
+ // prepare RSA, we only need chiperRSA
+ try {
+ StringTokenizer keycutter = new StringTokenizer(publicKey, ":");
+ BigInteger Exponent = new
BigInteger(Base64.decode(keycutter.nextToken()));
+ BigInteger Modulus = new
BigInteger(Base64.decode(keycutter.nextToken()));
+ RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(Modulus,
Exponent);
+
+ KeyFactory fact = KeyFactory.getInstance("RSA", "BC");
+ PublicKey pubKey = fact.generatePublic(pubKeySpec);
+ cipherRSA = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
+ cipherRSA.init(Cipher.ENCRYPT_MODE, pubKey);
+ cipherRSAinSize = cipherRSA.getBlockSize();
+ cipherRSAoutSize = cipherRSA.getOutputSize(cipherRSAinSize);
+ if( cipherRSAinSize != 117 || cipherRSAoutSize != 128 ) {
+ throw new Exception("block size invalid,
inSize="+cipherRSAinSize+"; outSize="+cipherRSAoutSize);
+ }
+ } catch(Throwable t) {
+ logger.log(Level.SEVERE, "Error in encrypt, RSA preparation", t);
+ return null;
+ }
+
+ // encrypt keybytes with RSA
+ byte rsaEncData[] = null;
+ try {
+ byte[] rsaInpData = new byte[cipherRSAinSize]; // input for RSA
encryption
+ // build 128 byte, first 16 byte the AES session key, remaining
bytes are random data
+ byte[] randomBytes = new byte[cipherRSAinSize -
aesKeyBytes.length];
+ getSecureRandom().nextBytes(randomBytes);
+
+ System.arraycopy(aesKeyBytes, 0, rsaInpData, 0,
aesKeyBytes.length);
+ System.arraycopy(randomBytes, 0, rsaInpData, aesKeyBytes.length,
randomBytes.length);
+
+ rsaEncData = cipherRSA.doFinal(rsaInpData, 0, rsaInpData.length);
+ if( rsaEncData.length != cipherRSAoutSize ) {
+ throw new Exception("RSA out block size invalid:
"+rsaEncData.length);
+ }
+ } catch (Throwable t) {
+ logger.log(Level.SEVERE, "Error in encrypt, RSA encryption", t);
+ return null;
+ }
+
+ // encrypt content using AES
+
+ ByteArrayOutputStream plainOut = new ByteArrayOutputStream(what.length
+ (what.length/10) +rsaEncData.length);
+ try {
+ // write RSA encrypted data
+ plainOut.write(rsaEncData);
+
+ // encrypt
+ CipherOutputStream cOut = new CipherOutputStream(plainOut,
cipherAES);
+ cOut.write(what);
+
+ cOut.close();
+ } catch (IOException e) {
+ logger.log(Level.SEVERE, "Error in encrypt, AES encryption", e);
+ return null;
+ }
+ return plainOut.toByteArray();
+ }
+
+ public synchronized String decrypt(String what, String privateKey) {
+ try {
+ byte[] encBytes = Base64.decode(what.getBytes("ISO-8859-1"));
+ byte[] decBytes = decrypt(encBytes, privateKey);
+ return new String(decBytes, "UTF-8");
+ } catch(UnsupportedEncodingException ex) {
+ logger.log(Level.SEVERE, "UTF-8 encoding is not supported.", ex);
+ }
+ return null;
+ }
+
+ /**
+ * Decrypts a byte array.
+ *
+ * The first 128 byte in array must be the RSA encrypted AES key,
+ * remaining data is the AES data. See encrypt().
+ */
+ public synchronized byte[] decrypt(byte[] what, String privateKey) {
+
+ Cipher cipherAES = null;
+ Cipher cipherRSA = null;
+
+ int cipherRSAinSize = 0;
+ int cipherRSAoutSize = 0;
+
+ // prepare RSA, we need chiperRSA
+ try {
+ StringTokenizer keycutter = new StringTokenizer(privateKey, ":");
+ RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec(
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())));
+
+ KeyFactory fact = KeyFactory.getInstance("RSA", "BC");
+ PrivateKey privKey = fact.generatePrivate(privKeySpec);
+ cipherRSA = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
+ cipherRSA.init(Cipher.DECRYPT_MODE, privKey);
+ cipherRSAinSize = cipherRSA.getBlockSize();
+ cipherRSAoutSize = cipherRSA.getOutputSize(cipherRSAinSize);
+ if( cipherRSAinSize != 128 || cipherRSAoutSize != 117 ) {
+ throw new Exception("RSA decryption block size invalid,
inSize="+cipherRSAinSize+"; outSize="+cipherRSAoutSize);
+ }
+ } catch(Throwable e) {
+ logger.log(Level.SEVERE, "Error in decrypt, RSA preparation", e);
+ return null;
+ }
+
+ // decrypt rsa and get aes key
+ byte[] aesKeyBytes = null;
+ try {
+ byte[] sessionKeyBytes = cipherRSA.doFinal(what, 0,
cipherRSAinSize);
+ if( sessionKeyBytes == null ) {
+ throw new Exception("RSA decryption failed, sessionKeyBytes =
null");
+ }
+ if( sessionKeyBytes.length != cipherRSAoutSize ) {
+ throw new Exception("RSA decryption failed,
sessionKeyBytes.length = "+sessionKeyBytes.length+
+ ", must be "+cipherRSAoutSize);
+ }
+ // we need the first 16 byte
+ aesKeyBytes = new byte[16];
+ System.arraycopy(sessionKeyBytes, 0, aesKeyBytes, 0,
aesKeyBytes.length);
+ } catch (Throwable e) {
+ logger.log(Level.SEVERE, "Error in decrypt, RSA decryption", e);
+ return null;
+ }
+
+ // prepare AES, we need cipherAES
+ cipherAES = buildCipherAES(Cipher.DECRYPT_MODE, aesKeyBytes);;
+ if( cipherAES == null ) {
+ return null;
+ }
+
+ // decrypt aes
+ ByteArrayOutputStream plainOut = new ByteArrayOutputStream(what.length
- cipherRSAinSize);
+
+ ByteArrayInputStream bIn = new ByteArrayInputStream(what,
cipherRSAinSize, what.length-cipherRSAinSize);
+ CipherInputStream cIn = new CipherInputStream(bIn, cipherAES);
+
+ try {
+ byte[] buf = new byte[1024];
+ while(true) {
+ int bLen = cIn.read(buf);
+ if( bLen < 0 ) {
+ break; // eof
+ }
+ plainOut.write(buf, 0, bLen);
+ }
+ cIn.close();
+ } catch (Throwable e) {
+ logger.log(Level.SEVERE, "Error in decrypt, AES decryption", e);
+ return null;
+ }
+ return plainOut.toByteArray();
+ }
+
+ public synchronized String detachedSign(String message, String key){
+ try {
+ byte[] msgBytes = message.getBytes("UTF-8");
+ return detachedSign(msgBytes, key);
+ } catch(UnsupportedEncodingException ex) {
+ logger.log(Level.SEVERE, "UTF-8 encoding is not supported.", ex);
+ }
+ return null;
+ }
+ public synchronized String detachedSign(byte[] message, String key) {
+
+ StringTokenizer keycutter = new StringTokenizer(key, ":");
+ RSAPrivateCrtKeyParameters privKey =
+ new RSAPrivateCrtKeyParameters(
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())),
+ new BigInteger(Base64.decode(keycutter.nextToken())));
+
+ signer.init(true, privKey);
+ signer.update(message, 0, message.length);
+
+ byte[] signature = null;
+ try {
+ signature = signer.generateSignature();
+ } catch (CryptoException e) {
+ logger.log(Level.SEVERE, "Exception thrown in detachedSign(String
message, String key)", e);
+ }
+ signer.reset();
+ try {
+ String result = new String(Base64.encode(signature), "ISO-8859-1");
+ return result;
+ } catch(UnsupportedEncodingException ex) {
+ logger.log(Level.SEVERE, "ISO-8859-1 encoding is not supported.",
ex);
+ }
+ return null;
+ }
+
+ public synchronized boolean detachedVerify(String message, String key,
String sig){
+ try {
+ byte[] msgBytes = message.getBytes("UTF-8");
+ return detachedVerify(msgBytes, key, sig);
+ } catch(UnsupportedEncodingException ex) {
+ logger.log(Level.SEVERE, "UTF-8 encoding is not supported.", ex);
+ }
+ return false;
+ }
+ public synchronized boolean detachedVerify(byte[] message, String key,
String _sig) {
+ try {
+ byte[] sig = Base64.decode(_sig.getBytes("ISO-8859-1"));
+
+ StringTokenizer keycutter = new StringTokenizer(key, ":");
+ BigInteger Exponent = new
BigInteger(Base64.decode(keycutter.nextToken()));
+ BigInteger Modulus = new
BigInteger(Base64.decode(keycutter.nextToken()));
+
+ signer.init(false, new RSAKeyParameters(true, Modulus, Exponent));
+
+ signer.update(message, 0, message.length);
+ boolean result = signer.verifySignature(sig);
+ signer.reset();
+ return result;
+ } catch(UnsupportedEncodingException ex) {
+ logger.log(Level.SEVERE, "ISO-8859-1 encoding is not supported.",
ex);
+ }
+ return false;
+ }
+
+ public synchronized SecureRandom getSecureRandom() {
+ return secureRandom;
+ }
+
+ public String decode64(String what) {
+ try {
+ byte[] whatBytes = what.getBytes("ISO-8859-1");
+ return new String(Base64.decode(whatBytes), "UTF-8");
+ } catch(UnsupportedEncodingException ex) {
+ logger.log(Level.SEVERE, "UTF-8 or ISO-8859-1 encoding is not
supported.", ex);
+ }
+ return null;
+ }
+
+ public String encode64(String what) {
+ try {
+ byte[] whatBytes = what.getBytes("UTF-8");
+ return new String(Base64.encode(whatBytes), "ISO-8859-1");
+ } catch(UnsupportedEncodingException ex) {
+ logger.log(Level.SEVERE, "UTF-8 or ISO-8859-1 encoding is not
supported.", ex);
+ }
+ return null;
+ }
+
+ /**
+ * Called by encrypt() to generate a new random session key for AES.
+ * Must be called synchronized (we use a global object)!
+ * Currently only called by synchronized encrypt().
+ *
+ * @return the new session key or null.
+ */
+ private byte[] generateAESSessionKey() {
+ if( keyGeneratorAES == null ) {
+ try {
+ keyGeneratorAES = KeyGenerator.getInstance("AES");
+ } catch (NoSuchAlgorithmException e) {
+ logger.log(Level.SEVERE, "Could not get a KeyGenerator for
AES.", e);
+ return null;
+ }
+ keyGeneratorAES.init(128); // 192 and 256 bits may not be
available!
+ }
+ SecretKey skey = keyGeneratorAES.generateKey();
+ byte[] keyBytes = skey.getEncoded(); // 16 bytes
+ return keyBytes;
+ }
+
+ /**
+ * Builds and returns a new Cipher for AES.
+ */
+ private Cipher buildCipherAES(int mode, byte[] aesKey) {
+ Cipher cipherAES = null;
+ try {
+ if( aesKey == null ) {
+ return null;
+ }
+ SecretKeySpec sessionKey = new SecretKeySpec(aesKey, "AES");
+ cipherAES = Cipher.getInstance("AES", "BC");
+ cipherAES.init(mode, sessionKey);
+
+ } catch(Throwable t) {
+ logger.log(Level.SEVERE, "Error in AES preparation", t);
+ return null;
+ }
+ return cipherAES;
+ }
+
+ /**
+ * Computes the SHA256 checksum of utf-8 string.
+ */
+ public String computeChecksumSHA256(String message) {
+ try {
+ byte[] food = message.getBytes("UTF-8");
+ return computeChecksumSHA256(food);
+ } catch(UnsupportedEncodingException ex) {
+ logger.log(Level.SEVERE, "UTF-8 encoding is not supported.", ex);
+ }
+ return null;
+ }
+
+ /**
+ * Computes the SHA256 checksum of bytes.
+ */
+ public String computeChecksumSHA256(byte[] message) {
+ try {
+ byte[] food = message;
+
+ MessageDigest sha256 = MessageDigest.getInstance("SHA256", "BC");
+ sha256.update(food);
+ byte[] poop = sha256.digest();
+
+ StringBuilder sb = new StringBuilder();
+ for (int i=0; i < poop.length; i++) {
+ sb.append(Integer.toString( ( poop[i] & 0xff ) + 0x100 ,
16).substring(1));
+ }
+ return sb.toString().toUpperCase();
+ } catch (NoSuchAlgorithmException ex) {
+ logger.log(Level.SEVERE, "Algorithm SHA256 not supported.", ex);
+ } catch (NoSuchProviderException ex) {
+ logger.log(Level.SEVERE, "Provider BC not supported.", ex);
+ }
+ return null;
+ }
+
+ /**
+ * Computes the SHA256 checksum of a file.
+ */
+ public String computeChecksumSHA256(File file) {
+ try {
+ FileChannel chan = null;
+ try {
+ chan = (new FileInputStream(file)).getChannel();
+ } catch (Throwable e) {
+ logger.log(Level.SEVERE, "Exception thrown 1", e);
+ return null;
+ }
+
+ MessageDigest sha256 = MessageDigest.getInstance("SHA256", "BC");
+
+ byte[] temp = new byte[4 * 1024];
+ ByteBuffer _temp = ByteBuffer.wrap(temp);
+ try {
+ while (true) {
+ //if (y >= file.length()) break;
+ //if (y > file.length()) y = file.length();
+ int pos = _temp.position();
+ int read = chan.read(_temp);
+ if (read == -1)
+ break;
+ sha256.update(temp, pos, read);
+ if (_temp.remaining() == 0)
+ _temp.position(0);
+ }
+ chan.close();
+ } catch (Throwable e) {
+ logger.log(Level.SEVERE, "Exception thrown 2", e);
+ }
+
+ byte[] poop = sha256.digest();
+
+ StringBuilder sb = new StringBuilder();
+ for (int i=0; i < poop.length; i++) {
+ sb.append(Integer.toString( ( poop[i] & 0xff ) + 0x100 ,
16).substring(1));
+ }
+ return sb.toString().toUpperCase();
+
+ } catch (NoSuchAlgorithmException ex) {
+ logger.log(Level.SEVERE, "Algorithm SHA256 not supported.", ex);
+ } catch (NoSuchProviderException ex) {
+ logger.log(Level.SEVERE, "Provider BC not supported.", ex);
+ }
+ return null;
+ }
+}
Modified: trunk/apps/Thaw/src/thaw/core/MainWindow.java
===================================================================
--- trunk/apps/Thaw/src/thaw/core/MainWindow.java 2007-07-27 18:13:50 UTC
(rev 14394)
+++ trunk/apps/Thaw/src/thaw/core/MainWindow.java 2007-07-27 18:14:06 UTC
(rev 14395)
@@ -594,6 +594,7 @@
new JLabel(I18n.getMessage("thaw.about.l10")),
new JLabel(I18n.getMessage("thaw.about.l11")),
new JLabel(I18n.getMessage("thaw.about.l12")),
+ new JLabel(I18n.getMessage("thaw.about.l13"))
};
Modified: trunk/apps/Thaw/src/thaw/fcp/SHA256Computer.java
===================================================================
--- trunk/apps/Thaw/src/thaw/fcp/SHA256Computer.java 2007-07-27 18:13:50 UTC
(rev 14394)
+++ trunk/apps/Thaw/src/thaw/fcp/SHA256Computer.java 2007-07-27 18:14:06 UTC
(rev 14395)
@@ -56,12 +56,12 @@
setChanged();
notifyObservers();
}
-
+
bis.close();
in.close();
-
+
synchronized (hashLock) {
- hash = Base64.encode(md.digest());
+ hash = Base64.encode(md.digest());
}
isFinished = true;
SHA256.returnMessageDigest(md);
Modified: trunk/apps/Thaw/src/thaw/i18n/thaw.properties
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/thaw.properties 2007-07-27 18:13:50 UTC
(rev 14394)
+++ trunk/apps/Thaw/src/thaw/i18n/thaw.properties 2007-07-27 18:14:06 UTC
(rev 14395)
@@ -254,9 +254,10 @@
thaw.about.l07=- InfoNode look&feel ( http://www.infonode.net/ ; GPL )
thaw.about.l08=- Liquid look&feel ( https://liquidlnf.dev.java.net/ ; LGPL )
thaw.about.l09=- Hsqldb ( http://hsqldb.org/ ; Hsqldb license )
-thaw.about.l10=- JmDNS ( http://jmdns.sourceforge.net/ ; LGPL )
-thaw.about.l11=- Some parts of the Freenet node source code (
http://freenetproject.org/ ; GPL )
-thaw.about.l12=- Some parts of Frost source code (
http://jtcfrost.sourceforge.net/ ; GPL )
+thaw.about.l10=- BouncyCastle ( http://bouncycastle.org/ ; Bouncy castle
license )
+thaw.about.l11=- JmDNS ( http://jmdns.sourceforge.net/ ; LGPL )
+thaw.about.l12=- Some parts of the Freenet node source code (
http://freenetproject.org/ ; GPL )
+thaw.about.l13=- Some parts of Frost source code (
http://jtcfrost.sourceforge.net/ ; GPL )
## HsqlDb
Modified: trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties
===================================================================
--- trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties 2007-07-27 18:13:50 UTC
(rev 14394)
+++ trunk/apps/Thaw/src/thaw/i18n/thaw_fr.properties 2007-07-27 18:14:06 UTC
(rev 14395)
@@ -64,6 +64,7 @@
thaw.common.removeFromTheList=Annuler et retirer les transferts
s\u00e9lectionn\u00e9s
thaw.common.cancel=Annuler
thaw.common.delay=Retarder
+thaw.common.copyKeyToClipboard=Copier la clef dans le presse-papier
thaw.common.copyKeysToClipboard=Copier les clefs dans le presse-papier
thaw.common.forceRestart=Forcer le red\u00e9marrage du/des transfert(s)
thaw.common.downloadLocally=T\u00e9l\u00e9chargement en local
@@ -520,6 +521,7 @@
thaw.plugin.miniFrost=Forums
thaw.plugin.miniFrost.boards=Boards
+thaw.plugin.miniFrost.board=Board
thaw.plugin.miniFrost.FrostKSK=boards Frost non-sign\u00e9e
thaw.plugin.miniFrost.selectType=Veuillez selectionner le type de board voulu
thaw.plugin.miniFrost.boardName=Nom de la board ?
@@ -555,3 +557,9 @@
thaw.plugin.miniFrost.seeArchived=Voir les messages archiv\u00e9s
thaw.plugin.miniFrost.maxBoardsRefreshed=Nombre maximum de boards rafraichies
simultan\u00e9ment
+
+thaw.plugin.miniFrost.copyAllKeys=Copier toutes les clefs des fichiers joints
dans le presse-papier
+
+thaw.plugin.miniFrost.attachments=Pieces jointes
+thaw.plugin.miniFrost.downloadAll=T\u00e9l\u00e9charger tout les fichiers
joints
+
Modified: trunk/apps/Thaw/src/thaw/plugins/index/Comment.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/index/Comment.java 2007-07-27 18:13:50 UTC
(rev 14394)
+++ trunk/apps/Thaw/src/thaw/plugins/index/Comment.java 2007-07-27 18:14:06 UTC
(rev 14395)
@@ -70,15 +70,7 @@
import java.sql.SQLException;
-/* Base 64 */
-import freenet.support.Base64;
-
-/* a little bit of DSA */
-
-import freenet.crypt.DSASignature;
-
-
/* Thaw */
import thaw.core.Config;
@@ -115,8 +107,7 @@
/* needed to check the signature */
- private byte[] r;
- private byte[] s;
+ private String sig;
private Comment() {
@@ -207,7 +198,7 @@
JPanel trustPanel = new JPanel(new BorderLayout(5, 5));
- if (author.getX() == null) {
+ if (author.getPrivateKey() == null) {
trustPanel.add(trust, BorderLayout.CENTER);
trustPanel.add(changeTrust, BorderLayout.EAST);
}
@@ -216,7 +207,7 @@
bottomRightPanel.add(trustPanel, BorderLayout.CENTER);
- if (hasPrivateKey && (author.getX() == null || blackListed) ) {
+ if (hasPrivateKey && (author.getPrivateKey() == null ||
blackListed) ) {
changeBlackListState = new JButton(blackListed ?
I18n.getMessage("thaw.plugin.index.comment.unmoderate") :
I18n.getMessage("thaw.plugin.index.comment.moderate"));
@@ -390,32 +381,22 @@
Element signatureTag = xmlDoc.createElement("signature");
Element sigTag = xmlDoc.createElement("sig");
- Element rTag = xmlDoc.createElement("r");
- Element sTag = xmlDoc.createElement("s");
- DSASignature sig = author.sign(index.getCommentPublicKey()+"-"+
- author.getNick()+"-"+
- comment);
+ String sig = author.sign(index.getCommentPublicKey()+"-"+
+ author.getNick()+"-"+
+ comment);
- Text rTxt =
xmlDoc.createTextNode(Base64.encode(sig.getR().toByteArray()));
- Text sTxt =
xmlDoc.createTextNode(Base64.encode(sig.getS().toByteArray()));
+ Text sigTxt = xmlDoc.createTextNode(sig);
- rTag.appendChild(rTxt);
- sTag.appendChild(sTxt);
+ sigTag.appendChild(sigTxt);
- sigTag.appendChild(rTag);
- sigTag.appendChild(sTag);
-
Element publicKeyTag = xmlDoc.createElement("publicKey");
- Element yTag = xmlDoc.createElement("y");
+ Text publicKeyTxt =
xmlDoc.createTextNode(author.getPublicKey());
- Text yTxt = xmlDoc.createTextNode(Base64.encode(author.getY()));
+ publicKeyTag.appendChild(publicKeyTxt);
- yTag.appendChild(yTxt);
- publicKeyTag.appendChild(yTag);
-
signatureTag.appendChild(sigTag);
signatureTag.appendChild(publicKeyTag);
@@ -534,13 +515,12 @@
private boolean authorTag;
private boolean textTag;
- private boolean yTag;
- private boolean rTag;
- private boolean sTag;
+ private boolean publicKeyTag;
+ private boolean sigTag;
/* needed to create / get the corresponding identity */
private String authorTxt;
- private byte[] y;
+ private String publicKey;
/**
@@ -564,14 +544,11 @@
if ("text".equals(rawName))
textTag = true;
- if ("y".equals(rawName))
- yTag = true;
+ if ("publicKey".equals(rawName))
+ publicKeyTag = true;
- if ("r".equals(rawName))
- rTag = true;
-
- if ("s".equals(rawName))
- sTag = true;
+ if ("sig".equals(rawName))
+ sigTag = true;
}
@@ -594,14 +571,11 @@
if ("text".equals(rawName))
textTag = false;
- if ("y".equals(rawName))
- yTag = false;
+ if ("publicKey".equals(rawName))
+ publicKeyTag = false;
- if ("r".equals(rawName))
- rTag = false;
-
- if ("s".equals(rawName))
- sTag = false;
+ if ("sig".equals(rawName))
+ sigTag = false;
}
@@ -621,18 +595,11 @@
if (textTag)
comment = txt;
- try {
- if (yTag)
- y = Base64.decode(txt);
+ if (publicKeyTag)
+ publicKey = txt;
- if (rTag)
- r = Base64.decode(txt);
-
- if (sTag)
- s = Base64.decode(txt);
- } catch(freenet.support.IllegalBase64Exception e) {
- Logger.error(this, "IllegalBase64Exception =>
won't validate :P");
- }
+ if (sigTag)
+ sig = txt;
}
public void ignorableWhitespace(char[] ch, int start, int end)
throws SAXException {
@@ -657,13 +624,13 @@
public void endDocument() throws SAXException {
try {
if (comment != null && authorTxt != null
- && y != null && r != null && s != null) {
+ && publicKey != null && sig != null) {
- author = Identity.getIdentity(db,
authorTxt, y);
+ author = Identity.getIdentity(db,
authorTxt, publicKey);
valid =
author.check(index.getCommentPublicKey()+"-"+
author.getNick()+"-"+
comment,
- r, s);
+ sig);
if (!valid) {
Logger.notice(this, "Signature
validation failed !");
@@ -733,14 +700,13 @@
PreparedStatement st;
st =
db.getConnection().prepareStatement("INSERT INTO indexComments "+
-
"(authorId, text, rev, indexId, r, s) "+
-
"VALUES (?, ?, ?, ?, ?, ?)");
+
"(authorId, text, rev, indexId, sig) "+
+
"VALUES (?, ?, ?, ?, ?)");
st.setInt(1, author.getId());
st.setString(2, comment);
st.setInt(3, rev);
st.setInt(4, index.getId());
- st.setBytes(5, r);
- st.setBytes(6, s);
+ st.setString(5, sig);
st.execute();
@@ -775,10 +741,9 @@
PreparedStatement st;
st = db.getConnection().prepareStatement("SELECT id
FROM indexComments "+
- "WHERE r = ?
AND s = ? ");
+ "WHERE sig =
?");
- st.setBytes(1, r);
- st.setBytes(2, s);
+ st.setString(1, sig);
ResultSet set = st.executeQuery();
Modified: trunk/apps/Thaw/src/thaw/plugins/index/DatabaseManager.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/index/DatabaseManager.java 2007-07-27
18:13:50 UTC (rev 14394)
+++ trunk/apps/Thaw/src/thaw/plugins/index/DatabaseManager.java 2007-07-27
18:14:06 UTC (rev 14395)
@@ -91,7 +91,7 @@
if (config.getValue("indexDatabaseVersion") == null) {
newDb = true;
- config.setValue("indexDatabaseVersion", "7");
+ config.setValue("indexDatabaseVersion", "8");
} else {
/* CONVERTIONS */
@@ -141,6 +141,13 @@
config.setValue("indexDatabaseVersion",
"7");
}
+ if
("7".equals(config.getValue("indexDatabaseVersion"))) {
+ if (splashScreen != null)
+ splashScreen.setStatus("Converting
database ...");
+ if (convertDatabase_7_to_8(db))
+ config.setValue("indexDatabaseVersion",
"8");
+ }
+
/* ... */
}
@@ -278,8 +285,7 @@
+ "text VARCHAR(16384) NOT NULL," /* 16 KB */
+ "rev INTEGER NOT NULL,"
+ "indexId INTEGER NOT NULL,"
- + "r VARBINARY(400) NOT NULL," /* signature */
- + "s VARBINARY(400) NOT NULL," /* signature */
+ + "sig VARCHAR(400) NOT NULL," /* signature */
+ "FOREIGN KEY (indexId) REFERENCES indexes (id),"
+ "FOREIGN KEY (authorId) REFERENCES signatures
(id))");
@@ -984,4 +990,17 @@
return true;
}
+
+ public static boolean convertDatabase_7_to_8(Hsqldb db) {
+ if (!sendQuery(db, "DELETE FROM indexComments")
+ || !sendQuery(db, "ALTER TABLE indexComments DROP r")
+ || !sendQuery(db, "ALTER TABLE indexComments DROP s")
+ || !sendQuery(db, "ALTER TABLE indexComments ADD sig
VARCHAR(400) NOT NULL")) {
+
+ Logger.error(new DatabaseManager(), "Error while
converting the database (7 to 8) !");
+ return false;
+ }
+
+ return true;
+ }
}
Modified:
trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKMessageParser.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKMessageParser.java
2007-07-27 18:13:50 UTC (rev 14394)
+++ trunk/apps/Thaw/src/thaw/plugins/miniFrost/frostKSK/KSKMessageParser.java
2007-07-27 18:14:06 UTC (rev 14395)
@@ -12,7 +12,6 @@
import java.util.Iterator;
import java.util.List;
-
import frost.util.XMLTools;
import thaw.plugins.Hsqldb;
@@ -39,6 +38,8 @@
private String board;
private String body;
+ private String signature;
+
private Vector attachments;
@@ -64,6 +65,7 @@
}
+
public boolean insert(Hsqldb db,
int boardId, int rev,
String boardNameExpected) {
@@ -183,6 +185,17 @@
}
+ public String getSignedContent() {
+ return null;
+ }
+
+
+ public boolean checkSignature(Hsqldb db) {
+
+ return true;
+ }
+
+
protected boolean loadXMLElements(Element root) {
messageId = XMLTools.getChildElementsCDATAValue(root,
"MessageId");
inReplyTo = XMLTools.getChildElementsCDATAValue(root,
"InReplyTo");
Modified: trunk/apps/Thaw/src/thaw/plugins/signatures/DatabaseManager.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/signatures/DatabaseManager.java
2007-07-27 18:13:50 UTC (rev 14394)
+++ trunk/apps/Thaw/src/thaw/plugins/signatures/DatabaseManager.java
2007-07-27 18:14:06 UTC (rev 14395)
@@ -26,19 +26,19 @@
if (config.getValue("signaturesDatabaseVersion") == null) {
newDb = true;
- config.setValue("signaturesDatabaseVersion", "1");
+ config.setValue("signaturesDatabaseVersion", "2");
} else {
/* CONVERTIONS */
- /*
- if
("1".equals(config.getValue("indexDatabaseVersion"))) {
+
+ if
("1".equals(config.getValue("signaturesDatabaseVersion"))) {
if (splashScreen != null)
splashScreen.setStatus("Converting
database ...");
if (convertDatabase_1_to_2(db))
- config.setValue("indexDatabaseVersion",
"2");
+
config.setValue("signaturesDatabaseVersion", "2");
}
- */
+
}
@@ -63,12 +63,25 @@
sendQuery(db, "CREATE CACHED TABLE signatures ("
+ "id INTEGER IDENTITY NOT NULL, "
+ "nickName VARCHAR(255) NOT NULL, "
- + "y VARBINARY(400) NOT NULL, " /* publicKey */
- + "x VARBINARY(400) DEFAULT NULL NULL, " /*
privateKey */
+ + "publicKey VARCHAR(400) NOT NULL, " /* publicKey */
+ + "privateKey VARCHAR(400) DEFAULT NULL NULL, " /*
privateKey */
+ "isDup BOOLEAN DEFAULT FALSE NOT NULL, "
+ "trustLevel TINYINT DEFAULT 0 NOT NULL, " /* See
Identity.java */
+ "PRIMARY KEY(id))");
}
/* dropTables is not implements because signatures may be VERY
important */
+ /* (anyway, because of the foreign key, it would probably fail */
+
+ protected static boolean convertDatabase_1_to_2(Hsqldb db) {
+ if (!sendQuery(db, "DELETE FROM indexComments")
+ || !sendQuery(db, "DELETE FROM signatures")
+ || !sendQuery(db, "ALTER TABLE signatures DROP y")
+ || !sendQuery(db, "ALTER TABLE signatures DROP x")
+ || !sendQuery(db, "ALTER TABLE signatures ADD publicKey
VARCHAR(400) NOT NULL")
+ || !sendQuery(db, "ALTER TABLE signatures ADD privateKey
VARCHAR(400) NULL"))
+ return false;
+
+ return true;
+ }
}
Modified: trunk/apps/Thaw/src/thaw/plugins/signatures/Identity.java
===================================================================
--- trunk/apps/Thaw/src/thaw/plugins/signatures/Identity.java 2007-07-27
18:13:50 UTC (rev 14394)
+++ trunk/apps/Thaw/src/thaw/plugins/signatures/Identity.java 2007-07-27
18:14:06 UTC (rev 14395)
@@ -10,13 +10,15 @@
import freenet.crypt.SHA256;
import freenet.support.Base64;
-import freenet.crypt.DSA;
-import freenet.crypt.DSAPrivateKey;
-import freenet.crypt.DSAPublicKey;
-import freenet.crypt.DSASignature;
+//import freenet.crypt.DSA;
+//import freenet.crypt.DSAPrivateKey;
+//import freenet.crypt.DSAPublicKey;
+//import freenet.crypt.DSASignature;
import freenet.crypt.Global;
import freenet.crypt.RandomSource;
+import frost.crypt.FrostCrypt;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -66,11 +68,11 @@
private String nick;
- /* public key */
- private byte[] y;
+ /* public key (aka Y) */
+ private String publicKey;
- /* private key */
- private byte[] x;
+ /* private key (aka X) */
+ private String privateKey;
private boolean isDup;
private int trustLevel;
@@ -78,7 +80,9 @@
private String hash;
+ private static FrostCrypt frostCrypt;
+
private Identity() {
}
@@ -87,21 +91,28 @@
* @param nick part *before* the @
*/
public Identity(Hsqldb db, int id, String nick,
- byte[] y, byte[] x,
+ String publicKey, String privateKey,
boolean isDup,
int trustLevel) {
this.db = db;
this.id = id;
this.nick = nick;
- this.y = y;
- this.x = x;
+ this.publicKey = publicKey;
+ this.privateKey = privateKey;
this.isDup = isDup;
this.trustLevel = trustLevel;
- hash = Base64.encode(SHA256.digest(y));
+ //hash =
Base64.encode(SHA256.digest(publicKey.getBytes("UTF-8")));
+ initFrostCrypt();
+ hash = frostCrypt.digest(publicKey);
}
+ private static void initFrostCrypt() {
+ if (frostCrypt == null)
+ frostCrypt = new FrostCrypt();
+ }
+
public int getId() {
return id;
}
@@ -110,18 +121,18 @@
return nick;
}
- public byte[] getY() {
- return y;
+ public String getPublicKey() {
+ return publicKey;
}
- public byte[] getX() {
- return x;
+ public String getPrivateKey() {
+ return privateKey;
}
public String getTrustLevelStr() {
int i;
- if (x != null) {
+ if (privateKey != null) {
return "thaw.plugin.signature.trustLevel.me";
}
@@ -146,7 +157,7 @@
public Color getTrustLevelColor() {
int i;
- if (x != null)
+ if (privateKey != null)
return new java.awt.Color(0, 175, 0);
for (i = 0 ; i < trustLevelInt.length ; i++) {
@@ -225,7 +236,7 @@
public boolean mustBeIgnored(Config config) {
- if (x != null)
+ if (privateKey != null)
return false;
int min = Integer.parseInt(config.getValue("minTrustLevel"));
@@ -239,21 +250,22 @@
*/
public static Identity getIdentity(Hsqldb db,
String nick,
- byte[] y) {
+ String publicKey) {
try {
synchronized(db.dbLock) {
PreparedStatement st;
- st =
db.getConnection().prepareStatement("SELECT id, nickName, y, x, isDup,
trustLevel "+
+ st =
db.getConnection().prepareStatement("SELECT id, nickName, publicKey, "+
+
"privateKey, isDup, trustLevel "+
"FROM
signatures "+
"WHERE
y = ? LIMIT 1");
- st.setBytes(1, y);
+ st.setString(1, publicKey);
ResultSet set = st.executeQuery();
if (set.next()) {
Identity i = new Identity(db,
set.getInt("id"), set.getString("nickName"),
-
set.getBytes("y"), set.getBytes("x"),
+
set.getString("publicKey"), set.getString("privateKey"),
set.getBoolean("isDup"), set.getInt("trustLevel"));
Logger.info(i, "Identity found");
return i;
@@ -272,17 +284,17 @@
/* and we add */
st =
db.getConnection().prepareStatement("INSERT INTO signatures "+
-
"(nickName, y, x, isDup, trustLevel) "+
+
"(nickName, publicKey, privateKey, isDup, trustLevel) "+
"VALUES (?, ?, ?, ?, 0)");
st.setString(1, nick);
- st.setBytes(2, y);
- st.setNull(3, Types.VARBINARY);
+ st.setString(2, publicKey);
+ st.setNull(3, Types.VARCHAR);
st.setBoolean(4, isDup);
st.execute();
- Identity i = new Identity(db, -1, nick, y,
null, isDup, 0);
+ Identity i = new Identity(db, -1, nick,
publicKey, null, isDup, 0);
Logger.info(i, "New identity found");
return i;
@@ -306,7 +318,8 @@
synchronized(db.dbLock) {
PreparedStatement st;
- st =
db.getConnection().prepareStatement("SELECT id, nickName, y, x, isDup,
trustLevel "+
+ st =
db.getConnection().prepareStatement("SELECT id, nickName, publicKey, "+
+
"privateKey, isDup, trustLevel "+
"FROM
signatures "+
"WHERE
id = ? LIMIT 1");
st.setInt(1, id);
@@ -317,7 +330,7 @@
return null;
i = new Identity(db, id,
set.getString("nickName"),
- set.getBytes("y"),
set.getBytes("x"),
+ set.getString("publicKey"),
set.getString("privateKey"),
set.getBoolean("isDup"),
set.getInt("trustLevel"));
}
} catch(SQLException e) {
@@ -330,18 +343,22 @@
/**
* Generate a new identity
- * you have to insert() it
+ * you have to insert() it after
* @param db just here to fill in the class
*/
public static Identity generate(Hsqldb db, String nick) {
- Logger.info(nick, "thaw.plugins.signatures.Identity :
Generating new identity ...");
+ Logger.info(null, "thaw.plugins.signatures.Identity :
Generating new identity ...");
- DSAPrivateKey privateKey = new
DSAPrivateKey(Global.DSAgroupBigA, Core.getRandom());
- DSAPublicKey publicKey = new DSAPublicKey(Global.DSAgroupBigA,
privateKey);
+ //DSAPrivateKey privateKey = new
DSAPrivateKey(Global.DSAgroupBigA, Core.getRandom());
+ //DSAPublicKey publicKey = new
DSAPublicKey(Global.DSAgroupBigA, privateKey);
+ initFrostCrypt();
+
+ String[] keys = frostCrypt.generateKeys();
+
Identity identity = new Identity(db, -1, nick,
- publicKey.getY().toByteArray(),
-
privateKey.getX().toByteArray(),
+ keys[1], /* public */
+ keys[0], /* private */
false,
10);
@@ -360,11 +377,13 @@
synchronized(db.dbLock) {
PreparedStatement st;
- st =
db.getConnection().prepareStatement("INSERT INTO signatures (nickName, y, x,
isDup, trustLevel) "+
+ st =
db.getConnection().prepareStatement("INSERT INTO signatures "+
+
"(nickName, publicKey, privateKey, "+
+
"isDup, trustLevel) "+
"VALUES (?, ?, ?, ?, ?)");
st.setString(1, nick);
- st.setBytes(2, y);
- st.setBytes(3, x);
+ st.setString(2, publicKey);
+ st.setString(3, privateKey);
st.setBoolean(4, isDup);
st.setInt(5, trustLevel);
@@ -396,72 +415,44 @@
}
- public DSASignature sign(String text) {
- return sign(text, x);
+ public String sign(String text) {
+ initFrostCrypt();
+
+ return frostCrypt.detachedSign(text, privateKey);
}
- public static DSASignature sign(String text, byte[] x) {
- BigInteger m;
+ public static String sign(String text, String privateKey) {
+ initFrostCrypt();
- byte[] bytes;
-
- try {
- bytes = text.getBytes("UTF-8");
- } catch(java.io.UnsupportedEncodingException e) {
- Logger.warning(new Identity(), "sign() :
UnsupportedEncodingException ? => Falling back on default charset");
- bytes = text.getBytes();
- }
-
- m = new BigInteger(1, SHA256.digest(bytes));
-
-
- DSASignature sign = DSA.sign(Global.DSAgroupBigA,
- new DSAPrivateKey(new
BigInteger(1, x)),
- m,
- (RandomSource)Core.getRandom());
-
-
- return sign;
+ return frostCrypt.detachedSign(text, privateKey);
}
- public boolean check(String text, byte[] r, byte[] s) {
- return check(text, r, s, y);
+ public boolean check(String text, String sig) {
+ initFrostCrypt();
+ return frostCrypt.detachedVerify(text, publicKey, sig);
}
public static boolean check(String text, /* signed text */
- byte[] r, /* sig */
- byte[] s, /* sig */
- byte[] y) /* publicKey */ {
+ String sig,
+ String publicKey) /* y */ {
+ initFrostCrypt();
+ return frostCrypt.detachedVerify(text, publicKey, sig);
+ }
- BigInteger m;
- byte[] bytes;
+ public String toString() {
+ String n = nick;
- try {
- bytes = text.getBytes("UTF-8");
- } catch(java.io.UnsupportedEncodingException e) {
- /* no logging because if it happens once, it will
happen often */
- bytes = text.getBytes();
- }
+ if (n.indexOf('@') >= 0)
+ n.replaceAll("@", "_");
- m = new BigInteger(1, SHA256.digest(bytes));
-
- boolean ret = DSA.verify(new DSAPublicKey(Global.DSAgroupBigA,
new BigInteger(1, y)),
- new DSASignature(new BigInteger(1, r),
new BigInteger(1, s)),
- m, false);
-
- return ret;
+ return n+"@"+hash;
}
- public String toString() {
- return nick+"@"+hash;
- }
-
-
public static Vector getIdentities(Hsqldb db, String cond) {
try {
synchronized(db.dbLock) {
@@ -470,9 +461,15 @@
PreparedStatement st;
if (cond != null)
- st =
db.getConnection().prepareStatement("SELECT id, nickName, y, x, isDup,
trustLevel FROM signatures WHERE "+cond + " ORDER BY nickName");
+ st =
db.getConnection().prepareStatement("SELECT id, nickName, publicKey, "+
+
"privateKey, isDup, trustLevel "+
+
"FROM signatures "+
+
"WHERE "+cond + " "+
+
"ORDER BY nickName");
else
- st =
db.getConnection().prepareStatement("SELECT id, nickName, y, x, isDup,
trustLevel FROM signatures ORDER BY nickName");
+ st =
db.getConnection().prepareStatement("SELECT id, nickName, publicKey, "+
+
"privateKey, isDup, trustLevel "+
+
"FROM signatures ORDER BY nickName");
ResultSet set = st.executeQuery();
@@ -480,8 +477,8 @@
v.add(new Identity(db,
set.getInt("id"),
set.getString("nickName"),
- set.getBytes("y"),
- set.getBytes("x"),
+
set.getString("publicKey"),
+
set.getString("privateKey"),
set.getBoolean("isDup"),
set.getInt("trustLevel")));
}
@@ -497,12 +494,12 @@
public static Vector getYourIdentities(Hsqldb db) {
- return getIdentities(db, "x IS NOT NULL");
+ return getIdentities(db, "privateKey IS NOT NULL");
}
public static Vector getOtherIdentities(Hsqldb db) {
- return getIdentities(db, "x IS NULL");
+ return getIdentities(db, "privateKey IS NULL");
}
@@ -513,13 +510,13 @@
out.write((nick+"\n").getBytes("UTF-8"));
- if (getX() != null)
- out.write(
(Base64.encode(getX())+"\n").getBytes("UTF-8") );
+ if (getPrivateKey() != null)
+ out.write(
(getPrivateKey()+"\n").getBytes("UTF-8") );
else
out.write( "\n".getBytes("UTF-8"));
- if (getY() != null)
- out.write(
(Base64.encode(getY())+"\n").getBytes("UTF-8") );
+ if (getPublicKey() != null)
+ out.write(
(getPublicKey()+"\n").getBytes("UTF-8") );
else
out.write( "\n".getBytes("UTF-8"));
@@ -559,8 +556,8 @@
}
Identity i = new Identity(db, -1, elements[0],
- Base64.decode(elements[2]),
- Base64.decode(elements[1]),
+ elements[2],
+ elements[1],
false, 10);
i.insert();
@@ -569,8 +566,6 @@
Logger.error(new Identity(), "(1) Unable to import
identity because : "+e.toString());
} catch(java.io.IOException e) {
Logger.error(new Identity(), "(2) Unable to import
identity because : "+e.toString());
- } catch(freenet.support.IllegalBase64Exception e) {
- Logger.error(new Identity(), "(2) Unable to import
identity because : "+e.toString());
}
return null;