/* Copyright (c) 2011 Danish Maritime Authority. * * 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 net.maritimecloud.internal.net.messages; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException; import net.maritimecloud.internal.security.SecurityTools; import net.maritimecloud.message.Message; import net.maritimecloud.util.Binary; import net.maritimecloud.util.Timestamp; import net.maritimecloud.util.geometry.Position; /** * * @author Kasper Nielsen */ public class MessageHasher { static Binary binaryOf(Broadcast br) { Binary b = Binary.EMPTY; b = b.concat(from(br.getBroadcastType(), false, "broadcastType")); b = b.concat(from(br.getSenderId(), false, "senderId")); b = b.concat(from(br.getSenderTimestamp(), false, "senderTimestamp")); b = b.concat(from(br.getSenderPosition(), true, "senderPosition")); b = b.concat(from(br.getPayload(), true, "payload")); return b; } static Binary binaryOf(BroadcastAck br) { Binary b = Binary.EMPTY; b = b.concat(from(br.getAckForMessageId(), false, "broadcastType")); b = b.concat(from(br.getOriginalSenderId(), false, "senderId")); b = b.concat(from(br.getReceiverId(), false, "senderTimestamp")); b = b.concat(from(br.getReceiverTimestamp(), true, "senderPosition")); return b.concat(from(br.getReceiverPosition(), true, "payload")); } static Binary binaryOf(MethodInvoke mi) { Binary b = Binary.EMPTY; b = b.concat(from(mi.getEndpointMethod(), false, "endpointMethod")); b = b.concat(from(mi.getSenderId(), false, "senderId")); b = b.concat(from(mi.getSenderTimestamp(), false, "senderTimestamp")); b = b.concat(from(mi.getSenderPosition(), true, "senderPosition")); b = b.concat(from(mi.getReceiverId(), true, "receiverId")); // null=server return b.concat(from(mi.getParameters(), true, "parameters")); // true } static Binary binaryOf(MethodInvokeResult mir) { Binary b = Binary.EMPTY; b = b.concat(from(mir.getResultForMessageId(), false, "resultForMessageId")); b = b.concat(from(mir.getOriginalSenderId(), false, "originalSenderId")); b = b.concat(from(mir.getReceiverId(), false, "receiverId")); b = b.concat(from(mir.getReceiverTimestamp(), true, "senderPosition")); b = b.concat(from(mir.getResult(), true, "receiverId")); // null=server return b.concat(from(mir.getFailure(), true, "parameters")); // true } public static Binary calculateSHA256(Broadcast mi) { return binaryOf(mi).sha256(); } public static Binary calculateSHA256(BroadcastAck mi) { return binaryOf(mi).sha256(); } public static Binary calculateSHA256(MethodInvoke mi) { return binaryOf(mi).sha256(); } public static Binary calculateSHA256(MethodInvokeResult mi) { return binaryOf(mi).sha256(); } static Binary checkEmpty(boolean optional, String name) { if (optional) { return Binary.EMPTY; } throw new IllegalArgumentException("The field '" + name + "' was not filled out"); } static Binary from(Binary binary, boolean optional, String name) { return binary == null ? checkEmpty(optional, name) : binary; } static Binary from(Message mes, boolean optional, String name) { return mes == null ? checkEmpty(optional, name) : Binary.copyFromUtf8(mes.toJSON()); } static Binary from(Position position, boolean optional, String name) { return position == null ? checkEmpty(optional, name) : position.toBinary(); } static Binary from(String str, boolean optional, String name) { return str == null ? checkEmpty(optional, name) : Binary.copyFromUtf8(str); } static Binary from(Timestamp timestamp, boolean optional, String name) { return timestamp == null ? checkEmpty(optional, name) : timestamp.toBinary(); } static Binary sign(Binary b, PrivateKey key) throws SignatureException { Signature dsa = SecurityTools.newSignatureForSigning(key); dsa.update(b.toByteArray()); byte[] signature = dsa.sign(); return Binary.copyFrom(signature); } public static Binary sign(Broadcast mi, PrivateKey key) throws SignatureException { return sign(binaryOf(mi), key); } public static Binary sign(BroadcastAck mi, PrivateKey key) throws SignatureException { return sign(binaryOf(mi), key); } public static Binary sign(MethodInvoke mi, PrivateKey key) throws SignatureException { return sign(binaryOf(mi), key); } public static Binary sign(MethodInvokeResult mi, PrivateKey key) throws SignatureException { return sign(binaryOf(mi), key); } static boolean verify(Binary b, PublicKey key) throws SignatureException { Signature dsa = SecurityTools.newSignatureForVerify(key); return dsa.verify(b.toByteArray()); } public static boolean verify(Broadcast mi, PublicKey key) throws SignatureException { return verify(binaryOf(mi), key); } public static boolean verify(BroadcastAck mi, PublicKey key) throws SignatureException { return verify(binaryOf(mi), key); } public static boolean verify(MethodInvoke mi, PublicKey key) throws SignatureException { return verify(binaryOf(mi), key); } public static boolean verify(MethodInvokeResult mi, PublicKey key) throws SignatureException { return verify(binaryOf(mi), key); } }