|
|
package cert
|
|
|
|
|
|
import (
|
|
|
"b612.me/starcrypto"
|
|
|
"b612.me/stario"
|
|
|
"b612.me/starlog"
|
|
|
"crypto"
|
|
|
"crypto/x509"
|
|
|
"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 enPasswd 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(",")
|
|
|
}
|
|
|
}
|
|
|
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)
|
|
|
}
|
|
|
key, err := LoadPriv(caKey, caKeyPwd)
|
|
|
if err != nil {
|
|
|
starlog.Errorln("加载Key错误", err)
|
|
|
os.Exit(1)
|
|
|
}
|
|
|
csr := outputCsr(GenerateCsr(country, province, city, org, orgUnit, name, dnsName), key)
|
|
|
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)
|
|
|
}
|
|
|
var caKeyRaw crypto.PrivateKey
|
|
|
var caCertRaw *x509.Certificate
|
|
|
var err error
|
|
|
if !isCa {
|
|
|
caKeyRaw, caCertRaw, err = LoadCA(caKey, caCert, caKeyPwd)
|
|
|
if err != nil {
|
|
|
starlog.Errorln("加载CA错误", err)
|
|
|
os.Exit(1)
|
|
|
}
|
|
|
} else {
|
|
|
caKeyRaw, err = LoadPriv(caKey, 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)
|
|
|
}
|
|
|
certReq := &x509.Certificate{
|
|
|
Subject: csrRaw.Subject,
|
|
|
IsCA: isCa,
|
|
|
NotBefore: start,
|
|
|
NotAfter: end,
|
|
|
MaxPathLen: maxPathLen,
|
|
|
MaxPathLenZero: maxPathLenZero,
|
|
|
}
|
|
|
if isCa {
|
|
|
caCertRaw = certReq
|
|
|
}
|
|
|
cert, err := MakeCert(caKeyRaw, caCertRaw, certReq, 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", "CN", "国家")
|
|
|
CmdCsr.Flags().StringVarP(&province, "province", "p", "B612", "省份")
|
|
|
CmdCsr.Flags().StringVarP(&city, "city", "t", "B612", "城市")
|
|
|
CmdCsr.Flags().StringVarP(&org, "org", "o", "", "组织")
|
|
|
CmdCsr.Flags().StringVarP(&orgUnit, "orgUnit", "u", "", "组织单位")
|
|
|
CmdCsr.Flags().StringVarP(&name, "name", "n", "Starainrt", "通用名称")
|
|
|
CmdCsr.Flags().StringSliceVarP(&dnsName, "dnsName", "d", nil, "dns名称")
|
|
|
CmdCsr.Flags().StringVarP(&savefolder, "savefolder", "s", "./", "保存文件夹")
|
|
|
CmdCsr.Flags().StringVarP(&caKey, "secret-key", "k", "", "加密私钥")
|
|
|
CmdCsr.Flags().StringVarP(&caKeyPwd, "secret-key-passwd", "K", "", "加密私钥的密码")
|
|
|
//CmdCsr.Flags().BoolVarP(&isCa, "isCa", "A", false, "是否是CA")
|
|
|
//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().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私钥密码")
|
|
|
CmdGen.Flags().BoolVarP(&isCa, "isCa", "A", false, "是否是CA")
|
|
|
CmdGen.Flags().StringVarP(&startStr, "start", "S", time.Now().Format(time.RFC3339), "开始时间,格式:2006-01-02T15:04:05Z07:00")
|
|
|
CmdGen.Flags().StringVarP(&endStr, "end", "E", time.Now().AddDate(1, 0, 0).Format(time.RFC3339), "结束时间,格式:2006-01-02T15:04:05Z07:00")
|
|
|
CmdGen.Flags().BoolVarP(&maxPathLenZero, "maxPathLenZero", "z", false, "允许最大路径长度为0")
|
|
|
CmdGen.Flags().IntVarP(&maxPathLen, "maxPathLen", "m", 0, "最大路径长度")
|
|
|
Cmd.AddCommand(CmdGen)
|
|
|
|
|
|
CmdParse.Flags().StringVarP(&passwd, "passwd", "p", "", "pfx解密密码")
|
|
|
Cmd.AddCommand(CmdParse)
|
|
|
|
|
|
CmdPkcs8.Flags().StringVarP(&passwd, "passwd", "p", "", "解密密码")
|
|
|
CmdPkcs8.Flags().StringVarP(&savefolder, "savefolder", "s", ".", "保存文件夹")
|
|
|
CmdPkcs8.Flags().StringVarP(&enPasswd, "en-passwd", "P", "", "加密密码")
|
|
|
Cmd.AddCommand(CmdPkcs8)
|
|
|
CmdPkcs1.Flags().StringVarP(&passwd, "passwd", "p", "", "解密密码")
|
|
|
CmdPkcs1.Flags().StringVarP(&savefolder, "savefolder", "s", ".", "保存文件夹")
|
|
|
CmdPkcs1.Flags().StringVarP(&enPasswd, "en-passwd", "P", "", "加密密码")
|
|
|
Cmd.AddCommand(CmdPkcs1)
|
|
|
CmdPkcs12.Flags().StringVarP(&passwd, "passwd", "p", "", "pfx解密密码")
|
|
|
CmdPkcs12.Flags().StringVarP(&enPasswd, "pfx-passwd", "P", "", "pfx加密密码")
|
|
|
CmdPkcs12.Flags().StringVarP(&savefolder, "savefolder", "s", ".", "保存文件夹")
|
|
|
Cmd.AddCommand(CmdPkcs12)
|
|
|
|
|
|
CmdBasic.Flags().StringVarP(&passwd, "passwd", "p", "", "解密密码")
|
|
|
CmdBasic.Flags().StringVarP(&savefolder, "savefolder", "s", ".", "保存文件夹")
|
|
|
CmdBasic.Flags().StringVarP(&enPasswd, "en-passwd", "P", "", "加密密码")
|
|
|
Cmd.AddCommand(CmdBasic)
|
|
|
|
|
|
CmdOpenssh.Flags().StringVarP(&passwd, "passwd", "p", "", "解密密码")
|
|
|
CmdOpenssh.Flags().StringVarP(&savefolder, "savefolder", "s", ".", "保存文件夹")
|
|
|
CmdOpenssh.Flags().StringVarP(&enPasswd, "en-passwd", "P", "", "加密密码")
|
|
|
Cmd.AddCommand(CmdOpenssh)
|
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
}
|
|
|
err = Pkcs8(data, passwd, enPasswd, filepath.Base(v), savefolder)
|
|
|
if err != nil {
|
|
|
starlog.Errorln("pkcs8转换错误", err)
|
|
|
continue
|
|
|
}
|
|
|
fmt.Println("\n-------" + v + "转换完毕---------\n")
|
|
|
}
|
|
|
},
|
|
|
}
|
|
|
|
|
|
var CmdPkcs1 = &cobra.Command{
|
|
|
Use: "pkcs1",
|
|
|
Short: "pkcs1转换",
|
|
|
Long: "pkcs1转换",
|
|
|
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
|
|
|
}
|
|
|
err = Pkcs1(data, passwd, enPasswd, filepath.Base(v), savefolder)
|
|
|
if err != nil {
|
|
|
starlog.Errorln("pkcs1转换错误", err)
|
|
|
continue
|
|
|
}
|
|
|
fmt.Println("\n-------" + v + "转换完毕---------\n")
|
|
|
}
|
|
|
},
|
|
|
}
|
|
|
|
|
|
var CmdPkcs12 = &cobra.Command{
|
|
|
Use: "pkcs12",
|
|
|
Short: "pkcs12转换",
|
|
|
Long: "pkcs12转换",
|
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
|
if len(args) == 0 {
|
|
|
starlog.Errorln("请输入证书文件")
|
|
|
os.Exit(1)
|
|
|
}
|
|
|
var keys []any
|
|
|
var certs []x509.Certificate
|
|
|
|
|
|
for _, v := range args {
|
|
|
data, err := os.ReadFile(v)
|
|
|
if err != nil {
|
|
|
starlog.Errorln("读取证书错误", err)
|
|
|
continue
|
|
|
}
|
|
|
key, cert, err := GetCert(data, passwd)
|
|
|
if err != nil {
|
|
|
starlog.Errorln("证书读取错误", err)
|
|
|
os.Exit(1)
|
|
|
}
|
|
|
keys = append(keys, key...)
|
|
|
certs = append(certs, cert...)
|
|
|
}
|
|
|
err := Pkcs12(keys, certs, enPasswd, filepath.Base(args[0]), savefolder)
|
|
|
if err != nil {
|
|
|
starlog.Errorln("pkcs12转换错误", err)
|
|
|
os.Exit(1)
|
|
|
}
|
|
|
fmt.Println("\n-------pfk转换完毕---------\n")
|
|
|
},
|
|
|
}
|
|
|
|
|
|
var CmdBasic = &cobra.Command{
|
|
|
Use: "basic",
|
|
|
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
|
|
|
}
|
|
|
err = Tran(data, passwd, filepath.Base(v), savefolder)
|
|
|
if err != nil {
|
|
|
starlog.Errorln("证书转换错误", err)
|
|
|
continue
|
|
|
}
|
|
|
fmt.Println("\n-------" + v + "转换完毕---------\n")
|
|
|
}
|
|
|
},
|
|
|
}
|
|
|
|
|
|
var CmdOpenssh = &cobra.Command{
|
|
|
Use: "openssh",
|
|
|
Short: "openssh转换",
|
|
|
Long: "openssh转换",
|
|
|
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
|
|
|
}
|
|
|
err = Openssh(data, passwd, enPasswd, filepath.Base(v), savefolder)
|
|
|
if err != nil {
|
|
|
starlog.Errorln("openssh转换错误", err)
|
|
|
continue
|
|
|
}
|
|
|
fmt.Println("\n-------" + v + "转换完毕---------\n")
|
|
|
}
|
|
|
},
|
|
|
}
|