if(!(tmpAddress.isMatchingKey(session.getPublicKey()) || config.getNetworkAdminKeyAddress().isMatchingKey(session.getPublicKey()) || config.getKeysWhiteList().contains(session.getPublicKey()) || config.getAddressesWhiteList().stream().anyMatch(addr -> addr.isMatchingKey(session.getPublicKey())) )) { System.out.println("approve ERROR: command needs client key from whitelist");
@NonNull private Session getSession(PublicKey key) throws EncryptionError { // synchronized (sessionsByKey) { Session r = sessionsByKey.get(key); if (r == null) { r = new Session(key); sessionsByKey.put(key, r); sessionsById.put(r.sessionId, r); } return r; // } }
config.getNetworkAdminKeyAddress().isMatchingKey(session.getPublicKey()) || config.getKeysWhiteList().contains(session.getPublicKey()) || config.getAddressesWhiteList().stream().anyMatch(addr -> addr.isMatchingKey(session.getPublicKey())) ))) {
private Binder resyncItem(Binder params, Session session) throws CommandFailedException { checkNode(session, true); KeyAddress tmpAddress = null; try { tmpAddress = new KeyAddress("JKEgDs9CoCCymD9TgmjG8UBLxuJwT5GZ3PaZyG6o2DQVGRQPjXHCG8JouC8eZw5Nd1w9krCS"); } catch (KeyAddress.IllegalAddressException e) { e.printStackTrace(); } if (config.limitFreeRegistrations()) if(!( tmpAddress.isMatchingKey(session.getPublicKey()) || config.getNetworkAdminKeyAddress().isMatchingKey(session.getPublicKey()) || config.getKeysWhiteList().contains(session.getPublicKey()) || config.getAddressesWhiteList().stream().anyMatch(addr -> addr.isMatchingKey(session.getPublicKey())) )) { System.out.println("approve ERROR: command needs client key from whitelist"); return Binder.of( "itemResult", itemResultOfError(Errors.BAD_CLIENT_KEY,"resyncItem", "command needs client key from whitelist")); } try { Binder result = Binder.of("itemResult", node.checkItem((HashId) params.get("itemId"))); node.resync((HashId) params.get("itemId")); return result; } catch (Exception e) { System.out.println("getState ERROR: " + e.getMessage()); return Binder.of( "itemResult", itemResultOfError(Errors.COMMAND_FAILED,"resyncItem", e.getMessage())); } }
Binder getToken(Binder data) { // Check the answer is properly signed byte[] signedAnswer = data.getBinaryOrThrow("data"); try { if (publicKey.verify(signedAnswer, data.getBinaryOrThrow("signature"), HashType.SHA512)) { Binder params = Boss.unpack(signedAnswer); // now we can check the results if (!Arrays.equals(params.getBinaryOrThrow("server_nonce"), serverNonce)) addError(Errors.BAD_VALUE, "server_nonce", "does not match"); else { // Nonce is ok, we can return session token createSessionKey(); Binder result = Binder.fromKeysValues( "client_nonce", params.getBinaryOrThrow("client_nonce"), "encrypted_token", encryptedAnswer ); byte[] packed = Boss.pack(result); return Binder.fromKeysValues( "data", packed, "signature", myKey.sign(packed, HashType.SHA512) ); } } } catch (Exception e) { addError(Errors.BAD_VALUE, "signed_data", "wrong or tampered data block:" + e.getMessage()); } return null; }
private Binder startApproval(final Binder params, Session session) throws IOException, Quantiser.QuantiserException { if (config == null || config.limitFreeRegistrations()) if(config == null || ( !config.getKeysWhiteList().contains(session.getPublicKey()) && !config.getAddressesWhiteList().stream().anyMatch(addr -> addr.isMatchingKey(session.getPublicKey())))) { System.out.println("startApproval ERROR: session key shoild be in the white list"); return Binder.of( "itemResult", itemResultOfError(Errors.BAD_CLIENT_KEY,"startApproval", "command needs client key from whitelist")); } int n = asyncStarts.incrementAndGet(); AtomicInteger k = new AtomicInteger(); params.getListOrThrow("packedItems").forEach((item) -> es.execute(() -> { try { checkNode(session); System.out.println("Request to start registration #"+n+":"+k.incrementAndGet()); node.registerItem(Contract.fromPackedTransaction(((Bytes)item).toArray())); } catch (Exception e) { e.printStackTrace(); } }) ); //TODO: return ItemResult return new Binder(); }
public Binder command(Binder params) throws ClientError, EncryptionError { // decrypt params and execute command Binder result = null; try { result = Binder.fromKeysValues( "result", executeAuthenticatedCommand( Boss.unpack( sessionKey.decrypt(params.getBinaryOrThrow("params")) ) ) ); } catch (Exception e) { ErrorRecord r = (e instanceof ClientError) ? ((ClientError) e).getErrorRecord() : new ErrorRecord(Errors.COMMAND_FAILED, "", e.getMessage()); result = Binder.fromKeysValues( "error", r ); } // encrypt and return result return Binder.fromKeysValues( "result", sessionKey.encrypt(Boss.pack(result)) ); }
@Test public void handshakeAndSecureCommand() throws Exception { PrivateKey nodeKey = TestKeys.privateKey(1); PrivateKey clientKey = TestKeys.privateKey(2); BasicHttpServer s = new BasicHttpServer(nodeKey, 15600, 32, log); BasicHttpClient c = new BasicHttpClient("http://localhost:15600"); c.start(clientKey, nodeKey.getPublicKey(), null); Binder res = c.command("sping"); assertEquals("spong", res.getStringOrThrow("sping")); s.addSecureEndpoint("getSessionInfo", (params,session)-> { // System.out.println("in sec, "+session); // System.out.println("\t "+session.getPublicKey()); return Binder.of("publicKey", session.getPublicKey().info().toString()); }); res = c.command("getSessionInfo"); s.shutdown(); }
private void checkNode(Session session, boolean checkKeyLimit) throws CommandFailedException { // checking node if (node == null) { throw new CommandFailedException(Errors.NOT_READY, "", "please call again after a while"); } if(node.isSanitating()) { //WHILE NODE IS SANITATING IT COMMUNICATES WITH THE OTHER NODES ONLY if(netConfig.toList().stream().anyMatch(nodeInfo -> nodeInfo.getPublicKey().equals(session.getPublicKey()))) return; throw new CommandFailedException(Errors.NOT_READY, "", "please call again after a while"); } // checking key limit if (checkKeyLimit) if (!node.checkKeyLimit(session.getPublicKey())) throw new CommandFailedException(Errors.COMMAND_FAILED, "", "exceeded the limit of requests for key per minute, please call again after a while"); }
private Binder getStats(Binder params, Session session) throws CommandFailedException { checkNode(session, true); if (config == null || node == null || !( config.getNetworkAdminKeyAddress().isMatchingKey(session.getPublicKey()) || node.getNodeKey().equals(session.getPublicKey()) || config.getKeysWhiteList().contains(session.getPublicKey()) || config.getAddressesWhiteList().stream().anyMatch(addr -> addr.isMatchingKey(session.getPublicKey())) )) { System.out.println("command needs admin key"); return Binder.of( "itemResult", itemResultOfError(Errors.BAD_CLIENT_KEY,"getStats", "command needs admin key")); } return node.provideStats(params.getInt("showDays",null)); }
private Binder onConnect(Binder params) throws ClientError { try { PublicKey clientKey = new PublicKey(params.getBinaryOrThrow("client_key")); return inSession(clientKey, session -> session.connect()); } catch (Exception e) { throw new ClientError(Errors.BAD_CLIENT_KEY, "client_key", "bad client key"); } }
BasicHttpServer(PrivateKey key, int port, int maxTrheads, BufferedLogger log) throws IOException { this.myKey = key; this.log = log; service = new MicroHTTPDService(); addEndpoint("/ping", params -> onPing(params)); addEndpoint("/connect", params -> onConnect(params)); addEndpoint("/get_token", params -> inSession(params.getLongOrThrow("session_id"), s -> s.getToken(params))); addEndpoint("/command", params -> inSession(params.getLongOrThrow("session_id"), s -> s.command(params))); service.start(port, maxTrheads); }