syncsynchalt/illustrated-tls12

server key calculation curve25519 tool

lomateron opened this issue · 1 comments

in Server Encryption Keys Calculation it says that the inputs for curve25519() are
client's public key and server's private key
then in https://tls.ulfheim.net/files/curve25519-mult.c there is:

reads the 32-byte key from a PEM file, takes advantage of the
fact that the last 32 bytes of encoded DER data are the key in
both the private and public key forms.

It says the public and private files end with 32 bytes of key data
but

RSAPublicKey ::= SEQUENCE {
          modulus           INTEGER,  -- n
          publicExponent    INTEGER   -- e
      }
RSAPrivateKey ::= SEQUENCE {
          version           Version,
          modulus           INTEGER,  -- n
          publicExponent    INTEGER,  -- e
          privateExponent   INTEGER,  -- d
          prime1            INTEGER,  -- p
          prime2            INTEGER,  -- q
          exponent1         INTEGER,  -- d mod (p-1)
          exponent2         INTEGER,  -- d mod (q-1)
          coefficient       INTEGER,  -- (inverse of q) mod p
          otherPrimeInfos   OtherPrimeInfos OPTIONAL
      }

https://tools.ietf.org/html/rfc3447#appendix-A.1.1
https://tools.ietf.org/html/rfc3447#appendix-A.1.2
so I am confuse
what attribute of server's private key does the curve25519() really uses?
also plz link to the RFC chapter that defines this

There are multiple algorithms to perform key exchange. RSA is one, Diffie-Hellman is another. The algorithm used in this handshake is ECDHE, which is Elliptical Curve Diffie-Hellman with Ephemeral keys. The specific EC function used is X25519 (multiplication using Curve25519).

X25519 is defined in this RFC: https://tools.ietf.org/html/rfc7748#section-5 and its use in ECDH is defined in https://tools.ietf.org/html/rfc7748#section-6 . The last "E" refers to generating a new key for every connection (ephemeral), which doesn't change the algorithm.

The comment that you quoted from curve25519-mult.c refers to a trick that the coder is using - PEM files are a base64 encoding of a binary format called DER. DER encodes things in a binary format of type+length+data, and it would take a bit of code to write a proper DER parser. However, if you know the format is fixed and that the data you want is the last field (and you know its length is 32), you can shortcut all that and just read the last 32 bytes without parsing DER at all. To see the DER data try the following command on a pem file:

$ openssl asn1parse -in server-ephemeral-private.key -inform PEM
    0:d=0  hl=2 l=  46 cons: SEQUENCE          
    2:d=1  hl=2 l=   1 prim: INTEGER           :00
    5:d=1  hl=2 l=   5 cons: SEQUENCE          
    7:d=2  hl=2 l=   3 prim: OBJECT            :X25519
   12:d=1  hl=2 l=  34 prim: OCTET STRING      [HEX DUMP]:0420909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAF

I believe the ASN.1 definition for these key files is in PKCS#8: https://tools.ietf.org/html/rfc5208