Search in sources :

Example 1 with SimpleDataStructure

use of net.i2p.data.SimpleDataStructure 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 2 with SimpleDataStructure

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

Example 3 with SimpleDataStructure

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

the class SU3File method write.

/**
 *  One-pass wrap and sign the content.
 *  Writes to the file specified in the constructor.
 *  Throws on all errors.
 *
 *  @param content the input file, probably in zip format
 *  @param fileType 0-255, 0 for zip
 *  @param contentType 0-255
 *  @param version 1-255 bytes when converted to UTF-8
 *  @param signer ID of the public key, 1-255 bytes when converted to UTF-8
 */
public void write(File content, int fileType, int contentType, String version, String signer, PrivateKey privkey, SigType sigType) throws IOException {
    InputStream in = null;
    DigestOutputStream out = null;
    boolean ok = false;
    try {
        in = new BufferedInputStream(new FileInputStream(content));
        MessageDigest md = sigType.getDigestInstance();
        out = new DigestOutputStream(new BufferedOutputStream(new FileOutputStream(_file)), md);
        out.write(MAGIC_BYTES);
        out.write((byte) 0);
        out.write((byte) FILE_VERSION);
        DataHelper.writeLong(out, 2, sigType.getCode());
        DataHelper.writeLong(out, 2, sigType.getSigLen());
        out.write((byte) 0);
        byte[] verBytes = DataHelper.getUTF8(version);
        if (verBytes.length == 0 || verBytes.length > 255)
            throw new IllegalArgumentException("bad version length");
        int verLen = Math.max(verBytes.length, MIN_VERSION_BYTES);
        out.write((byte) verLen);
        out.write((byte) 0);
        byte[] signerBytes = DataHelper.getUTF8(signer);
        if (signerBytes.length == 0 || signerBytes.length > 255)
            throw new IllegalArgumentException("bad signer length");
        out.write((byte) signerBytes.length);
        long contentLength = content.length();
        if (contentLength <= 0)
            throw new IllegalArgumentException("No content");
        DataHelper.writeLong(out, 8, contentLength);
        out.write((byte) 0);
        if (fileType < 0 || fileType > 255)
            throw new IllegalArgumentException("bad content type");
        out.write((byte) fileType);
        out.write((byte) 0);
        if (contentType < 0 || contentType > 255)
            throw new IllegalArgumentException("bad content type");
        out.write((byte) contentType);
        out.write(new byte[12]);
        out.write(verBytes);
        if (verBytes.length < MIN_VERSION_BYTES)
            out.write(new byte[MIN_VERSION_BYTES - verBytes.length]);
        out.write(signerBytes);
        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();
            out.write(buf, 0, read);
            tot += read;
        }
        byte[] sha = md.digest();
        out.on(false);
        SimpleDataStructure hash = sigType.getHashInstance();
        hash.setData(sha);
        Signature signature = _context.dsa().sign(hash, privkey, sigType);
        if (signature == null)
            throw new IOException("sig fail");
        // System.out.println("hash\n" + HexDump.dump(sha));
        // System.out.println("sig\n" + HexDump.dump(signature.getData()));
        signature.writeBytes(out);
        ok = 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)
            try {
                out.close();
            } catch (IOException ioe) {
            }
        if (!ok)
            _file.delete();
    }
}
Also used : 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) DigestOutputStream(java.security.DigestOutputStream) SecureFileOutputStream(net.i2p.util.SecureFileOutputStream) FileOutputStream(java.io.FileOutputStream) Signature(net.i2p.data.Signature) EOFException(java.io.EOFException) MessageDigest(java.security.MessageDigest) BufferedOutputStream(java.io.BufferedOutputStream) SimpleDataStructure(net.i2p.data.SimpleDataStructure)

Example 4 with SimpleDataStructure

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

the class I2PClientImpl method createDestination.

/**
 * Create the destination with the given payload and write it out along with
 * the PrivateKey and SigningPrivateKey to the destKeyStream
 *
 * If cert is a KeyCertificate, the signing keypair will be of the specified type.
 * The KeyCertificate data must be .............................
 * The padding if any will be randomized. The extra key data if any will be set in the
 * key cert.
 *
 * Caller must close stream.
 *
 * @param destKeyStream location to write out the destination, PrivateKey, and SigningPrivateKey,
 *                      format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
 */
