mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 16:59:27 +08:00
This commit is contained in:
1 parent
b0d368e067
commit
7ee1052c8b
5 files changed
+151
-57
No files matched your search
+25
-16
@@ -1773,7 +1773,7 @@ function renderSignatures() {
|
|||||||
const fragment = document.createDocumentFragment();
|
const fragment = document.createDocumentFragment();
|
||||||
for (const signature of signatures) {
|
for (const signature of signatures) {
|
||||||
const row = document.createElement("div");
|
const row = document.createElement("div");
|
||||||
row.className = `signature-row ${signature.valid ? "valid" : "invalid"}`;
|
row.className = `signature-row ${signature.status}`;
|
||||||
|
|
||||||
const head = document.createElement("div");
|
const head = document.createElement("div");
|
||||||
head.className = "signature-head";
|
head.className = "signature-head";
|
||||||
@@ -1782,7 +1782,7 @@ function renderSignatures() {
|
|||||||
|
|
||||||
const badges = document.createElement("div");
|
const badges = document.createElement("div");
|
||||||
badges.className = "signature-badges";
|
badges.className = "signature-badges";
|
||||||
badges.append(fontBadge(signature.valid ? "通过" : "异常", signature.valid ? "valid" : "invalid"));
|
badges.append(fontBadge(signature.status === "valid" ? "通过" : signature.status === "invalid" ? "异常" : "未验", signature.status));
|
||||||
|
|
||||||
head.append(name, badges);
|
head.append(name, badges);
|
||||||
row.append(head);
|
row.append(head);
|
||||||
@@ -1795,20 +1795,20 @@ function renderSignatures() {
|
|||||||
appendSignatureLine(row, "签者", signature.signer);
|
appendSignatureLine(row, "签者", signature.signer);
|
||||||
appendSignatureLine(row, "时间", formatSignatureTime(signature.signatureDateTime));
|
appendSignatureLine(row, "时间", formatSignatureTime(signature.signatureDateTime));
|
||||||
appendSignatureLine(row, "机构", signatureAgency(signature));
|
appendSignatureLine(row, "机构", signatureAgency(signature));
|
||||||
appendSignatureCheck(row, "原文", signature.dataHashOK);
|
appendSignatureCheck(row, "原文", signature.dataHashChecked, signature.dataHashOK);
|
||||||
appendSignatureCheck(row, "签名", signature.signedValueOK);
|
appendSignatureCheck(row, "签名", signature.signedValueChecked, signature.signedValueOK);
|
||||||
if (signature.type !== "Sign") {
|
if (signature.type !== "Sign") {
|
||||||
appendSignatureCheck(row, "章验", signature.sealOK);
|
appendSignatureCheck(row, "章验", signature.sealChecked, signature.sealOK);
|
||||||
appendSignatureCheck(row, "一致", signature.sealMatchOK);
|
appendSignaturePolicy(row, "一致", signature.sealMatchChecked, signature.sealMatchOK);
|
||||||
}
|
}
|
||||||
appendSignatureCheck(row, "证书", signature.certOK);
|
appendSignatureCheck(row, "证书", signature.certChecked, signature.certOK);
|
||||||
appendSignaturePolicy(row, "签期", signature.signatureTimeChecked, signature.signatureTimeOK);
|
appendSignaturePolicy(row, "签期", signature.signatureTimeChecked, signature.signatureTimeOK);
|
||||||
appendSignaturePolicy(row, "章期", signature.sealTimeChecked, signature.sealTimeOK);
|
appendSignaturePolicy(row, "章期", signature.sealTimeChecked, signature.sealTimeOK);
|
||||||
if (signature.sealCertTimeChecked) {
|
if (signature.sealCertTimeChecked) {
|
||||||
appendSignatureLine(row, "制期", signature.sealCertTimeOK ? "有效" : "失效", signature.sealCertTimeOK ? "ok" : "");
|
appendSignatureLine(row, "制期", signature.sealCertTimeOK ? "有效" : "失效", signature.sealCertTimeOK ? "ok" : "");
|
||||||
}
|
}
|
||||||
appendSignaturePolicy(row, "时效", signature.certTimeChecked, signature.certTimeOK);
|
appendSignaturePolicy(row, "时效", signature.certTimeChecked, signature.certTimeOK);
|
||||||
appendSignaturePolicy(row, "信任", signature.certTrustChecked, signature.certTrustOK);
|
appendSignatureCheck(row, "信任", signature.certTrustChecked, signature.certTrustOK);
|
||||||
appendSignatureLine(row, "保护", signatureReferenceText(signature), signatureReferenceStatus(signature));
|
appendSignatureLine(row, "保护", signatureReferenceText(signature), signatureReferenceStatus(signature));
|
||||||
appendSignatureLine(row, "算法", signature.signatureMethod);
|
appendSignatureLine(row, "算法", signature.signatureMethod);
|
||||||
appendSignatureLine(row, "散列", signature.digestMethod);
|
appendSignatureLine(row, "散列", signature.digestMethod);
|
||||||
@@ -1826,11 +1826,16 @@ function signatureSummary(signatures) {
|
|||||||
if (!signatures.length) {
|
if (!signatures.length) {
|
||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
const invalid = signatures.filter((signature) => !signature.valid).length;
|
const invalid = signatures.filter((signature) => signature.status === "invalid").length;
|
||||||
|
const unchecked = signatures.filter((signature) => signature.status === "unchecked").length;
|
||||||
|
const parts = [String(signatures.length)];
|
||||||
if (invalid) {
|
if (invalid) {
|
||||||
return `${signatures.length} · 异常 ${invalid}`;
|
parts.push(`异常 ${invalid}`);
|
||||||
}
|
}
|
||||||
return `通过 ${signatures.length}`;
|
if (unchecked) {
|
||||||
|
parts.push(`未验 ${unchecked}`);
|
||||||
|
}
|
||||||
|
return parts.length > 1 ? parts.join(" · ") : `通过 ${signatures.length}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function signatureNameNode(signature) {
|
function signatureNameNode(signature) {
|
||||||
@@ -1885,7 +1890,8 @@ function signatureReferenceText(signature) {
|
|||||||
if (!count) {
|
if (!count) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return `${passed === count ? "通过" : "失败"} ${passed}/${count}`;
|
const status = signatureReferenceStatus(signature);
|
||||||
|
return `${status === "ok" ? "通过" : status === "fail" ? "失败" : "未验"} ${passed}/${count}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function signatureReferenceStatus(signature) {
|
function signatureReferenceStatus(signature) {
|
||||||
@@ -1893,7 +1899,10 @@ function signatureReferenceStatus(signature) {
|
|||||||
if (!count) {
|
if (!count) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
return signature.referencePassed === count ? "ok" : "fail";
|
if (signature.referencePassed < signature.referenceChecked) {
|
||||||
|
return "fail";
|
||||||
|
}
|
||||||
|
return signature.referenceChecked === count ? "ok" : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatSignatureTime(value) {
|
function formatSignatureTime(value) {
|
||||||
@@ -1920,15 +1929,15 @@ function appendSignatureLine(row, label, value, status = "") {
|
|||||||
row.append(line);
|
row.append(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendSignatureCheck(row, label, ok) {
|
function appendSignatureCheck(row, label, checked, ok) {
|
||||||
appendSignatureLine(row, label, ok ? "通过" : "失败", ok ? "ok" : "fail");
|
appendSignatureLine(row, label, checked ? ok ? "通过" : "失败" : "未验", checked ? ok ? "ok" : "fail" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendSignaturePolicy(row, label, checked, ok) {
|
function appendSignaturePolicy(row, label, checked, ok) {
|
||||||
if (!checked) {
|
if (!checked) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
appendSignatureCheck(row, label, ok);
|
appendSignatureCheck(row, label, checked, ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function focusSignatureStamp(stamp) {
|
async function focusSignatureStamp(stamp) {
|
||||||
|
|||||||
+37
-10
@@ -23,6 +23,7 @@ import (
|
|||||||
"image/jpeg"
|
"image/jpeg"
|
||||||
"image/png"
|
"image/png"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/xiaoqidun/ofdgo"
|
"github.com/xiaoqidun/ofdgo"
|
||||||
)
|
)
|
||||||
@@ -43,7 +44,7 @@ type FontInfo = ofdgo.FontInfo
|
|||||||
type SignatureInfo struct {
|
type SignatureInfo struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Valid bool `json:"valid"`
|
Status string `json:"status"`
|
||||||
Version string `json:"version,omitempty"`
|
Version string `json:"version,omitempty"`
|
||||||
SealType string `json:"sealType,omitempty"`
|
SealType string `json:"sealType,omitempty"`
|
||||||
SealID string `json:"sealId,omitempty"`
|
SealID string `json:"sealId,omitempty"`
|
||||||
@@ -53,10 +54,15 @@ type SignatureInfo struct {
|
|||||||
SignatureDateTime string `json:"signatureDateTime,omitempty"`
|
SignatureDateTime string `json:"signatureDateTime,omitempty"`
|
||||||
Provider string `json:"provider,omitempty"`
|
Provider string `json:"provider,omitempty"`
|
||||||
Company string `json:"company,omitempty"`
|
Company string `json:"company,omitempty"`
|
||||||
|
DataHashChecked bool `json:"dataHashChecked"`
|
||||||
DataHashOK bool `json:"dataHashOK"`
|
DataHashOK bool `json:"dataHashOK"`
|
||||||
|
SignedValueChecked bool `json:"signedValueChecked"`
|
||||||
SignedValueOK bool `json:"signedValueOK"`
|
SignedValueOK bool `json:"signedValueOK"`
|
||||||
|
SealChecked bool `json:"sealChecked"`
|
||||||
SealOK bool `json:"sealOK"`
|
SealOK bool `json:"sealOK"`
|
||||||
|
SealMatchChecked bool `json:"sealMatchChecked"`
|
||||||
SealMatchOK bool `json:"sealMatchOK"`
|
SealMatchOK bool `json:"sealMatchOK"`
|
||||||
|
CertChecked bool `json:"certChecked"`
|
||||||
CertOK bool `json:"certOK"`
|
CertOK bool `json:"certOK"`
|
||||||
SignatureTimeChecked bool `json:"signatureTimeChecked,omitempty"`
|
SignatureTimeChecked bool `json:"signatureTimeChecked,omitempty"`
|
||||||
SignatureTimeOK bool `json:"signatureTimeOK,omitempty"`
|
SignatureTimeOK bool `json:"signatureTimeOK,omitempty"`
|
||||||
@@ -69,6 +75,7 @@ type SignatureInfo struct {
|
|||||||
CertTrustChecked bool `json:"certTrustChecked,omitempty"`
|
CertTrustChecked bool `json:"certTrustChecked,omitempty"`
|
||||||
CertTrustOK bool `json:"certTrustOK,omitempty"`
|
CertTrustOK bool `json:"certTrustOK,omitempty"`
|
||||||
ReferenceCount int `json:"referenceCount"`
|
ReferenceCount int `json:"referenceCount"`
|
||||||
|
ReferenceChecked int `json:"referenceChecked"`
|
||||||
ReferencePassed int `json:"referencePassed"`
|
ReferencePassed int `json:"referencePassed"`
|
||||||
SignatureMethod string `json:"signatureMethod,omitempty"`
|
SignatureMethod string `json:"signatureMethod,omitempty"`
|
||||||
DigestMethod string `json:"digestMethod,omitempty"`
|
DigestMethod string `json:"digestMethod,omitempty"`
|
||||||
@@ -426,23 +433,39 @@ func (s *Session) signatureInfos() ([]SignatureInfo, error) {
|
|||||||
// 入参: report 签名验证报告
|
// 入参: report 签名验证报告
|
||||||
// 返回: SignatureInfo 签名验证信息
|
// 返回: SignatureInfo 签名验证信息
|
||||||
func signatureInfo(report ofdgo.SignatureVerifyReport) SignatureInfo {
|
func signatureInfo(report ofdgo.SignatureVerifyReport) SignatureInfo {
|
||||||
|
status := "unchecked"
|
||||||
|
if report.Valid {
|
||||||
|
status = "valid"
|
||||||
|
} else if report.HasFailure() {
|
||||||
|
status = "invalid"
|
||||||
|
}
|
||||||
|
dateTime := report.SignatureDateTime
|
||||||
|
if !report.SignatureTime.IsZero() {
|
||||||
|
dateTime = report.SignatureTime.Format(time.RFC3339Nano)
|
||||||
|
}
|
||||||
|
checked, passed := signatureReferenceCounts(report.References)
|
||||||
return SignatureInfo{
|
return SignatureInfo{
|
||||||
ID: report.ID,
|
ID: report.ID,
|
||||||
Type: string(report.Type),
|
Type: string(report.Type),
|
||||||
Valid: report.Valid,
|
Status: status,
|
||||||
Version: report.Provider.Version,
|
Version: report.Provider.Version,
|
||||||
SealType: report.SealType,
|
SealType: report.SealType,
|
||||||
SealID: report.SealInfo.ID,
|
SealID: report.SealInfo.ID,
|
||||||
SealName: report.SealInfo.Name,
|
SealName: report.SealInfo.Name,
|
||||||
SealVendor: report.SealInfo.VendorID,
|
SealVendor: report.SealInfo.VendorID,
|
||||||
Signer: signatureSigner(report),
|
Signer: signatureSigner(report),
|
||||||
SignatureDateTime: report.SignatureDateTime,
|
SignatureDateTime: dateTime,
|
||||||
Provider: report.Provider.ProviderName,
|
Provider: report.Provider.ProviderName,
|
||||||
Company: report.Provider.Company,
|
Company: report.Provider.Company,
|
||||||
|
DataHashChecked: report.DataHashChecked,
|
||||||
DataHashOK: report.DataHashOK,
|
DataHashOK: report.DataHashOK,
|
||||||
|
SignedValueChecked: report.SignedValueChecked,
|
||||||
SignedValueOK: report.SignedValueOK,
|
SignedValueOK: report.SignedValueOK,
|
||||||
|
SealChecked: report.SealChecked,
|
||||||
SealOK: report.SealOK,
|
SealOK: report.SealOK,
|
||||||
|
SealMatchChecked: report.SealMatchChecked,
|
||||||
SealMatchOK: report.SealMatchOK,
|
SealMatchOK: report.SealMatchOK,
|
||||||
|
CertChecked: report.CertChecked,
|
||||||
CertOK: report.CertOK,
|
CertOK: report.CertOK,
|
||||||
SignatureTimeChecked: report.SignatureTimeChecked,
|
SignatureTimeChecked: report.SignatureTimeChecked,
|
||||||
SignatureTimeOK: report.SignatureTimeOK,
|
SignatureTimeOK: report.SignatureTimeOK,
|
||||||
@@ -455,7 +478,8 @@ func signatureInfo(report ofdgo.SignatureVerifyReport) SignatureInfo {
|
|||||||
CertTrustChecked: report.CertTrustChecked,
|
CertTrustChecked: report.CertTrustChecked,
|
||||||
CertTrustOK: report.CertTrustOK,
|
CertTrustOK: report.CertTrustOK,
|
||||||
ReferenceCount: len(report.References),
|
ReferenceCount: len(report.References),
|
||||||
ReferencePassed: signatureReferencePassed(report.References),
|
ReferenceChecked: checked,
|
||||||
|
ReferencePassed: passed,
|
||||||
SignatureMethod: report.SignatureMethod,
|
SignatureMethod: report.SignatureMethod,
|
||||||
DigestMethod: report.DigestMethod,
|
DigestMethod: report.DigestMethod,
|
||||||
SignSerial: report.SignCert.SerialNumber,
|
SignSerial: report.SignCert.SerialNumber,
|
||||||
@@ -483,17 +507,20 @@ func signatureSigner(report ofdgo.SignatureVerifyReport) string {
|
|||||||
return report.SignCert.Subject
|
return report.SignCert.Subject
|
||||||
}
|
}
|
||||||
|
|
||||||
// signatureReferencePassed 获取已通过保护文件数量
|
// signatureReferenceCounts 获取保护文件检查数量
|
||||||
// 入参: refs 保护文件验证结果
|
// 入参: refs 保护文件验证结果
|
||||||
// 返回: int 已通过保护文件数量
|
// 返回: int 已检查数量, int 已通过数量
|
||||||
func signatureReferencePassed(refs []ofdgo.SignatureReferenceVerify) int {
|
func signatureReferenceCounts(refs []ofdgo.SignatureReferenceVerify) (int, int) {
|
||||||
count := 0
|
checked, passed := 0, 0
|
||||||
for _, ref := range refs {
|
for _, ref := range refs {
|
||||||
|
if ref.Checked {
|
||||||
|
checked++
|
||||||
|
}
|
||||||
if ref.OK {
|
if ref.OK {
|
||||||
count++
|
passed++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return count
|
return checked, passed
|
||||||
}
|
}
|
||||||
|
|
||||||
// signatureReportError 获取签名错误信息
|
// signatureReportError 获取签名错误信息
|
||||||
|
|||||||
+26
-9
@@ -29,12 +29,15 @@ const (
|
|||||||
|
|
||||||
// digitalVerifyResult 数字签名验证结果
|
// digitalVerifyResult 数字签名验证结果
|
||||||
type digitalVerifyResult struct {
|
type digitalVerifyResult struct {
|
||||||
DataHashOK bool
|
DataHashChecked bool
|
||||||
SignedOK bool
|
DataHashOK bool
|
||||||
CertOK bool
|
SignedChecked bool
|
||||||
SignerCerts [][]byte
|
SignedOK bool
|
||||||
Certs [][]byte
|
CertChecked bool
|
||||||
CertInfo SignatureCertInfo
|
CertOK bool
|
||||||
|
SignerCerts [][]byte
|
||||||
|
Certs [][]byte
|
||||||
|
CertInfo SignatureCertInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// gbtSignedData GB/T 35275 SignedData结构
|
// gbtSignedData GB/T 35275 SignedData结构
|
||||||
@@ -85,15 +88,17 @@ func verifyRawDigitalSignature(signedValue, signedData []byte, options *signatur
|
|||||||
if len(options.SignCerts) == 0 {
|
if len(options.SignCerts) == 0 {
|
||||||
return nil, fmt.Errorf("signature certificate not found")
|
return nil, fmt.Errorf("signature certificate not found")
|
||||||
}
|
}
|
||||||
result := &digitalVerifyResult{DataHashOK: true}
|
result := &digitalVerifyResult{DataHashChecked: true, DataHashOK: true}
|
||||||
for _, cert := range options.SignCerts {
|
for _, cert := range options.SignCerts {
|
||||||
pub, err := parseSM2PublicKeyFromCert(cert)
|
pub, err := parseSM2PublicKeyFromCert(cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
result.CertChecked = true
|
||||||
result.CertOK = true
|
result.CertOK = true
|
||||||
result.SignerCerts = [][]byte{cert}
|
result.SignerCerts = [][]byte{cert}
|
||||||
result.CertInfo = signatureCertInfo(cert)
|
result.CertInfo = signatureCertInfo(cert)
|
||||||
|
result.SignedChecked = true
|
||||||
if sm2VerifySignature(pub, nil, signedData, signedValue) {
|
if sm2VerifySignature(pub, nil, signedData, signedValue) {
|
||||||
result.SignedOK = true
|
result.SignedOK = true
|
||||||
return result, nil
|
return result, nil
|
||||||
@@ -112,15 +117,17 @@ func verifyRawPublicKeySignature(method, digestMethod string, signedValue, signe
|
|||||||
if _, err := signatureMethodHash(method, digestMethod); err != nil {
|
if _, err := signatureMethodHash(method, digestMethod); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
result := &digitalVerifyResult{DataHashOK: true}
|
result := &digitalVerifyResult{DataHashChecked: true, DataHashOK: true}
|
||||||
for _, cert := range options.SignCerts {
|
for _, cert := range options.SignCerts {
|
||||||
ok, err := verifyPublicKeySignature(method, digestMethod, cert, signedData, signedValue)
|
ok, err := verifyPublicKeySignature(method, digestMethod, cert, signedData, signedValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
result.CertChecked = true
|
||||||
result.CertOK = true
|
result.CertOK = true
|
||||||
result.SignerCerts = [][]byte{cert}
|
result.SignerCerts = [][]byte{cert}
|
||||||
result.CertInfo = signatureCertInfo(cert)
|
result.CertInfo = signatureCertInfo(cert)
|
||||||
|
result.SignedChecked = true
|
||||||
if ok {
|
if ok {
|
||||||
result.SignedOK = true
|
result.SignedOK = true
|
||||||
return result, nil
|
return result, nil
|
||||||
@@ -147,18 +154,21 @@ func verifyGBT35275SignedData(signedValue, signedData []byte, options *signature
|
|||||||
return nil, fmt.Errorf("invalid signed data signer info")
|
return nil, fmt.Errorf("invalid signed data signer info")
|
||||||
}
|
}
|
||||||
result := &digitalVerifyResult{Certs: sd.rawCerts()}
|
result := &digitalVerifyResult{Certs: sd.rawCerts()}
|
||||||
for _, signer := range sd.Signers {
|
for index, signer := range sd.Signers {
|
||||||
digest, err := signatureDigest(signer.DigestAlg, signedData)
|
digest, err := signatureDigest(signer.DigestAlg, signedData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(sd.ContentDigest) != 0 && !bytes.Equal(sd.ContentDigest, digest) {
|
if len(sd.ContentDigest) != 0 && !bytes.Equal(sd.ContentDigest, digest) {
|
||||||
|
result.DataHashChecked = true
|
||||||
|
result.DataHashOK = false
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
result.DataHashOK = true
|
result.DataHashOK = true
|
||||||
plain := sd.ContentDigest
|
plain := sd.ContentDigest
|
||||||
if len(signer.AuthAttrs) != 0 {
|
if len(signer.AuthAttrs) != 0 {
|
||||||
if !bytes.Equal(signer.AttrDigest, digest) {
|
if !bytes.Equal(signer.AttrDigest, digest) {
|
||||||
|
result.DataHashChecked = true
|
||||||
result.DataHashOK = false
|
result.DataHashOK = false
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
@@ -167,6 +177,7 @@ func verifyGBT35275SignedData(signedValue, signedData []byte, options *signature
|
|||||||
if len(plain) == 0 {
|
if len(plain) == 0 {
|
||||||
return nil, fmt.Errorf("invalid signed data content")
|
return nil, fmt.Errorf("invalid signed data content")
|
||||||
}
|
}
|
||||||
|
result.DataHashChecked = index == len(sd.Signers)-1
|
||||||
cert := sd.findCert(signer.Issuer, signer.Serial)
|
cert := sd.findCert(signer.Issuer, signer.Serial)
|
||||||
if cert == nil {
|
if cert == nil {
|
||||||
result.CertOK = false
|
result.CertOK = false
|
||||||
@@ -181,6 +192,8 @@ func verifyGBT35275SignedData(signedValue, signedData []byte, options *signature
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
if !sm2VerifySignature(pub, nil, plain, signer.Signature) {
|
if !sm2VerifySignature(pub, nil, plain, signer.Signature) {
|
||||||
|
result.SignedChecked = true
|
||||||
|
result.CertChecked = index == len(sd.Signers)-1
|
||||||
result.CertOK = true
|
result.CertOK = true
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
@@ -195,11 +208,15 @@ func verifyGBT35275SignedData(signedValue, signedData []byte, options *signature
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
|
result.SignedChecked = true
|
||||||
|
result.CertChecked = index == len(sd.Signers)-1
|
||||||
result.CertOK = true
|
result.CertOK = true
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
result.CertChecked = true
|
||||||
result.CertOK = true
|
result.CertOK = true
|
||||||
|
result.SignedChecked = true
|
||||||
result.SignedOK = true
|
result.SignedOK = true
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-13
@@ -74,19 +74,23 @@ type sesCertDigest struct {
|
|||||||
|
|
||||||
// sesVerifyResult SES签章验证结果
|
// sesVerifyResult SES签章验证结果
|
||||||
type sesVerifyResult struct {
|
type sesVerifyResult struct {
|
||||||
DataHashOK bool
|
DataHashChecked bool
|
||||||
SignedOK bool
|
DataHashOK bool
|
||||||
SealOK bool
|
SignedChecked bool
|
||||||
CertOK bool
|
SignedOK bool
|
||||||
SignCert SignatureCertInfo
|
SealChecked bool
|
||||||
SealCert SignatureCertInfo
|
SealOK bool
|
||||||
SignCertRaw []byte
|
CertChecked bool
|
||||||
SealCertRaw []byte
|
CertOK bool
|
||||||
SealRaw []byte
|
SignCert SignatureCertInfo
|
||||||
Certs [][]byte
|
SealCert SignatureCertInfo
|
||||||
SealType string
|
SignCertRaw []byte
|
||||||
SealInfo SignatureSealInfo
|
SealCertRaw []byte
|
||||||
SignatureTime time.Time
|
SealRaw []byte
|
||||||
|
Certs [][]byte
|
||||||
|
SealType string
|
||||||
|
SealInfo SignatureSealInfo
|
||||||
|
SignatureTime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseSESSignature 解析SES签章值
|
// parseSESSignature 解析SES签章值
|
||||||
@@ -240,6 +244,7 @@ func verifySESSignature(data, signedData []byte, options *signatureVerifyOptions
|
|||||||
result.SealType = sig.Seal.PicType
|
result.SealType = sig.Seal.PicType
|
||||||
result.SealInfo = sig.Seal.Info
|
result.SealInfo = sig.Seal.Info
|
||||||
result.SignatureTime = sig.Time
|
result.SignatureTime = sig.Time
|
||||||
|
result.DataHashChecked = true
|
||||||
result.DataHashOK = bytes.Equal(sig.DataHash, signSM3(signedData))
|
result.DataHashOK = bytes.Equal(sig.DataHash, signSM3(signedData))
|
||||||
signPub, err := parseSM2PublicKeyFromCert(sig.Cert)
|
signPub, err := parseSM2PublicKeyFromCert(sig.Cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -249,8 +254,11 @@ func verifySESSignature(data, signedData []byte, options *signatureVerifyOptions
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
result.SignedChecked = true
|
||||||
result.SignedOK = sm2VerifySignature(signPub, nil, sig.ToSign, sig.Signature)
|
result.SignedOK = sm2VerifySignature(signPub, nil, sig.ToSign, sig.Signature)
|
||||||
|
result.SealChecked = true
|
||||||
result.SealOK = sm2VerifySignature(sealPub, nil, sig.Seal.SignData, sig.Seal.Signature)
|
result.SealOK = sm2VerifySignature(sealPub, nil, sig.Seal.SignData, sig.Seal.Signature)
|
||||||
|
result.CertChecked = true
|
||||||
result.CertOK = sesCertInList(sig.Cert, sig.Seal.CertList)
|
result.CertOK = sesCertInList(sig.Cert, sig.Seal.CertList)
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|||||||
+42
-9
@@ -39,6 +39,7 @@ import (
|
|||||||
|
|
||||||
// SignatureVerifyReport 签名验证报告
|
// SignatureVerifyReport 签名验证报告
|
||||||
// Valid表示签名完整性、签名时间语义及调用方指定的证书策略均通过
|
// Valid表示签名完整性、签名时间语义及调用方指定的证书策略均通过
|
||||||
|
// Checked表示对应检查已得出结论, 未检查时不能将OK的零值视为失败
|
||||||
// SealCertTimeOK仅提供制章证书在签名时间的状态信息, 不参与Valid判断
|
// SealCertTimeOK仅提供制章证书在签名时间的状态信息, 不参与Valid判断
|
||||||
type SignatureVerifyReport struct {
|
type SignatureVerifyReport struct {
|
||||||
ID string
|
ID string
|
||||||
@@ -59,10 +60,15 @@ type SignatureVerifyReport struct {
|
|||||||
StampPositions []SignatureStampPosition
|
StampPositions []SignatureStampPosition
|
||||||
StampPositionError string
|
StampPositionError string
|
||||||
DigestOK bool
|
DigestOK bool
|
||||||
|
DataHashChecked bool
|
||||||
DataHashOK bool
|
DataHashOK bool
|
||||||
|
SignedValueChecked bool
|
||||||
SignedValueOK bool
|
SignedValueOK bool
|
||||||
|
SealChecked bool
|
||||||
SealOK bool
|
SealOK bool
|
||||||
|
SealMatchChecked bool
|
||||||
SealMatchOK bool
|
SealMatchOK bool
|
||||||
|
CertChecked bool
|
||||||
CertOK bool
|
CertOK bool
|
||||||
SignatureTimeChecked bool
|
SignatureTimeChecked bool
|
||||||
SignatureTimeOK bool
|
SignatureTimeOK bool
|
||||||
@@ -90,6 +96,21 @@ func (report SignatureVerifyReport) TrustedValid() bool {
|
|||||||
return report.IntegrityValid() && report.certificatePolicyOK() && report.CertTrustChecked && report.CertTimeChecked
|
return report.IntegrityValid() && report.certificatePolicyOK() && report.CertTrustChecked && report.CertTimeChecked
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasFailure 判断已完成的签名检查是否存在失败
|
||||||
|
// 返回: bool 是否存在失败, 未完成检查时仍需判断Valid和Error
|
||||||
|
func (report SignatureVerifyReport) HasFailure() bool {
|
||||||
|
for _, ref := range report.References {
|
||||||
|
if ref.Checked && !ref.OK {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return report.DataHashChecked && !report.DataHashOK ||
|
||||||
|
report.SignedValueChecked && !report.SignedValueOK ||
|
||||||
|
report.SealChecked && !report.SealOK ||
|
||||||
|
report.SealMatchChecked && !report.SealMatchOK ||
|
||||||
|
report.CertChecked && !report.CertOK || !report.certificatePolicyOK()
|
||||||
|
}
|
||||||
|
|
||||||
// SignatureCertInfo 签名证书信息
|
// SignatureCertInfo 签名证书信息
|
||||||
type SignatureCertInfo struct {
|
type SignatureCertInfo struct {
|
||||||
Raw []byte
|
Raw []byte
|
||||||
@@ -120,6 +141,7 @@ type SignatureReferenceVerify struct {
|
|||||||
Path string
|
Path string
|
||||||
CheckValue []byte
|
CheckValue []byte
|
||||||
Actual []byte
|
Actual []byte
|
||||||
|
Checked bool
|
||||||
OK bool
|
OK bool
|
||||||
Error string
|
Error string
|
||||||
}
|
}
|
||||||
@@ -298,16 +320,21 @@ func (r *Reader) verifySignature(sigListPath string, sigRef Signature, options *
|
|||||||
switch report.Type {
|
switch report.Type {
|
||||||
case SignTypeSign:
|
case SignTypeSign:
|
||||||
result, err := verifyDigitalSignature(report.SignatureMethod, report.DigestMethod, signedValue, sigData, options)
|
result, err := verifyDigitalSignature(report.SignatureMethod, report.DigestMethod, signedValue, sigData, options)
|
||||||
|
if result != nil {
|
||||||
|
report.DataHashChecked = result.DataHashChecked
|
||||||
|
report.DataHashOK = result.DataHashOK
|
||||||
|
report.SignedValueChecked = result.SignedChecked
|
||||||
|
report.SignedValueOK = result.SignedOK
|
||||||
|
report.CertChecked = result.CertChecked
|
||||||
|
report.CertOK = result.CertOK
|
||||||
|
report.SignCert = result.CertInfo
|
||||||
|
report.Signer = result.CertInfo.CommonName
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
report.Error = err.Error()
|
report.Error = err.Error()
|
||||||
return report
|
return report
|
||||||
}
|
}
|
||||||
report.DataHashOK = result.DataHashOK
|
|
||||||
report.SignedValueOK = result.SignedOK
|
|
||||||
report.SealOK = true
|
report.SealOK = true
|
||||||
report.CertOK = result.CertOK
|
|
||||||
report.SignCert = result.CertInfo
|
|
||||||
report.Signer = result.CertInfo.CommonName
|
|
||||||
report.SignatureTime = parseSignatureDateTime(report.SignatureDateTime)
|
report.SignatureTime = parseSignatureDateTime(report.SignatureDateTime)
|
||||||
report.applySignatureTimePolicy()
|
report.applySignatureTimePolicy()
|
||||||
report.applySignatureCertificatePolicy(options, result.SignerCerts, result.Certs)
|
report.applySignatureCertificatePolicy(options, result.SignerCerts, result.Certs)
|
||||||
@@ -320,6 +347,14 @@ func (r *Reader) verifySignature(sigListPath string, sigRef Signature, options *
|
|||||||
}
|
}
|
||||||
sesResult, err := verifySESSignature(signedValue, sigData, options)
|
sesResult, err := verifySESSignature(signedValue, sigData, options)
|
||||||
if sesResult != nil {
|
if sesResult != nil {
|
||||||
|
report.DataHashChecked = sesResult.DataHashChecked
|
||||||
|
report.DataHashOK = sesResult.DataHashOK
|
||||||
|
report.SignedValueChecked = sesResult.SignedChecked
|
||||||
|
report.SignedValueOK = sesResult.SignedOK
|
||||||
|
report.SealChecked = sesResult.SealChecked
|
||||||
|
report.SealOK = sesResult.SealOK
|
||||||
|
report.CertChecked = sesResult.CertChecked
|
||||||
|
report.CertOK = sesResult.CertOK
|
||||||
report.SignCert = sesResult.SignCert
|
report.SignCert = sesResult.SignCert
|
||||||
report.SealCert = sesResult.SealCert
|
report.SealCert = sesResult.SealCert
|
||||||
report.SealInfo = sesResult.SealInfo
|
report.SealInfo = sesResult.SealInfo
|
||||||
@@ -331,10 +366,6 @@ func (r *Reader) verifySignature(sigListPath string, sigRef Signature, options *
|
|||||||
report.Error = err.Error()
|
report.Error = err.Error()
|
||||||
return report
|
return report
|
||||||
}
|
}
|
||||||
report.DataHashOK = sesResult.DataHashOK
|
|
||||||
report.SignedValueOK = sesResult.SignedOK
|
|
||||||
report.SealOK = sesResult.SealOK
|
|
||||||
report.CertOK = sesResult.CertOK
|
|
||||||
report.applySignatureTimePolicy()
|
report.applySignatureTimePolicy()
|
||||||
report.applySignatureCertificatePolicy(options, [][]byte{sesResult.SignCertRaw, sesResult.SealCertRaw}, sesResult.Certs)
|
report.applySignatureCertificatePolicy(options, [][]byte{sesResult.SignCertRaw, sesResult.SealCertRaw}, sesResult.Certs)
|
||||||
if sigFile.SignedInfo.Seal.BaseLoc != "" {
|
if sigFile.SignedInfo.Seal.BaseLoc != "" {
|
||||||
@@ -344,6 +375,7 @@ func (r *Reader) verifySignature(sigListPath string, sigRef Signature, options *
|
|||||||
report.Error = err.Error()
|
report.Error = err.Error()
|
||||||
return report
|
return report
|
||||||
}
|
}
|
||||||
|
report.SealMatchChecked = true
|
||||||
report.SealMatchOK = bytes.Equal(sealData, sesResult.SealRaw)
|
report.SealMatchOK = bytes.Equal(sealData, sesResult.SealRaw)
|
||||||
}
|
}
|
||||||
report.Valid = report.IntegrityValid() && report.certificatePolicyOK()
|
report.Valid = report.IntegrityValid() && report.certificatePolicyOK()
|
||||||
@@ -387,6 +419,7 @@ func (r *Reader) verifySignatureReference(sigPath, method string, ref SignatureR
|
|||||||
}
|
}
|
||||||
result.CheckValue = checkValue
|
result.CheckValue = checkValue
|
||||||
result.Actual = actual
|
result.Actual = actual
|
||||||
|
result.Checked = true
|
||||||
result.OK = subtle.ConstantTimeCompare(checkValue, actual) == 1
|
result.OK = subtle.ConstantTimeCompare(checkValue, actual) == 1
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user