more refactor
This commit is contained in:
@@ -11,6 +11,10 @@ import (
|
||||
)
|
||||
|
||||
func Certs(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "POST" {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
var certs_info []map[string]any
|
||||
entires, err := os.ReadDir(os.Getenv("CERTS_PATH"))
|
||||
if err != nil {
|
||||
@@ -43,7 +47,7 @@ func Certs(w http.ResponseWriter, r *http.Request) {
|
||||
new_cert["href"] = fmt.Sprintf("https://%s", entry.Name())
|
||||
new_cert["cert"] = string(certdata)
|
||||
new_cert["key"] = string(keydata)
|
||||
new_cert["certinfo"] = utils.ParseCertificate(fmt.Sprintf("%s/%s/%s.crt", os.Getenv("CERTS_PATH"), entry.Name(), entry.Name()))
|
||||
new_cert["certinfo"] = utils.ParseCert(fmt.Sprintf("%s/%s/%s.crt", os.Getenv("CERTS_PATH"), entry.Name(), entry.Name()))
|
||||
certs_info = append(certs_info, new_cert)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"scm/model"
|
||||
"scm/utils"
|
||||
)
|
||||
|
||||
func CreateCert(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "GET" {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
var requestData model.CreateCertRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&requestData); err != nil {
|
||||
http.Error(w, "invalid JSON format", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
caCert, caKey, err := utils.LoadRootCertAndKey(
|
||||
fmt.Sprintf(
|
||||
"%s/%s/%s.crt",
|
||||
os.Getenv("CERTS_PATH"),
|
||||
"root",
|
||||
"TolaMironcenkoCA",
|
||||
),
|
||||
fmt.Sprintf(
|
||||
"%s/%s/%s.key",
|
||||
os.Getenv("CERTS_PATH"),
|
||||
"root",
|
||||
"TolaMironcenkoCA",
|
||||
),
|
||||
requestData.CAKeyPassword,
|
||||
)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
fmt.Println("error loading certificate and key:", err)
|
||||
return
|
||||
}
|
||||
// TODO: Implement create certificate endpoint
|
||||
serverKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
fmt.Println("error generating server key:", err)
|
||||
return
|
||||
}
|
||||
serverCert, err := utils.CreateServerCert(caCert, caKey, serverKey, requestData)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
fmt.Println("error creating server certificate:", err)
|
||||
return
|
||||
}
|
||||
err = utils.CheckExistsOrCreateDir(requestData.DNSNames[0])
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
err = utils.SavePEMFile(
|
||||
fmt.Sprintf(
|
||||
"%s/%s/%s.crt",
|
||||
os.Getenv("CERTS_PATH"),
|
||||
requestData.DNSNames[0],
|
||||
requestData.DNSNames[0],
|
||||
),
|
||||
"CERTIFICATE",
|
||||
serverCert,
|
||||
)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
fmt.Println("error saving certificate:", err)
|
||||
return
|
||||
}
|
||||
err = utils.SavePEMFile(
|
||||
fmt.Sprintf(
|
||||
"%s/%s/%s.key",
|
||||
os.Getenv("CERTS_PATH"),
|
||||
requestData.DNSNames[0],
|
||||
requestData.DNSNames[0],
|
||||
),
|
||||
"RSA PRIVATE KEY",
|
||||
x509.MarshalPKCS1PrivateKey(serverKey),
|
||||
)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
fmt.Println("error saving private key:", err)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(w, "%s", `{"status": "success", "message": "Certificate created successfully"}`)
|
||||
}
|
||||
|
||||
// func createServerCert(
|
||||
// caCert *x509.Certificate,
|
||||
// caKey *rsa.PrivateKey,
|
||||
// serverKey *rsa.PrivateKey,
|
||||
// certdata model.CreateCertificateRequest,
|
||||
// ) ([]byte, error) {
|
||||
// // Шаблон серверного сертификата
|
||||
// template := x509.Certificate{
|
||||
// SerialNumber: big.NewInt(time.Now().Unix()),
|
||||
// Subject: pkix.Name{
|
||||
// Organization: certdata.OrganizationName,
|
||||
// CommonName: certdata.CommonName,
|
||||
// OrganizationalUnit: certdata.OrganizationUnit,
|
||||
// },
|
||||
// NotBefore: time.Now(),
|
||||
// NotAfter: time.Now().AddDate(1, 0, 0), // 1 год
|
||||
// KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
|
||||
// ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
// DNSNames: certdata.DNSNames,
|
||||
// }
|
||||
|
||||
// // Создаем сертификат, подписанный CA
|
||||
// return x509.CreateCertificate(
|
||||
// rand.Reader,
|
||||
// &template,
|
||||
// caCert,
|
||||
// &serverKey.PublicKey,
|
||||
// caKey,
|
||||
// )
|
||||
// }
|
||||
@@ -9,6 +9,10 @@ import (
|
||||
)
|
||||
|
||||
func DeleteCert(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "GET" {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
var requestData model.DeleteCertRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&requestData); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
@@ -13,6 +13,10 @@ var Frontend embed.FS
|
||||
func SpaHandler(fs http.FileSystem) http.Handler {
|
||||
fileServer := http.FileServer(fs)
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "POST" {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
fmt.Println("/frontend" + r.URL.Path)
|
||||
r.URL.Path = "/frontend" + path.Clean(r.URL.Path)
|
||||
if _, err := fs.Open(path.Clean(r.URL.Path)); err != nil {
|
||||
@@ -1,181 +0,0 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"os"
|
||||
"scm/model"
|
||||
"time"
|
||||
|
||||
"github.com/youmark/pkcs8"
|
||||
)
|
||||
|
||||
func CreateCert(w http.ResponseWriter, r *http.Request) {
|
||||
var requestData model.CreateCertificateRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&requestData); err != nil {
|
||||
http.Error(w, "invalid JSON format", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
caCert, caKey, err := loadCertAndKey(
|
||||
fmt.Sprintf(
|
||||
"%s/%s/%s.crt",
|
||||
os.Getenv("CERTS_PATH"),
|
||||
"root",
|
||||
"TolaMironcenkoCA",
|
||||
),
|
||||
fmt.Sprintf(
|
||||
"%s/%s/%s.key",
|
||||
os.Getenv("CERTS_PATH"),
|
||||
"root",
|
||||
"TolaMironcenkoCA",
|
||||
),
|
||||
requestData.CAKeyPassword,
|
||||
)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
fmt.Println("error loading certificate and key:", err)
|
||||
return
|
||||
}
|
||||
// TODO: Implement create certificate endpoint
|
||||
serverKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
fmt.Println("error generating server key:", err)
|
||||
return
|
||||
}
|
||||
serverCert, err := createServerCert(caCert, caKey, serverKey, requestData)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
fmt.Println("error creating server certificate:", err)
|
||||
return
|
||||
}
|
||||
_, err = os.Stat(fmt.Sprintf("%s/%s", os.Getenv("CERTS_PATH"), requestData.DNSNames[0]))
|
||||
if err == nil {
|
||||
http.Error(w, "certificate already exists", http.StatusConflict)
|
||||
fmt.Println("certificate already exists")
|
||||
return
|
||||
} else if os.IsNotExist(err) {
|
||||
err := os.Mkdir(fmt.Sprintf("%s/%s", os.Getenv("CERTS_PATH"), requestData.DNSNames[0]), 0755)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
fmt.Println("error creating directory:", err)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
fmt.Println("error checking certificate directory:", err)
|
||||
return
|
||||
}
|
||||
err = savePEM(fmt.Sprintf("%s/%s/%s.crt", os.Getenv("CERTS_PATH"), requestData.DNSNames[0], requestData.DNSNames[0]), "CERTIFICATE", serverCert)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
fmt.Println("error saving certificate:", err)
|
||||
return
|
||||
}
|
||||
err = savePEM(fmt.Sprintf("%s/%s/%s.key", os.Getenv("CERTS_PATH"), requestData.DNSNames[0], requestData.DNSNames[0]), "RSA PRIVATE KEY", x509.MarshalPKCS1PrivateKey(serverKey))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
fmt.Println("error saving private key:", err)
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(w, "%s", `{"status": "success", "message": "Certificate created successfully"}`)
|
||||
}
|
||||
|
||||
func createServerCert(
|
||||
caCert *x509.Certificate,
|
||||
caKey *rsa.PrivateKey,
|
||||
serverKey *rsa.PrivateKey,
|
||||
certdata model.CreateCertificateRequest,
|
||||
) ([]byte, error) {
|
||||
// Шаблон серверного сертификата
|
||||
template := x509.Certificate{
|
||||
SerialNumber: big.NewInt(time.Now().Unix()),
|
||||
Subject: pkix.Name{
|
||||
Organization: certdata.OrganizationName,
|
||||
CommonName: certdata.CommonName,
|
||||
OrganizationalUnit: certdata.OrganizationUnit,
|
||||
},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().AddDate(1, 0, 0), // 1 год
|
||||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
DNSNames: certdata.DNSNames,
|
||||
}
|
||||
|
||||
// Создаем сертификат, подписанный CA
|
||||
return x509.CreateCertificate(
|
||||
rand.Reader,
|
||||
&template,
|
||||
caCert,
|
||||
&serverKey.PublicKey,
|
||||
caKey,
|
||||
)
|
||||
}
|
||||
|
||||
func loadCertAndKey(certFile, keyFile, password string) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||
fmt.Println(certFile, keyFile)
|
||||
// Загрузка корневого сертификата
|
||||
caCertPEM, err := os.ReadFile(certFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
block, _ := pem.Decode(caCertPEM)
|
||||
if block == nil {
|
||||
return nil, nil, errors.New("failed to parse CA certificate PEM")
|
||||
}
|
||||
|
||||
caCert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Загрузка зашифрованного приватного ключа
|
||||
keyPEM, err := os.ReadFile(keyFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
block, _ = pem.Decode(keyPEM)
|
||||
if block == nil {
|
||||
return nil, nil, errors.New("failed to parse CA key PEM")
|
||||
}
|
||||
fmt.Print(block.Type)
|
||||
// Декодирование ключа с паролем
|
||||
decryptedKey, err := pkcs8.ParsePKCS8PrivateKey(block.Bytes, []byte(password))
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to decrypt CA key: %v", err)
|
||||
}
|
||||
|
||||
caKey, ok := decryptedKey.(*rsa.PrivateKey)
|
||||
if !ok {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return caCert, caKey, nil
|
||||
}
|
||||
|
||||
func savePEM(filename, blockType string, data []byte) error {
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
err = pem.Encode(file, &pem.Block{
|
||||
Type: blockType,
|
||||
Bytes: data,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -1,42 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"scm/api"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"scm/server"
|
||||
"scm/utils"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := godotenv.Load("./scm.conf")
|
||||
if err != nil {
|
||||
log.Fatal("Error loading .env file")
|
||||
}
|
||||
|
||||
http.Handle("/", api.SpaHandler(http.FS(api.Frontend)))
|
||||
http.HandleFunc("/api/certs", api.Certs)
|
||||
http.HandleFunc("/api/certs/create", api.CreateCert)
|
||||
http.HandleFunc("/api/certs/delete", api.DeleteCert)
|
||||
|
||||
if os.Getenv("ENABLE_TLS") == "true" {
|
||||
e := http.ListenAndServeTLS(
|
||||
os.Getenv("SERVER_ADDRESS")+":"+os.Getenv("SERVER_PORT"),
|
||||
os.Getenv("CERT_FILE"),
|
||||
os.Getenv("KEY_FILE"),
|
||||
nil,
|
||||
)
|
||||
if e != nil {
|
||||
log.Fatal(e)
|
||||
}
|
||||
} else {
|
||||
e := http.ListenAndServe(
|
||||
os.Getenv("SERVER_ADDRESS")+":"+os.Getenv("SERVER_PORT"),
|
||||
nil,
|
||||
)
|
||||
if e != nil {
|
||||
log.Fatal(e)
|
||||
}
|
||||
}
|
||||
utils.LoadEnv()
|
||||
server.Configure()
|
||||
server.Run()
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package model
|
||||
|
||||
type CreateCertificateRequest struct {
|
||||
type CreateCertRequest struct {
|
||||
CommonName string `json:"commonname"`
|
||||
OrganizationName []string `json:"organizationname"`
|
||||
OrganizationUnit []string `json:"organizationunit"`
|
||||
@@ -0,0 +1,13 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"scm/api"
|
||||
)
|
||||
|
||||
func Configure() {
|
||||
http.Handle("/", api.SpaHandler(http.FS(api.Frontend)))
|
||||
http.HandleFunc("/api/certs", api.Certs)
|
||||
http.HandleFunc("/api/certs/create", api.CreateCert)
|
||||
http.HandleFunc("/api/certs/delete", api.DeleteCert)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
func Run() {
|
||||
if os.Getenv("ENABLE_TLS") == "true" {
|
||||
err := http.ListenAndServeTLS(
|
||||
os.Getenv("SERVER_ADDRESS")+":"+os.Getenv("SERVER_PORT"),
|
||||
os.Getenv("CERT_FILE"),
|
||||
os.Getenv("KEY_FILE"),
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
err := http.ListenAndServe(
|
||||
os.Getenv("SERVER_ADDRESS")+":"+os.Getenv("SERVER_PORT"),
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func CheckExistsOrCreateDir(dnsname string) error {
|
||||
_, err := os.Stat(fmt.Sprintf("%s/%s", os.Getenv("CERTS_PATH"), dnsname))
|
||||
if err == nil {
|
||||
fmt.Println("certificate already exists")
|
||||
return fmt.Errorf("%s", "certificate already exists")
|
||||
} else if os.IsNotExist(err) {
|
||||
err := os.Mkdir(fmt.Sprintf("%s/%s", os.Getenv("CERTS_PATH"), dnsname), 0755)
|
||||
if err != nil {
|
||||
fmt.Println("error creating directory:", err)
|
||||
return fmt.Errorf("%s", "error creating directory")
|
||||
}
|
||||
} else {
|
||||
fmt.Println("error checking certificate directory:", err)
|
||||
return fmt.Errorf("%s", "error checking certificate directory")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"math/big"
|
||||
"scm/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CreateServerCert(
|
||||
caCert *x509.Certificate,
|
||||
caKey *rsa.PrivateKey,
|
||||
serverKey *rsa.PrivateKey,
|
||||
certdata model.CreateCertRequest,
|
||||
) ([]byte, error) {
|
||||
// Шаблон серверного сертификата
|
||||
template := x509.Certificate{
|
||||
SerialNumber: big.NewInt(time.Now().Unix()),
|
||||
Subject: pkix.Name{
|
||||
Organization: certdata.OrganizationName,
|
||||
CommonName: certdata.CommonName,
|
||||
OrganizationalUnit: certdata.OrganizationUnit,
|
||||
},
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().AddDate(1, 0, 0), // 1 год
|
||||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
DNSNames: certdata.DNSNames,
|
||||
}
|
||||
|
||||
// Создаем сертификат, подписанный CA
|
||||
return x509.CreateCertificate(
|
||||
rand.Reader,
|
||||
&template,
|
||||
caCert,
|
||||
&serverKey.PublicKey,
|
||||
caKey,
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func LoadEnv() {
|
||||
err := godotenv.Load("./scm.conf")
|
||||
if err != nil {
|
||||
log.Fatal("Error loading .env file")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/youmark/pkcs8"
|
||||
)
|
||||
|
||||
func LoadRootCertAndKey(certFile, keyFile, password string) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||
fmt.Println(certFile, keyFile)
|
||||
// Загрузка корневого сертификата
|
||||
caCertPEM, err := os.ReadFile(certFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
block, _ := pem.Decode(caCertPEM)
|
||||
if block == nil {
|
||||
return nil, nil, errors.New("failed to parse CA certificate PEM")
|
||||
}
|
||||
|
||||
caCert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Загрузка зашифрованного приватного ключа
|
||||
keyPEM, err := os.ReadFile(keyFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
block, _ = pem.Decode(keyPEM)
|
||||
if block == nil {
|
||||
return nil, nil, errors.New("failed to parse CA key PEM")
|
||||
}
|
||||
fmt.Print(block.Type)
|
||||
// Декодирование ключа с паролем
|
||||
decryptedKey, err := pkcs8.ParsePKCS8PrivateKey(block.Bytes, []byte(password))
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to decrypt CA key: %v", err)
|
||||
}
|
||||
|
||||
caKey, ok := decryptedKey.(*rsa.PrivateKey)
|
||||
if !ok {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return caCert, caKey, nil
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
func ParseCertificate(certPath string) map[string]any {
|
||||
func ParseCert(certPath string) map[string]any {
|
||||
// Чтение PEM-файла
|
||||
pemData, err := os.ReadFile(certPath)
|
||||
if err != nil {
|
||||
@@ -0,0 +1,23 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/pem"
|
||||
"os"
|
||||
)
|
||||
|
||||
func SavePEMFile(filename, blockType string, data []byte) error {
|
||||
file, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
err = pem.Encode(file, &pem.Block{
|
||||
Type: blockType,
|
||||
Bytes: data,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user