(config *Config, signCert, cipherCert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg)
| 171 | } |
| 172 | |
| 173 | func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, signCert, cipherCert *Certificate, |
| 174 | clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { |
| 175 | preferredCurves := config.curvePreferences() |
| 176 | |
| 177 | NextCandidate: |
| 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) |
nothing calls this directly
no test coverage detected