MCPcopy
hub / github.com/tjfoc/gmsm / generateServerKeyExchange

Method generateServerKeyExchange

gmtls/key_agreement.go:173–270  ·  view source on GitHub ↗
(config *Config, signCert, cipherCert *Certificate,
	clientHello *clientHelloMsg, hello *serverHelloMsg)

Source from the content-addressed store, hash-verified

171}
172
173func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, signCert, cipherCert *Certificate,
174 clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
175 preferredCurves := config.curvePreferences()
176
177NextCandidate:
178 for _, candidate := range preferredCurves {
179 for _, c := range clientHello.supportedCurves {
180 if candidate == c {
181 ka.curveid = c
182 break NextCandidate
183 }
184 }
185 }
186
187 if ka.curveid == 0 {
188 return nil, errors.New("tls: no supported elliptic curves offered")
189 }
190
191 var ecdhePublic []byte
192
193 if ka.curveid == X25519 {
194 var scalar, public [32]byte
195 if _, err := io.ReadFull(config.rand(), scalar[:]); err != nil {
196 return nil, err
197 }
198
199 curve25519.ScalarBaseMult(&public, &scalar)
200 ka.privateKey = scalar[:]
201 ecdhePublic = public[:]
202 } else {
203 curve, ok := curveForCurveID(ka.curveid)
204 if !ok {
205 return nil, errors.New("tls: preferredCurves includes unsupported curve")
206 }
207
208 var x, y *big.Int
209 var err error
210 ka.privateKey, x, y, err = elliptic.GenerateKey(curve, config.rand())
211 if err != nil {
212 return nil, err
213 }
214 ecdhePublic = elliptic.Marshal(curve, x, y)
215 }
216
217 // https://tools.ietf.org/html/rfc4492#section-5.4
218 serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic))
219 serverECDHParams[0] = 3 // named curve
220 serverECDHParams[1] = byte(ka.curveid >> 8)
221 serverECDHParams[2] = byte(ka.curveid)
222 serverECDHParams[3] = byte(len(ecdhePublic))
223 copy(serverECDHParams[4:], ecdhePublic)
224
225 priv, ok := signCert.PrivateKey.(crypto.Signer)
226 if !ok {
227 return nil, errors.New("tls: certificate private key does not implement crypto.Signer")
228 }
229
230 signatureAlgorithm, sigType, hashFunc, err := pickSignatureAlgorithm(priv.Public(), clientHello.supportedSignatureAlgorithms, supportedSignatureAlgorithms, ka.version)

Callers

nothing calls this directly

Calls 10

curveForCurveIDFunction · 0.85
pickSignatureAlgorithmFunction · 0.85
hashForServerKeyExchangeFunction · 0.85
curvePreferencesMethod · 0.80
NewMethod · 0.80
randMethod · 0.80
ScalarBaseMultMethod · 0.80
PublicMethod · 0.80
SignMethod · 0.80
ErrorMethod · 0.45

Tested by

no test coverage detected