<commit_before>package net.i2p.crypto;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import net.i2p.CoreVersion;
import net.i2p.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Signature;
import net.i2p.data.SigningPrivateKey;
import net.i2p.data.SigningPublicKey;
import net.i2p.util.Log;
import net.i2p.util.VersionComparator;

/**
 * <p>Handles DSA signing and verification of update files.
 * </p>
 * <p>For convenience this class also makes certain operations available via the
 * command line. These can be invoked as follows:
 * </p>
 * <pre>
 * java net.i2p.crypto.TrustedUpdate keygen       <i>publicKeyFile privateKeyFile</i>
 * java net.i2p.crypto.TrustedUpdate showversion  <i>signedFile</i>
 * java net.i2p.crypto.TrustedUpdate sign         <i>inputFile signedFile privateKeyFile version</i>
 * java net.i2p.crypto.TrustedUpdate verifysig    <i>signedFile</i>
 * java net.i2p.crypto.TrustedUpdate verifyupdate <i>signedFile</i>
 * </pre>
 * 
 * @author jrandom and smeghead
 */
public class TrustedUpdate {

    /**
     * <p>Default trusted key generated by <EMAIL>. This can be
     * authenticated via <code>gpg</code> without modification:</p>
     * <p>
     * <code>gpg --verify TrustedUpdate.java</code></p>
     */
/*
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

*/
    private static final String DEFAULT_TRUSTED_KEY =
        "<KEY>" +
        "<KEY>" +
        "<KEY>;
/*
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFCZ38IWYfZ3rPnHH0RAgOHAJ4wNgmfO2AkL8IXiGnPtWrTlXcVogCfQ79z
jP69nPbh4KLGhF+SD0+0bW4=
=npPe
-----END PGP SIGNATURE-----
*/
/*
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

*/
    /* zzz's key */
    private static final String DEFAULT_TRUSTED_KEY2 =
        "<KEY>" +
        "<KEY>" +
        "<KEY>;
/*
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFHdupcQVV2uqduC+0RAocuAKCR4ILLuz3RB8QT7zkadmS2LmFuMwCgweqG
lFm5Fqx/iW5+k0QaQZ3W9mY=
=V3i7
-----END PGP SIGNATURE-----
*/
/*
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

*/
    /* Complication's key */
    private static final String DEFAULT_TRUSTED_KEY3 =
        "<KEY>
        <KEY>" +
        "<KEY>;
/*
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFHphOV+h38a3n8zjMRAll+AJ9KA6WiDJcTN4qfrslSemUMr+FBrwCeM8pF
D8usM7Dxp5yrDrCYZ5AIijc=
=SrXI
-----END PGP SIGNATURE-----
*/

    private static final int    VERSION_BYTES       = 16;
    public static final int    HEADER_BYTES        = Signature.SIGNATURE_BYTES + VERSION_BYTES;
    private static final String PROP_TRUSTED_KEYS   = "router.trustedUpdateKeys";

    private static I2PAppContext _context;

    private Log       _log;
    private Map<SigningPublicKey, String> _trustedKeys;
    private String _newVersion;
    /** 172 */
    private static final int KEYSIZE_B64_BYTES = 2 + (SigningPublicKey.KEYSIZE_BYTES * 4 / 3);

    /**
     * Constructs a new <code>TrustedUpdate</code> with the default global
     * context.
     */
    public TrustedUpdate() {
        this(I2PAppContext.getGlobalContext());
    }

