Changes in / [a70a7a7:ebc4ca86]


Ignore:
Files:
24 added
1 deleted
57 edited

Legend:

Unmodified
Added
Removed
  • LICENSE.txt

    ra70a7a7 rebc4ca86  
    3939   SHA256 and HMAC:
    4040   Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
     41   See licenses/LICENSE-SHA256.txt
     42
     43   ElGamal:
     44   Copyright (c) 2000 - 2013 The Legion of the Bouncy Castle Inc. (http://www.bouncycastle.org)
    4145   See licenses/LICENSE-SHA256.txt
    4246
  • apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java

    ra70a7a7 rebc4ca86  
    472472                String msg;
    473473                if (getTunnel().getContext().isRouterContext())
     474                    msg = "Unable to build tunnels for the client";
     475                else
    474476                    msg = "Unable to connect to the router at " + getTunnel().host + ':' + portNum +
    475477                             " and build tunnels for the client";
    476                 else
    477                     msg = "Unable to build tunnels for the client";
    478478                if (++retries < MAX_RETRIES) {
    479479                    if (log != null)
  • apps/routerconsole/java/src/net/i2p/router/web/ConfigNavHelper.java

    ra70a7a7 rebc4ca86  
    2020                                          {"", "net", "ui", "sidebar", "home", "service", "update", "tunnels",
    2121                                           "clients", "peer", "keyring", "logging", "stats",
    22                                            "reseed", "advanced" };
     22                                           "reseed", "advanced", "family" };
    2323
    2424    private static final String titles[] =
     
    2626                                           _x("Service"), _x("Update"), _x("Tunnels"),
    2727                                           _x("Clients"), _x("Peers"), _x("Keyring"), _x("Logging"), _x("Stats"),
    28                                            _x("Reseeding"), _x("Advanced") };
     28                                           _x("Reseeding"), _x("Advanced"), _x("Router Family") };
    2929
    3030    /** @since 0.9.19 */
  • apps/routerconsole/java/src/net/i2p/router/web/HomeHelper.java

    ra70a7a7 rebc4ca86  
    6868        "stats.i2p" + S + _x("I2P Network Statistics") + S + "http://stats.i2p/cgi-bin/dashboard.cgi" + S + I + "chart_line.png" + S +
    6969        _x("Technical Docs") + S + _x("Technical documentation") + S + "http://i2p-projekt.i2p/how" + S + I + "education.png" + S +
     70        _x("The Tin Hat") + S + _x("Privacy guides and tutorials") + S + "http://secure.thetinhat.i2p/" + S + I + "thetinhat.png" + S +
    7071        _x("Trac Wiki") + S + S + "http://trac.i2p2.i2p/" + S + I + "billiard_marker.png" + S +
    7172        //_x("Ugha's Wiki") + S + S + "http://ugha.i2p/" + S + I + "billiard_marker.png" + S +
  • apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java

    ra70a7a7 rebc4ca86  
    1414    private static final Map<String, String> _tooltips = new ConcurrentHashMap<String, String>(4);
    1515    private static final Map<String, String> _icons = new ConcurrentHashMap<String, String>(4);
     16    private static final Map<String, byte[]> _binary = new ConcurrentHashMap<String, byte[]>(4);
    1617   
    1718    /**
     
    4142    }
    4243   
     44    /**
     45     *  Retrieve binary icon for a plugin
     46     *  @param name plugin name
     47     *  @return null if not found
     48     *  @since 0.9.25
     49     */
     50    public static byte[] getBinary(String name){
     51        if(name != null)
     52            return _binary.get(name);
     53        else
     54            return null;
     55    }
     56
     57    /**
     58     *  Store binary icon for a plugin
     59     *  @param name plugin name
     60     *  @since 0.9.25
     61     */
     62    public static void setBinary(String name, byte[] arr){
     63        _binary.put(name, arr);
     64    }
     65
     66
    4367    /**
    4468     *  Translated string is loaded by PluginStarter
  • apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java

    ra70a7a7 rebc4ca86  
    2323import net.i2p.app.ClientAppState;
    2424import net.i2p.data.DataHelper;
     25import net.i2p.data.Base64;
    2526import net.i2p.router.RouterContext;
    2627import net.i2p.router.RouterVersion;
     
    351352                    // we don't need to save
    352353                }
     354            }
     355        }
     356
     357        //handle console icons for plugins without web-resources through prop icon-code
     358        String fullprop = props.getProperty("icon-code");
     359        if(fullprop != null && fullprop.length() > 1){
     360            byte[] decoded = Base64.decode(fullprop);
     361            if(decoded != null) {
     362                NavHelper.setBinary(appName, decoded);
     363                iconfile = "/Plugins/pluginicon?plugin=" + appName;
     364            } else {
     365                iconfile = "/themes/console/images/plugin.png";
    353366            }
    354367        }
  • apps/routerconsole/jsp/configreseed.jsp

    ra70a7a7 rebc4ca86  
    7979<tr><td class="mediumtags" align="right"><b><%=intl._t("Reseed URLs")%>:</b></td>
    8080<td><textarea wrap="off" name="reseedURL" cols="60" rows="7" spellcheck="false"><jsp:getProperty name="reseedHelper" property="reseedURL" /></textarea>
    81 <div class="formaction"><input type="submit" name="action" value="<%=intl._t("Reset URL list")%>" /></div>
     81<div class="formaction"><input type="submit" name="action" class="reload" value="<%=intl._t("Reset URL list")%>" /></div>
    8282</td></tr>
    8383
  • apps/routerconsole/jsp/web.xml

    ra70a7a7 rebc4ca86  
    1515
    1616    <!-- precompiled servlets -->
     17
     18    <servlet>
     19      <servlet-name>net.i2p.router.web.CodedIconRendererServlet</servlet-name>
     20      <servlet-class>net.i2p.router.web.CodedIconRendererServlet</servlet-class>
     21    </servlet>
     22
     23    <servlet-mapping>
     24      <servlet-name>net.i2p.router.web.CodedIconRendererServlet</servlet-name>
     25      <url-pattern>/Plugins/*</url-pattern>
     26    </servlet-mapping>
     27
     28
    1729   
    1830    <!-- yeah, i'm lazy, using a jsp instead of a servlet.. -->
  • build.xml

    ra70a7a7 rebc4ca86  
    884884                </condition>
    885885            </fail>
     886            <fail message="javac.compilerargs7 must contain a -bootclasspath option in override.properties">
     887                <condition>
     888                    <not><contains string="${javac.compilerargs7}" substring="-bootclasspath"/></not>
     889                </condition>
     890            </fail>
    886891            <fail message="build.built-by must be set in override.properties">
    887892                <condition>
  • core/java/src/gnu/crypto/hash/BaseHashStandalone.java

    ra70a7a7 rebc4ca86  
    5252 *
    5353 * @version $Revision: 1.1 $
     54 * @deprecated to be removed in 0.9.27
    5455 */
     56@Deprecated
    5557public abstract class BaseHashStandalone implements IMessageDigestStandalone {
    5658
  • core/java/src/gnu/crypto/hash/IMessageDigestStandalone.java

    ra70a7a7 rebc4ca86  
    5555 *
    5656 * @version $Revision: 1.1 $
     57 * @deprecated to be removed in 0.9.27
    5758 */
     59@Deprecated
    5860public interface IMessageDigestStandalone extends Cloneable {
    5961
  • core/java/src/gnu/crypto/hash/Sha256Standalone.java

    ra70a7a7 rebc4ca86  
    6565 *
    6666 * @version $Revision: 1.2 $
     67 * @deprecated to be removed in 0.9.27
    6768 */
     69@Deprecated
    6870public class Sha256Standalone extends BaseHashStandalone {
    6971   // Constants and variables
  • core/java/src/net/i2p/crypto/CertUtil.java

    ra70a7a7 rebc4ca86  
    1010import java.security.GeneralSecurityException;
    1111import java.security.InvalidKeyException;
     12import java.security.KeyFactory;
    1213import java.security.PrivateKey;
    1314import java.security.PublicKey;
     
    1516import java.security.cert.CertificateFactory;
    1617import java.security.cert.CertificateEncodingException;
     18import java.security.cert.CRLException;
    1719import java.security.cert.X509Certificate;
     20import java.security.cert.X509CRL;
     21import java.security.spec.PKCS8EncodedKeySpec;
     22import java.security.spec.KeySpec;
     23import java.util.ArrayList;
     24import java.util.Collection;
     25import java.util.EnumSet;
     26import java.util.List;
    1827import java.util.Locale;
    1928
     
    2534import net.i2p.I2PAppContext;
    2635import net.i2p.data.Base64;
     36import net.i2p.data.DataHelper;
    2737import net.i2p.util.Log;
    2838import net.i2p.util.SecureFileOutputStream;
     
    3444 *  @since 0.9.9
    3545 */
    36 public class CertUtil {
     46public final class CertUtil {
    3747       
    3848    private static final int LINE_LENGTH = 64;
     
    94104        // Get the encoded form which is suitable for exporting
    95105        byte[] buf = cert.getEncoded();
    96         PrintWriter wr = new PrintWriter(new OutputStreamWriter(out, "UTF-8"));
    97         wr.println("-----BEGIN CERTIFICATE-----");
    98         String b64 = Base64.encode(buf, true);     // true = use standard alphabet
    99         for (int i = 0; i < b64.length(); i += LINE_LENGTH) {
    100             wr.println(b64.substring(i, Math.min(i + LINE_LENGTH, b64.length())));
    101         }
    102         wr.println("-----END CERTIFICATE-----");
    103         wr.flush();
    104         if (wr.checkError())
    105             throw new IOException("Failed write to " + out);
     106        writePEM(buf, "CERTIFICATE", out);
    106107    }
    107108
     
    122123        if (buf == null)
    123124            throw new InvalidKeyException("encoding unsupported for this key");
     125        writePEM(buf, "PRIVATE KEY", out);
     126    }
     127
     128    /**
     129     *  Modified from:
     130     *  http://www.exampledepot.com/egs/java.security.cert/ExportCert.html
     131     *
     132     *  Writes data in base64 format.
     133     *  Does NOT close the stream. Throws on all errors.
     134     *
     135     *  @since 0.9.25 consolidated from other methods
     136     */
     137    private static void writePEM(byte[] buf, String what, OutputStream out)
     138                                                throws IOException {
    124139        PrintWriter wr = new PrintWriter(new OutputStreamWriter(out, "UTF-8"));
    125         wr.println("-----BEGIN PRIVATE KEY-----");
     140        wr.println("-----BEGIN " + what + "-----");
    126141        String b64 = Base64.encode(buf, true);     // true = use standard alphabet
    127142        for (int i = 0; i < b64.length(); i += LINE_LENGTH) {
    128143            wr.println(b64.substring(i, Math.min(i + LINE_LENGTH, b64.length())));
    129144        }
    130         wr.println("-----END PRIVATE KEY-----");
     145        wr.println("-----END " + what + "-----");
    131146        wr.flush();
    132147        if (wr.checkError())
     
    236251        }
    237252    }
     253
     254    /**
     255     *  Get a single Private Key from an input stream.
     256     *  Does NOT close the stream.
     257     *
     258     *  @return non-null, non-empty, throws on all errors including certificate invalid
     259     *  @since 0.9.25
     260     */
     261    public static PrivateKey loadPrivateKey(InputStream in) throws IOException, GeneralSecurityException {
     262        try {
     263            String line;
     264            while ((line = DataHelper.readLine(in)) != null) {
     265                if (line.startsWith("---") && line.contains("BEGIN") && line.contains("PRIVATE"))
     266                    break;
     267            }
     268            if (line == null)
     269                throw new IOException("no private key found");
     270            StringBuilder buf = new StringBuilder(128);
     271            while ((line = DataHelper.readLine(in)) != null) {
     272                if (line.startsWith("---"))
     273                    break;
     274                buf.append(line.trim());
     275            }
     276            if (buf.length() <= 0)
     277                throw new IOException("no private key found");
     278            byte[] data = Base64.decode(buf.toString(), true);
     279            if (data == null)
     280                throw new CertificateEncodingException("bad base64 cert");
     281            PrivateKey rv = null;
     282            // try all the types
     283            for (SigAlgo algo : EnumSet.allOf(SigAlgo.class)) {
     284                try {
     285                    KeySpec ks = new PKCS8EncodedKeySpec(data);
     286                    String alg = algo.getName();
     287                    KeyFactory kf = KeyFactory.getInstance(alg);
     288                    rv = kf.generatePrivate(ks);
     289                    break;
     290                } catch (GeneralSecurityException gse) {
     291                    //gse.printStackTrace();
     292                }
     293            }
     294            if (rv == null)
     295                throw new InvalidKeyException("unsupported key type");
     296            return rv;
     297        } catch (IllegalArgumentException iae) {
     298            // java 1.8.0_40-b10, openSUSE
     299            // Exception in thread "main" java.lang.IllegalArgumentException: Input byte array has wrong 4-byte ending unit
     300            // at java.util.Base64$Decoder.decode0(Base64.java:704)
     301            throw new GeneralSecurityException("key error", iae);
     302        }
     303    }
     304
     305    /**
     306     *  Get one or more certificates from an input stream.
     307     *  Throws if any certificate is invalid (e.g. expired).
     308     *  Does NOT close the stream.
     309     *
     310     *  @return non-null, non-empty, throws on all errors including certificate invalid
     311     *  @since 0.9.25
     312     */
     313    public static List<X509Certificate> loadCerts(InputStream in) throws IOException, GeneralSecurityException {
     314        try {
     315            CertificateFactory cf = CertificateFactory.getInstance("X.509");
     316            Collection<? extends Certificate> certs = cf.generateCertificates(in);
     317            List<X509Certificate> rv = new ArrayList<X509Certificate>(certs.size());
     318            for (Certificate cert : certs) {
     319                if (!(cert instanceof X509Certificate))
     320                    throw new GeneralSecurityException("not a X.509 cert");
     321                X509Certificate xcert = (X509Certificate) cert;
     322                xcert.checkValidity();
     323                rv.add(xcert);
     324            }
     325            if (rv.isEmpty())
     326                throw new IOException("no certs found");
     327            return rv;
     328        } catch (IllegalArgumentException iae) {
     329            // java 1.8.0_40-b10, openSUSE
     330            // Exception in thread "main" java.lang.IllegalArgumentException: Input byte array has wrong 4-byte ending unit
     331            // at java.util.Base64$Decoder.decode0(Base64.java:704)
     332            throw new GeneralSecurityException("cert error", iae);
     333        } finally {
     334            try { in.close(); } catch (IOException foo) {}
     335        }
     336    }
     337
     338    /**
     339     *  Write a CRL to a file in base64 format.
     340     *
     341     *  @return success
     342     *  @since 0.9.25
     343     */
     344    public static boolean saveCRL(X509CRL crl, File file) {
     345        OutputStream os = null;
     346        try {
     347           os = new SecureFileOutputStream(file);
     348           exportCRL(crl, os);
     349           return true;
     350        } catch (CRLException ce) {
     351            error("Error writing X509 CRL " + file.getAbsolutePath(), ce);
     352           return false;
     353        } catch (IOException ioe) {
     354            error("Error writing X509 CRL " + file.getAbsolutePath(), ioe);
     355           return false;
     356        } finally {
     357            try { if (os != null) os.close(); } catch (IOException foo) {}
     358        }
     359    }
     360
     361    /**
     362     *  Writes a CRL in base64 format.
     363     *  Does NOT close the stream. Throws on all errors.
     364     *
     365     *  @throws CRLException if the crl does not support encoding
     366     *  @since 0.9.25
     367     */
     368    private static void exportCRL(X509CRL crl, OutputStream out)
     369                                                throws IOException, CRLException {
     370        byte[] buf = crl.getEncoded();
     371        writePEM(buf, "X509 CRL", out);
     372    }
     373
     374/****
     375    public static final void main(String[] args) {
     376        if (args.length < 2) {
     377            System.out.println("Usage: [loadcert | loadcrl | loadprivatekey] file");
     378            System.exit(1);
     379        }
     380        try {
     381            File f = new File(args[1]);
     382            if (args[0].equals("loadcert")) {
     383                loadCert(f);
     384            } else if (args[0].equals("loadcrl")) {
     385            } else {
     386            }
     387
     388        } catch (Exception e) {
     389            e.printStackTrace();
     390            System.exit(1);
     391        }
     392    }
     393****/
    238394}
  • core/java/src/net/i2p/crypto/CryptixAESEngine.java

    ra70a7a7 rebc4ca86  
    3737 * @author jrandom, thecrypto
    3838 */
    39 public class CryptixAESEngine extends AESEngine {
     39public final class CryptixAESEngine extends AESEngine {
    4040    private final static CryptixRijndael_Algorithm _algo = new CryptixRijndael_Algorithm();
    4141    // keys are now cached in the SessionKey objects
  • core/java/src/net/i2p/crypto/CryptoConstants.java

    ra70a7a7 rebc4ca86  
    3535import java.security.spec.DSAParameterSpec;
    3636
     37import net.i2p.crypto.elgamal.spec.ElGamalParameterSpec;
    3738import net.i2p.util.NativeBigInteger;
    3839
     
    4445 *
    4546 */
    46 public class CryptoConstants {
     47public final class CryptoConstants {
    4748    public static final BigInteger dsap = new NativeBigInteger(
    4849                                                               "9c05b2aa960d9b97b8931963c9cc9e8c3026e9b8ed92fad0a69cc886d5bf8015fcadae31"
     
    8081
    8182    /**
     83     *  @since 0.9.25
     84     */
     85    public static final ElGamalParameterSpec I2P_ELGAMAL_2048_SPEC = new ElGamalParameterSpec(elgp, elgg);
     86
     87    /**
    8288     *  This will be org.bouncycastle.jce.spec.ElgamalParameterSpec
    8389     *  if BC is available, otherwise it
     
    99105                //System.out.println("BC ElG spec failed");
    100106                //e.printStackTrace();
    101                 spec = new ElGamalParameterSpec(elgp, elgg);
     107                spec = I2P_ELGAMAL_2048_SPEC;
    102108            }
    103109        } else {
    104110            //System.out.println("BC not available");
    105             spec = new ElGamalParameterSpec(elgp, elgg);
     111            spec = I2P_ELGAMAL_2048_SPEC;
    106112        }
    107113        ELGAMAL_2048_SPEC = spec;
  • core/java/src/net/i2p/crypto/DSAEngine.java

    ra70a7a7 rebc4ca86  
    7373 *  EdDSA support added in 0.9.15
    7474 */
    75 public class DSAEngine {
     75public final class DSAEngine {
    7676    private final Log _log;
    7777    private final I2PAppContext _context;
     
    235235            BigInteger r = new NativeBigInteger(1, rbytes);
    236236            BigInteger y = new NativeBigInteger(1, verifyingKey.getData());
    237             BigInteger w = null;
     237            BigInteger w;
    238238            try {
    239239                w = s.modInverse(CryptoConstants.dsaq);
     
    403403
    404404        BigInteger k;
    405 
    406         boolean ok = false;
     405        boolean ok;
    407406        do {
    408407            k = new BigInteger(160, _context.random());
     
    517516            return altVerifySigSHA1(signature, data, offset, len, verifyingKey);
    518517
    519         java.security.Signature jsig;
    520         if (type.getBaseAlgorithm() == SigAlgo.EdDSA)
    521             jsig = new EdDSAEngine(type.getDigestInstance());
    522         else
    523             jsig = java.security.Signature.getInstance(type.getAlgorithmName());
    524518        PublicKey pubKey = SigUtil.toJavaKey(verifyingKey);
    525         jsig.initVerify(pubKey);
    526         jsig.update(data, offset, len);
    527         boolean rv = jsig.verify(SigUtil.toJavaSig(signature));
     519        byte[] sigbytes = SigUtil.toJavaSig(signature);
     520        boolean rv;
     521        if (type.getBaseAlgorithm() == SigAlgo.EdDSA) {
     522            // take advantage of one-shot mode
     523            EdDSAEngine jsig = new EdDSAEngine(type.getDigestInstance());
     524            jsig.initVerify(pubKey);
     525            rv = jsig.verifyOneShot(data, offset, len, sigbytes);
     526        } else {
     527            java.security.Signature jsig = java.security.Signature.getInstance(type.getAlgorithmName());
     528            jsig.initVerify(pubKey);
     529            jsig.update(data, offset, len);
     530            rv = jsig.verify(sigbytes);
     531        }
    528532        return rv;
    529533    }
     
    565569            throw new IllegalArgumentException("type mismatch hash=" + hash.getClass() + " key=" + type);
    566570
    567         String algo = getRawAlgo(type);
    568         java.security.Signature jsig;
    569         if (type.getBaseAlgorithm() == SigAlgo.EdDSA)
    570             jsig = new EdDSAEngine(); // Ignore algo, EdDSAKey includes a hash specification.
    571         else
    572             jsig = java.security.Signature.getInstance(algo);
    573         jsig.initVerify(pubKey);
    574         jsig.update(hash.getData());
    575         boolean rv = jsig.verify(SigUtil.toJavaSig(signature));
     571        byte[] sigbytes = SigUtil.toJavaSig(signature);
     572        boolean rv;
     573        if (type.getBaseAlgorithm() == SigAlgo.EdDSA) {
     574            // take advantage of one-shot mode
     575            // Ignore algo, EdDSAKey includes a hash specification.
     576            EdDSAEngine jsig = new EdDSAEngine();
     577            jsig.initVerify(pubKey);
     578            rv = jsig.verifyOneShot(hash.getData(), sigbytes);
     579        } else {
     580            String algo = getRawAlgo(type);
     581            java.security.Signature jsig = java.security.Signature.getInstance(algo);
     582            jsig.initVerify(pubKey);
     583            jsig.update(hash.getData());
     584            rv = jsig.verify(sigbytes);
     585        }
    576586        return rv;
    577587    }
     
    608618            return altSignSHA1(data, offset, len, privateKey);
    609619
    610         java.security.Signature jsig;
    611         if (type.getBaseAlgorithm() == SigAlgo.EdDSA)
    612             jsig = new EdDSAEngine(type.getDigestInstance());
    613         else
    614             jsig = java.security.Signature.getInstance(type.getAlgorithmName());
    615620        PrivateKey privKey = SigUtil.toJavaKey(privateKey);
    616         jsig.initSign(privKey, _context.random());
    617         jsig.update(data, offset, len);
    618         return SigUtil.fromJavaSig(jsig.sign(), type);
     621        byte[] sigbytes;
     622        if (type.getBaseAlgorithm() == SigAlgo.EdDSA) {
     623            // take advantage of one-shot mode
     624            EdDSAEngine jsig = new EdDSAEngine(type.getDigestInstance());
     625            jsig.initSign(privKey);
     626            sigbytes = jsig.signOneShot(data, offset, len);
     627        } else {
     628            java.security.Signature jsig = java.security.Signature.getInstance(type.getAlgorithmName());
     629            jsig.initSign(privKey, _context.random());
     630            jsig.update(data, offset, len);
     631            sigbytes = jsig.sign();
     632        }
     633        return SigUtil.fromJavaSig(sigbytes, type);
    619634    }
    620635
     
    651666            throw new IllegalArgumentException("type mismatch hash=" + hash.getClass() + " key=" + type);
    652667
    653         java.security.Signature jsig;
    654         if (type.getBaseAlgorithm() == SigAlgo.EdDSA)
    655             jsig = new EdDSAEngine(); // Ignore algo, EdDSAKey includes a hash specification.
    656         else
    657             jsig = java.security.Signature.getInstance(algo);
    658         jsig.initSign(privKey, _context.random());
    659         jsig.update(hash.getData());
    660         return SigUtil.fromJavaSig(jsig.sign(), type);
     668        byte[] sigbytes;
     669        if (type.getBaseAlgorithm() == SigAlgo.EdDSA) {
     670            // take advantage of one-shot mode
     671            // Ignore algo, EdDSAKey includes a hash specification.
     672            EdDSAEngine jsig = new EdDSAEngine();
     673            jsig.initSign(privKey);
     674            sigbytes = jsig.signOneShot(hash.getData());
     675        } else {
     676            java.security.Signature jsig = java.security.Signature.getInstance(type.getAlgorithmName());
     677            jsig.initSign(privKey, _context.random());
     678            jsig.update(hash.getData());
     679            sigbytes = jsig.sign();
     680        }
     681        return SigUtil.fromJavaSig(sigbytes, type);
    661682    }
    662683
  • core/java/src/net/i2p/crypto/ECConstants.java

    ra70a7a7 rebc4ca86  
    2121 * @since 0.9.9
    2222 */
    23 class ECConstants {
     23final class ECConstants {
    2424
    2525    private static final boolean DEBUG = false;
  • core/java/src/net/i2p/crypto/ECUtil.java

    ra70a7a7 rebc4ca86  
    2020 *  @since 0.9.16
    2121 */
    22 class ECUtil {
     22final class ECUtil {
    2323
    2424    private static final BigInteger TWO = new BigInteger("2");
  • core/java/src/net/i2p/crypto/ElGamalAESEngine.java

    ra70a7a7 rebc4ca86  
    3333 * No, this does not extend AESEngine or CryptixAESEngine.
    3434 */
    35 public class ElGamalAESEngine {
     35public final class ElGamalAESEngine {
    3636    private final Log _log;
    3737    private final static int MIN_ENCRYPTED_SIZE = 80; // smallest possible resulting size
  • core/java/src/net/i2p/crypto/ElGamalEngine.java

    ra70a7a7 rebc4ca86  
    5353 */
    5454
    55 public class ElGamalEngine {
     55public final class ElGamalEngine {
    5656    private final Log _log;
    5757    private final I2PAppContext _context;
  • core/java/src/net/i2p/crypto/EncType.java

    ra70a7a7 rebc4ca86  
    2828     *  Pubkey 256 bytes, privkey 256 bytes.
    2929     */
    30     ELGAMAL_2048(0, 256, 256, EncAlgo.ELGAMAL, "ElGamal/None/NoPadding", CryptoConstants.ELGAMAL_2048_SPEC, "0"),
     30    ELGAMAL_2048(0, 256, 256, EncAlgo.ELGAMAL, "ElGamal/None/NoPadding", CryptoConstants.I2P_ELGAMAL_2048_SPEC, "0"),
    3131
    3232    /**  Pubkey 64 bytes; privkey 32 bytes; */
  • core/java/src/net/i2p/crypto/HMAC256Generator.java

    ra70a7a7 rebc4ca86  
    2222 * Deprecated, used only by Syndie.
    2323 */
    24 public class HMAC256Generator extends HMACGenerator {
     24public final class HMAC256Generator extends HMACGenerator {
    2525
    2626    /**
  • core/java/src/net/i2p/crypto/KeyGenerator.java

    ra70a7a7 rebc4ca86  
    3535import net.i2p.crypto.eddsa.EdDSAPublicKey;
    3636import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
     37import net.i2p.crypto.provider.I2PProvider;
    3738import net.i2p.data.Hash;
    3839import net.i2p.data.PrivateKey;
     
    5657 * @author jrandom
    5758 */
    58 public class KeyGenerator {
     59public final class KeyGenerator {
    5960    private final I2PAppContext _context;
     61
     62    static {
     63        I2PProvider.addProvider();
     64    }
    6065
    6166    public KeyGenerator(I2PAppContext context) {
     
    209214        BigInteger x = null;
    210215
    211         // make sure the random key is less than the DSA q
     216        // make sure the random key is less than the DSA q and greater than zero
    212217        do {
    213218            x = new NativeBigInteger(160, _context.random());
    214         } while (x.compareTo(CryptoConstants.dsaq) >= 0);
     219        } while (x.compareTo(CryptoConstants.dsaq) >= 0 || x.equals(BigInteger.ZERO));
    215220
    216221        BigInteger y = CryptoConstants.dsag.modPow(x, CryptoConstants.dsap);
  • core/java/src/net/i2p/crypto/KeyStoreUtil.java

    ra70a7a7 rebc4ca86  
    1414import java.security.cert.CertificateNotYetValidException;
    1515import java.security.cert.X509Certificate;
     16import java.util.ArrayList;
    1617import java.util.Enumeration;
     18import java.util.List;
    1719import java.util.Locale;
    1820
    1921import net.i2p.I2PAppContext;
     22import net.i2p.crypto.provider.I2PProvider;
    2023import net.i2p.data.Base32;
    2124import net.i2p.util.Log;
     
    3033 *  @since 0.9.9
    3134 */
    32 public class KeyStoreUtil {
     35public final class KeyStoreUtil {
    3336       
    3437    public static boolean _blacklistLogged;
     
    3841    private static final int DEFAULT_KEY_SIZE = 2048;
    3942    private static final int DEFAULT_KEY_VALID_DAYS = 3652;  // 10 years
     43
     44    static {
     45        I2PProvider.addProvider();
     46    }
    4047
    4148    /**
     
    465472        }
    466473        String keytool = (new File(System.getProperty("java.home"), "bin/keytool")).getAbsolutePath();
    467         String[] args = new String[] {
    468                    keytool,
    469                    "-genkey",            // -genkeypair preferred in newer keytools, but this works with more
    470                    "-storetype", KeyStore.getDefaultType(),
    471                    "-keystore", ks.getAbsolutePath(),
    472                    "-storepass", ksPW,
    473                    "-alias", alias,
    474                    "-dname", "CN=" + cname + ",OU=" + ou + ",O=I2P Anonymous Network,L=XX,ST=XX,C=XX",
    475                    "-validity", Integer.toString(validDays),  // 10 years
    476                    "-keyalg", keyAlg,
    477                    "-sigalg", getSigAlg(keySize, keyAlg),
    478                    "-keysize", Integer.toString(keySize),
    479                    "-keypass", keyPW
    480         };
     474        List<String> a = new ArrayList<String>(32);
     475        a.add(keytool);
     476        a.add("-genkey");    // -genkeypair preferred in newer keytools, but this works with more
     477        //a.add("-v");         // verbose, gives you a stack trace on exception
     478        a.add("-storetype"); a.add(KeyStore.getDefaultType());
     479        a.add("-keystore");  a.add(ks.getAbsolutePath());
     480        a.add("-storepass"); a.add(ksPW);
     481        a.add("-alias");     a.add(alias);
     482        a.add("-dname");     a.add("CN=" + cname + ",OU=" + ou + ",O=I2P Anonymous Network,L=XX,ST=XX,C=XX");
     483        a.add("-validity");  a.add(Integer.toString(validDays));  // 10 years
     484        a.add("-keyalg");    a.add(keyAlg);
     485        a.add("-sigalg");    a.add(getSigAlg(keySize, keyAlg));
     486        a.add("-keysize");   a.add(Integer.toString(keySize));
     487        a.add("-keypass");   a.add(keyPW);
     488        if (keyAlg.equals("Ed") || keyAlg.equals("EdDSA") || keyAlg.equals("ElGamal")) {
     489            File f = I2PAppContext.getGlobalContext().getBaseDir();
     490            f = new File(f, "lib");
     491            f = new File(f, "i2p.jar");
     492            // providerpath is not in the man page; see keytool -genkey -help
     493            a.add("-providerpath");  a.add(f.getAbsolutePath());
     494            a.add("-providerclass"); a.add("net.i2p.crypto.provider.I2PProvider");
     495        }
     496        String[] args = a.toArray(new String[a.size()]);
    481497        // TODO pipe key password to process; requires ShellCommand enhancements
    482498        boolean success = (new ShellCommand()).executeSilentAndWaitTimed(args, 240);
     
    515531        if (keyalg.equals("EC"))
    516532            keyalg = "ECDSA";
     533        else if (keyalg.equals("Ed"))
     534            keyalg = "EdDSA";
    517535        String hash;
    518536        if (keyalg.equals("ECDSA")) {
     
    523541            else
    524542                hash = "SHA512";
     543        } else if (keyalg.equals("EdDSA")) {
     544            hash = "SHA512";
    525545        } else {
    526546            if (size <= 1024)
     
    561581
    562582    /**
     583     *  Export the private key and certificate chain (if any) out of a keystore.
     584     *  Does NOT close the stream. Throws on all errors.
     585     *
     586     *  @param ks path to the keystore
     587     *  @param ksPW the keystore password, may be null
     588     *  @param alias the name of the key
     589     *  @param keyPW the key password, must be at least 6 characters
     590     *  @since 0.9.25
     591     */
     592    public static void exportPrivateKey(File ks, String ksPW, String alias, String keyPW,
     593                                        OutputStream out)
     594                              throws GeneralSecurityException, IOException {
     595        InputStream fis = null;
     596        try {
     597            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
     598            fis = new FileInputStream(ks);
     599            char[] pwchars = ksPW != null ? ksPW.toCharArray() : null;
     600            keyStore.load(fis, pwchars);
     601            char[] keypwchars = keyPW.toCharArray();
     602            PrivateKey pk = (PrivateKey) keyStore.getKey(alias, keypwchars);
     603            if (pk == null)
     604                throw new GeneralSecurityException("private key not found: " + alias);
     605            Certificate[] certs = keyStore.getCertificateChain(alias);
     606            CertUtil.exportPrivateKey(pk, certs, out);
     607        } finally {
     608            if (fis != null) try { fis.close(); } catch (IOException ioe) {}
     609        }
     610    }
     611
     612    /**
     613     *  Import the private key and certificate chain to a keystore.
     614     *  Keystore will be created if it does not exist.
     615     *  Private key MUST be first in the stream.
     616     *  Closes the stream. Throws on all errors.
     617     *
     618     *  @param ks path to the keystore
     619     *  @param ksPW the keystore password, may be null
     620     *  @param alias the name of the key. If null, will be taken from the Subject CN
     621     *               of the first certificate in the chain.
     622     *  @param keyPW the key password, must be at least 6 characters
     623     *  @return the alias as specified or extracted
     624     *  @since 0.9.25
     625     */
     626    public static String importPrivateKey(File ks, String ksPW, String alias, String keyPW,
     627                                          InputStream in)
     628                              throws GeneralSecurityException, IOException {
     629        OutputStream fos = null;
     630        try {
     631            KeyStore keyStore = createKeyStore(ks, ksPW);
     632            PrivateKey pk = CertUtil.loadPrivateKey(in);
     633            List<X509Certificate> certs = CertUtil.loadCerts(in);
     634            if (alias == null) {
     635                alias = CertUtil.getSubjectValue(certs.get(0), "CN");
     636                if (alias == null)
     637                    throw new GeneralSecurityException("no alias specified and no Subject CN in cert");
     638                if (alias.endsWith(".family.i2p.net") && alias.length() > ".family.i2p.net".length())
     639                    alias = alias.substring(0, ".family.i2p.net".length());
     640            }
     641            keyStore.setKeyEntry(alias, pk, keyPW.toCharArray(), certs.toArray(new Certificate[certs.size()]));
     642            char[] pwchars = ksPW != null ? ksPW.toCharArray() : null;
     643            fos = new SecureFileOutputStream(ks);
     644            keyStore.store(fos, pwchars);
     645            return alias;
     646        } finally {
     647            if (fos != null) try { fos.close(); } catch (IOException ioe) {}
     648            try { in.close(); } catch (IOException ioe) {}
     649        }
     650    }
     651
     652    /**
     653     *  Import the private key and certificate chain to a keystore.
     654     *  Keystore will be created if it does not exist.
     655     *  Private key MUST be first in the stream.
     656     *  Closes the stream. Throws on all errors.
     657     *
     658     *  @param ks path to the keystore
     659     *  @param ksPW the keystore password, may be null
     660     *  @param alias the name of the key, non-null.
     661     *  @param keyPW the key password, must be at least 6 characters
     662     *  @since 0.9.25
     663     */
     664    public static void storePrivateKey(File ks, String ksPW, String alias, String keyPW,
     665                                       PrivateKey pk, List<X509Certificate> certs)
     666                              throws GeneralSecurityException, IOException {
     667        OutputStream fos = null;
     668        try {
     669            KeyStore keyStore = createKeyStore(ks, ksPW);
     670            keyStore.setKeyEntry(alias, pk, keyPW.toCharArray(), certs.toArray(new Certificate[certs.size()]));
     671            char[] pwchars = ksPW != null ? ksPW.toCharArray() : null;
     672            fos = new SecureFileOutputStream(ks);
     673            keyStore.store(fos, pwchars);
     674        } finally {
     675            if (fos != null) try { fos.close(); } catch (IOException ioe) {}
     676        }
     677    }
     678
     679    /**
    563680     *  Get a cert out of a keystore
    564681     *
     
    642759     *          KeyStoreUtil foo.ks (loads from system keystore, and from foo.ks keystore if exists, else creates empty)
    643760     *          KeyStoreUtil certDir (loads from system keystore and all certs in certDir if exists)
     761     *          KeyStoreUtil import file.ks file.key alias keypw (imxports private key from file to keystore)
     762     *          KeyStoreUtil export file.ks alias keypw (exports private key from keystore)
     763     *          KeyStoreUtil keygen file.ks alias keypw (create keypair in keystore)
     764     *          KeyStoreUtil keygen2 file.ks alias keypw (create keypair using I2PProvider)
    644765     */
    645766/****
    646767    public static void main(String[] args) {
    647         File ksf = (args.length > 0) ? new File(args[0]) : null;
    648         try {
     768        try {
     769            if (args.length > 0 && "import".equals(args[0])) {
     770                testImport(args);
     771                return;
     772            }
     773            if (args.length > 0 && "export".equals(args[0])) {
     774                testExport(args);
     775                return;
     776            }
     777            if (args.length > 0 && "keygen".equals(args[0])) {
     778                testKeygen(args);
     779                return;
     780            }
     781            if (args.length > 0 && "keygen2".equals(args[0])) {
     782                testKeygen2(args);
     783                return;
     784            }
     785            File ksf = (args.length > 0) ? new File(args[0]) : null;
    649786            if (ksf != null && !ksf.exists()) {
    650787                createKeyStore(ksf, DEFAULT_KEYSTORE_PASSWORD);
     
    675812        }
    676813    }
     814
     815    private static void testImport(String[] args) throws Exception {
     816        File ksf = new File(args[1]);
     817        InputStream in = new FileInputStream(args[2]);
     818        String alias = args[3];
     819        String pw = args[4];
     820        importPrivateKey(ksf, DEFAULT_KEYSTORE_PASSWORD, alias, pw, in);
     821    }
     822
     823
     824    private static void testExport(String[] args) throws Exception {
     825        File ksf = new File(args[1]);
     826        String alias = args[2];
     827        String pw = args[3];
     828        exportPrivateKey(ksf, DEFAULT_KEYSTORE_PASSWORD, alias, pw, System.out);
     829    }
     830
     831    private static void testKeygen(String[] args) throws Exception {
     832        File ksf = new File(args[1]);
     833        String alias = args[2];
     834        String pw = args[3];
     835        boolean ok = createKeys(ksf, DEFAULT_KEYSTORE_PASSWORD, alias, "test cname", "test ou",
     836                                //DEFAULT_KEY_VALID_DAYS, "EdDSA", 256, pw);
     837                                DEFAULT_KEY_VALID_DAYS, "ElGamal", 2048, pw);
     838        System.out.println("genkey ok? " + ok);
     839    }
     840
     841    private static void testKeygen2(String[] args) throws Exception {
     842        // keygen test using the I2PProvider
     843        //SigType type = SigType.EdDSA_SHA512_Ed25519;
     844        SigType type = SigType.ElGamal_SHA256_MODP2048;
     845        java.security.KeyPairGenerator kpg = java.security.KeyPairGenerator.getInstance(type.getBaseAlgorithm().getName());
     846        kpg.initialize(type.getParams());
     847        java.security.KeyPair kp = kpg.generateKeyPair();
     848        java.security.PublicKey jpub = kp.getPublic();
     849        java.security.PrivateKey jpriv = kp.getPrivate();
     850
     851        System.out.println("Encoded private key:");
     852        System.out.println(net.i2p.util.HexDump.dump(jpriv.getEncoded()));
     853        System.out.println("Encoded public key:");
     854        System.out.println(net.i2p.util.HexDump.dump(jpub.getEncoded()));
     855
     856        java.security.Signature jsig = java.security.Signature.getInstance(type.getAlgorithmName());
     857        jsig.initSign(jpriv);
     858        byte[] data = new byte[111];
     859        net.i2p.util.RandomSource.getInstance().nextBytes(data);
     860        jsig.update(data);
     861        byte[] bsig = jsig.sign();
     862        System.out.println("Encoded signature:");
     863        System.out.println(net.i2p.util.HexDump.dump(bsig));
     864        jsig.initVerify(jpub);
     865        jsig.update(data);
     866        boolean ok = jsig.verify(bsig);
     867        System.out.println("verify passed? " + ok);
     868
     869        net.i2p.data.Signature sig = SigUtil.fromJavaSig(bsig, type);
     870        System.out.println("Signature test: " + sig);
     871    }
    677872****/
    678873}
  • core/java/src/net/i2p/crypto/RSAConstants.java

    ra70a7a7 rebc4ca86  
    1111 * @since 0.9.9
    1212 */
    13 class RSAConstants {
     13final class RSAConstants {
    1414
    1515    /**
  • core/java/src/net/i2p/crypto/SHA256Generator.java

    ra70a7a7 rebc4ca86  
    11package net.i2p.crypto;
    2 
    3 import gnu.crypto.hash.Sha256Standalone;
    42
    53import java.security.DigestException;
     
    1513 *
    1614 * As of release 0.8.7, uses java.security.MessageDigest by default.
    17  * If that is unavailable, it uses
     15 * As of release 0.9.25, uses only MessageDigest.
    1816 * GNU-Crypto {@link gnu.crypto.hash.Sha256Standalone}
     17 * is deprecated.
    1918 */
    2019public final class SHA256Generator {
    2120    private final LinkedBlockingQueue<MessageDigest> _digests;
    22 
    23     private static final boolean _useGnu;
    24 
    25     static {
    26         boolean useGnu = false;
    27         try {
    28             MessageDigest.getInstance("SHA-256");
    29         } catch (NoSuchAlgorithmException e) {
    30             useGnu = true;
    31             System.out.println("INFO: Using GNU SHA-256");
    32         }
    33         _useGnu = useGnu;
    34     }
    3521
    3622    /**
     
    9783   
    9884    /**
    99      *  Return a new MessageDigest from the system libs unless unavailable
    100      *  in this JVM, in that case return a wrapped GNU Sha256Standalone
     85     *  Return a new MessageDigest from the system libs.
    10186     *  @since 0.8.7, public since 0.8.8 for FortunaStandalone
    10287     */
    10388    public static MessageDigest getDigestInstance() {
    104         if (!_useGnu) {
    105             try {
    106                 return MessageDigest.getInstance("SHA-256");
    107             } catch (NoSuchAlgorithmException e) {}
    108         }
    109         return new GnuMessageDigest();
    110     }
    111 
    112     /**
    113      *  Wrapper to make Sha256Standalone a MessageDigest
    114      *  @since 0.8.7
    115      */
    116     private static class GnuMessageDigest extends MessageDigest {
    117         private final Sha256Standalone _gnu;
    118 
    119         protected GnuMessageDigest() {
    120             super("SHA-256");
    121             _gnu = new Sha256Standalone();
    122         }
    123 
    124         protected byte[] engineDigest() {
    125             return _gnu.digest();
    126         }
    127 
    128         protected void engineReset() {
    129             _gnu.reset();
    130         }
    131 
    132         protected void engineUpdate(byte input) {
    133             _gnu.update(input);
    134         }
    135 
    136         protected void engineUpdate(byte[] input, int offset, int len) {
    137             _gnu.update(input, offset, len);
     89        try {
     90            return MessageDigest.getInstance("SHA-256");
     91        } catch (NoSuchAlgorithmException e) {
     92            throw new RuntimeException(e);
    13893        }
    13994    }
  • core/java/src/net/i2p/crypto/SigAlgo.java

    ra70a7a7 rebc4ca86  
    1111    EC("EC"),
    1212    EdDSA("EdDSA"),
    13     RSA("RSA")
     13    /**
     14     *  For local use only, not for use in the network.
     15     */
     16    RSA("RSA"),
     17    /**
     18     *  For local use only, not for use in the network.
     19     *  @since 0.9.25
     20     */
     21    ElGamal("ElGamal")
    1422    ;
    1523
  • core/java/src/net/i2p/crypto/SigType.java

    ra70a7a7 rebc4ca86  
    3333     *  @since 0.9.8
    3434     */
    35     DSA_SHA1(0, 128, 20, 20, 40, SigAlgo.DSA, "SHA-1", "SHA1withDSA", CryptoConstants.DSA_SHA1_SPEC, "0"),
     35    DSA_SHA1(0, 128, 20, 20, 40, SigAlgo.DSA, "SHA-1", "SHA1withDSA", CryptoConstants.DSA_SHA1_SPEC, "1.2.840.10040.4.3", "0"),
    3636    /**  Pubkey 64 bytes; privkey 32 bytes; hash 32 bytes; sig 64 bytes */
    37     ECDSA_SHA256_P256(1, 64, 32, 32, 64, SigAlgo.EC, "SHA-256", "SHA256withECDSA", ECConstants.P256_SPEC, "0.9.12"),
     37    ECDSA_SHA256_P256(1, 64, 32, 32, 64, SigAlgo.EC, "SHA-256", "SHA256withECDSA", ECConstants.P256_SPEC, "1.2.840.10045.4.3.2", "0.9.12"),
    3838    /**  Pubkey 96 bytes; privkey 48 bytes; hash 48 bytes; sig 96 bytes */
    39     ECDSA_SHA384_P384(2, 96, 48, 48, 96, SigAlgo.EC, "SHA-384", "SHA384withECDSA", ECConstants.P384_SPEC, "0.9.12"),
     39    ECDSA_SHA384_P384(2, 96, 48, 48, 96, SigAlgo.EC, "SHA-384", "SHA384withECDSA", ECConstants.P384_SPEC, "1.2.840.10045.4.3.3", "0.9.12"),
    4040    /**  Pubkey 132 bytes; privkey 66 bytes; hash 64 bytes; sig 132 bytes */
    41     ECDSA_SHA512_P521(3, 132, 66, 64, 132, SigAlgo.EC, "SHA-512", "SHA512withECDSA", ECConstants.P521_SPEC, "0.9.12"),
     41    ECDSA_SHA512_P521(3, 132, 66, 64, 132, SigAlgo.EC, "SHA-512", "SHA512withECDSA", ECConstants.P521_SPEC, "1.2.840.10045.4.3.4", "0.9.12"),
    4242
    4343    /**  Pubkey 256 bytes; privkey 512 bytes; hash 32 bytes; sig 256 bytes */
    44     RSA_SHA256_2048(4, 256, 512, 32, 256, SigAlgo.RSA, "SHA-256", "SHA256withRSA", RSAConstants.F4_2048_SPEC, "0.9.12"),
     44    RSA_SHA256_2048(4, 256, 512, 32, 256, SigAlgo.RSA, "SHA-256", "SHA256withRSA", RSAConstants.F4_2048_SPEC, "1.2.840.113549.1.1.11", "0.9.12"),
    4545    /**  Pubkey 384 bytes; privkey 768 bytes; hash 48 bytes; sig 384 bytes */
    46     RSA_SHA384_3072(5, 384, 768, 48, 384, SigAlgo.RSA, "SHA-384", "SHA384withRSA", RSAConstants.F4_3072_SPEC, "0.9.12"),
     46    RSA_SHA384_3072(5, 384, 768, 48, 384, SigAlgo.RSA, "SHA-384", "SHA384withRSA", RSAConstants.F4_3072_SPEC, "1.2.840.113549.1.1.12", "0.9.12"),
    4747    /**  Pubkey 512 bytes; privkey 1024 bytes; hash 64 bytes; sig 512 bytes */
    48     RSA_SHA512_4096(6, 512, 1024, 64, 512, SigAlgo.RSA, "SHA-512", "SHA512withRSA", RSAConstants.F4_4096_SPEC, "0.9.12"),
     48    RSA_SHA512_4096(6, 512, 1024, 64, 512, SigAlgo.RSA, "SHA-512", "SHA512withRSA", RSAConstants.F4_4096_SPEC, "1.2.840.113549.1.1.13", "0.9.12"),
    4949
    5050    /**
     
    5656     */
    5757    EdDSA_SHA512_Ed25519(7, 32, 32, 64, 64, SigAlgo.EdDSA, "SHA-512", "SHA512withEdDSA",
    58                          EdDSANamedCurveTable.getByName("ed25519-sha-512"), "0.9.17");
    59 
     58                         EdDSANamedCurveTable.getByName("ed25519-sha-512"), "1.3.101.101", "0.9.17"),
     59
     60    /**
     61     *  Prehash version (double hashing, for offline use such as su3, not for use on the network)
     62     *  Pubkey 32 bytes; privkey 32 bytes; hash 64 bytes; sig 64 bytes
     63     *  @since 0.9.25
     64     */
     65    EdDSA_SHA512_Ed25519ph(8, 32, 32, 64, 64, SigAlgo.EdDSA, "SHA-512", "NonewithEdDSA",
     66                           EdDSANamedCurveTable.getByName("ed25519-sha-512"), "1.3.101.101", "0.9.25"),
     67
     68    ;
    6069
    6170    // TESTING....................
     
    100109    private final int code, pubkeyLen, privkeyLen, hashLen, sigLen;
    101110    private final SigAlgo base;
    102     private final String digestName, algoName, since;
     111    private final String digestName, algoName, oid, since;
    103112    private final AlgorithmParameterSpec params;
    104113    private final boolean isAvail;
    105114
    106115    SigType(int cod, int pubLen, int privLen, int hLen, int sLen, SigAlgo baseAlgo,
    107             String mdName, String aName, AlgorithmParameterSpec pSpec, String supportedSince) {
     116            String mdName, String aName, AlgorithmParameterSpec pSpec, String oid, String supportedSince) {
    108117        code = cod;
    109118        pubkeyLen = pubLen;
     
    115124        algoName = aName;
    116125        params = pSpec;
     126        this.oid = oid;
    117127        since = supportedSince;
    118128        isAvail = x_isAvailable();
     
    182192    public String getSupportedSince() {
    183193        return since;
     194    }
     195
     196    /**
     197     *  The OID for the signature.
     198     *
     199     *  @since 0.9.25
     200     */
     201    public String getOID() {
     202        return oid;
    184203    }
    185204
     
    275294            if (uc.equals("EDDSA_SHA512_ED25519"))
    276295                return EdDSA_SHA512_Ed25519;
     296            if (uc.equals("EDDSA_SHA512_ED25519PH"))
     297                return EdDSA_SHA512_Ed25519ph;
    277298            return valueOf(uc);
    278299        } catch (IllegalArgumentException iae) {
  • core/java/src/net/i2p/crypto/SigUtil.java

    ra70a7a7 rebc4ca86  
    5151 * @since 0.9.9, public since 0.9.12
    5252 */
    53 public class SigUtil {
     53public final class SigUtil {
    5454
    5555    private static final Map<SigningPublicKey, ECPublicKey> _ECPubkeyCache = new LHMCache<SigningPublicKey, ECPublicKey>(64);
     
    142142            return fromJavaKey(k, type);
    143143        }
    144         throw new IllegalArgumentException("Unknown type");
     144        throw new IllegalArgumentException("Unknown type: " + pk.getClass());
    145145    }
    146146
     
    162162                return fromJavaKey((RSAPublicKey) pk, type);
    163163            default:
    164                 throw new IllegalArgumentException();
     164                throw new IllegalArgumentException("Unknown type: " + type);
    165165        }
    166166    }
     
    210210            return fromJavaKey(k, type);
    211211        }
    212         throw new IllegalArgumentException("Unknown type");
     212        throw new IllegalArgumentException("Unknown type: " + pk.getClass());
    213213    }
    214214
     
    230230                return fromJavaKey((RSAPrivateKey) pk, type);
    231231            default:
    232                 throw new IllegalArgumentException();
     232                throw new IllegalArgumentException("Unknown type: " + type);
    233233        }
    234234    }
     
    550550    /**
    551551     *  Split a byte array into two BigIntegers
     552     *  @param b length must be even
    552553     *  @return array of two BigIntegers
    553      */
    554     private static BigInteger[] split(byte[] b) {
     554     *  @since 0.9.9
     555     */
     556    private static NativeBigInteger[] split(byte[] b) {
     557        if ((b.length & 0x01) != 0)
     558            throw new IllegalArgumentException("length must be even");
    555559        int sublen = b.length / 2;
    556560        byte[] bx = new byte[sublen];
     
    566570     *  Combine two BigIntegers of nominal length = len / 2
    567571     *  @return array of exactly len bytes
     572     *  @since 0.9.9
    568573     */
    569574    private static byte[] combine(BigInteger x, BigInteger y, int len)
    570575                              throws InvalidKeyException {
     576        if ((len & 0x01) != 0)
     577            throw new InvalidKeyException("length must be even");
    571578        int sublen = len / 2;
    572579        byte[] b = new byte[len];
     
    610617    /**
    611618     *  http://download.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html
    612      *  Signature Format        ASN.1 sequence of two INTEGER values: r and s, in that order:
     619     *<pre>
     620     *  Signature Format: ASN.1 sequence of two INTEGER values: r and s, in that order:
    613621     *                                SEQUENCE ::= { r INTEGER, s INTEGER }
    614622     *
     
    620628     *  xx - length in octets
    621629     *  xxxxxx - value
     630     *</pre>
    622631     *
    623632     *  Convert to BigInteger and back so we have the minimum length representation, as required.
     
    627636     *  add a SigType with bigger signatures.
    628637     *
     638     *  @param sig length must be even
    629639     *  @throws IllegalArgumentException if too big
    630640     *  @since 0.8.7, moved to SigUtil in 0.9.9
    631641     */
    632642    private static byte[] sigBytesToASN1(byte[] sig) {
    633         //System.out.println("pre TO asn1\n" + net.i2p.util.HexDump.dump(sig));
    634         int len = sig.length;
    635         int sublen = len / 2;
    636         byte[] tmp = new byte[sublen];
    637 
    638         System.arraycopy(sig, 0, tmp, 0, sublen);
    639         BigInteger r = new BigInteger(1, tmp);
     643        BigInteger[] rs = split(sig);
     644        return sigBytesToASN1(rs[0], rs[1]);
     645    }
     646
     647    /**
     648     *  http://download.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html
     649     *<pre>
     650     *  Signature Format: ASN.1 sequence of two INTEGER values: r and s, in that order:
     651     *                                SEQUENCE ::= { r INTEGER, s INTEGER }
     652     *
     653     *  http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One
     654     *  30 -- tag indicating SEQUENCE
     655     *  xx - length in octets
     656     *
     657     *  02 -- tag indicating INTEGER
     658     *  xx - length in octets
     659     *  xxxxxx - value
     660     *</pre>
     661     *
     662     *  r and s are always non-negative.
     663     *
     664     *  Only supports sigs up to about 65530 bytes. See code to fix BER encoding for this before you
     665     *  add a SigType with bigger signatures.
     666     *
     667     *  @throws IllegalArgumentException if too big
     668     *  @since 0.9.25, split out from sigBytesToASN1(byte[])
     669     */
     670    public static byte[] sigBytesToASN1(BigInteger r, BigInteger s) {
     671        int extra = 4;
    640672        byte[] rb = r.toByteArray();
    641         if (rb.length > 127)
    642             throw new IllegalArgumentException("FIXME R length > 127");
    643         System.arraycopy(sig, sublen, tmp, 0, sublen);
    644         BigInteger s = new BigInteger(1, tmp);
     673        if (rb.length > 127) {
     674            extra++;
     675            if (rb.length > 255)
     676                extra++;
     677        }
    645678        byte[] sb = s.toByteArray();
    646         if (sb.length > 127)
    647             throw new IllegalArgumentException("FIXME S length > 127");
    648         int seqlen = rb.length + sb.length + 4;
    649         if (seqlen > 255)
    650             throw new IllegalArgumentException("FIXME seq length > 255");
     679        if (sb.length > 127) {
     680            extra++;
     681            if (sb.length > 255)
     682                extra++;
     683        }
     684        int seqlen = rb.length + sb.length + extra;
    651685        int totlen = seqlen + 2;
    652         if (seqlen > 127)
     686        if (seqlen > 127) {
    653687            totlen++;
     688            if (seqlen > 255)
     689                totlen++;
     690        }
    654691        byte[] rv = new byte[totlen];
    655692        int idx = 0;
    656693
    657694        rv[idx++] = 0x30;
    658         if (seqlen > 127)
    659             rv[idx++] =(byte) 0x81;
    660         rv[idx++] = (byte) seqlen;
     695        idx = intToASN1(rv, idx, seqlen);
    661696
    662697        rv[idx++] = 0x02;
    663         rv[idx++] = (byte) rb.length;
     698        idx = intToASN1(rv, idx, rb.length);
    664699        System.arraycopy(rb, 0, rv, idx, rb.length);
    665700        idx += rb.length;
    666701
    667702        rv[idx++] = 0x02;
    668         rv[idx++] = (byte) sb.length;
     703        idx = intToASN1(rv, idx, sb.length);
    669704        System.arraycopy(sb, 0, rv, idx, sb.length);
    670705
     
    674709
    675710    /**
     711     *  Output an length or integer value in ASN.1
     712     *  Does NOT output the tag e.g. 0x02 / 0x30
     713     *
     714     *  @param val 0-65535
     715     *  @return the new index
     716     *  @since 0.9.25
     717     */
     718    public static int intToASN1(byte[] d, int idx, int val) {
     719        if (val < 0 || val > 65535)
     720            throw new IllegalArgumentException("fixme length " + val);
     721        if (val > 127) {
     722            if (val > 255) {
     723                d[idx++] = (byte) 0x82;
     724                d[idx++] = (byte) (val >> 8);
     725            } else {
     726                d[idx++] = (byte) 0x81;
     727            }
     728        }
     729        d[idx++] = (byte) val;
     730        return idx;
     731    }
     732
     733    /**
    676734     *  See above.
    677      *  Only supports sigs up to about 252 bytes. See code to fix BER encoding for bigger than that.
    678      *
    679      *  @return len bytes
     735     *  Only supports sigs up to about 65530 bytes. See code to fix BER encoding for bigger than that.
     736     *
     737     *  @param len must be even, twice the nominal length of each BigInteger
     738     *  @return len bytes, call split() on the result to get two BigIntegers
    680739     *  @since 0.8.7, moved to SigUtil in 0.9.9
    681740     */
     
    694753        int sublen = len / 2;
    695754        int rlen = asn[++idx];
    696         if ((rlen & 0x80) != 0)
    697             throw new SignatureException("FIXME R length > 127");
     755        if ((rlen & 0x80) != 0) {
     756            if ((rlen & 0xff) == 0x81) {
     757                rlen = asn[++idx] & 0xff;
     758            } else if ((rlen & 0xff) == 0x82) {
     759                rlen = asn[++idx] & 0xff;
     760                rlen <<= 8;
     761                rlen |= asn[++idx] & 0xff;
     762            } else {
     763                throw new SignatureException("FIXME R length > 65535");
     764            }
     765        }
    698766        if ((asn[++idx] & 0x80) != 0)
    699767            throw new SignatureException("R is negative");
     
    705773            System.arraycopy(asn, idx, rv, sublen - rlen, rlen);
    706774        idx += rlen;
    707         int slenloc = idx + 1;
     775
    708776        if (asn[idx] != 0x02)
    709777            throw new SignatureException("asn[s] = " + (asn[idx] & 0xff));
    710         int slen = asn[slenloc];
    711         if ((slen & 0x80) != 0)
    712             throw new SignatureException("FIXME S length > 127");
    713         if ((asn[slenloc + 1] & 0x80) != 0)
     778        int slen = asn[++idx];
     779        if ((slen & 0x80) != 0) {
     780            if ((slen & 0xff) == 0x81) {
     781                slen = asn[++idx] & 0xff;
     782            } else if ((slen & 0xff) == 0x82) {
     783                slen = asn[++idx] & 0xff;
     784                slen <<= 8;
     785                slen |= asn[++idx] & 0xff;
     786            } else {
     787                throw new SignatureException("FIXME S length > 65535");
     788            }
     789        }
     790        if ((asn[++idx] & 0x80) != 0)
    714791            throw new SignatureException("S is negative");
    715792        if (slen > sublen + 1)
    716793            throw new SignatureException("S too big " + slen);
    717794        if (slen == sublen + 1)
    718             System.arraycopy(asn, slenloc + 2, rv, sublen, sublen);
     795            System.arraycopy(asn, idx + 1, rv, sublen, sublen);
    719796        else
    720             System.arraycopy(asn, slenloc + 1, rv, len - slen, slen);
     797            System.arraycopy(asn, idx, rv, len - slen, slen);
    721798        //System.out.println("post from asn1\n" + net.i2p.util.HexDump.dump(rv));
    722799        return rv;
     800    }
     801
     802    /**
     803     *  See above.
     804     *  Only supports sigs up to about 65530 bytes. See code to fix BER encoding for bigger than that.
     805     *
     806     *  @param len nominal length of each BigInteger
     807     *  @return two BigIntegers
     808     *  @since 0.9.25
     809     */
     810    public static NativeBigInteger[] aSN1ToBigInteger(byte[] asn, int len)
     811                              throws SignatureException {
     812        byte[] sig = aSN1ToSigBytes(asn, len * 2);
     813        return split(sig);
    723814    }
    724815
  • core/java/src/net/i2p/crypto/YKGenerator.java

    ra70a7a7 rebc4ca86  
    3636 * @author jrandom
    3737 */
    38 class YKGenerator {
     38final class YKGenerator {
    3939    //private final static Log _log = new Log(YKGenerator.class);
    4040    private final int MIN_NUM_BUILDERS;
  • core/java/src/net/i2p/crypto/eddsa/EdDSAEngine.java

    ra70a7a7 rebc4ca86  
    33import java.io.ByteArrayOutputStream;
    44import java.nio.ByteBuffer;
     5import java.security.InvalidAlgorithmParameterException;
    56import java.security.InvalidKeyException;
    67import java.security.MessageDigest;
     
    1011import java.security.Signature;
    1112import java.security.SignatureException;
     13import java.security.spec.AlgorithmParameterSpec;
    1214import java.util.Arrays;
    1315
     
    1719
    1820/**
     21 * Signing and verification for EdDSA.
     22 *<p>
     23 * The EdDSA sign and verify algorithms do not interact well with
     24 * the Java Signature API, as one or more update() methods must be
     25 * called before sign() or verify(). Using the standard API,
     26 * this implementation must copy and buffer all data passed in
     27 * via update().
     28 *</p><p>
     29 * This implementation offers two ways to avoid this copying,
     30 * but only if all data to be signed or verified is available
     31 * in a single byte array.
     32 *</p><p>
     33 *Option 1:
     34 *</p><ol>
     35 *<li>Call initSign() or initVerify() as usual.
     36 *</li><li>Call setParameter(ONE_SHOT_MOE)
     37 *</li><li>Call update(byte[]) or update(byte[], int, int) exactly once
     38 *</li><li>Call sign() or verify() as usual.
     39 *</li><li>If doing additional one-shot signs or verifies with this object, you must
     40 *         call setParameter(ONE_SHOT_MODE) each time
     41 *</li></ol>
     42 *
     43 *<p>
     44 *Option 2:
     45 *</p><ol>
     46 *<li>Call initSign() or initVerify() as usual.
     47 *</li><li>Call one of the signOneShot() or verifyOneShot() methods.
     48 *</li><li>If doing additional one-shot signs or verifies with this object,
     49 *         just call signOneShot() or verifyOneShot() again.
     50 *</li></ol>
     51 *
    1952 * @since 0.9.15
    2053 * @author str4d
    2154 *
    2255 */
    23 public class EdDSAEngine extends Signature {
     56public final class EdDSAEngine extends Signature {
    2457    private MessageDigest digest;
    25     private final ByteArrayOutputStream baos;
     58    private ByteArrayOutputStream baos;
    2659    private EdDSAKey key;
     60    private boolean oneShotMode;
     61    private byte[] oneShotBytes;
     62    private int oneShotOffset;
     63    private int oneShotLength;
     64
     65    /**
     66     *  To efficiently sign or verify data in one shot, pass this to setParameters()
     67     *  after initSign() or initVerify() but BEFORE THE FIRST AND ONLY
     68     *  update(data) or update(data, off, len). The data reference will be saved
     69     *  and then used in sign() or verify() without copying the data.
     70     *  Violate these rules and you will get a SignatureException.
     71     *
     72     *  @since 0.9.25
     73     */
     74    public static final AlgorithmParameterSpec ONE_SHOT_MODE = new OneShotSpec();
     75
     76    private static class OneShotSpec implements AlgorithmParameterSpec {}
    2777
    2878    /**
     
    3181    public EdDSAEngine() {
    3282        super("EdDSA");
    33         baos = new ByteArrayOutputStream(256);
    3483    }
    3584
     
    4392    }
    4493
    45     @Override
    46     protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
     94    /**
     95     * @since 0.9.25
     96     */
     97    private void reset() {
    4798        if (digest != null)
    4899            digest.reset();
    49         baos.reset();
    50 
     100        if (baos != null)
     101            baos.reset();
     102        oneShotMode = false;
     103        oneShotBytes = null;
     104    }
     105
     106    @Override
     107    protected void engineInitSign(PrivateKey privateKey) throws InvalidKeyException {
     108        reset();
    51109        if (privateKey instanceof EdDSAPrivateKey) {
    52110            EdDSAPrivateKey privKey = (EdDSAPrivateKey) privateKey;
     
    62120            } else if (!key.getParams().getHashAlgorithm().equals(digest.getAlgorithm()))
    63121                throw new InvalidKeyException("Key hash algorithm does not match chosen digest");
    64 
    65             // Preparing for hash
    66             // r = H(h_b,...,h_2b-1,M)
    67             int b = privKey.getParams().getCurve().getField().getb();
    68             digest.update(privKey.getH(), b/8, b/4 - b/8);
    69         } else
    70             throw new InvalidKeyException("cannot identify EdDSA private key.");
     122            digestInitSign(privKey);
     123        } else {
     124            throw new InvalidKeyException("cannot identify EdDSA private key: " + privateKey.getClass());
     125        }
     126    }
     127
     128    private void digestInitSign(EdDSAPrivateKey privKey) {
     129        // Preparing for hash
     130        // r = H(h_b,...,h_2b-1,M)
     131        int b = privKey.getParams().getCurve().getField().getb();
     132        digest.update(privKey.getH(), b/8, b/4 - b/8);
    71133    }
    72134
    73135    @Override
    74136    protected void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
    75         if (digest != null)
    76             digest.reset();
    77         baos.reset();
    78 
     137        reset();
    79138        if (publicKey instanceof EdDSAPublicKey) {
    80139            key = (EdDSAPublicKey) publicKey;
     
    89148            } else if (!key.getParams().getHashAlgorithm().equals(digest.getAlgorithm()))
    90149                throw new InvalidKeyException("Key hash algorithm does not match chosen digest");
    91         } else
    92             throw new InvalidKeyException("cannot identify EdDSA public key.");
    93     }
    94 
     150        } else {
     151            throw new InvalidKeyException("cannot identify EdDSA public key: " + publicKey.getClass());
     152        }
     153    }
     154
     155    /**
     156     * @throws SignatureException if in one-shot mode
     157     */
    95158    @Override
    96159    protected void engineUpdate(byte b) throws SignatureException {
    97         // We need to store the message because it is used in several hashes
    98         // XXX Can this be done more efficiently?
     160        if (oneShotMode)
     161            throw new SignatureException("unsupported in one-shot mode");
     162        if (baos == null)
     163            baos = new ByteArrayOutputStream(256);
    99164        baos.write(b);
    100165    }
    101166
     167    /**
     168     * @throws SignatureException if one-shot rules are violated
     169     */
    102170    @Override
    103171    protected void engineUpdate(byte[] b, int off, int len)
    104172            throws SignatureException {
    105         // We need to store the message because it is used in several hashes
    106         // XXX Can this be done more efficiently?
    107         baos.write(b, off, len);
     173        if (oneShotMode) {
     174            if (oneShotBytes != null)
     175                throw new SignatureException("update() already called");
     176            oneShotBytes = b;
     177            oneShotOffset = off;
     178            oneShotLength = len;
     179        } else {
     180            if (baos == null)
     181                baos = new ByteArrayOutputStream(256);
     182            baos.write(b, off, len);
     183        }
    108184    }
    109185
    110186    @Override
    111187    protected byte[] engineSign() throws SignatureException {
     188        try {
     189            return x_engineSign();
     190        } finally {
     191            reset();
     192            // must leave the object ready to sign again with
     193            // the same key, as required by the API
     194            EdDSAPrivateKey privKey = (EdDSAPrivateKey) key;
     195            digestInitSign(privKey);
     196        }
     197    }
     198
     199    private byte[] x_engineSign() throws SignatureException {
    112200        Curve curve = key.getParams().getCurve();
    113201        ScalarOps sc = key.getParams().getScalarOps();
    114202        byte[] a = ((EdDSAPrivateKey) key).geta();
    115203
    116         byte[] message = baos.toByteArray();
     204        byte[] message;
     205        int offset, length;
     206        if (oneShotMode) {
     207            if (oneShotBytes == null)
     208                throw new SignatureException("update() not called first");
     209            message = oneShotBytes;
     210            offset = oneShotOffset;
     211            length = oneShotLength;
     212        } else {
     213            if (baos == null)
     214                message = new byte[0];
     215            else
     216                message = baos.toByteArray();
     217            offset = 0;
     218            length = message.length;
     219        }
    117220        // r = H(h_b,...,h_2b-1,M)
    118         byte[] r = digest.digest(message);
     221        digest.update(message, offset, length);
     222        byte[] r = digest.digest();
    119223
    120224        // r mod l
     
    129233        digest.update(Rbyte);
    130234        digest.update(((EdDSAPrivateKey) key).getAbyte());
    131         byte[] h = digest.digest(message);
     235        digest.update(message, offset, length);
     236        byte[] h = digest.digest();
    132237        h = sc.reduce(h);
    133238        byte[] S = sc.multiplyAndAdd(h, a, r);
     
    142247    @Override
    143248    protected boolean engineVerify(byte[] sigBytes) throws SignatureException {
     249        try {
     250            return x_engineVerify(sigBytes);
     251        } finally {
     252            reset();
     253        }
     254    }
     255
     256    private boolean x_engineVerify(byte[] sigBytes) throws SignatureException {
    144257        Curve curve = key.getParams().getCurve();
    145258        int b = curve.getField().getb();
     
    151264        digest.update(((EdDSAPublicKey) key).getAbyte());
    152265        // h = H(Rbar,Abar,M)
    153         byte[] message = baos.toByteArray();
    154         byte[] h = digest.digest(message);
     266        byte[] message;
     267        int offset, length;
     268        if (oneShotMode) {
     269            if (oneShotBytes == null)
     270                throw new SignatureException("update() not called first");
     271            message = oneShotBytes;
     272            offset = oneShotOffset;
     273            length = oneShotLength;
     274        } else {
     275            if (baos == null)
     276                message = new byte[0];
     277            else
     278                message = baos.toByteArray();
     279            offset = 0;
     280            length = message.length;
     281        }
     282        digest.update(message, offset, length);
     283        byte[] h = digest.digest();
    155284
    156285        // h mod l
     
    173302
    174303    /**
     304     *  To efficiently sign all the data in one shot, if it is available,
     305     *  use this method, which will avoid copying the data.
     306     *
     307     * Same as:
     308     *<pre>
     309     *  setParameter(ONE_SHOT_MODE)
     310     *  update(data)
     311     *  sig = sign()
     312     *</pre>
     313     *
     314     * @throws SignatureException if update() already called
     315     * @see #ONE_SHOT_MODE
     316     * @since 0.9.25
     317     */
     318    public byte[] signOneShot(byte[] data) throws SignatureException {
     319        return signOneShot(data, 0, data.length);
     320    }
     321
     322    /**
     323     *  To efficiently sign all the data in one shot, if it is available,
     324     *  use this method, which will avoid copying the data.
     325     *
     326     * Same as:
     327     *<pre>
     328     *  setParameter(ONE_SHOT_MODE)
     329     *  update(data, off, len)
     330     *  sig = sign()
     331     *</pre>
     332     *
     333     * @throws SignatureException if update() already called
     334     * @see #ONE_SHOT_MODE
     335     * @since 0.9.25
     336     */
     337    public byte[] signOneShot(byte[] data, int off, int len) throws SignatureException {
     338        oneShotMode = true;
     339        update(data, off, len);
     340        return sign();
     341    }
     342
     343    /**
     344     *  To efficiently verify all the data in one shot, if it is available,
     345     *  use this method, which will avoid copying the data.
     346     *
     347     * Same as:
     348     *<pre>
     349     *  setParameter(ONE_SHOT_MODE)
     350     *  update(data)
     351     *  ok = verify(signature)
     352     *</pre>
     353     *
     354     * @throws SignatureException if update() already called
     355     * @see #ONE_SHOT_MODE
     356     * @since 0.9.25
     357     */
     358    public boolean verifyOneShot(byte[] data, byte[] signature) throws SignatureException {
     359        return verifyOneShot(data, 0, data.length, signature, 0, signature.length);
     360    }
     361
     362    /**
     363     *  To efficiently verify all the data in one shot, if it is available,
     364     *  use this method, which will avoid copying the data.
     365     *
     366     * Same as:
     367     *<pre>
     368     *  setParameter(ONE_SHOT_MODE)
     369     *  update(data, off, len)
     370     *  ok = verify(signature)
     371     *</pre>
     372     *
     373     * @throws SignatureException if update() already called
     374     * @see #ONE_SHOT_MODE
     375     * @since 0.9.25
     376     */
     377    public boolean verifyOneShot(byte[] data, int off, int len, byte[] signature) throws SignatureException {
     378        return verifyOneShot(data, off, len, signature, 0, signature.length);
     379    }
     380
     381    /**
     382     *  To efficiently verify all the data in one shot, if it is available,
     383     *  use this method, which will avoid copying the data.
     384     *
     385     * Same as:
     386     *<pre>
     387     *  setParameter(ONE_SHOT_MODE)
     388     *  update(data)
     389     *  ok = verify(signature, sigoff, siglen)
     390     *</pre>
     391     *
     392     * @throws SignatureException if update() already called
     393     * @see #ONE_SHOT_MODE
     394     * @since 0.9.25
     395     */
     396    public boolean verifyOneShot(byte[] data, byte[] signature, int sigoff, int siglen) throws SignatureException {
     397        return verifyOneShot(data, 0, data.length, signature, sigoff, siglen);
     398    }
     399
     400    /**
     401     *  To efficiently verify all the data in one shot, if it is available,
     402     *  use this method, which will avoid copying the data.
     403     *
     404     * Same as:
     405     *<pre>
     406     *  setParameter(ONE_SHOT_MODE)
     407     *  update(data, off, len)
     408     *  ok = verify(signature, sigoff, siglen)
     409     *</pre>
     410     *
     411     * @throws SignatureException if update() already called
     412     * @see #ONE_SHOT_MODE
     413     * @since 0.9.25
     414     */
     415    public boolean verifyOneShot(byte[] data, int off, int len, byte[] signature, int sigoff, int siglen) throws SignatureException {
     416        oneShotMode = true;
     417        update(data, off, len);
     418        return verify(signature, sigoff, siglen);
     419    }
     420
     421    /**
     422     * @throws InvalidAlgorithmParameterException if spec is ONE_SHOT_MODE and update() already called
     423     * @see #ONE_SHOT_MODE
     424     * @since 0.9.25
     425     */
     426    @Override
     427    protected void engineSetParameter(AlgorithmParameterSpec spec) throws InvalidAlgorithmParameterException {
     428        if (spec.equals(ONE_SHOT_MODE)) {
     429            if (oneShotBytes != null || baos != null && baos.size() > 0)
     430                throw new InvalidAlgorithmParameterException("update() already called");
     431            oneShotMode = true;
     432        } else {
     433            super.engineSetParameter(spec);
     434        }
     435    }
     436
     437    /**
    175438     * @deprecated replaced with <a href="#engineSetParameter(java.security.spec.AlgorithmParameterSpec)">
    176439     */
  • core/java/src/net/i2p/crypto/eddsa/EdDSAPrivateKey.java

    ra70a7a7 rebc4ca86  
    22
    33import java.security.PrivateKey;
     4import java.security.spec.InvalidKeySpecException;
     5import java.security.spec.PKCS8EncodedKeySpec;
     6import java.util.Arrays;
    47
    58import net.i2p.crypto.eddsa.math.GroupElement;
     9import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
    610import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
    711import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
     
    913/**
    1014 * An EdDSA private key.
     15 *<p>
     16 * Warning: Private key encoding is not fully specified in the
     17 * current IETF draft. This implementation uses PKCS#8 encoding,
     18 * and is subject to change. See getEncoded().
     19 *</p><p>
     20 * Ref: https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04
     21 *</p>
    1122 *
    1223 * @since 0.9.15
     
    3243    }
    3344
     45    /**
     46     *  @since 0.9.25
     47     */
     48    public EdDSAPrivateKey(PKCS8EncodedKeySpec spec) throws InvalidKeySpecException {
     49        this(new EdDSAPrivateKeySpec(decode(spec.getEncoded()),
     50                                     EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512)));
     51    }
     52
    3453    public String getAlgorithm() {
    3554        return "EdDSA";
     
    4059    }
    4160
     61    /**
     62     *  This follows the docs from
     63     *  java.security.spec.PKCS8EncodedKeySpec
     64     *  quote:
     65     *<pre>
     66     *  The PrivateKeyInfo syntax is defined in the PKCS#8 standard as follows:
     67     *  PrivateKeyInfo ::= SEQUENCE {
     68     *    version Version,
     69     *    privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
     70     *    privateKey PrivateKey,
     71     *    attributes [0] IMPLICIT Attributes OPTIONAL }
     72     *  Version ::= INTEGER
     73     *  PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
     74     *  PrivateKey ::= OCTET STRING
     75     *  Attributes ::= SET OF Attribute
     76     *</pre>
     77     *
     78     *<pre>
     79     *  AlgorithmIdentifier ::= SEQUENCE
     80     *  {
     81     *    algorithm           OBJECT IDENTIFIER,
     82     *    parameters          ANY OPTIONAL
     83     *  }
     84     *</pre>
     85     *
     86     *  Ref: https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04
     87     *
     88     *  Note that the private key encoding is not fully specified in the Josefsson draft version 04,
     89     *  and the example could be wrong, as it's lacking Version and AlgorithmIdentifier.
     90     *  This will hopefully be clarified in the next draft.
     91     *  But sun.security.pkcs.PKCS8Key expects them so we must include them for keytool to work.
     92     *
     93     *  @return 49 bytes for Ed25519, null for other curves
     94     *  @since implemented in 0.9.25
     95     */
    4296    public byte[] getEncoded() {
    43         // TODO Auto-generated method stub
    44         return null;
     97        if (!edDsaSpec.equals(EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512)))
     98            return null;
     99        int totlen = 17 + seed.length;
     100        byte[] rv = new byte[totlen];
     101        int idx = 0;
     102        // sequence
     103        rv[idx++] = 0x30;
     104        rv[idx++] = (byte) (15 + seed.length);
     105
     106        // version
     107        // not in the Josefsson example
     108        rv[idx++] = 0x02;
     109        rv[idx++] = 1;
     110        rv[idx++] = 0;
     111
     112        // Algorithm Identifier
     113        // sequence
     114        // not in the Josefsson example
     115        rv[idx++] = 0x30;
     116        rv[idx++] = 8;
     117        // OID 1.3.101.100
     118        // https://msdn.microsoft.com/en-us/library/windows/desktop/bb540809%28v=vs.85%29.aspx
     119        // not in the Josefsson example
     120        rv[idx++] = 0x06;
     121        rv[idx++] = 3;
     122        rv[idx++] = (1 * 40) + 3;
     123        rv[idx++] = 101;
     124        rv[idx++] = 100;
     125        // params
     126        rv[idx++] = 0x0a;
     127        rv[idx++] = 1;
     128        rv[idx++] = 1; // Ed25519
     129        // the key
     130        rv[idx++] = 0x04;  // octet string
     131        rv[idx++] = (byte) seed.length;
     132        System.arraycopy(seed, 0, rv, idx, seed.length);
     133        return rv;
     134    }
     135
     136    /**
     137     *  This is really dumb for now.
     138     *  See getEncoded().
     139     *
     140     *  @return 32 bytes for Ed25519, throws for other curves
     141     *  @since 0.9.25
     142     */
     143    private static byte[] decode(byte[] d) throws InvalidKeySpecException {
     144        try {
     145            int idx = 0;
     146            if (d[idx++] != 0x30 ||
     147                d[idx++] != 47 ||
     148                d[idx++] != 0x02 ||
     149                d[idx++] != 1 ||
     150                d[idx++] != 0 ||
     151                d[idx++] != 0x30 ||
     152                d[idx++] != 8 ||
     153                d[idx++] != 0x06 ||
     154                d[idx++] != 3 ||
     155                d[idx++] != (1 * 40) + 3 ||
     156                d[idx++] != 101 ||
     157                d[idx++] != 100 ||
     158                d[idx++] != 0x0a ||
     159                d[idx++] != 1 ||
     160                d[idx++] != 1 ||
     161                d[idx++] != 0x04 ||
     162                d[idx++] != 32) {
     163                throw new InvalidKeySpecException("unsupported key spec");
     164            }
     165            byte[] rv = new byte[32];
     166            System.arraycopy(d, idx, rv, 0, 32);
     167            return rv;
     168        } catch (IndexOutOfBoundsException ioobe) {
     169            throw new InvalidKeySpecException(ioobe);
     170        }
    45171    }
    46172
     
    68194        return Abyte;
    69195    }
     196
     197    /**
     198     *  @since 0.9.25
     199     */
     200    @Override
     201    public int hashCode() {
     202        return Arrays.hashCode(seed);
     203    }
     204
     205    /**
     206     *  @since 0.9.25
     207     */
     208    @Override
     209    public boolean equals(Object o) {
     210        if (o == this)
     211            return true;
     212        if (!(o instanceof EdDSAPrivateKey))
     213            return false;
     214        EdDSAPrivateKey pk = (EdDSAPrivateKey) o;
     215        return Arrays.equals(seed, pk.getSeed()) &&
     216               edDsaSpec.equals(pk.getParams());
     217    }
    70218}
  • core/java/src/net/i2p/crypto/eddsa/EdDSAPublicKey.java

    ra70a7a7 rebc4ca86  
    22
    33import java.security.PublicKey;
     4import java.security.spec.InvalidKeySpecException;
     5import java.security.spec.X509EncodedKeySpec;
     6import java.util.Arrays;
    47
    58import net.i2p.crypto.eddsa.math.GroupElement;
     9import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
    610import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec;
    711import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec;
     
    913/**
    1014 * An EdDSA public key.
     15 *<p>
     16 * Warning: Public key encoding is is based on the
     17 * current IETF draft, and is subject to change. See getEncoded().
     18 *</p><p>
     19 * Ref: https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04
     20 *</p>
    1121 *
    1222 * @since 0.9.15
     
    2838    }
    2939
     40    /**
     41     *  @since 0.9.25
     42     */
     43    public EdDSAPublicKey(X509EncodedKeySpec spec) throws InvalidKeySpecException {
     44        this(new EdDSAPublicKeySpec(decode(spec.getEncoded()),
     45                                    EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512)));
     46    }
     47
    3048    public String getAlgorithm() {
    3149        return "EdDSA";
     
    3654    }
    3755
     56    /**
     57     *  This follows the spec at
     58     *  ref: https://tools.ietf.org/html/draft-josefsson-pkix-eddsa-04
     59     *  which matches the docs from
     60     *  java.security.spec.X509EncodedKeySpec
     61     *  quote:
     62     *<pre>
     63     * The SubjectPublicKeyInfo syntax is defined in the X.509 standard as follows:
     64     *  SubjectPublicKeyInfo ::= SEQUENCE {
     65     *    algorithm AlgorithmIdentifier,
     66     *    subjectPublicKey BIT STRING }
     67     *</pre>
     68     *
     69     *<pre>
     70     *  AlgorithmIdentifier ::= SEQUENCE
     71     *  {
     72     *    algorithm           OBJECT IDENTIFIER,
     73     *    parameters          ANY OPTIONAL
     74     *  }
     75     *</pre>
     76     *
     77     *  @return 47 bytes for Ed25519, null for other curves
     78     *  @since implemented in 0.9.25
     79     */
    3880    public byte[] getEncoded() {
    39         // TODO Auto-generated method stub
    40         return null;
     81        if (!edDsaSpec.equals(EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512)))
     82            return null;
     83        int totlen = 15 + Abyte.length;
     84        byte[] rv = new byte[totlen];
     85        int idx = 0;
     86        // sequence
     87        rv[idx++] = 0x30;
     88        rv[idx++] = (byte) (13 + Abyte.length);
     89        // Algorithm Identifier
     90        // sequence
     91        rv[idx++] = 0x30;
     92        rv[idx++] = 8;
     93        // OID 1.3.101.100
     94        // https://msdn.microsoft.com/en-us/library/windows/desktop/bb540809%28v=vs.85%29.aspx
     95        rv[idx++] = 0x06;
     96        rv[idx++] = 3;
     97        rv[idx++] = (1 * 40) + 3;
     98        rv[idx++] = 101;
     99        rv[idx++] = 100;
     100        // params
     101        rv[idx++] = 0x0a;
     102        rv[idx++] = 1;
     103        rv[idx++] = 1; // Ed25519
     104        // the key
     105        rv[idx++] = 0x03; // bit string
     106        rv[idx++] = (byte) (1 + Abyte.length);
     107        rv[idx++] = 0; // number of trailing unused bits
     108        System.arraycopy(Abyte, 0, rv, idx, Abyte.length);
     109        return rv;
     110    }
     111
     112    /**
     113     *  This is really dumb for now.
     114     *  See getEncoded().
     115     *
     116     *  @return 32 bytes for Ed25519, throws for other curves
     117     *  @since 0.9.25
     118     */
     119    private static byte[] decode(byte[] d) throws InvalidKeySpecException {
     120        try {
     121            int idx = 0;
     122            if (d[idx++] != 0x30 ||
     123                d[idx++] != 45 ||
     124                d[idx++] != 0x30 ||
     125                d[idx++] != 8 ||
     126                d[idx++] != 0x06 ||
     127                d[idx++] != 3 ||
     128                d[idx++] != (1 * 40) + 3 ||
     129                d[idx++] != 101 ||
     130                d[idx++] != 100 ||
     131                d[idx++] != 0x0a ||
     132                d[idx++] != 1 ||
     133                d[idx++] != 1 ||
     134                d[idx++] != 0x03 ||
     135                d[idx++] != 33 ||
     136                d[idx++] != 0) {
     137                throw new InvalidKeySpecException("unsupported key spec");
     138            }
     139            byte[] rv = new byte[32];
     140            System.arraycopy(d, idx, rv, 0, 32);
     141            return rv;
     142        } catch (IndexOutOfBoundsException ioobe) {
     143            throw new InvalidKeySpecException(ioobe);
     144        }
    41145    }
    42146
     
    56160        return Abyte;
    57161    }
     162
     163    /**
     164     *  @since 0.9.25
     165     */
     166    @Override
     167    public int hashCode() {
     168        return Arrays.hashCode(Abyte);
     169    }
     170
     171    /**
     172     *  @since 0.9.25
     173     */
     174    @Override
     175    public boolean equals(Object o) {
     176        if (o == this)
     177            return true;
     178        if (!(o instanceof EdDSAPublicKey))
     179            return false;
     180        EdDSAPublicKey pk = (EdDSAPublicKey) o;
     181        return Arrays.equals(Abyte, pk.getAbyte()) &&
     182               edDsaSpec.equals(pk.getParams());
     183    }
    58184}
  • core/java/src/net/i2p/crypto/eddsa/KeyFactory.java

    ra70a7a7 rebc4ca86  
    88import java.security.spec.InvalidKeySpecException;
    99import java.security.spec.KeySpec;
     10import java.security.spec.PKCS8EncodedKeySpec;
     11import java.security.spec.X509EncodedKeySpec;
    1012
    1113import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec;
     
    1719 *
    1820 */
    19 public class KeyFactory extends KeyFactorySpi {
     21public final class KeyFactory extends KeyFactorySpi {
    2022
     23    /**
     24     *  As of 0.9.25, supports PKCS8EncodedKeySpec
     25     */
    2126    protected PrivateKey engineGeneratePrivate(KeySpec keySpec)
    2227            throws InvalidKeySpecException {
     
    2429            return new EdDSAPrivateKey((EdDSAPrivateKeySpec) keySpec);
    2530        }
    26         throw new InvalidKeySpecException("key spec not recognised");
     31        if (keySpec instanceof PKCS8EncodedKeySpec) {
     32            return new EdDSAPrivateKey((PKCS8EncodedKeySpec) keySpec);
     33        }
     34        throw new InvalidKeySpecException("key spec not recognised: " + keySpec.getClass());
    2735    }
    2836
     37    /**
     38     *  As of 0.9.25, supports X509EncodedKeySpec
     39     */
    2940    protected PublicKey engineGeneratePublic(KeySpec keySpec)
    3041            throws InvalidKeySpecException {
     
    3243            return new EdDSAPublicKey((EdDSAPublicKeySpec) keySpec);
    3344        }
    34         throw new InvalidKeySpecException("key spec not recognised");
     45        if (keySpec instanceof X509EncodedKeySpec) {
     46            return new EdDSAPublicKey((X509EncodedKeySpec) keySpec);
     47        }
     48        throw new InvalidKeySpecException("key spec not recognised: " + keySpec.getClass());
    3549    }
    3650
  • core/java/src/net/i2p/crypto/eddsa/KeyPairGenerator.java

    ra70a7a7 rebc4ca86  
    2222 *  @since 0.9.15
    2323 */
    24 public class KeyPairGenerator extends KeyPairGeneratorSpi {
     24public final class KeyPairGenerator extends KeyPairGeneratorSpi {
    2525    private static final int DEFAULT_STRENGTH = 256;
    2626    private EdDSAParameterSpec edParams;
  • core/java/src/net/i2p/crypto/eddsa/math/Curve.java

    ra70a7a7 rebc4ca86  
    7070        return ge;
    7171    }
     72
     73    /**
     74     *  @since 0.9.25
     75     */
     76    @Override
     77    public int hashCode() {
     78        return f.hashCode() ^
     79               d.hashCode() ^
     80               I.hashCode();
     81    }
     82
     83    /**
     84     *  @since 0.9.25
     85     */
     86    @Override
     87    public boolean equals(Object o) {
     88        if (o == this)
     89            return true;
     90        if (!(o instanceof Curve))
     91            return false;
     92        Curve c = (Curve) o;
     93        return f.equals(c.getField()) &&
     94               d.equals(c.getD()) &&
     95               I.equals(c.getI());
     96    }
    7297}
  • core/java/src/net/i2p/crypto/eddsa/math/FieldElement.java

    ra70a7a7 rebc4ca86  
    44
    55/**
     6 *
     7 * Note: concrete subclasses must implement hashCode() and equals()
    68 *
    79 * @since 0.9.15
     
    6163
    6264    public abstract FieldElement pow22523();
     65
     66    // Note: concrete subclasses must implement hashCode() and equals()
    6367}
  • core/java/src/net/i2p/crypto/eddsa/math/GroupElement.java

    ra70a7a7 rebc4ca86  
    717717    @Override
    718718    public boolean equals(Object obj) {
     719        if (obj == this)
     720            return true;
    719721        if (!(obj instanceof GroupElement))
    720722            return false;
  • core/java/src/net/i2p/crypto/eddsa/math/bigint/BigIntegerLittleEndianEncoding.java

    ra70a7a7 rebc4ca86  
    1616
    1717    @Override
    18     public void setField(Field f) {
     18    public synchronized void setField(Field f) {
    1919        super.setField(f);
    2020        mask = BigInteger.ONE.shiftLeft(f.getb()-1).subtract(BigInteger.ONE);
  • core/java/src/net/i2p/crypto/eddsa/spec/EdDSAParameterSpec.java

    ra70a7a7 rebc4ca86  
    6060        return B;
    6161    }
     62
     63    /**
     64     *  @since 0.9.25
     65     */
     66    @Override
     67    public int hashCode() {
     68        return hashAlgo.hashCode() ^
     69               curve.hashCode() ^
     70               B.hashCode();
     71    }
     72
     73    /**
     74     *  @since 0.9.25
     75     */
     76    @Override
     77    public boolean equals(Object o) {
     78        if (o == this)
     79            return true;
     80        if (!(o instanceof EdDSAParameterSpec))
     81            return false;
     82        EdDSAParameterSpec s = (EdDSAParameterSpec) o;
     83        return hashAlgo.equals(s.getHashAlgorithm()) &&
     84               curve.equals(s.getCurve()) &&
     85               B.equals(s.getB());
     86    }
    6287}
  • core/java/src/net/i2p/crypto/provider/I2PProvider.java

    ra70a7a7 rebc4ca86  
    44import java.security.PrivilegedAction;
    55import java.security.Provider;
     6import java.security.Security;
    67
    78/**
     
    1213    private static final String INFO = "I2P Security Provider v0.1, implementing" +
    1314            "several algorithms used by I2P.";
     15    private static boolean _installed;
    1416
    1517    /**
     
    3234    private void setup() {
    3335        // TODO: Implement SPIs for existing code
     36        // However -
     37        // quote
     38        // http://docs.oracle.com/javase/7/docs/technotes/guides/security/crypto/HowToImplAProvider.html
     39        //
     40        // If your provider is supplying encryption algorithms through the
     41        // Cipher, KeyAgreement, KeyGenerator, Mac, or SecretKeyFactory classes,
     42        // you will need to sign your JAR file so that the JCA can authenticate the code at runtime.
     43        // If you are NOT providing an implementation of this type you can skip this step.
     44        //
    3445        //put("Cipher.AES", "net.i2p.crypto.provider.CipherSpi$aesCBC");
    3546        //put("Cipher.ElGamal", "net.i2p.crypto.provider.CipherSpi$elGamal");
    3647        //put("Mac.HmacMD5-I2P", "net.i2p.crypto.provider.MacSpi");
     48
    3749        put("MessageDigest.SHA-1", "net.i2p.crypto.SHA1");
    3850        //put("Signature.SHA1withDSA", "net.i2p.crypto.provider.SignatureSpi");
    3951
    4052        // EdDSA
     53        // Key OID: 1.3.101.100; Sig OID: 1.3.101.101
    4154        put("KeyFactory.EdDSA", "net.i2p.crypto.eddsa.KeyFactory");
    4255        put("KeyPairGenerator.EdDSA", "net.i2p.crypto.eddsa.KeyPairGenerator");
    4356        put("Signature.SHA512withEdDSA", "net.i2p.crypto.eddsa.EdDSAEngine");
     57        // Didn't find much documentation on these at all,
     58        // see http://docs.oracle.com/javase/7/docs/technotes/guides/security/crypto/HowToImplAProvider.html
     59        // section "Mapping from OID to name"
     60        // without these, Certificate.verify() fails
     61        put("Alg.Alias.KeyFactory.1.3.101.100", "EdDSA");
     62        put("Alg.Alias.KeyFactory.OID.1.3.101.100", "EdDSA");
     63        // Without these, keytool fails with:
     64        // keytool error: java.security.NoSuchAlgorithmException: unrecognized algorithm name: SHA512withEdDSA
     65        put("Alg.Alias.KeyPairGenerator.1.3.101.100", "EdDSA");
     66        put("Alg.Alias.KeyPairGenerator.OID.1.3.101.100", "EdDSA");
     67        // with this setting, keytool keygen doesn't work
     68        // java.security.cert.CertificateException: Signature algorithm mismatch
     69        // it must match the key setting (1.3.101.100) to work
     70        // but this works fine with programmatic cert generation
     71        put("Alg.Alias.Signature.1.3.101.101", "SHA512withEdDSA");
     72        put("Alg.Alias.Signature.OID.1.3.101.101", "SHA512withEdDSA");
     73        // TODO Ed25519ph
     74        // OID: 1.3.101.101
     75
     76        // ElGamal
     77        // OID: 1.3.14.7.2.1.1
     78        put("KeyFactory.DH", "net.i2p.crypto.elgamal.KeyFactory");
     79        put("KeyFactory.DiffieHellman", "net.i2p.crypto.elgamal.KeyFactory");
     80        put("KeyFactory.ElGamal", "net.i2p.crypto.elgamal.KeyFactory");
     81        put("KeyPairGenerator.DH", "net.i2p.crypto.elgamal.KeyPairGenerator");
     82        put("KeyPairGenerator.DiffieHellman", "net.i2p.crypto.elgamal.KeyPairGenerator");
     83        put("KeyPairGenerator.ElGamal", "net.i2p.crypto.elgamal.KeyPairGenerator");
     84        put("Signature.SHA256withElGamal", "net.i2p.crypto.elgamal.ElGamalSigEngine");
     85        put("Alg.Alias.KeyFactory.1.3.14.7.2.1.1", "ElGamal");
     86        put("Alg.Alias.KeyFactory.OID.1.3.14.7.2.1.1", "ElGamal");
     87        put("Alg.Alias.KeyPairGenerator.1.3.14.7.2.1.1", "ElGamal");
     88        put("Alg.Alias.KeyPairGenerator.OID.1.3.14.7.2.1.1", "ElGamal");
     89        put("Alg.Alias.Signature.1.3.14.7.2.1.1", "SHA256withElGamal");
     90        put("Alg.Alias.Signature.OID.1.3.14.7.2.1.1", "SHA256withElGamal");
     91    }
     92
     93    /**
     94     *  Install the I2PProvider.
     95     *  Harmless to call multiple times.
     96     *  @since 0.9.25
     97     */
     98    public static void addProvider() {
     99        synchronized(I2PProvider.class) {
     100            if (!_installed) {
     101                try {
     102                    Provider us = new I2PProvider();
     103                    // put ours ahead of BC, if installed, because our ElGamal
     104                    // implementation may not be fully compatible with BC
     105                    Provider[] provs = Security.getProviders();
     106                    for (int i = 0; i < provs.length; i++) {
     107                        if (provs[i].getName().equals("BC")) {
     108                            Security.insertProviderAt(us, i);
     109                            _installed = true;
     110                            return;
     111                        }
     112                    }
     113                    Security.addProvider(us);
     114                    _installed = true;
     115                } catch (SecurityException se) {
     116                    System.out.println("WARN: Could not install I2P provider: " + se);
     117                }
     118            }
     119        }
    44120    }
    45121}
  • core/java/src/net/i2p/data/Base64.java

    ra70a7a7 rebc4ca86  
    103103    public static byte[] decode(String s) {
    104104        return safeDecode(s, false);
     105    }
     106
     107    /**
     108     *  Decodes data from Base64 notation using the I2P alphabet.
     109     *
     110     *  @param useStandardAlphabet Warning, must be false for I2P compatibility
     111     *  @return the decoded data, null on error
     112     *  @since 0.9.25
     113     */
     114    public static byte[] decode(String s, boolean useStandardAlphabet) {
     115        return safeDecode(s, useStandardAlphabet);
    105116    }
    106117
  • core/java/src/net/i2p/data/DataHelper.java

    ra70a7a7 rebc4ca86  
    13251325     * @param hash null OK
    13261326     * @return null on EOF
    1327      * @deprecated use MessageDigest version
    1328      */
     1327     * @deprecated use MessageDigest version to be removed in 0.9.27
     1328     */
     1329    @Deprecated
    13291330    public static String readLine(InputStream in, Sha256Standalone hash) throws IOException {
    13301331        StringBuilder buf = new StringBuilder(128);
     
    13811382     * @return true if the line was read, false if eof was reached on an empty line
    13821383     *              (returns true for non-empty last line without a newline)
    1383      * @deprecated use StringBuilder / MessageDigest version
     1384     * @deprecated use StringBuilder / MessageDigest version, to be removed in 0.9.27
    13841385     */
    13851386    @Deprecated
     
    14211422     * @return true if the line was read, false if eof was reached on an empty line
    14221423     *              (returns true for non-empty last line without a newline)
    1423      * @deprecated use MessageDigest version
    1424      */
     1424     * @deprecated use MessageDigest version, to be removed in 0.9.27
     1425     */
     1426    @Deprecated
    14251427    public static boolean readLine(InputStream in, StringBuilder buf, Sha256Standalone hash) throws IOException {
    14261428        int c = -1;
     
    14641466    /**
    14651467     *  update the hash along the way
    1466      *  @deprecated use MessageDigest version
    1467      */
     1468     *  @deprecated use MessageDigest version, to be removed in 0.9.27
     1469     */
     1470    @Deprecated
    14681471    public static void write(OutputStream out, byte data[], Sha256Standalone hash) throws IOException {
    14691472        hash.update(data);
  • core/java/src/net/i2p/util/RandomSource.java

    ra70a7a7 rebc4ca86  
    202202
    203203        // why urandom?  because /dev/random blocks
    204         ok = seedFromFile(new File("/dev/urandom"), buf) || ok;
     204        if (!SystemVersion.isWindows())
     205            ok = seedFromFile(new File("/dev/urandom"), buf) || ok;
    205206        // we merge (XOR) in the data from /dev/urandom with our own seedfile
    206207        File localFile = new File(_context.getConfigDir(), SEEDFILE);
  • installer/resources/checklist.md

    ra70a7a7 rebc4ca86  
    5252    build.built-by=xxx
    5353    javac.compilerargs=-bootclasspath /usr/lib/jvm/java-6-openjdk-amd64/jre/lib/rt.jar:/usr/lib/jvm/java-6-openjdk-amd64/jre/lib/jce.jar
     54    javac.compilerargs7=-bootclasspath /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/jce.jar
    5455    ```
    5556
     
    170171    number in data/releases.json, and check in
    171172
    172 2. Add update torrents to tracker2.postman.i2p and start seeding (su2 and su3)
     1732. Add i2pupdate-0.9.xx.su3 torrent to tracker2.postman.i2p and start seeding
    173174
    1741753. Notify the following people:
  • installer/resources/eepsite/contexts/base-context.xml

    ra70a7a7 rebc4ca86  
    3838    <Arg>/</Arg>
    3939  </Call>
     40  <Call name="addServlet">
     41    <Arg>org.eclipse.jetty.servlet.DefaultServlet</Arg>
     42    <Arg>/</Arg>
     43  </Call>
     44  <Call name="addFilter">
     45    <!-- Add a filter to gzip on-the fly, since if we don't do it, I2P will.
     46      -  This lowers the resource usage in the Java process on the client side,
     47      -  by pushing the decompression out of Java and into the browser.
     48      -  For all the reasons noted in the GzipFilter javadocs, this is normally
     49      -  a bad idea for static content, but this is I2P.
     50      -  See I2PTunnelHTTPServer for the I2P compressor.
     51      -->
     52    <Arg>
     53      <New class="org.eclipse.jetty.servlet.FilterHolder" >
     54        <Arg>
     55          <New class="org.eclipse.jetty.servlets.GzipFilter" />
     56        </Arg>
     57        <Call name="setInitParameter">
     58          <!-- minimum in Java is 1300 -->
     59          <Arg>minGzipSize</Arg>
     60          <Arg>512</Arg>
     61        </Call>
     62        <Call name="setInitParameter">
     63          <!-- In Java we have a blacklist. This covers the most common cases. -->
     64          <Arg>mimeTypes</Arg>
     65          <Arg>application/pdf,application/x-javascript,application/xhtml+xml,application/xml,image/svg+xml,text/css,text/html,text/plain</Arg>
     66        </Call>
     67      </New>
     68    </Arg>
     69    <Arg>/*</Arg>
     70    <Arg>
     71      <!-- just guessing here -->
     72      <Call class="java.util.EnumSet" name="of" >
     73        <Arg>
     74          <Call class="javax.servlet.DispatcherType" name="valueOf" >
     75            <Arg>REQUEST</Arg>
     76          </Call>
     77        </Arg>
     78      </Call>
     79    </Arg>
     80  </Call>
    4081</Configure>
    4182
  • installer/resources/eepsite/contexts/cgi-context.xml

    ra70a7a7 rebc4ca86  
    3434    <Arg>/</Arg>
    3535  </Call>
     36  <Call name="addFilter">
     37    <!-- See base-context.xml for info.
     38         Unlike for DefaultServlet, there's not even a theoretical
     39         inefficiency for using this.
     40      -->
     41    <Arg>
     42      <New class="org.eclipse.jetty.servlet.FilterHolder" >
     43        <Arg>
     44          <New class="org.eclipse.jetty.servlets.GzipFilter" />
     45        </Arg>
     46        <Call name="setInitParameter">
     47          <Arg>minGzipSize</Arg>
     48          <Arg>512</Arg>
     49        </Call>
     50        <Call name="setInitParameter">
     51          <Arg>mimeTypes</Arg>
     52          <Arg>application/pdf,application/x-javascript,application/xhtml+xml,application/xml,image/svg+xml,text/css,text/html,text/plain</Arg>
     53        </Call>
     54      </New>
     55    </Arg>
     56    <Arg>/*</Arg>
     57    <Arg>
     58      <Call class="java.util.EnumSet" name="of" >
     59        <Arg>
     60          <Call class="javax.servlet.DispatcherType" name="valueOf" >
     61            <Arg>REQUEST</Arg>
     62          </Call>
     63        </Arg>
     64      </Call>
     65    </Arg>
     66  </Call>
    3667</Configure>
  • installer/resources/hosts.txt

    ra70a7a7 rebc4ca86  
    365365i2pwiki.i2p=Zr1YUKIKooxymZRqLvtfSYuZggqv5txkLE8Ks~FTh3A8JDmhOV8C82dUBKJhzst~Pcbqz7rXc~TPyrqasaQ~LioAji~WLSs8PpmCLVF83edhYpx75Fp23ELboEszHduhKWuibVchPLNa-6nP4F0Ttcr4krTlphe3KveNfZDAbm511zFFlNzPcY4PqOdCRBrp7INiWkVwQxwGWO7jiNYTYa5x4QXJmxIN1YOiNRYQST7THz1aV6219ThsfT9FE5JtiX-epli6PF5ZX9TcVSjHUKZnr8uJLXfh5T4RMVNe1n~KXutMUZwxpFE0scOIez9vhDFd7t0HPIsQUsv7MUBzrz4FM9qol7UUPueSGDRgTOOfXMfj4BDsouiWQC4GcSmH3SflR0Ith9QWKC4u3XYvB7Tw-70QWBEV53hUo6I8YKidV13WgeN9JI3KWTYkMyX-TYjmY9y2q6Xd-Maszv4Tb~NzxQs9CNdu0W-JRSUFOqzgt3l4cx0K1pmx4p0tM5dLBQAEAAEAAA==
    366366lenta.i2p=DnW8NqbKilYLcIx5g5CG4mWVHkzrCkl0MbV4a5rGJku4BSs7HjvzjZpCoXWFky9JCUlHzjFotMETxQBhaKl0Q46vu-plKQ4BLnYyo45p7j2lTiejWvV4SDuXU4IAdmug27i~Jl4N44zwe9KYy~gMfY1Vsgv4bH9ov7X7l2iS-bycfcd9nE7JfycwFc4e0XU-dx7xf~tHw7I5--25dp-SsRX3-UYz4ygb58aD8UsKfQaFZtMy4x~Z1ufNEftuekb1HH9g2Rhhq8Bl62ad8PWSDa9Ne-SkCQsqTYjrCsvMY2DMvWgmZxI1hJYqzjRdFV6JEprrr~CJgHGJXr~KdnZhX12Vm4bKisZK847wBm42CoBQBT5HRzDkeflkbsliirRuKSUxVYMoZ1vic~avPZZl~pvIKZsz-YtiKha4vjCNE1zD-tHIS~2qq4uEO546Ol9pNokPaNttV6r7D2-zurEDx~9grJ8LhBozTxtdTdfZv2OqN4bVhrE7xUrxe0flIFKEAAAA
     367secure.thetinhat.i2p=0ncSrtVS20zwfcM7h2S6SSF56uVM2bftQwf40jsWKASNQnzyDVEzXpS04y-DJpm9EwKMGkgvx8ICBX-80W4E9xPJEdGFbb2u34fWmpTVMc3vwwB9ywmSXoxFbwiFx2sm7-HCcdALZwrjU3J41AfBvpEVkB5dXklTZIh~bU0JBTK2JIvQMD0XrSOztEruTc5kYymtkiCUpJaJJFXyIM3lKRcNlZ76UidE8AyQxHX7s9OR02pk7FhYV8Uh-Bs8loAZg6IPZzoYnnBYyi--b1-N8Ipv3aKmqSZPbQEzfQxU8-BE74xBLNEWAJtB8ptKMiKfHphO7qDKWqTzOU-7BtGXZAEOA3oblRAQcgqUbi~aICj0V0MAuYAdj7f-8BIi2k3Qfcl6k6XOFEpZqYFle71LeCjIZN~0mDDzxlr0Scx6LKMGnQAtYlGXFq99urp1MutPDZEu47mdxGWqc9CoNNNsE2UgS9ykvWygefNpZhkmceBXmDxWhuAPD1M2~eNF-fCMBQAIAAMAADZv~vU=
  • router/java/src/net/i2p/router/Router.java

    ra70a7a7 rebc4ca86  
    101101
    102102    /** used to differentiate routerInfo files on different networks */
    103     public static final int NETWORK_ID = 2;
     103    private static final int DEFAULT_NETWORK_ID = 2;
     104    private static final String PROP_NETWORK_ID = "router.networkID";
     105    private final int _networkID;
    104106   
    105107    /** coalesce stats this often - should be a little less than one minute, so the graphs get updated */
     
    348350            saveConfig();
    349351        }
     352        int id = DEFAULT_NETWORK_ID;
     353        String sid = _config.get(PROP_NETWORK_ID);
     354        if (sid != null) {
     355            try {
     356                id = Integer.parseInt(sid);
     357            } catch (NumberFormatException nfe) {}
     358        }
     359        _networkID = id;
    350360        changeState(State.INITIALIZED);
    351361        // *********  Start no threads before here ********* //
     
    537547        return Math.max(1000, System.currentTimeMillis() - _started);
    538548    }
     549
     550    /**
     551     *  The network ID. Default 2.
     552     *  May be changed with the config property router.networkID (restart required).
     553     *  Change only if running a test network to prevent cross-network contamination.
     554     *  @since 0.9.25
     555     */
     556    public int getNetworkID() { return _networkID; }
    539557   
    540558    /**
  • router/java/src/net/i2p/router/RouterContext.java

    ra70a7a7 rebc4ca86  
    121121            // to fill than to drain - so we don't need too many
    122122            long maxMemory = SystemVersion.getMaxMemory();
    123             long buffs = Math.min(16, Math.max(2, maxMemory / (14 * 1024 * 1024)));
     123            long maxBuffs = (SystemVersion.isAndroid() || SystemVersion.isARM()) ? 4 : 8;
     124            long buffs = Math.min(maxBuffs, Math.max(2, maxMemory / (21 * 1024 * 1024)));
    124125            envProps.setProperty("prng.buffers", "" + buffs);
    125126        }
  • router/java/src/net/i2p/router/StatisticsManager.java

    ra70a7a7 rebc4ca86  
    3333    private final Log _log;
    3434    private final RouterContext _context;
     35    private final String _networkID;
    3536   
    3637    public final static String PROP_PUBLISH_RANKINGS = "router.publishPeerRankings";
     
    4748        _pct = new DecimalFormat("#0.00%", new DecimalFormatSymbols(Locale.UK));
    4849        _log = context.logManager().getLog(StatisticsManager.class);
     50        _networkID = Integer.toString(context.router().getNetworkID());
    4951    }
    5052       
     
    7375        if (CoreVersion.VERSION.equals("0.9.23"))
    7476            stats.setProperty("coreVersion", CoreVersion.VERSION);
    75         stats.setProperty(RouterInfo.PROP_NETWORK_ID, Integer.toString(Router.NETWORK_ID));
     77        stats.setProperty(RouterInfo.PROP_NETWORK_ID, _networkID);
    7678        stats.setProperty(RouterInfo.PROP_CAPABILITIES, _context.router().getCapabilities());
    7779
  • router/java/src/net/i2p/router/crypto/FamilyKeyCrypto.java

    ra70a7a7 rebc4ca86  
    4848    private final SigningPublicKey _pubkey;
    4949
    50     private static final String PROP_KEYSTORE_PASSWORD = "netdb.family.keystorePassword";
     50    public static final String PROP_KEYSTORE_PASSWORD = "netdb.family.keystorePassword";
    5151    public static final String PROP_FAMILY_NAME = "netdb.family.name";
    52     private static final String PROP_KEY_PASSWORD = "netdb.family.keyPassword";
    53     private static final String CERT_SUFFIX = ".crt";
    54     private static final String KEYSTORE_PREFIX = "family-";
    55     private static final String KEYSTORE_SUFFIX = ".ks";
     52    public static final String PROP_KEY_PASSWORD = "netdb.family.keyPassword";
     53    public static final String CERT_SUFFIX = ".crt";
     54    public static final String KEYSTORE_PREFIX = "family-";
     55    public static final String KEYSTORE_SUFFIX = ".ks";
     56    public static final String CN_SUFFIX = ".family.i2p.net";
    5657    private static final int DEFAULT_KEY_VALID_DAYS = 3652;  // 10 years
    5758    // Note that we can't use RSA here, as the b64 sig would exceed the 255 char limit for a Mapping
     
    290291        String keyPassword = KeyStoreUtil.randomString();
    291292        // and one for the cname
    292         String cname = _fname + ".family.i2p.net";
     293        String cname = _fname + CN_SUFFIX;
    293294
    294295        boolean success = KeyStoreUtil.createKeys(ks, KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD, _fname, cname, "family",
  • router/java/src/net/i2p/router/networkdb/kademlia/FloodfillNetworkDatabaseFacade.java

    ra70a7a7 rebc4ca86  
    480480        // yikes don't do this - stack overflow //  getFloodfillPeers().size() == 0 ||
    481481        // yikes2 don't do this either - deadlock! // getKnownRouters() < MIN_REMAINING_ROUTERS ||
    482         if (info.getNetworkId() == Router.NETWORK_ID &&
     482        if (info.getNetworkId() == _networkID &&
    483483            (getKBucketSetSize() < MIN_REMAINING_ROUTERS ||
    484484             _context.router().getUptime() < DONT_FAIL_PERIOD ||
  • router/java/src/net/i2p/router/networkdb/kademlia/KademliaNetworkDatabaseFacade.java

    ra70a7a7 rebc4ca86  
    7171    private volatile long _lastRIPublishTime;
    7272    private NegativeLookupCache _negativeCache;
     73    protected final int _networkID;
    7374
    7475    /**
     
    157158        _context = context;
    158159        _log = _context.logManager().getLog(getClass());
     160        _networkID = context.router().getNetworkID();
    159161        _peerSelector = createPeerSelector();
    160162        _publishingLeaseSets = new HashMap<Hash, RepublishLeaseSetJob>(8);
     
    890892            return "Invalid routerInfo signature";
    891893        }
    892         if (routerInfo.getNetworkId() != Router.NETWORK_ID){
     894        if (routerInfo.getNetworkId() != _networkID){
    893895            _context.banlist().banlistRouter(key, "Not in our network");
    894896            if (_log.shouldLog(Log.WARN))
  • router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java

    ra70a7a7 rebc4ca86  
    5555    private volatile boolean _initialized;
    5656    private final boolean _flat;
     57    private final int _networkID;
    5758   
    5859    private final static int READ_DELAY = 2*60*1000;
     
    6667    public PersistentDataStore(RouterContext ctx, String dbDir, KademliaNetworkDatabaseFacade facade) throws IOException {
    6768        super(ctx);
     69        _networkID = ctx.router().getNetworkID();
    6870        _flat = ctx.getBooleanProperty(PROP_FLAT);
    6971        _dbDir = getDbDir(dbDir);
     
    506508                    RouterInfo ri = new RouterInfo();
    507509                    ri.readBytes(fis, true);  // true = verify sig on read
    508                     if (ri.getNetworkId() != Router.NETWORK_ID) {
     510                    if (ri.getNetworkId() != _networkID) {
    509511                        corrupt = true;
    510512                        if (_log.shouldLog(Log.ERROR))
  • router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java

    ra70a7a7 rebc4ca86  
    4343    private final UDPTransport _transport;
    4444    private final PacketBuilder _builder;
     45    private final int _networkID;
    4546
    4647    /** map of RemoteHostId to InboundEstablishState */
     
    141142        _context = ctx;
    142143        _log = ctx.logManager().getLog(EstablishmentManager.class);
     144        _networkID = ctx.router().getNetworkID();
    143145        _transport = transport;
    144146        _builder = new PacketBuilder(ctx, transport);
     
    250252        RouterIdentity toIdentity = toRouterInfo.getIdentity();
    251253        Hash toHash = toIdentity.calculateHash();
    252         if (toRouterInfo.getNetworkId() != Router.NETWORK_ID) {
     254        if (toRouterInfo.getNetworkId() != _networkID) {
    253255            _context.banlist().banlistRouter(toHash);
    254256            _transport.markUnreachable(toHash);
     
    763765            _log.info("Completing to the peer after IB confirm: " + peer);
    764766        DeliveryStatusMessage dsm = new DeliveryStatusMessage(_context);
    765         dsm.setArrival(Router.NETWORK_ID); // overloaded, sure, but future versions can check this
     767        dsm.setArrival(_networkID); // overloaded, sure, but future versions can check this
    766768                                           // This causes huge values in the inNetPool.droppedDeliveryStatusDelay stat
    767769                                           // so it needs to be caught in InNetMessagePool.
  • router/java/src/net/i2p/router/transport/udp/UDPTransport.java

    ra70a7a7 rebc4ca86  
    8888    private int _mtu_ipv6;
    8989    private boolean _mismatchLogged;
     90    private final int _networkID;
    9091
    9192    /**
     
    219220    public UDPTransport(RouterContext ctx, DHSessionKeyBuilder.Factory dh) {
    220221        super(ctx);
     222        _networkID = ctx.router().getNetworkID();
    221223        _dhFactory = dh;
    222224        _log = ctx.logManager().getLog(UDPTransport.class);
     
    12901292                return;
    12911293            if (entry.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO &&
    1292                 ((RouterInfo) entry).getNetworkId() != Router.NETWORK_ID) {
     1294                ((RouterInfo) entry).getNetworkId() != _networkID) {
    12931295                // this is pre-0.6.1.10, so it isn't going to happen any more
    12941296
Note: See TracChangeset for help on using the changeset viewer.