tls.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. package serverctl
  2. import (
  3. "crypto/ed25519"
  4. ssl "crypto/tls"
  5. "crypto/x509"
  6. "encoding/json"
  7. "encoding/pem"
  8. "errors"
  9. "fmt"
  10. "github.com/gravitl/netmaker/database"
  11. "github.com/gravitl/netmaker/tls"
  12. )
  13. // SaveCert - save a certificate to file and DB
  14. func SaveCert(path, name string, cert *x509.Certificate) error {
  15. if err := SaveCertToDB(name, cert); err != nil {
  16. return err
  17. }
  18. return tls.SaveCertToFile(path, name, cert)
  19. }
  20. // SaveCertToDB - save a certificate to the certs database
  21. func SaveCertToDB(name string, cert *x509.Certificate) error {
  22. if certBytes := pem.EncodeToMemory(&pem.Block{
  23. Type: "CERTIFICATE",
  24. Bytes: cert.Raw,
  25. }); len(certBytes) > 0 {
  26. data, err := json.Marshal(&certBytes)
  27. if err != nil {
  28. return fmt.Errorf("failed to marshal certificate - %v ", err)
  29. }
  30. return database.Insert(name, string(data), database.CERTS_TABLE_NAME)
  31. } else {
  32. return fmt.Errorf("failed to write cert to DB - %s ", name)
  33. }
  34. }
  35. // SaveKey - save a private key (ed25519) to file and DB
  36. func SaveKey(path, name string, key ed25519.PrivateKey) error {
  37. if err := SaveKeyToDB(name, key); err != nil {
  38. return err
  39. }
  40. return tls.SaveKeyToFile(path, name, key)
  41. }
  42. // SaveKeyToDB - save a private key (ed25519) to the specified path
  43. func SaveKeyToDB(name string, key ed25519.PrivateKey) error {
  44. privBytes, err := x509.MarshalPKCS8PrivateKey(key)
  45. if err != nil {
  46. return fmt.Errorf("failed to marshal key %v ", err)
  47. }
  48. if pemBytes := pem.EncodeToMemory(&pem.Block{
  49. Type: "PRIVATE KEY",
  50. Bytes: privBytes,
  51. }); len(pemBytes) > 0 {
  52. data, err := json.Marshal(&pemBytes)
  53. if err != nil {
  54. return fmt.Errorf("failed to marshal key %v ", err)
  55. }
  56. return database.Insert(name, string(data), database.CERTS_TABLE_NAME)
  57. } else {
  58. return fmt.Errorf("failed to write key to DB - %v ", err)
  59. }
  60. }
  61. // ReadCertFromDB - reads a certificate from the database
  62. func ReadCertFromDB(name string) (*x509.Certificate, error) {
  63. certString, err := database.FetchRecord(database.CERTS_TABLE_NAME, name)
  64. if err != nil {
  65. return nil, fmt.Errorf("unable to read file %w", err)
  66. }
  67. var certBytes []byte
  68. if err = json.Unmarshal([]byte(certString), &certBytes); err != nil {
  69. return nil, fmt.Errorf("unable to unmarshal db cert %w", err)
  70. }
  71. block, _ := pem.Decode(certBytes)
  72. if block == nil || block.Type != "CERTIFICATE" {
  73. return nil, errors.New("not a cert " + block.Type)
  74. }
  75. cert, err := x509.ParseCertificate(block.Bytes)
  76. if err != nil {
  77. return nil, fmt.Errorf("unable to parse cert %w", err)
  78. }
  79. return cert, nil
  80. }
  81. // ReadKeyFromDB - reads a private key (ed25519) from the database
  82. func ReadKeyFromDB(name string) (*ed25519.PrivateKey, error) {
  83. keyString, err := database.FetchRecord(database.CERTS_TABLE_NAME, name)
  84. if err != nil {
  85. return nil, fmt.Errorf("unable to read key value from db - %w", err)
  86. }
  87. var bytes []byte
  88. if err = json.Unmarshal([]byte(keyString), &bytes); err != nil {
  89. return nil, fmt.Errorf("unable to unmarshal db key - %w", err)
  90. }
  91. keyBytes, _ := pem.Decode(bytes)
  92. key, err := x509.ParsePKCS8PrivateKey(keyBytes.Bytes)
  93. if err != nil {
  94. return nil, fmt.Errorf("unable to parse key from DB - %w", err)
  95. }
  96. private := key.(ed25519.PrivateKey)
  97. return &private, nil
  98. }
  99. // SaveClientCertToDB - saves client cert for servers to connect to MQ broker with
  100. func SaveClientCertToDB(serverClientPemPath, serverClientKeyPath string, ca *x509.Certificate) error {
  101. certpool := x509.NewCertPool()
  102. ok := certpool.AppendCertsFromPEM(ca.Raw)
  103. if !ok {
  104. return fmt.Errorf("failed to append root cert to server client cert")
  105. }
  106. clientKeyPair, err := ssl.LoadX509KeyPair(serverClientPemPath, serverClientKeyPath)
  107. if err != nil {
  108. return err
  109. }
  110. certs := []ssl.Certificate{clientKeyPair}
  111. netmakerClientCert := ssl.Config{
  112. RootCAs: certpool,
  113. ClientAuth: ssl.NoClientCert,
  114. ClientCAs: nil,
  115. Certificates: certs,
  116. InsecureSkipVerify: false,
  117. }
  118. data, err := json.Marshal(netmakerClientCert)
  119. if err != nil {
  120. return err
  121. }
  122. return database.Insert(tls.SERVER_CLIENT_ENTRY, string(data), database.CERTS_TABLE_NAME)
  123. }
  124. // ReadClientCertFromDB - reads the client cert from the DB
  125. func ReadClientCertFromDB() (*ssl.Config, error) {
  126. var netmakerClientCert ssl.Config
  127. record, err := database.FetchRecord(database.CERTS_TABLE_NAME, tls.SERVER_CLIENT_ENTRY)
  128. if err != nil {
  129. return nil, err
  130. }
  131. if err = json.Unmarshal([]byte(record), &netmakerClientCert); err != nil {
  132. return nil, err
  133. }
  134. return &netmakerClientCert, err
  135. }