    /**
     * Constructs a new <code>TrustedUpdate</code> with the given
     * {@link net.i2p.I2PAppContext}.
     * 
     * @param context An instance of <code>I2PAppContext</code>.
     */
    public TrustedUpdate(I2PAppContext context) {
        _context = context;
        _log = _context.logManager().getLog(TrustedUpdate.class);
        _trustedKeys = new HashMap(4);
        _newVersion = null;

        String propertyTrustedKeys = context.getProperty(PROP_TRUSTED_KEYS);

        if ( (propertyTrustedKeys != null) && (propertyTrustedKeys.length() > 0) ) {
            StringTokenizer propertyTrustedKeysTokens = new StringTokenizer(propertyTrustedKeys, " ,\r\n");

            while (propertyTrustedKeysTokens.hasMoreTokens())
                addKey(propertyTrustedKeysTokens.nextToken().trim(), "");

        } else {
            addKey(DEFAULT_TRUSTED_KEY, "jrandom@mail.i2p");
            addKey(DEFAULT_TRUSTED_KEY2, "zzz@mail.i2p");
            //addKey(DEFAULT_TRUSTED_KEY3, "<EMAIL>lication@mail.i2p");
        }
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("TrustedUpdate created, trusting " + _trustedKeys.size() + " keys.");
    }

