allinssl/backend/internal/cert/cert.go

205 lines
4.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package cert
import (
"ALLinSSL/backend/public"
"fmt"
"strconv"
"strings"
"time"
)
func GetSqlite() (*public.Sqlite, error) {
s, err := public.NewSqlite("data/data.db", "")
if err != nil {
return nil, err
}
s.TableName = "cert"
return s, nil
}
func GetList(search string, p, limit int64) ([]map[string]any, int, error) {
var data []map[string]any
var count int64
s, err := GetSqlite()
if err != nil {
return data, 0, err
}
defer s.Close()
var limits []int64
if p >= 0 && limit >= 0 {
limits = []int64{0, limit}
if p > 1 {
limits[0] = (p - 1) * limit
limits[1] = limit
}
}
if search != "" {
count, err = s.Where("domains like ?", []interface{}{"%" + search + "%"}).Count()
data, err = s.Where("domains like ?", []interface{}{"%" + search + "%"}).Limit(limits).Order("end_time", "esc").Select()
} else {
count, err = s.Count()
data, err = s.Order("end_time", "esc").Limit(limits).Select()
}
if err != nil {
return data, 0, err
}
for _, v := range data {
endtime, err := time.Parse("2006-01-02 15:04:05", v["end_time"].(string))
if err != nil {
continue
}
v["end_day"] = strconv.FormatInt(int64(endtime.Sub(time.Now())/(24*time.Hour)), 10)
}
return data, int(count), nil
}
func AddCert(source, key, cert, issuer, issuerCert, domains, sha256, historyId, startTime, endTime, endDay string) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
workflowId := ""
if historyId != "" {
s, err := public.NewSqlite("data/data.db", "")
if err != nil {
return err
}
s.TableName = "workflow_history"
defer s.Close()
// 查询 workflowId
wh, err := s.Where("id=?", []interface{}{historyId}).Select()
if err != nil {
return err
}
if len(wh) > 0 {
workflowId = wh[0]["workflow_id"].(string)
}
}
now := time.Now().Format("2006-01-02 15:04:05")
_, err = s.Insert(map[string]any{
"source": source,
"key": key,
"cert": cert,
"issuer": issuer,
"issuer_cert": issuerCert,
"domains": domains,
"sha256": sha256,
"history_id": historyId,
"workflow_id": workflowId,
"create_time": now,
"update_time": now,
"start_time": startTime,
"end_time": endTime,
"end_day": endDay,
})
if err != nil {
return err
}
return nil
}
func SaveCert(source, key, cert, issuerCert, historyId string) (string, error) {
if err := public.ValidateSSLCertificate(cert, key); err != nil {
return "", err
}
certObj, err := public.ParseCertificate([]byte(cert))
if err != nil {
return "", fmt.Errorf("解析证书失败: %v", err)
}
// SHA256
sha256, err := public.GetSHA256(cert)
if err != nil {
return "", fmt.Errorf("获取 SHA256 失败: %v", err)
}
if d, _ := GetCert(sha256); d != nil {
return sha256, nil
}
domainSet := make(map[string]bool)
if certObj.Subject.CommonName != "" {
domainSet[certObj.Subject.CommonName] = true
}
for _, dns := range certObj.DNSNames {
domainSet[dns] = true
}
// 转成切片并拼接成逗号分隔的字符串
var domains []string
for domain := range domainSet {
domains = append(domains, domain)
}
domainList := strings.Join(domains, ",")
// 提取 CA 名称Issuer 的组织名)
caName := "UNKNOWN"
if len(certObj.Issuer.Organization) > 0 {
caName = certObj.Issuer.Organization[0]
} else if certObj.Issuer.CommonName != "" {
caName = certObj.Issuer.CommonName
}
// 证书有效期
startTime := certObj.NotBefore.Format("2006-01-02 15:04:05")
endTime := certObj.NotAfter.Format("2006-01-02 15:04:05")
endDay := fmt.Sprintf("%d", int(certObj.NotAfter.Sub(time.Now()).Hours()/24))
err = AddCert(source, key, cert, caName, issuerCert, domainList, sha256, historyId, startTime, endTime, endDay)
if err != nil {
return "", fmt.Errorf("保存证书失败: %v", err)
}
return sha256, nil
}
func UploadCert(key, cert string) (string, error) {
sha256, err := SaveCert("upload", key, cert, "", "")
if err != nil {
return sha256, fmt.Errorf("保存证书失败: %v", err)
}
return sha256, nil
}
func DelCert(id string) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
_, err = s.Where("id=?", []interface{}{id}).Delete()
if err != nil {
return err
}
return nil
}
func GetCert(id string) (map[string]string, error) {
s, err := GetSqlite()
if err != nil {
return nil, err
}
defer s.Close()
res, err := s.Where("id=? or sha256=?", []interface{}{id, id}).Select()
if err != nil {
return nil, err
}
if len(res) == 0 {
return nil, fmt.Errorf("证书不存在")
}
data := map[string]string{
"domains": res[0]["domains"].(string),
"cert": res[0]["cert"].(string),
"key": res[0]["key"].(string),
}
return data, nil
}
// ========================================================