I'm considering using TLS for a peer-to-peer, SSH-like usage without PKI.

First, there is a setup phase of the clients, before any connection between them is established. The setup consists of generating a self-signed certificate that authenticates A, and then transmitting that certificate to host B. The certificate is transmitted using some pre-established secure channel such as SSH. A requirement is that information flows in the setup phase only from A to B, not the other way around. That means that A can't know about public keys or certificates generated by B.

In the use phase, host A tries to connect to B. In this situation, even if B would have a self-signed certificate of its own, A wouldn't know it. B can't connect to A because of firewalls, NATs, dynamic IPs or other such reasons.

My question is, does TLS using X.509 support this kind of pattern?

1) Is it possible to establish a secure connection using only client certificate, while the server has none? A's certificate isn't meant to be distributed widely; so in theory it would be possible to generate a token using A's private key and demand B to prove that decrypt it using A's public key, or what's even simpler, just demand B to send back the A's public key; I'm unaware whether TLS supports such a flow?

2) From "semantic" perspective certificates are meant to be public information; however, if the use case of 1) is possible, A's certificate must be considered a secret. Is there any better fitting schemes here? I'm thinking of TLS-PSK, but it, on the other hand eschews asymmetricity and A must then be authenticate itself using other, asymmetric means, if I don't want B to be able to imitate A.

  • What would be the benefits compared to standard TLS with PKI? I couldn't think of any. Feb 18 '19 at 12:28
  • TLS with PKI: you need to delegate generating a certificate to a CA for every client you add. The clients might not have domain names or static IP addresses. The clients might be not online 100% of the time, and they might be behind a NAT. That makes it hard, unless you run your own CA which is a bunch of work and complications. It's basically the same reason why SSH with public-private keypairs is so easy to setup and popular.
    – GolDDranks
    Feb 18 '19 at 13:25
  • @GolDDranks Running your own CA sounds a whole lot easier than this odd scenario that uses some corner case of the specification, if it exists at all. In the time you wrote this question, you could have looked up how to create a CA and sign certificates with it :P
    – Luc
    Feb 18 '19 at 14:04
  • @GolDDranks: in the setup phase A creates a certificate and installs it on B. Yet, you claim that in the use phase there is no certificate on B known to A. This does not make any sense for me, since there should be the certificate on B which was installed in the setup phase. And this is known to A. Feb 18 '19 at 14:49
  • @GolDDranks: to make more clear which contradicting statements I refer to: "generating a self-signed certificate on host A, and then installing that certificate on host B " - this statement clearly says that there will be some certificate on B and A also knows which certificate this is since A created it. This contradicts the second statement: "... even if B did have a self-signed certificate, A wouldn't know it" - Feb 18 '19 at 14:51

From RFC 5246 (TLS 1.2) section 7.4.4 "Certificate Request":

It is a fatal handshake_failure alert for an anonymous server to request client authentication.

It it is not clear in your case if the server is anonymous. But, you specify that the server does not provide a server certificate and you don't say anything about other forms of authentication, like PSK. This suggests that the server in your use case is not authenticated which means it cannot request a client certificate.

But, based on your question you don't actually need a client-certificate-only TLS handshake at all. What you need instead is a TCP connection from A to B followed by a TLS handshake from B to A. In this case A has a role of a TLS server with a certificate known to B. This kind of setup is possible since all the TLS handshake needs is an established underlying (TCP) connection. It does not matter who initiated the TCP connection.


Is it possible to establish a secure connection using only client certificate

Speaking generally, not necessarily of TLS, the answer is "it depends". If you consider a connection secure if it's between two known parties, then no: with only one side authenticating (the client side), you don't know if you're talking to the real server or to an impostor. Same with HTTPS as it is usually deployed (without client-side certificate): the server does not know whom they are talking to, only the client knows they are talking to the right server.

If you don't care about authenticating the server to the client, it doesn't really matter whether TLS supports your specific setup: you can always let the client accept any certificate, which is equally secure to the server not presenting any certificate.

generate a token using A's private key and demand B to prove that decrypt it using A's public key

So it sounds like you do want mutual authentication.

Treating a public key as private is probably going to go wrong at some point. It reminds me of the fairy tale of Rumpelstiltskin, where nobody is allowed to know your name (public key). And in case of RSA, an attacker (having knowledge of neither the public nor private key) could submit any message to B and demand they 'decrypt' (message^e mod n) it using A's public key. So an attacker does not know A's public key, but they can ask B to encrypt anything they want to send to A using that public key. It depends on the scenario if that is actually useful for anything, but the whole scenario feels wrong.

or what's even simpler, just demand B to send back the A's public key

An attacker could just capture the transmission once and replay it ever after. Are you assuming there is already an encrypted channel based on the client certificate? Because then you're not using the TLS handshake but just building something inside the TLS tunnel.

I don't know the entire TLS specification by heart to be able to tell you that this is supported by the protocol, or all features of a popular client to be able to tell you that a specific client cannot do this, but it seems doubtful. I don't see a need to support this: your scenario cannot really exist, since if no data can flow from B back to A, there can be no handshake. Therefore, when you exchange the key from A to B via something like SSH, B can also communicate back to A. If you want mutual authentication and there is, at some point in time, an established encrypted tunnel that was mutually authenticated, then that would be the opportunity to exchange keys. And if you're not looking for mutual authentication but only for "a secure TLS connection using only client certificate" (i.e. only one side is authenticated), then you can use TLS as normal but ignore the validity of the server's certificate (so like curl -k).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.