Search in sources :

Example 1 with Signature

use of net.i2p.data.Signature in project i2p.i2p by i2p.

the class ProofHelper method getProof.

public String getProof() {
    StringBuilder buf = new StringBuilder(512);
    RouterInfo us = _context.router().getRouterInfo();
    buf.append("Hash: ").append(us.getIdentity().calculateHash().toBase64()).append('\n');
    // buf.append("Ident: ").append(us.getIdentity().toBase64()).append('\n');
    for (RouterAddress addr : us.getAddresses()) {
        buf.append(addr.getTransportStyle()).append(": ").append(addr.getHost()).append('\n');
    }
    buf.append("Caps: ").append(us.getCapabilities()).append('\n');
    // no trailing newline
    buf.append("Date: ").append(new Date());
    String msg = buf.toString();
    byte[] data = DataHelper.getUTF8(msg);
    Signature sig = _context.dsa().sign(data, _context.keyManager().getSigningPrivateKey());
    buf.setLength(0);
    buf.append("---BEGIN I2P SIGNED MESSAGE---\n");
    buf.append(msg);
    buf.append("\n---BEGIN I2P SIGNATURE---\n");
    buf.append(sig.toBase64());
    buf.append("\n---END I2P SIGNATURE---");
    return buf.toString();
}
Also used : RouterInfo(net.i2p.data.router.RouterInfo) Signature(net.i2p.data.Signature) RouterAddress(net.i2p.data.router.RouterAddress) Date(java.util.Date)

Example 2 with Signature

use of net.i2p.data.Signature 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 3 with Signature

use of net.i2p.data.Signature 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)

Example 4 with Signature

use of net.i2p.data.Signature in project i2p.i2p by i2p.

the class BlocklistEntries method verify.

public synchronized boolean verify(I2PAppContext ctx) {
    if (verified)
        return true;
    if (signer == null || sig == null || supdated == null)
        return false;
    if (updated > ctx.clock().now() + MAX_FUTURE)
        return false;
    Log log = ctx.logManager().getLog(BlocklistEntries.class);
    String[] ss = DataHelper.split(sig, ":", 2);
    if (ss.length != 2) {
        log.error("blocklist feed bad sig: " + sig);
        return false;
    }
    SigType type = SigType.parseSigType(ss[0]);
    if (type == null) {
        log.error("blocklist feed bad sig: " + sig);
        return false;
    }
    if (!type.isAvailable()) {
        log.error("blocklist feed sigtype unavailable: " + sig);
        return false;
    }
    byte[] bsig = Base64.decode(ss[1]);
    if (bsig == null) {
        log.error("blocklist feed bad sig: " + sig);
        return false;
    }
    Signature ssig;
    try {
        ssig = new Signature(type, bsig);
    } catch (IllegalArgumentException iae) {
        log.error("blocklist feed bad sig: " + sig);
        return false;
    }
    // look in both install dir and config dir for the signer cert
    KeyRing ring = new DirKeyRing(new File(ctx.getBaseDir(), "certificates"));
    PublicKey pubkey;
    try {
        pubkey = ring.getKey(signer, CONTENT_ROUTER, type);
    } catch (IOException ioe) {
        log.error("blocklist feed error", ioe);
        return false;
    } catch (GeneralSecurityException gse) {
        log.error("blocklist feed error", gse);
        return false;
    }
    if (pubkey == null) {
        boolean diff = true;
        try {
            diff = !ctx.getBaseDir().getCanonicalPath().equals(ctx.getConfigDir().getCanonicalPath());
        } catch (IOException ioe) {
        }
        if (diff) {
            ring = new DirKeyRing(new File(ctx.getConfigDir(), "certificates"));
            try {
                pubkey = ring.getKey(signer, CONTENT_ROUTER, type);
            } catch (IOException ioe) {
                log.error("blocklist feed error", ioe);
                return false;
            } catch (GeneralSecurityException gse) {
                log.error("blocklist feed error", gse);
                return false;
            }
        }
        if (pubkey == null) {
            log.error("unknown signer for blocklist feed: " + signer);
            return false;
        }
    }
    SigningPublicKey spubkey;
    try {
        spubkey = SigUtil.fromJavaKey(pubkey, type);
    } catch (GeneralSecurityException gse) {
        log.error("blocklist feed bad sig: " + sig, gse);
        return false;
    }
    StringBuilder buf = new StringBuilder(256);
    buf.append(supdated).append('\n');
    for (String s : entries) {
        buf.append(s).append('\n');
    }
    for (String s : removes) {
        buf.append('!').append(s).append('\n');
    }
    byte[] data = DataHelper.getUTF8(buf.toString());
    boolean rv = ctx.dsa().verifySignature(ssig, data, spubkey);
    if (rv)
        log.info("blocklist feed sig ok");
    else
        log.error("blocklist feed sig verify fail: " + signer);
    verified = rv;
    return rv;
}
Also used : SigningPublicKey(net.i2p.data.SigningPublicKey) Log(net.i2p.util.Log) PublicKey(java.security.PublicKey) SigningPublicKey(net.i2p.data.SigningPublicKey) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) SigType(net.i2p.crypto.SigType) DirKeyRing(net.i2p.crypto.DirKeyRing) KeyRing(net.i2p.crypto.KeyRing) DirKeyRing(net.i2p.crypto.DirKeyRing) Signature(net.i2p.data.Signature) File(java.io.File)

