// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT

// Package signaturehash provides the SignatureHashAlgorithm as defined in TLS 1.2
package signaturehash import ( ) // Algorithm is a signature/hash algorithm pairs which may be used in // digital signatures. // // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 type Algorithm struct { Hash hash.Algorithm Signature signature.Algorithm } // Algorithms are all the know SignatureHash Algorithms func () []Algorithm { return []Algorithm{ {hash.SHA256, signature.ECDSA}, {hash.SHA384, signature.ECDSA}, {hash.SHA512, signature.ECDSA}, {hash.SHA256, signature.RSA}, {hash.SHA384, signature.RSA}, {hash.SHA512, signature.RSA}, {hash.Ed25519, signature.Ed25519}, } } // SelectSignatureScheme returns most preferred and compatible scheme. func ( []Algorithm, crypto.PrivateKey) (Algorithm, error) { for , := range { if .isCompatible() { return , nil } } return Algorithm{}, errNoAvailableSignatureSchemes } // isCompatible checks that given private key is compatible with the signature scheme. func ( *Algorithm) ( crypto.PrivateKey) bool { switch .(type) { case ed25519.PrivateKey: return .Signature == signature.Ed25519 case *ecdsa.PrivateKey: return .Signature == signature.ECDSA case *rsa.PrivateKey: return .Signature == signature.RSA default: return false } } // ParseSignatureSchemes translates []tls.SignatureScheme to []signatureHashAlgorithm. // It returns default signature scheme list if no SignatureScheme is passed. func ( []tls.SignatureScheme, bool) ([]Algorithm, error) { if len() == 0 { return Algorithms(), nil } := []Algorithm{} for , := range { := signature.Algorithm( & 0xFF) if , := signature.Algorithms()[]; ! { return nil, fmt.Errorf("SignatureScheme %04x: %w", , errInvalidSignatureAlgorithm) } := hash.Algorithm( >> 8) if , := hash.Algorithms()[]; ! || ( && == hash.None) { return nil, fmt.Errorf("SignatureScheme %04x: %w", , errInvalidHashAlgorithm) } if .Insecure() && ! { continue } = append(, Algorithm{ Hash: , Signature: , }) } if len() == 0 { return nil, errNoAvailableSignatureSchemes } return , nil }