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;


Reply via email to