u_public.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  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/cipher"
  7. "crypto/x509"
  8. "hash"
  9. )
  10. type ClientHandshakeState struct {
  11. C *Conn
  12. ServerHello *ServerHelloMsg
  13. Hello *ClientHelloMsg
  14. Suite *CipherSuite
  15. FinishedHash FinishedHash
  16. MasterSecret []byte
  17. Session *ClientSessionState
  18. }
  19. // getPrivatePtr() methods make shallow copies
  20. func (chs *ClientHandshakeState) getPrivatePtr() *clientHandshakeState {
  21. if chs == nil {
  22. return nil
  23. } else {
  24. return &clientHandshakeState{
  25. c: chs.C,
  26. serverHello: chs.ServerHello.getPrivatePtr(),
  27. hello: chs.Hello.getPrivatePtr(),
  28. suite: chs.Suite.getPrivatePtr(),
  29. finishedHash: *chs.FinishedHash.getPrivatePtr(),
  30. masterSecret: chs.MasterSecret,
  31. session: chs.Session,
  32. }
  33. }
  34. }
  35. func (chs *clientHandshakeState) getPublicPtr() *ClientHandshakeState {
  36. if chs == nil {
  37. return nil
  38. } else {
  39. return &ClientHandshakeState{
  40. C: chs.c,
  41. ServerHello: chs.serverHello.getPublicPtr(),
  42. Hello: chs.hello.getPublicPtr(),
  43. Suite: chs.suite.getPublicPtr(),
  44. FinishedHash: *chs.finishedHash.getPublicPtr(),
  45. MasterSecret: chs.masterSecret,
  46. Session: chs.session,
  47. }
  48. }
  49. }
  50. type BensStruct serverHelloMsg
  51. type ServerHelloMsg struct {
  52. Raw []byte
  53. Vers uint16
  54. Random []byte
  55. SessionId []byte
  56. CipherSuite uint16
  57. CompressionMethod uint8
  58. NextProtoNeg bool
  59. NextProtos []string
  60. OcspStapling bool
  61. Scts [][]byte
  62. Ems bool
  63. TicketSupported bool
  64. SecureRenegotiation []byte
  65. SecureRenegotiationSupported bool
  66. AlpnProtocol string
  67. }
  68. func (shm *ServerHelloMsg) getPrivatePtr() *serverHelloMsg {
  69. if shm == nil {
  70. return nil
  71. } else {
  72. return &serverHelloMsg{
  73. raw: shm.Raw,
  74. vers: shm.Vers,
  75. random: shm.Random,
  76. sessionId: shm.SessionId,
  77. cipherSuite: shm.CipherSuite,
  78. compressionMethod: shm.CompressionMethod,
  79. nextProtoNeg: shm.NextProtoNeg,
  80. nextProtos: shm.NextProtos,
  81. ocspStapling: shm.OcspStapling,
  82. scts: shm.Scts,
  83. ems: shm.Ems,
  84. ticketSupported: shm.TicketSupported,
  85. secureRenegotiation: shm.SecureRenegotiation,
  86. secureRenegotiationSupported: shm.SecureRenegotiationSupported,
  87. alpnProtocol: shm.AlpnProtocol,
  88. }
  89. }
  90. }
  91. func (shm *serverHelloMsg) getPublicPtr() *ServerHelloMsg {
  92. if shm == nil {
  93. return nil
  94. } else {
  95. return &ServerHelloMsg{
  96. Raw: shm.raw,
  97. Vers: shm.vers,
  98. Random: shm.random,
  99. SessionId: shm.sessionId,
  100. CipherSuite: shm.cipherSuite,
  101. CompressionMethod: shm.compressionMethod,
  102. NextProtoNeg: shm.nextProtoNeg,
  103. NextProtos: shm.nextProtos,
  104. OcspStapling: shm.ocspStapling,
  105. Scts: shm.scts,
  106. Ems: shm.ems,
  107. TicketSupported: shm.ticketSupported,
  108. SecureRenegotiation: shm.secureRenegotiation,
  109. SecureRenegotiationSupported: shm.secureRenegotiationSupported,
  110. AlpnProtocol: shm.alpnProtocol,
  111. }
  112. }
  113. }
  114. type ClientHelloMsg struct {
  115. Raw []byte
  116. Vers uint16
  117. Random []byte
  118. SessionId []byte
  119. CipherSuites []uint16
  120. CompressionMethods []uint8
  121. NextProtoNeg bool
  122. ServerName string
  123. OcspStapling bool
  124. Scts bool
  125. Ems bool
  126. SupportedCurves []CurveID
  127. SupportedPoints []uint8
  128. TicketSupported bool
  129. SessionTicket []uint8
  130. SignatureAndHashes []SignatureAndHash
  131. SecureRenegotiation []byte
  132. SecureRenegotiationSupported bool
  133. AlpnProtocols []string
  134. }
  135. func (chm *ClientHelloMsg) getPrivatePtr() *clientHelloMsg {
  136. if chm == nil {
  137. return nil
  138. } else {
  139. return &clientHelloMsg{
  140. raw: chm.Raw,
  141. vers: chm.Vers,
  142. random: chm.Random,
  143. sessionId: chm.SessionId,
  144. cipherSuites: chm.CipherSuites,
  145. compressionMethods: chm.CompressionMethods,
  146. nextProtoNeg: chm.NextProtoNeg,
  147. serverName: chm.ServerName,
  148. ocspStapling: chm.OcspStapling,
  149. scts: chm.Scts,
  150. ems: chm.Ems,
  151. supportedCurves: chm.SupportedCurves,
  152. supportedPoints: chm.SupportedPoints,
  153. ticketSupported: chm.TicketSupported,
  154. sessionTicket: chm.SessionTicket,
  155. signatureAndHashes: sigAndHashGetMakePrivate(chm.SignatureAndHashes),
  156. secureRenegotiation: chm.SecureRenegotiation,
  157. secureRenegotiationSupported: chm.SecureRenegotiationSupported,
  158. alpnProtocols: chm.AlpnProtocols,
  159. }
  160. }
  161. }
  162. func (chm *clientHelloMsg) getPublicPtr() *ClientHelloMsg {
  163. if chm == nil {
  164. return nil
  165. } else {
  166. return &ClientHelloMsg{
  167. Raw: chm.raw,
  168. Vers: chm.vers,
  169. Random: chm.random,
  170. SessionId: chm.sessionId,
  171. CipherSuites: chm.cipherSuites,
  172. CompressionMethods: chm.compressionMethods,
  173. NextProtoNeg: chm.nextProtoNeg,
  174. ServerName: chm.serverName,
  175. OcspStapling: chm.ocspStapling,
  176. Scts: chm.scts,
  177. Ems: chm.ems,
  178. SupportedCurves: chm.supportedCurves,
  179. SupportedPoints: chm.supportedPoints,
  180. TicketSupported: chm.ticketSupported,
  181. SessionTicket: chm.sessionTicket,
  182. SignatureAndHashes: sigAndHashMakePublic(chm.signatureAndHashes),
  183. SecureRenegotiation: chm.secureRenegotiation,
  184. SecureRenegotiationSupported: chm.secureRenegotiationSupported,
  185. AlpnProtocols: chm.alpnProtocols,
  186. }
  187. }
  188. }
  189. // SignatureAndHash mirrors the TLS 1.2, SignatureAndHashAlgorithm struct. See
  190. // RFC 5246, section A.4.1.
  191. type SignatureAndHash struct {
  192. Hash, Signature uint8
  193. }
  194. func sigAndHashGetMakePrivate(sahSlice []SignatureAndHash) []signatureAndHash {
  195. res := []signatureAndHash{}
  196. for _, sah := range sahSlice {
  197. res = append(res, signatureAndHash{hash: sah.Hash,
  198. signature: sah.Signature})
  199. }
  200. return res
  201. }
  202. func sigAndHashMakePublic(sahSlice []signatureAndHash) []SignatureAndHash {
  203. res := []SignatureAndHash{}
  204. for _, sah := range sahSlice {
  205. res = append(res, SignatureAndHash{Hash: sah.hash,
  206. Signature: sah.signature})
  207. }
  208. return res
  209. }
  210. // A CipherSuite is a specific combination of key agreement, cipher and MAC
  211. // function. All cipher suites currently assume RSA key agreement.
  212. type CipherSuite struct {
  213. Id uint16
  214. // the lengths, in bytes, of the key material needed for each component.
  215. KeyLen int
  216. MacLen int
  217. IvLen int
  218. Ka func(version uint16) keyAgreement
  219. // flags is a bitmask of the suite* values, above.
  220. Flags int
  221. Cipher func(key, iv []byte, isRead bool) interface{}
  222. Mac func(version uint16, macKey []byte) macFunction
  223. Aead func(key, fixedNonce []byte) cipher.AEAD
  224. }
  225. func (cs *CipherSuite) getPrivatePtr() *cipherSuite {
  226. if cs == nil {
  227. return nil
  228. } else {
  229. return &cipherSuite{
  230. id: cs.Id,
  231. keyLen: cs.KeyLen,
  232. macLen: cs.MacLen,
  233. ivLen: cs.IvLen,
  234. ka: cs.Ka,
  235. flags: cs.Flags,
  236. cipher: cs.Cipher,
  237. mac: cs.Mac,
  238. aead: cs.Aead,
  239. }
  240. }
  241. }
  242. func (cs *cipherSuite) getPublicPtr() *CipherSuite {
  243. if cs == nil {
  244. return nil
  245. } else {
  246. return &CipherSuite{
  247. Id: cs.id,
  248. KeyLen: cs.keyLen,
  249. MacLen: cs.macLen,
  250. IvLen: cs.ivLen,
  251. Ka: cs.ka,
  252. Flags: cs.flags,
  253. Cipher: cs.cipher,
  254. Mac: cs.mac,
  255. Aead: cs.aead,
  256. }
  257. }
  258. }
  259. // A FinishedHash calculates the hash of a set of handshake messages suitable
  260. // for including in a Finished message.
  261. type FinishedHash struct {
  262. Client hash.Hash
  263. Server hash.Hash
  264. // Prior to TLS 1.2, an additional MD5 hash is required.
  265. ClientMD5 hash.Hash
  266. ServerMD5 hash.Hash
  267. // In TLS 1.2, a full buffer is sadly required.
  268. Buffer []byte
  269. Version uint16
  270. Prf func(result, secret, label, seed []byte)
  271. }
  272. func (fh *FinishedHash) getPrivatePtr() *finishedHash {
  273. if fh == nil {
  274. return nil
  275. } else {
  276. return &finishedHash{
  277. client: fh.Client,
  278. server: fh.Server,
  279. clientMD5: fh.ClientMD5,
  280. serverMD5: fh.ServerMD5,
  281. buffer: fh.Buffer,
  282. version: fh.Version,
  283. prf: fh.Prf,
  284. }
  285. }
  286. }
  287. func (fh *finishedHash) getPublicPtr() *FinishedHash {
  288. if fh == nil {
  289. return nil
  290. } else {
  291. return &FinishedHash{
  292. Client: fh.client,
  293. Server: fh.server,
  294. ClientMD5: fh.clientMD5,
  295. ServerMD5: fh.serverMD5,
  296. Buffer: fh.buffer,
  297. Version: fh.version,
  298. Prf: fh.prf}
  299. }
  300. }
  301. // ClientSessionState is public, but all its fields are private. Let's add setters, getters and constructor
  302. // ClientSessionState contains the state needed by clients to resume TLS sessions.
  303. func MakeClientSessionState(
  304. SessionTicket []uint8,
  305. Vers uint16,
  306. CipherSuite uint16,
  307. MasterSecret []byte,
  308. ServerCertificates []*x509.Certificate,
  309. VerifiedChains [][]*x509.Certificate) *ClientSessionState {
  310. css := ClientSessionState{sessionTicket: SessionTicket,
  311. vers: Vers,
  312. cipherSuite: CipherSuite,
  313. masterSecret: MasterSecret,
  314. serverCertificates: ServerCertificates,
  315. verifiedChains: VerifiedChains}
  316. return &css
  317. }
  318. // Encrypted ticket used for session resumption with server
  319. func (css *ClientSessionState) SessionTicket() []uint8 {
  320. return css.sessionTicket
  321. }
  322. // SSL/TLS version negotiated for the session
  323. func (css *ClientSessionState) Vers() uint16 {
  324. return css.vers
  325. }
  326. // Ciphersuite negotiated for the session
  327. func (css *ClientSessionState) CipherSuite() uint16 {
  328. return css.cipherSuite
  329. }
  330. // MasterSecret generated by client on a full handshake
  331. func (css *ClientSessionState) MasterSecret() []byte {
  332. return css.masterSecret
  333. }
  334. // Certificate chain presented by the server
  335. func (css *ClientSessionState) ServerCertificates() []*x509.Certificate {
  336. return css.serverCertificates
  337. }
  338. // Certificate chains we built for verification
  339. func (css *ClientSessionState) VerifiedChains() [][]*x509.Certificate {
  340. return css.verifiedChains
  341. }
  342. func (css *ClientSessionState) SetSessionTicket(SessionTicket []uint8) {
  343. css.sessionTicket = SessionTicket
  344. }
  345. func (css *ClientSessionState) SetVers(Vers uint16) {
  346. css.vers = Vers
  347. }
  348. func (css *ClientSessionState) SetCipherSuite(CipherSuite uint16) {
  349. css.cipherSuite = CipherSuite
  350. }
  351. func (css *ClientSessionState) SetMasterSecret(MasterSecret []byte) {
  352. css.masterSecret = MasterSecret
  353. }
  354. func (css *ClientSessionState) SetServerCertificates(ServerCertificates []*x509.Certificate) {
  355. css.serverCertificates = ServerCertificates
  356. }
  357. func (css *ClientSessionState) SetVerifiedChains(VerifiedChains [][]*x509.Certificate) {
  358. css.verifiedChains = VerifiedChains
  359. }