Signed update protocol, v1

Client defaults: no endpoint and no public key; manual check only.
Outer JSON:
{"Payload":"BASE64_OF_UTF8_JSON","Signature":"BASE64_RSA_SIGNATURE"}

Decoded payload example (sign these exact UTF-8 bytes):
{"Version":"1.1.0","Architecture":"x64","Url":"https://your-server.example/IOC-Setup.exe","Sha256":"64_HEX_DIGITS","Notes":"Release notes"}

Signature: RSA PKCS#1 v1.5 / SHA-256; minimum 2048-bit key.
Configure only the RSA public XML key in the client. Keep the private key
offline/on your release infrastructure. No signing key is embedded here.

Both manifest and package must use HTTPS. Redirects are not followed.
Manifest limit: 1 MiB. Installer limit: 200 MiB. Client timeout: 90 s.
Manifest signature is checked before URLs/metadata are accepted. Package
SHA-256 is checked before it is written as an executable. Versions <= 1.1.0
are not offered. Installation requires a separate user confirmation.
Cryptographic package integrity is distinct from Windows Authenticode.
No automatic release server, certificate, rollback or hosting is supplied.

To generate an envelope in C# using an already provisioned private key:
var payload = Encoding.UTF8.GetBytes(json);
var signature = rsa.SignData(payload, CryptoConfig.MapNameToOID("SHA256"));
var envelope = new {
  Payload = Convert.ToBase64String(payload),
  Signature = Convert.ToBase64String(signature)
};

Serve the serialized envelope from the configured HTTPS URL. The sample
domain above is documentation only and is not contacted by the application.
