|
|
|
|
package cert
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"b612.me/starcrypto"
|
|
|
|
|
"b612.me/stario"
|
|
|
|
|
"b612.me/starlog"
|
|
|
|
|
"fmt"
|
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var country, province, city, org, orgUnit, name string
|
|
|
|
|
var dnsName []string
|
|
|
|
|
var start, end time.Time
|
|
|
|
|
var startStr, endStr string
|
|
|
|
|
var savefolder string
|
|
|
|
|
var promptMode bool
|
|
|
|
|
var isCa bool
|
|
|
|
|
var maxPathLenZero bool
|
|
|
|
|
var maxPathLen int
|
|
|
|
|
|
|
|
|
|
var caKey string
|
|
|
|
|
var caCert string
|
|
|
|
|
var csr string
|
|
|
|
|
var pubKey string
|
|
|
|
|
var caKeyPwd string
|
|
|
|
|
var passwd string
|
|
|
|
|
|
|
|
|
|
var Cmd = &cobra.Command{
|
|
|
|
|
Use: "cert",
|
|
|
|
|
Short: "证书生成与解析",
|
|
|
|
|
Long: "证书生成与解析",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var CmdCsr = &cobra.Command{
|
|
|
|
|
Use: "csr",
|
|
|
|
|
Short: "生成证书请求",
|
|
|
|
|
Long: "生成证书请求",
|
|
|
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
|
|
|
var err error
|
|
|
|
|
if promptMode {
|
|
|
|
|
if country == "" {
|
|
|
|
|
country = stario.MessageBox("请输入国家:", "").MustString()
|
|
|
|
|
}
|
|
|
|
|
if province == "" {
|
|
|
|
|
province = stario.MessageBox("请输入省份:", "").MustString()
|
|
|
|
|
}
|
|
|
|
|
if city == "" {
|
|
|
|
|
city = stario.MessageBox("请输入城市:", "").MustString()
|
|
|
|
|
}
|
|
|
|
|
if org == "" {
|
|
|
|
|
org = stario.MessageBox("请输入组织:", "").MustString()
|
|
|
|
|
}
|
|
|
|
|
if orgUnit == "" {
|
|
|
|
|
orgUnit = stario.MessageBox("请输入组织单位:", "").MustString()
|
|
|
|
|
}
|
|
|
|
|
if name == "" {
|
|
|
|
|
name = stario.MessageBox("请输入通用名称:", "").MustString()
|
|
|
|
|
}
|
|
|
|
|
if dnsName == nil {
|
|
|
|
|
dnsName = stario.MessageBox("请输入dns名称,用逗号分割:", "").MustSliceString(",")
|
|
|
|
|
}
|
|
|
|
|
if startStr == "" {
|
|
|
|
|
startStr = stario.MessageBox("请输入开始时间:", "").MustString()
|
|
|
|
|
}
|
|
|
|
|
if endStr == "" {
|
|
|
|
|
endStr = stario.MessageBox("请输入结束时间:", "").MustString()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
start, err = time.Parse(time.RFC3339, startStr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("开始时间格式错误,格式:2006-01-02T15:04:05Z07:00", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
end, err = time.Parse(time.RFC3339, endStr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("结束时间格式错误,格式:2006-01-02T15:04:05Z07:00", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
csr := outputCsr(GenerateCsr(country, province, city, org, orgUnit, name, dnsName, start, end, isCa, maxPathLenZero, maxPathLen))
|
|
|
|
|
err = os.WriteFile(savefolder+"/"+name+".csr", csr, 0644)
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("保存csr文件错误", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
starlog.Infoln("保存csr文件成功", savefolder+"/"+name+".csr")
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var CmdGen = &cobra.Command{
|
|
|
|
|
Use: "gen",
|
|
|
|
|
Short: "生成证书",
|
|
|
|
|
Long: "生成证书",
|
|
|
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
|
|
|
if caKey == "" {
|
|
|
|
|
starlog.Errorln("CA私钥不能为空")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
if caCert == "" {
|
|
|
|
|
starlog.Errorln("CA证书不能为空")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
if csr == "" {
|
|
|
|
|
starlog.Errorln("证书请求不能为空")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
if pubKey == "" {
|
|
|
|
|
starlog.Errorln("证书公钥不能为空")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
caKeyRaw, caCertRaw, err := LoadCA(caKey, caCert, caKeyPwd)
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("加载CA错误", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
csrRaw, err := LoadCsr(csr)
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("加载证书请求错误", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
pubKeyByte, err := os.ReadFile(pubKey)
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("加载公钥错误", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
pubKeyRaw, err := starcrypto.DecodePublicKey(pubKeyByte)
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("解析公钥错误", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
cert, err := MakeCert(caKeyRaw, caCertRaw, csrRaw, pubKeyRaw)
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("生成证书错误", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
err = os.WriteFile(savefolder+"/"+csrRaw.Subject.CommonName+".crt", cert, 0644)
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("保存证书错误", err)
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
starlog.Infoln("保存证书成功", savefolder+"/"+csrRaw.Subject.CommonName+".crt")
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var CmdParse = &cobra.Command{
|
|
|
|
|
Use: "parse",
|
|
|
|
|
Short: "解析证书",
|
|
|
|
|
Long: "解析证书",
|
|
|
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
|
|
|
if len(args) == 0 {
|
|
|
|
|
starlog.Errorln("请输入证书文件")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
for _, v := range args {
|
|
|
|
|
data, err := os.ReadFile(v)
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("读取证书错误", err)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
ParseCert(data, passwd)
|
|
|
|
|
fmt.Println("\n-------" + v + "解析完毕---------\n")
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
|
Cmd.AddCommand(CmdCsr)
|
|
|
|
|
CmdCsr.Flags().BoolVarP(&promptMode, "prompt", "P", false, "是否交互模式")
|
|
|
|
|
CmdCsr.Flags().StringVarP(&country, "country", "c", "", "国家")
|
|
|
|
|
CmdCsr.Flags().StringVarP(&province, "province", "p", "", "省份")
|
|
|
|
|
CmdCsr.Flags().StringVarP(&city, "city", "t", "", "城市")
|
|
|
|
|
CmdCsr.Flags().StringVarP(&org, "org", "o", "", "组织")
|
|
|
|
|
CmdCsr.Flags().StringVarP(&orgUnit, "orgUnit", "u", "", "组织单位")
|
|
|
|
|
CmdCsr.Flags().StringVarP(&name, "name", "n", "", "通用名称")
|
|
|
|
|
CmdCsr.Flags().StringSliceVarP(&dnsName, "dnsName", "d", nil, "dns名称")
|
|
|
|
|
CmdCsr.Flags().StringVarP(&startStr, "start", "S", time.Now().Format(time.RFC3339), "开始时间,格式:2006-01-02T15:04:05Z07:00")
|
|
|
|
|
CmdCsr.Flags().StringVarP(&endStr, "end", "E", time.Now().AddDate(1, 0, 0).Format(time.RFC3339), "结束时间,格式:2006-01-02T15:04:05Z07:00")
|
|
|
|
|
CmdCsr.Flags().StringVarP(&savefolder, "savefolder", "s", "./", "保存文件夹")
|
|
|
|
|
CmdCsr.Flags().BoolVarP(&isCa, "isCa", "A", false, "是否是CA")
|
|
|
|
|
CmdCsr.Flags().BoolVarP(&maxPathLenZero, "maxPathLenZero", "z", false, "允许最大路径长度为0")
|
|
|
|
|
CmdCsr.Flags().IntVarP(&maxPathLen, "maxPathLen", "m", 0, "最大路径长度")
|
|
|
|
|
|
|
|
|
|
CmdGen.Flags().StringVarP(&caKey, "caKey", "k", "", "CA私钥")
|
|
|
|
|
CmdGen.Flags().StringVarP(&caCert, "caCert", "C", "", "CA证书")
|
|
|
|
|
CmdGen.Flags().StringVarP(&csr, "csr", "r", "", "证书请求")
|
|
|
|
|
CmdGen.Flags().StringVarP(&pubKey, "pubKey", "P", "", "证书公钥")
|
|
|
|
|
CmdGen.Flags().StringVarP(&savefolder, "savefolder", "s", "./", "保存文件夹")
|
|
|
|
|
CmdGen.Flags().StringVarP(&caKeyPwd, "caKeyPwd", "p", "", "CA私钥密码")
|
|
|
|
|
Cmd.AddCommand(CmdGen)
|
|
|
|
|
|
|
|
|
|
CmdParse.Flags().StringVarP(&passwd, "passwd", "p", "", "证书密码")
|
|
|
|
|
Cmd.AddCommand(CmdParse)
|
|
|
|
|
CmdPkcs8.Flags().StringVarP(&passwd, "passwd", "p", "", "证书密码")
|
|
|
|
|
CmdPkcs8.Flags().StringVarP(&savefolder, "savefolder", "s", "./", "保存文件夹")
|
|
|
|
|
Cmd.AddCommand(CmdPkcs8)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var CmdPkcs8 = &cobra.Command{
|
|
|
|
|
Use: "pkcs8",
|
|
|
|
|
Short: "pkcs8转换",
|
|
|
|
|
Long: "pkcs8转换",
|
|
|
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
|
|
|
if len(args) == 0 {
|
|
|
|
|
starlog.Errorln("请输入证书文件")
|
|
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
for _, v := range args {
|
|
|
|
|
data, err := os.ReadFile(v)
|
|
|
|
|
if err != nil {
|
|
|
|
|
starlog.Errorln("读取证书错误", err)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
Pkcs8(data, passwd, filepath.Base(v), savefolder)
|
|
|
|
|
fmt.Println("\n-------" + v + "转换完毕---------\n")
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
}
|