添加 github.com/pion/dtls 代码

This commit is contained in:
bjdgyc
2021-05-21 19:03:00 +08:00
parent 54a0cb7928
commit 28b5119f50
380 changed files with 16870 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
package signaturehash
import "errors"
var (
errNoAvailableSignatureSchemes = errors.New("connection can not be created, no SignatureScheme satisfy this Config")
errInvalidSignatureAlgorithm = errors.New("invalid signature algorithm")
errInvalidHashAlgorithm = errors.New("invalid hash algorithm")
)

View File

@@ -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
}

View File

@@ -0,0 +1,46 @@
// +build go1.13
package signaturehash
import (
"crypto/tls"
"reflect"
"testing"
"github.com/pion/dtls/v2/pkg/crypto/hash"
"github.com/pion/dtls/v2/pkg/crypto/signature"
"golang.org/x/xerrors"
)
func TestParseSignatureSchemes_Ed25519(t *testing.T) {
cases := map[string]struct {
input []tls.SignatureScheme
expected []Algorithm
err error
insecureHashes bool
}{
"Translate": {
input: []tls.SignatureScheme{
tls.Ed25519,
},
expected: []Algorithm{
{hash.Ed25519, signature.Ed25519},
},
err: nil,
insecureHashes: false,
},
}
for name, testCase := range cases {
testCase := testCase
t.Run(name, func(t *testing.T) {
output, err := ParseSignatureSchemes(testCase.input, testCase.insecureHashes)
if testCase.err != nil && !xerrors.Is(err, testCase.err) {
t.Fatalf("Expected error: %v, got: %v", testCase.err, err)
}
if !reflect.DeepEqual(testCase.expected, output) {
t.Errorf("Expected signatureHashAlgorithm:\n%+v\ngot:\n%+v", testCase.expected, output)
}
})
}
}

View File

@@ -0,0 +1,102 @@
package signaturehash
import (
"crypto/tls"
"reflect"
"testing"
"github.com/pion/dtls/v2/pkg/crypto/hash"
"github.com/pion/dtls/v2/pkg/crypto/signature"
"golang.org/x/xerrors"
)
func TestParseSignatureSchemes(t *testing.T) {
cases := map[string]struct {
input []tls.SignatureScheme
expected []Algorithm
err error
insecureHashes bool
}{
"Translate": {
input: []tls.SignatureScheme{
tls.ECDSAWithP256AndSHA256,
tls.ECDSAWithP384AndSHA384,
tls.ECDSAWithP521AndSHA512,
tls.PKCS1WithSHA256,
tls.PKCS1WithSHA384,
tls.PKCS1WithSHA512,
},
expected: []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},
},
insecureHashes: false,
err: nil,
},
"InvalidSignatureAlgorithm": {
input: []tls.SignatureScheme{
tls.ECDSAWithP256AndSHA256, // Valid
0x04FF, // Invalid: unknown signature with SHA-256
},
expected: nil,
insecureHashes: false,
err: errInvalidSignatureAlgorithm,
},
"InvalidHashAlgorithm": {
input: []tls.SignatureScheme{
tls.ECDSAWithP256AndSHA256, // Valid
0x0003, // Invalid: ECDSA with None
},
expected: nil,
insecureHashes: false,
err: errInvalidHashAlgorithm,
},
"InsecureHashAlgorithmDenied": {
input: []tls.SignatureScheme{
tls.ECDSAWithP256AndSHA256, // Valid
tls.ECDSAWithSHA1, // Insecure
},
expected: []Algorithm{
{hash.SHA256, signature.ECDSA},
},
insecureHashes: false,
err: nil,
},
"InsecureHashAlgorithmAllowed": {
input: []tls.SignatureScheme{
tls.ECDSAWithP256AndSHA256, // Valid
tls.ECDSAWithSHA1, // Insecure
},
expected: []Algorithm{
{hash.SHA256, signature.ECDSA},
{hash.SHA1, signature.ECDSA},
},
insecureHashes: true,
err: nil,
},
"OnlyInsecureHashAlgorithm": {
input: []tls.SignatureScheme{
tls.ECDSAWithSHA1, // Insecure
},
insecureHashes: false,
err: errNoAvailableSignatureSchemes,
},
}
for name, testCase := range cases {
testCase := testCase
t.Run(name, func(t *testing.T) {
output, err := ParseSignatureSchemes(testCase.input, testCase.insecureHashes)
if testCase.err != nil && !xerrors.Is(err, testCase.err) {
t.Fatalf("Expected error: %v, got: %v", testCase.err, err)
}
if !reflect.DeepEqual(testCase.expected, output) {
t.Errorf("Expected signatureHashAlgorithm:\n%+v\ngot:\n%+v", testCase.expected, output)
}
})
}
}