Session(NodeInfo remoteNodeInfo) { this.remoteNodeInfo = remoteNodeInfo; localNonce = Do.randomBytes(64); state = new AtomicInteger(STATE_HANDSHAKE); handshakeStep = new AtomicInteger(HANDSHAKE_STEP_INIT); handshakeExpiresAt = Instant.now().minusMillis(HANDSHAKE_TIMEOUT_MILLIS); }
Binder connect() { if (serverNonce == null) serverNonce = Do.randomBytes(48); return Binder.fromKeysValues( "server_nonce", serverNonce, "session_id", ""+sessionId ); }
/** * Create random new hashId. Mainly for testing purposes. To create random bytes, use {@link Do#randomBytes(int)} * instead. * * @return instance with random digest */ public static HashId createRandom() { return HashId.withDigest(Do.randomBytes(64)); }
/** * Create a random (e.g. every call a different) sequence of bytes that identidy this key. There can almost infinite * number if anonynous ids for e key (more than 1.0E77), so it is really anonymous way to identify some key. The * anonymousId for public and private keys are the same. * <p> * Anonymous ID size is 64 bytes: first are 32 random bytes, last are HMAC(key, sha256) of these random bytes. * <p> * The most important thing about anonymous ids is that every time this call generates new id for the same key, * providing anonymous but exact identification of a key. * <p> * To check that the key matches some anonymousId, use {@link #matchAnonymousId(byte[])}. * <p> * Therefore, the private key fingerprint is its public key fingerprint. The public key fingerprint is calculated * using some hash over it's parameters, see {@link PublicKey#fingerprint()} * * @return */ public byte[] createAnonymousId() { byte[] rvector = Do.randomBytes(32); HMAC hmac = new HMAC(fingerprint()); hmac.update(rvector); byte[] result = new byte[64]; System.arraycopy(rvector, 0, result, 0, 32); System.arraycopy(hmac.digest(), 0, result, 32, 32); return result; }
/** * We have received {@link PacketTypes#HELLO} packet. Should create localNonce and send it in reply. * @param packet received {@link Packet} */ private void onReceiveHello(Packet packet) throws EncryptionError { report(logLabel, ()->"received hello from " + packet.senderNodeId, VerboseLevel.BASE); NodeInfo nodeInfo = netConfig.getInfo(packet.senderNodeId); if (nodeInfo != null) { SessionReader sessionReader = getOrCreateSessionReaderCandidate(packet.senderNodeId); if (sessionReader != null) { sessionReader.protectFromDuples(packet.packetId, ()->{ if (sessionReader.nextLocalNonceGenerationTime.isBefore(Instant.now())) { sessionReader.localNonce = Do.randomBytes(64); sessionReader.nextLocalNonceGenerationTime = Instant.now().plusMillis(HANDSHAKE_TIMEOUT_MILLIS); } sessionReader.handshake_keyReqPart1 = null; sessionReader.handshake_keyReqPart2 = null; sendWelcome(sessionReader); }); } } else { throw new EncryptionError(Errors.BAD_VALUE + ": block got from unknown node " + packet.senderNodeId); } }
f1.createNewFile(); f2.createNewFile(); Files.write(f1.toPath(), Do.randomBytes(32)); Files.write(f2.toPath(), Do.randomBytes(1024));
session.localNonce = Do.randomBytes(64); List data = Arrays.asList(session.localNonce, session.remoteNonce); byte[] packed = Boss.pack(data);
/** * Each adapter will try to send blocks until have got special {@link Packet} with type {@link PacketTypes#ACK}, * that means receiver have got block. So when we got block, but something went wrong - call this method. Note that * for success blocks needs to call {@link UDPAdapter#sendAck(SessionReader, Integer)} * @param nodeNumber node id in which sending is * @param packetId is id of block we have got. */ private void sendNack(Integer nodeNumber, Integer packetId) { try { NodeInfo destination = netConfig.getInfo(nodeNumber); if (destination != null) { report(logLabel, ()->"send nack to "+nodeNumber, VerboseLevel.DETAILED); byte[] randomSeed = Do.randomBytes(64); byte[] data = Boss.dumpToArray(Arrays.asList(packetId, randomSeed)); byte[] sign = new PrivateKey(ownPrivateKey.pack()).sign(data, HashType.SHA512); byte[] payload = Boss.dumpToArray(Arrays.asList(data, sign)); Packet packet = new Packet(0, myNodeInfo.getNumber(), nodeNumber, PacketTypes.NACK, payload); sendPacket(destination, packet); } } catch (EncryptionError e) { callErrorCallbacks("(sendNack) can't send NACK, EncryptionError: " + e); } }
@Ignore @Test public void testHashId() throws Exception { testSomeWork(() -> { byte[] randBytes = Do.randomBytes(1*1024*1024); for (int i = 0; i < 100; ++i) HashId.of(randBytes); }); }
protected void sendWelcome(NodeInfo myNodeInfo, NodeInfo destination, UDPAdapter udpAdapter, DatagramSocket socket) throws Exception { byte[] payload = new PublicKey(destination.getPublicKey().pack()).encrypt(Do.randomBytes(64)); UDPAdapter.Packet packet = udpAdapter.createTestPacket( new Random().nextInt(Integer.MAX_VALUE), myNodeInfo.getNumber(), destination.getNumber(), UDPAdapter.PacketTypes.WELCOME, payload); sendBlock(packet, socket, destination); }
protected void sendDataGarbage(NodeInfo myNodeInfo, NodeInfo destination, UDPAdapter udpAdapter, DatagramSocket socket) throws Exception { byte[] data = new PublicKey(destination.getPublicKey().pack()).encrypt(Do.randomBytes(64)); byte[] crc32 = new Crc32().digest(data); byte[] payload = new byte[data.length + crc32.length]; System.arraycopy(data, 0, payload, 0, data.length); System.arraycopy(crc32, 0, payload, data.length, crc32.length); UDPAdapter.Packet packet = udpAdapter.createTestPacket( new Random().nextInt(Integer.MAX_VALUE), myNodeInfo.getNumber(), destination.getNumber(), UDPAdapter.PacketTypes.DATA, payload); sendBlock(packet, socket, destination); }
/** * ACK packets are used only for respond to DATA packets. Retransmission of handshake's packet types stops on each * next handshake step. But last step need to be ACK-ed. For this used {@link PacketTypes#SESSION_ACK} packet. * @param session is {@link Session} in which sending is. * @throws EncryptionError */ private void sendSessionAck(Session session) throws EncryptionError { report(logLabel, ()->"send session_ack to "+session.remoteNodeInfo.getNumber(), VerboseLevel.BASE); Packet packet = new Packet(0, myNodeInfo.getNumber(), session.remoteNodeInfo.getNumber(), PacketTypes.SESSION_ACK, new SymmetricKey(session.sessionKey.getKey()).etaEncrypt(Do.randomBytes(32))); sendPacket(session.remoteNodeInfo, packet); }
@Test public void processBytes() throws Exception { byte x[] = Do.randomBytes(10); Binder s = DefaultBiMapper.serialize(x); byte[] result = ((Bytes)DefaultBiMapper.deserialize(s)).getData(); assertArrayEquals(x, result); } }
@Test public void encode() { for(int i=0; i<100;i++) { byte [] src = Do.randomBytes(256+Do.randomInt(1024)); assertArrayEquals(src, Safe58.decode(Safe58.encode(src))); } }
@Test public void v3Hash() throws Exception { byte[] src = Do.randomBytes(107); byte[] hid = HashId.of(src).getDigest(); assertArrayEquals(new Sha512_256().digest(src), Arrays.copyOfRange(hid, 0, 32)); assertArrayEquals(new Sha3_256().digest(src), Arrays.copyOfRange(hid, 32, 64)); assertArrayEquals(new Gost3411_2012_256().digest(src), Arrays.copyOfRange(hid, 64, 96)); // System.out.println("src: "+ Base64.encodeString(src)); // System.out.println("hid: "+ Base64.encodeString(hid)); } }
params.put("param2", 42l); Map<String, byte[]> files = new HashMap<>(); byte[] fileData = Do.randomBytes(3200); files.put("filename", fileData); List httpRes = httpClient.sendPostRequestMultipart("http://localhost:8880/test", JSApiHttpClient.RESPTYPE_JSON, params, files);
byte[] payload1 = Do.randomBytes(1024 * 10);
/** * This is first step of creation and installation of the session. * @param session is {@link Session} in which sending is. */ private void sendHello(Session session) { try { report(logLabel, () -> "send hello to " + session.remoteNodeInfo.getNumber(), VerboseLevel.BASE); byte[] helloNonce = Do.randomBytes(64); Packet packet = new Packet(getNextPacketId(), myNodeInfo.getNumber(), session.remoteNodeInfo.getNumber(), PacketTypes.HELLO, new PublicKey(session.remoteNodeInfo.getPublicKey().pack()).encrypt(helloNonce)); sendPacket(session.remoteNodeInfo, packet); session.addPacketToRetransmitMap(packet.packetId, packet, helloNonce); } catch (EncryptionError e) { callErrorCallbacks("(sendHello) EncryptionError: " + e); } }
@Test public void compactString() throws Exception { byte[] data = new byte[]{-2, 2, 3, 4}; assertEquals("/gIDBA==", Base64.encodeString(data)); assertEquals("/gIDBA", Base64.encodeCompactString(data)); assertArrayEquals(data, Base64u.decodeCompactString(Base64u.encodeCompactString(data))); for (int i = 1; i < 70; i++) { byte[] l = Do.randomBytes(i); assertArrayEquals(l, Base64u.decodeCompactString(Base64u.encodeCompactString(l))); } } }
byte[] client_nonce = Do.randomBytes(47); byte[] data = Boss.pack(Binder.fromKeysValues( "client_nonce", client_nonce,