mirror of
https://github.com/unidoc/unipdf.git
synced 2025-05-02 22:17:06 +08:00
Merge pull request #175 from adrg/signature-certificate-array
Parse signature certificate arrays on signature validation
This commit is contained in:
commit
b063d02193
@ -10,6 +10,7 @@ import (
|
|||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/gunnsth/pkcs7"
|
"github.com/gunnsth/pkcs7"
|
||||||
|
|
||||||
@ -71,16 +72,35 @@ func (a *adobePKCS7Detached) InitSignature(sig *model.PdfSignature) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *adobePKCS7Detached) getCertificate(sig *model.PdfSignature) (*x509.Certificate, error) {
|
func (a *adobePKCS7Detached) getCertificate(sig *model.PdfSignature) (*x509.Certificate, error) {
|
||||||
certificate := a.certificate
|
if a.certificate != nil {
|
||||||
if certificate == nil {
|
return a.certificate, nil
|
||||||
certData := sig.Cert.(*core.PdfObjectString).Bytes()
|
|
||||||
certs, err := x509.ParseCertificates(certData)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
certificate = certs[0]
|
|
||||||
}
|
}
|
||||||
return certificate, nil
|
|
||||||
|
var certData []byte
|
||||||
|
switch certObj := sig.Cert.(type) {
|
||||||
|
case *core.PdfObjectString:
|
||||||
|
certData = certObj.Bytes()
|
||||||
|
case *core.PdfObjectArray:
|
||||||
|
if certObj.Len() == 0 {
|
||||||
|
return nil, errors.New("no signature certificates found")
|
||||||
|
}
|
||||||
|
for _, obj := range certObj.Elements() {
|
||||||
|
certStr, ok := core.GetString(obj)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("invalid certificate object type in signature certificate chain: %T", obj)
|
||||||
|
}
|
||||||
|
certData = append(certData, certStr.Bytes()...)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("invalid signature certificate object type: %T", certObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
certs, err := x509.ParseCertificates(certData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return certs[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDigest creates a new digest.
|
// NewDigest creates a new digest.
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/asn1"
|
"encoding/asn1"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"hash"
|
"hash"
|
||||||
|
|
||||||
"github.com/unidoc/unipdf/v3/core"
|
"github.com/unidoc/unipdf/v3/core"
|
||||||
@ -70,16 +71,35 @@ func getHashFromSignatureAlgorithm(sa x509.SignatureAlgorithm) (crypto.Hash, boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *adobeX509RSASHA1) getCertificate(sig *model.PdfSignature) (*x509.Certificate, error) {
|
func (a *adobeX509RSASHA1) getCertificate(sig *model.PdfSignature) (*x509.Certificate, error) {
|
||||||
certificate := a.certificate
|
if a.certificate != nil {
|
||||||
if certificate == nil {
|
return a.certificate, nil
|
||||||
certData := sig.Cert.(*core.PdfObjectString).Bytes()
|
|
||||||
certs, err := x509.ParseCertificates(certData)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
certificate = certs[0]
|
|
||||||
}
|
}
|
||||||
return certificate, nil
|
|
||||||
|
var certData []byte
|
||||||
|
switch certObj := sig.Cert.(type) {
|
||||||
|
case *core.PdfObjectString:
|
||||||
|
certData = certObj.Bytes()
|
||||||
|
case *core.PdfObjectArray:
|
||||||
|
if certObj.Len() == 0 {
|
||||||
|
return nil, errors.New("no signature certificates found")
|
||||||
|
}
|
||||||
|
for _, obj := range certObj.Elements() {
|
||||||
|
certStr, ok := core.GetString(obj)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("invalid certificate object type in signature certificate chain: %T", obj)
|
||||||
|
}
|
||||||
|
certData = append(certData, certStr.Bytes()...)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("invalid signature certificate object type: %T", certObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
certs, err := x509.ParseCertificates(certData)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return certs[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDigest creates a new digest.
|
// NewDigest creates a new digest.
|
||||||
@ -94,15 +114,11 @@ func (a *adobeX509RSASHA1) NewDigest(sig *model.PdfSignature) (model.Hasher, err
|
|||||||
|
|
||||||
// Validate validates PdfSignature.
|
// Validate validates PdfSignature.
|
||||||
func (a *adobeX509RSASHA1) Validate(sig *model.PdfSignature, digest model.Hasher) (model.SignatureValidationResult, error) {
|
func (a *adobeX509RSASHA1) Validate(sig *model.PdfSignature, digest model.Hasher) (model.SignatureValidationResult, error) {
|
||||||
certData := sig.Cert.(*core.PdfObjectString).Bytes()
|
certificate, err := a.getCertificate(sig)
|
||||||
certs, err := x509.ParseCertificates(certData)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return model.SignatureValidationResult{}, err
|
return model.SignatureValidationResult{}, err
|
||||||
}
|
}
|
||||||
if len(certs) == 0 {
|
|
||||||
return model.SignatureValidationResult{}, errors.New("certificate not found")
|
|
||||||
}
|
|
||||||
cert := certs[0]
|
|
||||||
signed := sig.Contents.Bytes()
|
signed := sig.Contents.Bytes()
|
||||||
var sigHash []byte
|
var sigHash []byte
|
||||||
if _, err := asn1.Unmarshal(signed, &sigHash); err != nil {
|
if _, err := asn1.Unmarshal(signed, &sigHash); err != nil {
|
||||||
@ -112,12 +128,8 @@ func (a *adobeX509RSASHA1) Validate(sig *model.PdfSignature, digest model.Hasher
|
|||||||
if !ok {
|
if !ok {
|
||||||
return model.SignatureValidationResult{}, errors.New("hash type error")
|
return model.SignatureValidationResult{}, errors.New("hash type error")
|
||||||
}
|
}
|
||||||
certificate, err := a.getCertificate(sig)
|
|
||||||
if err != nil {
|
|
||||||
return model.SignatureValidationResult{}, err
|
|
||||||
}
|
|
||||||
ha, _ := getHashFromSignatureAlgorithm(certificate.SignatureAlgorithm)
|
ha, _ := getHashFromSignatureAlgorithm(certificate.SignatureAlgorithm)
|
||||||
if err := rsa.VerifyPKCS1v15(cert.PublicKey.(*rsa.PublicKey), ha, h.Sum(nil), sigHash); err != nil {
|
if err := rsa.VerifyPKCS1v15(certificate.PublicKey.(*rsa.PublicKey), ha, h.Sum(nil), sigHash); err != nil {
|
||||||
return model.SignatureValidationResult{}, err
|
return model.SignatureValidationResult{}, err
|
||||||
}
|
}
|
||||||
return model.SignatureValidationResult{IsSigned: true, IsVerified: true}, nil
|
return model.SignatureValidationResult{IsSigned: true, IsVerified: true}, nil
|
||||||
|
Loading…
x
Reference in New Issue
Block a user