Repository: codenotary/immudb
File: pkg/client/auditor/auditor.go (Go)

Code before:
		a.logger.Warningf(
			"audit #%d detected possible tampering of db %s remote state (at id %d) "+
				"so it will not overwrite the previous local state (at id %d)",
			a.index, dbName, state.TxId, prevState.TxId)
	} else if prevState == nil || state.TxId != prevState.TxId {
		if err := a.history.Set(serverID, dbName, state); err != nil {
			a.logger.Errorf(err.Error())
			return noErr
		}
	}
	a.logger.Infof("audit #%d finished in %s @ %s",
		a.index, time.Since(start), time.Now().Format(time.RFC3339Nano))

	return noErr
}

func (a *defaultAuditor) verifyStateSignature(
	serverID string,
	serverState *schema.ImmutableState,
) error {

	if a.serverSigningPubKey != nil && serverState.GetSignature() == nil {
		return fmt.Errorf(
			"a server signing public key has been specified for the auditor, "+
				"but the state %s at TX %d received from server %s @ %s is not signed",
			serverState.GetTxHash(), serverState.GetTxId(), serverID, a.serverAddress)
	}

	if serverState.GetSignature() != nil {
		pk := a.serverSigningPubKey
		if pk == nil {
			x, y := elliptic.Unmarshal(elliptic.P256(), serverState.GetSignature().GetPublicKey())
			pk = &ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y}
		}

		if okSig, err := serverState.CheckSignature(pk); err != nil || !okSig {
			return fmt.Errorf(
				"failed to verify signature for state %s at TX %d received from server %s @ %s: "+
					"verification result: %t, verification error: %v",
				serverState.GetTxHash(), serverState.GetTxId(), serverID, a.serverAddress,
				okSig, err)
		}
	}

	return nil
}

// Signature ...
type Signature struct {
	Signature string `json:"signature"`
	PublicKey string `json:"public_key"`

Review comment (security):
Can we issue some kind of warning here? Checking the signature here without any form of public key verification does not protect from man-in-the-middle attacks and may give a false sense of security.

Code after:
			a.logger.Errorf(err.Error())
			return noErr
		}
	}
	a.logger.Infof("audit #%d finished in %s @ %s",
		a.index, time.Since(start), time.Now().Format(time.RFC3339Nano))

	return noErr
}

func (a *defaultAuditor) verifyStateSignature(
	serverID string,
	serverState *schema.ImmutableState,
) error {

	if a.serverSigningPubKey != nil && serverState.GetSignature() == nil {
		return fmt.Errorf(
			"a server signing public key has been specified for the auditor, "+
				"but the state %s at TX %d received from server %s @ %s is not signed",
			serverState.GetTxHash(), serverState.GetTxId(), serverID, a.serverAddress)
	}

	if serverState.GetSignature() != nil {
		pk := a.serverSigningPubKey
		if pk == nil {
			x, y := elliptic.Unmarshal(elliptic.P256(), serverState.GetSignature().GetPublicKey())
			pk = &ecdsa.PublicKey{Curve: elliptic.P256(), X: x, Y: y}
		}

		if okSig, err := serverState.CheckSignature(pk); err != nil || !okSig {
			return fmt.Errorf(
				"failed to verify signature for state %s at TX %d received from server %s @ %s: "+
					"verification result: %t, verification error: %v",
				serverState.GetTxHash(), serverState.GetTxId(), serverID, a.serverAddress,
				okSig, err)
		}
	}

	return nil
}

// Signature ...
type Signature struct {
	Signature string `json:"signature"`
	PublicKey string `json:"public_key"`
}

// State ...
type State struct {
	Tx        uint64    `json:"tx" validate:"required"`
	Hash      string    `json:"hash" validate:"required"`