When you answer you get a response in a similar way than before.
Again first 4 bytes are the length of the message, followed by protobuf serialized data
This time we have just 2 fields, both of type 2 (string, bytes).
The first field (ID=1) is the so called ephemeral public key, which is the public key of a key pair, that you generate each time you form a new connection. You do this so that even if someone breaks the key, it broke only the session, not all the communication before, but you do use the same key for establishing who you are (peerID).
This key is supposed to be in P-256 eliptical form, but I'm not sure what that is. I suspect it's secp256k1 or prime256v1. I think NIST named P-256 the later.
For some reason, the field is 65 bytes long and the first byte is always
0x04, the rest being the actual key bytes.
If I generate new eliptical keys using openssl:
openssl ecparam -name secp256k1 -genkey -noout -out ec-key.pem
openssl ec -in ec-key.pem -pubout -outform der -out ec-pub.der
I get the public key file
ec-pub.der with 88 bytes (91 bytes with prime256v1).
Each time I generate new keys, the first 24 bytes (27 bytes with prime256v1) are always the same and the last 64 bytes are different. The byte before the bytes of the key is always
0x04, so it might be that it's just a badly stripped header byte or it indicates the type of key. No idea.
The second field (ID=2) in the protobuf data is the signature. It's 256 bytes long. It's a SHA-256 RSA digest of the
corpus in secio lingo.
The corpus is composed of 3 strings concatenated together:
Propose protobuf serialized data of the server (i.e. what we've received before
Response, without the first 4 bytes indicating length)
Propose protobuf serialized data of the client (i.e. what we've sent back, without the first 4 bytes indicating length)
- Ephemeral public key (i.e. the 65 bytes we just received)
We can check if the signature coresponds to the corpus if we save the corpus as described to a file e.g.
corpus.dat, the signature to e.g.
sig.dat and the public key of the server (which we received in the previous message, i.e.
server-pubkey.der and then running the following:
openssl dgst -sha256 -verify server-pubkey.der -keyform der -signature sig.dat corpus.dat
It should return