mirror of
https://github.com/bjdgyc/anylink.git
synced 2025-08-08 17:42:50 +08:00
添加 github.com/pion/dtls 代码
This commit is contained in:
50
dtls-2.0.9/pkg/crypto/fingerprint/fingerprint.go
Normal file
50
dtls-2.0.9/pkg/crypto/fingerprint/fingerprint.go
Normal file
@@ -0,0 +1,50 @@
|
||||
// Package fingerprint provides a helper to create fingerprint string from certificate
|
||||
package fingerprint
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
errHashUnavailable = errors.New("fingerprint: hash algorithm is not linked into the binary")
|
||||
errInvalidFingerprintLength = errors.New("fingerprint: invalid fingerprint length")
|
||||
)
|
||||
|
||||
// Fingerprint creates a fingerprint for a certificate using the specified hash algorithm
|
||||
func Fingerprint(cert *x509.Certificate, algo crypto.Hash) (string, error) {
|
||||
if !algo.Available() {
|
||||
return "", errHashUnavailable
|
||||
}
|
||||
h := algo.New()
|
||||
for i := 0; i < len(cert.Raw); {
|
||||
n, _ := h.Write(cert.Raw[i:])
|
||||
// Hash.Writer is specified to be never returning an error.
|
||||
// https://golang.org/pkg/hash/#Hash
|
||||
i += n
|
||||
}
|
||||
digest := []byte(fmt.Sprintf("%x", h.Sum(nil)))
|
||||
|
||||
digestlen := len(digest)
|
||||
if digestlen == 0 {
|
||||
return "", nil
|
||||
}
|
||||
if digestlen%2 != 0 {
|
||||
return "", errInvalidFingerprintLength
|
||||
}
|
||||
res := make([]byte, digestlen>>1+digestlen-1)
|
||||
|
||||
pos := 0
|
||||
for i, c := range digest {
|
||||
res[pos] = c
|
||||
pos++
|
||||
if (i)%2 != 0 && i < digestlen-1 {
|
||||
res[pos] = byte(':')
|
||||
pos++
|
||||
}
|
||||
}
|
||||
|
||||
return string(res), nil
|
||||
}
|
52
dtls-2.0.9/pkg/crypto/fingerprint/fingerprint_test.go
Normal file
52
dtls-2.0.9/pkg/crypto/fingerprint/fingerprint_test.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package fingerprint
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var errInvalidHashID = errors.New("invalid hash ID")
|
||||
|
||||
func TestFingerprint(t *testing.T) {
|
||||
rawCertificate := []byte{
|
||||
0x30, 0x82, 0x01, 0x98, 0x30, 0x82, 0x01, 0x3d, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x11, 0x00, 0xa9, 0x91, 0x76, 0x0a, 0xcd, 0x97, 0x4c, 0x36, 0xba,
|
||||
0xc9, 0xc2, 0x66, 0x91, 0x47, 0x6c, 0xac, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x27,
|
||||
0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x31, 0x31, 0x30, 0x30,
|
||||
0x39, 0x30, 0x34, 0x32, 0x33, 0x5a, 0x17, 0x0d, 0x31, 0x39, 0x31, 0x32, 0x31, 0x30, 0x30, 0x39, 0x30, 0x34, 0x32, 0x33, 0x5a, 0x30, 0x2b, 0x31, 0x29,
|
||||
0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48,
|
||||
0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x9c, 0x12, 0x8e, 0xb5, 0x21, 0x23, 0x9f,
|
||||
0x35, 0x5d, 0x39, 0x64, 0xc3, 0x75, 0x81, 0xa4, 0xc8, 0xc8, 0x08, 0x8a, 0xa8, 0x42, 0x30, 0x30, 0x65, 0xb8, 0xb1, 0x3e, 0x4a, 0x51, 0x86, 0xeb, 0xad,
|
||||
0x03, 0x02, 0x35, 0x83, 0xc4, 0x19, 0x3a, 0x5b, 0x79, 0x83, 0xec, 0x59, 0x0e, 0x4f, 0x99, 0xb1, 0xd2, 0xf0, 0x50, 0xfa, 0xb8, 0x5f, 0xfc, 0x88, 0xf3,
|
||||
0x15, 0xed, 0xb8, 0x14, 0xf0, 0xba, 0xcd, 0xa3, 0x42, 0x30, 0x40, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02,
|
||||
0x05, 0xa0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x08,
|
||||
0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff,
|
||||
0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xcd, 0x44, 0xb1, 0xf2, 0x09,
|
||||
0xe5, 0xf1, 0xf4, 0xc9, 0x26, 0x95, 0x9a, 0x2d, 0x6d, 0xf3, 0x0c, 0xb8, 0xeb, 0x27, 0x2d, 0x81, 0x19, 0xe9, 0x51, 0xf7, 0xad, 0x64, 0x7d, 0x42, 0x32,
|
||||
0x9e, 0xf8, 0x02, 0x21, 0x00, 0xee, 0xad, 0x96, 0x41, 0xf1, 0x12, 0xd0, 0x6b, 0xcd, 0x09, 0xf0, 0x3c, 0x67, 0xb3, 0xdd, 0xed, 0x0a, 0xf1, 0xd8, 0x41,
|
||||
0x4f, 0x61, 0xfd, 0x53, 0x1d, 0xf5, 0x27, 0xbe, 0x6d, 0x0b, 0xe2, 0x0d,
|
||||
}
|
||||
|
||||
cert, err := x509.ParseCertificate(rawCertificate)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
const expectedSHA256 = "60:ef:f5:79:ad:8d:3e:d7:e8:4d:5a:5a:d6:1e:71:2d:47:52:a5:cb:df:34:37:87:10:a5:4e:d7:2a:2c:37:34"
|
||||
actualSHA256, err := Fingerprint(cert, crypto.SHA256)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
} else if actualSHA256 != expectedSHA256 {
|
||||
t.Fatalf("Fingerprint SHA256 mismatch expected(%s) actual(%s)", expectedSHA256, actualSHA256)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFingerprint_UnavailableHash(t *testing.T) {
|
||||
_, err := Fingerprint(&x509.Certificate{}, crypto.Hash(0xFFFFFFFF))
|
||||
if !errors.Is(err, errHashUnavailable) {
|
||||
t.Errorf("%w: Expected error '%v' for invalid hash ID, got '%v'", errInvalidHashID, errHashUnavailable, err)
|
||||
}
|
||||
}
|
37
dtls-2.0.9/pkg/crypto/fingerprint/hash.go
Normal file
37
dtls-2.0.9/pkg/crypto/fingerprint/hash.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package fingerprint
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"errors"
|
||||
)
|
||||
|
||||
var errInvalidHashAlgorithm = errors.New("fingerprint: invalid hash algorithm")
|
||||
|
||||
func nameToHash() map[string]crypto.Hash {
|
||||
return map[string]crypto.Hash{
|
||||
"md5": crypto.MD5, // [RFC3279]
|
||||
"sha-1": crypto.SHA1, // [RFC3279]
|
||||
"sha-224": crypto.SHA224, // [RFC4055]
|
||||
"sha-256": crypto.SHA256, // [RFC4055]
|
||||
"sha-384": crypto.SHA384, // [RFC4055]
|
||||
"sha-512": crypto.SHA512, // [RFC4055]
|
||||
}
|
||||
}
|
||||
|
||||
// HashFromString allows looking up a hash algorithm by it's string representation
|
||||
func HashFromString(s string) (crypto.Hash, error) {
|
||||
if h, ok := nameToHash()[s]; ok {
|
||||
return h, nil
|
||||
}
|
||||
return 0, errInvalidHashAlgorithm
|
||||
}
|
||||
|
||||
// StringFromHash allows looking up a string representation of the crypto.Hash.
|
||||
func StringFromHash(hash crypto.Hash) (string, error) {
|
||||
for s, h := range nameToHash() {
|
||||
if h == hash {
|
||||
return s, nil
|
||||
}
|
||||
}
|
||||
return "", errInvalidHashAlgorithm
|
||||
}
|
41
dtls-2.0.9/pkg/crypto/fingerprint/hash_test.go
Normal file
41
dtls-2.0.9/pkg/crypto/fingerprint/hash_test.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package fingerprint
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"errors"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHashFromString(t *testing.T) {
|
||||
t.Run("InvalidHashAlgorithm", func(t *testing.T) {
|
||||
_, err := HashFromString("invalid-hash-algorithm")
|
||||
if !errors.Is(err, errInvalidHashAlgorithm) {
|
||||
t.Errorf("Expected error '%v' for invalid hash name, got '%v'", errInvalidHashAlgorithm, err)
|
||||
}
|
||||
})
|
||||
t.Run("ValidHashAlgorithm", func(t *testing.T) {
|
||||
h, err := HashFromString("sha-512")
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error for valid hash name, got '%v'", err)
|
||||
}
|
||||
if h != crypto.SHA512 {
|
||||
t.Errorf("Expected hash ID of %d, got %d", int(crypto.SHA512), int(h))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestStringFromHash_Roundtrip(t *testing.T) {
|
||||
for _, h := range nameToHash() {
|
||||
s, err := StringFromHash(h)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error for valid hash algorithm, got '%v'", err)
|
||||
}
|
||||
h2, err := HashFromString(s)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error for valid hash name, got '%v'", err)
|
||||
}
|
||||
if h != h2 {
|
||||
t.Errorf("Hash value doesn't match, expected: 0x%x, got 0x%x", h, h2)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user