summaryrefslogtreecommitdiff
path: root/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go')
-rw-r--r--vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go93
1 files changed, 93 insertions, 0 deletions
diff --git a/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go b/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go
new file mode 100644
index 0000000..f2017bc
--- /dev/null
+++ b/vendor/github.com/pion/dtls/v2/pkg/crypto/signaturehash/signaturehash.go
@@ -0,0 +1,93 @@
+// Package signaturehash provides the SignatureHashAlgorithm as defined in TLS 1.2
+package signaturehash
+
+import (
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "crypto/tls"
+
+ "github.com/pion/dtls/v2/pkg/crypto/hash"
+ "github.com/pion/dtls/v2/pkg/crypto/signature"
+ "golang.org/x/xerrors"
+)
+
+// 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 Algorithms() []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 SelectSignatureScheme(sigs []Algorithm, privateKey crypto.PrivateKey) (Algorithm, error) {
+ for _, ss := range sigs {
+ if ss.isCompatible(privateKey) {
+ return ss, nil
+ }
+ }
+ return Algorithm{}, errNoAvailableSignatureSchemes
+}
+
+// isCompatible checks that given private key is compatible with the signature scheme.
+func (a *Algorithm) isCompatible(privateKey crypto.PrivateKey) bool {
+ switch privateKey.(type) {
+ case ed25519.PrivateKey:
+ return a.Signature == signature.Ed25519
+ case *ecdsa.PrivateKey:
+ return a.Signature == signature.ECDSA
+ case *rsa.PrivateKey:
+ return a.Signature == signature.RSA
+ default:
+ return false
+ }
+}
+
+// ParseSignatureSchemes translates []tls.SignatureScheme to []signatureHashAlgorithm.
+// It returns default signature scheme list if no SignatureScheme is passed.
+func ParseSignatureSchemes(sigs []tls.SignatureScheme, insecureHashes bool) ([]Algorithm, error) {
+ if len(sigs) == 0 {
+ return Algorithms(), nil
+ }
+ out := []Algorithm{}
+ for _, ss := range sigs {
+ sig := signature.Algorithm(ss & 0xFF)
+ if _, ok := signature.Algorithms()[sig]; !ok {
+ return nil,
+ xerrors.Errorf("SignatureScheme %04x: %w", ss, errInvalidSignatureAlgorithm)
+ }
+ h := hash.Algorithm(ss >> 8)
+ if _, ok := hash.Algorithms()[h]; !ok || (ok && h == hash.None) {
+ return nil, xerrors.Errorf("SignatureScheme %04x: %w", ss, errInvalidHashAlgorithm)
+ }
+ if h.Insecure() && !insecureHashes {
+ continue
+ }
+ out = append(out, Algorithm{
+ Hash: h,
+ Signature: sig,
+ })
+ }
+
+ if len(out) == 0 {
+ return nil, errNoAvailableSignatureSchemes
+ }
+
+ return out, nil
+}