Hi,
I was going through the DTLS implementation, and I know it’s still an experimental feature, but I wanted to raise some potential issues with the interface. I might be miss-understanding some part, but if not, it seems unnecessarily inconvenient.
I only consider the case where pre-shared keys are not used.
So, my understanding is the following.
- After the client sent the `?EncryptionToken=` and the subclass implementation of `UGameInstance::ReceivedNetworkEncryptionAck` generate the `EncryptionData`, we end-up calling `FDTLSHandlerComponent::SetEncryptionData`.
- In the case where we don’t use a pre-shared key, only`EncryptionData.Identifier` and `EncryptionData.Fingerprint` is relevant. The `EncryptionData.Identifier` is an arbitrary identifier, used when we added the certificate and private key to the certificate store. The private key being necessary on the server and forbidden on the client.
- The `Fingerprint` is useful on the client if we don’t want people to impersonate our server by getting any valid certificates and private key.
On the server, it serves important purpose.(Edit: I meant, on the server, it serves no purpose) - From what I get, the only way to have a private key with the certificate is to call `FDTLSCertStore::CreateCert` which calls `FDTLSCertificate::GenerateCertificate` which creates a X509 certificate and private key. The X509 certificate is self-signed.
- So, it leads to the point where the client somehow needs to get this `Fingerprint` to verify the cert. In fact, it’s doubly important, because the client has no other way to verify the certificate chain. So, how does the client get this `Fingerprint`? Presumably by calling an external service in `UGameInstance::ReceivedNetworkEncryptionAck`?
Is my understanding incorrect?
If my understanding is correct, I wonder why not adding a function `FDTLSCertStore::ImportCertAndKey` which allows for importing a X509 cert and a private key. The server could basically hardcode the `EncryptionData.Identifier` aka `CertId` use to import the cert. The client could hardcode the `EncryptionData.Fingerprint`. No external services would be needed.
Ideally, the client may want to Fingerprint a parent certificate in the chain, or maybe the public key to allow updating a cert. In fact, fingerprinting the cert may not even be desirable, simply verifying the chain might be what the devs want.
I think this approach would be more inline with the intention of TLS.
Cheers,
Laurent