Search in sources :

Example 16 with Signature

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

the class PacketBuilder method buildSessionCreatedPacket.

/**
 * Build a new SessionCreated packet for the given peer, encrypting it
 * as necessary.
 *
 * @return ready to send packet, or null if there was a problem
 */
public UDPPacket buildSessionCreatedPacket(InboundEstablishState state, int externalPort, SessionKey ourIntroKey) {
    UDPPacket packet = buildPacketHeader(SESSION_CREATED_FLAG_BYTE);
    DatagramPacket pkt = packet.getPacket();
    byte[] data = pkt.getData();
    int off = HEADER_SIZE;
    InetAddress to = null;
    try {
        to = InetAddress.getByAddress(state.getSentIP());
    } catch (UnknownHostException uhe) {
        if (_log.shouldLog(Log.ERROR))
            _log.error("How did we think this was a valid IP?  " + state.getRemoteHostId().toString());
        packet.release();
        return null;
    }
    state.prepareSessionCreated();
    byte[] sentIP = state.getSentIP();
    if ((sentIP == null) || (sentIP.length <= 0) || (!_transport.isValid(sentIP))) {
        if (_log.shouldLog(Log.ERROR))
            _log.error("How did our sent IP become invalid? " + state);
        state.fail();
        packet.release();
        return null;
    }
    // now for the body
    System.arraycopy(state.getSentY(), 0, data, off, state.getSentY().length);
    off += state.getSentY().length;
    DataHelper.toLong(data, off, 1, sentIP.length);
    off += 1;
    System.arraycopy(sentIP, 0, data, off, sentIP.length);
    off += sentIP.length;
    DataHelper.toLong(data, off, 2, state.getSentPort());
    off += 2;
    DataHelper.toLong(data, off, 4, state.getSentRelayTag());
    off += 4;
    DataHelper.toLong(data, off, 4, state.getSentSignedOnTime());
    off += 4;
    // handle variable signature size
    Signature sig = state.getSentSignature();
    int siglen = sig.length();
    System.arraycopy(sig.getData(), 0, data, off, siglen);
    off += siglen;
    // ok, we need another few bytes of random padding
    int rem = siglen % 16;
    int padding;
    if (rem > 0) {
        padding = 16 - rem;
        _context.random().nextBytes(data, off, padding);
        off += padding;
    } else {
        padding = 0;
    }
    if (_log.shouldLog(Log.DEBUG)) {
        StringBuilder buf = new StringBuilder(128);
        buf.append("Sending sessionCreated:");
        buf.append(" Alice: ").append(Addresses.toString(sentIP, state.getSentPort()));
        buf.append(" Bob: ").append(Addresses.toString(state.getReceivedOurIP(), externalPort));
        buf.append(" RelayTag: ").append(state.getSentRelayTag());
        buf.append(" SignedOn: ").append(state.getSentSignedOnTime());
        buf.append(" signature: ").append(Base64.encode(sig.getData()));
        buf.append("\nRawCreated: ").append(Base64.encode(data, 0, off));
        buf.append("\nsignedTime: ").append(Base64.encode(data, off - padding - siglen - 4, 4));
        _log.debug(buf.toString());
    }
    // ok, now the full data is in there, but we also need to encrypt
    // the signature, which means we need the IV
    byte[] iv = SimpleByteCache.acquire(UDPPacket.IV_SIZE);
    _context.random().nextBytes(iv);
    int encrWrite = siglen + padding;
    int sigBegin = off - encrWrite;
    _context.aes().encrypt(data, sigBegin, data, sigBegin, state.getCipherKey(), iv, encrWrite);
    // pad up so we're on the encryption boundary
    off = pad1(data, off);
    off = pad2(data, off);
    pkt.setLength(off);
    authenticate(packet, ourIntroKey, ourIntroKey, iv);
    setTo(packet, to, state.getSentPort());
    SimpleByteCache.release(iv);
    packet.setMessageType(TYPE_CREAT);
    return packet;
}
Also used : UnknownHostException(java.net.UnknownHostException) DatagramPacket(java.net.DatagramPacket) Signature(net.i2p.data.Signature) InetAddress(java.net.InetAddress)

Example 17 with Signature

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

the class FamilyKeyCrypto method sign.

/**
 *  Caller must add family to RI also.
 *  throws on all errors
 *
 *  @param family non-null, must match that we were initialized with or will throw GSE
 *  @param h non-null
 *  @return non-null options to be added to the RI
 *  @throws GeneralSecurityException on null hash, null or changed family, or signing error
 */
