diff --git a/apps/addressbook/java/src/net/i2p/router/naming/BlockfileNamingService.java b/apps/addressbook/java/src/net/i2p/router/naming/BlockfileNamingService.java index cf9f4c72c9fe62e1920c340120517aa8482f3e83..af8928e1f8b58c09b4b7256adf3bc16e25aa1ec9 100644 --- a/apps/addressbook/java/src/net/i2p/router/naming/BlockfileNamingService.java +++ b/apps/addressbook/java/src/net/i2p/router/naming/BlockfileNamingService.java @@ -2069,9 +2069,8 @@ public class BlockfileNamingService extends DummyNamingService { } if (baos.size() > 65535) throw new DataFormatException("Properties too big (65535 max): " + baos.size()); - byte propBytes[] = baos.toByteArray(); - DataHelper.writeLong(rawStream, 2, propBytes.length); - rawStream.write(propBytes); + DataHelper.writeLong(rawStream, 2, baos.size()); + baos.writeTo(rawStream); } else { DataHelper.writeLong(rawStream, 2, 0); } diff --git a/apps/streaming/java/src/net/i2p/client/streaming/impl/Packet.java b/apps/streaming/java/src/net/i2p/client/streaming/impl/Packet.java index eed07853d8368145847e0ea13a6eca95e0e90e58..42c0af698afb609516b693e21bc4b2d3849bfca0 100644 --- a/apps/streaming/java/src/net/i2p/client/streaming/impl/Packet.java +++ b/apps/streaming/java/src/net/i2p/client/streaming/impl/Packet.java @@ -1,7 +1,6 @@ package net.i2p.client.streaming.impl; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.Date; @@ -16,6 +15,7 @@ import net.i2p.data.DataHelper; import net.i2p.data.Destination; import net.i2p.data.Signature; import net.i2p.data.SigningPublicKey; +import net.i2p.util.ByteArrayStream; import net.i2p.util.Log; /** @@ -799,7 +799,7 @@ class Packet { l.warn("Offline signature expired " + toString()); return false; } - ByteArrayOutputStream baos = new ByteArrayOutputStream(6 + _transientSigningPublicKey.length()); + ByteArrayStream baos = new ByteArrayStream(6 + _transientSigningPublicKey.length()); try { DataHelper.writeLong(baos, 4, _transientExpires / 1000); DataHelper.writeLong(baos, 2, _transientSigningPublicKey.getType().getCode()); @@ -809,8 +809,7 @@ class Packet { } catch (DataFormatException dfe) { return false; } - byte[] data = baos.toByteArray(); - boolean ok = ctx.dsa().verifySignature(_offlineSignature, data, 0, data.length, spk); + boolean ok = baos.verifySignature(ctx, _offlineSignature, spk); if (!ok) { Log l = ctx.logManager().getLog(Packet.class); if (l.shouldLog(Log.WARN)) @@ -915,7 +914,7 @@ class Packet { else buf.append(" (no expiration)"); if (_transientSigningPublicKey != null) - buf.append(" TRANSKEY ").append(_transientSigningPublicKey.getType()); + buf.append(" TRANSKEY ").append(_transientSigningPublicKey.getType()).append(':').append(_transientSigningPublicKey.toBase64()); else buf.append(" (no key data)"); if (_offlineSignature != null) diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java index 735259554439bf67160c8c386557ea90ecc46ee0..1e628a44ddfa5fd2599421b9a1eaf910ffcc1fdf 100644 --- a/core/java/src/net/i2p/data/DataHelper.java +++ b/core/java/src/net/i2p/data/DataHelper.java @@ -46,6 +46,7 @@ import java.util.zip.CRC32; import java.util.zip.Deflater; import net.i2p.I2PAppContext; +import net.i2p.util.ByteArrayStream; import net.i2p.util.ByteCache; import net.i2p.util.FileUtil; import net.i2p.util.OrderedProperties; @@ -283,9 +284,8 @@ public class DataHelper { } if (baos.size() > 65535) throw new DataFormatException("Properties too big (65535 max): " + baos.size()); - byte propBytes[] = baos.toByteArray(); - writeLong(rawStream, 2, propBytes.length); - rawStream.write(propBytes); + writeLong(rawStream, 2, baos.size()); + baos.writeTo(rawStream); } else { writeLong(rawStream, 2, 0); } @@ -318,7 +318,7 @@ public class DataHelper { p = new OrderedProperties(); p.putAll(props); } - ByteArrayOutputStream baos = new ByteArrayOutputStream(p.size() * 64); + ByteArrayStream baos = new ByteArrayStream(p.size() * 64); for (Map.Entry<Object, Object> entry : p.entrySet()) { String key = (String) entry.getKey(); String val = (String) entry.getValue(); @@ -329,11 +329,10 @@ public class DataHelper { } if (baos.size() > 65535) throw new DataFormatException("Properties too big (65535 max): " + baos.size()); - byte propBytes[] = baos.toByteArray(); - toLong(target, offset, 2, propBytes.length); + toLong(target, offset, 2, baos.size()); offset += 2; - System.arraycopy(propBytes, 0, target, offset, propBytes.length); - offset += propBytes.length; + baos.copyTo(target, offset); + offset += baos.size(); return offset; } else { toLong(target, offset, 2, 0); diff --git a/core/java/src/net/i2p/data/LeaseSet2.java b/core/java/src/net/i2p/data/LeaseSet2.java index df523efad7aa9e846d3ffd25546fb5ddad6c281f..9888b30f6f43cfa49a02285c690bfdfd429517a5 100644 --- a/core/java/src/net/i2p/data/LeaseSet2.java +++ b/core/java/src/net/i2p/data/LeaseSet2.java @@ -299,9 +299,7 @@ public class LeaseSet2 extends LeaseSet { } catch (DataFormatException dfe) { return null; } - byte[] data = baos.toByteArray(); - I2PAppContext ctx = I2PAppContext.getGlobalContext(); - return ctx.dsa().sign(data, priv); + return baos.sign(priv); } public boolean verifyOfflineSignature() { @@ -324,8 +322,7 @@ public class LeaseSet2 extends LeaseSet { } catch (DataFormatException dfe) { return false; } - byte[] data = baos.toByteArray(); - return ctx.dsa().verifySignature(_offlineSignature, data, 0, data.length, getSigningPublicKey()); + return baos.verifySignature(ctx, _offlineSignature, getSigningPublicKey()); } /** @@ -613,9 +610,8 @@ public class LeaseSet2 extends LeaseSet { } catch (IOException ioe) { throw new DataFormatException("Signature failed", ioe); } - byte data[] = out.toByteArray(); // now sign with the key - _signature = DSAEngine.getInstance().sign(data, key); + _signature = out.sign(key); if (_signature == null) throw new DataFormatException("Signature failed with " + key.getType() + " key"); } @@ -659,8 +655,7 @@ public class LeaseSet2 extends LeaseSet { dfe.printStackTrace(); return false; } - byte data[] = out.toByteArray(); - return DSAEngine.getInstance().verifySignature(_signature, data, spk); + return out.verifySignature(_signature, spk); } @Override diff --git a/core/java/src/net/i2p/data/i2cp/SessionConfig.java b/core/java/src/net/i2p/data/i2cp/SessionConfig.java index a138e6aaaf8aa3652b2094b762e30aa1a545ec1c..75435be17ce74b737f0c574d97a1519ebb212ce9 100644 --- a/core/java/src/net/i2p/data/i2cp/SessionConfig.java +++ b/core/java/src/net/i2p/data/i2cp/SessionConfig.java @@ -289,9 +289,7 @@ public class SessionConfig extends DataStructureImpl { } catch (DataFormatException dfe) { return false; } - byte[] odata = baos.toByteArray(); - boolean ok = DSAEngine.getInstance().verifySignature(sig, odata, 0, odata.length, - _destination.getSigningPublicKey()); + boolean ok = baos.verifySignature(sig, _destination.getSigningPublicKey()); if (!ok) return false; } else { diff --git a/core/java/src/net/i2p/util/ByteArrayStream.java b/core/java/src/net/i2p/util/ByteArrayStream.java index 6fd3c1ffb0adc8114ebe31d36dbc740a99f6eead..c4de782713d2cb937fe792091cfa2e91cbf87d22 100644 --- a/core/java/src/net/i2p/util/ByteArrayStream.java +++ b/core/java/src/net/i2p/util/ByteArrayStream.java @@ -4,6 +4,12 @@ import java.io.ByteArrayOutputStream; import java.io.ByteArrayInputStream; import java.util.Arrays; +import net.i2p.I2PAppContext; +import net.i2p.crypto.DSAEngine; +import net.i2p.data.Signature; +import net.i2p.data.SigningPrivateKey; +import net.i2p.data.SigningPublicKey; + /** * OutputStream to InputStream adapter. * Zero-copy where possible. Unsynchronized. @@ -52,4 +58,41 @@ public class ByteArrayStream extends ByteArrayOutputStream { public ByteArrayInputStream asInputStream() { return new ByteArrayInputStream(buf, 0, count); } + + /** + * Copy all data to the target + */ + public void copyTo(byte[] target, int offset) { + System.arraycopy(buf, 0, target, offset, count); + } + + /** + * Verify the written data + */ + public boolean verifySignature(Signature signature, SigningPublicKey verifyingKey) { + return DSAEngine.getInstance().verifySignature(signature, buf, 0, count, verifyingKey); + } + + /** + * Verify the written data + */ + public boolean verifySignature(I2PAppContext ctx, Signature signature, SigningPublicKey verifyingKey) { + return ctx.dsa().verifySignature(signature, buf, 0, count, verifyingKey); + } + + /** + * Sign the written data + * @return null on error + */ + public Signature sign(SigningPrivateKey signingKey) { + return DSAEngine.getInstance().sign(buf, 0, count, signingKey); + } + + /** + * Sign the written data + * @return null on error + */ + public Signature sign(I2PAppContext ctx, SigningPrivateKey signingKey) { + return ctx.dsa().sign(buf, 0, count, signingKey); + } }