mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-30 01:27:26 +08:00
1 parent
e9579e3d46
commit
4853ad702b
1 file changed
+82
-34
+82
-34
@@ -224,7 +224,7 @@ func signatureWriteParts(r *Reader) (map[string][]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// signatureWritePackage 完成输出优化后计算签名,不改写已有签名保护的资源
|
// signatureWritePackage 完成输出优化后计算签名,不改写已有签名保护的资源
|
||||||
// 签名目录采用Sign_N兼容OFDRW容器,标识使用独立的sN签章域
|
// 签名目录采用Sign_N,标识使用独立的sN序列
|
||||||
// 入参: parts 独立包文件, options 签署选项, index 文档索引
|
// 入参: parts 独立包文件, options 签署选项, index 文档索引
|
||||||
// 返回: []byte 完整包, error 错误信息
|
// 返回: []byte 完整包, error 错误信息
|
||||||
func signatureWritePackage(parts map[string][]byte, options SignatureWriteOptions, index int) ([]byte, error) {
|
func signatureWritePackage(parts map[string][]byte, options SignatureWriteOptions, index int) ([]byte, error) {
|
||||||
@@ -242,31 +242,20 @@ func signatureWritePackage(parts map[string][]byte, options SignatureWriteOption
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
protected := make(map[string][]byte)
|
if options.Time.IsZero() {
|
||||||
for other := range r.OFD.DocBody {
|
options.Time = time.Now()
|
||||||
if other == index {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
view, err := r.Document(other)
|
options.Time = options.Time.UTC().Truncate(time.Second)
|
||||||
|
identity, err := signatureWriteIdentity(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if view.doc.Signatures == "" {
|
verifyOptions := append([]SignatureVerifyOption(nil), options.ExistingVerifyOptions...)
|
||||||
continue
|
verifyOptions = append(verifyOptions, WithSignatureCert(identity.cert.Raw))
|
||||||
}
|
protected, err := signatureWriteProtected(r, parts, verifyOptions)
|
||||||
reports, err := r.VerifyDocumentSignatures(other)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, report := range reports {
|
|
||||||
if report.Error != "" {
|
|
||||||
return nil, fmt.Errorf("cannot preserve document %d signature: %s", other, report.Error)
|
|
||||||
}
|
|
||||||
for _, ref := range report.References {
|
|
||||||
protected[ref.Path] = bytes.Clone(parts[ref.Path])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if options.Compression.Mode != CompressionUnchanged && doc.Signatures == "" && len(protected) == 0 {
|
if options.Compression.Mode != CompressionUnchanged && doc.Signatures == "" && len(protected) == 0 {
|
||||||
images, sizes, err := r.compressionImagePlan(context.Background(), options.Compression)
|
images, sizes, err := r.compressionImagePlan(context.Background(), options.Compression)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -294,14 +283,6 @@ func signatureWritePackage(parts map[string][]byte, options SignatureWriteOption
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if options.Time.IsZero() {
|
|
||||||
options.Time = time.Now()
|
|
||||||
}
|
|
||||||
options.Time = options.Time.UTC().Truncate(time.Second)
|
|
||||||
identity, err := signatureWriteIdentity(options)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
stamps, err := signatureWriteStamps(r, options.Stamps, len(options.Seal) != 0)
|
stamps, err := signatureWriteStamps(r, options.Stamps, len(options.Seal) != 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -322,8 +303,6 @@ func signatureWritePackage(parts map[string][]byte, options SignatureWriteOption
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
verifyOptions := append([]SignatureVerifyOption(nil), options.ExistingVerifyOptions...)
|
|
||||||
verifyOptions = append(verifyOptions, WithSignatureCert(identity.cert.Raw))
|
|
||||||
if options.Mode == SignatureAppend && oldCount > 0 {
|
if options.Mode == SignatureAppend && oldCount > 0 {
|
||||||
reports, err := r.VerifyDocumentSignatures(index, verifyOptions...)
|
reports, err := r.VerifyDocumentSignatures(index, verifyOptions...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -402,6 +381,11 @@ func signatureWritePackage(parts map[string][]byte, options SignatureWriteOption
|
|||||||
updatedList = editorPatchXML(original, []editorXMLPatch{{root.start, root.end, updated}})
|
updatedList = editorPatchXML(original, []editorXMLPatch{{root.start, root.end, updated}})
|
||||||
}
|
}
|
||||||
parts[listPath] = updatedList
|
parts[listPath] = updatedList
|
||||||
|
for name, before := range protected {
|
||||||
|
if data, ok := parts[name]; !ok || !bytes.Equal(before, data) {
|
||||||
|
return nil, fmt.Errorf("another document signature protects %s", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
refs := SignatureReferences{CheckMethod: identity.digest}
|
refs := SignatureReferences{CheckMethod: identity.digest}
|
||||||
names := make([]string, 0, len(parts))
|
names := make([]string, 0, len(parts))
|
||||||
for name := range parts {
|
for name := range parts {
|
||||||
@@ -444,11 +428,6 @@ func signatureWritePackage(parts map[string][]byte, options SignatureWriteOption
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for name, before := range protected {
|
|
||||||
if !bytes.Equal(before, parts[name]) {
|
|
||||||
return nil, fmt.Errorf("another document signature protects %s", name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
output, err := signatureWriteZIP(parts, options.Compression)
|
output, err := signatureWriteZIP(parts, options.Compression)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -472,6 +451,75 @@ func signatureWritePackage(parts map[string][]byte, options SignatureWriteOption
|
|||||||
return output, nil
|
return output, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// signatureWriteProtected 收集其他文档的签名文件及保护内容,不受默认版本选择影响
|
||||||
|
// 入参: r 包阅读器, parts 原始包文件, options 既有签名的验证选项
|
||||||
|
// 返回: map[string][]byte 不可改写的文件, error 读取或验签错误
|
||||||
|
func signatureWriteProtected(r *Reader, parts map[string][]byte, options []SignatureVerifyOption) (map[string][]byte, error) {
|
||||||
|
protected := make(map[string][]byte)
|
||||||
|
retain := func(name string) error {
|
||||||
|
if _, ok := protected[name]; ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
data, ok := parts[name]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("signature file not found: %s", name)
|
||||||
|
}
|
||||||
|
protected[name] = bytes.Clone(data)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for index := range r.OFD.DocBody {
|
||||||
|
if index == r.documentIndex {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
view := &Reader{files: parts, documentIndex: index, selectedVersion: new(string)}
|
||||||
|
if err := view.initRoot(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
doc, err := view.docStructure()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if doc.Signatures == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
reports, err := view.VerifyDocumentSignatures(index, options...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
listPath := view.ResPath(doc.Signatures)
|
||||||
|
if err := retain(listPath); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, report := range reports {
|
||||||
|
if !report.Valid {
|
||||||
|
reason := report.Error
|
||||||
|
if reason == "" {
|
||||||
|
reason = "signature verification failed"
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("cannot preserve document %d signature %s: %s", index, report.ID, reason)
|
||||||
|
}
|
||||||
|
sigPath := signatureRefPath(listPath, report.BaseLoc)
|
||||||
|
file, err := parseSignatureFile(parts[sigPath])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
names := []string{sigPath, signatureRefPath(sigPath, file.SignedValue)}
|
||||||
|
if file.SignedInfo.Seal.BaseLoc != "" {
|
||||||
|
names = append(names, signatureRefPath(sigPath, file.SignedInfo.Seal.BaseLoc))
|
||||||
|
}
|
||||||
|
for _, ref := range report.References {
|
||||||
|
names = append(names, ref.Path)
|
||||||
|
}
|
||||||
|
for _, name := range names {
|
||||||
|
if err := retain(name); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return protected, nil
|
||||||
|
}
|
||||||
|
|
||||||
// signatureWriteIDs 为签名和全部外观分配同一签章域的标识,不修改文档图元编号
|
// signatureWriteIDs 为签名和全部外观分配同一签章域的标识,不修改文档图元编号
|
||||||
// 入参: list 签名列表, listPath 列表路径, parts 包文件, stamps 外观
|
// 入参: list 签名列表, listPath 列表路径, parts 包文件, stamps 外观
|
||||||
// 返回: string 签名标识, []SignatureStamp 外观, error 错误信息
|
// 返回: string 签名标识, []SignatureStamp 外观, error 错误信息
|
||||||
|
|||||||
Reference in new issue
Block a user