diff options
Diffstat (limited to 'internal/protocol/handshake.go')
| -rw-r--r-- | internal/protocol/handshake.go | 128 | +0 −128 |
1 files changed, 0 insertions, 128 deletions
diff --git a/internal/protocol/handshake.go b/internal/protocol/handshake.go deleted file mode 100644 --- a/internal/protocol/handshake.go +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-FileCopyrightText: 2026 Nikolay Govorov -// SPDX-License-Identifier: AGPL-3.0-or-later - -package protocol - -import ( - "crypto/ed25519" - "crypto/rand" - "crypto/tls" - "crypto/x509" - "encoding/pem" - "errors" - "fmt" - "math/big" - "net/url" - "os" - "time" - - "dimidiumlabs/mirum/internal/config" -) - -var ( - ErrKeyNotPEM = errors.New("key file does not contain a PEM block") - ErrKeyNotPKCS8 = errors.New("key file does not contain a PKCS8 private key") - ErrKeyNotPKIX = errors.New("key file does not contain a PKIX public key") - ErrKeyNotEd25519 = errors.New("key file does not contain an ed25519 key") - - ErrClockSkew = errors.New("clock skew too large") -) - -// WorkerMeta describes the worker for embedding in a self-signed X.509 -// certificate as a URI SAN (mirum:worker?name=...&version=...&...). -type WorkerMeta struct { - Name string - Version string - Os string - Arch string - Runtime string -} - -// URI encodes worker metadata as a mirum: URI. -func (m *WorkerMeta) URI() *url.URL { - return &url.URL{ - Scheme: "mirum", - Opaque: "worker", - RawQuery: url.Values{ - "name": {m.Name}, - "version": {m.Version}, - "os": {m.Os}, - "arch": {m.Arch}, - "runtime": {m.Runtime}, - }.Encode(), - } -} - -// ParseWorkerMeta extracts WorkerMeta from a certificate's URI SANs. -// Returns nil if no mirum:worker URI is found. -func ParseWorkerMeta(cert *x509.Certificate) *WorkerMeta { - for _, u := range cert.URIs { - if u.Scheme == "mirum" && u.Opaque == "worker" { - q := u.Query() - return &WorkerMeta{ - Name: q.Get("name"), - Version: q.Get("version"), - Os: q.Get("os"), - Arch: q.Get("arch"), - Runtime: q.Get("runtime"), - } - } - } - return nil -} - -// LoadPrivateKey reads a PEM-encoded PKCS8 ed25519 private key from path. -func LoadPrivateKey(path string) (ed25519.PrivateKey, error) { - data, err := os.ReadFile(path) - if err != nil { - return nil, fmt.Errorf("read key: %w", err) - } - - block, _ := pem.Decode(data) - if block == nil { - return nil, ErrKeyNotPEM - } - - key, err := x509.ParsePKCS8PrivateKey(block.Bytes) - if err != nil { - return nil, fmt.Errorf("%w: %w", ErrKeyNotPKCS8, err) - } - - edKey, ok := key.(ed25519.PrivateKey) - if !ok { - return nil, ErrKeyNotEd25519 - } - - return edKey, nil -} - -// SelfSignedCert generates a self-signed X.509 certificate from an ed25519 -// private key with worker metadata encoded as a URI SAN. The server extracts -// the public key for authentication, metadata from the URI, and uses NotBefore -// for clock skew detection. -func SelfSignedCert(key ed25519.PrivateKey, meta *WorkerMeta) (tls.Certificate, error) { - serial, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128)) - if err != nil { - return tls.Certificate{}, fmt.Errorf("generate serial: %w", err) - } - - now := time.Now() - tmpl := &x509.Certificate{ - SerialNumber: serial, - NotBefore: now, - NotAfter: now.Add(config.WorkerCertLifetime), - KeyUsage: x509.KeyUsageDigitalSignature, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, - URIs: []*url.URL{meta.URI()}, - } - - certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, key.Public(), key) - if err != nil { - return tls.Certificate{}, fmt.Errorf("create certificate: %w", err) - } - - return tls.Certificate{ - Certificate: [][]byte{certDER}, - PrivateKey: key, - }, nil -} |
