From 22d62e420bfd72ca5099408dd6ac667c0e23ab4d Mon Sep 17 00:00:00 2001 From: Jacky Date: Tue, 13 Feb 2024 14:15:02 +0800 Subject: [PATCH] feat: configurable cert key type #264 --- api/certificate/certificate.go | 18 +++++--- api/certificate/issue.go | 1 + app/src/api/cert.ts | 1 + app/src/views/certificate/RenewCert.vue | 2 +- .../views/certificate/WildcardCertificate.vue | 10 ++-- .../cert/components/AutoCertStepOne.vue | 46 ++++++++++++++++++- .../domain/cert/components/ObtainCertLive.vue | 3 +- internal/cert/auto_cert.go | 1 + internal/cert/cert.go | 9 ++-- internal/validation/key_type.go | 15 ++++++ internal/validation/validation.go | 6 +++ model/cert.go | 31 +++++++++---- 12 files changed, 115 insertions(+), 28 deletions(-) create mode 100644 internal/validation/key_type.go diff --git a/api/certificate/certificate.go b/api/certificate/certificate.go index 62cd47fb..b5f9ba77 100644 --- a/api/certificate/certificate.go +++ b/api/certificate/certificate.go @@ -7,6 +7,7 @@ import ( "github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/query" "github.com/gin-gonic/gin" + "github.com/go-acme/lego/v4/certcrypto" "github.com/spf13/cast" "net/http" "os" @@ -76,13 +77,14 @@ func GetCert(c *gin.Context) { } type certJson struct { - Name string `json:"name" binding:"required"` - SSLCertificatePath string `json:"ssl_certificate_path" binding:"required,certificate_path"` - SSLCertificateKeyPath string `json:"ssl_certificate_key_path" binding:"required,privatekey_path"` - SSLCertificate string `json:"ssl_certificate" binding:"omitempty,certificate"` - SSLCertificateKey string `json:"ssl_certificate_key" binding:"omitempty,privatekey"` - ChallengeMethod string `json:"challenge_method"` - DnsCredentialID int `json:"dns_credential_id"` + Name string `json:"name" binding:"required"` + SSLCertificatePath string `json:"ssl_certificate_path" binding:"required,certificate_path"` + SSLCertificateKeyPath string `json:"ssl_certificate_key_path" binding:"required,privatekey_path"` + SSLCertificate string `json:"ssl_certificate" binding:"omitempty,certificate"` + SSLCertificateKey string `json:"ssl_certificate_key" binding:"omitempty,privatekey"` + KeyType certcrypto.KeyType `json:"key_type" binding:"omitempty,auto_cert_key_type"` + ChallengeMethod string `json:"challenge_method"` + DnsCredentialID int `json:"dns_credential_id"` } func AddCert(c *gin.Context) { @@ -96,6 +98,7 @@ func AddCert(c *gin.Context) { Name: json.Name, SSLCertificatePath: json.SSLCertificatePath, SSLCertificateKeyPath: json.SSLCertificateKeyPath, + KeyType: json.KeyType, ChallengeMethod: json.ChallengeMethod, DnsCredentialID: json.DnsCredentialID, } @@ -146,6 +149,7 @@ func ModifyCert(c *gin.Context) { SSLCertificatePath: json.SSLCertificatePath, SSLCertificateKeyPath: json.SSLCertificateKeyPath, ChallengeMethod: json.ChallengeMethod, + KeyType: json.KeyType, DnsCredentialID: json.DnsCredentialID, }) diff --git a/api/certificate/issue.go b/api/certificate/issue.go index e7701d30..e8e532e0 100644 --- a/api/certificate/issue.go +++ b/api/certificate/issue.go @@ -122,6 +122,7 @@ func IssueCert(c *gin.Context) { SSLCertificatePath: sslCertificatePath, SSLCertificateKeyPath: sslCertificateKeyPath, AutoCert: model.AutoCertEnabled, + KeyType: payload.KeyType, }) if err != nil { diff --git a/app/src/api/cert.ts b/app/src/api/cert.ts index b0ade97b..72072147 100644 --- a/app/src/api/cert.ts +++ b/app/src/api/cert.ts @@ -14,6 +14,7 @@ export interface Cert extends ModelBase { challenge_method: string dns_credential_id: number dns_credential?: DnsCredential + key_type: string log: string certificate_info: CertificateInfo } diff --git a/app/src/views/certificate/RenewCert.vue b/app/src/views/certificate/RenewCert.vue index 5d4ebbef..a8bd8513 100644 --- a/app/src/views/certificate/RenewCert.vue +++ b/app/src/views/certificate/RenewCert.vue @@ -21,7 +21,7 @@ const data = inject('data') as Ref const issueCert = () => { modalVisible.value = true - refObtainCertLive.value.issue_cert(data.value.name, data.value.domains).then(() => { + refObtainCertLive.value.issue_cert(data.value.name, data.value.domains, data.value.key_type).then(() => { message.success($gettext('Renew successfully')) emit('renewed') }) diff --git a/app/src/views/certificate/WildcardCertificate.vue b/app/src/views/certificate/WildcardCertificate.vue index 628fcbad..bab1ddfa 100644 --- a/app/src/views/certificate/WildcardCertificate.vue +++ b/app/src/views/certificate/WildcardCertificate.vue @@ -44,10 +44,12 @@ const issueCert = () => { step.value++ modalVisible.value = true - refObtainCertLive.value.issue_cert(computedDomain.value, [computedDomain.value, domain.value]).then(() => { - message.success($gettext('Renew successfully')) - emit('issued') - }) + refObtainCertLive.value.issue_cert(computedDomain.value, + [computedDomain.value, domain.value]) + .then(() => { + message.success($gettext('Renew successfully')) + emit('issued') + }) } diff --git a/app/src/views/domain/cert/components/AutoCertStepOne.vue b/app/src/views/domain/cert/components/AutoCertStepOne.vue index 442d8c30..89461fc4 100644 --- a/app/src/views/domain/cert/components/AutoCertStepOne.vue +++ b/app/src/views/domain/cert/components/AutoCertStepOne.vue @@ -3,6 +3,7 @@ import { useGettext } from 'vue3-gettext' import type { Ref } from 'vue' import type { DnsChallenge } from '@/api/auto_cert' import DNSChallenge from '@/views/domain/cert/components/DNSChallenge.vue' +import type { Cert } from '@/api/cert' defineProps<{ hideNote?: boolean @@ -13,7 +14,39 @@ const { $gettext } = useGettext() const no_server_name = inject('no_server_name') // Provide by ObtainCert.vue -const data = inject('data') as Ref +const data = inject('data') as Ref + +const keyType = shallowRef([ + { + key: '2048', + name: 'RSA2048', + }, + { + key: '3072', + name: 'RSA3072', + }, + { + key: '4096', + name: 'RSA4096', + }, + { + key: '8192', + name: 'RAS8192', + }, + { + key: 'P256', + name: 'EC256', + }, + { + key: 'P384', + name: 'EC384', + }, +]) + +onMounted(() => { + if (data.value.key_type === '') + data.value.key_type = 'RSA2048' +})