Up until a few years ago there was a <keygen> tag which embedded a x509 CSR generator into a regular HTML form. The private key was generated by the browser(1) and was completely inaccessible to the site or any JS running on it. That's the proper way to generate certificates in browsers, but it's been removed since and was never supported in IE.
StartSSL used it, for example, but also allowed you to hand them a CSR of your own making. Although they of course ignored almost everything in the CSR apart from the public key (which is probably a good idea).
(1) IIRC you could even have a smartcard generate the key, at least in theory.
You say "they of course ignored almost everything in the CSR apart from the public key" but it turns out they went a bit further than that, they also ignored the signature on the CSR.
So you could put some other public key in there, add a bogus signature that wouldn't verify and they'd issue certificates for a key you never even controlled.
The bad security implications for that scenario are a bit subtle, and situational, but CAs are supposed to be checking that the CSR is properly signed, that's only a long way down the list because StartCom/ WoSign had so many other serious problems.
Actually I've never seen a solid argument for why that's a problem. A similar issue exists in PGP, but again it's unclear what the actual problem is. Some (non-x509) PKIs can't do this anyway.
Two people have asked essentially the same thing here, I'll answer this one because it was at the top. I am going to deliberately use a far-fetched scenario rather than invoke specific technologies, because there is no benefit to learning more specific here than "Nope, a competent CA must never allow this to happen".
Alice has public key A, and Bob has public key B, and everybody trusts Charlie the Certificate Agency to issue certificates, Alice has one binding (Alice,A) and Bob has one binding (Bob,B).
Alice controls a missile she will only accept Major Tom's commands. Bob runs firework displays, he accepts the display organizer's commands.
I want to fire Alice's missile. I impersonate Bob, and I trick Charlie into issuing a certificate (Bob,A) because she doesn't verify that I know the Private Key for A. Then I offer (as Bob) to run a really great firework show for Tom, and I give him the (Bob,A) certificate so he can command firework launching.
When Tom sends me a launch message encrypted to A, I simply deliver it to Alice, who launches the missile as I desired.
Alice was never compromised, neither was Tom. Charlie's only mistake was not verifying that I controlled the Private Key for the cert she issued me. Bob was compromised, but he was just running a firework business, he didn't know this was a matter of national security.
Ah, ok. In your scenario, the assumption appears to be that by issuing a (Bob, A) certificate, Charlie asserts that key A belongs to Bob.
For some reason, I never thought of DV certificates that way. I always took (Bob, A) to mean "I checked with the real Bob and he says it's fine to use key A in his name".
The former is, of course, the more useful guarantee.
I'm aware of this[1], and with what you said out front in mind - it doesn't apply to either HTTPS or PGP. (I'm pretty sure you can build systems affected by this with X509, though).
[1] I don't want to take away from your good post, it's a good and well explained scenario to illustrate the issue. Personally I found Dominic Tarr's paper on AKEs-as-capabilities quite illuminating when I read it, and the analysis applies to your scenario as well. (The scenario is also a neat demonstration of a bunch of other issues, too)
Hmm. I think I agree with you that it isn't practical in HTTPS. I can see clearly why you can't do anything like this in TLS 1.3 because it has this nice simple ordering - the client and server do DH key agreement - we now both have encryption but no certainty of who we're talking to - then the server sends a certificate and uses the key from that certificate to sign their DH transcript, the client optionally also sends a certificate, they too use the key from that certificate to sign the transcript. Since I don't know Alice's Private Key I cannot sign transcripts while presenting the (Bob,A) certificate, and if I let Alice do the key exchange so that she'll sign, I'm cut out of the loop entirely. That's easy to follow.
But in TLS 1.2 and earlier it's murkier to me because there are cases with and without DH, and what gets signed, by who, and when varies. I think you're right, but I started doodling the possible cases out and I filled two A4 pages before I gave up. Certainly even if you're right as to how the protocol is designed it will not astonish me if somebody implements it wrong and doesn't check a signature somewhere given the many cases.
Sure, they should have checked but I don't see the implication. If you take steps to prove ownership of a domain and then request a certificate for it with a key you do not control, that's on you.
It can't be that hard to whip up a cross platform Qt app that streamlines the keygen and CSR process in a user friendly fashion. Maybe throw in some dodgy key escrow service for the daring. Why does everything have to be done over the web.
StartSSL used it, for example, but also allowed you to hand them a CSR of your own making. Although they of course ignored almost everything in the CSR apart from the public key (which is probably a good idea).
(1) IIRC you could even have a smartcard generate the key, at least in theory.