mirror of
https://github.com/unidoc/unipdf.git
synced 2025-05-02 22:17:06 +08:00
security: add missing license headers, more documentation
This commit is contained in:
parent
7bd4ba688d
commit
84284c88ec
@ -17,14 +17,20 @@ import (
|
|||||||
crypto "github.com/unidoc/unidoc/pdf/core/security/crypt"
|
crypto "github.com/unidoc/unidoc/pdf/core/security/crypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Version represents a version of a PDF standard.
|
||||||
type Version struct {
|
type Version struct {
|
||||||
Major int
|
Major int
|
||||||
Minor int
|
Minor int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EncryptInfo contains an information generated by the document encrypter.
|
||||||
type EncryptInfo struct {
|
type EncryptInfo struct {
|
||||||
|
// Version is minimal PDF version that supports specified encryption algorithm.
|
||||||
Version
|
Version
|
||||||
Encrypt *PdfObjectDictionary
|
// Encrypt is an encryption dictionary that contains all necessary parameters.
|
||||||
|
// It should be stored in all copies of the document trailer.
|
||||||
|
Encrypt *PdfObjectDictionary
|
||||||
|
// ID0 and ID1 are IDs used in the trailer. Older algorithms such as RC4 uses them for encryption.
|
||||||
ID0, ID1 string
|
ID0, ID1 string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +63,7 @@ func PdfCryptNewEncrypt(cf crypto.Filter, userPass, ownerPass []byte, perm secur
|
|||||||
crypter.streamFilter = defaultFilter
|
crypter.streamFilter = defaultFilter
|
||||||
crypter.stringFilter = defaultFilter
|
crypter.stringFilter = defaultFilter
|
||||||
}
|
}
|
||||||
ed := crypter.newEncyptDict()
|
ed := crypter.newEncryptDict()
|
||||||
|
|
||||||
// Prepare the ID object for the trailer.
|
// Prepare the ID object for the trailer.
|
||||||
hashcode := md5.Sum([]byte(time.Now().Format(time.RFC850)))
|
hashcode := md5.Sum([]byte(time.Now().Format(time.RFC850)))
|
||||||
@ -244,7 +250,7 @@ func decodeCryptFilter(cf *crypto.FilterDict, d *PdfObjectDictionary) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (crypt *PdfCrypt) newEncyptDict() *PdfObjectDictionary {
|
func (crypt *PdfCrypt) newEncryptDict() *PdfObjectDictionary {
|
||||||
// Generate the encryption dictionary.
|
// Generate the encryption dictionary.
|
||||||
ed := MakeDict()
|
ed := MakeDict()
|
||||||
ed.Set("Filter", MakeName("Standard"))
|
ed.Set("Filter", MakeName("Standard"))
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* This file is subject to the terms and conditions defined in
|
||||||
|
* file 'LICENSE.md', which is part of this source code package.
|
||||||
|
*/
|
||||||
|
|
||||||
package security
|
package security
|
||||||
|
|
||||||
// AuthEvent is an event type that triggers authentication.
|
// AuthEvent is an event type that triggers authentication.
|
||||||
type AuthEvent string
|
type AuthEvent string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
EventDocOpen = AuthEvent("DocOpen") // document open
|
// EventDocOpen is an event triggered when opening the document.
|
||||||
EventEFOpen = AuthEvent("EFOpen") // embedded file open
|
EventDocOpen = AuthEvent("DocOpen")
|
||||||
|
// EventEFOpen is an event triggered when accessing an embedded file.
|
||||||
|
EventEFOpen = AuthEvent("EFOpen")
|
||||||
)
|
)
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* This file is subject to the terms and conditions defined in
|
||||||
|
* file 'LICENSE.md', which is part of this source code package.
|
||||||
|
*/
|
||||||
|
|
||||||
package crypt
|
package crypt
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
@ -22,28 +27,35 @@ func newFilterAESV2(d FilterDict) (Filter, error) {
|
|||||||
return filterAESV2{}, nil
|
return filterAESV2{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ Filter = filterAESV2{}
|
||||||
|
|
||||||
// filterAESV2 is an AES-based filter (128 bit key, PDF 1.6)
|
// filterAESV2 is an AES-based filter (128 bit key, PDF 1.6)
|
||||||
type filterAESV2 struct {
|
type filterAESV2 struct {
|
||||||
filterAES
|
filterAES
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PDFVersion implements Filter interface.
|
||||||
func (filterAESV2) PDFVersion() [2]int {
|
func (filterAESV2) PDFVersion() [2]int {
|
||||||
return [2]int{1, 5}
|
return [2]int{1, 5}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandlerVersion implements Filter interface.
|
||||||
func (filterAESV2) HandlerVersion() (V, R int) {
|
func (filterAESV2) HandlerVersion() (V, R int) {
|
||||||
V, R = 4, 4
|
V, R = 4, 4
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name implements Filter interface.
|
||||||
func (filterAESV2) Name() string {
|
func (filterAESV2) Name() string {
|
||||||
return "AESV2"
|
return "AESV2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KeyLength implements Filter interface.
|
||||||
func (filterAESV2) KeyLength() int {
|
func (filterAESV2) KeyLength() int {
|
||||||
return 128 / 8
|
return 128 / 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MakeKey implements Filter interface.
|
||||||
func (filterAESV2) MakeKey(objNum, genNum uint32, ekey []byte) ([]byte, error) {
|
func (filterAESV2) MakeKey(objNum, genNum uint32, ekey []byte) ([]byte, error) {
|
||||||
return makeKeyV2(objNum, genNum, ekey, true)
|
return makeKeyV2(objNum, genNum, ekey, true)
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* This file is subject to the terms and conditions defined in
|
||||||
|
* file 'LICENSE.md', which is part of this source code package.
|
||||||
|
*/
|
||||||
|
|
||||||
package crypt
|
package crypt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -146,28 +151,35 @@ func (filterAES) DecryptBytes(buf []byte, okey []byte) ([]byte, error) {
|
|||||||
return buf, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ Filter = filterAESV3{}
|
||||||
|
|
||||||
// filterAESV3 is an AES-based filter (256 bit key, PDF 2.0)
|
// filterAESV3 is an AES-based filter (256 bit key, PDF 2.0)
|
||||||
type filterAESV3 struct {
|
type filterAESV3 struct {
|
||||||
filterAES
|
filterAES
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PDFVersion implements Filter interface.
|
||||||
func (filterAESV3) PDFVersion() [2]int {
|
func (filterAESV3) PDFVersion() [2]int {
|
||||||
return [2]int{2, 0}
|
return [2]int{2, 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandlerVersion implements Filter interface.
|
||||||
func (filterAESV3) HandlerVersion() (V, R int) {
|
func (filterAESV3) HandlerVersion() (V, R int) {
|
||||||
V, R = 5, 6
|
V, R = 5, 6
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name implements Filter interface.
|
||||||
func (filterAESV3) Name() string {
|
func (filterAESV3) Name() string {
|
||||||
return "AESV3"
|
return "AESV3"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KeyLength implements Filter interface.
|
||||||
func (filterAESV3) KeyLength() int {
|
func (filterAESV3) KeyLength() int {
|
||||||
return 256 / 8
|
return 256 / 8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MakeKey implements Filter interface.
|
||||||
func (filterAESV3) MakeKey(_, _ uint32, ekey []byte) ([]byte, error) {
|
func (filterAESV3) MakeKey(_, _ uint32, ekey []byte) ([]byte, error) {
|
||||||
return ekey, nil
|
return ekey, nil // document encryption key == object encryption key
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* This file is subject to the terms and conditions defined in
|
||||||
|
* file 'LICENSE.md', which is part of this source code package.
|
||||||
|
*/
|
||||||
|
|
||||||
package crypt
|
package crypt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -21,6 +26,7 @@ func NewFilterV2(length int) Filter {
|
|||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// newFilterV2 creates a RC4-based filter from a Filter dictionary.
|
||||||
func newFilterV2(d FilterDict) (Filter, error) {
|
func newFilterV2(d FilterDict) (Filter, error) {
|
||||||
if d.Length%8 != 0 {
|
if d.Length%8 != 0 {
|
||||||
return nil, fmt.Errorf("Crypt filter length not multiple of 8 (%d)", d.Length)
|
return nil, fmt.Errorf("Crypt filter length not multiple of 8 (%d)", d.Length)
|
||||||
@ -74,32 +80,40 @@ func makeKeyV2(objNum, genNum uint32, ekey []byte, isAES bool) ([]byte, error) {
|
|||||||
return hashb, nil
|
return hashb, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ Filter = filterV2{}
|
||||||
|
|
||||||
// filterV2 is a RC4-based filter
|
// filterV2 is a RC4-based filter
|
||||||
type filterV2 struct {
|
type filterV2 struct {
|
||||||
length int
|
length int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PDFVersion implements Filter interface.
|
||||||
func (f filterV2) PDFVersion() [2]int {
|
func (f filterV2) PDFVersion() [2]int {
|
||||||
return [2]int{} // TODO(dennwc): unspecified; check what it should be
|
return [2]int{} // TODO(dennwc): unspecified; check what it should be
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandlerVersion implements Filter interface.
|
||||||
func (f filterV2) HandlerVersion() (V, R int) {
|
func (f filterV2) HandlerVersion() (V, R int) {
|
||||||
V, R = 2, 3
|
V, R = 2, 3
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name implements Filter interface.
|
||||||
func (filterV2) Name() string {
|
func (filterV2) Name() string {
|
||||||
return "V2"
|
return "V2"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KeyLength implements Filter interface.
|
||||||
func (f filterV2) KeyLength() int {
|
func (f filterV2) KeyLength() int {
|
||||||
return f.length
|
return f.length
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MakeKey implements Filter interface.
|
||||||
func (f filterV2) MakeKey(objNum, genNum uint32, ekey []byte) ([]byte, error) {
|
func (f filterV2) MakeKey(objNum, genNum uint32, ekey []byte) ([]byte, error) {
|
||||||
return makeKeyV2(objNum, genNum, ekey, false)
|
return makeKeyV2(objNum, genNum, ekey, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// EncryptBytes implements Filter interface.
|
||||||
func (filterV2) EncryptBytes(buf []byte, okey []byte) ([]byte, error) {
|
func (filterV2) EncryptBytes(buf []byte, okey []byte) ([]byte, error) {
|
||||||
// Standard RC4 algorithm.
|
// Standard RC4 algorithm.
|
||||||
ciph, err := rc4.NewCipher(okey)
|
ciph, err := rc4.NewCipher(okey)
|
||||||
@ -112,6 +126,7 @@ func (filterV2) EncryptBytes(buf []byte, okey []byte) ([]byte, error) {
|
|||||||
return buf, nil
|
return buf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecryptBytes implements Filter interface.
|
||||||
func (filterV2) DecryptBytes(buf []byte, okey []byte) ([]byte, error) {
|
func (filterV2) DecryptBytes(buf []byte, okey []byte) ([]byte, error) {
|
||||||
// Standard RC4 algorithm.
|
// Standard RC4 algorithm.
|
||||||
ciph, err := rc4.NewCipher(okey)
|
ciph, err := rc4.NewCipher(okey)
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* This file is subject to the terms and conditions defined in
|
||||||
|
* file 'LICENSE.md', which is part of this source code package.
|
||||||
|
*/
|
||||||
|
|
||||||
package crypt
|
package crypt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -13,6 +18,27 @@ var (
|
|||||||
// filterFunc is used to construct crypt filters from CryptFilter dictionary
|
// filterFunc is used to construct crypt filters from CryptFilter dictionary
|
||||||
type filterFunc func(d FilterDict) (Filter, error)
|
type filterFunc func(d FilterDict) (Filter, error)
|
||||||
|
|
||||||
|
// Filter is a common interface for crypt filter methods.
|
||||||
|
type Filter interface {
|
||||||
|
// Name returns a name of the filter that should be used in CFM field of Encrypt dictionary.
|
||||||
|
Name() string
|
||||||
|
// KeyLength returns a length of the encryption key in bytes.
|
||||||
|
KeyLength() int
|
||||||
|
// PDFVersion reports the minimal version of PDF document that introduced this filter.
|
||||||
|
PDFVersion() [2]int
|
||||||
|
// HandlerVersion reports V and R parameters that should be used for this filter.
|
||||||
|
HandlerVersion() (V, R int)
|
||||||
|
// MakeKey generates a object encryption key based on file encryption key and object numbers.
|
||||||
|
// Used only for legacy filters - AESV3 doesn't change the key for each object.
|
||||||
|
MakeKey(objNum, genNum uint32, fkey []byte) ([]byte, error)
|
||||||
|
// EncryptBytes encrypts a buffer using object encryption key, as returned by MakeKey.
|
||||||
|
// Implementation may reuse a buffer and encrypt data in-place.
|
||||||
|
EncryptBytes(p []byte, okey []byte) ([]byte, error)
|
||||||
|
// DecryptBytes decrypts a buffer using object encryption key, as returned by MakeKey.
|
||||||
|
// Implementation may reuse a buffer and decrypt data in-place.
|
||||||
|
DecryptBytes(p []byte, okey []byte) ([]byte, error)
|
||||||
|
}
|
||||||
|
|
||||||
// NewFilter creates CryptFilter from a corresponding dictionary.
|
// NewFilter creates CryptFilter from a corresponding dictionary.
|
||||||
func NewFilter(d FilterDict) (Filter, error) {
|
func NewFilter(d FilterDict) (Filter, error) {
|
||||||
fnc, err := getFilter(d.CFM)
|
fnc, err := getFilter(d.CFM)
|
||||||
@ -56,27 +82,6 @@ func getFilter(name string) (filterFunc, error) {
|
|||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter is a common interface for crypt filter methods.
|
|
||||||
type Filter interface {
|
|
||||||
// Name returns a name of the filter that should be used in CFM field of Encrypt dictionary.
|
|
||||||
Name() string
|
|
||||||
// KeyLength returns a length of the encryption key in bytes.
|
|
||||||
KeyLength() int
|
|
||||||
// PDFVersion reports the minimal version of PDF document that introduced this filter.
|
|
||||||
PDFVersion() [2]int
|
|
||||||
// HandlerVersion reports V and R parameters that should be used for this filter.
|
|
||||||
HandlerVersion() (V, R int)
|
|
||||||
// MakeKey generates a object encryption key based on file encryption key and object numbers.
|
|
||||||
// Used only for legacy filters - AESV3 doesn't change the key for each object.
|
|
||||||
MakeKey(objNum, genNum uint32, fkey []byte) ([]byte, error)
|
|
||||||
// EncryptBytes encrypts a buffer using object encryption key, as returned by MakeKey.
|
|
||||||
// Implementation may reuse a buffer and encrypt data in-place.
|
|
||||||
EncryptBytes(p []byte, okey []byte) ([]byte, error)
|
|
||||||
// DecryptBytes decrypts a buffer using object encryption key, as returned by MakeKey.
|
|
||||||
// Implementation may reuse a buffer and decrypt data in-place.
|
|
||||||
DecryptBytes(p []byte, okey []byte) ([]byte, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
type filterIdentity struct{}
|
type filterIdentity struct{}
|
||||||
|
|
||||||
func (filterIdentity) PDFVersion() [2]int {
|
func (filterIdentity) PDFVersion() [2]int {
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* This file is subject to the terms and conditions defined in
|
||||||
|
* file 'LICENSE.md', which is part of this source code package.
|
||||||
|
*/
|
||||||
|
|
||||||
package security
|
package security
|
||||||
|
|
||||||
import "math"
|
import "math"
|
||||||
@ -9,17 +14,22 @@ const (
|
|||||||
// PermOwner grants all permissions.
|
// PermOwner grants all permissions.
|
||||||
PermOwner = Permissions(math.MaxUint32)
|
PermOwner = Permissions(math.MaxUint32)
|
||||||
|
|
||||||
PermPrinting = Permissions(1 << 2) // bit 3
|
// PermPrinting allows printing the document with a low quality.
|
||||||
PermModify = Permissions(1 << 3) // bit 4
|
PermPrinting = Permissions(1 << 2)
|
||||||
PermExtractGraphics = Permissions(1 << 4) // bit 5
|
// PermModify allows to modify the document.
|
||||||
PermAnnotate = Permissions(1 << 5) // bit 6
|
PermModify = Permissions(1 << 3)
|
||||||
|
// PermExtractGraphics allows to extract graphics from the document.
|
||||||
|
PermExtractGraphics = Permissions(1 << 4)
|
||||||
|
// PermAnnotate allows annotating the document.
|
||||||
|
PermAnnotate = Permissions(1 << 5)
|
||||||
// PermFillForms allow form filling, if annotation is disabled? If annotation enabled, is not looked at.
|
// PermFillForms allow form filling, if annotation is disabled? If annotation enabled, is not looked at.
|
||||||
PermFillForms = Permissions(1 << 8) // bit 9
|
PermFillForms = Permissions(1 << 8)
|
||||||
PermDisabilityExtract = Permissions(1 << 9) // bit 10 // TODO: not clear what this means!
|
// PermDisabilityExtract allows to extract graphics in accessibility mode.
|
||||||
|
PermDisabilityExtract = Permissions(1 << 9)
|
||||||
// PermRotateInsert allows rotating, editing page order.
|
// PermRotateInsert allows rotating, editing page order.
|
||||||
PermRotateInsert = Permissions(1 << 10) // bit 11
|
PermRotateInsert = Permissions(1 << 10)
|
||||||
// PermFullPrintQuality limits print quality (lowres), assuming Printing bit is set.
|
// PermFullPrintQuality limits print quality (lowres), assuming Printing bit is set.
|
||||||
PermFullPrintQuality = Permissions(1 << 11) // bit 12
|
PermFullPrintQuality = Permissions(1 << 11)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Allowed checks if a set of permissions can be granted.
|
// Allowed checks if a set of permissions can be granted.
|
||||||
|
@ -26,6 +26,10 @@ func NewHandlerR4(id0 string, length int) StdHandler {
|
|||||||
return stdHandlerR4{ID0: id0, Length: length}
|
return stdHandlerR4{ID0: id0, Length: length}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// stdHandlerR4 is a standard security handler for R<=4.
|
||||||
|
// It uses RC4 and MD5 to generate encryption parameters.
|
||||||
|
// This legacy handler also requires Length parameter from
|
||||||
|
// Encrypt dictionary and ID0 from the trailer.
|
||||||
type stdHandlerR4 struct {
|
type stdHandlerR4 struct {
|
||||||
Length int
|
Length int
|
||||||
ID0 string
|
ID0 string
|
||||||
@ -260,7 +264,7 @@ func (sh stdHandlerR4) alg6(d *StdEncryptDict, upass []byte) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// alg7 authenticates the owner password and returns the document encryption key.
|
// alg7 authenticates the owner password and returns the document encryption key.
|
||||||
//// It returns an nil key in case authentication failed.
|
// It returns an nil key in case authentication failed.
|
||||||
func (sh stdHandlerR4) alg7(d *StdEncryptDict, opass []byte) ([]byte, error) {
|
func (sh stdHandlerR4) alg7(d *StdEncryptDict, opass []byte) ([]byte, error) {
|
||||||
encKey := sh.alg3Key(d.R, opass)
|
encKey := sh.alg3Key(d.R, opass)
|
||||||
|
|
||||||
@ -298,6 +302,8 @@ func (sh stdHandlerR4) alg7(d *StdEncryptDict, opass []byte) ([]byte, error) {
|
|||||||
return ekey, nil
|
return ekey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenerateParams generates and sets O and U parameters for the encryption dictionary.
|
||||||
|
// It expects R, P and EncryptMetadata fields to be set.
|
||||||
func (sh stdHandlerR4) GenerateParams(d *StdEncryptDict, opass, upass []byte) ([]byte, error) {
|
func (sh stdHandlerR4) GenerateParams(d *StdEncryptDict, opass, upass []byte) ([]byte, error) {
|
||||||
// Make the O and U objects.
|
// Make the O and U objects.
|
||||||
O, err := sh.alg3(d.R, upass, opass)
|
O, err := sh.alg3(d.R, upass, opass)
|
||||||
@ -320,6 +326,7 @@ func (sh stdHandlerR4) GenerateParams(d *StdEncryptDict, opass, upass []byte) ([
|
|||||||
return ekey, nil
|
return ekey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Authenticate implements StdHandler interface.
|
||||||
func (sh stdHandlerR4) Authenticate(d *StdEncryptDict, pass []byte) ([]byte, Permissions, error) {
|
func (sh stdHandlerR4) Authenticate(d *StdEncryptDict, pass []byte) ([]byte, Permissions, error) {
|
||||||
// Try owner password.
|
// Try owner password.
|
||||||
// May not be necessary if only want to get all contents.
|
// May not be necessary if only want to get all contents.
|
||||||
|
@ -27,6 +27,7 @@ func NewHandlerR6() StdHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stdHandlerR6 is an implementation of standard security handler with R=5 and R=6.
|
// stdHandlerR6 is an implementation of standard security handler with R=5 and R=6.
|
||||||
|
// Both revisions are expected to be used with AES encryption filters.
|
||||||
type stdHandlerR6 struct{}
|
type stdHandlerR6 struct{}
|
||||||
|
|
||||||
// alg2a retrieves the encryption key from an encrypted document (R >= 5).
|
// alg2a retrieves the encryption key from an encrypted document (R >= 5).
|
||||||
@ -115,10 +116,10 @@ func (sh stdHandlerR6) alg2a(d *StdEncryptDict, pass []byte) ([]byte, Permission
|
|||||||
return fkey, perm, nil
|
return fkey, perm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// alg2b_R5 computes a hash for R=5, used in a deprecated extension.
|
// alg2bR5 computes a hash for R=5, used in a deprecated extension.
|
||||||
// It's used the same way as a hash described in Algorithm 2.B, but it doesn't use the original password
|
// It's used the same way as a hash described in Algorithm 2.B, but it doesn't use the original password
|
||||||
// and the user key to calculate the hash.
|
// and the user key to calculate the hash.
|
||||||
func alg2b_R5(data []byte) []byte {
|
func alg2bR5(data []byte) []byte {
|
||||||
h := sha256.New()
|
h := sha256.New()
|
||||||
h.Write(data)
|
h.Write(data)
|
||||||
return h.Sum(nil)
|
return h.Sum(nil)
|
||||||
@ -216,7 +217,7 @@ func alg2b(data, pwd, userKey []byte) []byte {
|
|||||||
// alg2b computes a hash for R=5 and R=6.
|
// alg2b computes a hash for R=5 and R=6.
|
||||||
func (sh stdHandlerR6) alg2b(R int, data, pwd, userKey []byte) []byte {
|
func (sh stdHandlerR6) alg2b(R int, data, pwd, userKey []byte) []byte {
|
||||||
if R == 5 {
|
if R == 5 {
|
||||||
return alg2b_R5(data)
|
return alg2bR5(data)
|
||||||
}
|
}
|
||||||
return alg2b(data, pwd, userKey)
|
return alg2b(data, pwd, userKey)
|
||||||
}
|
}
|
||||||
@ -422,9 +423,10 @@ func (sh stdHandlerR6) alg13(d *StdEncryptDict, fkey []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateR6 is the algorithm opposite to alg2a (R>=5).
|
// GenerateParams is the algorithm opposite to alg2a (R>=5).
|
||||||
// It generates U,O,UE,OE,Perms fields using AESv3 encryption.
|
// It generates U,O,UE,OE,Perms fields using AESv3 encryption.
|
||||||
// There is no algorithm number assigned to this function in the spec.
|
// There is no algorithm number assigned to this function in the spec.
|
||||||
|
// It expects R, P and EncryptMetadata fields to be set.
|
||||||
func (sh stdHandlerR6) GenerateParams(d *StdEncryptDict, opass, upass []byte) ([]byte, error) {
|
func (sh stdHandlerR6) GenerateParams(d *StdEncryptDict, opass, upass []byte) ([]byte, error) {
|
||||||
ekey := make([]byte, 32)
|
ekey := make([]byte, 32)
|
||||||
if _, err := io.ReadFull(rand.Reader, ekey); err != nil {
|
if _, err := io.ReadFull(rand.Reader, ekey); err != nil {
|
||||||
@ -461,6 +463,7 @@ func (sh stdHandlerR6) GenerateParams(d *StdEncryptDict, opass, upass []byte) ([
|
|||||||
return ekey, nil
|
return ekey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Authenticate implements StdHandler interface.
|
||||||
func (sh stdHandlerR6) Authenticate(d *StdEncryptDict, pass []byte) ([]byte, Permissions, error) {
|
func (sh stdHandlerR6) Authenticate(d *StdEncryptDict, pass []byte) ([]byte, Permissions, error) {
|
||||||
return sh.alg2a(d, pass)
|
return sh.alg2a(d, pass)
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* This file is subject to the terms and conditions defined in
|
||||||
|
* file 'LICENSE.md', which is part of this source code package.
|
||||||
|
*/
|
||||||
|
|
||||||
package security
|
package security
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -17,12 +17,11 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/unidoc/unidoc/pdf/core/security/crypt"
|
|
||||||
|
|
||||||
"github.com/unidoc/unidoc/common"
|
"github.com/unidoc/unidoc/common"
|
||||||
"github.com/unidoc/unidoc/common/license"
|
"github.com/unidoc/unidoc/common/license"
|
||||||
. "github.com/unidoc/unidoc/pdf/core"
|
. "github.com/unidoc/unidoc/pdf/core"
|
||||||
"github.com/unidoc/unidoc/pdf/core/security"
|
"github.com/unidoc/unidoc/pdf/core/security"
|
||||||
|
"github.com/unidoc/unidoc/pdf/core/security/crypt"
|
||||||
"github.com/unidoc/unidoc/pdf/model/fonts"
|
"github.com/unidoc/unidoc/pdf/model/fonts"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user