-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
08 Zinx TLS
刘丹冰 edited this page May 11, 2023
·
2 revisions
Case Source Code : https://github.com/aceld/zinx/tree/master/examples/zinx_tls
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"github.com/aceld/zinx/zconf"
"github.com/aceld/zinx/ziface"
"github.com/aceld/zinx/zlog"
"github.com/aceld/zinx/znet"
"math/big"
"os"
"time"
)
// PingRouter is a custom router for ping test
type PingRouter struct {
znet.BaseRouter
}
// Handle handles the ping request
func (this *PingRouter) Handle(request ziface.IRequest) {
zlog.Debug("Call PingRouter Handle")
// Read client data first, then write back ping...ping...ping
zlog.Debug("Received from client: msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
err := request.GetConnection().SendBuffMsg(2, []byte("Pong with TLS"))
if err != nil {
zlog.Error(err)
}
}
// genExampleCrtAndKeyFile generates certificate and key files for testing purposes only!! Please customize this function or use openssl to generate them for actual use.
// Refer to the following link for generating certificates and private keys using openssl: https://blog.csdn.net/qq_44637753/article/details/124152315
func genExampleCrtAndKeyFile(crtFileName, KeyFileName string) (err error) {
// Regenerate if already exists
_ = os.Remove(crtFileName)
_ = os.Remove(KeyFileName)
defer func() {
if err != nil {
// Remove the generated certificate and private key files if an error occurs during the process
_ = os.Remove(crtFileName)
_ = os.Remove(KeyFileName)
}
}()
// Generate private key
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
// Create certificate template
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return err
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"Beijing University of Post and Telecommunication"},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(24 * time.Hour * 365 * 10), // Certificate is valid for ten years
KeyUsage: x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
// Create certificate
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
if err != nil {
return err
}
// Serialize certificate file
pemCert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
if pemCert == nil {
return err
}
if err := os.WriteFile(crtFileName, pemCert, 0644); err != nil {
return err
}
// Generate private key file
privateBytes, err := x509.MarshalPKCS8PrivateKey(privateKey)
if err != nil {
return err
}
pemKey := pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privateBytes})
if pemKey == nil {
return err
}
if err != nil {
return err
}
if err := os.WriteFile(KeyFileName, pemKey, 0600); err != nil {
return err
}
return nil
}
package main
import (
"fmt"
"github.com/aceld/zinx/ziface"
"github.com/aceld/zinx/zlog"
"github.com/aceld/zinx/znet"
"os"
"os/signal"
"time"
)
// PongRouter is a custom router for pong test
type PongRouter struct {
znet.BaseRouter
}
// Handle is a method for handling the pong request
func (this *PongRouter) Handle(request ziface.IRequest) {
zlog.Debug("Call PongRouter Handle")
// Read data returned from the server
zlog.Debug("recv from client : msgId=", request.GetMsgID(), ", data=", string(request.GetData()))
}
// Wait listens for interrupt and kill signals
func wait() {
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, os.Kill)
sig := <-c
fmt.Println("===exit===", sig)
}
func main() {
// Create a TLS client
c := znet.NewTLSClient("127.0.0.1", 8899)
// Set up connection start function
c.SetOnConnStart(func(connection ziface.IConnection) {
go func() {
for {
// Send ping message
err := connection.SendMsg(1, []byte("Ping with TLS"))
if err != nil {
fmt.Println(err)
break
}
time.Sleep(1 * time.Second)
}
}()
})
// Add custom router
c.AddRouter(2, &PongRouter{})
// Start the client
c.Start()
// Wait for interrupt or kill signal
wait()
}