public Map<String, String> sign(String family, Hash h) throws GeneralSecurityException {
    if (_privkey == null) {
        _log.logAlways(Log.WARN, "family name now set, must restart router to generate or load keys");
        throw new GeneralSecurityException("family name now set, must restart router to generate or load keys");
    }
    if (h == null)
        throw new GeneralSecurityException("null router hash");
    if (!_fname.equals(family)) {
        _log.logAlways(Log.WARN, "family name changed, must restart router to generate or load new keys");
        throw new GeneralSecurityException("family name changed, must restart router to generate or load new keys");
    }
    byte[] nb = DataHelper.getUTF8(_fname);
    int len = nb.length + Hash.HASH_LENGTH;
    byte[] b = new byte[len];
    System.arraycopy(nb, 0, b, 0, nb.length);
    System.arraycopy(h.getData(), 0, b, nb.length, Hash.HASH_LENGTH);
    Signature sig = _context.dsa().sign(b, _privkey);
    if (sig == null)
        throw new GeneralSecurityException("sig failed");
    Map<String, String> rv = new HashMap<String, String>(3);
    rv.put(OPT_NAME, family);
    rv.put(OPT_KEY, _pubkey.getType().getCode() + ":" + _pubkey.toBase64());
    rv.put(OPT_SIG, sig.toBase64());
    return rv;
}
Also used : HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) GeneralSecurityException(java.security.GeneralSecurityException) Signature(net.i2p.data.Signature)

Example 18 with Signature

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

the class FamilyKeyCrypto method verify.

/**
 *  Verify the family in a RouterInfo, name already retrieved
 *  @since 0.9.28
 */
private boolean verify(RouterInfo ri, String name) {
    Hash h = ri.getHash();
    String ssig = ri.getOption(OPT_SIG);
    if (ssig == null) {
        if (_log.shouldInfo())
            _log.info("No sig for " + h + ' ' + name);
        return false;
    }
    String nameAndSig = _verified.get(h);
    String riNameAndSig = name + ssig;
    if (nameAndSig != null) {
        if (nameAndSig.equals(riNameAndSig))
            return true;
        // name or sig changed
        _verified.remove(h);
    }
    SigningPublicKey spk;
    if (name.equals(_fname)) {
        // us
        spk = _pubkey;
    } else {
        if (_negativeCache.contains(h))
            return false;
        spk = loadCert(name);
        if (spk == null) {
            // look for a b64 key in the RI
            String skey = ri.getOption(OPT_KEY);
            if (skey != null) {
                int colon = skey.indexOf(':');
                // switched from ';' to ':' during dev, remove this later
                if (colon < 0)
                    colon = skey.indexOf(';');
                if (colon > 0) {
                    try {
                        int code = Integer.parseInt(skey.substring(0, colon));
                        SigType type = SigType.getByCode(code);
                        if (type != null) {
                            byte[] bkey = Base64.decode(skey.substring(colon + 1));
                            if (bkey != null) {
                                spk = new SigningPublicKey(type, bkey);
                            }
                        }
                    } catch (NumberFormatException e) {
                        if (_log.shouldInfo())
                            _log.info("Bad b64 family key: " + ri, e);
                    } catch (IllegalArgumentException e) {
                        if (_log.shouldInfo())
                            _log.info("Bad b64 family key: " + ri, e);
                    } catch (ArrayIndexOutOfBoundsException e) {
                        if (_log.shouldInfo())
                            _log.info("Bad b64 family key: " + ri, e);
                    }
                }
            }
            if (spk == null) {
                _negativeCache.add(h);
                if (_log.shouldInfo())
                    _log.info("No cert or valid key for " + h + ' ' + name);
                return false;
            }
        }
    }
    if (!spk.getType().isAvailable()) {
        _negativeCache.add(h);
        if (_log.shouldInfo())
            _log.info("Unsupported crypto for sig for " + h);
        return false;
    }
    byte[] bsig = Base64.decode(ssig);
    if (bsig == null) {
        _negativeCache.add(h);
        if (_log.shouldInfo())
            _log.info("Bad sig for " + h + ' ' + name + ' ' + ssig);
        return false;
    }
    Signature sig;
    try {
        sig = new Signature(spk.getType(), bsig);
    } catch (IllegalArgumentException iae) {
        // wrong size (type mismatch)
        _negativeCache.add(h);
        if (_log.shouldInfo())
            _log.info("Bad sig for " + ri, iae);
        return false;
    }
    byte[] nb = DataHelper.getUTF8(name);
    byte[] b = new byte[nb.length + Hash.HASH_LENGTH];
    System.arraycopy(nb, 0, b, 0, nb.length);
    System.arraycopy(ri.getHash().getData(), 0, b, nb.length, Hash.HASH_LENGTH);
    boolean rv = _context.dsa().verifySignature(sig, b, spk);
    if (rv)
        _verified.put(h, riNameAndSig);
    else
        _negativeCache.add(h);
    if (_log.shouldInfo())
        _log.info("Verified? " + rv + " for " + h + ' ' + name + ' ' + ssig);
    return rv;
}
Also used : SigningPublicKey(net.i2p.data.SigningPublicKey) Signature(net.i2p.data.Signature) Hash(net.i2p.data.Hash) SigType(net.i2p.crypto.SigType)

