Search in sources :

Example 1 with IntegrityPacket

use of me.retrodaredevil.solarthing.packets.security.IntegrityPacket in project solarthing by wildmountainfarms.

the class SecurityPacketReceiver method receivePacketGroup.

private void receivePacketGroup(StoredPacketGroup storedPacketGroup, TargetPacketGroup packetGroup) {
    LOGGER.debug("Receiving packet group: " + storedPacketGroup.getStoredIdentifier());
    long packetGroupDateMillis = packetGroup.getDateMillis();
    List<? extends Packet> packetGroupPackets = packetGroup.getPackets();
    if (packetGroupPackets.stream().noneMatch(packet -> packet instanceof SecurityPacket && !(packet instanceof AuthNewSenderPacket))) {
        LOGGER.debug("This packet group has no useful SecurityPackets. Ignoring. identifier: " + storedPacketGroup.getStoredIdentifier());
        return;
    }
    if (packetGroupPackets.size() != 1) {
        /*
			In any "millis database" we have the documents inside follow the packet collection format.
			Packet collections can have many packets inside them. When we are dealing with security packets,
			we want to be able to easily refer to a single security packet. Because no one should ever need
			to contain multiple security packets in a given packet collection, we will only process
			packet collections with a single security packet. This allows things like SecurityEventPackets to work nicely,
			and doesn't have any real drawbacks except for some (possible) future use case that we don't know of.
			 */
        LOGGER.warn("This packetGroup targeting us had a packetGroup.size != 1! stored identifier: " + storedPacketGroup.getStoredIdentifier());
        reject(storedPacketGroup, SecurityRejectPacket.Reason.INVALID_DATA, "You cannot have more than one packet (besides source and target)");
        return;
    }
    Packet packet = packetGroupPackets.stream().findFirst().orElseThrow(() -> new AssertionError("size should be 1! This should not fail"));
    if (!(packet instanceof LargeIntegrityPacket)) {
        if (packet instanceof IntegrityPacket) {
            LOGGER.warn(SolarThingConstants.SUMMARY_MARKER, "Got an IntegrityPacket! This is no longer supported!");
            reject(storedPacketGroup, SecurityRejectPacket.Reason.LEGACY_REQUEST, "IntegrityPacket is no longer supported");
        } else if (packet instanceof AuthNewSenderPacket) {
            LOGGER.warn("Got an AuthNewSenderPacket. Ignoring.");
            reject(storedPacketGroup, SecurityRejectPacket.Reason.UNKNOWN_ERROR, "Got auth new sender packet");
        } else {
            LOGGER.warn("Unknown packet: " + packet);
            reject(storedPacketGroup, SecurityRejectPacket.Reason.UNKNOWN_ERROR, "Got unknown packet");
        }
        return;
    }
    LargeIntegrityPacket largeIntegrityPacket = (LargeIntegrityPacket) packet;
    String sender = largeIntegrityPacket.getSender();
    final String invalidSenderReason = sender == null ? "sender is null!" : SenderUtil.getInvalidSenderNameReason(sender);
    if (invalidSenderReason != null) {
        LOGGER.warn(SolarThingConstants.SUMMARY_MARKER, invalidSenderReason);
        reject(storedPacketGroup, SecurityRejectPacket.Reason.INVALID_DATA, invalidSenderReason);
        return;
    }
    String encodedHash = decryptData(storedPacketGroup, sender, largeIntegrityPacket.getEncryptedHash(), packetGroupDateMillis);
    if (encodedHash == null) {
        // If encodedHash is null, then decryptData should have already called reject()
        return;
    }
    byte[] decodedHash;
    try {
        decodedHash = Base64Variants.getDefaultVariant().decode(encodedHash);
    } catch (IllegalArgumentException e) {
        LOGGER.error("Not base64 data!", e);
        reject(storedPacketGroup, SecurityRejectPacket.Reason.INVALID_DATA, "Not base64 data!");
        return;
    }
    String payload = largeIntegrityPacket.getPayload();
    byte[] payloadHash = HashUtil.hash(payload);
    if (!Arrays.equals(decodedHash, payloadHash)) {
        LOGGER.warn("Unsuccessfully compared hashes! The data may have been tampered with!");
        reject(storedPacketGroup, SecurityRejectPacket.Reason.DIFFERENT_PAYLOAD, "Unsuccessfully compared hashes");
        return;
    }
    LOGGER.debug("Successfully compared hashes!");
    handleMessage(storedPacketGroup, payload, sender);
}
Also used : Packet(me.retrodaredevil.solarthing.packets.Packet) IntegrityPacket(me.retrodaredevil.solarthing.packets.security.IntegrityPacket) SecurityRejectPacket(me.retrodaredevil.solarthing.commands.event.SecurityRejectPacket) LargeIntegrityPacket(me.retrodaredevil.solarthing.packets.security.LargeIntegrityPacket) InstanceSourcePacket(me.retrodaredevil.solarthing.packets.instance.InstanceSourcePacket) DocumentedPacket(me.retrodaredevil.solarthing.packets.DocumentedPacket) SecurityPacket(me.retrodaredevil.solarthing.packets.security.SecurityPacket) ImmutableSecurityRejectPacket(me.retrodaredevil.solarthing.commands.event.ImmutableSecurityRejectPacket) ImmutableSecurityAcceptPacket(me.retrodaredevil.solarthing.commands.event.ImmutableSecurityAcceptPacket) SecurityAcceptPacket(me.retrodaredevil.solarthing.commands.event.SecurityAcceptPacket) InstancePacket(me.retrodaredevil.solarthing.packets.instance.InstancePacket) AuthNewSenderPacket(me.retrodaredevil.solarthing.packets.security.AuthNewSenderPacket) SecurityEventPacket(me.retrodaredevil.solarthing.commands.event.SecurityEventPacket) SecurityPacket(me.retrodaredevil.solarthing.packets.security.SecurityPacket) AuthNewSenderPacket(me.retrodaredevil.solarthing.packets.security.AuthNewSenderPacket) IntegrityPacket(me.retrodaredevil.solarthing.packets.security.IntegrityPacket) LargeIntegrityPacket(me.retrodaredevil.solarthing.packets.security.LargeIntegrityPacket) LargeIntegrityPacket(me.retrodaredevil.solarthing.packets.security.LargeIntegrityPacket)

