mirror of
https://github.com/certimate-go/certimate.git
synced 2026-09-24 23:10:13 +08:00
feat: enhance certificate model with subjectName, issuerName, and validationPolicy fields
This commit is contained in:
@@ -17,30 +17,35 @@ const CollectionNameCertificate = "certificate"
|
||||
|
||||
type Certificate struct {
|
||||
Meta
|
||||
Source CertificateSourceType `db:"source" json:"source"`
|
||||
SubjectAltNames string `db:"subjectAltNames" json:"subjectAltNames"`
|
||||
SerialNumber string `db:"serialNumber" json:"serialNumber"`
|
||||
Certificate string `db:"certificate" json:"certificate"`
|
||||
PrivateKey string `db:"privateKey" json:"privateKey"`
|
||||
IssuerOrg string `db:"issuerOrg" json:"issuerOrg"`
|
||||
IssuerCertificate string `db:"issuerCertificate" json:"issuerCertificate"`
|
||||
KeyAlgorithm CertificateKeyAlgorithmType `db:"keyAlgorithm" json:"keyAlgorithm"`
|
||||
ValidityNotBefore time.Time `db:"validityNotBefore" json:"validityNotBefore"`
|
||||
ValidityNotAfter time.Time `db:"validityNotAfter" json:"validityNotAfter"`
|
||||
ValidityInterval int32 `db:"validityInterval" json:"validityInterval"`
|
||||
ACMEAcctUrl string `db:"acmeAcctUrl" json:"acmeAcctUrl"`
|
||||
ACMECertUrl string `db:"acmeCertUrl" json:"acmeCertUrl"`
|
||||
IsRenewed bool `db:"isRenewed" json:"isRenewed"`
|
||||
IsRevoked bool `db:"isRevoked" json:"isRevoked"`
|
||||
WorkflowId string `db:"workflowRef" json:"workflowId"`
|
||||
WorkflowRunId string `db:"workflowRunRef" json:"workflowRunId"`
|
||||
WorkflowNodeId string `db:"workflowNodeId" json:"workflowNodeId"`
|
||||
DeletedAt *time.Time `db:"deleted" json:"deleted"`
|
||||
Source CertificateSourceType `db:"source" json:"source"`
|
||||
Certificate string `db:"certificate" json:"certificate"`
|
||||
PrivateKey string `db:"privateKey" json:"privateKey"`
|
||||
SerialNumber string `db:"serialNumber" json:"serialNumber"`
|
||||
SubjectName string `db:"subjectName" json:"subjectName"`
|
||||
SubjectAltNames string `db:"subjectAltNames" json:"subjectAltNames"`
|
||||
IssuerName string `db:"issuerName" json:"issuerName"`
|
||||
IssuerOrg string `db:"issuerOrg" json:"issuerOrg"`
|
||||
IssuerCertificate string `db:"issuerCertificate" json:"issuerCertificate"`
|
||||
KeyAlgorithm CertificateKeyAlgorithmType `db:"keyAlgorithm" json:"keyAlgorithm"`
|
||||
ValidationPolicy CertificateValidationPolicyType `db:"validationPolicy" json:"validationPolicy"`
|
||||
ValidityNotBefore time.Time `db:"validityNotBefore" json:"validityNotBefore"`
|
||||
ValidityNotAfter time.Time `db:"validityNotAfter" json:"validityNotAfter"`
|
||||
ValidityInterval int32 `db:"validityInterval" json:"validityInterval"`
|
||||
ACMEAcctUrl string `db:"acmeAcctUrl" json:"acmeAcctUrl"`
|
||||
ACMECertUrl string `db:"acmeCertUrl" json:"acmeCertUrl"`
|
||||
IsRenewed bool `db:"isRenewed" json:"isRenewed"`
|
||||
IsRevoked bool `db:"isRevoked" json:"isRevoked"`
|
||||
WorkflowId string `db:"workflowRef" json:"workflowId"`
|
||||
WorkflowRunId string `db:"workflowRunRef" json:"workflowRunId"`
|
||||
WorkflowNodeId string `db:"workflowNodeId" json:"workflowNodeId"`
|
||||
DeletedAt *time.Time `db:"deleted" json:"deleted"`
|
||||
}
|
||||
|
||||
func (c *Certificate) PopulateFromX509(certX509 *x509.Certificate) *Certificate {
|
||||
c.SubjectAltNames = strings.Join(xcertx509.GetSubjectAltNames(certX509), ";")
|
||||
c.SerialNumber = strings.ToUpper(certX509.SerialNumber.Text(16))
|
||||
c.SubjectName = certX509.Subject.CommonName
|
||||
c.SubjectAltNames = strings.Join(xcertx509.GetSubjectAltNames(certX509), ";")
|
||||
c.IssuerName = certX509.Issuer.CommonName
|
||||
c.IssuerOrg = strings.Join(certX509.Issuer.Organization, ";")
|
||||
c.ValidityNotBefore = certX509.NotBefore
|
||||
c.ValidityNotAfter = certX509.NotAfter
|
||||
@@ -58,6 +63,20 @@ func (c *Certificate) PopulateFromX509(certX509 *x509.Certificate) *Certificate
|
||||
c.KeyAlgorithm = CertificateKeyAlgorithmType("")
|
||||
}
|
||||
|
||||
validationType := xcertx509.GetValidationType(certX509)
|
||||
switch validationType {
|
||||
case xcertx509.ExtendedValidation:
|
||||
c.ValidationPolicy = CertificateValidationPolicyTypeEV
|
||||
case xcertx509.DomainValidated:
|
||||
c.ValidationPolicy = CertificateValidationPolicyTypeDV
|
||||
case xcertx509.OrganizationalValidated:
|
||||
c.ValidationPolicy = CertificateValidationPolicyTypeOV
|
||||
case xcertx509.IndividualValidated:
|
||||
c.ValidationPolicy = CertificateValidationPolicyTypeIV
|
||||
default:
|
||||
c.ValidationPolicy = CertificateValidationPolicyType("")
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
@@ -106,6 +125,19 @@ const (
|
||||
CertificateKeyAlgorithmTypeEC384 = CertificateKeyAlgorithmType(certcrypto.EC384)
|
||||
)
|
||||
|
||||
type CertificateValidationPolicyType string
|
||||
|
||||
func (t CertificateValidationPolicyType) String() string {
|
||||
return string(t)
|
||||
}
|
||||
|
||||
const (
|
||||
CertificateValidationPolicyTypeEV = CertificateValidationPolicyType("EV")
|
||||
CertificateValidationPolicyTypeDV = CertificateValidationPolicyType("DV")
|
||||
CertificateValidationPolicyTypeOV = CertificateValidationPolicyType("OV")
|
||||
CertificateValidationPolicyTypeIV = CertificateValidationPolicyType("IV")
|
||||
)
|
||||
|
||||
type CertificateFormatType string
|
||||
|
||||
func (t CertificateFormatType) String() string {
|
||||
|
||||
@@ -94,13 +94,16 @@ func (r *CertificateRepository) Save(ctx context.Context, certificate *domain.Ce
|
||||
}
|
||||
|
||||
record.Set("source", certificate.Source.String())
|
||||
record.Set("subjectAltNames", certificate.SubjectAltNames)
|
||||
record.Set("serialNumber", certificate.SerialNumber)
|
||||
record.Set("certificate", certificate.Certificate)
|
||||
record.Set("privateKey", certificate.PrivateKey)
|
||||
record.Set("serialNumber", certificate.SerialNumber)
|
||||
record.Set("subjectName", certificate.SubjectName)
|
||||
record.Set("subjectAltNames", certificate.SubjectAltNames)
|
||||
record.Set("issuerOrg", certificate.IssuerOrg)
|
||||
record.Set("issuerName", certificate.IssuerName)
|
||||
record.Set("issuerCertificate", certificate.IssuerCertificate)
|
||||
record.Set("keyAlgorithm", certificate.KeyAlgorithm.String())
|
||||
record.Set("validationPolicy", certificate.ValidationPolicy.String())
|
||||
record.Set("validityNotBefore", certificate.ValidityNotBefore)
|
||||
record.Set("validityNotAfter", certificate.ValidityNotAfter)
|
||||
record.Set("validityInterval", certificate.ValidityInterval)
|
||||
@@ -156,13 +159,16 @@ func (r *CertificateRepository) castRecordToModel(record *core.Record) (*domain.
|
||||
UpdatedAt: record.GetDateTime("updated").Time(),
|
||||
},
|
||||
Source: domain.CertificateSourceType(record.GetString("source")),
|
||||
SubjectAltNames: record.GetString("subjectAltNames"),
|
||||
SerialNumber: record.GetString("serialNumber"),
|
||||
Certificate: record.GetString("certificate"),
|
||||
PrivateKey: record.GetString("privateKey"),
|
||||
SerialNumber: record.GetString("serialNumber"),
|
||||
SubjectName: record.GetString("subjectName"),
|
||||
SubjectAltNames: record.GetString("subjectAltNames"),
|
||||
IssuerName: record.GetString("issuerName"),
|
||||
IssuerOrg: record.GetString("issuerOrg"),
|
||||
IssuerCertificate: record.GetString("issuerCertificate"),
|
||||
KeyAlgorithm: domain.CertificateKeyAlgorithmType(record.GetString("keyAlgorithm")),
|
||||
ValidationPolicy: domain.CertificateValidationPolicyType(record.GetString("validationPolicy")),
|
||||
ValidityNotBefore: record.GetDateTime("validityNotBefore").Time(),
|
||||
ValidityNotAfter: record.GetDateTime("validityNotAfter").Time(),
|
||||
ValidityInterval: int32(record.GetInt("validityInterval")),
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
tracer := NewTracer("v0.4.25")
|
||||
tracer.Printf("go ...")
|
||||
|
||||
// update collection `access`
|
||||
// - modify field `config` schema
|
||||
{
|
||||
collection, err := app.FindCollectionByNameOrId("4yzbv8urny5ja1e")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
records, err := app.FindAllRecords(collection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, record := range records {
|
||||
changed := false
|
||||
|
||||
provider := record.GetString("provider")
|
||||
config := make(map[string]any)
|
||||
if err := record.UnmarshalJSONField("config", &config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch provider {
|
||||
case "cloudflare":
|
||||
{
|
||||
if _, ok := config["dnsApiToken"]; ok {
|
||||
config["apiToken"] = config["dnsApiToken"]
|
||||
delete(config, "dnsApiToken")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
if _, ok := config["zoneApiToken"]; ok {
|
||||
config["apiTokenForZone"] = config["zoneApiToken"]
|
||||
delete(config, "zoneApiToken")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
case "byteplus":
|
||||
{
|
||||
if _, ok := config["accessKey"]; ok {
|
||||
config["accessKeyId"] = config["accessKey"]
|
||||
delete(config, "accessKey")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
if _, ok := config["secretKey"]; ok {
|
||||
config["secretAccessKey"] = config["secretKey"]
|
||||
delete(config, "secretKey")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
case "volcengine":
|
||||
{
|
||||
if _, ok := config["accessKeySecret"]; ok {
|
||||
config["secretAccessKey"] = config["accessKeySecret"]
|
||||
delete(config, "accessKeySecret")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if changed {
|
||||
if err := app.Save(record); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tracer.Printf("record #%s in collection '%s' updated", record.Id, collection.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tracer.Printf("done")
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
|
||||
xcert "github.com/certimate-go/certimate/pkg/utils/cert"
|
||||
xcertx509 "github.com/certimate-go/certimate/pkg/utils/cert/x509"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
tracer := NewTracer("v0.4.25")
|
||||
tracer.Printf("go ...")
|
||||
|
||||
// update collection `access`
|
||||
// - modify field `config` schema
|
||||
{
|
||||
collection, err := app.FindCollectionByNameOrId("4yzbv8urny5ja1e")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
records, err := app.FindAllRecords(collection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, record := range records {
|
||||
changed := false
|
||||
|
||||
provider := record.GetString("provider")
|
||||
config := make(map[string]any)
|
||||
if err := record.UnmarshalJSONField("config", &config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch provider {
|
||||
case "cloudflare":
|
||||
{
|
||||
if _, ok := config["dnsApiToken"]; ok {
|
||||
config["apiToken"] = config["dnsApiToken"]
|
||||
delete(config, "dnsApiToken")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
if _, ok := config["zoneApiToken"]; ok {
|
||||
config["apiTokenForZone"] = config["zoneApiToken"]
|
||||
delete(config, "zoneApiToken")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
case "byteplus":
|
||||
{
|
||||
if _, ok := config["accessKey"]; ok {
|
||||
config["accessKeyId"] = config["accessKey"]
|
||||
delete(config, "accessKey")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
if _, ok := config["secretKey"]; ok {
|
||||
config["secretAccessKey"] = config["secretKey"]
|
||||
delete(config, "secretKey")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
case "volcengine":
|
||||
{
|
||||
if _, ok := config["accessKeySecret"]; ok {
|
||||
config["secretAccessKey"] = config["accessKeySecret"]
|
||||
delete(config, "accessKeySecret")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if changed {
|
||||
if err := app.Save(record); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tracer.Printf("record #%s in collection '%s' updated", record.Id, collection.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update collection `certificate`
|
||||
// - add field `subjectName`
|
||||
// - add field `issuerName`
|
||||
// - add field `validationPolicy`
|
||||
{
|
||||
collection, err := app.FindCollectionByNameOrId("4szxr9x43tpj6np")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(2, []byte(`{
|
||||
"autogeneratePattern": "",
|
||||
"help": "",
|
||||
"hidden": false,
|
||||
"id": "plmambpz",
|
||||
"max": 100000,
|
||||
"min": 0,
|
||||
"name": "certificate",
|
||||
"pattern": "",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(3, []byte(`{
|
||||
"autogeneratePattern": "",
|
||||
"help": "",
|
||||
"hidden": false,
|
||||
"id": "49qvwxcg",
|
||||
"max": 100000,
|
||||
"min": 0,
|
||||
"name": "privateKey",
|
||||
"pattern": "",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(4, []byte(`{
|
||||
"autogeneratePattern": "",
|
||||
"help": "",
|
||||
"hidden": false,
|
||||
"id": "text2069360702",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "serialNumber",
|
||||
"pattern": "",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(5, []byte(`{
|
||||
"autogeneratePattern": "",
|
||||
"help": "",
|
||||
"hidden": false,
|
||||
"id": "text2876278798",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "subjectName",
|
||||
"pattern": "",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(7, []byte(`{
|
||||
"autogeneratePattern": "",
|
||||
"help": "",
|
||||
"hidden": false,
|
||||
"id": "text2678583873",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "issuerName",
|
||||
"pattern": "",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(11, []byte(`{
|
||||
"autogeneratePattern": "",
|
||||
"help": "",
|
||||
"hidden": false,
|
||||
"id": "text2516249007",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "validationPolicy",
|
||||
"pattern": "",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := app.Save(collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tracer.Printf("collection '%s' updated", collection.Name)
|
||||
|
||||
records, err := app.FindAllRecords(collection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, record := range records {
|
||||
changed := false
|
||||
|
||||
if certX509, err := xcert.ParseCertificateFromPEM(record.GetString("certificate")); err == nil {
|
||||
record.Set("subjectName", certX509.Subject.CommonName)
|
||||
record.Set("issuerName", certX509.Issuer.CommonName)
|
||||
|
||||
switch xcertx509.GetValidationType(certX509) {
|
||||
case xcertx509.ExtendedValidation:
|
||||
record.Set("validationPolicy", "EV")
|
||||
case xcertx509.DomainValidated:
|
||||
record.Set("validationPolicy", "DV")
|
||||
case xcertx509.OrganizationalValidated:
|
||||
record.Set("validationPolicy", "OV")
|
||||
case xcertx509.IndividualValidated:
|
||||
record.Set("validationPolicy", "IV")
|
||||
default:
|
||||
record.Set("validationPolicy", "")
|
||||
}
|
||||
|
||||
changed = true
|
||||
}
|
||||
|
||||
if changed {
|
||||
if err := app.Save(record); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tracer.Printf("record #%s in collection '%s' updated", record.Id, collection.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tracer.Printf("done")
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
return errors.ErrUnsupported
|
||||
})
|
||||
}
|
||||
@@ -6,7 +6,14 @@ import (
|
||||
"net"
|
||||
)
|
||||
|
||||
var oidSubjectAlternativeNameExtension = asn1.ObjectIdentifier{2, 5, 29, 17}
|
||||
var (
|
||||
oidSubjectAlternativeNameExtension = asn1.ObjectIdentifier{2, 5, 29, 17}
|
||||
|
||||
oidValidationTypeEV = asn1.ObjectIdentifier{2, 23, 140, 1, 1}
|
||||
oidValidationTypeDV = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1}
|
||||
oidValidationTypeOV = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 2}
|
||||
oidValidationTypeIV = asn1.ObjectIdentifier{2, 23, 140, 1, 2, 3}
|
||||
)
|
||||
|
||||
const (
|
||||
sanGeneralNameTagEmail = 1
|
||||
@@ -15,6 +22,16 @@ const (
|
||||
sanGeneralNameTagIP = 7
|
||||
)
|
||||
|
||||
type ValidationType int
|
||||
|
||||
const (
|
||||
UnknownValidation ValidationType = iota
|
||||
ExtendedValidation
|
||||
DomainValidated
|
||||
OrganizationalValidated
|
||||
IndividualValidated
|
||||
)
|
||||
|
||||
// 返回指定 x509.Certificate 对象的主题名称。
|
||||
// 如果主题名称为空,则返回第一个主题替代名称。
|
||||
//
|
||||
@@ -84,3 +101,58 @@ func GetSubjectAltNames(cert *x509.Certificate) []string {
|
||||
|
||||
return sans
|
||||
}
|
||||
|
||||
// 返回指定 x509.Certificate 对象的证书验证类型。
|
||||
//
|
||||
// 入参:
|
||||
// - cert: x509.Certificate 对象。
|
||||
//
|
||||
// 出参:
|
||||
// - 证书验证类型。
|
||||
func GetValidationType(cert *x509.Certificate) ValidationType {
|
||||
// 同一证书可能有多个符合的策略,按 EV > OV > IV > DV 顺序判断
|
||||
if HasPolicy(cert, oidValidationTypeEV) {
|
||||
return ExtendedValidation
|
||||
} else if HasPolicy(cert, oidValidationTypeOV) {
|
||||
return OrganizationalValidated
|
||||
} else if HasPolicy(cert, oidValidationTypeIV) {
|
||||
return IndividualValidated
|
||||
} else if HasPolicy(cert, oidValidationTypeDV) {
|
||||
return DomainValidated
|
||||
}
|
||||
return UnknownValidation
|
||||
}
|
||||
|
||||
// 检查指定 x509.Certificate 对象是否包含指定的证书策略。
|
||||
//
|
||||
// 入参:
|
||||
// - cert: x509.Certificate 对象。
|
||||
// - policy: 证书策略 OID。
|
||||
//
|
||||
// 出参:
|
||||
// - 是否包含指定的证书策略。
|
||||
func HasPolicy(cert *x509.Certificate, policy asn1.ObjectIdentifier) bool {
|
||||
for _, p := range cert.PolicyIdentifiers {
|
||||
if p.Equal(policy) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查指定 x509.Certificate 对象是否包含指定的证书策略。
|
||||
//
|
||||
// 入参:
|
||||
// - cert: x509.Certificate 对象。
|
||||
// - policy: 证书策略 OID 字符串。
|
||||
//
|
||||
// 出参:
|
||||
// - 是否包含指定的证书策略。
|
||||
func HasPolicyString(cert *x509.Certificate, policy string) bool {
|
||||
for _, p := range cert.PolicyIdentifiers {
|
||||
if p.String() == policy {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -2,12 +2,15 @@ import { type WorkflowModel } from "./workflow";
|
||||
|
||||
export interface CertificateModel extends BaseModel {
|
||||
source: string;
|
||||
subjectAltNames: string;
|
||||
serialNumber: string;
|
||||
certificate: string;
|
||||
privateKey: string;
|
||||
serialNumber: string;
|
||||
subjectName: string;
|
||||
subjectAltNames: string;
|
||||
issuerName: string;
|
||||
issuerOrg: string;
|
||||
keyAlgorithm: string;
|
||||
validationPolicy: string;
|
||||
validityNotBefore: ISO8601String;
|
||||
validityNotAfter: ISO8601String;
|
||||
isRenewed: boolean;
|
||||
|
||||
Reference in New Issue
Block a user