sign_test.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package cert
  2. import (
  3. "crypto/ecdsa"
  4. "crypto/ed25519"
  5. "crypto/elliptic"
  6. "crypto/rand"
  7. "net/netip"
  8. "strings"
  9. "testing"
  10. "time"
  11. "github.com/slackhq/nebula/cert/p256"
  12. "github.com/stretchr/testify/assert"
  13. "github.com/stretchr/testify/require"
  14. )
  15. func TestCertificateV1_Sign(t *testing.T) {
  16. before := time.Now().Add(time.Second * -60).Round(time.Second)
  17. after := time.Now().Add(time.Second * 60).Round(time.Second)
  18. pubKey := []byte("1234567890abcedfghij1234567890ab")
  19. tbs := TBSCertificate{
  20. Version: Version1,
  21. Name: "testing",
  22. Networks: []netip.Prefix{
  23. mustParsePrefixUnmapped("10.1.1.1/24"),
  24. mustParsePrefixUnmapped("10.1.1.2/16"),
  25. },
  26. UnsafeNetworks: []netip.Prefix{
  27. mustParsePrefixUnmapped("9.1.1.2/24"),
  28. mustParsePrefixUnmapped("9.1.1.3/24"),
  29. },
  30. Groups: []string{"test-group1", "test-group2", "test-group3"},
  31. NotBefore: before,
  32. NotAfter: after,
  33. PublicKey: pubKey,
  34. IsCA: false,
  35. }
  36. pub, priv, err := ed25519.GenerateKey(rand.Reader)
  37. c, err := tbs.Sign(&certificateV1{details: detailsV1{notBefore: before, notAfter: after}}, Curve_CURVE25519, priv)
  38. require.NoError(t, err)
  39. assert.NotNil(t, c)
  40. assert.True(t, c.CheckSignature(pub))
  41. b, err := c.Marshal()
  42. require.NoError(t, err)
  43. uc, err := unmarshalCertificateV1(b, nil)
  44. require.NoError(t, err)
  45. assert.NotNil(t, uc)
  46. }
  47. func TestCertificateV1_SignP256(t *testing.T) {
  48. before := time.Now().Add(time.Second * -60).Round(time.Second)
  49. after := time.Now().Add(time.Second * 60).Round(time.Second)
  50. pubKey := []byte("01234567890abcedfghij1234567890ab1234567890abcedfghij1234567890ab")
  51. tbs := TBSCertificate{
  52. Version: Version1,
  53. Name: "testing",
  54. Networks: []netip.Prefix{
  55. mustParsePrefixUnmapped("10.1.1.1/24"),
  56. mustParsePrefixUnmapped("10.1.1.2/16"),
  57. },
  58. UnsafeNetworks: []netip.Prefix{
  59. mustParsePrefixUnmapped("9.1.1.2/24"),
  60. mustParsePrefixUnmapped("9.1.1.3/16"),
  61. },
  62. Groups: []string{"test-group1", "test-group2", "test-group3"},
  63. NotBefore: before,
  64. NotAfter: after,
  65. PublicKey: pubKey,
  66. IsCA: false,
  67. Curve: Curve_P256,
  68. }
  69. priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  70. require.NoError(t, err)
  71. pub := elliptic.Marshal(elliptic.P256(), priv.PublicKey.X, priv.PublicKey.Y)
  72. rawPriv := priv.D.FillBytes(make([]byte, 32))
  73. c, err := tbs.Sign(&certificateV1{details: detailsV1{notBefore: before, notAfter: after}}, Curve_P256, rawPriv)
  74. require.NoError(t, err)
  75. assert.NotNil(t, c)
  76. assert.True(t, c.CheckSignature(pub))
  77. b, err := c.Marshal()
  78. require.NoError(t, err)
  79. uc, err := unmarshalCertificateV1(b, nil)
  80. require.NoError(t, err)
  81. assert.NotNil(t, uc)
  82. }
  83. func TestCertificate_SignP256_AlwaysNormalized(t *testing.T) {
  84. before := time.Now().Add(time.Second * -60).Round(time.Second)
  85. after := time.Now().Add(time.Second * 60).Round(time.Second)
  86. pubKey := []byte("01234567890abcedfghij1234567890ab1234567890abcedfghij1234567890ab")
  87. tbs := TBSCertificate{
  88. Version: Version1,
  89. Name: "testing",
  90. Networks: []netip.Prefix{
  91. mustParsePrefixUnmapped("10.1.1.1/24"),
  92. mustParsePrefixUnmapped("10.1.1.2/16"),
  93. },
  94. UnsafeNetworks: []netip.Prefix{
  95. mustParsePrefixUnmapped("9.1.1.2/24"),
  96. mustParsePrefixUnmapped("9.1.1.3/16"),
  97. },
  98. Groups: []string{"test-group1", "test-group2", "test-group3"},
  99. NotBefore: before,
  100. NotAfter: after,
  101. PublicKey: pubKey,
  102. IsCA: true,
  103. Curve: Curve_P256,
  104. }
  105. priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
  106. require.NoError(t, err)
  107. pub := elliptic.Marshal(elliptic.P256(), priv.PublicKey.X, priv.PublicKey.Y)
  108. rawPriv := priv.D.FillBytes(make([]byte, 32))
  109. for i := range 1000 {
  110. if i&1 == 1 {
  111. tbs.Version = Version1
  112. } else {
  113. tbs.Version = Version2
  114. }
  115. c, err := tbs.Sign(nil, Curve_P256, rawPriv)
  116. require.NoError(t, err)
  117. assert.NotNil(t, c)
  118. assert.True(t, c.CheckSignature(pub))
  119. normie, err := p256.IsNormalized(c.Signature())
  120. require.NoError(t, err)
  121. assert.True(t, normie)
  122. }
  123. }
  124. func TestCertificateV2_SignRejectsUnparseable(t *testing.T) {
  125. _, priv, err := ed25519.GenerateKey(rand.Reader)
  126. require.NoError(t, err)
  127. var invalid *ErrInvalidCertificateProperties
  128. newTBS := func() TBSCertificate {
  129. return TBSCertificate{
  130. Version: Version2,
  131. Name: "testing",
  132. Networks: []netip.Prefix{mustParsePrefixUnmapped("10.1.1.1/24")},
  133. Groups: []string{"test-group1"},
  134. NotBefore: time.Now().Add(-time.Minute),
  135. NotAfter: time.Now().Add(time.Minute),
  136. PublicKey: []byte("1234567890abcedfghij1234567890ab"),
  137. Curve: Curve_CURVE25519,
  138. IsCA: true,
  139. }
  140. }
  141. tbs := newTBS()
  142. tbs.Name = strings.Repeat("a", MaxNameLength)
  143. c, err := tbs.Sign(nil, Curve_CURVE25519, priv)
  144. require.NoError(t, err)
  145. b, err := c.Marshal()
  146. require.NoError(t, err)
  147. _, err = unmarshalCertificateV2(b, nil, Curve_CURVE25519)
  148. require.NoError(t, err)
  149. tbs = newTBS()
  150. tbs.Name = strings.Repeat("a", MaxNameLength+1)
  151. _, err = tbs.Sign(nil, Curve_CURVE25519, priv)
  152. require.ErrorAs(t, err, &invalid)
  153. tbs = newTBS()
  154. tbs.Name = ""
  155. _, err = tbs.Sign(nil, Curve_CURVE25519, priv)
  156. require.ErrorAs(t, err, &invalid)
  157. tbs = newTBS()
  158. tbs.Groups = []string{"test-group1", ""}
  159. _, err = tbs.Sign(nil, Curve_CURVE25519, priv)
  160. require.ErrorAs(t, err, &invalid)
  161. }