mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-30 09:37:26 +08:00
This commit is contained in:
1 parent
3927929822
commit
e3908c1149
8 files changed
+314
-142
No files matched your search
@@ -353,8 +353,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
<dialog id="signPanel" class="form-dialog security-dialog" aria-label="签章">
|
<dialog id="signPanel" class="form-dialog security-dialog" aria-labelledby="signTitle">
|
||||||
<form id="signForm" autocomplete="off">
|
<form id="signForm" autocomplete="off">
|
||||||
|
<h2 id="signTitle" class="form-title">签署文档</h2>
|
||||||
<div class="form-row"><label for="signCertificate">证书</label><input id="signCertificate" type="file" accept=".pem,.cer,.crt,.der" required></div>
|
<div class="form-row"><label for="signCertificate">证书</label><input id="signCertificate" type="file" accept=".pem,.cer,.crt,.der" required></div>
|
||||||
<div class="form-row"><label for="signKey">私钥</label><input id="signKey" type="file" accept=".pem,.key,.der" required></div>
|
<div class="form-row"><label for="signKey">私钥</label><input id="signKey" type="file" accept=".pem,.key,.der" required></div>
|
||||||
<div class="form-row"><label for="signKeyPassword">私钥口令</label><input id="signKeyPassword" type="password" autocomplete="off"></div>
|
<div class="form-row"><label for="signKeyPassword">私钥口令</label><input id="signKeyPassword" type="password" autocomplete="off"></div>
|
||||||
@@ -374,8 +375,9 @@
|
|||||||
<div class="form-actions"><div id="signStatus" class="form-status" role="status" aria-live="polite"></div><button id="signCancel" class="button" type="button">取消</button><button class="button" type="submit" title="签署另存">签署</button></div>
|
<div class="form-actions"><div id="signStatus" class="form-status" role="status" aria-live="polite"></div><button id="signCancel" class="button" type="button">取消</button><button class="button" type="submit" title="签署另存">签署</button></div>
|
||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
<dialog id="verifyPanel" class="form-dialog security-dialog" aria-label="验签">
|
<dialog id="verifyPanel" class="form-dialog security-dialog" aria-labelledby="verifyTitle">
|
||||||
<form id="verifyForm">
|
<form id="verifyForm">
|
||||||
|
<h2 id="verifyTitle" class="form-title">验证签名</h2>
|
||||||
<div class="form-row"><label for="verifyRoots">信任根</label><input id="verifyRoots" type="file" accept=".pem,.cer,.crt,.der" multiple></div>
|
<div class="form-row"><label for="verifyRoots">信任根</label><input id="verifyRoots" type="file" accept=".pem,.cer,.crt,.der" multiple></div>
|
||||||
<div class="form-row"><label for="verifyCerts">证书</label><input id="verifyCerts" type="file" accept=".pem,.cer,.crt,.der" multiple></div>
|
<div class="form-row"><label for="verifyCerts">证书</label><input id="verifyCerts" type="file" accept=".pem,.cer,.crt,.der" multiple></div>
|
||||||
<div class="form-row"><label for="verifyTimeRoots">时间戳根</label><input id="verifyTimeRoots" type="file" accept=".pem,.cer,.crt,.der" multiple></div>
|
<div class="form-row"><label for="verifyTimeRoots">时间戳根</label><input id="verifyTimeRoots" type="file" accept=".pem,.cer,.crt,.der" multiple></div>
|
||||||
@@ -386,8 +388,9 @@
|
|||||||
<div class="form-actions"><div id="verifyStatus" class="form-status" role="status" aria-live="polite"></div><button id="verifyCancel" class="button" type="button">取消</button><button class="button" type="submit">验签</button></div>
|
<div class="form-actions"><div id="verifyStatus" class="form-status" role="status" aria-live="polite"></div><button id="verifyCancel" class="button" type="button">取消</button><button class="button" type="submit">验签</button></div>
|
||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
<dialog id="credentialsPanel" class="form-dialog security-dialog" aria-label="解锁文档">
|
<dialog id="credentialsPanel" class="form-dialog security-dialog" aria-labelledby="credentialsTitle">
|
||||||
<form id="credentialsForm" autocomplete="off">
|
<form id="credentialsForm" autocomplete="off">
|
||||||
|
<h2 id="credentialsTitle" class="form-title">解锁文档</h2>
|
||||||
<div class="form-row"><label for="credentialsType">方式</label><select id="credentialsType"><option value="password">口令</option><option value="certificate">证书</option></select></div>
|
<div class="form-row"><label for="credentialsType">方式</label><select id="credentialsType"><option value="password">口令</option><option value="certificate">证书</option></select></div>
|
||||||
<div class="form-row"><label for="credentialsUser">用户</label><input id="credentialsUser" type="text" autocomplete="off" spellcheck="false"></div>
|
<div class="form-row"><label for="credentialsUser">用户</label><input id="credentialsUser" type="text" autocomplete="off" spellcheck="false"></div>
|
||||||
<div id="credentialsPasswordRow" class="form-row"><label for="credentialsPassword">口令</label><input id="credentialsPassword" type="password" autocomplete="off" required autofocus></div>
|
<div id="credentialsPasswordRow" class="form-row"><label for="credentialsPassword">口令</label><input id="credentialsPassword" type="password" autocomplete="off" required autofocus></div>
|
||||||
@@ -397,8 +400,9 @@
|
|||||||
<div class="form-actions"><div id="credentialsStatus" class="form-status" role="status" aria-live="polite"></div><button id="credentialsCancel" class="button" type="button">取消</button><button class="button" type="submit">解锁</button></div>
|
<div class="form-actions"><div id="credentialsStatus" class="form-status" role="status" aria-live="polite"></div><button id="credentialsCancel" class="button" type="button">取消</button><button class="button" type="submit">解锁</button></div>
|
||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
<dialog id="exportPanel" class="form-dialog" aria-label="导出文档">
|
<dialog id="exportPanel" class="form-dialog" aria-labelledby="exportTitle">
|
||||||
<form id="exportForm">
|
<form id="exportForm">
|
||||||
|
<h2 id="exportTitle" class="form-title">导出文档</h2>
|
||||||
<div id="encryptionFields" hidden>
|
<div id="encryptionFields" hidden>
|
||||||
<div class="form-row"><label for="encryptionType">方式</label><select id="encryptionType"><option value="password">口令</option><option value="certificate">证书</option></select></div>
|
<div class="form-row"><label for="encryptionType">方式</label><select id="encryptionType"><option value="password">口令</option><option value="certificate">证书</option></select></div>
|
||||||
<div id="encryptionUserRow" class="form-row"><label for="encryptionUser">用户</label><input id="encryptionUser" type="text" autocomplete="off" spellcheck="false"></div>
|
<div id="encryptionUserRow" class="form-row"><label for="encryptionUser">用户</label><input id="encryptionUser" type="text" autocomplete="off" spellcheck="false"></div>
|
||||||
|
|||||||
@@ -645,6 +645,16 @@ button:not(:disabled):hover {
|
|||||||
padding: 12px;
|
padding: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-title {
|
||||||
|
margin: -12px -12px 12px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
border-bottom: 1px solid var(--line);
|
||||||
|
background: #eef1f4;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
.security-dialog {
|
.security-dialog {
|
||||||
width: 360px;
|
width: 360px;
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-17
@@ -350,6 +350,7 @@ const el = {
|
|||||||
exportPageButton: document.querySelector("#exportPageButton"),
|
exportPageButton: document.querySelector("#exportPageButton"),
|
||||||
exportButton: document.querySelector("#exportButton"),
|
exportButton: document.querySelector("#exportButton"),
|
||||||
exportPanel: document.querySelector("#exportPanel"),
|
exportPanel: document.querySelector("#exportPanel"),
|
||||||
|
exportTitle: document.querySelector("#exportTitle"),
|
||||||
exportForm: document.querySelector("#exportForm"),
|
exportForm: document.querySelector("#exportForm"),
|
||||||
exportAll: document.querySelector("#exportAll"),
|
exportAll: document.querySelector("#exportAll"),
|
||||||
exportSpecified: document.querySelector("#exportSpecified"),
|
exportSpecified: document.querySelector("#exportSpecified"),
|
||||||
@@ -1602,7 +1603,7 @@ async function toggleEditor() {
|
|||||||
const openSeq = ++state.openSeq;
|
const openSeq = ++state.openSeq;
|
||||||
setBusy(true, "正在准备编辑", null, "正在准备编辑");
|
setBusy(true, "正在准备编辑", null, "正在准备编辑");
|
||||||
try {
|
try {
|
||||||
const doc = await callWASM("ofdgoEditDocument");
|
const doc = await callWASM("ofdgoEditDocument", pageIndex);
|
||||||
if (openSeq !== state.openSeq) return;
|
if (openSeq !== state.openSeq) return;
|
||||||
state.savedRevision = doc.revision;
|
state.savedRevision = doc.revision;
|
||||||
state.editorViews.clear();
|
state.editorViews.clear();
|
||||||
@@ -3961,7 +3962,7 @@ function openExportPanel(encrypted = false) {
|
|||||||
el.encryptionFields.hidden = !encrypted;
|
el.encryptionFields.hidden = !encrypted;
|
||||||
el.encryptionPassword.required = el.encryptionConfirm.required = encrypted;
|
el.encryptionPassword.required = el.encryptionConfirm.required = encrypted;
|
||||||
updateEncryptionType();
|
updateEncryptionType();
|
||||||
el.exportPanel.setAttribute("aria-label", encrypted ? "加密另存" : "导出文档");
|
el.exportTitle.textContent = encrypted ? "加密另存" : "导出文档";
|
||||||
el.exportSubmit.textContent = encrypted ? "保存" : "导出";
|
el.exportSubmit.textContent = encrypted ? "保存" : "导出";
|
||||||
if (state.editing && state.pageSelection.size) {
|
if (state.editing && state.pageSelection.size) {
|
||||||
el.exportSpecified.checked = true;
|
el.exportSpecified.checked = true;
|
||||||
@@ -5851,9 +5852,9 @@ function renderSignatures() {
|
|||||||
|
|
||||||
head.append(badges, name);
|
head.append(badges, name);
|
||||||
row.append(head);
|
row.append(head);
|
||||||
appendInfoLine(row, "章名", signature.sealName);
|
|
||||||
appendInfoLine(row, "签署人", signature.signer);
|
appendInfoLine(row, "签署人", signature.signer);
|
||||||
appendInfoLine(row, "时间", formatDocumentTime(signature.signatureDateTime));
|
appendInfoLine(row, "时间", formatDocumentTime(signature.signatureDateTime));
|
||||||
|
appendInfoLine(row, "章名", signature.sealName);
|
||||||
appendInfoLine(row, "机构", signatureAgency(signature));
|
appendInfoLine(row, "机构", signatureAgency(signature));
|
||||||
appendSignatureCheck(row, "信任", signature.certTrustChecked, signature.certTrustOK);
|
appendSignatureCheck(row, "信任", signature.certTrustChecked, signature.certTrustOK);
|
||||||
appendInfoLine(row, "保护文件", signatureReferenceText(signature), signatureReferenceStatus(signature));
|
appendInfoLine(row, "保护文件", signatureReferenceText(signature), signatureReferenceStatus(signature));
|
||||||
@@ -5864,25 +5865,25 @@ function renderSignatures() {
|
|||||||
checks.append(checksTitle);
|
checks.append(checksTitle);
|
||||||
appendSignatureCheck(checks, "原文", signature.dataHashChecked, signature.dataHashOK);
|
appendSignatureCheck(checks, "原文", signature.dataHashChecked, signature.dataHashOK);
|
||||||
appendSignatureCheck(checks, "签名", signature.signedValueChecked, signature.signedValueOK);
|
appendSignatureCheck(checks, "签名", signature.signedValueChecked, signature.signedValueOK);
|
||||||
|
appendSignatureCheck(checks, "证书", signature.certChecked, signature.certOK);
|
||||||
|
appendSignaturePolicy(checks, "证书期限", signature.certTimeChecked, signature.certTimeOK);
|
||||||
|
appendInfoLine(checks, "信任错误", signature.certTrustError, "fail");
|
||||||
|
appendSignaturePolicy(checks, "签署时间", signature.signatureTimeChecked, signature.signatureTimeOK);
|
||||||
if (signature.type !== "Sign") {
|
if (signature.type !== "Sign") {
|
||||||
appendSignatureCheck(checks, "印章", signature.sealChecked, signature.sealOK);
|
appendSignatureCheck(checks, "印章", signature.sealChecked, signature.sealOK);
|
||||||
appendSignaturePolicy(checks, "印章匹配", signature.sealMatchChecked, signature.sealMatchOK);
|
appendSignaturePolicy(checks, "印章匹配", signature.sealMatchChecked, signature.sealMatchOK);
|
||||||
}
|
|
||||||
appendSignatureCheck(checks, "证书", signature.certChecked, signature.certOK);
|
|
||||||
appendSignaturePolicy(checks, "签署时间", signature.signatureTimeChecked, signature.signatureTimeOK);
|
|
||||||
appendSignaturePolicy(checks, "印章期限", signature.sealTimeChecked, signature.sealTimeOK);
|
appendSignaturePolicy(checks, "印章期限", signature.sealTimeChecked, signature.sealTimeOK);
|
||||||
if (signature.sealCertTimeChecked) {
|
if (signature.sealCertTimeChecked) {
|
||||||
appendInfoLine(checks, "制章证书", signature.sealCertTimeOK ? "有效" : "失效", signature.sealCertTimeOK ? "ok" : "fail");
|
appendInfoLine(checks, "制章证书", signature.sealCertTimeOK ? "有效" : "失效", signature.sealCertTimeOK ? "ok" : "fail");
|
||||||
}
|
}
|
||||||
appendSignaturePolicy(checks, "证书期限", signature.certTimeChecked, signature.certTimeOK);
|
}
|
||||||
appendSignatureCheck(checks, "策略", signature.policyChecked, signature.policyOK);
|
|
||||||
appendSignatureCheck(checks, "覆盖", signature.coverageChecked, signature.coverageOK);
|
appendSignatureCheck(checks, "覆盖", signature.coverageChecked, signature.coverageOK);
|
||||||
appendSignatureCheck(checks, "时间戳", signature.timestampChecked, signature.timestampOK);
|
|
||||||
appendSignatureCheck(checks, "撤销", signature.revocationChecked, signature.revocationOK);
|
|
||||||
appendInfoLine(checks, "策略错误", signature.policyError, "fail");
|
|
||||||
appendInfoLine(checks, "信任错误", signature.certTrustError, "fail");
|
|
||||||
appendInfoLine(checks, "覆盖错误", signature.coverageError, "fail");
|
appendInfoLine(checks, "覆盖错误", signature.coverageError, "fail");
|
||||||
appendInfoLine(checks, "未保护", signature.uncoveredFiles?.join("、"), "fail");
|
appendInfoLine(checks, "未保护", signature.uncoveredFiles?.join("、"), "fail");
|
||||||
|
appendSignatureCheck(checks, "策略", signature.policyChecked, signature.policyOK);
|
||||||
|
appendInfoLine(checks, "策略错误", signature.policyError, "fail");
|
||||||
|
appendSignatureCheck(checks, "时间戳", signature.timestampChecked, signature.timestampOK);
|
||||||
|
appendSignatureCheck(checks, "撤销", signature.revocationChecked, signature.revocationOK);
|
||||||
row.append(checks);
|
row.append(checks);
|
||||||
for (const timestamp of signature.timestamps || []) {
|
for (const timestamp of signature.timestamps || []) {
|
||||||
const details = document.createElement("details");
|
const details = document.createElement("details");
|
||||||
@@ -5917,17 +5918,17 @@ function renderSignatures() {
|
|||||||
title.textContent = "签章信息";
|
title.textContent = "签章信息";
|
||||||
details.append(title);
|
details.append(title);
|
||||||
appendInfoLine(details, "编号", signature.id);
|
appendInfoLine(details, "编号", signature.id);
|
||||||
appendInfoLine(details, "版本", signature.version);
|
|
||||||
appendInfoLine(details, "章图", signature.sealType);
|
|
||||||
appendInfoLine(details, "章号", signature.sealId);
|
|
||||||
appendInfoLine(details, "厂商", signature.sealVendor);
|
|
||||||
appendInfoLine(details, "文档", signature.docRoot);
|
appendInfoLine(details, "文档", signature.docRoot);
|
||||||
appendInfoLine(details, "算法", signature.signatureMethod);
|
appendInfoLine(details, "算法", signature.signatureMethod);
|
||||||
appendInfoLine(details, "摘要", signature.digestMethod);
|
appendInfoLine(details, "摘要", signature.digestMethod);
|
||||||
appendInfoLine(details, "序列号", signature.signSerial);
|
|
||||||
appendInfoLine(details, "证书主体", signature.signSubject);
|
appendInfoLine(details, "证书主体", signature.signSubject);
|
||||||
appendInfoLine(details, "颁发者", signature.signIssuer);
|
appendInfoLine(details, "颁发者", signature.signIssuer);
|
||||||
|
appendInfoLine(details, "序列号", signature.signSerial);
|
||||||
|
appendInfoLine(details, "章号", signature.sealId);
|
||||||
|
appendInfoLine(details, "章图", signature.sealType);
|
||||||
appendInfoLine(details, "制章证书", signature.sealSubject);
|
appendInfoLine(details, "制章证书", signature.sealSubject);
|
||||||
|
appendInfoLine(details, "印章厂商", signature.sealVendor);
|
||||||
|
appendInfoLine(details, "组件版本", signature.version);
|
||||||
row.append(details);
|
row.append(details);
|
||||||
fragment.append(row);
|
fragment.append(row);
|
||||||
}
|
}
|
||||||
|
|||||||
+45
-2
@@ -498,6 +498,15 @@ func renderPage(args []js.Value) (any, error) {
|
|||||||
dpi = args[2].Float()
|
dpi = args[2].Float()
|
||||||
}
|
}
|
||||||
raster := len(args) > 3 && args[3].Bool()
|
raster := len(args) > 3 && args[3].Bool()
|
||||||
|
if currentEditor != nil {
|
||||||
|
page, err := currentEditor.Page(args[0].Int())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := syncEditorPageIDs(args[0].Int(), page); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
page, err := currentSession.RenderPage(args[0].Int(), backend, dpi, raster)
|
page, err := currentSession.RenderPage(args[0].Int(), backend, dpi, raster)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -569,7 +578,7 @@ func renderPage(args []js.Value) (any, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pageTextString 提取OFD页面原文
|
// pageTextString 提取OFD页面原文
|
||||||
// 入参: args 浏览器参数
|
// 入参: args 页面索引
|
||||||
// 返回: any 页面原文, error 错误信息
|
// 返回: any 页面原文, error 错误信息
|
||||||
func pageTextString(args []js.Value) (any, error) {
|
func pageTextString(args []js.Value) (any, error) {
|
||||||
if currentSession == nil {
|
if currentSession == nil {
|
||||||
@@ -2906,7 +2915,7 @@ func updateInfo(args []js.Value) (any, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// editDocument 将已打开文档接入编辑器,沿用页面、资源及字体配置
|
// editDocument 将已打开文档接入编辑器,沿用页面、资源及字体配置
|
||||||
// 入参: args 浏览器参数
|
// 入参: args 当前页索引,省略时使用首页
|
||||||
// 返回: any 编辑状态, error 错误信息
|
// 返回: any 编辑状态, error 错误信息
|
||||||
func editDocument(args []js.Value) (any, error) {
|
func editDocument(args []js.Value) (any, error) {
|
||||||
if currentSession == nil {
|
if currentSession == nil {
|
||||||
@@ -2924,6 +2933,17 @@ func editDocument(args []js.Value) (any, error) {
|
|||||||
editor.SetFontFS(currentSession.fontFS)
|
editor.SetFontFS(currentSession.fontFS)
|
||||||
}
|
}
|
||||||
editor.SetRenderBackends(currentSession.Renderer.Backends())
|
editor.SetRenderBackends(currentSession.Renderer.Backends())
|
||||||
|
page := 0
|
||||||
|
if len(args) != 0 {
|
||||||
|
page = args[0].Int()
|
||||||
|
}
|
||||||
|
content, err := editor.Page(page)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := syncEditorPageIDs(page, content); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
currentEditor = editor
|
currentEditor = editor
|
||||||
currentSession.editing = true
|
currentSession.editing = true
|
||||||
copiedObjects = nil
|
copiedObjects = nil
|
||||||
@@ -2931,6 +2951,29 @@ func editDocument(args []js.Value) (any, error) {
|
|||||||
return editorSummary(), nil
|
return editorSummary(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// syncEditorPageIDs 同步编辑副本的对象编号,不改变原渲染属性或丢弃正常页面缓存
|
||||||
|
// 入参: index 页面索引, content 编辑页面
|
||||||
|
// 返回: error 页面读取错误
|
||||||
|
func syncEditorPageIDs(index int, content *ofdgo.PageContent) error {
|
||||||
|
page, err := currentSession.pageContent(index)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, layer := range content.Content.Layer {
|
||||||
|
for j, object := range layer.Objects {
|
||||||
|
before := &page.Content.Layer[i].Objects[j]
|
||||||
|
if before.TextObject.ID != object.TextObject.ID || before.PathObject.ID != object.PathObject.ID || before.ImageObject.ID != object.ImageObject.ID || before.CompositeGraphicUnit.ID != object.CompositeGraphicUnit.ID {
|
||||||
|
before.TextObject.ID = object.TextObject.ID
|
||||||
|
before.PathObject.ID = object.PathObject.ID
|
||||||
|
before.ImageObject.ID = object.ImageObject.ID
|
||||||
|
before.CompositeGraphicUnit.ID = object.CompositeGraphicUnit.ID
|
||||||
|
delete(currentSession.textCache, index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// previewEditor 通过内存快照更新预览,不生成中间压缩包
|
// previewEditor 通过内存快照更新预览,不生成中间压缩包
|
||||||
// 入参: editor 编辑文档, annotations 是否显示注解
|
// 入参: editor 编辑文档, annotations 是否显示注解
|
||||||
// 返回: editorInfo 文档信息, error 错误信息
|
// 返回: editorInfo 文档信息, error 错误信息
|
||||||
|
|||||||
+86
-86
@@ -43,65 +43,65 @@ type FontInfo = ofdgo.FontInfo
|
|||||||
type SignatureInfo struct {
|
type SignatureInfo struct {
|
||||||
DocIndex int `json:"docIndex"`
|
DocIndex int `json:"docIndex"`
|
||||||
DocRoot string `json:"docRoot,omitempty"`
|
DocRoot string `json:"docRoot,omitempty"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Status string `json:"status"`
|
||||||
IntegrityValid bool `json:"integrityValid"`
|
IntegrityValid bool `json:"integrityValid"`
|
||||||
TrustedValid bool `json:"trustedValid"`
|
TrustedValid bool `json:"trustedValid"`
|
||||||
PolicyChecked bool `json:"policyChecked"`
|
Error string `json:"error,omitempty"`
|
||||||
PolicyOK bool `json:"policyOK"`
|
Signer string `json:"signer,omitempty"`
|
||||||
PolicyError string `json:"policyError,omitempty"`
|
SignatureDateTime string `json:"signatureDateTime,omitempty"`
|
||||||
|
SealName string `json:"sealName,omitempty"`
|
||||||
|
Provider string `json:"provider,omitempty"`
|
||||||
|
Company string `json:"company,omitempty"`
|
||||||
|
SealType string `json:"sealType,omitempty"`
|
||||||
|
SealID string `json:"sealId,omitempty"`
|
||||||
|
SealVendor string `json:"sealVendor,omitempty"`
|
||||||
|
Version string `json:"version,omitempty"`
|
||||||
|
SignSubject string `json:"signSubject,omitempty"`
|
||||||
|
SignIssuer string `json:"signIssuer,omitempty"`
|
||||||
|
SignSerial string `json:"signSerial,omitempty"`
|
||||||
|
SealSubject string `json:"sealSubject,omitempty"`
|
||||||
|
SignatureMethod string `json:"signatureMethod,omitempty"`
|
||||||
|
DigestMethod string `json:"digestMethod,omitempty"`
|
||||||
|
ReferenceCount int `json:"referenceCount"`
|
||||||
|
ReferenceChecked int `json:"referenceChecked"`
|
||||||
|
ReferencePassed int `json:"referencePassed"`
|
||||||
|
Stamps []SignatureStampInfo `json:"stamps,omitempty"`
|
||||||
|
DataHashChecked bool `json:"dataHashChecked"`
|
||||||
|
DataHashOK bool `json:"dataHashOK"`
|
||||||
|
SignedValueChecked bool `json:"signedValueChecked"`
|
||||||
|
SignedValueOK bool `json:"signedValueOK"`
|
||||||
|
CertChecked bool `json:"certChecked"`
|
||||||
|
CertOK bool `json:"certOK"`
|
||||||
|
CertTimeChecked bool `json:"certTimeChecked,omitempty"`
|
||||||
|
CertTimeOK bool `json:"certTimeOK,omitempty"`
|
||||||
|
CertTrustChecked bool `json:"certTrustChecked,omitempty"`
|
||||||
|
CertTrustOK bool `json:"certTrustOK,omitempty"`
|
||||||
|
CertTrustError string `json:"certTrustError,omitempty"`
|
||||||
|
SignatureTimeChecked bool `json:"signatureTimeChecked,omitempty"`
|
||||||
|
SignatureTimeOK bool `json:"signatureTimeOK,omitempty"`
|
||||||
|
SealChecked bool `json:"sealChecked"`
|
||||||
|
SealOK bool `json:"sealOK"`
|
||||||
|
SealMatchChecked bool `json:"sealMatchChecked"`
|
||||||
|
SealMatchOK bool `json:"sealMatchOK"`
|
||||||
|
SealTimeChecked bool `json:"sealTimeChecked,omitempty"`
|
||||||
|
SealTimeOK bool `json:"sealTimeOK,omitempty"`
|
||||||
|
SealCertTimeChecked bool `json:"sealCertTimeChecked,omitempty"`
|
||||||
|
SealCertTimeOK bool `json:"sealCertTimeOK,omitempty"`
|
||||||
CoverageChecked bool `json:"coverageChecked"`
|
CoverageChecked bool `json:"coverageChecked"`
|
||||||
CoverageOK bool `json:"coverageOK"`
|
CoverageOK bool `json:"coverageOK"`
|
||||||
CoverageError string `json:"coverageError,omitempty"`
|
CoverageError string `json:"coverageError,omitempty"`
|
||||||
UncoveredFiles []string `json:"uncoveredFiles,omitempty"`
|
UncoveredFiles []string `json:"uncoveredFiles,omitempty"`
|
||||||
|
PolicyChecked bool `json:"policyChecked"`
|
||||||
|
PolicyOK bool `json:"policyOK"`
|
||||||
|
PolicyError string `json:"policyError,omitempty"`
|
||||||
TimestampChecked bool `json:"timestampChecked"`
|
TimestampChecked bool `json:"timestampChecked"`
|
||||||
TimestampOK bool `json:"timestampOK"`
|
TimestampOK bool `json:"timestampOK"`
|
||||||
Timestamps []TimestampInfo `json:"timestamps,omitempty"`
|
Timestamps []TimestampInfo `json:"timestamps,omitempty"`
|
||||||
RevocationChecked bool `json:"revocationChecked"`
|
RevocationChecked bool `json:"revocationChecked"`
|
||||||
RevocationOK bool `json:"revocationOK"`
|
RevocationOK bool `json:"revocationOK"`
|
||||||
Revocations []RevocationInfo `json:"revocations,omitempty"`
|
Revocations []RevocationInfo `json:"revocations,omitempty"`
|
||||||
ID string `json:"id"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
Status string `json:"status"`
|
|
||||||
Version string `json:"version,omitempty"`
|
|
||||||
SealType string `json:"sealType,omitempty"`
|
|
||||||
SealID string `json:"sealId,omitempty"`
|
|
||||||
SealName string `json:"sealName,omitempty"`
|
|
||||||
SealVendor string `json:"sealVendor,omitempty"`
|
|
||||||
Signer string `json:"signer,omitempty"`
|
|
||||||
SignatureDateTime string `json:"signatureDateTime,omitempty"`
|
|
||||||
Provider string `json:"provider,omitempty"`
|
|
||||||
Company string `json:"company,omitempty"`
|
|
||||||
DataHashChecked bool `json:"dataHashChecked"`
|
|
||||||
DataHashOK bool `json:"dataHashOK"`
|
|
||||||
SignedValueChecked bool `json:"signedValueChecked"`
|
|
||||||
SignedValueOK bool `json:"signedValueOK"`
|
|
||||||
SealChecked bool `json:"sealChecked"`
|
|
||||||
SealOK bool `json:"sealOK"`
|
|
||||||
SealMatchChecked bool `json:"sealMatchChecked"`
|
|
||||||
SealMatchOK bool `json:"sealMatchOK"`
|
|
||||||
CertChecked bool `json:"certChecked"`
|
|
||||||
CertOK bool `json:"certOK"`
|
|
||||||
SignatureTimeChecked bool `json:"signatureTimeChecked,omitempty"`
|
|
||||||
SignatureTimeOK bool `json:"signatureTimeOK,omitempty"`
|
|
||||||
SealTimeChecked bool `json:"sealTimeChecked,omitempty"`
|
|
||||||
SealTimeOK bool `json:"sealTimeOK,omitempty"`
|
|
||||||
SealCertTimeChecked bool `json:"sealCertTimeChecked,omitempty"`
|
|
||||||
SealCertTimeOK bool `json:"sealCertTimeOK,omitempty"`
|
|
||||||
CertTimeChecked bool `json:"certTimeChecked,omitempty"`
|
|
||||||
CertTimeOK bool `json:"certTimeOK,omitempty"`
|
|
||||||
CertTrustChecked bool `json:"certTrustChecked,omitempty"`
|
|
||||||
CertTrustOK bool `json:"certTrustOK,omitempty"`
|
|
||||||
CertTrustError string `json:"certTrustError,omitempty"`
|
|
||||||
ReferenceCount int `json:"referenceCount"`
|
|
||||||
ReferenceChecked int `json:"referenceChecked"`
|
|
||||||
ReferencePassed int `json:"referencePassed"`
|
|
||||||
SignatureMethod string `json:"signatureMethod,omitempty"`
|
|
||||||
DigestMethod string `json:"digestMethod,omitempty"`
|
|
||||||
SignSerial string `json:"signSerial,omitempty"`
|
|
||||||
SignSubject string `json:"signSubject,omitempty"`
|
|
||||||
SignIssuer string `json:"signIssuer,omitempty"`
|
|
||||||
SealSubject string `json:"sealSubject,omitempty"`
|
|
||||||
Stamps []SignatureStampInfo `json:"stamps,omitempty"`
|
|
||||||
Error string `json:"error,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TimestampInfo 独立展示时间戳绑定、签名、信任和证书时效
|
// TimestampInfo 独立展示时间戳绑定、签名、信任和证书时效
|
||||||
@@ -681,63 +681,63 @@ func signatureInfo(report ofdgo.SignatureVerifyReport) SignatureInfo {
|
|||||||
info := SignatureInfo{
|
info := SignatureInfo{
|
||||||
DocIndex: report.DocIndex,
|
DocIndex: report.DocIndex,
|
||||||
DocRoot: report.DocRoot,
|
DocRoot: report.DocRoot,
|
||||||
IntegrityValid: report.IntegrityValid(),
|
|
||||||
TrustedValid: report.TrustedValid(),
|
|
||||||
PolicyChecked: report.PolicyChecked,
|
|
||||||
PolicyOK: report.PolicyOK,
|
|
||||||
PolicyError: report.PolicyError,
|
|
||||||
CoverageChecked: report.CoverageChecked,
|
|
||||||
CoverageOK: report.CoverageOK,
|
|
||||||
CoverageError: report.CoverageError,
|
|
||||||
UncoveredFiles: report.UncoveredFiles,
|
|
||||||
TimestampChecked: report.TimestampChecked,
|
|
||||||
TimestampOK: report.TimestampOK,
|
|
||||||
RevocationChecked: report.RevocationChecked,
|
|
||||||
RevocationOK: report.RevocationOK,
|
|
||||||
ID: report.ID,
|
ID: report.ID,
|
||||||
Type: string(report.Type),
|
Type: string(report.Type),
|
||||||
Status: status,
|
Status: status,
|
||||||
Version: report.Provider.Version,
|
IntegrityValid: report.IntegrityValid(),
|
||||||
SealType: report.SealType,
|
TrustedValid: report.TrustedValid(),
|
||||||
SealID: report.SealInfo.ID,
|
Error: signatureReportError(report),
|
||||||
SealName: report.SealInfo.Name,
|
|
||||||
SealVendor: report.SealInfo.VendorID,
|
|
||||||
Signer: signatureSigner(report),
|
Signer: signatureSigner(report),
|
||||||
SignatureDateTime: dateTime,
|
SignatureDateTime: dateTime,
|
||||||
|
SealName: report.SealInfo.Name,
|
||||||
Provider: report.Provider.ProviderName,
|
Provider: report.Provider.ProviderName,
|
||||||
Company: report.Provider.Company,
|
Company: report.Provider.Company,
|
||||||
|
SealType: report.SealType,
|
||||||
|
SealID: report.SealInfo.ID,
|
||||||
|
SealVendor: report.SealInfo.VendorID,
|
||||||
|
Version: report.Provider.Version,
|
||||||
|
SignSubject: report.SignCert.Subject,
|
||||||
|
SignIssuer: report.SignCert.Issuer,
|
||||||
|
SignSerial: report.SignCert.SerialNumber,
|
||||||
|
SealSubject: report.SealCert.Subject,
|
||||||
|
SignatureMethod: report.SignatureMethod,
|
||||||
|
DigestMethod: report.DigestMethod,
|
||||||
|
ReferenceCount: len(report.References),
|
||||||
|
ReferenceChecked: checked,
|
||||||
|
ReferencePassed: passed,
|
||||||
|
Stamps: signatureStampInfos(report.StampPositions),
|
||||||
DataHashChecked: report.DataHashChecked,
|
DataHashChecked: report.DataHashChecked,
|
||||||
DataHashOK: report.DataHashOK,
|
DataHashOK: report.DataHashOK,
|
||||||
SignedValueChecked: report.SignedValueChecked,
|
SignedValueChecked: report.SignedValueChecked,
|
||||||
SignedValueOK: report.SignedValueOK,
|
SignedValueOK: report.SignedValueOK,
|
||||||
SealChecked: report.SealChecked,
|
|
||||||
SealOK: report.SealOK,
|
|
||||||
SealMatchChecked: report.SealMatchChecked,
|
|
||||||
SealMatchOK: report.SealMatchOK,
|
|
||||||
CertChecked: report.CertChecked,
|
CertChecked: report.CertChecked,
|
||||||
CertOK: report.CertOK,
|
CertOK: report.CertOK,
|
||||||
SignatureTimeChecked: report.SignatureTimeChecked,
|
|
||||||
SignatureTimeOK: report.SignatureTimeOK,
|
|
||||||
SealTimeChecked: report.SealTimeChecked,
|
|
||||||
SealTimeOK: report.SealTimeOK,
|
|
||||||
SealCertTimeChecked: report.SealCertTimeChecked,
|
|
||||||
SealCertTimeOK: report.SealCertTimeOK,
|
|
||||||
CertTimeChecked: report.CertTimeChecked,
|
CertTimeChecked: report.CertTimeChecked,
|
||||||
CertTimeOK: report.CertTimeOK,
|
CertTimeOK: report.CertTimeOK,
|
||||||
CertTrustChecked: report.CertTrustChecked,
|
CertTrustChecked: report.CertTrustChecked,
|
||||||
CertTrustOK: report.CertTrustOK,
|
CertTrustOK: report.CertTrustOK,
|
||||||
CertTrustError: report.CertTrustError,
|
CertTrustError: report.CertTrustError,
|
||||||
ReferenceCount: len(report.References),
|
SignatureTimeChecked: report.SignatureTimeChecked,
|
||||||
ReferenceChecked: checked,
|
SignatureTimeOK: report.SignatureTimeOK,
|
||||||
ReferencePassed: passed,
|
SealChecked: report.SealChecked,
|
||||||
SignatureMethod: report.SignatureMethod,
|
SealOK: report.SealOK,
|
||||||
DigestMethod: report.DigestMethod,
|
SealMatchChecked: report.SealMatchChecked,
|
||||||
SignSerial: report.SignCert.SerialNumber,
|
SealMatchOK: report.SealMatchOK,
|
||||||
SignSubject: report.SignCert.Subject,
|
SealTimeChecked: report.SealTimeChecked,
|
||||||
SignIssuer: report.SignCert.Issuer,
|
SealTimeOK: report.SealTimeOK,
|
||||||
SealSubject: report.SealCert.Subject,
|
SealCertTimeChecked: report.SealCertTimeChecked,
|
||||||
Stamps: signatureStampInfos(report.StampPositions),
|
SealCertTimeOK: report.SealCertTimeOK,
|
||||||
Error: signatureReportError(report),
|
CoverageChecked: report.CoverageChecked,
|
||||||
|
CoverageOK: report.CoverageOK,
|
||||||
|
CoverageError: report.CoverageError,
|
||||||
|
UncoveredFiles: report.UncoveredFiles,
|
||||||
|
PolicyChecked: report.PolicyChecked,
|
||||||
|
PolicyOK: report.PolicyOK,
|
||||||
|
PolicyError: report.PolicyError,
|
||||||
|
TimestampChecked: report.TimestampChecked,
|
||||||
|
TimestampOK: report.TimestampOK,
|
||||||
|
RevocationChecked: report.RevocationChecked,
|
||||||
|
RevocationOK: report.RevocationOK,
|
||||||
}
|
}
|
||||||
for _, stamp := range report.Timestamps {
|
for _, stamp := range report.Timestamps {
|
||||||
info.Timestamps = append(info.Timestamps, TimestampInfo{
|
info.Timestamps = append(info.Timestamps, TimestampInfo{
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ type editorSourcePage struct {
|
|||||||
root *editorXML
|
root *editorXML
|
||||||
original *PageContent
|
original *PageContent
|
||||||
nodes map[string]*editorXML
|
nodes map[string]*editorXML
|
||||||
|
repaired bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ObjectCapabilities 已有对象可执行的操作,Reason说明受限原因
|
// ObjectCapabilities 已有对象可执行的操作,Reason说明受限原因
|
||||||
@@ -260,6 +261,103 @@ func (e *Editor) sourceRGB() bool {
|
|||||||
return space != nil && space.Type == "RGB" && (space.BitsPerComponent == 0 || space.BitsPerComponent == 8) && len(space.Palette) == 0
|
return space != nil && space.Type == "RGB" && (space.BitsPerComponent == 0 || space.BitsPerComponent == 8) && len(space.Palette) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// repairSourceObjectIDs 按实际节点区分重复对象,只修复没有引用歧义的编号
|
||||||
|
// 入参: data 页面原文, root 页面节点
|
||||||
|
// 返回: []byte 编辑副本, bool 是否修复, error 错误信息
|
||||||
|
func (e *Editor) repairSourceObjectIDs(data []byte, root *editorXML) ([]byte, bool, error) {
|
||||||
|
seen := make(map[string]bool)
|
||||||
|
duplicates := make(map[string]bool)
|
||||||
|
var nodes []*editorXML
|
||||||
|
var visit func(*editorXML) error
|
||||||
|
visit = func(parent *editorXML) error {
|
||||||
|
for _, node := range parent.children {
|
||||||
|
id := node.attr("ID")
|
||||||
|
if id != "" && seen[id] {
|
||||||
|
switch node.name.Local {
|
||||||
|
case "TextObject", "PathObject", "ImageObject", "CompositeObject":
|
||||||
|
nodes = append(nodes, node)
|
||||||
|
duplicates[id] = true
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("duplicate container ID %q", id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
seen[id] = true
|
||||||
|
if node.name.Local == "PageBlock" {
|
||||||
|
if err := visit(node); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if content := root.child("Content"); content != nil {
|
||||||
|
for _, layer := range content.children {
|
||||||
|
if layer.name.Local == "Layer" {
|
||||||
|
if err := visit(layer); err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(nodes) == 0 {
|
||||||
|
return data, false, nil
|
||||||
|
}
|
||||||
|
if err := e.checkDuplicateObjectReferences(duplicates); err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
if err := e.prepareSourceIDs(); err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
maximum := e.maxID
|
||||||
|
var patches []editorXMLPatch
|
||||||
|
for _, node := range nodes {
|
||||||
|
maximum++
|
||||||
|
encoded, err := editorXMLAttribute(data, node, "ID", strconv.Itoa(maximum))
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
patches = append(patches, editorXMLPatch{node.start, node.end, encoded})
|
||||||
|
}
|
||||||
|
e.maxID = maximum
|
||||||
|
return editorPatchXML(data, patches), true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// checkDuplicateObjectReferences 拒绝无法判定目标的编号引用,不猜测其所属对象
|
||||||
|
// 入参: duplicates 重复编号
|
||||||
|
// 返回: error 引用歧义或读取错误
|
||||||
|
func (e *Editor) checkDuplicateObjectReferences(duplicates map[string]bool) error {
|
||||||
|
reader := e.source.reader
|
||||||
|
for _, name := range reader.fileNamesFold {
|
||||||
|
if !strings.EqualFold(path.Ext(name), ".xml") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
input, err := reader.openFile(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
decoder := xml.NewDecoder(input)
|
||||||
|
for {
|
||||||
|
token, readErr := decoder.Token()
|
||||||
|
if readErr != nil {
|
||||||
|
input.Close()
|
||||||
|
if readErr != io.EOF {
|
||||||
|
return readErr
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if node, ok := token.(xml.StartElement); ok {
|
||||||
|
for _, attr := range node.Attr {
|
||||||
|
if editorObjectReference(attr.Name.Local) && duplicates[editorResourceID(attr.Value)] {
|
||||||
|
input.Close()
|
||||||
|
return fmt.Errorf("ambiguous reference to duplicate object ID %q in %s", attr.Value, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// loadSourcePage 首次访问时解析原始页面,不加载图片或字体二进制数据
|
// loadSourcePage 首次访问时解析原始页面,不加载图片或字体二进制数据
|
||||||
// 入参: index 页面索引
|
// 入参: index 页面索引
|
||||||
// 返回: error 错误信息
|
// 返回: error 错误信息
|
||||||
@@ -281,6 +379,21 @@ func (e *Editor) loadSourcePage(index int) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
data, repaired, err := e.repairSourceObjectIDs(data, root)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if repaired {
|
||||||
|
root, err = parseEditorXML(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var updated PageContent
|
||||||
|
if err := xml.Unmarshal(data, &updated); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
page.Content = updated.Content
|
||||||
|
}
|
||||||
nodes := make(map[string]*editorXML)
|
nodes := make(map[string]*editorXML)
|
||||||
if content := root.child("Content"); content != nil {
|
if content := root.child("Content"); content != nil {
|
||||||
for _, layer := range content.children {
|
for _, layer := range content.children {
|
||||||
@@ -293,6 +406,7 @@ func (e *Editor) loadSourcePage(index int) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
source.data, source.root, source.nodes = data, root, nodes
|
source.data, source.root, source.nodes = data, root, nodes
|
||||||
|
source.repaired = repaired
|
||||||
for i := range page.Content.Layer {
|
for i := range page.Content.Layer {
|
||||||
layer := &page.Content.Layer[i]
|
layer := &page.Content.Layer[i]
|
||||||
for j, object := range layer.Objects {
|
for j, object := range layer.Objects {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ func (e *Editor) sourceParts(progress editorProgress) (map[string][]byte, error)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !bytes.Equal(data, original.data) {
|
if original.repaired || !bytes.Equal(data, original.data) {
|
||||||
parts[reader.ResPath(original.ref.BaseLoc)] = data
|
parts[reader.ResPath(original.ref.BaseLoc)] = data
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+32
-32
@@ -46,32 +46,20 @@ import (
|
|||||||
type SignatureVerifyReport struct {
|
type SignatureVerifyReport struct {
|
||||||
DocIndex int
|
DocIndex int
|
||||||
DocRoot string
|
DocRoot string
|
||||||
PolicyChecked bool
|
|
||||||
PolicyOK bool
|
|
||||||
PolicyError string
|
|
||||||
CoverageChecked bool
|
|
||||||
CoverageOK bool
|
|
||||||
CoverageError string
|
|
||||||
CoveredFiles []string
|
|
||||||
UncoveredFiles []string
|
|
||||||
TimestampChecked bool
|
|
||||||
TimestampOK bool
|
|
||||||
Timestamps []SignatureTimestampReport
|
|
||||||
RevocationChecked bool
|
|
||||||
RevocationOK bool
|
|
||||||
Revocations []SignatureRevocationReport
|
|
||||||
ID string
|
ID string
|
||||||
BaseLoc string
|
BaseLoc string
|
||||||
Type SignType
|
Type SignType
|
||||||
Provider SignatureProvider
|
Valid bool
|
||||||
|
Error string
|
||||||
Signer string
|
Signer string
|
||||||
SignCert SignatureCertInfo
|
|
||||||
SealCert SignatureCertInfo
|
|
||||||
SealInfo SignatureSealInfo
|
|
||||||
SealType string
|
|
||||||
SignatureMethod string
|
|
||||||
SignatureDateTime string
|
SignatureDateTime string
|
||||||
SignatureTime time.Time
|
SignatureTime time.Time
|
||||||
|
Provider SignatureProvider
|
||||||
|
SealInfo SignatureSealInfo
|
||||||
|
SealType string
|
||||||
|
SignCert SignatureCertInfo
|
||||||
|
SealCert SignatureCertInfo
|
||||||
|
SignatureMethod string
|
||||||
DigestMethod string
|
DigestMethod string
|
||||||
References []SignatureReferenceVerify
|
References []SignatureReferenceVerify
|
||||||
Stamps []SignatureStamp
|
Stamps []SignatureStamp
|
||||||
@@ -82,25 +70,37 @@ type SignatureVerifyReport struct {
|
|||||||
DataHashOK bool
|
DataHashOK bool
|
||||||
SignedValueChecked bool
|
SignedValueChecked bool
|
||||||
SignedValueOK bool
|
SignedValueOK bool
|
||||||
SealChecked bool
|
|
||||||
SealOK bool
|
|
||||||
SealMatchChecked bool
|
|
||||||
SealMatchOK bool
|
|
||||||
CertChecked bool
|
CertChecked bool
|
||||||
CertOK bool
|
CertOK bool
|
||||||
SignatureTimeChecked bool
|
|
||||||
SignatureTimeOK bool
|
|
||||||
SealCertTimeChecked bool
|
|
||||||
SealCertTimeOK bool
|
|
||||||
SealTimeChecked bool
|
|
||||||
SealTimeOK bool
|
|
||||||
CertTimeChecked bool
|
CertTimeChecked bool
|
||||||
CertTimeOK bool
|
CertTimeOK bool
|
||||||
CertTrustChecked bool
|
CertTrustChecked bool
|
||||||
CertTrustOK bool
|
CertTrustOK bool
|
||||||
CertTrustError string
|
CertTrustError string
|
||||||
Valid bool
|
SignatureTimeChecked bool
|
||||||
Error string
|
SignatureTimeOK bool
|
||||||
|
SealChecked bool
|
||||||
|
SealOK bool
|
||||||
|
SealMatchChecked bool
|
||||||
|
SealMatchOK bool
|
||||||
|
SealTimeChecked bool
|
||||||
|
SealTimeOK bool
|
||||||
|
SealCertTimeChecked bool
|
||||||
|
SealCertTimeOK bool
|
||||||
|
CoverageChecked bool
|
||||||
|
CoverageOK bool
|
||||||
|
CoverageError string
|
||||||
|
CoveredFiles []string
|
||||||
|
UncoveredFiles []string
|
||||||
|
PolicyChecked bool
|
||||||
|
PolicyOK bool
|
||||||
|
PolicyError string
|
||||||
|
TimestampChecked bool
|
||||||
|
TimestampOK bool
|
||||||
|
Timestamps []SignatureTimestampReport
|
||||||
|
RevocationChecked bool
|
||||||
|
RevocationOK bool
|
||||||
|
Revocations []SignatureRevocationReport
|
||||||
}
|
}
|
||||||
|
|
||||||
// IntegrityValid 判断签名完整性是否有效
|
// IntegrityValid 判断签名完整性是否有效
|
||||||
|
|||||||
Reference in new issue
Block a user