Search in sources :

Example 1 with SigType

use of net.i2p.crypto.SigType in project i2p.i2p by i2p.

the class I2PSocketManagerFull method getSigType.

/**
 *  @param opts may be null
 *  @since 0.9.21 copied from I2PSocketManagerFactory
 */
private SigType getSigType(Properties opts) {
    if (opts != null) {
        String st = opts.getProperty(I2PClient.PROP_SIGTYPE);
        if (st != null) {
            SigType rv = SigType.parseSigType(st);
            if (rv != null && rv.isAvailable())
                return rv;
            if (rv != null)
                st = rv.toString();
            _log.logAlways(Log.WARN, "Unsupported sig type " + st + ", reverting to " + I2PClient.DEFAULT_SIGTYPE);
        // TODO throw instead?
        }
    }
    return I2PClient.DEFAULT_SIGTYPE;
}
Also used : SigType(net.i2p.crypto.SigType)

Example 2 with SigType

use of net.i2p.crypto.SigType in project i2p.i2p by i2p.

the class I2PSocketManagerFull method addSubsession.

/**
 *  For a server, you must call connect() on the returned object.
 *  Connecting the primary session does NOT connect any subsessions.
 *  If the primary session is not connected, connecting a subsession will connect the primary session first.
 *
 *  @return a new subsession, non-null
 *  @param privateKeyStream null for transient, if non-null must have same encryption keys as primary session
 *                          and different signing keys
 *  @param opts subsession options if any, may be null
 *  @since 0.9.21
 */
public I2PSession addSubsession(InputStream privateKeyStream, Properties opts) throws I2PSessionException {
    if (privateKeyStream == null) {
        // We don't actually need the same pubkey in the dest, just in the LS.
        // The dest one is unused. But this is how we find the LS keys
        // to reuse in RequestLeaseSetMessageHandler.
        ByteArrayOutputStream keyStream = new ByteArrayOutputStream(1024);
        try {
            SigType type = getSigType(opts);
            if (type != SigType.DSA_SHA1) {
                // hassle, have to set up the padding and cert, see I2PClientImpl
                throw new I2PSessionException("type " + type + " unsupported");
            }
            PublicKey pub = _session.getMyDestination().getPublicKey();
            PrivateKey priv = _session.getDecryptionKey();
            SimpleDataStructure[] keys = _context.keyGenerator().generateSigningKeys(type);
            pub.writeBytes(keyStream);
            // signing pub
            keys[0].writeBytes(keyStream);
            Certificate.NULL_CERT.writeBytes(keyStream);
            priv.writeBytes(keyStream);
            // signing priv
            keys[1].writeBytes(keyStream);
        } catch (GeneralSecurityException e) {
            throw new I2PSessionException("Error creating keys", e);
        } catch (I2PException e) {
            throw new I2PSessionException("Error creating keys", e);
        } catch (IOException e) {
            throw new I2PSessionException("Error creating keys", e);
        } catch (RuntimeException e) {
            throw new I2PSessionException("Error creating keys", e);
        }
        privateKeyStream = new ByteArrayInputStream(keyStream.toByteArray());
    }
    I2PSession rv = _session.addSubsession(privateKeyStream, opts);
    boolean added = _subsessions.add(rv);
    if (!added) {
        // shouldn't happen
        _session.removeSubsession(rv);
        throw new I2PSessionException("dup");
    }
    ConnectionOptions defaultOptions = new ConnectionOptions(opts);
    int protocol = defaultOptions.getEnforceProtocol() ? I2PSession.PROTO_STREAMING : I2PSession.PROTO_ANY;
    rv.addMuxedSessionListener(_connectionManager.getMessageHandler(), protocol, defaultOptions.getLocalPort());
    if (_log.shouldLog(Log.WARN))
        _log.warn("Added subsession " + rv);
    return rv;
}
Also used : I2PException(net.i2p.I2PException) PrivateKey(net.i2p.data.PrivateKey) PublicKey(net.i2p.data.PublicKey) GeneralSecurityException(java.security.GeneralSecurityException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) SigType(net.i2p.crypto.SigType) ByteArrayInputStream(java.io.ByteArrayInputStream) I2PSessionException(net.i2p.client.I2PSessionException) I2PSession(net.i2p.client.I2PSession) SimpleDataStructure(net.i2p.data.SimpleDataStructure)

