From 47cf8d4d5869389a72e5226a4c15cabf9cc697ab Mon Sep 17 00:00:00 2001 From: 1998-felix Date: Fri, 3 May 2024 08:28:12 +0300 Subject: [PATCH] feat: add dtls config Signed-off-by: 1998-felix --- Makefile | 28 +++++++-- README.md | 10 +++ cmd/main.go | 143 +++++++++++++++++++++++++++++-------------- coap/client.go | 12 +++- go.mod | 10 +-- go.sum | 6 +- ssl/Makefile | 64 +++++++++++++++++++ ssl/certs/ca.crt | 22 +++++++ ssl/certs/ca.key | 28 +++++++++ ssl/certs/ca.srl | 1 + ssl/certs/client.crt | 26 ++++++++ ssl/certs/client.key | 52 ++++++++++++++++ 12 files changed, 341 insertions(+), 61 deletions(-) create mode 100644 ssl/Makefile create mode 100644 ssl/certs/ca.crt create mode 100644 ssl/certs/ca.key create mode 100644 ssl/certs/ca.srl create mode 100644 ssl/certs/client.crt create mode 100644 ssl/certs/client.key diff --git a/Makefile b/Makefile index b99296f..8ce8e73 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,27 @@ # Copyright (c) Abstract Machines # SPDX-License-Identifier: Apache-2.0 -all: - CGO_ENABLED=0 GOOS=linux go build -ldflags "-s -w" -o build/coap-cli-linux cmd/main.go - CGO_ENABLED=0 GOOS=darwin go build -ldflags "-s -w" -o build/coap-cli-darwin cmd/main.go - CGO_ENABLED=0 GOOS=windows go build -ldflags "-s -w" -o build/coap-cli-windows cmd/main.go +INSTALL_DIR=/usr/local/bin +BUILD_DIR=build +BUILD_FLAGS=-ldflags "-s -w" + +.PHONY: all linux darwin windows install install-linux + +all: linux darwin windows + +linux: + CGO_ENABLED=0 GOOS=linux go build $(BUILD_FLAGS) -o $(BUILD_DIR)/coap-cli-linux cmd/main.go + +darwin: + CGO_ENABLED=0 GOOS=darwin go build $(BUILD_FLAGS) -o $(BUILD_DIR)/coap-cli-darwin cmd/main.go + +windows: + CGO_ENABLED=0 GOOS=windows go build $(BUILD_FLAGS) -o $(BUILD_DIR)/coap-cli-windows cmd/main.go + +install: install-linux + +install-linux: + @cp $(BUILD_DIR)/coap-cli-linux $(INSTALL_DIR)/coap-cli || { echo "Installation failed"; exit 1; } + +clean: + rm -rf $(BUILD_DIR)/* diff --git a/README.md b/README.md index 320e9cd..c6dd768 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,13 @@ Available Commands: Flags: -a, --auth string Auth + -A, --ca-file string Client CA file + -C, --cert-file string Client certificate file -c, --content-format int Content format (default 50) -h, --help help for coap-cli -H, --host string Host (default "localhost") -k, --keep-alive uint Send a ping after interval seconds of inactivity. If not specified (or 0), keep-alive is disabled (default). + -K, --key-file string Client key file -m, --max-retries uint32 Max retries for keep alive (default 10) -O, --options num,text Add option num with contents of text to the request. If the text begins with 0x, then the hex text (two [0-9a-f] per byte) is converted to binary data. -p, --port string Port (default "5683") @@ -44,6 +47,10 @@ coap-cli get channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic --a coap-cli get channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic --options 6,0x00 --options 15,auth=1e1017e6-dee7-45b4-8a13-00e6afeb66eb ``` +```bash +coap-cli get channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic --options 6,0x00 --options 15,auth=1e1017e6-dee7-45b4-8a13-00e6afeb66eb --ca-file ssl/certs/ca.crt --cert-file ssl/certs/client.crt --key-file ssl/certs/client.key +``` + ```bash coap-cli post channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic --auth 1e1017e6-dee7-45b4-8a13-00e6afeb66eb -d "hello world" ``` @@ -55,3 +62,6 @@ coap-cli post channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic -- ```bash coap-cli post channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic -options 15,auth=1e1017e6-dee7-45b4-8a13-00e6afeb66eb -d "hello world" -H 0.0.0.0 -p 5683 ``` +```bash +coap-cli post channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic --auth 1e1017e6-dee7-45b4-8a13-00e6afeb66eb -d "hello world" --ca-file ssl/certs/ca.crt --cert-file ssl/certs/client.crt --key-file ssl/certs/client.key +``` \ No newline at end of file diff --git a/cmd/main.go b/cmd/main.go index 64f3cea..19f498b 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -5,7 +5,10 @@ package main import ( "context" + "crypto/tls" + "crypto/x509" "encoding/hex" + "errors" "fmt" "log" "os" @@ -17,25 +20,13 @@ import ( coap "github.com/absmach/coap-cli/coap" "github.com/fatih/color" + piondtls "github.com/pion/dtls/v2" coapmsg "github.com/plgd-dev/go-coap/v3/message" "github.com/plgd-dev/go-coap/v3/message/codes" "github.com/plgd-dev/go-coap/v3/message/pool" "github.com/spf13/cobra" ) -var ( - host string - port string - contentFormat int - auth string - observe bool - data string - options []string - keepAlive uint64 - verbose bool - maxRetries uint32 -) - const verboseFmt = `Date: %s Code: %s Type: %s @@ -44,6 +35,8 @@ Message-ID: %d ` func main() { + req := &request{} + rootCmd := &cobra.Command{ Use: "coap-cli [options]", Short: "CLI for CoAP", @@ -54,46 +47,49 @@ func main() { Short: "Perform a GET request on a COAP resource", Example: "coap-cli get channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic -a 1e1017e6-dee7-45b4-8a13-00e6afeb66eb -H localhost -p 5683 -O 17,50 -o \n" + "coap-cli get channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic --auth 1e1017e6-dee7-45b4-8a13-00e6afeb66eb --host localhost --port 5683 --options 17,50 --observe", - Run: runCmd(codes.GET), + Run: runCmd(req, codes.GET), } - getCmd.Flags().BoolVarP(&observe, "observe", "o", false, "Observe resource") + getCmd.Flags().BoolVarP(&req.observe, "observe", "o", false, "Observe resource") putCmd := &cobra.Command{ Use: "put ", Short: "Perform a PUT request on a COAP resource", Example: "coap-cli put /test -H coap.me -p 5683 -c 50 -d 'hello, world'\n" + "coap-cli put /test --host coap.me --port 5683 --content-format 50 --data 'hello, world'", - Run: runCmd(codes.PUT), + Run: runCmd(req, codes.PUT), } - putCmd.Flags().StringVarP(&data, "data", "d", "", "Data") + putCmd.Flags().StringVarP(&req.data, "data", "d", "", "Data") postCmd := &cobra.Command{ Use: "post ", Short: "Perform a POST request on a COAP resource", Example: "coap-cli post channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic -a 1e1017e6-dee7-45b4-8a13-00e6afeb66eb -H localhost -p 5683 -c 50 -d 'hello, world'\n" + "coap-cli post channels/0bb5ba61-a66e-4972-bab6-26f19962678f/messages/subtopic --auth 1e1017e6-dee7-45b4-8a13-00e6afeb66eb --host localhost --port 5683 --content-format 50 --data 'hello, world'", - Run: runCmd(codes.POST), + Run: runCmd(req, codes.POST), } - postCmd.Flags().StringVarP(&data, "data", "d", "", "Data") + postCmd.Flags().StringVarP(&req.data, "data", "d", "", "Data") deleteCmd := &cobra.Command{ Use: "delete ", Short: "Perform a DELETE request on a COAP resource", Example: "coap-cli delete /test -H coap.me -p 5683 -c 50 -d 'hello, world' -O 17,50\n" + "coap-cli delete /test --host coap.me --port 5683 --content-format 50 --data 'hello, world' --options 17,50", - Run: runCmd(codes.DELETE), + Run: runCmd(req, codes.DELETE), } - deleteCmd.Flags().StringVarP(&data, "data", "d", "", "Data") + deleteCmd.Flags().StringVarP(&req.data, "data", "d", "", "Data") rootCmd.AddCommand(getCmd, putCmd, postCmd, deleteCmd) - rootCmd.PersistentFlags().StringVarP(&host, "host", "H", "localhost", "Host") - rootCmd.PersistentFlags().StringVarP(&port, "port", "p", "5683", "Port") - rootCmd.PersistentFlags().StringVarP(&auth, "auth", "a", "", "Auth") - rootCmd.PersistentFlags().IntVarP(&contentFormat, "content-format", "c", 50, "Content format") - rootCmd.PersistentFlags().StringArrayVarP(&options, "options", "O", []string{}, "Add option num with contents of text to the request. If the text begins with 0x, then the hex text (two [0-9a-f] per byte) is converted to binary data.") - rootCmd.PersistentFlags().Uint64VarP(&keepAlive, "keep-alive", "k", 0, "Send a ping after interval seconds of inactivity. If not specified (or 0), keep-alive is disabled (default).") - rootCmd.PersistentFlags().Uint32VarP(&maxRetries, "max-retries", "m", 10, "Max retries for keep alive") - rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Verbose output") + rootCmd.PersistentFlags().StringVarP(&req.host, "host", "H", "localhost", "Host") + rootCmd.PersistentFlags().StringVarP(&req.port, "port", "p", "5683", "Port") + rootCmd.PersistentFlags().StringVarP(&req.auth, "auth", "a", "", "Auth") + rootCmd.PersistentFlags().IntVarP(&req.contentFormat, "content-format", "c", 50, "Content format") + rootCmd.PersistentFlags().StringArrayVarP(&req.options, "options", "O", []string{}, "Add option num with contents of text to the request. If the text begins with 0x, then the hex text (two [0-9a-f] per byte) is converted to binary data.") + rootCmd.PersistentFlags().Uint64VarP(&req.keepAlive, "keep-alive", "k", 0, "Send a ping after interval seconds of inactivity. If not specified (or 0), keep-alive is disabled (default).") + rootCmd.PersistentFlags().Uint32VarP(&req.maxRetries, "max-retries", "m", 10, "Max retries for keep alive") + rootCmd.PersistentFlags().BoolVarP(&req.verbose, "verbose", "v", false, "Verbose output") + rootCmd.PersistentFlags().StringVarP(&req.certFile, "cert-file", "C", "", "Client certificate file") + rootCmd.PersistentFlags().StringVarP(&req.keyFile, "key-file", "K", "", "Client key file") + rootCmd.PersistentFlags().StringVarP(&req.clientCAFile, "ca-file", "A", "", "Client CA file") if err := rootCmd.Execute(); err != nil { log.Fatalf("Error executing command: %v", err) @@ -126,14 +122,18 @@ func printMsg(m *pool.Message, verbose bool) { } } -func makeRequest(code codes.Code, args []string) { - client, err := coap.NewClient(host+":"+port, keepAlive, maxRetries) +func makeRequest(req *request, args []string) { + dtlsConfig, err := req.createDTLSConfig() + if err != nil { + log.Fatalf("Error creating DTLS config: %v", err) + } + client, err := coap.NewClient(req.host+":"+req.port, req.keepAlive, req.maxRetries, dtlsConfig) if err != nil { log.Fatalf("Error coap creating client: %v", err) } var opts coapmsg.Options - for _, optString := range options { + for _, optString := range req.options { opt := strings.Split(optString, ",") if len(opt) < 2 { log.Fatal("Invalid option format") @@ -153,20 +153,20 @@ func makeRequest(code codes.Code, args []string) { opts = append(opts, coapmsg.Option{ID: coapmsg.OptionID(optId), Value: []byte(opt[1])}) } } - if auth != "" { - opts = append(opts, coapmsg.Option{ID: coapmsg.URIQuery, Value: []byte("auth=" + auth)}) + if req.auth != "" { + opts = append(opts, coapmsg.Option{ID: coapmsg.URIQuery, Value: []byte("auth=" + req.auth)}) } if opts.HasOption(coapmsg.Observe) { - if value, _ := opts.GetBytes(coapmsg.Observe); len(value) == 1 && value[0] == 0 && !observe { - observe = true + if value, _ := opts.GetBytes(coapmsg.Observe); len(value) == 1 && value[0] == 0 && !req.observe { + req.observe = true } } - switch code { + switch req.code { case codes.GET: switch { - case observe: - obs, err := client.Receive(args[0], verbose, opts...) + case req.observe: + obs, err := client.Receive(args[0], req.verbose, opts...) if err != nil { log.Fatalf("Error observing resource: %v", err) } @@ -183,28 +183,79 @@ func makeRequest(code codes.Code, args []string) { } log.Fatalf("Observation terminated: %v", err) default: - res, err := client.Send(args[0], code, coapmsg.MediaType(contentFormat), nil, opts...) + res, err := client.Send(args[0], req.code, coapmsg.MediaType(req.contentFormat), nil, opts...) if err != nil { log.Fatalf("Error sending message: %v", err) } - printMsg(res, verbose) + printMsg(res, req.verbose) } default: - pld := strings.NewReader(data) - res, err := client.Send(args[0], code, coapmsg.MediaType(contentFormat), pld, opts...) + pld := strings.NewReader(req.data) + res, err := client.Send(args[0], req.code, coapmsg.MediaType(req.contentFormat), pld, opts...) if err != nil { log.Fatalf("Error sending message: %v", err) } - printMsg(res, verbose) + printMsg(res, req.verbose) } } -func runCmd(code codes.Code) func(cmd *cobra.Command, args []string) { +func runCmd(req *request, code codes.Code) func(cmd *cobra.Command, args []string) { return func(cmd *cobra.Command, args []string) { if len(args) < 1 { fmt.Fprintf(os.Stdout, color.YellowString("\nusage: %s\n\n"), cmd.Use) return } - makeRequest(code, args) + req.code = code + makeRequest(req, args) + } +} + +type request struct { + code codes.Code + host string + port string + contentFormat int + auth string + observe bool + data string + options []string + keepAlive uint64 + verbose bool + maxRetries uint32 + certFile string + keyFile string + clientCAFile string +} + +func (r *request) createDTLSConfig() (*piondtls.Config, error) { + if r.certFile == "" || r.keyFile == "" { + return nil, nil + } + dc := &piondtls.Config{} + cert, err := tls.LoadX509KeyPair(r.certFile, r.keyFile) + if err != nil { + return nil, errors.Join(errors.New("failed to load certificates"), err) + } + dc.Certificates = []tls.Certificate{cert} + rootCA, err := loadCertFile(r.clientCAFile) + if err != nil { + return nil, errors.Join(errors.New("failed to load Client CA"), err) + } + if len(rootCA) > 0 { + if dc.RootCAs == nil { + dc.RootCAs = x509.NewCertPool() + } + if !dc.RootCAs.AppendCertsFromPEM(rootCA) { + return nil, errors.New("failed to append root ca tls.Config") + } + } + dc.InsecureSkipVerify = true + return dc, nil +} + +func loadCertFile(certFile string) ([]byte, error) { + if certFile != "" { + return os.ReadFile(certFile) } + return []byte{}, nil } diff --git a/coap/client.go b/coap/client.go index 2395ba2..53f91f0 100644 --- a/coap/client.go +++ b/coap/client.go @@ -11,6 +11,8 @@ import ( "log" "time" + piondtls "github.com/pion/dtls/v2" + "github.com/plgd-dev/go-coap/v3/dtls" "github.com/plgd-dev/go-coap/v3/message" "github.com/plgd-dev/go-coap/v3/message/codes" "github.com/plgd-dev/go-coap/v3/message/pool" @@ -39,12 +41,18 @@ type Client struct { } // NewClient returns new CoAP client connecting it to the server. -func NewClient(addr string, keepAlive uint64, maxRetries uint32) (Client, error) { +func NewClient(addr string, keepAlive uint64, maxRetries uint32, dtlsConfig *piondtls.Config) (Client, error) { var dialOptions []udp.Option if keepAlive > 0 { dialOptions = append(dialOptions, options.WithKeepAlive(maxRetries, time.Duration(keepAlive)*time.Second, onInactive)) } - c, err := udp.Dial(addr, dialOptions...) + var c *client.Conn + var err error + if dtlsConfig != nil { + c, err = dtls.Dial(addr, dtlsConfig, dialOptions...) + } else { + c, err = udp.Dial(addr, dialOptions...) + } if err != nil { return Client{}, errors.Join(errDialFailed, err) } diff --git a/go.mod b/go.mod index ada77fe..a8abde0 100644 --- a/go.mod +++ b/go.mod @@ -4,26 +4,22 @@ go 1.22 require ( github.com/fatih/color v1.17.0 + github.com/pion/dtls/v2 v2.2.8-0.20240501061905-2c36d63320a0 github.com/plgd-dev/go-coap/v3 v3.3.4 github.com/spf13/cobra v1.8.0 ) require ( - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.20 // indirect -) - -require ( + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dsnet/golib/memfile v1.0.0 // indirect - github.com/fatih/color v1.16.0 github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/pion/dtls/v2 v2.2.8-0.20240501061905-2c36d63320a0 // indirect github.com/pion/logging v0.2.2 // indirect github.com/pion/transport/v3 v3.0.2 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/spf13/pflag v1.0.5 // indirect go.uber.org/atomic v1.11.0 // indirect golang.org/x/crypto v0.22.0 // indirect diff --git a/go.sum b/go.sum index f9c5817..4e9b122 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dsnet/golib/memfile v1.0.0 h1:J9pUspY2bDCbF9o+YGwcf3uG6MdyITfh/Fk3/CaEiFs= github.com/dsnet/golib/memfile v1.0.0/go.mod h1:tXGNW9q3RwvWt1VV2qrRKlSSz0npnh12yftCSCy2T64= github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= @@ -26,8 +27,9 @@ github.com/pion/transport/v3 v3.0.2 h1:r+40RJR25S9w3jbA6/5uEPTzcdn7ncyU44RWCbHkL github.com/pion/transport/v3 v3.0.2/go.mod h1:nIToODoOlb5If2jF9y2Igfx3PFYWfuXi37m0IlWa/D0= github.com/plgd-dev/go-coap/v3 v3.3.4 h1:clDLFOXXmXfhZqB0eSk6WJs2iYfjC2J22Ixwu5MHiO0= github.com/plgd-dev/go-coap/v3 v3.3.4/go.mod h1:vxBvAgXxL+Au/58XYTM+8ftqO/ycFC9/Dh+uI72xYjA= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= diff --git a/ssl/Makefile b/ssl/Makefile new file mode 100644 index 0000000..b5e8359 --- /dev/null +++ b/ssl/Makefile @@ -0,0 +1,64 @@ +# Copyright (c) Abstract Machines +# SPDX-License-Identifier: Apache-2.0 + +CRT_LOCATION = certs +O = absmach +OU_CA = absmach_ca +OU_CRT = absmach_crt +EA = info@absmach.com +CLIENT_CN = coap-cli-client +CRT_FILE_NAME = client +CN_CA = Absmach_Self_Signed_CA + +define CERT_CONFIG +[ca] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer:always + +[req] +req_extensions = v3_req +distinguished_name = dn +prompt = no + +[dn] +CN = $(COMMON_NAME) +C = FR +ST = FR +L = PARIS +O = absmach +OU = absmach + +[v3_req] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = $(COMMON_NAME) +endef + + +.PHONY: all clean_certs client_cert client_cert_revoked client_cert_unknown ca + +# Generate all client certificates +all: clean_certs ca client_cert client_cert_revoked client_cert_unknown + +ca: + openssl req -newkey rsa:2048 -x509 -nodes -sha512 -days 1095 \ + -keyout $(CRT_LOCATION)/ca.key -out $(CRT_LOCATION)/ca.crt -subj "/CN=$(CN_CA)/O=$(O)/OU=$(OU_CA)/emailAddress=$(EA)" + +client_cert: + # Create absmach client key and CSR. + openssl req -new -sha256 -newkey rsa:4096 -nodes -keyout $(CRT_LOCATION)/$(CRT_FILE_NAME).key \ + -out $(CRT_LOCATION)/$(CRT_FILE_NAME).csr -subj "/CN=$(CLIENT_CN)/O=$(O)/OU=$(OU_CRT)/emailAddress=$(EA)" + + # Sign client CSR. + openssl x509 -req -days 730 -in $(CRT_LOCATION)/$(CRT_FILE_NAME).csr -CA $(CRT_LOCATION)/ca.crt -CAkey $(CRT_LOCATION)/ca.key -CAcreateserial -out $(CRT_LOCATION)/$(CRT_FILE_NAME).crt + + # Remove CSR. + rm $(CRT_LOCATION)/$(CRT_FILE_NAME).csr + +clean_certs: + rm -f $(CRT_LOCATION)/*.crt + rm -f $(CRT_LOCATION)/*.key + rm -f $(CRT_LOCATION)/*.srl diff --git a/ssl/certs/ca.crt b/ssl/certs/ca.crt new file mode 100644 index 0000000..66b21d5 --- /dev/null +++ b/ssl/certs/ca.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDszCCApugAwIBAgIULa101cRg3Vvf+M/fLHj8pYTJIyEwDQYJKoZIhvcNAQEN +BQAwaTEfMB0GA1UEAwwWQWJzbWFjaF9TZWxmX1NpZ25lZF9DQTEQMA4GA1UECgwH +YWJzbWFjaDETMBEGA1UECwwKYWJzbWFjaF9jYTEfMB0GCSqGSIb3DQEJARYQaW5m +b0BhYnNtYWNoLmNvbTAeFw0yNDA1MDcwODUyMTFaFw0yNzA1MDcwODUyMTFaMGkx +HzAdBgNVBAMMFkFic21hY2hfU2VsZl9TaWduZWRfQ0ExEDAOBgNVBAoMB2Fic21h +Y2gxEzARBgNVBAsMCmFic21hY2hfY2ExHzAdBgkqhkiG9w0BCQEWEGluZm9AYWJz +bWFjaC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrtBFpQ4SB +5QCN/kgl3974UvUe/mcar1AEnR3rBRRdpQV4fxifDN/GBzuYt0xhfaQcPNBX8pL1 +luhHsOEkS1Q1o0TsKCL+2o6x98ez0+Q0YDRCBFs027YCyBRzZB7zRwSno82A8st+ +XjzF53kskXwGvv+3dv/XMc1BcO6lhVdNy65cBIhEc15Jpeq8hy27lRPIAcjldEnj +5A6BvUrCBqD1FEXobqxAYeQ8vSpqZhaa+C1p03zz0yZ4aCkUBciVoBan8dAB9oKo +AL36oSnGCTyxfXLFCGuIBqhK1dlMX/AnBy6FeCa+yAL6AsC873xevcoYEUCrcPme +FM89BFy7vi3lAgMBAAGjUzBRMB0GA1UdDgQWBBRynRpuEdb2USRiLagfJJYTcJSa +JDAfBgNVHSMEGDAWgBRynRpuEdb2USRiLagfJJYTcJSaJDAPBgNVHRMBAf8EBTAD +AQH/MA0GCSqGSIb3DQEBDQUAA4IBAQBroEYZ6yn0WBzbfEwT8V/yJzFqEh1D+Dwk +OrvNluYCG5Bk8UJtqirt3Hh/C1y0/84koSiWbr2ODV8Q2CfUW2DVIL7JS7WapC5K +lg5KcqIyjTXT3IvAABnlORHY0ah+0NeZ8LD0bYJ+JLPdFmxhZ8thivyJwDXUcZim +l/DG4qvSd+kuGWk8G/pnab4OOS+nFtWosddFoZ52MIzrYxjloMCWAzgz2Ah/lO3Z +2qsf2LKMnzDnV1GD4MjSeep4cZWY6xWyrsGK/VA8vcqLvBURZ6udeLvXaQ4hPkwa +UfdnALWx/1/zsc6q6oFEDyVmMt+0njLixY2grA1o3Lz4q6hCVgtv +-----END CERTIFICATE----- diff --git a/ssl/certs/ca.key b/ssl/certs/ca.key new file mode 100644 index 0000000..5ae37d4 --- /dev/null +++ b/ssl/certs/ca.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCrtBFpQ4SB5QCN +/kgl3974UvUe/mcar1AEnR3rBRRdpQV4fxifDN/GBzuYt0xhfaQcPNBX8pL1luhH +sOEkS1Q1o0TsKCL+2o6x98ez0+Q0YDRCBFs027YCyBRzZB7zRwSno82A8st+XjzF +53kskXwGvv+3dv/XMc1BcO6lhVdNy65cBIhEc15Jpeq8hy27lRPIAcjldEnj5A6B +vUrCBqD1FEXobqxAYeQ8vSpqZhaa+C1p03zz0yZ4aCkUBciVoBan8dAB9oKoAL36 +oSnGCTyxfXLFCGuIBqhK1dlMX/AnBy6FeCa+yAL6AsC873xevcoYEUCrcPmeFM89 +BFy7vi3lAgMBAAECggEAB5ODtCkYQvIDlwBaFx+8cykX60Tu8Di9l2KGZC0ec65Z +IjK7d6MmCZMeoFOwMVoNoHhXehX4QZFl0On/WS5guhgo7aGsv6GNq9Ei1O670krP +a31NN/Uc4B0Ld/b6PaJL1IjQA8lSzNHkLRhUWrDVr+eEGYiM6+Yk6CcPRKrwSfyo +1HcX9MzEiSRwHQw3M7wRtNByjqCXxvnbtniZRAMGJl7WHONZEQNf/R+1LukLx2qK +hM89RJLj2bZ4KBC2+pPFzf8xr6oV/rLkNHj8NxwXFiSR2FuvdoLxHUS+lo48Bkw0 +9hhKtnBOQY6dZetcV7HxPczyomPoAMrMkcme4Y9PkQKBgQDyHJztZCNnyyvni1+W +xnGjE9F9VpoYucDHNQihmnRE/T2R9WMAKOZb0CLeWeMKzWNLE6vQHoieDfNcjQIB +2BWaQpuHkpDMBjtjJOx3NIF34mpvJszr6ZT87IcVzlqc26QIUYX+DV6pYPjzCVN8 +BEYEx9utX1erXVgLXCPmWc+mMQKBgQC1jYPaLta3croVeWiMAbUeKX8S9cZNzBZW +NaOIJWY2wGZAiJ3bjgxoiEAPaZ3rbWmC5Q9juc+6wcKxWKjmE1L9UAYr2mzkZc2v +WLXD7wK9EHArIUXZlwQgms6Flbe5RorDu79Fxq2+FsJSRNDwnNaiQcjefmawNp5S +6M4qoZDx9QKBgE2kgWrb10Lc9AqANrpqj1zF6UOxtx9AyqLXzhnNJ4ZMVCdvsz0E +4MMG33fBCb+YGESmXU4TzKorPSUsDz26J0teGvSCOy9CvF7SI4ci7nYcxRc6MTNi +qCXoUHXcxFBTW6pTQo4ziWz2LT/7eKtnz3CPC1LxJXNOLwMNnHGt0ZqxAoGAJeTe +w3iJSosAuiC4KJjmo+AHbP6toGlbtCzH8E/WENGBxjB9umjgwCTIMi9aTdxtbGvB +FZCgAhwVNg0KW9NmvAaq8xZJKjbxgorijX3itXGr5+Su/qadruyA9LL2QQ6vQgF6 +/+ZjN0zqzF8euUoTJpTSh1YcuuT7kNSUy6MjbM0CgYEA8aHZbygOxyWMSQV5l+wh +Aj6Urt/LTUB9xLBwbfg6axQHb7sVY9fodB+ih0BOl1Iy0x2VQTk+jzy3R7lHBdZu +qlyePXrUzoo2BdJ5dBykzeMCjtm3QyZI1EHLHn2SCRBpIgs9Qc2cAgYCNwamAws2 +lmg52kH9C1gAwNIB6KLkj/g= +-----END PRIVATE KEY----- diff --git a/ssl/certs/ca.srl b/ssl/certs/ca.srl new file mode 100644 index 0000000..b4ff21e --- /dev/null +++ b/ssl/certs/ca.srl @@ -0,0 +1 @@ +63394BC07145D7006696CBA3DA6B37DC4DB06EDF diff --git a/ssl/certs/client.crt b/ssl/certs/client.crt new file mode 100644 index 0000000..cb0bcc0 --- /dev/null +++ b/ssl/certs/client.crt @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEUzCCAzsCFGM5S8BxRdcAZpbLo9prN9xNsG7fMA0GCSqGSIb3DQEBCwUAMGkx +HzAdBgNVBAMMFkFic21hY2hfU2VsZl9TaWduZWRfQ0ExEDAOBgNVBAoMB2Fic21h +Y2gxEzARBgNVBAsMCmFic21hY2hfY2ExHzAdBgkqhkiG9w0BCQEWEGluZm9AYWJz +bWFjaC5jb20wHhcNMjQwNTA3MDg1MjExWhcNMjYwNTA3MDg1MjExWjBjMRgwFgYD +VQQDDA9jb2FwLWNsaS1jbGllbnQxEDAOBgNVBAoMB2Fic21hY2gxFDASBgNVBAsM +C2Fic21hY2hfY3J0MR8wHQYJKoZIhvcNAQkBFhBpbmZvQGFic21hY2guY29tMIIC +IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsO54byUb7eGxUpnjGNmzMckc +jldeC2IWLoB9KNAbpJBGfzN8jHwYkJIB7JtyFuZksPr4KhMr9IEKKWY9JcddeJlj +T5zp0QdLR/ZnPsfVSD8rtbEtCAgzO8OtoAMlTlmxDT7F+axP3ezLAjAuEP3+3UhX +1711YeciRQNcxRtQSlbiI9Y9ftgkUiysF1Sv2Dd897kE1daMBImjth8eaEmEC7iS +ayc0muVqL51J9leBRfFh67G6gvChl10iZdyT/v6EpKgUyfrG+yX0GWKHqoKBgKO4 +xhGVwkMgrmk4TFBNIbqnyg3c8Ai5m3J44jYe/1M3zxlWUNuSu6ZvYEqCxUIFiruZ +PjYBIZMCyExtWAS69zh9wSl28uruDEyWRxyIHbbg2DXPnDpcCalKfrr1Zg7fKGiG +kK847oxWkXUdYjVPGwiT2E/pMoACIs8BpGAvQ5YWqbw7K5a93CDvi5TJt4b2Ej9m +ilEBQns1RSMAopd/6bWQmVMUT1hTnYmR0LzmAO7OJwpwxWtqzt8GK4zXSHuBowUx +9uORObOOQR5EO5+bycvyQvBbi+Z1y6f0OEvvBrp3ZnRbAk4ManaWzFCiaQQCvr/k +GAJt6PRKZlYMTfTfNHjd2oIuebBj0/42r6M5AbGJJj2PzxgzAS5LjdpCsW20p8bN +ZkB2egOX9A28zTyYZb0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAImOV4jTqK8j3 +FD59J2ZC2rlZX1O/P5egrxVe1cfeH7OV+wGYpARsvhn1Z2IyH3rzqJrQd5j1xiLd +mh6MhFHJFWdbeCeN+//AKSVxtQoCuAq2HIe24hsQp7oDsamgKlvKTZvmsHVMwx4w +EMFoO3YodzTBmKmO78x5K5KxOyGqTXcygYgzZDad5hMaCIn93t4LHPgNs3fVJHeS +bZ8MjhE6trnyOGawhscJZrY5cF8hM5AZkEss75DzY4N5GfR6CTmKPgRj8m/GChv3 +i2VF+6F7SpxofwJqtGobITcS22Qr0PH1eUBrKg8TR9v9VCB2wh/x2+OfuEbgvfHE +cxvkbUuphw== +-----END CERTIFICATE----- diff --git a/ssl/certs/client.key b/ssl/certs/client.key new file mode 100644 index 0000000..7dc9ac0 --- /dev/null +++ b/ssl/certs/client.key @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +nLIYGRGy7V3HLlv59yeXP+2NCSh9qA== +-----END PRIVATE KEY-----