helpers.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package e2e
  2. import (
  3. "crypto/rand"
  4. "io"
  5. "net"
  6. "net/netip"
  7. "time"
  8. "github.com/slackhq/nebula/cert"
  9. "golang.org/x/crypto/curve25519"
  10. "golang.org/x/crypto/ed25519"
  11. )
  12. // NewTestCaCert will generate a CA cert
  13. func NewTestCaCert(before, after time.Time, ips, subnets []netip.Prefix, groups []string) (*cert.NebulaCertificate, []byte, []byte, []byte) {
  14. pub, priv, err := ed25519.GenerateKey(rand.Reader)
  15. if before.IsZero() {
  16. before = time.Now().Add(time.Second * -60).Round(time.Second)
  17. }
  18. if after.IsZero() {
  19. after = time.Now().Add(time.Second * 60).Round(time.Second)
  20. }
  21. nc := &cert.NebulaCertificate{
  22. Details: cert.NebulaCertificateDetails{
  23. Name: "test ca",
  24. NotBefore: time.Unix(before.Unix(), 0),
  25. NotAfter: time.Unix(after.Unix(), 0),
  26. PublicKey: pub,
  27. IsCA: true,
  28. InvertedGroups: make(map[string]struct{}),
  29. },
  30. }
  31. if len(ips) > 0 {
  32. nc.Details.Ips = make([]*net.IPNet, len(ips))
  33. for i, ip := range ips {
  34. nc.Details.Ips[i] = &net.IPNet{IP: ip.Addr().AsSlice(), Mask: net.CIDRMask(ip.Bits(), ip.Addr().BitLen())}
  35. }
  36. }
  37. if len(subnets) > 0 {
  38. nc.Details.Subnets = make([]*net.IPNet, len(subnets))
  39. for i, ip := range subnets {
  40. nc.Details.Ips[i] = &net.IPNet{IP: ip.Addr().AsSlice(), Mask: net.CIDRMask(ip.Bits(), ip.Addr().BitLen())}
  41. }
  42. }
  43. if len(groups) > 0 {
  44. nc.Details.Groups = groups
  45. }
  46. err = nc.Sign(cert.Curve_CURVE25519, priv)
  47. if err != nil {
  48. panic(err)
  49. }
  50. pem, err := nc.MarshalToPEM()
  51. if err != nil {
  52. panic(err)
  53. }
  54. return nc, pub, priv, pem
  55. }
  56. // NewTestCert will generate a signed certificate with the provided details.
  57. // Expiry times are defaulted if you do not pass them in
  58. func NewTestCert(ca *cert.NebulaCertificate, key []byte, name string, before, after time.Time, ip netip.Prefix, subnets []netip.Prefix, groups []string) (*cert.NebulaCertificate, []byte, []byte, []byte) {
  59. issuer, err := ca.Sha256Sum()
  60. if err != nil {
  61. panic(err)
  62. }
  63. if before.IsZero() {
  64. before = time.Now().Add(time.Second * -60).Round(time.Second)
  65. }
  66. if after.IsZero() {
  67. after = time.Now().Add(time.Second * 60).Round(time.Second)
  68. }
  69. pub, rawPriv := x25519Keypair()
  70. ipb := ip.Addr().AsSlice()
  71. nc := &cert.NebulaCertificate{
  72. Details: cert.NebulaCertificateDetails{
  73. Name: name,
  74. Ips: []*net.IPNet{{IP: ipb[:], Mask: net.CIDRMask(ip.Bits(), ip.Addr().BitLen())}},
  75. //Subnets: subnets,
  76. Groups: groups,
  77. NotBefore: time.Unix(before.Unix(), 0),
  78. NotAfter: time.Unix(after.Unix(), 0),
  79. PublicKey: pub,
  80. IsCA: false,
  81. Issuer: issuer,
  82. InvertedGroups: make(map[string]struct{}),
  83. },
  84. }
  85. err = nc.Sign(ca.Details.Curve, key)
  86. if err != nil {
  87. panic(err)
  88. }
  89. pem, err := nc.MarshalToPEM()
  90. if err != nil {
  91. panic(err)
  92. }
  93. return nc, pub, cert.MarshalX25519PrivateKey(rawPriv), pem
  94. }
  95. func x25519Keypair() ([]byte, []byte) {
  96. privkey := make([]byte, 32)
  97. if _, err := io.ReadFull(rand.Reader, privkey); err != nil {
  98. panic(err)
  99. }
  100. pubkey, err := curve25519.X25519(privkey, curve25519.Basepoint)
  101. if err != nil {
  102. panic(err)
  103. }
  104. return pubkey, privkey
  105. }