Example 3 with SigType

use of net.i2p.crypto.SigType in project i2p.i2p by i2p.

the class Packet method readPacket.

/**
 * Read the packet from the buffer (starting at the offset) and return
 * the number of bytes read.
 *
 * @param buffer packet buffer containing the data
 * @param offset index into the buffer to start readign
 * @param length how many bytes within the buffer past the offset are
 *               part of the packet?
 *
 * @throws IllegalArgumentException if the data is b0rked
 */
public void readPacket(byte[] buffer, int offset, int length) throws IllegalArgumentException {
    if (buffer.length - offset < length)
        throw new IllegalArgumentException("len=" + buffer.length + " off=" + offset + " length=" + length);
    if (// min header size
    length < 22)
        throw new IllegalArgumentException("Too small: len=" + buffer.length);
    int cur = offset;
    setSendStreamId(DataHelper.fromLong(buffer, cur, 4));
    cur += 4;
    setReceiveStreamId(DataHelper.fromLong(buffer, cur, 4));
    cur += 4;
    setSequenceNum(DataHelper.fromLong(buffer, cur, 4));
    cur += 4;
    setAckThrough(DataHelper.fromLong(buffer, cur, 4));
    cur += 4;
    int numNacks = buffer[cur] & 0xff;
    cur++;
    if (length < 22 + numNacks * 4)
        throw new IllegalArgumentException("Too small with " + numNacks + " nacks: " + length);
    if (numNacks > 0) {
        long[] nacks = new long[numNacks];
        for (int i = 0; i < numNacks; i++) {
            nacks[i] = DataHelper.fromLong(buffer, cur, 4);
            cur += 4;
        }
        setNacks(nacks);
    } else {
        setNacks(null);
    }
    setResendDelay(buffer[cur] & 0xff);
    cur++;
    setFlags((int) DataHelper.fromLong(buffer, cur, 2));
    cur += 2;
    int optionSize = (int) DataHelper.fromLong(buffer, cur, 2);
    cur += 2;
    if (length < 22 + numNacks * 4 + optionSize)
        throw new IllegalArgumentException("Too small with " + numNacks + " nacks and " + optionSize + " options: " + length);
    int payloadBegin = cur + optionSize;
    int payloadSize = length - payloadBegin;
    if ((payloadSize < 0) || (payloadSize > MAX_PAYLOAD_SIZE))
        throw new IllegalArgumentException("length: " + length + " offset: " + offset + " begin: " + payloadBegin);
    // skip ahead to the payload
    // _payload = new ByteArray(new byte[payloadSize]);
    _payload = new ByteArray(buffer, payloadBegin, payloadSize);
    // ok now lets go back and deal with the options
    if (isFlagSet(FLAG_DELAY_REQUESTED)) {
        setOptionalDelay((int) DataHelper.fromLong(buffer, cur, 2));
        cur += 2;
    }
    if (isFlagSet(FLAG_FROM_INCLUDED)) {
        ByteArrayInputStream bais = new ByteArrayInputStream(buffer, cur, length - cur);
        try {
            Destination optionFrom = Destination.create(bais);
            cur += optionFrom.size();
            _optionFrom = optionFrom;
        } catch (IOException ioe) {
            throw new IllegalArgumentException("Bad from field", ioe);
        } catch (DataFormatException dfe) {
            throw new IllegalArgumentException("Bad from field", dfe);
        }
    }
    if (isFlagSet(FLAG_MAX_PACKET_SIZE_INCLUDED)) {
        setOptionalMaxSize((int) DataHelper.fromLong(buffer, cur, 2));
        cur += 2;
    }
    if (isFlagSet(FLAG_SIGNATURE_INCLUDED)) {
        Signature optionSignature;
        Destination from = getOptionalFrom();
        if (from != null) {
            optionSignature = new Signature(from.getSigningPublicKey().getType());
        } else {
            // super cheat for now, look for correct type,
            // assume no more options. If we add to the options
            // we will have to ask the manager.
            // We will get this wrong for Ed25519, same length as P256...
            // See verifySignature() below where we will recast the signature to
            // the correct type if necessary
            int siglen = payloadBegin - cur;
            SigType type = null;
            for (SigType t : SigType.values()) {
                if (t.getSigLen() == siglen) {
                    type = t;
                    break;
                }
            }
            if (type == null) {
                if (siglen < Signature.SIGNATURE_BYTES)
                    throw new IllegalArgumentException("unknown sig type len=" + siglen);
                // Hope it's the default type with some unknown options following;
                // if not the sig will fail later
                type = SigType.DSA_SHA1;
                siglen = Signature.SIGNATURE_BYTES;
            }
            optionSignature = new Signature(type);
        }
        byte[] buf = new byte[optionSignature.length()];
        System.arraycopy(buffer, cur, buf, 0, buf.length);
        optionSignature.setData(buf);
        setOptionalSignature(optionSignature);
        cur += buf.length;
    }
}
Also used : Destination(net.i2p.data.Destination) DataFormatException(net.i2p.data.DataFormatException) ByteArrayInputStream(java.io.ByteArrayInputStream) Signature(net.i2p.data.Signature) ByteArray(net.i2p.data.ByteArray) IOException(java.io.IOException) SigType(net.i2p.crypto.SigType)

