cert.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /*
  2. * Copyright (c)2013-2020 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2025-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. package cli
  14. import (
  15. "encoding/json"
  16. "fmt"
  17. "io/ioutil"
  18. "zerotier/pkg/zerotier"
  19. )
  20. func interactiveMakeSubject() *zerotier.CertificateSubject {
  21. s := new(zerotier.CertificateSubject)
  22. return s
  23. }
  24. func Cert(basePath string, authTokenGenerator func() string, args []string, jsonOutput bool) int {
  25. if len(args) < 1 {
  26. Help()
  27. return 1
  28. }
  29. switch args[0] {
  30. case "list":
  31. case "show":
  32. if len(args) != 1 {
  33. Help()
  34. return 1
  35. }
  36. case "newsid":
  37. if len(args) > 2 {
  38. Help()
  39. return 1
  40. }
  41. uniqueId, uniqueIdPrivate, err := zerotier.NewCertificateSubjectUniqueId(zerotier.CertificateUniqueIdTypeNistP384)
  42. if err != nil {
  43. pErr("unable to create unique ID and private key: %s", err.Error())
  44. return 1
  45. }
  46. sec, err := json.MarshalIndent(&zerotier.CertificateSubjectUniqueIDSecret{
  47. UniqueID: uniqueId,
  48. UniqueIDSecret: uniqueIdPrivate,
  49. }, "", " ")
  50. if err != nil {
  51. pErr("unable to create unique ID and private key: %s", err.Error())
  52. return 1
  53. }
  54. if len(args) == 1 {
  55. fmt.Println(string(sec))
  56. } else {
  57. _ = ioutil.WriteFile(args[1], sec, 0600)
  58. pResult("%s", args[1])
  59. }
  60. case "newcsr":
  61. if len(args) != 4 {
  62. Help()
  63. return 1
  64. }
  65. var subject zerotier.CertificateSubject
  66. err := readJSONFile(args[1], &subject)
  67. if err != nil {
  68. pErr("unable to read subject from %s: %s", args[1], err.Error())
  69. return 1
  70. }
  71. var uniqueIdSecret zerotier.CertificateSubjectUniqueIDSecret
  72. err = readJSONFile(args[2], &uniqueIdSecret)
  73. if err != nil {
  74. pErr("unable to read unique ID secret from %s: %s", args[2], err.Error())
  75. return 1
  76. }
  77. csr, err := zerotier.NewCertificateCSR(&subject, uniqueIdSecret.UniqueID, uniqueIdSecret.UniqueIDSecret)
  78. if err != nil {
  79. pErr("problem creating CSR: %s", err.Error())
  80. return 1
  81. }
  82. err = ioutil.WriteFile(args[3], csr, 0644)
  83. if err == nil {
  84. pResult("%s", args[3])
  85. } else {
  86. pErr("unable to write CSR to %s: %s", args[3], err.Error())
  87. return 1
  88. }
  89. case "sign":
  90. if len(args) != 4 {
  91. Help()
  92. return 1
  93. }
  94. csrBytes, err := ioutil.ReadFile(args[1])
  95. if err != nil {
  96. pErr("unable to read CSR from %s: %s", args[1], err.Error())
  97. return 1
  98. }
  99. csr, err := zerotier.NewCertificateFromBytes(csrBytes, false)
  100. if err != nil {
  101. pErr("CSR in %s is invalid: %s", args[1], err.Error())
  102. return 1
  103. }
  104. signingIdentity := cliGetIdentityOrFatal(args[2])
  105. if signingIdentity == nil {
  106. pErr("unable to read identity from %s", args[2])
  107. return 1
  108. }
  109. if !signingIdentity.HasPrivate() {
  110. pErr("signing identity in %s lacks private key", args[2])
  111. return 1
  112. }
  113. cert, err := csr.Sign(signingIdentity)
  114. if err != nil {
  115. pErr("error signing CSR or generating certificate: %s", err.Error())
  116. return 1
  117. }
  118. cb, err := cert.Marshal()
  119. if err != nil {
  120. pErr("error marshaling signed certificate: %s", err.Error())
  121. return 1
  122. }
  123. err = ioutil.WriteFile(args[3], cb, 0644)
  124. if err == nil {
  125. pResult("%s", args[3])
  126. } else {
  127. pErr("unable to write signed certificate to %s: %s", args[3], err.Error())
  128. return 1
  129. }
  130. case "verify", "dump":
  131. if len(args) != 2 {
  132. Help()
  133. return 1
  134. }
  135. certBytes, err := ioutil.ReadFile(args[1])
  136. if err != nil {
  137. pErr("unable to read certificate from %s: %s", args[1], err.Error())
  138. return 1
  139. }
  140. cert, err := zerotier.NewCertificateFromBytes(certBytes, true)
  141. if err != nil {
  142. pErr("certificate in %s invalid: %s", args[1], err.Error())
  143. return 1
  144. }
  145. if args[0] == "dump" {
  146. fmt.Println(cert.JSON())
  147. } else {
  148. fmt.Println("OK")
  149. }
  150. case "import":
  151. case "restore":
  152. case "export":
  153. case "delete":
  154. }
  155. return 0
  156. }