Skip to content

Commit b063d02

Browse files
authored
Merge pull request #175 from adrg/signature-certificate-array
Parse signature certificate arrays on signature validation
2 parents 5c6d448 + 0bd31c8 commit b063d02

File tree

2 files changed

+59
-27
lines changed

2 files changed

+59
-27
lines changed

model/sighandler/sighandler_pkcs7.go

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"crypto/rsa"
1111
"crypto/x509"
1212
"errors"
13+
"fmt"
1314

1415
"github.com/gunnsth/pkcs7"
1516

@@ -71,16 +72,35 @@ func (a *adobePKCS7Detached) InitSignature(sig *model.PdfSignature) error {
7172
}
7273

7374
func (a *adobePKCS7Detached) getCertificate(sig *model.PdfSignature) (*x509.Certificate, error) {
74-
certificate := a.certificate
75-
if certificate == nil {
76-
certData := sig.Cert.(*core.PdfObjectString).Bytes()
77-
certs, err := x509.ParseCertificates(certData)
78-
if err != nil {
79-
return nil, err
75+
if a.certificate != nil {
76+
return a.certificate, nil
77+
}
78+
79+
var certData []byte
80+
switch certObj := sig.Cert.(type) {
81+
case *core.PdfObjectString:
82+
certData = certObj.Bytes()
83+
case *core.PdfObjectArray:
84+
if certObj.Len() == 0 {
85+
return nil, errors.New("no signature certificates found")
8086
}
81-
certificate = certs[0]
87+
for _, obj := range certObj.Elements() {
88+
certStr, ok := core.GetString(obj)
89+
if !ok {
90+
return nil, fmt.Errorf("invalid certificate object type in signature certificate chain: %T", obj)
91+
}
92+
certData = append(certData, certStr.Bytes()...)
93+
}
94+
default:
95+
return nil, fmt.Errorf("invalid signature certificate object type: %T", certObj)
8296
}
83-
return certificate, nil
97+
98+
certs, err := x509.ParseCertificates(certData)
99+
if err != nil {
100+
return nil, err
101+
}
102+
103+
return certs[0], nil
84104
}
85105

86106
// NewDigest creates a new digest.

model/sighandler/sighandler_rsa_sha1.go

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"crypto/x509"
1313
"encoding/asn1"
1414
"errors"
15+
"fmt"
1516
"hash"
1617

1718
"github.com/unidoc/unipdf/v3/core"
@@ -70,16 +71,35 @@ func getHashFromSignatureAlgorithm(sa x509.SignatureAlgorithm) (crypto.Hash, boo
7071
}
7172

7273
func (a *adobeX509RSASHA1) getCertificate(sig *model.PdfSignature) (*x509.Certificate, error) {
73-
certificate := a.certificate
74-
if certificate == nil {
75-
certData := sig.Cert.(*core.PdfObjectString).Bytes()
76-
certs, err := x509.ParseCertificates(certData)
77-
if err != nil {
78-
return nil, err
74+
if a.certificate != nil {
75+
return a.certificate, nil
76+
}
77+
78+
var certData []byte
79+
switch certObj := sig.Cert.(type) {
80+
case *core.PdfObjectString:
81+
certData = certObj.Bytes()
82+
case *core.PdfObjectArray:
83+
if certObj.Len() == 0 {
84+
return nil, errors.New("no signature certificates found")
7985
}
80-
certificate = certs[0]
86+
for _, obj := range certObj.Elements() {
87+
certStr, ok := core.GetString(obj)
88+
if !ok {
89+
return nil, fmt.Errorf("invalid certificate object type in signature certificate chain: %T", obj)
90+
}
91+
certData = append(certData, certStr.Bytes()...)
92+
}
93+
default:
94+
return nil, fmt.Errorf("invalid signature certificate object type: %T", certObj)
95+
}
96+
97+
certs, err := x509.ParseCertificates(certData)
98+
if err != nil {
99+
return nil, err
81100
}
82-
return certificate, nil
101+
102+
return certs[0], nil
83103
}
84104

85105
// NewDigest creates a new digest.
@@ -94,15 +114,11 @@ func (a *adobeX509RSASHA1) NewDigest(sig *model.PdfSignature) (model.Hasher, err
94114

95115
// Validate validates PdfSignature.
96116
func (a *adobeX509RSASHA1) Validate(sig *model.PdfSignature, digest model.Hasher) (model.SignatureValidationResult, error) {
97-
certData := sig.Cert.(*core.PdfObjectString).Bytes()
98-
certs, err := x509.ParseCertificates(certData)
117+
certificate, err := a.getCertificate(sig)
99118
if err != nil {
100119
return model.SignatureValidationResult{}, err
101120
}
102-
if len(certs) == 0 {
103-
return model.SignatureValidationResult{}, errors.New("certificate not found")
104-
}
105-
cert := certs[0]
121+
106122
signed := sig.Contents.Bytes()
107123
var sigHash []byte
108124
if _, err := asn1.Unmarshal(signed, &sigHash); err != nil {
@@ -112,12 +128,8 @@ func (a *adobeX509RSASHA1) Validate(sig *model.PdfSignature, digest model.Hasher
112128
if !ok {
113129
return model.SignatureValidationResult{}, errors.New("hash type error")
114130
}
115-
certificate, err := a.getCertificate(sig)
116-
if err != nil {
117-
return model.SignatureValidationResult{}, err
118-
}
119131
ha, _ := getHashFromSignatureAlgorithm(certificate.SignatureAlgorithm)
120-
if err := rsa.VerifyPKCS1v15(cert.PublicKey.(*rsa.PublicKey), ha, h.Sum(nil), sigHash); err != nil {
132+
if err := rsa.VerifyPKCS1v15(certificate.PublicKey.(*rsa.PublicKey), ha, h.Sum(nil), sigHash); err != nil {
121133
return model.SignatureValidationResult{}, err
122134
}
123135
return model.SignatureValidationResult{IsSigned: true, IsVerified: true}, nil

0 commit comments

Comments
 (0)