    /**
     *  Duplicate keys or names rejected,
     *  except that duplicate empty names are allowed
     *  @since 0.7.12
     *  @return true if successful
     */
    public boolean addKey(String key, String name) {
        SigningPublicKey signingPublicKey = new SigningPublicKey();
        try {
            // fromBase64() won't reject a string that is too long
            if (key.length() != KEYSIZE_B64_BYTES)
                throw new DataFormatException("x");
            signingPublicKey.fromBase64(key);<commit_msg>Add HungryHobo as a signer<commit_after>package net.i2p.crypto;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

import net.i2p.CoreVersion;
import net.i2p.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Signature;
import net.i2p.data.SigningPrivateKey;
import net.i2p.data.SigningPublicKey;
import net.i2p.util.Log;
import net.i2p.util.VersionComparator;

/**
 * <p>Handles DSA signing and verification of update files.
 * </p>
 * <p>For convenience this class also makes certain operations available via the
 * command line. These can be invoked as follows:
 * </p>
 * <pre>
 * java net.i2p.crypto.TrustedUpdate keygen       <i>publicKeyFile privateKeyFile</i>
 * java net.i2p.crypto.TrustedUpdate showversion  <i>signedFile</i>
 * java net.i2p.crypto.TrustedUpdate sign         <i>inputFile signedFile privateKeyFile version</i>
 * java net.i2p.crypto.TrustedUpdate verifysig    <i>signedFile</i>
 * java net.i2p.crypto.TrustedUpdate verifyupdate <i>signedFile</i>
 * </pre>
 * 
 * @author jrandom and smeghead
 */
public class TrustedUpdate {

    /**
     * <p>Default trusted key generated by <EMAIL>. This can be
     * authenticated via <code>gpg</code> without modification:</p>
     * <p>
     * <code>gpg --verify TrustedUpdate.java</code></p>
     */
/*
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

*/
    private static final String DEFAULT_TRUSTED_KEY =
        "<KEY>" +
        "M7sAKYDZay5z1HvYYOl9CNVz00xF03KPU9RUCVxhDZ1YXhZIskPKjUPUs" +
        "CIpE~Z1C~N9KSEV6~2stDlBNH10VZ4T0X1TrcXwb3IBXliWo2y2GAx~Ow=";
/*
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFCZ38IWYfZ3rPnHH0RAgOHAJ4wNgmfO2AkL8IXiGnPtWrTlXcVogCfQ79z
jP69nPbh4KLGhF+SD0+0bW4=
=npPe
-----END PGP SIGNATURE-----
*/
/*
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

*/
    /* zzz's key */
    private static final String DEFAULT_TRUSTED_KEY2 =
        "<KEY>" +
        "<KEY>" +
        "<KEY>;
/*
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFHdupcQVV2uqduC+0RAocuAKCR4ILLuz3RB8QT7zkadmS2LmFuMwCgweqG
lFm5Fqx/iW5+k0QaQZ3W9mY=
=V3i7
-----END PGP SIGNATURE-----
*/
/*
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

*/
    /* Complication's key */
    private static final String DEFAULT_TRUSTED_KEY3 =
        "<KEY>XFZH9Nk62OPRHbvvQHTi8EANV-D~3tjLjaz9p9cs6F" +
        "s8W3FSLfUwsQeFg7dfVSQQZga~1jMjboo94vIcm3j6XbW4mbcorVQ74uP" +
        "jd8EA1AQhJ6bBTxDAFk~6fVDOdhHT0Wo5CcUn7v8bAYY3x3UWiL8Remx0=";
/*
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD8DBQFHphOV+h38a3n8zjMRAll+AJ9KA6WiDJcTN4qfrslSemUMr+FBrwCeM8pF
D8usM7Dxp5yrDrCYZ5AIijc=
=SrXI
-----END PGP SIGNATURE-----
*/
/*
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

*/
    /* HungryHobo's key */
    private static final String DEFAULT_TRUSTED_KEY4 =
        "<KEY>" +
        "<KEY>" +
        <KEY>;
/*
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iEYEARECAAYFAkysnNIACgkQHix7YXbc3BJVfwCeNGUHaWSqZUbWN9L8VyQLpwxI
JXQAnA28vDmMMMH/WPbC5ixmJeGGNUiR
=3oMC
-----END PGP SIGNATURE-----
*/

    private static final int    VERSION_BYTES       = 16;
    public static final int    HEADER_BYTES        = Signature.SIGNATURE_BYTES + VERSION_BYTES;
    private static final String PROP_TRUSTED_KEYS   = "router.trustedUpdateKeys";

    private static I2PAppContext _context;

    private Log       _log;
    private Map<SigningPublicKey, String> _trustedKeys;
    private String _newVersion;
    /** 172 */
    private static final int KEYSIZE_B64_BYTES = 2 + (SigningPublicKey.KEYSIZE_BYTES * 4 / 3);

    /**
     * Constructs a new <code>TrustedUpdate</code> with the default global
     * context.
     */
    public TrustedUpdate() {
        this(I2PAppContext.getGlobalContext());
    }

    /**
     * Constructs a new <code>TrustedUpdate</code> with the given
     * {@link net.i2p.I2PAppContext}.
     * 
     * @param context An instance of <code>I2PAppContext</code>.
     */
    public TrustedUpdate(I2PAppContext context) {
        _context = context;
        _log = _context.logManager().getLog(TrustedUpdate.class);
        _trustedKeys = new HashMap(4);
        _newVersion = null;

        String propertyTrustedKeys = context.getProperty(PROP_TRUSTED_KEYS);

        if ( (propertyTrustedKeys != null) && (propertyTrustedKeys.length() > 0) ) {
            StringTokenizer propertyTrustedKeysTokens = new StringTokenizer(propertyTrustedKeys, " ,\r\n");

            while (propertyTrustedKeysTokens.hasMoreTokens())
                addKey(propertyTrustedKeysTokens.nextToken().trim(), "");

        } else {
            addKey(DEFAULT_TRUSTED_KEY, "jrandom@mail.i2p");
            addKey(DEFAULT_TRUSTED_KEY2, "zzz@mail.i2p");
            //addKey(DEFAULT_TRUSTED_KEY3, "complication@mail.i2p");
            addKey(DEFAULT_TRUSTED_KEY4, "HungryHobo@mail.i2p");
        }
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("TrustedUpdate created, trusting " + _trustedKeys.size() + " keys.");
    }

    /**
     *  Duplicate keys or names rejected,
     *  except that duplicate empty names are allowed
     *  @since 0.7.12
     *  @return true if successful
     */
    public boolean addKey(String key, String name) {
        SigningPublicKey signingPublicKey = new SigningPublicKey();
        try {
            // fromBase64() won't reject a string that is too long
            if (key.length() != KEYSIZE_B64_BYTES)
                throw new DataFormatException("x");
            signingPublicKey.fromBase64(key);
{'fraction_non_alphanumeric': 0.12314553563302084, 'fraction_numerical': 0.02575771366160007, 'mean_word_length': 3.0337738619676946, 'pattern_counts': {'":': 0, '<': 85, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1452613', 'n_tokens_mistral': 4098, 'n_tokens_neox': 3955, 'n_words': 766}