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;
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 {
private long stream;
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 {
}
public interface Broadcast extends ObjectPayload {
byte[] getEncrypted();
}

View File

@ -20,7 +20,8 @@ import java.io.IOException;
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 {
private long stream;

View File

@ -20,7 +20,7 @@ import java.io.IOException;
import java.io.OutputStream;
/**
* Created by chris on 24.03.15.
* Request for a public key.
*/
public class GetPubkey implements ObjectPayload {
private long stream;
@ -28,7 +28,7 @@ public class GetPubkey implements ObjectPayload {
private byte[] tag;
public GetPubkey(long stream, byte[] ripeOrTag) {
this.stream=stream;
this.stream = stream;
switch (ripeOrTag.length) {
case 20:
ripe = ripeOrTag;
@ -37,7 +37,7 @@ public class GetPubkey implements ObjectPayload {
tag = ripeOrTag;
break;
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;
/**
* Created by chris on 07.04.15.
* Used for person-to-person messages.
*/
public class Msg implements ObjectPayload {
private long stream;
private byte[] encrypted;
private UnencryptedMessage unencrypted;
public Msg(long stream, byte[] encrypted) {
this.stream = stream;
this.encrypted = encrypted;
}
public Msg(UnencryptedMessage unencrypted) {
this.stream = unencrypted.getStream();
this.unencrypted = unencrypted;
}
@Override
public long getStream() {
return stream;
}
public byte[] getEncrypted() {
if (encrypted == null) {
// TODO
}
return encrypted;
}
@Override
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;
/**
* Created by chris on 24.03.15.
* Public keys for signing and encryption, the answer to a 'getpubkey' request.
*/
public interface Pubkey extends ObjectPayload {
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;
/**
* Created by chris on 24.03.15.
* A version 2 public key.
*/
public class V2Pubkey implements Pubkey {
protected long stream;
protected long behaviorBitfield;
protected int behaviorBitfield;
protected byte[] publicSigningKey;
protected byte[] publicEncryptionKey;
@ -61,15 +61,15 @@ public class V2Pubkey implements Pubkey {
}
@Override
public void write(OutputStream stream) throws IOException {
Encode.int32(behaviorBitfield, stream);
stream.write(publicSigningKey);
stream.write(publicEncryptionKey);
public void write(OutputStream os) throws IOException {
Encode.int32(behaviorBitfield, os);
os.write(publicSigningKey);
os.write(publicEncryptionKey);
}
public static class Builder {
private long streamNumber;
private long behaviorBitfield;
private int behaviorBitfield;
private byte[] publicSigningKey;
private byte[] publicEncryptionKey;
@ -81,7 +81,7 @@ public class V2Pubkey implements Pubkey {
return this;
}
public Builder behaviorBitfield(long behaviorBitfield) {
public Builder behaviorBitfield(int behaviorBitfield) {
this.behaviorBitfield = behaviorBitfield;
return this;
}

View File

@ -22,7 +22,7 @@ import java.io.IOException;
import java.io.OutputStream;
/**
* Created by chris on 27.03.15.
* A version 3 public key.
*/
public class V3Pubkey extends V2Pubkey {
long nonceTrialsPerByte;
@ -41,12 +41,12 @@ public class V3Pubkey extends V2Pubkey {
}
@Override
public void write(OutputStream stream) throws IOException {
super.write(stream);
Encode.varInt(nonceTrialsPerByte, stream);
Encode.varInt(extraBytes, stream);
Encode.varInt(signature.length, stream);
stream.write(signature);
public void write(OutputStream os) throws IOException {
super.write(os);
Encode.varInt(nonceTrialsPerByte, os);
Encode.varInt(extraBytes, os);
Encode.varInt(signature.length, os);
os.write(signature);
}
@Override
@ -56,7 +56,7 @@ public class V3Pubkey extends V2Pubkey {
public static class Builder extends V2Pubkey.Builder {
private long streamNumber;
private long behaviorBitfield;
private int behaviorBitfield;
private byte[] publicSigningKey;
private byte[] publicEncryptionKey;
@ -72,7 +72,7 @@ public class V3Pubkey extends V2Pubkey {
return this;
}
public Builder behaviorBitfield(long behaviorBitfield) {
public Builder behaviorBitfield(int behaviorBitfield) {
this.behaviorBitfield = behaviorBitfield;
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;
/**
* 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 {
private long stream;
@ -38,7 +41,7 @@ public class V4Pubkey implements Pubkey {
this.stream = decrypted.stream;
// TODO: this.tag = new BitmessageAddress(this).doubleHash
this.decrypted = decrypted;
// TODO: this.encrypted
}
@Override
@ -57,6 +60,10 @@ public class V4Pubkey implements Pubkey {
return stream;
}
public byte[] getTag() {
return tag;
}
@Override
public byte[] 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) {
switch ((int) objectType) {
case 0: // getpubkey
return new GetPubkey(streamNumber, Decode.bytes(stream, length));
return parseGetPubkey((int) version, streamNumber, stream, length);
case 1: // pubkey
return parsePubkey((int) version, streamNumber, stream, length);
case 2: // msg
@ -54,6 +54,10 @@ public class Factory {
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 {
switch (version) {
case 2:
@ -75,7 +79,7 @@ public class Factory {
v3.signature(Decode.bytes(stream, sigLength));
return v3.build();
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");
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 {
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));
}
}
}