Skip to content

Commit

Permalink
added crypt keys
Browse files Browse the repository at this point in the history
  • Loading branch information
alexlzrv committed Nov 15, 2023
1 parent a76f94c commit 5466e76
Show file tree
Hide file tree
Showing 8 changed files with 138 additions and 5 deletions.
45 changes: 45 additions & 0 deletions cmd/key/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package main

import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"log"
"os"
)

func main() {
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
log.Fatal(err)
}

publicKey := &privateKey.PublicKey
privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey)

privateKeyPEM := pem.EncodeToMemory(&pem.Block{
Type: "SERVER PRIVATE KEY",
Bytes: privateKeyBytes,
})

err = os.WriteFile("./private.pem", privateKeyPEM, 0644)
if err != nil {
log.Fatal(err)
}

publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
log.Fatal(err)
}

publicKeyPEM := pem.EncodeToMemory(&pem.Block{
Type: "AGENT PUBLIC KEY",
Bytes: publicKeyBytes,
})

err = os.WriteFile("./public.pem", publicKeyPEM, 0644)
if err != nil {
log.Fatal(err)
}
}
2 changes: 2 additions & 0 deletions internal/pkg/agent/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type AgentConfig struct {
ReportInterval int `env:"REPORT_INTERVAL"`
PollInterval int `env:"POLL_INTERVAL"`
RateLimit int `env:"RATE_LIMIT"`
PublicKey string `env:"CRYPTO_KEY"`
SignKeyByte []byte
}

Expand Down Expand Up @@ -44,5 +45,6 @@ func (c *AgentConfig) init() {
flag.IntVar(&c.PollInterval, "p", pollIntervalDefault, "Interval of poll metric")
flag.StringVar(&c.SignKey, "k", "", "Server key")
flag.IntVar(&c.RateLimit, "l", rateLimitDefault, "Rate limit")
flag.StringVar(&c.PublicKey, "-crypto-key", "", "Public key path")
flag.Parse()
}
32 changes: 32 additions & 0 deletions internal/pkg/agent/encrypt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package agent

import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"os"
)

func encrypt(publicKeyPath string, data []byte) ([]byte, error) {
publicKeyPEM, err := os.ReadFile(publicKeyPath)
if err != nil {
return nil, err
}
publicKeyBlock, _ := pem.Decode(publicKeyPEM)
if publicKeyBlock == nil {
return nil, err
}

publicKey, err := x509.ParsePKIXPublicKey(publicKeyBlock.Bytes)
if err != nil {
return nil, err
}

ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey.(*rsa.PublicKey), data)
if err != nil {
return nil, err
}

return ciphertext, nil
}
15 changes: 11 additions & 4 deletions internal/pkg/agent/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func RunSendMetric(ctx context.Context, reportTicker *time.Ticker, c *config.Age
case <-ctx.Done():
return
case <-reportTicker.C:
ok, err := SendMetrics(ctx, s, c.ServerAddress, c.SignKeyByte)
ok, err := SendMetrics(ctx, s, c.ServerAddress, c.SignKeyByte, c.PublicKey)
if err != nil {
logrus.Errorf("Error send metrics %v", err)
}
Expand All @@ -37,7 +37,7 @@ func RunSendMetric(ctx context.Context, reportTicker *time.Ticker, c *config.Age
}
}

func SendMetrics(ctx context.Context, s storage.Store, serverAddress string, signKey []byte) (bool, error) {
func SendMetrics(ctx context.Context, s storage.Store, serverAddress string, signKey []byte, publicKey string) (bool, error) {
metricsMap, err := s.GetMetrics(ctx)
if err != nil {
logrus.Errorf("Some error ocured during metrics get: %q", err)
Expand All @@ -51,18 +51,25 @@ func SendMetrics(ctx context.Context, s storage.Store, serverAddress string, sig

url := fmt.Sprintf("http://%s/updates/", serverAddress)

if err = SendBatchJSON(url, metricsBatch, signKey); err != nil {
if err = SendBatchJSON(url, metricsBatch, signKey, publicKey); err != nil {
return false, fmt.Errorf("error create post request %w", err)
}
return true, nil
}

func SendBatchJSON(url string, metricsBatch []*metrics.Metrics, signKey []byte) error {
func SendBatchJSON(url string, metricsBatch []*metrics.Metrics, signKey []byte, publicKey string) error {
body, err := json.Marshal(metricsBatch)
if err != nil {
return fmt.Errorf("error encoding metric %w", err)
}

if publicKey != "" {
body, err = encrypt(publicKey, body)
if err != nil {
return err
}
}

var buf bytes.Buffer
gz := gzip.NewWriter(&buf)
if _, err = gz.Write(body); err != nil {
Expand Down
3 changes: 2 additions & 1 deletion internal/pkg/agent/reporter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const (

func TestSendReport(t *testing.T) {
secretKey := []byte("secret")
publicKey := ""
mtr := storage.NewMetrics()

err := agent.UpdateMetrics(context.Background(), mtr)
Expand Down Expand Up @@ -70,5 +71,5 @@ func TestSendReport(t *testing.T) {
}))
defer server.Close()

agent.SendMetrics(context.Background(), mtr, server.URL, secretKey)
agent.SendMetrics(context.Background(), mtr, server.URL, secretKey, publicKey)
}
43 changes: 43 additions & 0 deletions internal/pkg/middleware/crypt.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package middleware

import (
"bytes"
"crypto/hmac"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"io"
"net/http"
"os"
)

func CryptMiddleware(signKey []byte) func(handler http.Handler) http.Handler {
Expand Down Expand Up @@ -51,3 +57,40 @@ func CryptMiddleware(signKey []byte) func(handler http.Handler) http.Handler {
})
}
}

func DecryptMiddleware(privateKeyPath string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if privateKeyPath == "" {
return
}

privateKeyPEM, err := os.ReadFile(privateKeyPath)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
privateKeyBlock, _ := pem.Decode(privateKeyPEM)
privateKey, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

plaintext, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, body)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}

r.Body = io.NopCloser(bytes.NewBuffer(plaintext))
next.ServeHTTP(w, r)
})
}
}
2 changes: 2 additions & 0 deletions internal/pkg/server/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type ServerConfig struct {
DatabaseDSN string `env:"DATABASE_DSN"`
StoreInterval int `env:"STORE_INTERVAL"`
Restore bool `env:"RESTORE"`
PrivateKey string `env:"CRYPTO_KEY"`
SignKeyByte []byte
}

Expand Down Expand Up @@ -45,5 +46,6 @@ func (c *ServerConfig) init() {
flag.BoolVar(&c.Restore, "r", true, "Restore")
flag.StringVar(&c.DatabaseDSN, "d", "", "Connect database string")
flag.StringVar(&c.SignKey, "k", "", "Server key")
flag.StringVar(&c.PrivateKey, "-crypto-key", "", "Private key path")
flag.Parse()
}
1 change: 1 addition & 0 deletions internal/pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func StartListener(c *config.ServerConfig) {
mux.Use(
middleware.LoggingMiddleware,
middleware.CryptMiddleware(c.SignKeyByte),
middleware.DecryptMiddleware(c.PrivateKey),
)

RegisterHandlers(mux, metricStore)
Expand Down

0 comments on commit 5466e76

Please sign in to comment.