handshake-messages.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. package mint
  2. import (
  3. "bytes"
  4. "crypto"
  5. "crypto/x509"
  6. "encoding/binary"
  7. "fmt"
  8. "github.com/bifurcation/mint/syntax"
  9. )
  10. type HandshakeMessageBody interface {
  11. Type() HandshakeType
  12. Marshal() ([]byte, error)
  13. Unmarshal(data []byte) (int, error)
  14. }
  15. // struct {
  16. // ProtocolVersion legacy_version = 0x0303; /* TLS v1.2 */
  17. // Random random;
  18. // opaque legacy_session_id<0..32>;
  19. // CipherSuite cipher_suites<2..2^16-2>;
  20. // opaque legacy_compression_methods<1..2^8-1>;
  21. // Extension extensions<0..2^16-1>;
  22. // } ClientHello;
  23. type ClientHelloBody struct {
  24. LegacyVersion uint16
  25. Random [32]byte
  26. LegacySessionID []byte
  27. CipherSuites []CipherSuite
  28. Extensions ExtensionList
  29. }
  30. type clientHelloBodyInnerTLS struct {
  31. LegacyVersion uint16
  32. Random [32]byte
  33. LegacySessionID []byte `tls:"head=1,max=32"`
  34. CipherSuites []CipherSuite `tls:"head=2,min=2"`
  35. LegacyCompressionMethods []byte `tls:"head=1,min=1"`
  36. Extensions []Extension `tls:"head=2"`
  37. }
  38. type clientHelloBodyInnerDTLS struct {
  39. LegacyVersion uint16
  40. Random [32]byte
  41. LegacySessionID []byte `tls:"head=1,max=32"`
  42. EmptyCookie uint8
  43. CipherSuites []CipherSuite `tls:"head=2,min=2"`
  44. LegacyCompressionMethods []byte `tls:"head=1,min=1"`
  45. Extensions []Extension `tls:"head=2"`
  46. }
  47. func (ch ClientHelloBody) Type() HandshakeType {
  48. return HandshakeTypeClientHello
  49. }
  50. func (ch ClientHelloBody) Marshal() ([]byte, error) {
  51. if ch.LegacyVersion == tls12Version {
  52. return syntax.Marshal(clientHelloBodyInnerTLS{
  53. LegacyVersion: ch.LegacyVersion,
  54. Random: ch.Random,
  55. LegacySessionID: []byte{},
  56. CipherSuites: ch.CipherSuites,
  57. LegacyCompressionMethods: []byte{0},
  58. Extensions: ch.Extensions,
  59. })
  60. } else {
  61. return syntax.Marshal(clientHelloBodyInnerDTLS{
  62. LegacyVersion: ch.LegacyVersion,
  63. Random: ch.Random,
  64. LegacySessionID: []byte{},
  65. CipherSuites: ch.CipherSuites,
  66. LegacyCompressionMethods: []byte{0},
  67. Extensions: ch.Extensions,
  68. })
  69. }
  70. }
  71. func (ch *ClientHelloBody) Unmarshal(data []byte) (int, error) {
  72. var read int
  73. var err error
  74. // Note that this might be 0, in which case we do TLS. That
  75. // makes the tests easier.
  76. if ch.LegacyVersion != dtls12WireVersion {
  77. var inner clientHelloBodyInnerTLS
  78. read, err = syntax.Unmarshal(data, &inner)
  79. if err != nil {
  80. return 0, err
  81. }
  82. if len(inner.LegacyCompressionMethods) != 1 || inner.LegacyCompressionMethods[0] != 0 {
  83. return 0, fmt.Errorf("tls.clienthello: Invalid compression method")
  84. }
  85. ch.LegacyVersion = inner.LegacyVersion
  86. ch.Random = inner.Random
  87. ch.LegacySessionID = inner.LegacySessionID
  88. ch.CipherSuites = inner.CipherSuites
  89. ch.Extensions = inner.Extensions
  90. } else {
  91. var inner clientHelloBodyInnerDTLS
  92. read, err = syntax.Unmarshal(data, &inner)
  93. if err != nil {
  94. return 0, err
  95. }
  96. if inner.EmptyCookie != 0 {
  97. return 0, fmt.Errorf("tls.clienthello: Invalid cookie")
  98. }
  99. if len(inner.LegacyCompressionMethods) != 1 || inner.LegacyCompressionMethods[0] != 0 {
  100. return 0, fmt.Errorf("tls.clienthello: Invalid compression method")
  101. }
  102. ch.LegacyVersion = inner.LegacyVersion
  103. ch.Random = inner.Random
  104. ch.LegacySessionID = inner.LegacySessionID
  105. ch.CipherSuites = inner.CipherSuites
  106. ch.Extensions = inner.Extensions
  107. }
  108. return read, nil
  109. }
  110. // TODO: File a spec bug to clarify this
  111. func (ch ClientHelloBody) Truncated() ([]byte, error) {
  112. if len(ch.Extensions) == 0 {
  113. return nil, fmt.Errorf("tls.clienthello.truncate: No extensions")
  114. }
  115. pskExt := ch.Extensions[len(ch.Extensions)-1]
  116. if pskExt.ExtensionType != ExtensionTypePreSharedKey {
  117. return nil, fmt.Errorf("tls.clienthello.truncate: Last extension is not PSK")
  118. }
  119. body, err := ch.Marshal()
  120. if err != nil {
  121. return nil, err
  122. }
  123. chm := &HandshakeMessage{
  124. msgType: ch.Type(),
  125. body: body,
  126. length: uint32(len(body)),
  127. }
  128. chData := chm.Marshal()
  129. psk := PreSharedKeyExtension{
  130. HandshakeType: HandshakeTypeClientHello,
  131. }
  132. _, err = psk.Unmarshal(pskExt.ExtensionData)
  133. if err != nil {
  134. return nil, err
  135. }
  136. // Marshal just the binders so that we know how much to truncate
  137. binders := struct {
  138. Binders []PSKBinderEntry `tls:"head=2,min=33"`
  139. }{Binders: psk.Binders}
  140. binderData, _ := syntax.Marshal(binders)
  141. binderLen := len(binderData)
  142. chLen := len(chData)
  143. return chData[:chLen-binderLen], nil
  144. }
  145. // struct {
  146. // ProtocolVersion legacy_version = 0x0303; /* TLS v1.2 */
  147. // Random random;
  148. // opaque legacy_session_id_echo<0..32>;
  149. // CipherSuite cipher_suite;
  150. // uint8 legacy_compression_method = 0;
  151. // Extension extensions<6..2^16-1>;
  152. // } ServerHello;
  153. type ServerHelloBody struct {
  154. Version uint16
  155. Random [32]byte
  156. LegacySessionID []byte `tls:"head=1,max=32"`
  157. CipherSuite CipherSuite
  158. LegacyCompressionMethod uint8
  159. Extensions ExtensionList `tls:"head=2"`
  160. }
  161. func (sh ServerHelloBody) Type() HandshakeType {
  162. return HandshakeTypeServerHello
  163. }
  164. func (sh ServerHelloBody) Marshal() ([]byte, error) {
  165. return syntax.Marshal(sh)
  166. }
  167. func (sh *ServerHelloBody) Unmarshal(data []byte) (int, error) {
  168. return syntax.Unmarshal(data, sh)
  169. }
  170. // struct {
  171. // opaque verify_data[verify_data_length];
  172. // } Finished;
  173. //
  174. // verifyDataLen is not a field in the TLS struct, but we add it here so
  175. // that calling code can tell us how much data to expect when we marshal /
  176. // unmarshal. (We could add this to the marshal/unmarshal methods, but let's
  177. // try to keep the signature consistent for now.)
  178. //
  179. // For similar reasons, we don't use the `syntax` module here, because this
  180. // struct doesn't map well to standard TLS presentation language concepts.
  181. //
  182. // TODO: File a spec bug
  183. type FinishedBody struct {
  184. VerifyDataLen int
  185. VerifyData []byte
  186. }
  187. func (fin FinishedBody) Type() HandshakeType {
  188. return HandshakeTypeFinished
  189. }
  190. func (fin FinishedBody) Marshal() ([]byte, error) {
  191. if len(fin.VerifyData) != fin.VerifyDataLen {
  192. return nil, fmt.Errorf("tls.finished: data length mismatch")
  193. }
  194. body := make([]byte, len(fin.VerifyData))
  195. copy(body, fin.VerifyData)
  196. return body, nil
  197. }
  198. func (fin *FinishedBody) Unmarshal(data []byte) (int, error) {
  199. if len(data) < fin.VerifyDataLen {
  200. return 0, fmt.Errorf("tls.finished: Malformed finished; too short")
  201. }
  202. fin.VerifyData = make([]byte, fin.VerifyDataLen)
  203. copy(fin.VerifyData, data[:fin.VerifyDataLen])
  204. return fin.VerifyDataLen, nil
  205. }
  206. // struct {
  207. // Extension extensions<0..2^16-1>;
  208. // } EncryptedExtensions;
  209. //
  210. // Marshal() and Unmarshal() are handled by ExtensionList
  211. type EncryptedExtensionsBody struct {
  212. Extensions ExtensionList `tls:"head=2"`
  213. }
  214. func (ee EncryptedExtensionsBody) Type() HandshakeType {
  215. return HandshakeTypeEncryptedExtensions
  216. }
  217. func (ee EncryptedExtensionsBody) Marshal() ([]byte, error) {
  218. return syntax.Marshal(ee)
  219. }
  220. func (ee *EncryptedExtensionsBody) Unmarshal(data []byte) (int, error) {
  221. return syntax.Unmarshal(data, ee)
  222. }
  223. // opaque ASN1Cert<1..2^24-1>;
  224. //
  225. // struct {
  226. // ASN1Cert cert_data;
  227. // Extension extensions<0..2^16-1>
  228. // } CertificateEntry;
  229. //
  230. // struct {
  231. // opaque certificate_request_context<0..2^8-1>;
  232. // CertificateEntry certificate_list<0..2^24-1>;
  233. // } Certificate;
  234. type CertificateEntry struct {
  235. CertData *x509.Certificate
  236. Extensions ExtensionList
  237. }
  238. type CertificateBody struct {
  239. CertificateRequestContext []byte
  240. CertificateList []CertificateEntry
  241. }
  242. type certificateEntryInner struct {
  243. CertData []byte `tls:"head=3,min=1"`
  244. Extensions ExtensionList `tls:"head=2"`
  245. }
  246. type certificateBodyInner struct {
  247. CertificateRequestContext []byte `tls:"head=1"`
  248. CertificateList []certificateEntryInner `tls:"head=3"`
  249. }
  250. func (c CertificateBody) Type() HandshakeType {
  251. return HandshakeTypeCertificate
  252. }
  253. func (c CertificateBody) Marshal() ([]byte, error) {
  254. inner := certificateBodyInner{
  255. CertificateRequestContext: c.CertificateRequestContext,
  256. CertificateList: make([]certificateEntryInner, len(c.CertificateList)),
  257. }
  258. for i, entry := range c.CertificateList {
  259. inner.CertificateList[i] = certificateEntryInner{
  260. CertData: entry.CertData.Raw,
  261. Extensions: entry.Extensions,
  262. }
  263. }
  264. return syntax.Marshal(inner)
  265. }
  266. func (c *CertificateBody) Unmarshal(data []byte) (int, error) {
  267. inner := certificateBodyInner{}
  268. read, err := syntax.Unmarshal(data, &inner)
  269. if err != nil {
  270. return read, err
  271. }
  272. c.CertificateRequestContext = inner.CertificateRequestContext
  273. c.CertificateList = make([]CertificateEntry, len(inner.CertificateList))
  274. for i, entry := range inner.CertificateList {
  275. c.CertificateList[i].CertData, err = x509.ParseCertificate(entry.CertData)
  276. if err != nil {
  277. return 0, fmt.Errorf("tls:certificate: Certificate failed to parse: %v", err)
  278. }
  279. c.CertificateList[i].Extensions = entry.Extensions
  280. }
  281. return read, nil
  282. }
  283. // struct {
  284. // SignatureScheme algorithm;
  285. // opaque signature<0..2^16-1>;
  286. // } CertificateVerify;
  287. type CertificateVerifyBody struct {
  288. Algorithm SignatureScheme
  289. Signature []byte `tls:"head=2"`
  290. }
  291. func (cv CertificateVerifyBody) Type() HandshakeType {
  292. return HandshakeTypeCertificateVerify
  293. }
  294. func (cv CertificateVerifyBody) Marshal() ([]byte, error) {
  295. return syntax.Marshal(cv)
  296. }
  297. func (cv *CertificateVerifyBody) Unmarshal(data []byte) (int, error) {
  298. return syntax.Unmarshal(data, cv)
  299. }
  300. func (cv *CertificateVerifyBody) EncodeSignatureInput(data []byte) []byte {
  301. // TODO: Change context for client auth
  302. // TODO: Put this in a const
  303. const context = "TLS 1.3, server CertificateVerify"
  304. sigInput := bytes.Repeat([]byte{0x20}, 64)
  305. sigInput = append(sigInput, []byte(context)...)
  306. sigInput = append(sigInput, []byte{0}...)
  307. sigInput = append(sigInput, data...)
  308. return sigInput
  309. }
  310. func (cv *CertificateVerifyBody) Sign(privateKey crypto.Signer, handshakeHash []byte) (err error) {
  311. sigInput := cv.EncodeSignatureInput(handshakeHash)
  312. cv.Signature, err = sign(cv.Algorithm, privateKey, sigInput)
  313. logf(logTypeHandshake, "Signed: alg=[%04x] sigInput=[%x], sig=[%x]", cv.Algorithm, sigInput, cv.Signature)
  314. return
  315. }
  316. func (cv *CertificateVerifyBody) Verify(publicKey crypto.PublicKey, handshakeHash []byte) error {
  317. sigInput := cv.EncodeSignatureInput(handshakeHash)
  318. logf(logTypeHandshake, "About to verify: alg=[%04x] sigInput=[%x], sig=[%x]", cv.Algorithm, sigInput, cv.Signature)
  319. return verify(cv.Algorithm, publicKey, sigInput, cv.Signature)
  320. }
  321. // struct {
  322. // opaque certificate_request_context<0..2^8-1>;
  323. // Extension extensions<2..2^16-1>;
  324. // } CertificateRequest;
  325. type CertificateRequestBody struct {
  326. CertificateRequestContext []byte `tls:"head=1"`
  327. Extensions ExtensionList `tls:"head=2"`
  328. }
  329. func (cr CertificateRequestBody) Type() HandshakeType {
  330. return HandshakeTypeCertificateRequest
  331. }
  332. func (cr CertificateRequestBody) Marshal() ([]byte, error) {
  333. return syntax.Marshal(cr)
  334. }
  335. func (cr *CertificateRequestBody) Unmarshal(data []byte) (int, error) {
  336. return syntax.Unmarshal(data, cr)
  337. }
  338. // struct {
  339. // uint32 ticket_lifetime;
  340. // uint32 ticket_age_add;
  341. // opaque ticket_nonce<1..255>;
  342. // opaque ticket<1..2^16-1>;
  343. // Extension extensions<0..2^16-2>;
  344. // } NewSessionTicket;
  345. type NewSessionTicketBody struct {
  346. TicketLifetime uint32
  347. TicketAgeAdd uint32
  348. TicketNonce []byte `tls:"head=1,min=1"`
  349. Ticket []byte `tls:"head=2,min=1"`
  350. Extensions ExtensionList `tls:"head=2"`
  351. }
  352. const ticketNonceLen = 16
  353. func NewSessionTicket(ticketLen int, ticketLifetime uint32) (*NewSessionTicketBody, error) {
  354. buf := make([]byte, 4+ticketNonceLen+ticketLen)
  355. _, err := prng.Read(buf)
  356. if err != nil {
  357. return nil, err
  358. }
  359. tkt := &NewSessionTicketBody{
  360. TicketLifetime: ticketLifetime,
  361. TicketAgeAdd: binary.BigEndian.Uint32(buf[:4]),
  362. TicketNonce: buf[4 : 4+ticketNonceLen],
  363. Ticket: buf[4+ticketNonceLen:],
  364. }
  365. return tkt, err
  366. }
  367. func (tkt NewSessionTicketBody) Type() HandshakeType {
  368. return HandshakeTypeNewSessionTicket
  369. }
  370. func (tkt NewSessionTicketBody) Marshal() ([]byte, error) {
  371. return syntax.Marshal(tkt)
  372. }
  373. func (tkt *NewSessionTicketBody) Unmarshal(data []byte) (int, error) {
  374. return syntax.Unmarshal(data, tkt)
  375. }
  376. // enum {
  377. // update_not_requested(0), update_requested(1), (255)
  378. // } KeyUpdateRequest;
  379. //
  380. // struct {
  381. // KeyUpdateRequest request_update;
  382. // } KeyUpdate;
  383. type KeyUpdateBody struct {
  384. KeyUpdateRequest KeyUpdateRequest
  385. }
  386. func (ku KeyUpdateBody) Type() HandshakeType {
  387. return HandshakeTypeKeyUpdate
  388. }
  389. func (ku KeyUpdateBody) Marshal() ([]byte, error) {
  390. return syntax.Marshal(ku)
  391. }
  392. func (ku *KeyUpdateBody) Unmarshal(data []byte) (int, error) {
  393. return syntax.Unmarshal(data, ku)
  394. }
  395. // struct {} EndOfEarlyData;
  396. type EndOfEarlyDataBody struct{}
  397. func (eoed EndOfEarlyDataBody) Type() HandshakeType {
  398. return HandshakeTypeEndOfEarlyData
  399. }
  400. func (eoed EndOfEarlyDataBody) Marshal() ([]byte, error) {
  401. return []byte{}, nil
  402. }
  403. func (eoed *EndOfEarlyDataBody) Unmarshal(data []byte) (int, error) {
  404. return 0, nil
  405. }