go tls源码阅读

tls 代码阅读

概览

分别从客户端和服务端角度,解决整个握手流程,基于go 1.16版本进行分析
重点:三个随机数:client hello随机数、server hello随机数、keyExchange 随机数
三个随机数生成后续使用对称算法减的密钥
客户端和服务端都是基于Conn进行操作的

客户端处理流程

概览

使用单独goroutine迁移处理tls
代码实现,handshake_client.go
入口:clientHandshake

  1. makeClientHello:
    • 支持版本
    • 支持的cipher suite
    • 随机数
    • 支持的算法
  2. loadSession:如果开启了session,客户端和服务端均开启
  3. 发送helloMsg,writeRecord(hello.marshal())
  4. 获取serverMsg
    • 读取serverHelloMsg
    • 处理serverHelloMsg
      • 确认cipher suite
      • server确认是否开启session
        如果开启,session没有过期
        • establishKeys
        • readSessionTicket
        • readFinished
        • sendFinished
  5. 如果session不存在,doFullHandshake,做全量握手
    • 读取certificateMsg
    • 读取certificateStatusMsg请求
      • 如果第一次握手,校验服务端证书verifyServerCertificate
    • 读取serverKeyExchangeMsg请求
      • processServerKeyExchange
    • 读取certificateRequestMsg
      • 如果请求存在,则发送客户端证书
    • 读取serverHelloDoneMsg请求
    • generateClientKeyExchange,创建客户端keyExchange
  6. establishKeys
    • 设置当前Conn的cipher suite
  7. sendFinished
  8. readSessionTicket,读取newSessionTicketMsg请求,
  9. 读取finishedMsg请求

服务端处理流程

概览

代码实现,handshake_server.go
入口:serverHandshake、serverHandshakeState

  1. readClientHello
    • 读取clientHelloMsg请求,决策使用什么tls版本
  2. handshake
    • serverHandshakeStateTLS13
    • serverHandshakeState
      • processClientHello
      • 是否resume session
    • pickCipherSuite:确认使用的cipher suite
    • doFullHandshake
      • writeRecord(serverHello)
      • writeRecord(certMsg)
      • writeRecord(certStatus)
      • generateServerKeyExchange
        • writeRecord(serverKeyExchangeMsg)
      • 如果校验客户端证书,writeRecord(certificateRequestMsg)
      • writeRecord(serverHelloDoneMsg)
      • 读取客户端请求certificateMsg
      • 读取客户端clientKeyExchangeMsg
      • processClientKeyExchange,获取masterSecret
      • 读取certificateVerifyMsg
    • establishKeys
    • readFinished
    • sendSessionTicket
    • sendFinished

session实现

概览

session需要客户端和服务端均开启,通过server加密ticket,返回给客户端
客户端使用lru算法,存储服务端ticket

实现

服务端:

type sessionState struct {
    vers         uint16
    cipherSuite  uint16
    createdAt    uint64
    masterSecret []byte // opaque master_secret<1..2^16-1>;
    // struct { opaque certificate<1..2^24-1> } Certificate;
    certificates [][]byte // Certificate certificate_list<0..2^24-1>;

    // usedOldKey is true if the ticket from which this session came from
    // was encrypted with an older key and thus should be refreshed.
    usedOldKey bool
}

客户端
存储lruSessionCache

type ClientSessionState struct {
    sessionTicket      []uint8               // Encrypted ticket used for session resumption with server
    vers               uint16                // TLS version negotiated for the session
    cipherSuite        uint16                // Ciphersuite negotiated for the session
    masterSecret       []byte                // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret
    serverCertificates []*x509.Certificate   // Certificate chain presented by the server
    verifiedChains     [][]*x509.Certificate // Certificate chains we built for verification
    receivedAt         time.Time             // When the session ticket was received from the server
    ocspResponse       []byte                // Stapled OCSP response presented by the server
    scts               [][]byte              // SCTs presented by the server

    // TLS 1.3 fields.
    nonce  []byte    // Ticket nonce sent by the server, to derive PSK
    useBy  time.Time // Expiration of the ticket lifetime as set by the server
    ageAdd uint32    // Random obfuscation factor for sending the ticket age
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值