func ticketKeyFromBytes(b [32]byte) (key ticketKey) {
	hashed := sha512.Sum512(b[:])
	copy(key.keyName[:], hashed[:ticketKeyNameLen])
	copy(key.aesKey[:], hashed[ticketKeyNameLen:ticketKeyNameLen+16])
	copy(key.hmacKey[:], hashed[ticketKeyNameLen+16:ticketKeyNameLen+32])
	return key
}
ticketKeyFromBytes converts from the external representation of a session
ticket key to a ticketKey. Externally, session ticket keys are 32 random
bytes and this function expands that into sufficient name and key material.
package tls
import (
	"container/list"
	"crypto"
	"crypto/rand"
	"crypto/sha512"
	"crypto/x509"
	"errors"
	"fmt"
	"io"
	"math/big"
	"net"
	"strings"
	"sync"
	"time"
	"github.com/jmhodges/howsmyssl/tls110/cipherhw"
)
const (
	VersionSSL30 = 0x0300
	VersionTLS10 = 0x0301
	VersionTLS11 = 0x0302
	VersionTLS12 = 0x0303
)
const (
	maxPlaintext      = 16384         
	maxCiphertext     = 16384 + 2048  
	recordHeaderLen   = 5             
	maxHandshake      = 65536         
	maxWarnAlertCount = 5             
	minVersion = VersionTLS10
	maxVersion = VersionTLS12
)
type recordType uint8
const (
	recordTypeChangeCipherSpec recordType = 20
	recordTypeAlert            recordType = 21
	recordTypeHandshake        recordType = 22
	recordTypeApplicationData  recordType = 23
)
const (
	typeHelloRequest       uint8 = 0
	typeClientHello        uint8 = 1
	typeServerHello        uint8 = 2
	typeNewSessionTicket   uint8 = 4
	typeCertificate        uint8 = 11
	typeServerKeyExchange  uint8 = 12
	typeCertificateRequest uint8 = 13
	typeServerHelloDone    uint8 = 14
	typeCertificateVerify  uint8 = 15
	typeClientKeyExchange  uint8 = 16
	typeFinished           uint8 = 20
	typeCertificateStatus  uint8 = 22
	typeNextProtocol       uint8 = 67  
)
const (
	compressionNone uint8 = 0
)
const (
	extensionServerName          uint16 = 0
	extensionStatusRequest       uint16 = 5
	extensionSupportedCurves     uint16 = 10
	extensionSupportedPoints     uint16 = 11
	extensionSignatureAlgorithms uint16 = 13
	extensionALPN                uint16 = 16
	extensionSCT                 uint16 = 18  
	extensionSessionTicket       uint16 = 35
	extensionNextProtoNeg        uint16 = 13172  
	extensionRenegotiationInfo   uint16 = 0xff01
	extensionSupportedVersions uint16 = 43
)
const (
	scsvRenegotiation uint16 = 0x00ff
)
type CurveID uint16
const (
	CurveP256 CurveID = 23
	CurveP384 CurveID = 24
	CurveP521 CurveID = 25
	X25519    CurveID = 29
)
const (
	pointFormatUncompressed uint8 = 0
)
const (
	statusTypeOCSP uint8 = 1
)
const (
	certTypeRSASign    = 1  
	certTypeDSSSign    = 2  
	certTypeRSAFixedDH = 3  
	certTypeDSSFixedDH = 4  
	certTypeECDSASign      = 64  
	certTypeRSAFixedECDH   = 65  
	certTypeECDSAFixedECDH = 66  
)
const (
	signatureRSA   uint8 = 1
	signatureECDSA uint8 = 3
)
var supportedSignatureAlgorithms = []SignatureScheme{
	PKCS1WithSHA256,
	ECDSAWithP256AndSHA256,
	PKCS1WithSHA384,
	ECDSAWithP384AndSHA384,
	PKCS1WithSHA512,
	ECDSAWithP521AndSHA512,
	PKCS1WithSHA1,
	ECDSAWithSHA1,
}
type ConnectionState struct {
	Version                     uint16                 
	HandshakeComplete           bool                   
	DidResume                   bool                   
	CipherSuite                 uint16                 
	NegotiatedProtocol          string                 
	NegotiatedProtocolIsMutual  bool                   
	ServerName                  string                 
	PeerCertificates            []*x509.Certificate    
	VerifiedChains              [][]*x509.Certificate  
	SignedCertificateTimestamps [][]byte               
	OCSPResponse                []byte                 
	TLSUnique []byte
	ClientCipherSuites               []uint16
	CompressionMethods               []uint8
	NMinusOneRecordSplittingDetected bool
	AbleToDetectNMinusOneSplitting   bool
	SessionTicketsSupported          bool
	SupportedVersions                []uint16
}
type ClientAuthType int
const (
	NoClientCert ClientAuthType = iota
	RequestClientCert
	RequireAnyClientCert
	VerifyClientCertIfGiven
	RequireAndVerifyClientCert
)
type ClientSessionState struct {
	sessionTicket      []uint8                
	vers               uint16                 
	cipherSuite        uint16                 
	masterSecret       []byte                 
	serverCertificates []*x509.Certificate    
	verifiedChains     [][]*x509.Certificate  
}
type ClientSessionCache interface {
	Get(sessionKey string) (session *ClientSessionState, ok bool)
	Put(sessionKey string, cs *ClientSessionState)
}
type SignatureScheme uint16
const (
	PKCS1WithSHA1   SignatureScheme = 0x0201
	PKCS1WithSHA256 SignatureScheme = 0x0401
	PKCS1WithSHA384 SignatureScheme = 0x0501
	PKCS1WithSHA512 SignatureScheme = 0x0601
	PSSWithSHA256 SignatureScheme = 0x0804
	PSSWithSHA384 SignatureScheme = 0x0805
	PSSWithSHA512 SignatureScheme = 0x0806
	ECDSAWithP256AndSHA256 SignatureScheme = 0x0403
	ECDSAWithP384AndSHA384 SignatureScheme = 0x0503
	ECDSAWithP521AndSHA512 SignatureScheme = 0x0603
	ECDSAWithSHA1 SignatureScheme = 0x0203
)
type ClientHelloInfo struct {
	CipherSuites []uint16
	ServerName string
	SupportedCurves []CurveID
	SupportedPoints []uint8
	SignatureSchemes []SignatureScheme
	SupportedProtos []string
	SupportedVersions []uint16
	Conn net.Conn
}
type CertificateRequestInfo struct {
	AcceptableCAs [][]byte
	SignatureSchemes []SignatureScheme
}
type RenegotiationSupport int
const (
	RenegotiateNever RenegotiationSupport = iota
	RenegotiateOnceAsClient
	RenegotiateFreelyAsClient
)
type Config struct {
	Rand io.Reader
	Time func() time.Time
	Certificates []Certificate
	NameToCertificate map[string]*Certificate
	GetCertificate func(*ClientHelloInfo) (*Certificate, error)
	GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error)
	GetConfigForClient func(*ClientHelloInfo) (*Config, error)
	VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
	RootCAs *x509.CertPool
	NextProtos []string
	ServerName string
	ClientAuth ClientAuthType
	ClientCAs *x509.CertPool
	InsecureSkipVerify bool
	CipherSuites []uint16
	PreferServerCipherSuites bool
	SessionTicketsDisabled bool
	SessionTicketKey [32]byte
	ClientSessionCache ClientSessionCache
	MinVersion uint16
	MaxVersion uint16
	CurvePreferences []CurveID
	DynamicRecordSizingDisabled bool
	Renegotiation RenegotiationSupport
	KeyLogWriter io.Writer
	serverInitOnce sync.Once  
	mutex sync.RWMutex
	sessionTicketKeys []ticketKey
}
const ticketKeyNameLen = 16
type ticketKey struct {
	keyName [ticketKeyNameLen]byte
	aesKey  [16]byte
	hmacKey [16]byte
}