package peergos.shared.user.fs; import jsinterop.annotations.*; import peergos.shared.cbor.*; import peergos.shared.crypto.asymmetric.*; import peergos.shared.crypto.symmetric.SymmetricKey; import peergos.shared.util.*; import java.util.*; public class Location implements Cborable { public static final int MAP_KEY_LENGTH = 32; @JsProperty public final PublicSigningKey owner, writer; private final byte[] mapKey; public Location(PublicSigningKey owner, PublicSigningKey writer, byte[] mapKey) { if (mapKey.length != MAP_KEY_LENGTH) throw new IllegalArgumentException("map key length "+ mapKey.length +" is not "+ MAP_KEY_LENGTH); this.owner = owner; this.writer = writer; this.mapKey = mapKey; } public CborObject toCbor() { return new CborObject.CborList(Arrays.asList( owner.toCbor(), writer.toCbor(), new CborObject.CborByteArray(mapKey) )); } @JsMethod public byte[] encrypt(SymmetricKey key, byte[] nonce) { return key.encrypt(serialize(), nonce); } @JsMethod public byte[] getMapKey() { return Arrays.copyOf(mapKey, mapKey.length); } public String toString() { return new ByteArrayWrapper(mapKey).toString(); } public static Location fromByteArray(byte[] raw) { return fromCbor(CborObject.fromByteArray(raw)); } public static Location fromCbor(CborObject cbor) { if (! (cbor instanceof CborObject.CborList)) throw new IllegalStateException("Incorrect cbor for Location: " + cbor); List<CborObject> values = ((CborObject.CborList) cbor).value; return new Location(PublicSigningKey.fromCbor(values.get(0)), PublicSigningKey.fromCbor(values.get(1)), ((CborObject.CborByteArray) values.get(2)).value); } public static Location decrypt(SymmetricKey fromKey, byte[] nonce, byte[] location) { byte[] bytes = fromKey.decrypt(location, nonce); return Location.fromCbor(CborObject.fromByteArray(bytes)); } public Location withWriter(PublicSigningKey newWriter) { return new Location(owner, newWriter, mapKey); } public Location withMapKey(byte[] newMapKey) { return new Location(owner, writer, newMapKey); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Location location = (Location) o; if (owner != null ? !owner.equals(location.owner) : location.owner != null) return false; if (writer != null ? !writer.equals(location.writer) : location.writer != null) return false; return Arrays.equals(mapKey, location.mapKey); } @Override public int hashCode() { int result = owner != null ? owner.hashCode() : 0; result = 31 * result + (writer != null ? writer.hashCode() : 0); result = 31 * result + Arrays.hashCode(mapKey); return result; } }