Example 4 with SigType

use of net.i2p.crypto.SigType in project i2p.i2p by i2p.

the class TunnelController method createPrivateKey.

/**
 * @return success
 */
private boolean createPrivateKey() {
    I2PClient client = I2PClientFactory.createClient();
    File keyFile = getPrivateKeyFile();
    if (keyFile == null) {
        log("No filename specified for the private key");
        return false;
    }
    if (keyFile.exists()) {
        // log("Not overwriting existing private keys in " + keyFile.getAbsolutePath());
        return true;
    } else {
        File parent = keyFile.getParentFile();
        if ((parent != null) && (!parent.exists()))
            parent.mkdirs();
    }
    FileOutputStream fos = null;
    try {
        fos = new SecureFileOutputStream(keyFile);
        SigType stype = PREFERRED_SIGTYPE;
        String st = _config.getProperty(OPT_SIG_TYPE);
        if (st != null) {
            SigType type = SigType.parseSigType(st);
            if (type != null && type.isAvailable())
                stype = type;
            else
                log("Unsupported sig type " + st + ", reverting to " + stype);
        }
        Destination dest = client.createDestination(fos, stype);
        String destStr = dest.toBase64();
        log("Private key created and saved in " + keyFile.getAbsolutePath());
        log("You should backup this file in a secure place.");
        log("New destination: " + destStr);
        String b32 = dest.toBase32();
        log("Base32: " + b32);
        File backupDir = new SecureFile(I2PAppContext.getGlobalContext().getConfigDir(), KEY_BACKUP_DIR);
        if (backupDir.isDirectory() || backupDir.mkdir()) {
            String name = b32 + '-' + I2PAppContext.getGlobalContext().clock().now() + ".dat";
            File backup = new File(backupDir, name);
            if (FileUtil.copy(keyFile, backup, false, true)) {
                SecureFileOutputStream.setPerms(backup);
                log("Private key backup saved to " + backup.getAbsolutePath());
            }
        }
    } catch (I2PException ie) {
        if (_log.shouldLog(Log.ERROR))
            _log.error("Error creating new destination", ie);
        log("Error creating new destination: " + ie.getMessage());
        return false;
    } catch (IOException ioe) {
        if (_log.shouldLog(Log.ERROR))
            _log.error("Error creating writing the destination to " + keyFile.getAbsolutePath(), ioe);
        log("Error writing the keys to " + keyFile.getAbsolutePath());
        return false;
    } finally {
        if (fos != null)
            try {
                fos.close();
            } catch (IOException ioe) {
            }
    }
    return true;
}
Also used : I2PException(net.i2p.I2PException) Destination(net.i2p.data.Destination) SecureFile(net.i2p.util.SecureFile) SecureFileOutputStream(net.i2p.util.SecureFileOutputStream) FileOutputStream(java.io.FileOutputStream) I2PClient(net.i2p.client.I2PClient) SecureFileOutputStream(net.i2p.util.SecureFileOutputStream) IOException(java.io.IOException) SecureFile(net.i2p.util.SecureFile) PrivateKeyFile(net.i2p.data.PrivateKeyFile) File(java.io.File) SigType(net.i2p.crypto.SigType)

