mirror of
https://github.com/unidoc/unipdf.git
synced 2025-05-02 22:17:06 +08:00
Improved crypto handling for encrypt dicts with references
This commit is contained in:
parent
698dbe3168
commit
90caacec66
@ -41,6 +41,8 @@ type PdfCrypt struct {
|
|||||||
CryptFilters CryptFilters
|
CryptFilters CryptFilters
|
||||||
StreamFilter string
|
StreamFilter string
|
||||||
StringFilter string
|
StringFilter string
|
||||||
|
|
||||||
|
parser *PdfParser
|
||||||
}
|
}
|
||||||
|
|
||||||
type AccessPermissions struct {
|
type AccessPermissions struct {
|
||||||
@ -69,15 +71,36 @@ type CryptFilters map[string]CryptFilter
|
|||||||
func (this *PdfCrypt) LoadCryptFilters(ed *PdfObjectDictionary) error {
|
func (this *PdfCrypt) LoadCryptFilters(ed *PdfObjectDictionary) error {
|
||||||
this.CryptFilters = CryptFilters{}
|
this.CryptFilters = CryptFilters{}
|
||||||
|
|
||||||
cf, ok := (*ed)["CF"].(*PdfObjectDictionary)
|
obj := (*ed)["CF"]
|
||||||
|
obj = TraceToDirectObject(obj) // XXX may need to resolve reference...
|
||||||
|
if ref, isRef := obj.(*PdfObjectReference); isRef {
|
||||||
|
o, err := this.parser.LookupByReference(*ref)
|
||||||
|
if err != nil {
|
||||||
|
common.Log.Debug("Error looking up CF reference")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
obj = TraceToDirectObject(o)
|
||||||
|
}
|
||||||
|
|
||||||
|
cf, ok := obj.(*PdfObjectDictionary)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
common.Log.Debug("Invalid CF, type: %T", obj)
|
||||||
return errors.New("Invalid CF")
|
return errors.New("Invalid CF")
|
||||||
}
|
}
|
||||||
|
|
||||||
for name, v := range *cf {
|
for name, v := range *cf {
|
||||||
|
if ref, isRef := v.(*PdfObjectReference); isRef {
|
||||||
|
o, err := this.parser.LookupByReference(*ref)
|
||||||
|
if err != nil {
|
||||||
|
common.Log.Debug("Error lookup up dictionary reference")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
v = TraceToDirectObject(o)
|
||||||
|
}
|
||||||
|
|
||||||
dict, ok := v.(*PdfObjectDictionary)
|
dict, ok := v.(*PdfObjectDictionary)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Invalid dict in CF (name %s)", name)
|
return fmt.Errorf("Invalid dict in CF (name %s) - not a dictionary but %T", name, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if name == "Identity" {
|
if name == "Identity" {
|
||||||
@ -160,11 +183,12 @@ func (this *PdfCrypt) LoadCryptFilters(ed *PdfObjectDictionary) error {
|
|||||||
|
|
||||||
// Prepare the document crypt handler based on the encryption dictionary
|
// Prepare the document crypt handler based on the encryption dictionary
|
||||||
// and trailer dictionary.
|
// and trailer dictionary.
|
||||||
func PdfCryptMakeNew(ed, trailer *PdfObjectDictionary) (PdfCrypt, error) {
|
func PdfCryptMakeNew(parser *PdfParser, ed, trailer *PdfObjectDictionary) (PdfCrypt, error) {
|
||||||
crypter := PdfCrypt{}
|
crypter := PdfCrypt{}
|
||||||
crypter.DecryptedObjects = map[PdfObject]bool{}
|
crypter.DecryptedObjects = map[PdfObject]bool{}
|
||||||
crypter.EncryptedObjects = map[PdfObject]bool{}
|
crypter.EncryptedObjects = map[PdfObject]bool{}
|
||||||
crypter.Authenticated = false
|
crypter.Authenticated = false
|
||||||
|
crypter.parser = parser
|
||||||
|
|
||||||
filter, ok := (*ed)["Filter"].(*PdfObjectName)
|
filter, ok := (*ed)["Filter"].(*PdfObjectName)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -261,12 +285,13 @@ func PdfCryptMakeNew(ed, trailer *PdfObjectDictionary) (PdfCrypt, error) {
|
|||||||
// but clearly not everyone is following the specification.
|
// but clearly not everyone is following the specification.
|
||||||
id0 := PdfObjectString("")
|
id0 := PdfObjectString("")
|
||||||
if idArray, ok := (*trailer)["ID"].(*PdfObjectArray); ok {
|
if idArray, ok := (*trailer)["ID"].(*PdfObjectArray); ok {
|
||||||
common.Log.Debug("Trailer ID array missing!")
|
|
||||||
id0obj, ok := (*idArray)[0].(*PdfObjectString)
|
id0obj, ok := (*idArray)[0].(*PdfObjectString)
|
||||||
if !ok {
|
if !ok {
|
||||||
return crypter, errors.New("Invalid trailer ID")
|
return crypter, errors.New("Invalid trailer ID")
|
||||||
}
|
}
|
||||||
id0 = *id0obj
|
id0 = *id0obj
|
||||||
|
} else {
|
||||||
|
common.Log.Debug("Trailer ID array missing or invalid!")
|
||||||
}
|
}
|
||||||
crypter.Id0 = string(id0)
|
crypter.Id0 = string(id0)
|
||||||
|
|
||||||
|
@ -1404,7 +1404,7 @@ func (this *PdfParser) IsEncrypted() (bool, error) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return false, errors.New("Trailer Encrypt object non dictionary")
|
return false, errors.New("Trailer Encrypt object non dictionary")
|
||||||
}
|
}
|
||||||
crypter, err := PdfCryptMakeNew(encDict, this.trailer)
|
crypter, err := PdfCryptMakeNew(this, encDict, this.trailer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user