I have a case at hand as follows:
- There is a number of clients in Internet (i.e. untrusted channel), initially in hundreds but growing in numbers.
- There is a server doing processing related to these clients. This relation is established prior to this elsewhere, say a web portal.
- The clients should be able to connect to the server via a piece of software (non-human operated, e.g. not a browser) over the internet to load the material so that channel is encrypted and that the server knows which client is connected.
- There should not be an issue the clients could claim they have not requested the material when a connection has been made and the material has been transmitted. As an edit related to Thomas's question about not receiving material when they did: if I were to use plain password here, would there be a danger the password leaking more easily than the cert and someone else using it to obtain the material to be transferred? Though, I've thought about mitigatiging against such a situation by using this "sequence id" (see point 6 in the following list), which probably helps with or without certificates.
- The client never accepts incoming connections. It only initiates them to this well-known server.
- The ones operating the clients usually do not have their own certificates issued by some certificate authority.
- The server processor program has a certificate issued by a certificate authority (e.g. Thawte).
Question: What would be a good way to accomplish this in a secure and a maintainable way?
As far as I know, there isn’t any PKI software that I can use. I've planned the following:
- Let the clients download the piece of transfer software, say from the portal. The portal can include a settings file having a client id of some sort in it (and a, say, one-time password see point 4).
- When the client installs the transfer software on the server it generates a self-signed certificate with the client ID in the CN. For instance
makecert -r -n "CN=SomeClientId" -pe -ss my
. - This software sends the thumbprint of the generated certificate to the server along with the client id and uses a one-time password it has obtained elsewhere (see point 1).
- The server stores the thumbprint along with the client ID.
- Now when transfer software connects to the server, it can check to which client it belongs via the transmitted thumbprint and the channel is secured.
- For added security the server maintains a sequence number that needs to match with that of a respective transfer client. If they get out of sync, a breach is suspected and the very least the client needs both to go to the portal to reset the counter and reset in the transfer software (e.g. set 0 in the settings file).
Does this look like a sound arrangement? Would there be a better one? It looks like that if access of certain client needs to denied, all that is needed is to set a flag in the server database to indicate a certain thumbprint is not allowed anymore. Whilst browsing through SE, I came across How to distribute client certificates without exposing private key?. Taking the cue from Thomas Pornin's answer, I see I could alter this process so that upon generating the certificate. As for an example:
- Create
someclient.inf
file with appropriate parameters (in Windows, otherwise in other OSes, e.g. using openssl). - Do
certreq -new someclient.inf request.csr
to create the request file. - Send the csr to the server using the one-time password.
- The server receives and csr file and creates the certificate, saves the thumbprint and sends the certificate back.
- The client optionally installs the certificate with
certreq -accept someclient.cer
.
Another question: Would this bring additional benefits beyond the procedure I outlined initially (and is this a sound procedure)?
Additiona questions: It's unclear me as to how the server should do the signing. Which program? With which parameters? But maybe these should be another questions if this procedure is a usable one.
As a note: it could be I don't have access to all of the software on the command line or writing the code gets compplicated on the client end, so perhaps I'll need to resort to something like a BouncyCastle.