【调整】暗色主题样式

This commit is contained in:
cai
2025-12-12 17:39:52 +08:00
parent 13669666e4
commit d01b42139c
1199 changed files with 203816 additions and 4592 deletions

View File

@@ -0,0 +1,428 @@
package private_ca
import (
"ALLinSSL/backend/public"
"encoding/json"
"fmt"
"time"
)
func CreateRootCA(name, commonName, organization, organizationalUnit, country, province, locality, keyType string, keyBits, validDays int64) error {
var err error
var data *CAConfig
if keyType == "sm2" {
// 国密SM2根证书 - 生成签名和加密双证书, 使用不同私钥
data, err = GenerateRootCASM2(name, commonName, organization, organizationalUnit, country, province, locality, int(validDays))
} else {
// 标准根证书 - 生成单一证书
data, err = GenerateRootCAStandard(name, commonName, organization, organizationalUnit, country, province, locality, KeyType(keyType), int(keyBits), int(validDays))
}
if err != nil {
return err
}
// 保存到数据库
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
_, err = s.Insert(public.StructToMap(data, true))
if err != nil {
return err
}
return nil
}
func CreateIntermediateCA(name, commonName, organization, organizationalUnit, country, province, locality string, rootId, keyBits, validDays int64) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
issuers, err := s.Where("id=?", []interface{}{rootId}).Select()
if err != nil {
return err
}
if len(issuers) == 0 {
return fmt.Errorf("issuer with id %d not found", rootId)
}
issuer := issuers[0]
keyType := issuer["algorithm"].(string)
cert := issuer["cert"].(string)
key := issuer["key"].(string)
var data *CAConfig
if keyType == "sm2" {
// 国密SM2中级证书 - 生成签名和加密双证书, 使用不同私钥
enCert := issuer["en_cert"].(string)
enKey := issuer["en_key"].(string)
data, err = GenerateIntermediateCASM2(name, commonName, organization, organizationalUnit, country, province, locality, cert, key, enCert, enKey, int(validDays))
} else {
// 标准中级证书 - 生成单一证书
data, err = GenerateIntermediateCAStandard(name, commonName, organization, organizationalUnit, country, province, locality, cert, key, keyType, int(keyBits), int(validDays))
}
if err != nil {
return err
}
// 保存到数据库
insertData := public.StructToMap(data, true)
insertData["root_id"] = rootId
_, err = s.Insert(insertData)
if err != nil {
return err
}
return nil
}
func DeleteCA(id int64) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
// 检查是否有子证书
children, err := s.Where("root_id=?", []interface{}{id}).Select()
if err != nil {
return err
}
if len(children) > 0 {
return fmt.Errorf("cannot delete CA with id %d: it has child CAs", id)
}
_, err = s.Where("id=?", []interface{}{id}).Delete()
if err != nil {
return err
}
return nil
}
func ListCAs(search, level string, p, limit int64) ([]map[string]interface{}, int, error) {
s, err := GetSqlite()
if err != nil {
return nil, 0, err
}
defer s.Close()
var data []map[string]any
var count int64
var limits []int64
if p >= 0 && limit >= 0 {
limits = []int64{0, limit}
if p > 1 {
limits[0] = (p - 1) * limit
limits[1] = limit
}
}
whereStr := "1=1"
var params []interface{}
if search != "" {
whereStr += " and (name like ? or cn like ?)"
params = append(params, "%"+search+"%", "%"+search+"%")
}
if level == "root" {
whereStr += " and root_id is null"
}
if level == "intermediate" {
whereStr += " and root_id is not null"
}
data, err = s.Where(whereStr, params).Limit(limits).Order("create_time", "desc").Select()
count, err = s.Where(whereStr, params).Limit(limits).Count()
if err != nil {
return data, int(count), err
}
return data, int(count), nil
}
func CreateLeafCert(caId, usage, keyBits, validDays int64, cn, san string) (*LeafCertConfig, error) {
if caId <= 0 {
return nil, fmt.Errorf("CA ID不能为空")
}
if san == "" {
return nil, fmt.Errorf("备用名称不能为空")
}
var sans SAN
err := json.Unmarshal([]byte(san), &sans)
if err != nil {
return nil, fmt.Errorf("备用名称格式错误: %v", err)
}
if cn == "" {
if len(sans.DNSNames) > 0 {
cn = sans.DNSNames[0]
} else if len(sans.IPAddresses) > 0 {
cn = string(sans.IPAddresses[0])
} else if len(sans.EmailAddresses) > 0 {
cn = sans.EmailAddresses[0]
} else {
return nil, fmt.Errorf("CN和SAN不能为空")
}
}
s, err := GetSqlite()
if err != nil {
return nil, err
}
defer s.Close()
issuers, err := s.Where("id=?", []interface{}{caId}).Select()
if err != nil {
return nil, err
}
if len(issuers) == 0 {
return nil, fmt.Errorf("issuer with id %d not found", caId)
}
issuer := issuers[0]
if issuer["root_id"] == "" || issuer["root_id"] == nil {
return nil, fmt.Errorf("不允许使用根证书直接签发叶子证书,请先创建中间证书")
}
keyType := issuer["algorithm"].(string)
cert := issuer["cert"].(string)
key := issuer["key"].(string)
var issuerObj *Certificate
if keyType == "sm2" {
enCert := issuer["en_cert"].(string)
enKey := issuer["en_key"].(string)
issuerObj, err = NewCertificateFromPEMSM2([]byte(cert), []byte(key), []byte(enCert), []byte(enKey))
} else {
issuerObj, err = NewCertificateFromPEMStandard([]byte(cert), []byte(key), KeyType(keyType))
}
leafObj, err := GenerateLeafCertificate(cn, sans, issuerObj, KeyType(keyType), int(usage), int(keyBits), int(validDays))
if err != nil {
return nil, err
}
s.TableName = "leaf"
// 保存到数据库
leafObj.SAN = san
leafObj.CaId = caId
insertData := public.StructToMap(leafObj, true)
_, err = s.Insert(insertData)
if err != nil {
return nil, err
}
return leafObj, nil
}
func ListLeafCerts(caId int64, search string, p, limit int64) ([]map[string]interface{}, int, error) {
s, err := GetSqlite()
if err != nil {
return nil, 0, err
}
defer s.Close()
s.TableName = "leaf"
var data []map[string]any
var count int64
var limits []int64
sql := `
select leaf.*, ca.name as ca_name, ca.cn as ca_cn
from leaf
left join ca on leaf.ca_id = ca.id
where 1=1
`
// 拼接查询条件
var params []interface{}
if caId > 0 {
sql += " and leaf.ca_id = ?"
params = append(params, caId)
}
if search != "" {
sql += " and (leaf.cn like ? or leaf.san like ?)"
params = append(params, "%"+search+"%", "%"+search+"%")
}
sql += " order by leaf.create_time desc"
sqlCount := "select count(id) as count from (" + sql + ")"
if p > 0 && limit > 0 {
limits = []int64{0, limit}
if p > 1 {
limits[0] = (p - 1) * limit
limits[1] = limit
}
sql += fmt.Sprintf(" limit %d offset %d", limits[1], limits[0])
}
data, err = s.Query(sql, params...)
if err != nil {
return data, 0, err
}
countResult, err := s.Query(sqlCount, params...)
if err != nil {
return data, 0, err
}
if len(countResult) > 0 {
count = countResult[0]["count"].(int64)
}
return data, int(count), nil
}
func DeleteLeafCert(id int64) error {
s, err := GetSqlite()
if err != nil {
return err
}
defer s.Close()
s.TableName = "leaf"
_, err = s.Where("id=?", []interface{}{id}).Delete()
if err != nil {
return err
}
return nil
}
func GetCert(id int64, certType string) (map[string]any, error) {
s, err := GetSqlite()
if err != nil {
return nil, err
}
defer s.Close()
s.TableName = certType
leafs, err := s.Where("id=?", []interface{}{id}).Select()
if err != nil {
return nil, err
}
if len(leafs) == 0 {
return nil, fmt.Errorf("leaf cert with id %d not found", id)
}
return leafs[0], nil
}
func WorkflowCreateLeafCert(params map[string]any, logger *public.Logger) (map[string]any, error) {
caId, ok := params["ca_id"].(float64)
if !ok || caId <= 0 {
return nil, fmt.Errorf("ca_id参数错误")
}
keyBits, ok := params["key_length"].(float64)
if !ok {
return nil, fmt.Errorf("key_length参数错误")
}
validDays, ok := params["valid_days"].(float64)
if !ok {
return nil, fmt.Errorf("valid_days参数错误")
}
endDay, ok := params["end_day"].(float64)
if !ok {
endDay = 0
}
cn, ok := params["cn"].(string)
if !ok {
cn = ""
}
san, ok := params["san"].(string)
if !ok || san == "" {
return nil, fmt.Errorf("san参数错误")
}
// 先获取ca信息确认是中间证书且不能是国密
s, err := GetSqlite()
if err != nil {
return nil, err
}
defer s.Close()
issuers, err := s.Where("id=?", []interface{}{caId}).Select()
if err != nil {
return nil, err
}
if len(issuers) == 0 {
return nil, fmt.Errorf("issuer with id %d not found", caId)
}
issuer := issuers[0]
if issuer["root_id"] == "" || issuer["root_id"] == nil {
return nil, fmt.Errorf("不允许使用根证书直接签发叶子证书,请先创建中间证书")
}
keyType := issuer["algorithm"].(string)
if keyType == "sm2" {
return nil, fmt.Errorf("暂不兼容国密证书,请使用标准证书")
}
// 判断中间证书不能为已过期,过期时间不能超过中间证书
caNotAfter, err := time.Parse("2006-01-02 15:04:05", issuer["not_after"].(string))
if err != nil {
return nil, fmt.Errorf("解析中间证书过期时间失败: %v", err)
}
maxValidDays := caNotAfter.Sub(time.Now()).Hours() / 24
if maxValidDays <= 0 {
return nil, fmt.Errorf("中间证书已过期,不能签发叶子证书")
}
if validDays > maxValidDays {
return nil, fmt.Errorf("叶子证书的有效期不能超过中间证书的有效期,中间证书将在 %s 过期,距离今天还有 %d 天", caNotAfter.Format("2006-01-02"), int(maxValidDays))
}
// 解析san判断数据库中是否已存在相同的cn和san
var sans SAN
err = json.Unmarshal([]byte(san), &sans)
if err != nil {
return nil, fmt.Errorf("备用名称格式错误: %v", err)
}
if cn == "" {
if len(sans.DNSNames) > 0 {
cn = sans.DNSNames[0]
} else {
cn = string(sans.IPAddresses[0])
}
}
s.TableName = "leaf"
// 获取所有未过期的证书判断是否有相同的cn和san
leafs, err := s.Where("ca_id=? and not_after>? and usage=1", []interface{}{caId, time.Now().Format("2006-01-02 15:04:05")}).Select()
if err != nil {
return nil, err
}
var certificate map[string]any
for _, v := range leafs {
// 判断剩余天数是否满足要求
if endDay > 0 {
notAfter, err := time.Parse("2006-01-02 15:04:05", v["not_after"].(string))
if err != nil {
continue
}
remainDays := notAfter.Sub(time.Now()).Hours() / 24
if remainDays < endDay {
continue
}
}
// 判断cn和san是否相同
if v["cn"] == cn {
var existingSAN SAN
err = json.Unmarshal([]byte(v["san"].(string)), &existingSAN)
if err != nil {
continue
}
if public.ContainsAllIgnoreBRepeats(existingSAN.DNSNames, sans.DNSNames) {
var existingIPs, newIPs []string
for _, ip := range existingSAN.IPAddresses {
existingIPs = append(existingIPs, ip.String())
}
for _, ip := range sans.IPAddresses {
newIPs = append(newIPs, ip.String())
}
if public.ContainsAllIgnoreBRepeats(existingIPs, newIPs) {
// 找到相同的证书,标记为跳过
logger.Debug("找到相同的证书,跳过创建", "id", v["id"])
certificate = map[string]any{
"cert": v["cert"],
"key": v["key"],
"skip": true,
}
break
}
}
}
}
if certificate == nil {
leaf, err := CreateLeafCert(int64(caId), 1, int64(keyBits), int64(validDays), cn, san)
if err != nil {
return nil, err
}
certificate = map[string]any{
"cert": leaf.Cert,
"key": leaf.Key,
}
}
return certificate, nil
}