Nginx with its lua extension and the ssl part of it can choose a certificate to expose based on the start of the handshake, and what the client sent as
ClientHello but maybe not what you need precisely (list of algorithms supported).
The full documentation is at https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md and https://github.com/openresty/lua-nginx-module/#ssl_certificate_by_lua_block
It is particularly useful for setting the SSL certificate chain and
the corresponding private key on a per-request basis.
One can also do interesting things with the SSL handshake requests
from the client side, like rejecting old SSL clients using the SSLv3
protocol or even below selectively.
You can easily access the client or server IP (for multihomed ones) through the function
raw_server_addr, as well as the hostname the client is attempting to reach by reading the SNI part with
Based on the documentation I do not see getting access to other part of client ClientHello, but you could maybe find a solution already with the above if you can discriminate your clients based on their IP maybe, or if you have two separate server names, each one can become tied to a specific certificate.
Reading https://github.com/openresty/lua-nginx-module/blob/master/src/ngx_http_lua_ssl_certby.c I see no specific method accessing the list of cipher suites sent by client. However that piece of code gets all underlying "SSL" information from the openssl library so I suspect what you want is technically possible there but just needs to be coded.
Now two other points:
1) "Assume I can still get hold of an MD5 or SHA1 signed certificate."
This may be hard. At least from a public known CA under default operation. CAB Forum requirements (https://cabforum.org/wp-content/uploads/CA-Browser-Forum-BR-1.6.3.pdf) has this on page 38:
Digest algorithm: SHA1*, SHA-256, SHA-384 or SHA-512
* SHA-1 MAY be used with RSA keys in accordance with the criteria defined in Section 7.1.3.
7.1.3. Algorithm Object Identifiers
Effective 1 January 2016, CAs MUST NOT issue any new Subscriber certificates or Subordinate CA certificates using the SHA-1 hash algorithm.
2) "As I understand the SSL/TLS protocol does contain protection against downgrade attacks, so if the server supports 1.2 and the client also support 1.2 then if a downgrade to 1.0 happens then the connection should terminate (in case of an active man-in-the-middle attack)."
Yes, but only if using extension
TLS_FALLBACK_SCSV, and probably forbidding client renegotiation during an existing session.
See https://crypto.stackexchange.com/questions/19673/how-does-tls-fallback-scsv-help#19674 for explanations, but quoting the core part of it:
Essentially, TLS_FALLBACK_SCSV allows clients to send a hidden version
number in the downgraded connection attempt in a way that doesn't
trigger the server bugs.
Wikipedia page at https://en.wikipedia.org/wiki/Transport_Layer_Security also discusses in detail things about downgrade attacks.
This is improved in TLS 1.3 by the way, quoting 4.1.3. Server Hello from RFC8446:
TLS 1.3 has a downgrade protection mechanism embedded in the server's
random value. TLS 1.3 servers which negotiate TLS 1.2 or below in
response to a ClientHello MUST set the last 8 bytes of their Random
value specially in their ServerHello.
For all handshake modes, the Finished MAC (and, where present, the
signature) prevents downgrade attacks. In addition, the use of
certain bytes in the random nonces as described in Section 4.1.3
allows the detection of downgrade to previous TLS versions. See
[BBFGKZ16] for more details on TLS 1.3 and downgrade.