MCPcopy Index your code
hub / github.com/golang/crypto / pickSignatureAlgorithm

Function pickSignatureAlgorithm

ssh/client_auth.go:260–332  ·  view source on GitHub ↗
(signer Signer, extensions map[string][]byte)

Source from the content-addressed store, hash-verified

258}
259
260func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (MultiAlgorithmSigner, string, error) {
261 var as MultiAlgorithmSigner
262 keyFormat := signer.PublicKey().Type()
263
264 // If the signer implements MultiAlgorithmSigner we use the algorithms it
265 // support, if it implements AlgorithmSigner we assume it supports all
266 // algorithms, otherwise only the key format one.
267 switch s := signer.(type) {
268 case MultiAlgorithmSigner:
269 as = s
270 case AlgorithmSigner:
271 as = &multiAlgorithmSigner{
272 AlgorithmSigner: s,
273 supportedAlgorithms: algorithmsForKeyFormat(underlyingAlgo(keyFormat)),
274 }
275 default:
276 as = &multiAlgorithmSigner{
277 AlgorithmSigner: algorithmSignerWrapper{signer},
278 supportedAlgorithms: []string{underlyingAlgo(keyFormat)},
279 }
280 }
281
282 getFallbackAlgo := func() (string, error) {
283 // Fallback to use if there is no "server-sig-algs" extension or a
284 // common algorithm cannot be found. We use the public key format if the
285 // MultiAlgorithmSigner supports it, otherwise we return an error.
286 if !slices.Contains(as.Algorithms(), underlyingAlgo(keyFormat)) {
287 return "", fmt.Errorf("ssh: no common public key signature algorithm, server only supports %q for key type %q, signer only supports %v",
288 underlyingAlgo(keyFormat), keyFormat, as.Algorithms())
289 }
290 return keyFormat, nil
291 }
292
293 extPayload, ok := extensions["server-sig-algs"]
294 if !ok {
295 // If there is no "server-sig-algs" extension use the fallback
296 // algorithm.
297 algo, err := getFallbackAlgo()
298 return as, algo, err
299 }
300
301 // The server-sig-algs extension only carries underlying signature
302 // algorithm, but we are trying to select a protocol-level public key
303 // algorithm, which might be a certificate type. Extend the list of server
304 // supported algorithms to include the corresponding certificate algorithms.
305 serverAlgos := strings.Split(string(extPayload), ",")
306 for _, algo := range serverAlgos {
307 if certAlgo, ok := certificateAlgo(algo); ok {
308 serverAlgos = append(serverAlgos, certAlgo)
309 }
310 }
311
312 // Filter algorithms based on those supported by MultiAlgorithmSigner.
313 // Iterate over the signer's algorithms first to preserve its preference order.
314 supportedKeyAlgos := algorithmsForKeyFormat(keyFormat)
315 var keyAlgos []string
316 for _, signerAlgo := range as.Algorithms() {
317 if idx := slices.IndexFunc(supportedKeyAlgos, func(algo string) bool {

Callers 3

authMethod · 0.85

Calls 7

AlgorithmsMethod · 0.95
algorithmsForKeyFormatFunction · 0.85
certificateAlgoFunction · 0.85
findCommonFunction · 0.85
underlyingAlgoFunction · 0.70
TypeMethod · 0.65
PublicKeyMethod · 0.65

Used in the wild real call sites across dependent graphs

searching dependent graphs…