Added comments and a few more object types

This commit is contained in:
Christian Basler 2015-04-08 20:54:00 +02:00
parent 35088ca033
commit 9b383e3bcd
12 changed files with 299 additions and 53 deletions

View File

@ -16,30 +16,10 @@
package ch.dissem.bitmessage.entity.payload; package ch.dissem.bitmessage.entity.payload;
import java.io.IOException;
import java.io.OutputStream;
/** /**
* Created by chris on 07.04.15. * Users who are subscribed to the sending address will see the message appear in their inbox.
* Broadcasts are version 4 or 5.
*/ */
public class Broadcast implements ObjectPayload { public interface Broadcast extends ObjectPayload {
private long stream; byte[] getEncrypted();
private byte[] tag;
private byte[] encrypted;
public Broadcast(long stream, byte[] tag, byte[] encrypted) {
this.stream = stream;
this.tag = tag;
this.encrypted = encrypted;
}
@Override
public long getStream() {
return stream;
}
@Override
public void write(OutputStream stream) throws IOException {
}
} }

View File

@ -20,7 +20,8 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
/** /**
* Created by chris on 24.03.15. * In cases we don't know what to do with an object, we just store its bytes and send it again - we don't really
* have to know what it is.
*/ */
public class GenericPayload implements ObjectPayload { public class GenericPayload implements ObjectPayload {
private long stream; private long stream;

View File

@ -20,7 +20,7 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
/** /**
* Created by chris on 24.03.15. * Request for a public key.
*/ */
public class GetPubkey implements ObjectPayload { public class GetPubkey implements ObjectPayload {
private long stream; private long stream;
@ -28,7 +28,7 @@ public class GetPubkey implements ObjectPayload {
private byte[] tag; private byte[] tag;
public GetPubkey(long stream, byte[] ripeOrTag) { public GetPubkey(long stream, byte[] ripeOrTag) {
this.stream=stream; this.stream = stream;
switch (ripeOrTag.length) { switch (ripeOrTag.length) {
case 20: case 20:
ripe = ripeOrTag; ripe = ripeOrTag;
@ -37,7 +37,7 @@ public class GetPubkey implements ObjectPayload {
tag = ripeOrTag; tag = ripeOrTag;
break; break;
default: default:
throw new RuntimeException("ripe (20 bytes) or tag (32 bytes) expected, but pubkey was " + ripeOrTag.length + " bytes."); throw new RuntimeException("ripe (20 bytes) or tag (32 bytes) expected, but pubkey was " + ripeOrTag.length + " bytes long.");
} }
} }

View File

@ -20,24 +20,37 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
/** /**
* Created by chris on 07.04.15. * Used for person-to-person messages.
*/ */
public class Msg implements ObjectPayload { public class Msg implements ObjectPayload {
private long stream; private long stream;
private byte[] encrypted; private byte[] encrypted;
private UnencryptedMessage unencrypted;
public Msg(long stream, byte[] encrypted) { public Msg(long stream, byte[] encrypted) {
this.stream = stream; this.stream = stream;
this.encrypted = encrypted; this.encrypted = encrypted;
} }
public Msg(UnencryptedMessage unencrypted) {
this.stream = unencrypted.getStream();
this.unencrypted = unencrypted;
}
@Override @Override
public long getStream() { public long getStream() {
return stream; return stream;
} }
public byte[] getEncrypted() {
if (encrypted == null) {
// TODO
}
return encrypted;
}
@Override @Override
public void write(OutputStream stream) throws IOException { public void write(OutputStream stream) throws IOException {
stream.write(encrypted); stream.write(getEncrypted());
} }
} }

View File

@ -17,7 +17,7 @@
package ch.dissem.bitmessage.entity.payload; package ch.dissem.bitmessage.entity.payload;
/** /**
* Created by chris on 24.03.15. * Public keys for signing and encryption, the answer to a 'getpubkey' request.
*/ */
public interface Pubkey extends ObjectPayload { public interface Pubkey extends ObjectPayload {
long getVersion(); long getVersion();

View File

@ -0,0 +1,142 @@
/*
* Copyright 2015 Christian Basler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.dissem.bitmessage.entity.payload;
import ch.dissem.bitmessage.entity.Streamable;
import ch.dissem.bitmessage.utils.Encode;
import java.io.IOException;
import java.io.OutputStream;
/**
* The unencrypted message to be sent by 'msg' or 'broadcast'.
*/
public class UnencryptedMessage implements Streamable {
private final long addressVersion;
private final long stream;
private final int behaviorBitfield;
private final byte[] publicSigningKey;
private final byte[] publicEncryptionKey;
private final long nonceTrialsPerByte;
private final long extraBytes;
private final long encoding;
private final byte[] message;
private final byte[] signature;
public long getStream() {
return stream;
}
private UnencryptedMessage(Builder builder) {
addressVersion = builder.addressVersion;
stream = builder.stream;
behaviorBitfield = builder.behaviorBitfield;
publicSigningKey = builder.publicSigningKey;
publicEncryptionKey = builder.publicEncryptionKey;
nonceTrialsPerByte = builder.nonceTrialsPerByte;
extraBytes = builder.extraBytes;
encoding = builder.encoding;
message = builder.message;
signature = builder.signature;
}
@Override
public void write(OutputStream os) throws IOException {
Encode.varInt(addressVersion, os);
Encode.varInt(stream, os);
Encode.int32(behaviorBitfield, os);
os.write(publicSigningKey);
os.write(publicEncryptionKey);
Encode.varInt(nonceTrialsPerByte, os);
Encode.varInt(extraBytes, os);
Encode.varInt(encoding, os);
Encode.varInt(message.length, os);
os.write(message);
Encode.varInt(signature.length, os);
os.write(signature);
}
public static final class Builder {
private long addressVersion;
private long stream;
private int behaviorBitfield;
private byte[] publicSigningKey;
private byte[] publicEncryptionKey;
private long nonceTrialsPerByte;
private long extraBytes;
private long encoding;
private byte[] message;
private byte[] signature;
public Builder() {
}
public Builder addressVersion(long addressVersion) {
this.addressVersion = addressVersion;
return this;
}
public Builder stream(long stream) {
this.stream = stream;
return this;
}
public Builder behaviorBitfield(int behaviorBitfield) {
this.behaviorBitfield = behaviorBitfield;
return this;
}
public Builder publicSigningKey(byte[] publicSigningKey) {
this.publicSigningKey = publicSigningKey;
return this;
}
public Builder publicEncryptionKey(byte[] publicEncryptionKey) {
this.publicEncryptionKey = publicEncryptionKey;
return this;
}
public Builder nonceTrialsPerByte(long nonceTrialsPerByte) {
this.nonceTrialsPerByte = nonceTrialsPerByte;
return this;
}
public Builder extraBytes(long extraBytes) {
this.extraBytes = extraBytes;
return this;
}
public Builder encoding(long encoding) {
this.encoding = encoding;
return this;
}
public Builder message(byte[] message) {
this.message = message;
return this;
}
public Builder signature(byte[] signature) {
this.signature = signature;
return this;
}
public UnencryptedMessage build() {
return new UnencryptedMessage(this);
}
}
}

View File

@ -22,11 +22,11 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
/** /**
* Created by chris on 24.03.15. * A version 2 public key.
*/ */
public class V2Pubkey implements Pubkey { public class V2Pubkey implements Pubkey {
protected long stream; protected long stream;
protected long behaviorBitfield; protected int behaviorBitfield;
protected byte[] publicSigningKey; protected byte[] publicSigningKey;
protected byte[] publicEncryptionKey; protected byte[] publicEncryptionKey;
@ -61,15 +61,15 @@ public class V2Pubkey implements Pubkey {
} }
@Override @Override
public void write(OutputStream stream) throws IOException { public void write(OutputStream os) throws IOException {
Encode.int32(behaviorBitfield, stream); Encode.int32(behaviorBitfield, os);
stream.write(publicSigningKey); os.write(publicSigningKey);
stream.write(publicEncryptionKey); os.write(publicEncryptionKey);
} }
public static class Builder { public static class Builder {
private long streamNumber; private long streamNumber;
private long behaviorBitfield; private int behaviorBitfield;
private byte[] publicSigningKey; private byte[] publicSigningKey;
private byte[] publicEncryptionKey; private byte[] publicEncryptionKey;
@ -81,7 +81,7 @@ public class V2Pubkey implements Pubkey {
return this; return this;
} }
public Builder behaviorBitfield(long behaviorBitfield) { public Builder behaviorBitfield(int behaviorBitfield) {
this.behaviorBitfield = behaviorBitfield; this.behaviorBitfield = behaviorBitfield;
return this; return this;
} }

View File

@ -22,7 +22,7 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
/** /**
* Created by chris on 27.03.15. * A version 3 public key.
*/ */
public class V3Pubkey extends V2Pubkey { public class V3Pubkey extends V2Pubkey {
long nonceTrialsPerByte; long nonceTrialsPerByte;
@ -41,12 +41,12 @@ public class V3Pubkey extends V2Pubkey {
} }
@Override @Override
public void write(OutputStream stream) throws IOException { public void write(OutputStream os) throws IOException {
super.write(stream); super.write(os);
Encode.varInt(nonceTrialsPerByte, stream); Encode.varInt(nonceTrialsPerByte, os);
Encode.varInt(extraBytes, stream); Encode.varInt(extraBytes, os);
Encode.varInt(signature.length, stream); Encode.varInt(signature.length, os);
stream.write(signature); os.write(signature);
} }
@Override @Override
@ -56,7 +56,7 @@ public class V3Pubkey extends V2Pubkey {
public static class Builder extends V2Pubkey.Builder { public static class Builder extends V2Pubkey.Builder {
private long streamNumber; private long streamNumber;
private long behaviorBitfield; private int behaviorBitfield;
private byte[] publicSigningKey; private byte[] publicSigningKey;
private byte[] publicEncryptionKey; private byte[] publicEncryptionKey;
@ -72,7 +72,7 @@ public class V3Pubkey extends V2Pubkey {
return this; return this;
} }
public Builder behaviorBitfield(long behaviorBitfield) { public Builder behaviorBitfield(int behaviorBitfield) {
this.behaviorBitfield = behaviorBitfield; this.behaviorBitfield = behaviorBitfield;
return this; return this;
} }

View File

@ -0,0 +1,49 @@
/*
* Copyright 2015 Christian Basler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.dissem.bitmessage.entity.payload;
import java.io.IOException;
import java.io.OutputStream;
/**
* Users who are subscribed to the sending address will see the message appear in their inbox.
* Broadcasts are version 4 or 5.
*/
public class V4Broadcast implements Broadcast {
private long stream;
private byte[] encrypted;
private UnencryptedMessage unencrypted;
public V4Broadcast(long stream, byte[] encrypted) {
this.stream = stream;
this.encrypted = encrypted;
}
@Override
public long getStream() {
return stream;
}
public byte[] getEncrypted() {
return encrypted;
}
@Override
public void write(OutputStream stream) throws IOException {
stream.write(getEncrypted());
}
}

View File

@ -20,7 +20,10 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
/** /**
* Created by chris on 27.03.15. * A version 4 public key. When version 4 pubkeys are created, most of the data in the pubkey is encrypted. This is
* done in such a way that only someone who has the Bitmessage address which corresponds to a pubkey can decrypt and
* use that pubkey. This prevents people from gathering pubkeys sent around the network and using the data from them
* to create messages to be used in spam or in flooding attacks.
*/ */
public class V4Pubkey implements Pubkey { public class V4Pubkey implements Pubkey {
private long stream; private long stream;
@ -38,7 +41,7 @@ public class V4Pubkey implements Pubkey {
this.stream = decrypted.stream; this.stream = decrypted.stream;
// TODO: this.tag = new BitmessageAddress(this).doubleHash // TODO: this.tag = new BitmessageAddress(this).doubleHash
this.decrypted = decrypted; this.decrypted = decrypted;
// TODO: this.encrypted
} }
@Override @Override
@ -57,6 +60,10 @@ public class V4Pubkey implements Pubkey {
return stream; return stream;
} }
public byte[] getTag() {
return tag;
}
@Override @Override
public byte[] getSigningKey() { public byte[] getSigningKey() {
return decrypted.getSigningKey(); return decrypted.getSigningKey();

View File

@ -0,0 +1,42 @@
/*
* Copyright 2015 Christian Basler
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.dissem.bitmessage.entity.payload;
import java.io.IOException;
import java.io.OutputStream;
/**
* Users who are subscribed to the sending address will see the message appear in their inbox.
*/
public class V5Broadcast extends V4Broadcast {
private byte[] tag;
public V5Broadcast(long stream, byte[] tag, byte[] encrypted) {
super(stream, encrypted);
this.tag = tag;
}
public byte[] getTag() {
return tag;
}
@Override
public void write(OutputStream stream) throws IOException {
stream.write(tag);
super.write(stream);
}
}

View File

@ -39,7 +39,7 @@ public class Factory {
if (objectType < 4) { if (objectType < 4) {
switch ((int) objectType) { switch ((int) objectType) {
case 0: // getpubkey case 0: // getpubkey
return new GetPubkey(streamNumber, Decode.bytes(stream, length)); return parseGetPubkey((int) version, streamNumber, stream, length);
case 1: // pubkey case 1: // pubkey
return parsePubkey((int) version, streamNumber, stream, length); return parsePubkey((int) version, streamNumber, stream, length);
case 2: // msg case 2: // msg
@ -54,6 +54,10 @@ public class Factory {
return new GenericPayload(streamNumber, Decode.bytes(stream, length)); return new GenericPayload(streamNumber, Decode.bytes(stream, length));
} }
private static ObjectPayload parseGetPubkey(int version, long streamNumber, InputStream stream, int length) throws IOException {
return new GetPubkey(streamNumber, Decode.bytes(stream, length));
}
private static ObjectPayload parsePubkey(int version, long streamNumber, InputStream stream, int length) throws IOException { private static ObjectPayload parsePubkey(int version, long streamNumber, InputStream stream, int length) throws IOException {
switch (version) { switch (version) {
case 2: case 2:
@ -75,7 +79,7 @@ public class Factory {
v3.signature(Decode.bytes(stream, sigLength)); v3.signature(Decode.bytes(stream, sigLength));
return v3.build(); return v3.build();
case 4: case 4:
// TODO return new V4Pubkey(streamNumber, Decode.bytes(stream, 32), Decode.bytes(stream, length - 32));
} }
LOG.debug("Unexpected pubkey version " + version + ", handling as generic payload object"); LOG.debug("Unexpected pubkey version " + version + ", handling as generic payload object");
return new GenericPayload(streamNumber, Decode.bytes(stream, length)); return new GenericPayload(streamNumber, Decode.bytes(stream, length));
@ -86,6 +90,14 @@ public class Factory {
} }
private static ObjectPayload parseBroadcast(int version, long streamNumber, InputStream stream, int length) throws IOException { private static ObjectPayload parseBroadcast(int version, long streamNumber, InputStream stream, int length) throws IOException {
return new Broadcast(streamNumber, Decode.bytes(stream, 32), Decode.bytes(stream, length - 32)); switch (version) {
case 4:
return new V4Broadcast(streamNumber, Decode.bytes(stream, length));
case 5:
return new V5Broadcast(streamNumber, Decode.bytes(stream, 32), Decode.bytes(stream, length - 32));
default:
LOG.debug("Encountered unknown broadcast version " + version);
return new GenericPayload(streamNumber, Decode.bytes(stream, length));
}
} }
} }