(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg)
| 168 | } |
| 169 | |
| 170 | func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { |
| 171 | var curveID CurveID |
| 172 | for _, c := range clientHello.supportedCurves { |
| 173 | if config.supportsCurve(ka.version, c) { |
| 174 | curveID = c |
| 175 | break |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | if curveID == 0 { |
| 180 | return nil, errors.New("tls: no supported elliptic curves offered") |
| 181 | } |
| 182 | if _, ok := curveForCurveID(curveID); !ok { |
| 183 | return nil, errors.New("tls: CurvePreferences includes unsupported curve") |
| 184 | } |
| 185 | |
| 186 | key, err := generateECDHEKey(config.rand(), curveID) |
| 187 | if err != nil { |
| 188 | return nil, err |
| 189 | } |
| 190 | ka.key = key |
| 191 | |
| 192 | // See RFC 4492, Section 5.4. |
| 193 | ecdhePublic := key.PublicKey().Bytes() |
| 194 | serverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic)) |
| 195 | serverECDHEParams[0] = 3 // named curve |
| 196 | serverECDHEParams[1] = byte(curveID >> 8) |
| 197 | serverECDHEParams[2] = byte(curveID) |
| 198 | serverECDHEParams[3] = byte(len(ecdhePublic)) |
| 199 | copy(serverECDHEParams[4:], ecdhePublic) |
| 200 | |
| 201 | priv, ok := cert.PrivateKey.(crypto.Signer) |
| 202 | if !ok { |
| 203 | return nil, fmt.Errorf("tls: certificate private key of type %T does not implement crypto.Signer", cert.PrivateKey) |
| 204 | } |
| 205 | |
| 206 | var signatureAlgorithm SignatureScheme |
| 207 | var sigType uint8 |
| 208 | var sigHash crypto.Hash |
| 209 | if ka.version >= VersionTLS12 { |
| 210 | signatureAlgorithm, err = selectSignatureScheme(ka.version, cert, clientHello.supportedSignatureAlgorithms) |
| 211 | if err != nil { |
| 212 | return nil, err |
| 213 | } |
| 214 | sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm) |
| 215 | if err != nil { |
| 216 | return nil, err |
| 217 | } |
| 218 | } else { |
| 219 | sigType, sigHash, err = legacyTypeAndHashFromPublicKey(priv.Public()) |
| 220 | if err != nil { |
| 221 | return nil, err |
| 222 | } |
| 223 | } |
| 224 | if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA { |
| 225 | return nil, errors.New("tls: certificate cannot be used with the selected cipher suite") |
| 226 | } |
| 227 |
nothing calls this directly
no test coverage detected