mirror of
https://github.com/certimate-go/certimate.git
synced 2026-09-03 06:23:54 +08:00
fix: #1407
This commit is contained in:
@@ -1,13 +1,17 @@
|
||||
package ucloudussl
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -125,9 +129,10 @@ func (c *Certmgr) tryGetResultIfCertExists(ctx context.Context, certPEM string)
|
||||
|
||||
// 查询用户证书列表
|
||||
// REF: https://docs.ucloud.cn/api/usslcertificate-api/get_certificate_list
|
||||
// REF: https://docs.ucloud.cn/api/usslcertificate-api/get_certificate_detail_info
|
||||
// REF: https://docs.ucloud.cn/api/usslcertificate-api/download_certificate
|
||||
getCertificateListPage := 1
|
||||
getCertificateListLimit := 1000
|
||||
getCertificateListPageSize := 1000
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
@@ -140,7 +145,7 @@ func (c *Certmgr) tryGetResultIfCertExists(ctx context.Context, certPEM string)
|
||||
getCertificateListReq.Domain = ucloud.String(certX509.Subject.CommonName)
|
||||
getCertificateListReq.Sort = ucloud.String("2")
|
||||
getCertificateListReq.Page = ucloud.Int(getCertificateListPage)
|
||||
getCertificateListReq.PageSize = ucloud.Int(getCertificateListLimit)
|
||||
getCertificateListReq.PageSize = ucloud.Int(getCertificateListPageSize)
|
||||
getCertificateListResp, err := c.sdkClient.GetCertificateList(getCertificateListReq)
|
||||
c.logger.Debug("sdk request 'ussl.GetCertificateList'", slog.Any("request", getCertificateListReq), slog.Any("response", getCertificateListResp))
|
||||
if err != nil {
|
||||
@@ -153,15 +158,10 @@ func (c *Certmgr) tryGetResultIfCertExists(ctx context.Context, certPEM string)
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书颁发者
|
||||
if len(certX509.Issuer.Organization) == 0 || certItem.Brand != certX509.Issuer.Organization[0] {
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书有效期
|
||||
if certX509.NotBefore.UnixMilli() != int64(certItem.NotBefore) {
|
||||
if certX509.NotBefore.UnixMilli() != certItem.NotBefore {
|
||||
continue
|
||||
} else if certX509.NotAfter.UnixMilli() != int64(certItem.NotAfter) {
|
||||
} else if certX509.NotAfter.UnixMilli() != certItem.NotAfter {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -213,6 +213,23 @@ func (c *Certmgr) tryGetResultIfCertExists(ctx context.Context, certPEM string)
|
||||
continue
|
||||
}
|
||||
|
||||
// 对比证书内容
|
||||
downloadCertificateReq := c.sdkClient.NewDownloadCertificateRequest()
|
||||
downloadCertificateReq.CertificateID = ucloud.Int(certItem.CertificateID)
|
||||
downloadCertificateResp, err := c.sdkClient.DownloadCertificate(downloadCertificateReq)
|
||||
c.logger.Debug("sdk request 'ussl.DownloadCertificate'", slog.Any("request", downloadCertificateReq), slog.Any("response", downloadCertificateResp))
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("failed to execute sdk request 'ussl.DownloadCertificate': %w", err)
|
||||
} else {
|
||||
oldCertPEM, err := downloadCertificateFromUCloud(downloadCertificateResp.CertificateUrl)
|
||||
if err != nil {
|
||||
c.logger.Warn("could not download certificate from ucloud", slog.String("url", downloadCertificateResp.CertificateUrl), slog.Any("error", err))
|
||||
}
|
||||
if oldCertPEM != nil && !xcert.EqualCertificatesFromPEM(certPEM, string(oldCertPEM)) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return &UploadResult{
|
||||
CertId: fmt.Sprintf("%d", certItem.CertificateID),
|
||||
CertName: certItem.Name,
|
||||
@@ -222,7 +239,8 @@ func (c *Certmgr) tryGetResultIfCertExists(ctx context.Context, certPEM string)
|
||||
}, true, nil
|
||||
}
|
||||
|
||||
if len(getCertificateListResp.CertificateList) < getCertificateListLimit {
|
||||
if len(getCertificateListResp.CertificateList) < getCertificateListPageSize ||
|
||||
getCertificateListPage*getCertificateListPageSize >= getCertificateListResp.TotalCount {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -259,3 +277,53 @@ func createSDKClient(privateKey, publicKey, projectId, endpoint string) (*ucloud
|
||||
client := ucloudsdk.NewClient(&cfg, &credential)
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func downloadCertificateFromUCloud(url string) ([]byte, error) {
|
||||
url = strings.ReplaceAll(url, "\\u0026", "&")
|
||||
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
contentType := resp.Header.Get("Content-Type")
|
||||
if !strings.HasPrefix(contentType, "application/zip") {
|
||||
return nil, fmt.Errorf("unexpected content type: %s", contentType)
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reader, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
const targetFileName = "Nginx/public.pem"
|
||||
var pemData []byte
|
||||
|
||||
for _, f := range reader.File {
|
||||
if strings.EqualFold(f.Name, "ALL/public.crt") || strings.EqualFold(f.Name, "Nginx/public.pem") {
|
||||
rc, err := f.Open()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
pemData, err = io.ReadAll(rc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(pemData) == 0 {
|
||||
return nil, fmt.Errorf("could not find the certificate file in the zip archive")
|
||||
}
|
||||
|
||||
return pemData, nil
|
||||
}
|
||||
|
||||
@@ -15,8 +15,6 @@ type DownloadCertificateResponse struct {
|
||||
response.CommonBase
|
||||
|
||||
CertificateUrl string
|
||||
CertCA *CertificateDownloadInfo
|
||||
Certificate *CertificateDownloadInfo
|
||||
}
|
||||
|
||||
func (c *USSLClient) NewDownloadCertificateRequest() *DownloadCertificateRequest {
|
||||
@@ -25,6 +23,7 @@ func (c *USSLClient) NewDownloadCertificateRequest() *DownloadCertificateRequest
|
||||
c.Client.SetupRequest(req)
|
||||
|
||||
req.SetRetryable(true)
|
||||
req.SetEncoder(request.NewJSONEncoder(c.GetConfig(), c.GetCredential()))
|
||||
return req
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ func (c *USSLClient) NewGetCertificateDetailInfoRequest() *GetCertificateDetailI
|
||||
c.Client.SetupRequest(req)
|
||||
|
||||
req.SetRetryable(true)
|
||||
req.SetEncoder(request.NewJSONEncoder(c.GetConfig(), c.GetCredential()))
|
||||
return req
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ func (c *USSLClient) NewGetCertificateListRequest() *GetCertificateListRequest {
|
||||
c.Client.SetupRequest(req)
|
||||
|
||||
req.SetRetryable(true)
|
||||
req.SetEncoder(request.NewJSONEncoder(c.GetConfig(), c.GetCredential()))
|
||||
return req
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ func (c *USSLClient) NewUploadNormalCertificateRequest() *UploadNormalCertificat
|
||||
c.Client.SetupRequest(req)
|
||||
|
||||
req.SetRetryable(false)
|
||||
req.SetEncoder(request.NewJSONEncoder(c.GetConfig(), c.GetCredential()))
|
||||
return req
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ type CertificateListItem struct {
|
||||
Brand string
|
||||
ValidityPeriod int
|
||||
Type string
|
||||
NotBefore int
|
||||
NotAfter int
|
||||
NotBefore int64
|
||||
NotAfter int64
|
||||
AlarmState int
|
||||
State string
|
||||
StateCode string
|
||||
@@ -54,8 +54,3 @@ type CertificateInfo struct {
|
||||
IssuedDate int
|
||||
ExpiredDate int
|
||||
}
|
||||
|
||||
type CertificateDownloadInfo struct {
|
||||
FileData string
|
||||
FileName string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user