Aggregations

ImmutableSecurityAcceptPacket (me.retrodaredevil.solarthing.commands.event.ImmutableSecurityAcceptPacket)1 ImmutableSecurityRejectPacket (me.retrodaredevil.solarthing.commands.event.ImmutableSecurityRejectPacket)1 SecurityAcceptPacket (me.retrodaredevil.solarthing.commands.event.SecurityAcceptPacket)1 SecurityEventPacket (me.retrodaredevil.solarthing.commands.event.SecurityEventPacket)1 SecurityRejectPacket (me.retrodaredevil.solarthing.commands.event.SecurityRejectPacket)1 DocumentedPacket (me.retrodaredevil.solarthing.packets.DocumentedPacket)1 Packet (me.retrodaredevil.solarthing.packets.Packet)1 InstancePacket (me.retrodaredevil.solarthing.packets.instance.InstancePacket)1 InstanceSourcePacket (me.retrodaredevil.solarthing.packets.instance.InstanceSourcePacket)1 AuthNewSenderPacket (me.retrodaredevil.solarthing.packets.security.AuthNewSenderPacket)1 IntegrityPacket (me.retrodaredevil.solarthing.packets.security.IntegrityPacket)1 LargeIntegrityPacket (me.retrodaredevil.solarthing.packets.security.LargeIntegrityPacket)1 SecurityPacket (me.retrodaredevil.solarthing.packets.security.SecurityPacket)1