mirror of
https://github.com/bjdgyc/anylink.git
synced 2025-08-08 08:22:26 +08:00
添加 github.com/pion/dtls 代码
This commit is contained in:
26
dtls-2.0.9/examples/certificates/README.md
Normal file
26
dtls-2.0.9/examples/certificates/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Certificates
|
||||
|
||||
The certificates in for the examples are generated using the commands shown below.
|
||||
|
||||
Note that this was run on OpenSSL 1.1.1d, of which the arguments can be found in the [OpenSSL Manpages](https://www.openssl.org/docs/man1.1.1/man1), and is not guaranteed to work on different OpenSSL versions.
|
||||
|
||||
```shell
|
||||
# Extensions required for certificate validation.
|
||||
$ EXTFILE='extfile.conf'
|
||||
$ echo 'subjectAltName = IP:127.0.0.1\nbasicConstraints = critical,CA:true' > "${EXTFILE}"
|
||||
|
||||
# Server.
|
||||
$ SERVER_NAME='server'
|
||||
$ openssl ecparam -name prime256v1 -genkey -noout -out "${SERVER_NAME}.pem"
|
||||
$ openssl req -key "${SERVER_NAME}.pem" -new -sha256 -subj '/C=NL' -out "${SERVER_NAME}.csr"
|
||||
$ openssl x509 -req -in "${SERVER_NAME}.csr" -extfile "${EXTFILE}" -days 365 -signkey "${SERVER_NAME}.pem" -sha256 -out "${SERVER_NAME}.pub.pem"
|
||||
|
||||
# Client.
|
||||
$ CLIENT_NAME='client'
|
||||
$ openssl ecparam -name prime256v1 -genkey -noout -out "${CLIENT_NAME}.pem"
|
||||
$ openssl req -key "${CLIENT_NAME}.pem" -new -sha256 -subj '/C=NL' -out "${CLIENT_NAME}.csr"
|
||||
$ openssl x509 -req -in "${CLIENT_NAME}.csr" -extfile "${EXTFILE}" -days 365 -CA "${SERVER_NAME}.pub.pem" -CAkey "${SERVER_NAME}.pem" -set_serial '0xabcd' -sha256 -out "${CLIENT_NAME}.pub.pem"
|
||||
|
||||
# Cleanup.
|
||||
$ rm "${EXTFILE}" "${SERVER_NAME}.csr" "${CLIENT_NAME}.csr"
|
||||
```
|
5
dtls-2.0.9/examples/certificates/client.pem
Normal file
5
dtls-2.0.9/examples/certificates/client.pem
Normal file
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIGOO78dEAcepxdUIeDzC28jMcFrJr2q7x+UdhgtJ/RS3oAoGCCqGSM49
|
||||
AwEHoUQDQgAEGLSNxlkJ9mETKI2Hogq3Cyh06pJKA1YMgcKqYKS6yQQlvvk5rU88
|
||||
+RojFPgXJukymhfIJmw4eGxxEMSjuEZY7w==
|
||||
-----END EC PRIVATE KEY-----
|
9
dtls-2.0.9/examples/certificates/client.pub.pem
Normal file
9
dtls-2.0.9/examples/certificates/client.pub.pem
Normal file
@@ -0,0 +1,9 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBLTCB1aADAgECAgMAq80wCgYIKoZIzj0EAwIwDTELMAkGA1UEBhMCTkwwHhcN
|
||||
MjAwMzIwMDk0NjQ0WhcNMjEwMzIwMDk0NjQ0WjANMQswCQYDVQQGEwJOTDBZMBMG
|
||||
ByqGSM49AgEGCCqGSM49AwEHA0IABBi0jcZZCfZhEyiNh6IKtwsodOqSSgNWDIHC
|
||||
qmCkuskEJb75Oa1PPPkaIxT4FybpMpoXyCZsOHhscRDEo7hGWO+jJDAiMA8GA1Ud
|
||||
EQQIMAaHBH8AAAEwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAgNHADBEAiBx
|
||||
sIkcADN9E60veZOFOeANaRWAiQaLWZfUxqkOmfHztQIgI2CfHMjDQwJZFh35HvFs
|
||||
NOPJj8wxFhqR5pqMF23cgOY=
|
||||
-----END CERTIFICATE-----
|
5
dtls-2.0.9/examples/certificates/server.pem
Normal file
5
dtls-2.0.9/examples/certificates/server.pem
Normal file
@@ -0,0 +1,5 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIDT8Xyx5RpPP+98ulYZKsvKIVdBUJug/L9H2M8JThv+GoAoGCCqGSM49
|
||||
AwEHoUQDQgAE6Wf0qQqIb5G7g51P83Dh1Yst52kyntGYz1Bt6S7crpmQFs9ZRZMy
|
||||
bJ6MGIwGcVBMgoL3pfxDKdZ3mnzmoibU0w==
|
||||
-----END EC PRIVATE KEY-----
|
9
dtls-2.0.9/examples/certificates/server.pub.pem
Normal file
9
dtls-2.0.9/examples/certificates/server.pub.pem
Normal file
@@ -0,0 +1,9 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBPzCB5qADAgECAhRtzyVTL+9D0KHfbcKYeKckpLVRmTAKBggqhkjOPQQDAjAN
|
||||
MQswCQYDVQQGEwJOTDAeFw0yMDAzMjAwOTQ2NDRaFw0yMTAzMjAwOTQ2NDRaMA0x
|
||||
CzAJBgNVBAYTAk5MMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6Wf0qQqIb5G7
|
||||
g51P83Dh1Yst52kyntGYz1Bt6S7crpmQFs9ZRZMybJ6MGIwGcVBMgoL3pfxDKdZ3
|
||||
mnzmoibU06MkMCIwDwYDVR0RBAgwBocEfwAAATAPBgNVHRMBAf8EBTADAQH/MAoG
|
||||
CCqGSM49BAMCA0gAMEUCIQD000SU+klkNLGvHZcMYNVkCFsImnGKIqPMy3LELSiF
|
||||
0gIgSGIFkNEIAyNxn44CXZJu3piyz1ouK2fLefDJMYfcXgM=
|
||||
-----END CERTIFICATE-----
|
45
dtls-2.0.9/examples/dial/psk/main.go
Normal file
45
dtls-2.0.9/examples/dial/psk/main.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/pion/dtls/v2"
|
||||
"github.com/pion/dtls/v2/examples/util"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Prepare the IP to connect to
|
||||
addr := &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 4444}
|
||||
|
||||
//
|
||||
// Everything below is the pion-DTLS API! Thanks for using it ❤️.
|
||||
//
|
||||
|
||||
// Prepare the configuration of the DTLS connection
|
||||
config := &dtls.Config{
|
||||
PSK: func(hint []byte) ([]byte, error) {
|
||||
fmt.Printf("Server's hint: %s \n", hint)
|
||||
return []byte{0xAB, 0xC1, 0x23}, nil
|
||||
},
|
||||
PSKIdentityHint: []byte("Pion DTLS Server"),
|
||||
CipherSuites: []dtls.CipherSuiteID{dtls.TLS_PSK_WITH_AES_128_CCM_8},
|
||||
ExtendedMasterSecret: dtls.RequireExtendedMasterSecret,
|
||||
}
|
||||
|
||||
// Connect to a DTLS server
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
dtlsConn, err := dtls.DialWithContext(ctx, "udp", addr, config)
|
||||
util.Check(err)
|
||||
defer func() {
|
||||
util.Check(dtlsConn.Close())
|
||||
}()
|
||||
|
||||
fmt.Println("Connected; type 'exit' to shutdown gracefully")
|
||||
|
||||
// Simulate a chat session
|
||||
util.Chat(dtlsConn)
|
||||
}
|
47
dtls-2.0.9/examples/dial/selfsign/main.go
Normal file
47
dtls-2.0.9/examples/dial/selfsign/main.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/pion/dtls/v2"
|
||||
"github.com/pion/dtls/v2/examples/util"
|
||||
"github.com/pion/dtls/v2/pkg/crypto/selfsign"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Prepare the IP to connect to
|
||||
addr := &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 4444}
|
||||
|
||||
// Generate a certificate and private key to secure the connection
|
||||
certificate, genErr := selfsign.GenerateSelfSigned()
|
||||
util.Check(genErr)
|
||||
|
||||
//
|
||||
// Everything below is the pion-DTLS API! Thanks for using it ❤️.
|
||||
//
|
||||
|
||||
// Prepare the configuration of the DTLS connection
|
||||
config := &dtls.Config{
|
||||
Certificates: []tls.Certificate{certificate},
|
||||
InsecureSkipVerify: true,
|
||||
ExtendedMasterSecret: dtls.RequireExtendedMasterSecret,
|
||||
}
|
||||
|
||||
// Connect to a DTLS server
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
dtlsConn, err := dtls.DialWithContext(ctx, "udp", addr, config)
|
||||
util.Check(err)
|
||||
defer func() {
|
||||
util.Check(dtlsConn.Close())
|
||||
}()
|
||||
|
||||
fmt.Println("Connected; type 'exit' to shutdown gracefully")
|
||||
|
||||
// Simulate a chat session
|
||||
util.Chat(dtlsConn)
|
||||
}
|
54
dtls-2.0.9/examples/dial/verify/main.go
Normal file
54
dtls-2.0.9/examples/dial/verify/main.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/pion/dtls/v2"
|
||||
"github.com/pion/dtls/v2/examples/util"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Prepare the IP to connect to
|
||||
addr := &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 4444}
|
||||
|
||||
//
|
||||
// Everything below is the pion-DTLS API! Thanks for using it ❤️.
|
||||
//
|
||||
|
||||
certificate, err := util.LoadKeyAndCertificate("examples/certificates/client.pem",
|
||||
"examples/certificates/client.pub.pem")
|
||||
util.Check(err)
|
||||
|
||||
rootCertificate, err := util.LoadCertificate("examples/certificates/server.pub.pem")
|
||||
util.Check(err)
|
||||
certPool := x509.NewCertPool()
|
||||
cert, err := x509.ParseCertificate(rootCertificate.Certificate[0])
|
||||
util.Check(err)
|
||||
certPool.AddCert(cert)
|
||||
|
||||
// Prepare the configuration of the DTLS connection
|
||||
config := &dtls.Config{
|
||||
Certificates: []tls.Certificate{*certificate},
|
||||
ExtendedMasterSecret: dtls.RequireExtendedMasterSecret,
|
||||
RootCAs: certPool,
|
||||
}
|
||||
|
||||
// Connect to a DTLS server
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
dtlsConn, err := dtls.DialWithContext(ctx, "udp", addr, config)
|
||||
util.Check(err)
|
||||
defer func() {
|
||||
util.Check(dtlsConn.Close())
|
||||
}()
|
||||
|
||||
fmt.Println("Connected; type 'exit' to shutdown gracefully")
|
||||
|
||||
// Simulate a chat session
|
||||
util.Chat(dtlsConn)
|
||||
}
|
72
dtls-2.0.9/examples/listen/psk/main.go
Normal file
72
dtls-2.0.9/examples/listen/psk/main.go
Normal file
@@ -0,0 +1,72 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/pion/dtls/v2"
|
||||
"github.com/pion/dtls/v2/examples/util"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Prepare the IP to connect to
|
||||
addr := &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 4444}
|
||||
|
||||
// Create parent context to cleanup handshaking connections on exit.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
//
|
||||
// Everything below is the pion-DTLS API! Thanks for using it ❤️.
|
||||
//
|
||||
|
||||
// Prepare the configuration of the DTLS connection
|
||||
config := &dtls.Config{
|
||||
PSK: func(hint []byte) ([]byte, error) {
|
||||
fmt.Printf("Client's hint: %s \n", hint)
|
||||
return []byte{0xAB, 0xC1, 0x23}, nil
|
||||
},
|
||||
PSKIdentityHint: []byte("Pion DTLS Client"),
|
||||
CipherSuites: []dtls.CipherSuiteID{dtls.TLS_PSK_WITH_AES_128_CCM_8},
|
||||
ExtendedMasterSecret: dtls.RequireExtendedMasterSecret,
|
||||
// Create timeout context for accepted connection.
|
||||
ConnectContextMaker: func() (context.Context, func()) {
|
||||
return context.WithTimeout(ctx, 30*time.Second)
|
||||
},
|
||||
}
|
||||
|
||||
// Connect to a DTLS server
|
||||
listener, err := dtls.Listen("udp", addr, config)
|
||||
util.Check(err)
|
||||
defer func() {
|
||||
util.Check(listener.Close())
|
||||
}()
|
||||
|
||||
fmt.Println("Listening")
|
||||
|
||||
// Simulate a chat session
|
||||
hub := util.NewHub()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
// Wait for a connection.
|
||||
conn, err := listener.Accept()
|
||||
util.Check(err)
|
||||
// defer conn.Close() // TODO: graceful shutdown
|
||||
|
||||
// `conn` is of type `net.Conn` but may be casted to `dtls.Conn`
|
||||
// using `dtlsConn := conn.(*dtls.Conn)` in order to to expose
|
||||
// functions like `ConnectionState` etc.
|
||||
|
||||
// Register the connection with the chat hub
|
||||
if err == nil {
|
||||
hub.Register(conn)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Start chatting
|
||||
hub.Chat()
|
||||
}
|
73
dtls-2.0.9/examples/listen/selfsign/main.go
Normal file
73
dtls-2.0.9/examples/listen/selfsign/main.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/pion/dtls/v2"
|
||||
"github.com/pion/dtls/v2/examples/util"
|
||||
"github.com/pion/dtls/v2/pkg/crypto/selfsign"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Prepare the IP to connect to
|
||||
addr := &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 4444}
|
||||
|
||||
// Generate a certificate and private key to secure the connection
|
||||
certificate, genErr := selfsign.GenerateSelfSigned()
|
||||
util.Check(genErr)
|
||||
|
||||
// Create parent context to cleanup handshaking connections on exit.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
//
|
||||
// Everything below is the pion-DTLS API! Thanks for using it ❤️.
|
||||
//
|
||||
|
||||
// Prepare the configuration of the DTLS connection
|
||||
config := &dtls.Config{
|
||||
Certificates: []tls.Certificate{certificate},
|
||||
ExtendedMasterSecret: dtls.RequireExtendedMasterSecret,
|
||||
// Create timeout context for accepted connection.
|
||||
ConnectContextMaker: func() (context.Context, func()) {
|
||||
return context.WithTimeout(ctx, 30*time.Second)
|
||||
},
|
||||
}
|
||||
|
||||
// Connect to a DTLS server
|
||||
listener, err := dtls.Listen("udp", addr, config)
|
||||
util.Check(err)
|
||||
defer func() {
|
||||
util.Check(listener.Close())
|
||||
}()
|
||||
|
||||
fmt.Println("Listening")
|
||||
|
||||
// Simulate a chat session
|
||||
hub := util.NewHub()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
// Wait for a connection.
|
||||
conn, err := listener.Accept()
|
||||
util.Check(err)
|
||||
// defer conn.Close() // TODO: graceful shutdown
|
||||
|
||||
// `conn` is of type `net.Conn` but may be casted to `dtls.Conn`
|
||||
// using `dtlsConn := conn.(*dtls.Conn)` in order to to expose
|
||||
// functions like `ConnectionState` etc.
|
||||
|
||||
// Register the connection with the chat hub
|
||||
if err == nil {
|
||||
hub.Register(conn)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Start chatting
|
||||
hub.Chat()
|
||||
}
|
80
dtls-2.0.9/examples/listen/verify/main.go
Normal file
80
dtls-2.0.9/examples/listen/verify/main.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/pion/dtls/v2"
|
||||
"github.com/pion/dtls/v2/examples/util"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Prepare the IP to connect to
|
||||
addr := &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 4444}
|
||||
|
||||
// Create parent context to cleanup handshaking connections on exit.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
//
|
||||
// Everything below is the pion-DTLS API! Thanks for using it ❤️.
|
||||
//
|
||||
|
||||
certificate, err := util.LoadKeyAndCertificate("examples/certificates/server.pem",
|
||||
"examples/certificates/server.pub.pem")
|
||||
util.Check(err)
|
||||
|
||||
rootCertificate, err := util.LoadCertificate("examples/certificates/server.pub.pem")
|
||||
util.Check(err)
|
||||
certPool := x509.NewCertPool()
|
||||
cert, err := x509.ParseCertificate(rootCertificate.Certificate[0])
|
||||
util.Check(err)
|
||||
certPool.AddCert(cert)
|
||||
|
||||
// Prepare the configuration of the DTLS connection
|
||||
config := &dtls.Config{
|
||||
Certificates: []tls.Certificate{*certificate},
|
||||
ExtendedMasterSecret: dtls.RequireExtendedMasterSecret,
|
||||
ClientAuth: dtls.RequireAndVerifyClientCert,
|
||||
ClientCAs: certPool,
|
||||
// Create timeout context for accepted connection.
|
||||
ConnectContextMaker: func() (context.Context, func()) {
|
||||
return context.WithTimeout(ctx, 30*time.Second)
|
||||
},
|
||||
}
|
||||
|
||||
// Connect to a DTLS server
|
||||
listener, err := dtls.Listen("udp", addr, config)
|
||||
util.Check(err)
|
||||
defer func() {
|
||||
util.Check(listener.Close())
|
||||
}()
|
||||
|
||||
fmt.Println("Listening")
|
||||
|
||||
// Simulate a chat session
|
||||
hub := util.NewHub()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
// Wait for a connection.
|
||||
conn, err := listener.Accept()
|
||||
util.Check(err)
|
||||
// defer conn.Close() // TODO: graceful shutdown
|
||||
|
||||
// `conn` is of type `net.Conn` but may be casted to `dtls.Conn`
|
||||
// using `dtlsConn := conn.(*dtls.Conn)` in order to to expose
|
||||
// functions like `ConnectionState` etc.
|
||||
|
||||
// Register the connection with the chat hub
|
||||
hub.Register(conn)
|
||||
}
|
||||
}()
|
||||
|
||||
// Start chatting
|
||||
hub.Chat()
|
||||
}
|
80
dtls-2.0.9/examples/util/hub.go
Normal file
80
dtls-2.0.9/examples/util/hub.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Hub is a helper to handle one to many chat
|
||||
type Hub struct {
|
||||
conns map[string]net.Conn
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
// NewHub builds a new hub
|
||||
func NewHub() *Hub {
|
||||
return &Hub{conns: make(map[string]net.Conn)}
|
||||
}
|
||||
|
||||
// Register adds a new conn to the Hub
|
||||
func (h *Hub) Register(conn net.Conn) {
|
||||
fmt.Printf("Connected to %s\n", conn.RemoteAddr())
|
||||
h.lock.Lock()
|
||||
defer h.lock.Unlock()
|
||||
|
||||
h.conns[conn.RemoteAddr().String()] = conn
|
||||
|
||||
go h.readLoop(conn)
|
||||
}
|
||||
|
||||
func (h *Hub) readLoop(conn net.Conn) {
|
||||
b := make([]byte, bufSize)
|
||||
for {
|
||||
n, err := conn.Read(b)
|
||||
if err != nil {
|
||||
h.unregister(conn)
|
||||
return
|
||||
}
|
||||
fmt.Printf("Got message: %s\n", string(b[:n]))
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Hub) unregister(conn net.Conn) {
|
||||
h.lock.Lock()
|
||||
defer h.lock.Unlock()
|
||||
delete(h.conns, conn.RemoteAddr().String())
|
||||
err := conn.Close()
|
||||
if err != nil {
|
||||
fmt.Println("Failed to disconnect", conn.RemoteAddr(), err)
|
||||
} else {
|
||||
fmt.Println("Disconnected ", conn.RemoteAddr())
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Hub) broadcast(msg []byte) {
|
||||
h.lock.RLock()
|
||||
defer h.lock.RUnlock()
|
||||
for _, conn := range h.conns {
|
||||
_, err := conn.Write(msg)
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to write message to %s: %v\n", conn.RemoteAddr(), err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Chat starts the stdin readloop to dispatch messages to the hub
|
||||
func (h *Hub) Chat() {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
for {
|
||||
msg, err := reader.ReadString('\n')
|
||||
Check(err)
|
||||
if strings.TrimSpace(msg) == "exit" {
|
||||
return
|
||||
}
|
||||
h.broadcast([]byte(msg))
|
||||
}
|
||||
}
|
154
dtls-2.0.9/examples/util/util.go
Normal file
154
dtls-2.0.9/examples/util/util.go
Normal file
@@ -0,0 +1,154 @@
|
||||
// Package util provides auxiliary utilities used in examples
|
||||
package util
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const bufSize = 8192
|
||||
|
||||
var (
|
||||
errBlockIsNotPrivateKey = errors.New("block is not a private key, unable to load key")
|
||||
errUnknownKeyTime = errors.New("unknown key time in PKCS#8 wrapping, unable to load key")
|
||||
errNoPrivateKeyFound = errors.New("no private key found, unable to load key")
|
||||
errBlockIsNotCertificate = errors.New("block is not a certificate, unable to load certificates")
|
||||
errNoCertificateFound = errors.New("no certificate found, unable to load certificates")
|
||||
)
|
||||
|
||||
// Chat simulates a simple text chat session over the connection
|
||||
func Chat(conn io.ReadWriter) {
|
||||
go func() {
|
||||
b := make([]byte, bufSize)
|
||||
|
||||
for {
|
||||
n, err := conn.Read(b)
|
||||
Check(err)
|
||||
fmt.Printf("Got message: %s\n", string(b[:n]))
|
||||
}
|
||||
}()
|
||||
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
for {
|
||||
text, err := reader.ReadString('\n')
|
||||
Check(err)
|
||||
|
||||
if strings.TrimSpace(text) == "exit" {
|
||||
return
|
||||
}
|
||||
|
||||
_, err = conn.Write([]byte(text))
|
||||
Check(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Check is a helper to throw errors in the examples
|
||||
func Check(err error) {
|
||||
switch e := err.(type) {
|
||||
case nil:
|
||||
case (net.Error):
|
||||
if e.Temporary() {
|
||||
fmt.Printf("Warning: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("net.Error: %v\n", err)
|
||||
panic(err)
|
||||
default:
|
||||
fmt.Printf("error: %v\n", err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// LoadKeyAndCertificate reads certificates or key from file
|
||||
func LoadKeyAndCertificate(keyPath string, certificatePath string) (*tls.Certificate, error) {
|
||||
privateKey, err := LoadKey(keyPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
certificate, err := LoadCertificate(certificatePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
certificate.PrivateKey = privateKey
|
||||
|
||||
return certificate, nil
|
||||
}
|
||||
|
||||
// LoadKey Load/read key from file
|
||||
func LoadKey(path string) (crypto.PrivateKey, error) {
|
||||
rawData, err := ioutil.ReadFile(filepath.Clean(path))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
block, _ := pem.Decode(rawData)
|
||||
if block == nil || !strings.HasSuffix(block.Type, "PRIVATE KEY") {
|
||||
return nil, errBlockIsNotPrivateKey
|
||||
}
|
||||
|
||||
if key, err := x509.ParsePKCS1PrivateKey(block.Bytes); err == nil {
|
||||
return key, nil
|
||||
}
|
||||
|
||||
if key, err := x509.ParsePKCS8PrivateKey(block.Bytes); err == nil {
|
||||
switch key := key.(type) {
|
||||
case *rsa.PrivateKey, *ecdsa.PrivateKey:
|
||||
return key, nil
|
||||
default:
|
||||
return nil, errUnknownKeyTime
|
||||
}
|
||||
}
|
||||
|
||||
if key, err := x509.ParseECPrivateKey(block.Bytes); err == nil {
|
||||
return key, nil
|
||||
}
|
||||
|
||||
return nil, errNoPrivateKeyFound
|
||||
}
|
||||
|
||||
// LoadCertificate Load/read certificate(s) from file
|
||||
func LoadCertificate(path string) (*tls.Certificate, error) {
|
||||
rawData, err := ioutil.ReadFile(filepath.Clean(path))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var certificate tls.Certificate
|
||||
|
||||
for {
|
||||
block, rest := pem.Decode(rawData)
|
||||
if block == nil {
|
||||
break
|
||||
}
|
||||
|
||||
if block.Type != "CERTIFICATE" {
|
||||
return nil, errBlockIsNotCertificate
|
||||
}
|
||||
|
||||
certificate.Certificate = append(certificate.Certificate, block.Bytes)
|
||||
rawData = rest
|
||||
}
|
||||
|
||||
if len(certificate.Certificate) == 0 {
|
||||
return nil, errNoCertificateFound
|
||||
}
|
||||
|
||||
return &certificate, nil
|
||||
}
|
Reference in New Issue
Block a user