mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: NATS mTLS pubsub implementation (#26902)
This commit is contained in:
@@ -2,13 +2,19 @@ package dbgen
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"math/big"
|
||||
"net"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -2223,10 +2229,47 @@ func newCryptoKeySecret(feature database.CryptoKeyFeature) (string, error) {
|
||||
return generateCryptoKey(64)
|
||||
case database.CryptoKeyFeatureTailnetResume:
|
||||
return generateCryptoKey(64)
|
||||
case database.CryptoKeyFeatureNATSCA:
|
||||
return generateCACryptoKeySecret()
|
||||
}
|
||||
return "", xerrors.Errorf("unknown feature: %s", feature)
|
||||
}
|
||||
|
||||
// generateCACryptoKeySecret generates a self-signed CA certificate and private
|
||||
// key as a PEM bundle, matching the secret format that coderd/cryptokeys
|
||||
// produces for the nats_ca feature. It intentionally duplicates
|
||||
// cryptokeys.generateCASecret rather than calling it: coderd/cryptokeys's
|
||||
// internal tests import dbgen, so importing cryptokeys here would create a
|
||||
// test-build import cycle.
|
||||
func generateCACryptoKeySecret() (string, error) {
|
||||
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
return "", xerrors.Errorf("generate key: %w", err)
|
||||
}
|
||||
template := &x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
Subject: pkix.Name{CommonName: "dbgen-ca"},
|
||||
NotBefore: time.Now().Add(-time.Hour),
|
||||
NotAfter: time.Now().Add(24 * time.Hour),
|
||||
KeyUsage: x509.KeyUsageCertSign,
|
||||
BasicConstraintsValid: true,
|
||||
IsCA: true,
|
||||
MaxPathLenZero: true,
|
||||
}
|
||||
der, err := x509.CreateCertificate(rand.Reader, template, template, key.Public(), key)
|
||||
if err != nil {
|
||||
return "", xerrors.Errorf("create certificate: %w", err)
|
||||
}
|
||||
keyDER, err := x509.MarshalECPrivateKey(key)
|
||||
if err != nil {
|
||||
return "", xerrors.Errorf("marshal private key: %w", err)
|
||||
}
|
||||
var secret []byte
|
||||
secret = append(secret, pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: der})...)
|
||||
secret = append(secret, pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: keyDER})...)
|
||||
return string(secret), nil
|
||||
}
|
||||
|
||||
func generateCryptoKey(length int) (string, error) {
|
||||
b := make([]byte, length)
|
||||
_, err := rand.Read(b)
|
||||
|
||||
@@ -2,7 +2,6 @@ package database
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"slices"
|
||||
"sort"
|
||||
@@ -873,10 +872,6 @@ func (k CryptoKey) ExpiresAt(keyDuration time.Duration) time.Time {
|
||||
return k.StartsAt.Add(keyDuration).UTC()
|
||||
}
|
||||
|
||||
func (k CryptoKey) DecodeString() ([]byte, error) {
|
||||
return hex.DecodeString(k.Secret.String)
|
||||
}
|
||||
|
||||
func (k CryptoKey) CanSign(now time.Time) bool {
|
||||
isAfterStart := !k.StartsAt.IsZero() && !now.Before(k.StartsAt)
|
||||
return isAfterStart && k.CanVerify(now)
|
||||
|
||||
Reference in New Issue
Block a user