mirror of
https://github.com/unidoc/unipdf.git
synced 2025-04-26 13:48:55 +08:00
Parse signature certificate arrays on signature validation
This commit is contained in:
parent
5c6d448fca
commit
0bd31c8f84
@ -10,6 +10,7 @@ import (
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"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) {
|
||||
certificate := a.certificate
|
||||
if certificate == nil {
|
||||
certData := sig.Cert.(*core.PdfObjectString).Bytes()
|
||||
certs, err := x509.ParseCertificates(certData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
certificate = certs[0]
|
||||
if a.certificate != nil {
|
||||
return a.certificate, nil
|
||||
}
|
||||
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.
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"crypto/x509"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
|
||||
"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) {
|
||||
certificate := a.certificate
|
||||
if certificate == nil {
|
||||
certData := sig.Cert.(*core.PdfObjectString).Bytes()
|
||||
certs, err := x509.ParseCertificates(certData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
certificate = certs[0]
|
||||
if a.certificate != nil {
|
||||
return a.certificate, nil
|
||||
}
|
||||
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.
|
||||
@ -94,15 +114,11 @@ func (a *adobeX509RSASHA1) NewDigest(sig *model.PdfSignature) (model.Hasher, err
|
||||
|
||||
// Validate validates PdfSignature.
|
||||
func (a *adobeX509RSASHA1) Validate(sig *model.PdfSignature, digest model.Hasher) (model.SignatureValidationResult, error) {
|
||||
certData := sig.Cert.(*core.PdfObjectString).Bytes()
|
||||
certs, err := x509.ParseCertificates(certData)
|
||||
certificate, err := a.getCertificate(sig)
|
||||
if err != nil {
|
||||
return model.SignatureValidationResult{}, err
|
||||
}
|
||||
if len(certs) == 0 {
|
||||
return model.SignatureValidationResult{}, errors.New("certificate not found")
|
||||
}
|
||||
cert := certs[0]
|
||||
|
||||
signed := sig.Contents.Bytes()
|
||||
var sigHash []byte
|
||||
if _, err := asn1.Unmarshal(signed, &sigHash); err != nil {
|
||||
@ -112,12 +128,8 @@ func (a *adobeX509RSASHA1) Validate(sig *model.PdfSignature, digest model.Hasher
|
||||
if !ok {
|
||||
return model.SignatureValidationResult{}, errors.New("hash type error")
|
||||
}
|
||||
certificate, err := a.getCertificate(sig)
|
||||
if err != nil {
|
||||
return model.SignatureValidationResult{}, err
|
||||
}
|
||||
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{IsSigned: true, IsVerified: true}, nil
|
||||
|
Loading…
x
Reference in New Issue
Block a user