Example 5 with Signature

use of net.i2p.data.Signature in project i2p.i2p by i2p.

the class SU3File method verifyAndMigrate.

/**
 *  One-pass verify and extract the content.
 *  Recommend extracting to a temp location as the sig is not checked until
 *  after extraction. This will delete the file if the sig does not verify.
 *  Throws IOE on all format errors.
 *
 *  @param migrateTo the output file, probably in zip format. Null for verify only.
 *  @return true if signature is good
 */
public boolean verifyAndMigrate(File migrateTo) throws IOException {
    InputStream in = null;
    FileOutputStream out = null;
    boolean rv = false;
    try {
        in = new BufferedInputStream(new FileInputStream(_file));
        // read 10 bytes to get the sig type
        in.mark(10);
        // following is a dup of that in verifyHeader()
        byte[] magic = new byte[MAGIC_BYTES.length];
        DataHelper.read(in, magic);
        if (!DataHelper.eq(magic, MAGIC_BYTES))
            throw new IOException("Not an su3 file");
        skip(in, 1);
        int foo = in.read();
        if (foo != FILE_VERSION)
            throw new IOException("bad file version");
        skip(in, 1);
        int sigTypeCode = in.read();
        _sigType = SigType.getByCode(sigTypeCode);
        if (_sigType == null)
            throw new IOException("unknown sig type: " + sigTypeCode);
        // end duplicate code
        // rewind
        in.reset();
        MessageDigest md = _sigType.getDigestInstance();
        DigestInputStream din = new DigestInputStream(in, md);
        in = din;
        if (!_headerVerified)
            verifyHeader(in);
        else
            skip(in, getContentOffset());
        if (_verifySignature) {
            if (_signerPubkey == null)
                throw new IOException("unknown signer: " + _signer + " for content type: " + _contentType.getName());
        }
        if (// else verify only
        migrateTo != null)
            out = new SecureFileOutputStream(migrateTo);
        byte[] buf = new byte[16 * 1024];
        long tot = 0;
        while (tot < _contentLength) {
            int read = in.read(buf, 0, (int) Math.min(buf.length, _contentLength - tot));
            if (read < 0)
                throw new EOFException();
            if (// else verify only
            migrateTo != null)
                out.write(buf, 0, read);
            tot += read;
        }
        if (_verifySignature) {
            byte[] sha = md.digest();
            din.on(false);
            Signature signature = new Signature(_sigType);
            signature.readBytes(in);
            int avail = in.available();
            if (avail > 0)
                throw new IOException(avail + " bytes data after sig");
            SimpleDataStructure hash = _sigType.getHashInstance();
            hash.setData(sha);
            // System.out.println("hash\n" + HexDump.dump(sha));
            // System.out.println("sig\n" + HexDump.dump(signature.getData()));
            rv = _context.dsa().verifySignature(signature, hash, _signerPubkey);
        } else {
            rv = true;
        }
    } catch (DataFormatException dfe) {
        IOException ioe = new IOException("foo");
        ioe.initCause(dfe);
        throw ioe;
    } finally {
        if (in != null)
            try {
                in.close();
            } catch (IOException ioe) {
            }
        if (out != null) {
            // so do a POSIX flush and sync to ensure it will be there.
            try {
                out.flush();
                out.getFD().sync();
            } catch (IOException ioe) {
            }
            try {
                out.close();
            } catch (IOException ioe) {
            }
        }
        if (migrateTo != null && !rv)
            migrateTo.delete();
    }
    return rv;
}
Also used : DigestInputStream(java.security.DigestInputStream) BufferedInputStream(java.io.BufferedInputStream) FileInputStream(java.io.FileInputStream) DigestInputStream(java.security.DigestInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) DataFormatException(net.i2p.data.DataFormatException) BufferedInputStream(java.io.BufferedInputStream) SecureFileOutputStream(net.i2p.util.SecureFileOutputStream) FileOutputStream(java.io.FileOutputStream) Signature(net.i2p.data.Signature) EOFException(java.io.EOFException) SecureFileOutputStream(net.i2p.util.SecureFileOutputStream) MessageDigest(java.security.MessageDigest) SimpleDataStructure(net.i2p.data.SimpleDataStructure)

Aggregations

Signature (net.i2p.data.Signature)36 IOException (java.io.IOException)16 SigType (net.i2p.crypto.SigType)14 DataFormatException (net.i2p.data.DataFormatException)11 SigningPublicKey (net.i2p.data.SigningPublicKey)11 ByteArrayInputStream (java.io.ByteArrayInputStream)7 GeneralSecurityException (java.security.GeneralSecurityException)6 FileInputStream (java.io.FileInputStream)5 StringWriter (java.io.StringWriter)5 SigningPrivateKey (net.i2p.data.SigningPrivateKey)5 InetAddress (java.net.InetAddress)4 MessageDigest (java.security.MessageDigest)4 Destination (net.i2p.data.Destination)4 SimpleDataStructure (net.i2p.data.SimpleDataStructure)4 FileOutputStream (java.io.FileOutputStream)3 InputStream (java.io.InputStream)3 DigestInputStream (java.security.DigestInputStream)3 Hash (net.i2p.data.Hash)3 Log (net.i2p.util.Log)3 SecureFileOutputStream (net.i2p.util.SecureFileOutputStream)3