public Destination createDestination(OutputStream destKeyStream, Certificate cert) throws I2PException, IOException {
    Destination d = new Destination();
    Object[] keypair = KeyGenerator.getInstance().generatePKIKeypair();
    PublicKey publicKey = (PublicKey) keypair[0];
    PrivateKey privateKey = (PrivateKey) keypair[1];
    SimpleDataStructure[] signingKeys;
    if (cert.getCertificateType() == Certificate.CERTIFICATE_TYPE_KEY) {
        KeyCertificate kcert = cert.toKeyCertificate();
        SigType type = kcert.getSigType();
        try {
            signingKeys = KeyGenerator.getInstance().generateSigningKeys(type);
        } catch (GeneralSecurityException gse) {
            throw new I2PException("keygen fail", gse);
        }
    } else {
        signingKeys = KeyGenerator.getInstance().generateSigningKeys();
    }
    SigningPublicKey signingPubKey = (SigningPublicKey) signingKeys[0];
    SigningPrivateKey signingPrivKey = (SigningPrivateKey) signingKeys[1];
    d.setPublicKey(publicKey);
    d.setSigningPublicKey(signingPubKey);
    if (cert.getCertificateType() == Certificate.CERTIFICATE_TYPE_KEY) {
        // fix up key certificate or padding
        KeyCertificate kcert = cert.toKeyCertificate();
        SigType type = kcert.getSigType();
        int len = type.getPubkeyLen();
        if (len < 128) {
            byte[] pad = new byte[128 - len];
            RandomSource.getInstance().nextBytes(pad);
            d.setPadding(pad);
        } else if (len > 128) {
            System.arraycopy(signingPubKey.getData(), 128, kcert.getPayload(), KeyCertificate.HEADER_LENGTH, len - 128);
        }
    }
    d.setCertificate(cert);
    d.writeBytes(destKeyStream);
    privateKey.writeBytes(destKeyStream);
    signingPrivKey.writeBytes(destKeyStream);
    destKeyStream.flush();
    return d;
}
Also used : I2PException(net.i2p.I2PException) Destination(net.i2p.data.Destination) SigningPublicKey(net.i2p.data.SigningPublicKey) PrivateKey(net.i2p.data.PrivateKey) SigningPrivateKey(net.i2p.data.SigningPrivateKey) SigningPublicKey(net.i2p.data.SigningPublicKey) PublicKey(net.i2p.data.PublicKey) GeneralSecurityException(java.security.GeneralSecurityException) SigType(net.i2p.crypto.SigType) SigningPrivateKey(net.i2p.data.SigningPrivateKey) KeyCertificate(net.i2p.data.KeyCertificate) SimpleDataStructure(net.i2p.data.SimpleDataStructure)

Example 5 with SimpleDataStructure

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

the class KeyGenerator method generatePKIKeys.

/**
 *  Same as above but different return type
 *  @since 0.8.7
 */
public SimpleDataStructure[] generatePKIKeys() {
    BigInteger a = new NativeBigInteger(getElGamalExponentSize(), _context.random());
    BigInteger aalpha = CryptoConstants.elgg.modPow(a, CryptoConstants.elgp);
    SimpleDataStructure[] keys = new SimpleDataStructure[2];
    keys[0] = new PublicKey();
    keys[1] = new PrivateKey();
    try {
        keys[0].setData(SigUtil.rectify(aalpha, PublicKey.KEYSIZE_BYTES));
        keys[1].setData(SigUtil.rectify(a, PrivateKey.KEYSIZE_BYTES));
    } catch (InvalidKeyException ike) {
        throw new IllegalArgumentException(ike);
    }
    return keys;
}
Also used : NativeBigInteger(net.i2p.util.NativeBigInteger) PrivateKey(net.i2p.data.PrivateKey) ECPrivateKey(java.security.interfaces.ECPrivateKey) EdDSAPrivateKey(net.i2p.crypto.eddsa.EdDSAPrivateKey) RSAPrivateKey(java.security.interfaces.RSAPrivateKey) SigningPrivateKey(net.i2p.data.SigningPrivateKey) SigningPublicKey(net.i2p.data.SigningPublicKey) RSAPublicKey(java.security.interfaces.RSAPublicKey) EdDSAPublicKey(net.i2p.crypto.eddsa.EdDSAPublicKey) ECPublicKey(java.security.interfaces.ECPublicKey) PublicKey(net.i2p.data.PublicKey) BigInteger(java.math.BigInteger) NativeBigInteger(net.i2p.util.NativeBigInteger) InvalidKeyException(java.security.InvalidKeyException) SimpleDataStructure(net.i2p.data.SimpleDataStructure)

Aggregations

SimpleDataStructure (net.i2p.data.SimpleDataStructure)14 GeneralSecurityException (java.security.GeneralSecurityException)7 SigningPrivateKey (net.i2p.data.SigningPrivateKey)7 SigningPublicKey (net.i2p.data.SigningPublicKey)7 PrivateKey (net.i2p.data.PrivateKey)6 PublicKey (net.i2p.data.PublicKey)6 IOException (java.io.IOException)5 SigType (net.i2p.crypto.SigType)5 MessageDigest (java.security.MessageDigest)4 DataFormatException (net.i2p.data.DataFormatException)4 Signature (net.i2p.data.Signature)4 SecureFileOutputStream (net.i2p.util.SecureFileOutputStream)4 FileOutputStream (java.io.FileOutputStream)3 InputStream (java.io.InputStream)3 DigestInputStream (java.security.DigestInputStream)3 I2PException (net.i2p.I2PException)3 KeyCertificate (net.i2p.data.KeyCertificate)3 NativeBigInteger (net.i2p.util.NativeBigInteger)3 BufferedInputStream (java.io.BufferedInputStream)2 BufferedOutputStream (java.io.BufferedOutputStream)2