feat(数字签名): 优化签名验签状态与时间展示,统一前后端字段顺序
build.yaml / build (push) Successful in 37s

This commit is contained in:
xiaoqidun committed 2026-09-08 13:45:58 +08:00
1 parent b0d368e067
commit 7ee1052c8b
5 files changed
+151 -57

No files matched your search

+25 -16
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
} }