Example 5 with SigType

use of net.i2p.crypto.SigType in project i2p.i2p by i2p.

the class BlocklistEntries method main.

/**
 *  BlocklistEntries [-p keystorepw] input.txt keystore.ks you@mail.i2p
 *  File format: One entry per line, # starts a comment, ! starts an unblock entry.
 *  Single IPv4 or IPv6 address only (no mask allowed), or 44-char base 64 router hash.
 *  See MAX_ENTRIES above.
 */
public static void main(String[] args) {
    if (args.length < 3) {
        System.err.println("Usage: BlocklistEntries [-p keystorepw] input.txt keystore.ks you@mail.i2p");
        System.exit(1);
    }
    int st;
    String kspass;
    if (args[0].equals("-p")) {
        kspass = args[1];
        st = 2;
    } else {
        kspass = KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD;
        st = 0;
    }
    String inputFile = args[st++];
    String privateKeyFile = args[st++];
    String signerName = args[st];
    I2PAppContext ctx = new I2PAppContext();
    List<String> elist = new ArrayList<String>(16);
    List<String> rlist = new ArrayList<String>(4);
    StringBuilder buf = new StringBuilder();
    long now = System.currentTimeMillis();
    String date = RFC3339Date.to3339Date(now);
    buf.append(date).append('\n');
    ;
    BufferedReader br = null;
    try {
        br = new BufferedReader(new InputStreamReader(new FileInputStream(inputFile), "UTF-8"));
        String s = null;
        while ((s = br.readLine()) != null) {
            int index = s.indexOf('#');
            if (index == 0)
                // comment
                continue;
            if (index > 0)
                s = s.substring(0, index);
            s = s.trim();
            if (s.length() < 7) {
                if (s.length() > 0)
                    System.err.println("Bad line: " + s);
                continue;
            }
            if (s.startsWith("!")) {
                rlist.add(s.substring(1));
            } else {
                elist.add(s);
                buf.append(s).append('\n');
                ;
            }
        }
    } catch (IOException ioe) {
        System.err.println("load error from " + args[0]);
        ioe.printStackTrace();
        System.exit(1);
    } finally {
        if (br != null)
            try {
                br.close();
            } catch (IOException ioe) {
            }
    }
    if (elist.isEmpty() && rlist.isEmpty()) {
        System.err.println("nothing to sign");
        System.exit(1);
    }
    if (elist.size() > MAX_ENTRIES) {
        System.err.println("too many blocks, max is " + MAX_ENTRIES);
        System.exit(1);
    }
    for (String s : rlist) {
        buf.append('!').append(s).append('\n');
    }
    SigningPrivateKey spk = null;
    try {
        String keypw = "";
        while (keypw.length() < 6) {
            System.err.print("Enter password for key \"" + signerName + "\": ");
            keypw = DataHelper.readLine(System.in);
            if (keypw == null) {
                System.out.println("\nEOF reading password");
                System.exit(1);
            }
            keypw = keypw.trim();
            if (keypw.length() > 0 && keypw.length() < 6)
                System.out.println("Key password must be at least 6 characters");
        }
        File pkfile = new File(privateKeyFile);
        PrivateKey pk = KeyStoreUtil.getPrivateKey(pkfile, kspass, signerName, keypw);
        if (pk == null) {
            System.out.println("Private key for " + signerName + " not found in keystore " + privateKeyFile);
            System.exit(1);
        }
        spk = SigUtil.fromJavaKey(pk);
    } catch (GeneralSecurityException gse) {
        System.out.println("Error signing input file '" + inputFile + "'");
        gse.printStackTrace();
        System.exit(1);
    } catch (IOException ioe) {
        System.out.println("Error signing input file '" + inputFile + "'");
        ioe.printStackTrace();
        System.exit(1);
    }
    SigType type = spk.getType();
    byte[] data = DataHelper.getUTF8(buf.toString());
    Signature ssig = ctx.dsa().sign(data, spk);
    if (ssig == null) {
        System.err.println("sign failed");
        System.exit(1);
    }
    String bsig = Base64.encode(ssig.getData());
    // verify
    BlocklistEntries ble = new BlocklistEntries(elist.size());
    ble.entries.addAll(elist);
    ble.removes.addAll(rlist);
    ble.supdated = date;
    ble.signer = signerName;
    ble.sig = type.getCode() + ":" + bsig;
    boolean ok = ble.verify(ctx);
    if (!ok) {
        System.err.println("verify failed");
        System.exit(1);
    }
    System.out.println("  <i2p:blocklist signer=\"" + signerName + "\" sig=\"" + type.getCode() + ':' + bsig + "\">");
    System.out.println("    <updated>" + date + "</updated>");
    for (String e : elist) {
        System.out.println("    <i2p:block>" + e + "</i2p:block>");
    }
    for (String e : rlist) {
        System.out.println("    <i2p:unblock>" + e + "</i2p:unblock>");
    }
    System.out.println("  </i2p:blocklist>");
}
Also used : SigningPrivateKey(net.i2p.data.SigningPrivateKey) PrivateKey(java.security.PrivateKey) InputStreamReader(java.io.InputStreamReader) I2PAppContext(net.i2p.I2PAppContext) GeneralSecurityException(java.security.GeneralSecurityException) ArrayList(java.util.ArrayList) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) SigType(net.i2p.crypto.SigType) SigningPrivateKey(net.i2p.data.SigningPrivateKey) Signature(net.i2p.data.Signature) BufferedReader(java.io.BufferedReader) File(java.io.File)

Aggregations

SigType (net.i2p.crypto.SigType)44 IOException (java.io.IOException)18 DataFormatException (net.i2p.data.DataFormatException)15 Signature (net.i2p.data.Signature)14 Destination (net.i2p.data.Destination)12 SigningPublicKey (net.i2p.data.SigningPublicKey)11 File (java.io.File)6 GeneralSecurityException (java.security.GeneralSecurityException)6 Properties (java.util.Properties)6 Hash (net.i2p.data.Hash)6 PrivateKey (net.i2p.data.PrivateKey)6 SigningPrivateKey (net.i2p.data.SigningPrivateKey)6 PublicKey (net.i2p.data.PublicKey)5 SimpleDataStructure (net.i2p.data.SimpleDataStructure)5 RouterInfo (net.i2p.data.router.RouterInfo)5 ByteArrayOutputStream (java.io.ByteArrayOutputStream)4 I2PException (net.i2p.I2PException)4 RouterIdentity (net.i2p.data.router.RouterIdentity)4 Log (net.i2p.util.Log)4 ByteArrayInputStream (java.io.ByteArrayInputStream)3