u_public.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. // Copyright 2017 Google Inc. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package tls
  5. import (
  6. "crypto"
  7. "crypto/ecdh"
  8. "crypto/x509"
  9. "hash"
  10. "github.com/Psiphon-Labs/utls/internal/mlkem768"
  11. )
  12. type PubKeySharePrivateKeys struct {
  13. Ecdhe map[CurveID]*ecdh.PrivateKey
  14. Kyber map[CurveID]*mlkem768.DecapsulationKey
  15. }
  16. func NewPubKeySharePrivateKeys() *PubKeySharePrivateKeys {
  17. return &PubKeySharePrivateKeys{
  18. Ecdhe: make(map[CurveID]*ecdh.PrivateKey),
  19. Kyber: make(map[CurveID]*mlkem768.DecapsulationKey),
  20. }
  21. }
  22. func (pk *PubKeySharePrivateKeys) toPrivate() *keySharePrivateKeys {
  23. if pk == nil {
  24. return nil
  25. } else {
  26. return &keySharePrivateKeys{
  27. ecdhe: pk.Ecdhe,
  28. kyber: pk.Kyber,
  29. }
  30. }
  31. }
  32. func (pk *keySharePrivateKeys) toPublic() *PubKeySharePrivateKeys {
  33. if pk == nil {
  34. return nil
  35. } else {
  36. return &PubKeySharePrivateKeys{
  37. Ecdhe: pk.ecdhe,
  38. Kyber: pk.kyber,
  39. }
  40. }
  41. }
  42. // ClientHandshakeState includes both TLS 1.3-only and TLS 1.2-only states,
  43. // only one of them will be used, depending on negotiated version.
  44. //
  45. // ClientHandshakeState will be converted into and from either
  46. // - clientHandshakeState (TLS 1.2)
  47. // - clientHandshakeStateTLS13 (TLS 1.3)
  48. //
  49. // uTLS will call .handshake() on one of these private internal states,
  50. // to perform TLS handshake using standard crypto/tls implementation.
  51. type PubClientHandshakeState struct {
  52. C *Conn
  53. ServerHello *PubServerHelloMsg
  54. Hello *PubClientHelloMsg
  55. MasterSecret []byte
  56. Session *SessionState
  57. State12 TLS12OnlyState
  58. State13 TLS13OnlyState
  59. uconn *UConn
  60. }
  61. // TLS 1.3 only
  62. type TLS13OnlyState struct {
  63. Suite *PubCipherSuiteTLS13
  64. KeyShareKeys *PubKeySharePrivateKeys
  65. EarlySecret []byte
  66. BinderKey []byte
  67. CertReq *CertificateRequestMsgTLS13
  68. UsingPSK bool // don't set this field when building client hello
  69. SentDummyCCS bool
  70. Transcript hash.Hash
  71. TrafficSecret []byte // client_application_traffic_secret_0
  72. }
  73. // TLS 1.2 and before only
  74. type TLS12OnlyState struct {
  75. FinishedHash FinishedHash
  76. Suite PubCipherSuite
  77. }
  78. func (chs *PubClientHandshakeState) toPrivate13() *clientHandshakeStateTLS13 {
  79. if chs == nil {
  80. return nil
  81. } else {
  82. return &clientHandshakeStateTLS13{
  83. c: chs.C,
  84. serverHello: chs.ServerHello.getPrivatePtr(),
  85. hello: chs.Hello.getPrivatePtr(),
  86. keyShareKeys: chs.State13.KeyShareKeys.toPrivate(),
  87. session: chs.Session,
  88. earlySecret: chs.State13.EarlySecret,
  89. binderKey: chs.State13.BinderKey,
  90. certReq: chs.State13.CertReq.toPrivate(),
  91. usingPSK: chs.State13.UsingPSK,
  92. sentDummyCCS: chs.State13.SentDummyCCS,
  93. suite: chs.State13.Suite.toPrivate(),
  94. transcript: chs.State13.Transcript,
  95. masterSecret: chs.MasterSecret,
  96. trafficSecret: chs.State13.TrafficSecret,
  97. uconn: chs.uconn,
  98. }
  99. }
  100. }
  101. func (chs13 *clientHandshakeStateTLS13) toPublic13() *PubClientHandshakeState {
  102. if chs13 == nil {
  103. return nil
  104. } else {
  105. tls13State := TLS13OnlyState{
  106. KeyShareKeys: chs13.keyShareKeys.toPublic(),
  107. EarlySecret: chs13.earlySecret,
  108. BinderKey: chs13.binderKey,
  109. CertReq: chs13.certReq.toPublic(),
  110. UsingPSK: chs13.usingPSK,
  111. SentDummyCCS: chs13.sentDummyCCS,
  112. Suite: chs13.suite.toPublic(),
  113. TrafficSecret: chs13.trafficSecret,
  114. Transcript: chs13.transcript,
  115. }
  116. return &PubClientHandshakeState{
  117. C: chs13.c,
  118. ServerHello: chs13.serverHello.getPublicPtr(),
  119. Hello: chs13.hello.getPublicPtr(),
  120. Session: chs13.session,
  121. MasterSecret: chs13.masterSecret,
  122. State13: tls13State,
  123. uconn: chs13.uconn,
  124. }
  125. }
  126. }
  127. func (chs *PubClientHandshakeState) toPrivate12() *clientHandshakeState {
  128. if chs == nil {
  129. return nil
  130. } else {
  131. return &clientHandshakeState{
  132. c: chs.C,
  133. serverHello: chs.ServerHello.getPrivatePtr(),
  134. hello: chs.Hello.getPrivatePtr(),
  135. suite: chs.State12.Suite.getPrivatePtr(),
  136. session: chs.Session,
  137. masterSecret: chs.MasterSecret,
  138. finishedHash: chs.State12.FinishedHash.getPrivateObj(),
  139. uconn: chs.uconn,
  140. }
  141. }
  142. }
  143. func (chs12 *clientHandshakeState) toPublic12() *PubClientHandshakeState {
  144. if chs12 == nil {
  145. return nil
  146. } else {
  147. tls12State := TLS12OnlyState{
  148. Suite: chs12.suite.getPublicObj(),
  149. FinishedHash: chs12.finishedHash.getPublicObj(),
  150. }
  151. return &PubClientHandshakeState{
  152. C: chs12.c,
  153. ServerHello: chs12.serverHello.getPublicPtr(),
  154. Hello: chs12.hello.getPublicPtr(),
  155. Session: chs12.session,
  156. MasterSecret: chs12.masterSecret,
  157. State12: tls12State,
  158. uconn: chs12.uconn,
  159. }
  160. }
  161. }
  162. // type EcdheParameters interface {
  163. // ecdheParameters
  164. // }
  165. type CertificateRequestMsgTLS13 struct {
  166. OcspStapling bool
  167. Scts bool
  168. SupportedSignatureAlgorithms []SignatureScheme
  169. SupportedSignatureAlgorithmsCert []SignatureScheme
  170. CertificateAuthorities [][]byte
  171. }
  172. func (crm *certificateRequestMsgTLS13) toPublic() *CertificateRequestMsgTLS13 {
  173. if crm == nil {
  174. return nil
  175. } else {
  176. return &CertificateRequestMsgTLS13{
  177. OcspStapling: crm.ocspStapling,
  178. Scts: crm.scts,
  179. SupportedSignatureAlgorithms: crm.supportedSignatureAlgorithms,
  180. SupportedSignatureAlgorithmsCert: crm.supportedSignatureAlgorithmsCert,
  181. CertificateAuthorities: crm.certificateAuthorities,
  182. }
  183. }
  184. }
  185. func (crm *CertificateRequestMsgTLS13) toPrivate() *certificateRequestMsgTLS13 {
  186. if crm == nil {
  187. return nil
  188. } else {
  189. return &certificateRequestMsgTLS13{
  190. ocspStapling: crm.OcspStapling,
  191. scts: crm.Scts,
  192. supportedSignatureAlgorithms: crm.SupportedSignatureAlgorithms,
  193. supportedSignatureAlgorithmsCert: crm.SupportedSignatureAlgorithmsCert,
  194. certificateAuthorities: crm.CertificateAuthorities,
  195. }
  196. }
  197. }
  198. type PubCipherSuiteTLS13 struct {
  199. Id uint16
  200. KeyLen int
  201. Aead func(key, fixedNonce []byte) aead
  202. Hash crypto.Hash
  203. }
  204. func (c *cipherSuiteTLS13) toPublic() *PubCipherSuiteTLS13 {
  205. if c == nil {
  206. return nil
  207. } else {
  208. return &PubCipherSuiteTLS13{
  209. Id: c.id,
  210. KeyLen: c.keyLen,
  211. Aead: c.aead,
  212. Hash: c.hash,
  213. }
  214. }
  215. }
  216. func (c *PubCipherSuiteTLS13) toPrivate() *cipherSuiteTLS13 {
  217. if c == nil {
  218. return nil
  219. } else {
  220. return &cipherSuiteTLS13{
  221. id: c.Id,
  222. keyLen: c.KeyLen,
  223. aead: c.Aead,
  224. hash: c.Hash,
  225. }
  226. }
  227. }
  228. type PubServerHelloMsg struct {
  229. Original []byte
  230. Vers uint16
  231. Random []byte
  232. SessionId []byte
  233. CipherSuite uint16
  234. CompressionMethod uint8
  235. NextProtoNeg bool
  236. NextProtos []string
  237. OcspStapling bool
  238. Scts [][]byte
  239. ExtendedMasterSecret bool
  240. TicketSupported bool // used by go tls to determine whether to add the session ticket ext
  241. SecureRenegotiation []byte
  242. SecureRenegotiationSupported bool
  243. AlpnProtocol string
  244. // 1.3
  245. SupportedVersion uint16
  246. ServerShare keyShare
  247. SelectedIdentityPresent bool
  248. SelectedIdentity uint16
  249. Cookie []byte // HelloRetryRequest extension
  250. SelectedGroup CurveID // HelloRetryRequest extension
  251. }
  252. func (shm *PubServerHelloMsg) getPrivatePtr() *serverHelloMsg {
  253. if shm == nil {
  254. return nil
  255. } else {
  256. return &serverHelloMsg{
  257. original: shm.Original,
  258. vers: shm.Vers,
  259. random: shm.Random,
  260. sessionId: shm.SessionId,
  261. cipherSuite: shm.CipherSuite,
  262. compressionMethod: shm.CompressionMethod,
  263. nextProtoNeg: shm.NextProtoNeg,
  264. nextProtos: shm.NextProtos,
  265. ocspStapling: shm.OcspStapling,
  266. scts: shm.Scts,
  267. extendedMasterSecret: shm.ExtendedMasterSecret,
  268. ticketSupported: shm.TicketSupported,
  269. secureRenegotiation: shm.SecureRenegotiation,
  270. secureRenegotiationSupported: shm.SecureRenegotiationSupported,
  271. alpnProtocol: shm.AlpnProtocol,
  272. supportedVersion: shm.SupportedVersion,
  273. serverShare: shm.ServerShare,
  274. selectedIdentityPresent: shm.SelectedIdentityPresent,
  275. selectedIdentity: shm.SelectedIdentity,
  276. cookie: shm.Cookie,
  277. selectedGroup: shm.SelectedGroup,
  278. }
  279. }
  280. }
  281. func (shm *serverHelloMsg) getPublicPtr() *PubServerHelloMsg {
  282. if shm == nil {
  283. return nil
  284. } else {
  285. return &PubServerHelloMsg{
  286. Original: shm.original,
  287. Vers: shm.vers,
  288. Random: shm.random,
  289. SessionId: shm.sessionId,
  290. CipherSuite: shm.cipherSuite,
  291. CompressionMethod: shm.compressionMethod,
  292. NextProtoNeg: shm.nextProtoNeg,
  293. NextProtos: shm.nextProtos,
  294. OcspStapling: shm.ocspStapling,
  295. Scts: shm.scts,
  296. ExtendedMasterSecret: shm.extendedMasterSecret,
  297. TicketSupported: shm.ticketSupported,
  298. SecureRenegotiation: shm.secureRenegotiation,
  299. SecureRenegotiationSupported: shm.secureRenegotiationSupported,
  300. AlpnProtocol: shm.alpnProtocol,
  301. SupportedVersion: shm.supportedVersion,
  302. ServerShare: shm.serverShare,
  303. SelectedIdentityPresent: shm.selectedIdentityPresent,
  304. SelectedIdentity: shm.selectedIdentity,
  305. Cookie: shm.cookie,
  306. SelectedGroup: shm.selectedGroup,
  307. }
  308. }
  309. }
  310. type PubClientHelloMsg struct {
  311. Original []byte
  312. Vers uint16
  313. Random []byte
  314. SessionId []byte
  315. CipherSuites []uint16
  316. CompressionMethods []uint8
  317. NextProtoNeg bool
  318. ServerName string
  319. OcspStapling bool
  320. Scts bool
  321. Ems bool // [uTLS] actually implemented due to its prevalence
  322. SupportedCurves []CurveID
  323. SupportedPoints []uint8
  324. TicketSupported bool
  325. SessionTicket []uint8
  326. SupportedSignatureAlgorithms []SignatureScheme
  327. SecureRenegotiation []byte
  328. SecureRenegotiationSupported bool
  329. AlpnProtocols []string
  330. // 1.3
  331. SupportedSignatureAlgorithmsCert []SignatureScheme
  332. SupportedVersions []uint16
  333. Cookie []byte
  334. KeyShares []KeyShare
  335. EarlyData bool
  336. PskModes []uint8
  337. PskIdentities []PskIdentity
  338. PskBinders [][]byte
  339. QuicTransportParameters []byte
  340. EncryptedClientHello []byte
  341. cachedPrivateHello *clientHelloMsg // todo: further optimize to reduce clientHelloMsg construction
  342. }
  343. func (chm *PubClientHelloMsg) getPrivatePtr() *clientHelloMsg {
  344. if chm == nil {
  345. return nil
  346. } else {
  347. private := &clientHelloMsg{
  348. original: chm.Original,
  349. vers: chm.Vers,
  350. random: chm.Random,
  351. sessionId: chm.SessionId,
  352. cipherSuites: chm.CipherSuites,
  353. compressionMethods: chm.CompressionMethods,
  354. serverName: chm.ServerName,
  355. ocspStapling: chm.OcspStapling,
  356. supportedCurves: chm.SupportedCurves,
  357. supportedPoints: chm.SupportedPoints,
  358. ticketSupported: chm.TicketSupported,
  359. sessionTicket: chm.SessionTicket,
  360. supportedSignatureAlgorithms: chm.SupportedSignatureAlgorithms,
  361. supportedSignatureAlgorithmsCert: chm.SupportedSignatureAlgorithmsCert,
  362. secureRenegotiationSupported: chm.SecureRenegotiationSupported,
  363. secureRenegotiation: chm.SecureRenegotiation,
  364. extendedMasterSecret: chm.Ems,
  365. alpnProtocols: chm.AlpnProtocols,
  366. scts: chm.Scts,
  367. supportedVersions: chm.SupportedVersions,
  368. cookie: chm.Cookie,
  369. keyShares: KeyShares(chm.KeyShares).ToPrivate(),
  370. earlyData: chm.EarlyData,
  371. pskModes: chm.PskModes,
  372. pskIdentities: PskIdentities(chm.PskIdentities).ToPrivate(),
  373. pskBinders: chm.PskBinders,
  374. quicTransportParameters: chm.QuicTransportParameters,
  375. encryptedClientHello: chm.EncryptedClientHello,
  376. nextProtoNeg: chm.NextProtoNeg,
  377. }
  378. chm.cachedPrivateHello = private
  379. return private
  380. }
  381. }
  382. func (chm *PubClientHelloMsg) getCachedPrivatePtr() *clientHelloMsg {
  383. if chm == nil {
  384. return nil
  385. } else {
  386. return chm.cachedPrivateHello
  387. }
  388. }
  389. func (chm *clientHelloMsg) getPublicPtr() *PubClientHelloMsg {
  390. if chm == nil {
  391. return nil
  392. } else {
  393. return &PubClientHelloMsg{
  394. Original: chm.original,
  395. Vers: chm.vers,
  396. Random: chm.random,
  397. SessionId: chm.sessionId,
  398. CipherSuites: chm.cipherSuites,
  399. CompressionMethods: chm.compressionMethods,
  400. NextProtoNeg: chm.nextProtoNeg,
  401. ServerName: chm.serverName,
  402. OcspStapling: chm.ocspStapling,
  403. Scts: chm.scts,
  404. Ems: chm.extendedMasterSecret,
  405. SupportedCurves: chm.supportedCurves,
  406. SupportedPoints: chm.supportedPoints,
  407. TicketSupported: chm.ticketSupported,
  408. SessionTicket: chm.sessionTicket,
  409. SupportedSignatureAlgorithms: chm.supportedSignatureAlgorithms,
  410. SecureRenegotiation: chm.secureRenegotiation,
  411. SecureRenegotiationSupported: chm.secureRenegotiationSupported,
  412. AlpnProtocols: chm.alpnProtocols,
  413. SupportedSignatureAlgorithmsCert: chm.supportedSignatureAlgorithmsCert,
  414. SupportedVersions: chm.supportedVersions,
  415. Cookie: chm.cookie,
  416. KeyShares: keyShares(chm.keyShares).ToPublic(),
  417. EarlyData: chm.earlyData,
  418. PskModes: chm.pskModes,
  419. PskIdentities: pskIdentities(chm.pskIdentities).ToPublic(),
  420. PskBinders: chm.pskBinders,
  421. QuicTransportParameters: chm.quicTransportParameters,
  422. EncryptedClientHello: chm.encryptedClientHello,
  423. cachedPrivateHello: chm,
  424. }
  425. }
  426. }
  427. // UnmarshalClientHello allows external code to parse raw client hellos.
  428. // It returns nil on failure.
  429. func UnmarshalClientHello(data []byte) *PubClientHelloMsg {
  430. m := &clientHelloMsg{}
  431. if m.unmarshal(data) {
  432. return m.getPublicPtr()
  433. }
  434. return nil
  435. }
  436. // Marshal allows external code to convert a ClientHello object back into
  437. // raw bytes.
  438. func (chm *PubClientHelloMsg) Marshal() ([]byte, error) {
  439. return chm.getPrivatePtr().marshal()
  440. }
  441. // A CipherSuite is a specific combination of key agreement, cipher and MAC
  442. // function. All cipher suites currently assume RSA key agreement.
  443. type PubCipherSuite struct {
  444. Id uint16
  445. // the lengths, in bytes, of the key material needed for each component.
  446. KeyLen int
  447. MacLen int
  448. IvLen int
  449. Ka func(version uint16) keyAgreement
  450. // flags is a bitmask of the suite* values, above.
  451. Flags int
  452. Cipher func(key, iv []byte, isRead bool) interface{}
  453. Mac func(macKey []byte) hash.Hash
  454. Aead func(key, fixedNonce []byte) aead
  455. }
  456. func (cs *PubCipherSuite) getPrivatePtr() *cipherSuite {
  457. if cs == nil {
  458. return nil
  459. } else {
  460. return &cipherSuite{
  461. id: cs.Id,
  462. keyLen: cs.KeyLen,
  463. macLen: cs.MacLen,
  464. ivLen: cs.IvLen,
  465. ka: cs.Ka,
  466. flags: cs.Flags,
  467. cipher: cs.Cipher,
  468. mac: cs.Mac,
  469. aead: cs.Aead,
  470. }
  471. }
  472. }
  473. func (cs *cipherSuite) getPublicObj() PubCipherSuite {
  474. if cs == nil {
  475. return PubCipherSuite{}
  476. } else {
  477. return PubCipherSuite{
  478. Id: cs.id,
  479. KeyLen: cs.keyLen,
  480. MacLen: cs.macLen,
  481. IvLen: cs.ivLen,
  482. Ka: cs.ka,
  483. Flags: cs.flags,
  484. Cipher: cs.cipher,
  485. Mac: cs.mac,
  486. Aead: cs.aead,
  487. }
  488. }
  489. }
  490. // A FinishedHash calculates the hash of a set of handshake messages suitable
  491. // for including in a Finished message.
  492. type FinishedHash struct {
  493. Client hash.Hash
  494. Server hash.Hash
  495. // Prior to TLS 1.2, an additional MD5 hash is required.
  496. ClientMD5 hash.Hash
  497. ServerMD5 hash.Hash
  498. // In TLS 1.2, a full buffer is sadly required.
  499. Buffer []byte
  500. Version uint16
  501. Prf func(result, secret, label, seed []byte)
  502. }
  503. func (fh *FinishedHash) getPrivateObj() finishedHash {
  504. if fh == nil {
  505. return finishedHash{}
  506. } else {
  507. return finishedHash{
  508. client: fh.Client,
  509. server: fh.Server,
  510. clientMD5: fh.ClientMD5,
  511. serverMD5: fh.ServerMD5,
  512. buffer: fh.Buffer,
  513. version: fh.Version,
  514. prf: fh.Prf,
  515. }
  516. }
  517. }
  518. func (fh *finishedHash) getPublicObj() FinishedHash {
  519. if fh == nil {
  520. return FinishedHash{}
  521. } else {
  522. return FinishedHash{
  523. Client: fh.client,
  524. Server: fh.server,
  525. ClientMD5: fh.clientMD5,
  526. ServerMD5: fh.serverMD5,
  527. Buffer: fh.buffer,
  528. Version: fh.version,
  529. Prf: fh.prf}
  530. }
  531. }
  532. // TLS 1.3 Key Share. See RFC 8446, Section 4.2.8.
  533. type KeyShare struct {
  534. Group CurveID `json:"group"`
  535. Data []byte `json:"key_exchange,omitempty"` // optional
  536. }
  537. type KeyShares []KeyShare
  538. type keyShares []keyShare
  539. func (kss keyShares) ToPublic() []KeyShare {
  540. var KSS []KeyShare
  541. for _, ks := range kss {
  542. KSS = append(KSS, KeyShare{Data: ks.data, Group: ks.group})
  543. }
  544. return KSS
  545. }
  546. func (KSS KeyShares) ToPrivate() []keyShare {
  547. var kss []keyShare
  548. for _, KS := range KSS {
  549. kss = append(kss, keyShare{data: KS.Data, group: KS.Group})
  550. }
  551. return kss
  552. }
  553. // TLS 1.3 PSK Identity. Can be a Session Ticket, or a reference to a saved
  554. // session. See RFC 8446, Section 4.2.11.
  555. type PskIdentity struct {
  556. Label []byte `json:"identity"`
  557. ObfuscatedTicketAge uint32 `json:"obfuscated_ticket_age"`
  558. }
  559. type PskIdentities []PskIdentity
  560. type pskIdentities []pskIdentity
  561. func (pss pskIdentities) ToPublic() []PskIdentity {
  562. var PSS []PskIdentity
  563. for _, ps := range pss {
  564. PSS = append(PSS, PskIdentity{Label: ps.label, ObfuscatedTicketAge: ps.obfuscatedTicketAge})
  565. }
  566. return PSS
  567. }
  568. func (PSS PskIdentities) ToPrivate() []pskIdentity {
  569. var pss []pskIdentity
  570. for _, PS := range PSS {
  571. pss = append(pss, pskIdentity{label: PS.Label, obfuscatedTicketAge: PS.ObfuscatedTicketAge})
  572. }
  573. return pss
  574. }
  575. // ClientSessionState is public, but all its fields are private. Let's add setters, getters and constructor
  576. // ClientSessionState contains the state needed by clients to resume TLS sessions.
  577. func MakeClientSessionState(
  578. SessionTicket []uint8,
  579. Vers uint16,
  580. CipherSuite uint16,
  581. MasterSecret []byte,
  582. ServerCertificates []*x509.Certificate,
  583. VerifiedChains [][]*x509.Certificate) *ClientSessionState {
  584. // TODO: Add EMS to this constructor in uTLS v2
  585. css := &ClientSessionState{
  586. session: &SessionState{
  587. version: Vers,
  588. cipherSuite: CipherSuite,
  589. secret: MasterSecret,
  590. peerCertificates: ServerCertificates,
  591. verifiedChains: VerifiedChains,
  592. ticket: SessionTicket,
  593. },
  594. }
  595. return css
  596. }
  597. // Encrypted ticket used for session resumption with server
  598. func (css *ClientSessionState) SessionTicket() []uint8 {
  599. return css.session.ticket
  600. }
  601. // SSL/TLS version negotiated for the session
  602. func (css *ClientSessionState) Vers() uint16 {
  603. return css.session.version
  604. }
  605. // Ciphersuite negotiated for the session
  606. func (css *ClientSessionState) CipherSuite() uint16 {
  607. return css.session.cipherSuite
  608. }
  609. // MasterSecret generated by client on a full handshake
  610. func (css *ClientSessionState) MasterSecret() []byte {
  611. return css.session.secret
  612. }
  613. func (css *ClientSessionState) EMS() bool {
  614. return css.session.extMasterSecret
  615. }
  616. // Certificate chain presented by the server
  617. func (css *ClientSessionState) ServerCertificates() []*x509.Certificate {
  618. return css.session.peerCertificates
  619. }
  620. // Certificate chains we built for verification
  621. func (css *ClientSessionState) VerifiedChains() [][]*x509.Certificate {
  622. return css.session.verifiedChains
  623. }
  624. func (css *ClientSessionState) SetSessionTicket(SessionTicket []uint8) {
  625. css.session.ticket = SessionTicket
  626. }
  627. func (css *ClientSessionState) SetVers(Vers uint16) {
  628. if css.session == nil {
  629. css.session = &SessionState{}
  630. }
  631. css.session.version = Vers
  632. }
  633. func (css *ClientSessionState) SetCipherSuite(CipherSuite uint16) {
  634. if css.session == nil {
  635. css.session = &SessionState{}
  636. }
  637. css.session.cipherSuite = CipherSuite
  638. }
  639. func (css *ClientSessionState) SetCreatedAt(createdAt uint64) {
  640. if css.session == nil {
  641. css.session = &SessionState{}
  642. }
  643. css.session.createdAt = createdAt
  644. }
  645. func (css *ClientSessionState) SetMasterSecret(MasterSecret []byte) {
  646. if css.session == nil {
  647. css.session = &SessionState{}
  648. }
  649. css.session.secret = MasterSecret
  650. }
  651. func (css *ClientSessionState) SetEMS(ems bool) {
  652. if css.session == nil {
  653. css.session = &SessionState{}
  654. }
  655. css.session.extMasterSecret = ems
  656. }
  657. func (css *ClientSessionState) SetServerCertificates(ServerCertificates []*x509.Certificate) {
  658. if css.session == nil {
  659. css.session = &SessionState{}
  660. }
  661. css.session.peerCertificates = ServerCertificates
  662. }
  663. func (css *ClientSessionState) SetVerifiedChains(VerifiedChains [][]*x509.Certificate) {
  664. if css.session == nil {
  665. css.session = &SessionState{}
  666. }
  667. css.session.verifiedChains = VerifiedChains
  668. }
  669. func (css *ClientSessionState) SetUseBy(useBy uint64) {
  670. if css.session == nil {
  671. css.session = &SessionState{}
  672. }
  673. css.session.useBy = useBy
  674. }
  675. func (css *ClientSessionState) SetAgeAdd(ageAdd uint32) {
  676. if css.session == nil {
  677. css.session = &SessionState{}
  678. }
  679. css.session.ageAdd = ageAdd
  680. }