Problem: A node creates its onion service through Tor's control protocol and caches the returned PrivateKey value for reconnects.
Tor reply parsing unescapes quoted values, so a control endpoint can return a value containing a line break or space.
On reconnect, the node inserts that value unquoted into an ADD_ONION command.
CRLF frames the remainder as a separate command, while a space adds further arguments.
An unprivileged local process can exploit this by impersonating the default loopback endpoint while Tor is unavailable, seeding the cache, and releasing the port before Tor is available again.
A compromised operator-configured endpoint can return the same malicious value.
The reply handler also continues after receiving an invalid service ID, logging it and caching the key before attempting to advertise the invalid address.
A later reply without a service ID can reuse an ID left by an earlier reply.
Fix: This PR validates the returned service ID as a Tor v3 onion address before logging it, caching the key, or advertising the service.
Each reply must provide its own service ID, and reply fields stay local until validation succeeds.
Key validation accepts NEW:ED25519-V3 or an ED25519-V3 key whose Base64 payload decodes to 64 bytes.
Returned keys are validated before adoption or caching, and cached keys are validated before reuse.
A malformed cached key leaves the onion service unavailable until the operator removes the file and restarts the node. It cannot inject another command or argument.