Example 19 with Signature

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

the class ElGamal2048_DSA1024 method verify.

/**
 * Only accepts <code>DSAPublicKey</code>s.
 */
@Override
public boolean verify(byte[] data, byte[] signature, PublicKey key) throws GeneralSecurityException {
    DSAPublicKey dsaKey = castToDSA(key);
    Signature signatureObj = new Signature(signature);
    boolean valid = DSAEngine.getInstance().verifySignature(signatureObj, data, dsaKey.getI2PKey());
    return valid;
}
Also used : Signature(net.i2p.data.Signature)

Example 20 with Signature

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

the class TrustedUpdate method sign.

/**
 * Uses the given {@link net.i2p.data.SigningPrivateKey} to sign the given
 * input file along with its version string using DSA. The output will be a
 * signed update file where the first 40 bytes are the resulting DSA
 * signature, the next 16 bytes are the input file's version string encoded
 * in UTF-8 (padded with trailing <code>0h</code> characters if necessary),
 * and the remaining bytes are the raw bytes of the input file.
 *
 * @param inputFile         The file to be signed.
 * @param signedFile        The signed update file to write.
 * @param signingPrivateKey An instance of <code>SigningPrivateKey</code>
 *                          to sign <code>inputFile</code> with.
 * @param version           The version string of the input file. If this is
 *                          longer than 16 characters it will be truncated.
 *
 * @return An instance of {@link net.i2p.data.Signature}, or
 *         <code>null</code> if there was an error.
 */
public Signature sign(String inputFile, String signedFile, SigningPrivateKey signingPrivateKey, String version) {
    byte[] versionHeader = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    byte[] versionRawBytes = null;
    if (version.length() > VERSION_BYTES)
        version = version.substring(0, VERSION_BYTES);
    try {
        versionRawBytes = version.getBytes("UTF-8");
    } catch (UnsupportedEncodingException e) {
        throw new RuntimeException("your JVM doesnt support utf-8? " + e.getMessage());
    }
    System.arraycopy(versionRawBytes, 0, versionHeader, 0, versionRawBytes.length);
    FileInputStream fileInputStream = null;
    Signature signature = null;
    SequenceInputStream bytesToSignInputStream = null;
    ByteArrayInputStream versionHeaderInputStream = null;
    try {
        fileInputStream = new FileInputStream(inputFile);
        versionHeaderInputStream = new ByteArrayInputStream(versionHeader);
        bytesToSignInputStream = new SequenceInputStream(versionHeaderInputStream, fileInputStream);
        signature = _context.dsa().sign(bytesToSignInputStream, signingPrivateKey);
    } catch (IOException e) {
        if (_log.shouldLog(Log.ERROR))
            _log.error("Error signing", e);
        return null;
    } finally {
        if (bytesToSignInputStream != null)
            try {
                bytesToSignInputStream.close();
            } catch (IOException ioe) {
            }
        if (fileInputStream != null)
            try {
                fileInputStream.close();
            } catch (IOException ioe) {
            }
    }
    FileOutputStream fileOutputStream = null;
    try {
        fileOutputStream = new FileOutputStream(signedFile);
        fileOutputStream.write(signature.getData());
        fileOutputStream.write(versionHeader);
        fileInputStream = new FileInputStream(inputFile);
        DataHelper.copy(fileInputStream, fileOutputStream);
        fileOutputStream.close();
    } catch (IOException ioe) {
        if (_log.shouldLog(Log.WARN))
            _log.log(Log.WARN, "Error writing signed file " + signedFile, ioe);
        return null;
    } finally {
        if (fileInputStream != null)
            try {
                fileInputStream.close();
            } catch (IOException ioe) {
            }
        if (fileOutputStream != null)
            try {
                fileOutputStream.close();
            } catch (IOException ioe) {
            }
    }
    return signature;
}
Also used : SequenceInputStream(java.io.SequenceInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) Signature(net.i2p.data.Signature) FileOutputStream(java.io.FileOutputStream) SecureFileOutputStream(net.i2p.util.SecureFileOutputStream) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream)

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