mirror of
https://github.com/usual2970/certimate.git
synced 2025-06-08 13:39:53 +00:00
refactor: extract x509 transformer utils
This commit is contained in:
parent
295b7779ee
commit
43b2ff7957
@ -1,21 +1,15 @@
|
|||||||
package deployer
|
package deployer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/pem"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/pavlo-v-chernykh/keystore-go/v4"
|
|
||||||
"github.com/pocketbase/pocketbase/models"
|
"github.com/pocketbase/pocketbase/models"
|
||||||
"software.sslmate.com/src/go-pkcs12"
|
|
||||||
|
|
||||||
"github.com/usual2970/certimate/internal/applicant"
|
"github.com/usual2970/certimate/internal/applicant"
|
||||||
"github.com/usual2970/certimate/internal/domain"
|
"github.com/usual2970/certimate/internal/domain"
|
||||||
"github.com/usual2970/certimate/internal/pkg/utils/x509"
|
|
||||||
"github.com/usual2970/certimate/internal/utils/app"
|
"github.com/usual2970/certimate/internal/utils/app"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -167,57 +161,3 @@ func toStr(tag string, data any) string {
|
|||||||
byts, _ := json.Marshal(data)
|
byts, _ := json.Marshal(data)
|
||||||
return tag + ":" + string(byts)
|
return tag + ":" + string(byts)
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertPEMToPFX(certificate string, privateKey string, password string) ([]byte, error) {
|
|
||||||
cert, err := x509.ParseCertificateFromPEM(certificate)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
privkey, err := x509.ParsePKCS1PrivateKeyFromPEM(privateKey)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pfxData, err := pkcs12.LegacyRC2.Encode(privkey, cert, nil, password)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return pfxData, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertPEMToJKS(certificate string, privateKey string, alias string, keypass string, storepass string) ([]byte, error) {
|
|
||||||
certBlock, _ := pem.Decode([]byte(certificate))
|
|
||||||
if certBlock == nil {
|
|
||||||
return nil, errors.New("failed to decode certificate PEM")
|
|
||||||
}
|
|
||||||
|
|
||||||
privkeyBlock, _ := pem.Decode([]byte(privateKey))
|
|
||||||
if privkeyBlock == nil {
|
|
||||||
return nil, errors.New("failed to decode private key PEM")
|
|
||||||
}
|
|
||||||
|
|
||||||
ks := keystore.New()
|
|
||||||
entry := keystore.PrivateKeyEntry{
|
|
||||||
CreationTime: time.Now(),
|
|
||||||
PrivateKey: privkeyBlock.Bytes,
|
|
||||||
CertificateChain: []keystore.Certificate{
|
|
||||||
{
|
|
||||||
Type: "X509",
|
|
||||||
Content: certBlock.Bytes,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := ks.SetPrivateKeyEntry(alias, entry, []byte(keypass)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
if err := ks.Store(&buf, []byte(storepass)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
xerrors "github.com/pkg/errors"
|
xerrors "github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/usual2970/certimate/internal/pkg/utils/fs"
|
"github.com/usual2970/certimate/internal/pkg/utils/fs"
|
||||||
|
"github.com/usual2970/certimate/internal/pkg/utils/x509"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LocalDeployer struct {
|
type LocalDeployer struct {
|
||||||
@ -73,7 +74,7 @@ func (d *LocalDeployer) Deploy(ctx context.Context) error {
|
|||||||
d.infos = append(d.infos, toStr("保存私钥成功", nil))
|
d.infos = append(d.infos, toStr("保存私钥成功", nil))
|
||||||
|
|
||||||
case certFormatPFX:
|
case certFormatPFX:
|
||||||
pfxData, err := convertPEMToPFX(
|
pfxData, err := x509.TransformCertificateFromPEMToPFX(
|
||||||
d.option.Certificate.Certificate,
|
d.option.Certificate.Certificate,
|
||||||
d.option.Certificate.PrivateKey,
|
d.option.Certificate.PrivateKey,
|
||||||
d.option.DeployConfig.GetConfigAsString("pfxPassword"),
|
d.option.DeployConfig.GetConfigAsString("pfxPassword"),
|
||||||
@ -89,7 +90,7 @@ func (d *LocalDeployer) Deploy(ctx context.Context) error {
|
|||||||
d.infos = append(d.infos, toStr("保存证书成功", nil))
|
d.infos = append(d.infos, toStr("保存证书成功", nil))
|
||||||
|
|
||||||
case certFormatJKS:
|
case certFormatJKS:
|
||||||
jksData, err := convertPEMToJKS(
|
jksData, err := x509.TransformCertificateFromPEMToJKS(
|
||||||
d.option.Certificate.Certificate,
|
d.option.Certificate.Certificate,
|
||||||
d.option.Certificate.PrivateKey,
|
d.option.Certificate.PrivateKey,
|
||||||
d.option.DeployConfig.GetConfigAsString("jksAlias"),
|
d.option.DeployConfig.GetConfigAsString("jksAlias"),
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
|
|
||||||
"github.com/usual2970/certimate/internal/domain"
|
"github.com/usual2970/certimate/internal/domain"
|
||||||
|
"github.com/usual2970/certimate/internal/pkg/utils/x509"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SSHDeployer struct {
|
type SSHDeployer struct {
|
||||||
@ -78,7 +79,7 @@ func (d *SSHDeployer) Deploy(ctx context.Context) error {
|
|||||||
d.infos = append(d.infos, toStr("SSH 上传私钥成功", nil))
|
d.infos = append(d.infos, toStr("SSH 上传私钥成功", nil))
|
||||||
|
|
||||||
case certFormatPFX:
|
case certFormatPFX:
|
||||||
pfxData, err := convertPEMToPFX(
|
pfxData, err := x509.TransformCertificateFromPEMToPFX(
|
||||||
d.option.Certificate.Certificate,
|
d.option.Certificate.Certificate,
|
||||||
d.option.Certificate.PrivateKey,
|
d.option.Certificate.PrivateKey,
|
||||||
d.option.DeployConfig.GetConfigAsString("pfxPassword"),
|
d.option.DeployConfig.GetConfigAsString("pfxPassword"),
|
||||||
@ -94,7 +95,7 @@ func (d *SSHDeployer) Deploy(ctx context.Context) error {
|
|||||||
d.infos = append(d.infos, toStr("SSH 上传证书成功", nil))
|
d.infos = append(d.infos, toStr("SSH 上传证书成功", nil))
|
||||||
|
|
||||||
case certFormatJKS:
|
case certFormatJKS:
|
||||||
jksData, err := convertPEMToJKS(
|
jksData, err := x509.TransformCertificateFromPEMToJKS(
|
||||||
d.option.Certificate.Certificate,
|
d.option.Certificate.Certificate,
|
||||||
d.option.Certificate.PrivateKey,
|
d.option.Certificate.PrivateKey,
|
||||||
d.option.DeployConfig.GetConfigAsString("jksAlias"),
|
d.option.DeployConfig.GetConfigAsString("jksAlias"),
|
||||||
|
87
internal/pkg/utils/x509/transformer.go
Normal file
87
internal/pkg/utils/x509/transformer.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package x509
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/pem"
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/pavlo-v-chernykh/keystore-go/v4"
|
||||||
|
"software.sslmate.com/src/go-pkcs12"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 将 PEM 编码的证书字符串转换为 PFX 格式。
|
||||||
|
//
|
||||||
|
// 入参:
|
||||||
|
// - certPem: 证书 PEM 内容。
|
||||||
|
// - privkeyPem: 私钥 PEM 内容。
|
||||||
|
// - pfxPassword: PFX 导出密码。
|
||||||
|
//
|
||||||
|
// 出参:
|
||||||
|
// - data: PFX 格式的证书数据。
|
||||||
|
// - err: 错误。
|
||||||
|
func TransformCertificateFromPEMToPFX(certPem string, privkeyPem string, pfxPassword string) ([]byte, error) {
|
||||||
|
cert, err := ParseCertificateFromPEM(certPem)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
privkey, err := ParsePKCS1PrivateKeyFromPEM(privkeyPem)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pfxData, err := pkcs12.LegacyRC2.Encode(privkey, cert, nil, pfxPassword)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pfxData, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将 PEM 编码的证书字符串转换为 JKS 格式。
|
||||||
|
//
|
||||||
|
// 入参:
|
||||||
|
// - certPem: 证书 PEM 内容。
|
||||||
|
// - privkeyPem: 私钥 PEM 内容。
|
||||||
|
// - jksAlias: JKS 别名。
|
||||||
|
// - jksKeypass: JKS 密钥密码。
|
||||||
|
// - jksStorepass: JKS 存储密码。
|
||||||
|
//
|
||||||
|
// 出参:
|
||||||
|
// - data: JKS 格式的证书数据。
|
||||||
|
// - err: 错误。
|
||||||
|
func TransformCertificateFromPEMToJKS(certPem string, privkeyPem string, jksAlias string, jksKeypass string, jksStorepass string) ([]byte, error) {
|
||||||
|
certBlock, _ := pem.Decode([]byte(certPem))
|
||||||
|
if certBlock == nil {
|
||||||
|
return nil, errors.New("failed to decode certificate PEM")
|
||||||
|
}
|
||||||
|
|
||||||
|
privkeyBlock, _ := pem.Decode([]byte(privkeyPem))
|
||||||
|
if privkeyBlock == nil {
|
||||||
|
return nil, errors.New("failed to decode private key PEM")
|
||||||
|
}
|
||||||
|
|
||||||
|
ks := keystore.New()
|
||||||
|
entry := keystore.PrivateKeyEntry{
|
||||||
|
CreationTime: time.Now(),
|
||||||
|
PrivateKey: privkeyBlock.Bytes,
|
||||||
|
CertificateChain: []keystore.Certificate{
|
||||||
|
{
|
||||||
|
Type: "X509",
|
||||||
|
Content: certBlock.Bytes,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ks.SetPrivateKeyEntry(jksAlias, entry, []byte(jksKeypass)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if err := ks.Store(&buf, []byte(jksStorepass)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user