Imagine a SSL-like protocol that instead of using certificates signed by a trusted CA, has the server's public key hard-coded in the client. My question is: what happens if the server's private key is compromised? Without certificates, the system doesn't have a CRL (Certificate Revocation List) and until the users update the client, the attacker can impersonate the server. How can one build a system that makes public-key revocation possible while having the public-key hard coded in the client?
If the application completely trusts the public key (e.g., runs code signed by it), then you could add "master key change" messages that can be signed by it, that make the application change it's hard-coded key. For additional security, you could require that the new key be additionally signed by a key hopefully separated from the now-compromised one - here decent options are either an additional more-secured key or confirming the new master key via HTTPS (trusting the CA hierarchy).
Of course in all methods you must ensure the client gets reasonably recent revocation messages - which may require periodic signing of "non-revocation" messages - but note that CRLs have this problem too.