Browsers should connect to port 80 and perform a GET for /tls-cert with an Accept: header listing all the certificate formats it knows and the applicable Host: header.
The server would respond with the certificate for that host-name and the browser would validate it. After that, the HTTP connection would switch into TLS mode using the key in that certificate.
If the server responds to this initial request with 404 or some other error, the browser either shows an error or continues in insecure mode.
This would have the benefit of bringing that initial certificate negotiation outside of the TLS black-box. For years, TLS deployment was held back because you couldn't have multiple domains on a single IP, long after the problem had been solved for HTTP.
Later, SNI was added to TLS, but the change wouldn't be rolled out to Windows XP users (except Firefox which used its own TLS implementation).
By using HTTP, you'd have the Host: header right away and could even introduce new certificate formats by looking at the Accept: header. This sort of thing is built into HTTP but had to be retrofitted with much pain and anguish into TLS.
Just like real-world TLS, the browser would validate the certificate before using it. TLS can be MITM'd too - if you can find a way around browser validation of the certificate.
Browsers should connect to port 80 and perform a GET for /tls-cert with an Accept: header listing all the certificate formats it knows and the applicable Host: header.
The server would respond with the certificate for that host-name and the browser would validate it. After that, the HTTP connection would switch into TLS mode using the key in that certificate.
If the server responds to this initial request with 404 or some other error, the browser either shows an error or continues in insecure mode.