github.com/unidoc/unidoc@v2.2.0+incompatible/pdf/core/crypt.go (about)

     1  /*
     2   * This file is subject to the terms and conditions defined in
     3   * file 'LICENSE.md', which is part of this source code package.
     4   */
     5  
     6  package core
     7  
     8  import (
     9  	"bytes"
    10  	"crypto/aes"
    11  	"crypto/cipher"
    12  	"crypto/md5"
    13  	"crypto/rand"
    14  	"crypto/rc4"
    15  	"crypto/sha256"
    16  	"crypto/sha512"
    17  	"encoding/binary"
    18  	"errors"
    19  	"fmt"
    20  	"hash"
    21  	"io"
    22  	"math"
    23  
    24  	"github.com/unidoc/unidoc/common"
    25  )
    26  
    27  // PdfCrypt provides PDF encryption/decryption support.
    28  // The PDF standard supports encryption of strings and streams (Section 7.6).
    29  // TODO (v3): Consider unexporting.
    30  type PdfCrypt struct {
    31  	Filter           string
    32  	Subfilter        string
    33  	V                int
    34  	Length           int
    35  	R                int
    36  	O                []byte
    37  	U                []byte
    38  	OE               []byte // R=6
    39  	UE               []byte // R=6
    40  	P                int    // TODO (v3): uint32
    41  	Perms            []byte // R=6
    42  	EncryptMetadata  bool
    43  	Id0              string
    44  	EncryptionKey    []byte
    45  	DecryptedObjects map[PdfObject]bool
    46  	EncryptedObjects map[PdfObject]bool
    47  	Authenticated    bool
    48  	// Crypt filters (V4).
    49  	CryptFilters CryptFilters
    50  	StreamFilter string
    51  	StringFilter string
    52  
    53  	parser *PdfParser
    54  
    55  	ivAESZero []byte // a zero buffer used as an initialization vector for AES
    56  }
    57  
    58  // AccessPermissions is a list of access permissions for a PDF file.
    59  type AccessPermissions struct {
    60  	Printing        bool
    61  	Modify          bool
    62  	ExtractGraphics bool
    63  	Annotate        bool
    64  
    65  	// Allow form filling, if annotation is disabled?  If annotation enabled, is not looked at.
    66  	FillForms         bool
    67  	DisabilityExtract bool // not clear what this means!
    68  
    69  	// Allow rotating, editing page order.
    70  	RotateInsert bool
    71  
    72  	// Limit print quality (lowres), assuming Printing is true.
    73  	FullPrintQuality bool
    74  }
    75  
    76  const padding = "\x28\xBF\x4E\x5E\x4E\x75\x8A\x41\x64\x00\x4E\x56\xFF" +
    77  	"\xFA\x01\x08\x2E\x2E\x00\xB6\xD0\x68\x3E\x80\x2F\x0C" +
    78  	"\xA9\xFE\x64\x53\x69\x7A"
    79  
    80  // StandardCryptFilter is a default name for a standard crypt filter.
    81  const StandardCryptFilter = "StdCF"
    82  
    83  // CryptFilter represents information from a CryptFilter dictionary.
    84  // TODO (v3): Replace with cryptFilterMethod interface.
    85  type CryptFilter struct {
    86  	Cfm    string
    87  	Length int
    88  	cfm    cryptFilterMethod
    89  }
    90  
    91  func (cf CryptFilter) getCFM() (cryptFilterMethod, error) {
    92  	// TODO (v3): remove this method and access cf.cfm directly
    93  	if cf.cfm != nil {
    94  		return cf.cfm, nil
    95  	}
    96  	// There is a non-zero chance that someone relies on the ability to
    97  	// add crypt filters manually using the library.
    98  	// So if we hit such case - be nice and find a filter by name.
    99  	return getCryptFilterMethod(cf.Cfm)
   100  }
   101  
   102  // Encryption filters names.
   103  // Table 25, CFM (page 92)
   104  const (
   105  	CryptFilterNone  = "None"  // do not decrypt data
   106  	CryptFilterV2    = "V2"    // RC4-based filter
   107  	CryptFilterAESV2 = "AESV2" // AES-based filter (128 bit key, PDF 1.6)
   108  	CryptFilterAESV3 = "AESV3" // AES-based filter (256 bit key, PDF 2.0)
   109  )
   110  
   111  func newCryptFiltersV2(length int) CryptFilters {
   112  	return CryptFilters{
   113  		StandardCryptFilter: NewCryptFilterV2(length),
   114  	}
   115  }
   116  
   117  // NewCryptFilterV2 creates a RC4-based filter with a specified key length (in bytes).
   118  func NewCryptFilterV2(length int) CryptFilter {
   119  	// TODO (v3): Unexport.
   120  	return CryptFilter{
   121  		Cfm:    CryptFilterV2,
   122  		Length: length,
   123  		cfm:    cryptFilterV2{},
   124  	}
   125  }
   126  
   127  // NewCryptFilterAESV2 creates an AES-based filter with a 128 bit key (AESV2).
   128  func NewCryptFilterAESV2() CryptFilter {
   129  	// TODO (v3): Unexport.
   130  	return CryptFilter{
   131  		Cfm:    CryptFilterAESV2,
   132  		Length: 16,
   133  		cfm:    cryptFilterAESV2{},
   134  	}
   135  }
   136  
   137  // NewCryptFilterAESV3 creates an AES-based filter with a 256 bit key (AESV3).
   138  func NewCryptFilterAESV3() CryptFilter {
   139  	// TODO (v3): Unexport.
   140  	return CryptFilter{
   141  		Cfm:    CryptFilterAESV3,
   142  		Length: 32,
   143  		cfm:    cryptFilterAESV3{},
   144  	}
   145  }
   146  
   147  // CryptFilters is a map of crypt filter name and underlying CryptFilter info.
   148  // TODO (v3): Unexport.
   149  type CryptFilters map[string]CryptFilter
   150  
   151  func (m CryptFilters) byName(cfm string) (cryptFilterMethod, error) {
   152  	cf, ok := m[cfm]
   153  	if !ok {
   154  		err := fmt.Errorf("Unsupported crypt filter (%s)", cfm)
   155  		common.Log.Debug("%s", err)
   156  		return nil, err
   157  	}
   158  	f, err := cf.getCFM()
   159  	if err != nil {
   160  		common.Log.Debug("%s", err)
   161  		return nil, err
   162  	}
   163  	return f, nil
   164  }
   165  
   166  // LoadCryptFilters loads crypt filter information from the encryption dictionary (V>=4).
   167  // TODO (v3): Unexport.
   168  func (crypt *PdfCrypt) LoadCryptFilters(ed *PdfObjectDictionary) error {
   169  	crypt.CryptFilters = CryptFilters{}
   170  
   171  	obj := ed.Get("CF")
   172  	obj = TraceToDirectObject(obj) // XXX may need to resolve reference...
   173  	if ref, isRef := obj.(*PdfObjectReference); isRef {
   174  		o, err := crypt.parser.LookupByReference(*ref)
   175  		if err != nil {
   176  			common.Log.Debug("Error looking up CF reference")
   177  			return err
   178  		}
   179  		obj = TraceToDirectObject(o)
   180  	}
   181  
   182  	cf, ok := obj.(*PdfObjectDictionary)
   183  	if !ok {
   184  		common.Log.Debug("Invalid CF, type: %T", obj)
   185  		return errors.New("Invalid CF")
   186  	}
   187  
   188  	for _, name := range cf.Keys() {
   189  		v := cf.Get(name)
   190  
   191  		if ref, isRef := v.(*PdfObjectReference); isRef {
   192  			o, err := crypt.parser.LookupByReference(*ref)
   193  			if err != nil {
   194  				common.Log.Debug("Error lookup up dictionary reference")
   195  				return err
   196  			}
   197  			v = TraceToDirectObject(o)
   198  		}
   199  
   200  		dict, ok := v.(*PdfObjectDictionary)
   201  		if !ok {
   202  			return fmt.Errorf("Invalid dict in CF (name %s) - not a dictionary but %T", name, v)
   203  		}
   204  
   205  		if name == "Identity" {
   206  			common.Log.Debug("ERROR - Cannot overwrite the identity filter - Trying next")
   207  			continue
   208  		}
   209  
   210  		// If Type present, should be CryptFilter.
   211  		if typename, ok := dict.Get("Type").(*PdfObjectName); ok {
   212  			if string(*typename) != "CryptFilter" {
   213  				return fmt.Errorf("CF dict type != CryptFilter (%s)", typename)
   214  			}
   215  		}
   216  
   217  		cf := CryptFilter{}
   218  
   219  		// Method.
   220  		cfmName, ok := dict.Get("CFM").(*PdfObjectName)
   221  		if !ok {
   222  			return fmt.Errorf("Unsupported crypt filter (None)")
   223  		}
   224  		cf.Cfm = string(*cfmName)
   225  
   226  		cfm, err := getCryptFilterMethod(cf.Cfm)
   227  		if err != nil {
   228  			return err
   229  		}
   230  		cf.cfm = cfm
   231  
   232  		// Length.
   233  		cf.Length = 0
   234  		length, ok := dict.Get("Length").(*PdfObjectInteger)
   235  		if ok {
   236  			// TODO(dennwc): pass length to getCryptFilterMethod and allow filter to validate it
   237  			if *length%8 != 0 {
   238  				return fmt.Errorf("Crypt filter length not multiple of 8 (%d)", *length)
   239  			}
   240  
   241  			// Standard security handler expresses the length in multiples of 8 (16 means 128)
   242  			// We only deal with standard so far. (Public key not supported yet).
   243  			if *length < 5 || *length > 16 {
   244  				if *length == 64 || *length == 128 {
   245  					common.Log.Debug("STANDARD VIOLATION: Crypt Length appears to be in bits rather than bytes - assuming bits (%d)", *length)
   246  					*length /= 8
   247  				} else if !(*length == 32 && cf.Cfm == CryptFilterAESV3) {
   248  					return fmt.Errorf("Crypt filter length not in range 40 - 128 bit (%d)", *length)
   249  				}
   250  			}
   251  			cf.Length = int(*length)
   252  		}
   253  
   254  		crypt.CryptFilters[string(name)] = cf
   255  	}
   256  	// Cannot be overwritten.
   257  	crypt.CryptFilters["Identity"] = CryptFilter{}
   258  
   259  	// StrF strings filter.
   260  	crypt.StringFilter = "Identity"
   261  	if strf, ok := ed.Get("StrF").(*PdfObjectName); ok {
   262  		if _, exists := crypt.CryptFilters[string(*strf)]; !exists {
   263  			return fmt.Errorf("Crypt filter for StrF not specified in CF dictionary (%s)", *strf)
   264  		}
   265  		crypt.StringFilter = string(*strf)
   266  	}
   267  
   268  	// StmF streams filter.
   269  	crypt.StreamFilter = "Identity"
   270  	if stmf, ok := ed.Get("StmF").(*PdfObjectName); ok {
   271  		if _, exists := crypt.CryptFilters[string(*stmf)]; !exists {
   272  			return fmt.Errorf("Crypt filter for StmF not specified in CF dictionary (%s)", *stmf)
   273  		}
   274  		crypt.StreamFilter = string(*stmf)
   275  	}
   276  
   277  	return nil
   278  }
   279  
   280  // SaveCryptFilters saves crypt filter information to the encryption dictionary (V>=4).
   281  // TODO (v3): Unexport.
   282  func (crypt *PdfCrypt) SaveCryptFilters(ed *PdfObjectDictionary) error {
   283  	if crypt.V < 4 {
   284  		return errors.New("can only be used with V>=4")
   285  	}
   286  	cf := MakeDict()
   287  	ed.Set("CF", cf)
   288  
   289  	for name, filter := range crypt.CryptFilters {
   290  		if name == "Identity" {
   291  			continue
   292  		}
   293  		v := MakeDict()
   294  		cf.Set(PdfObjectName(name), v)
   295  
   296  		v.Set("Type", MakeName("CryptFilter"))
   297  		v.Set("AuthEvent", MakeName("DocOpen"))
   298  		v.Set("CFM", MakeName(string(filter.Cfm)))
   299  		v.Set("Length", MakeInteger(int64(filter.Length)))
   300  	}
   301  	ed.Set("StrF", MakeName(crypt.StringFilter))
   302  	ed.Set("StmF", MakeName(crypt.StreamFilter))
   303  	return nil
   304  }
   305  
   306  // PdfCryptMakeNew makes the document crypt handler based on the encryption dictionary
   307  // and trailer dictionary. Returns an error on failure to process.
   308  func PdfCryptMakeNew(parser *PdfParser, ed, trailer *PdfObjectDictionary) (PdfCrypt, error) {
   309  	crypter := PdfCrypt{}
   310  	crypter.DecryptedObjects = map[PdfObject]bool{}
   311  	crypter.EncryptedObjects = map[PdfObject]bool{}
   312  	crypter.Authenticated = false
   313  	crypter.parser = parser
   314  
   315  	filter, ok := ed.Get("Filter").(*PdfObjectName)
   316  	if !ok {
   317  		common.Log.Debug("ERROR Crypt dictionary missing required Filter field!")
   318  		return crypter, errors.New("Required crypt field Filter missing")
   319  	}
   320  	if *filter != "Standard" {
   321  		common.Log.Debug("ERROR Unsupported filter (%s)", *filter)
   322  		return crypter, errors.New("Unsupported Filter")
   323  	}
   324  	crypter.Filter = string(*filter)
   325  
   326  	subfilter, ok := ed.Get("SubFilter").(*PdfObjectString)
   327  	if ok {
   328  		crypter.Subfilter = string(*subfilter)
   329  		common.Log.Debug("Using subfilter %s", subfilter)
   330  	}
   331  
   332  	if L, ok := ed.Get("Length").(*PdfObjectInteger); ok {
   333  		if (*L % 8) != 0 {
   334  			common.Log.Debug("ERROR Invalid encryption length")
   335  			return crypter, errors.New("Invalid encryption length")
   336  		}
   337  		crypter.Length = int(*L)
   338  	} else {
   339  		crypter.Length = 40
   340  	}
   341  
   342  	crypter.V = 0
   343  	if v, ok := ed.Get("V").(*PdfObjectInteger); ok {
   344  		V := int(*v)
   345  		crypter.V = V
   346  		if V >= 1 && V <= 2 {
   347  			// Default algorithm is V2.
   348  			crypter.CryptFilters = newCryptFiltersV2(crypter.Length)
   349  		} else if V >= 4 && V <= 5 {
   350  			if err := crypter.LoadCryptFilters(ed); err != nil {
   351  				return crypter, err
   352  			}
   353  		} else {
   354  			common.Log.Debug("ERROR Unsupported encryption algo V = %d", V)
   355  			return crypter, errors.New("Unsupported algorithm")
   356  		}
   357  	}
   358  
   359  	R, ok := ed.Get("R").(*PdfObjectInteger)
   360  	if !ok {
   361  		return crypter, errors.New("Encrypt dictionary missing R")
   362  	}
   363  	// TODO(dennwc): according to spec, R should be validated according to V value
   364  	if *R < 2 || *R > 6 {
   365  		return crypter, fmt.Errorf("Invalid R (%d)", *R)
   366  	}
   367  	crypter.R = int(*R)
   368  
   369  	O, ok := ed.Get("O").(*PdfObjectString)
   370  	if !ok {
   371  		return crypter, errors.New("Encrypt dictionary missing O")
   372  	}
   373  	if crypter.R == 5 || crypter.R == 6 {
   374  		// the spec says =48 bytes, but Acrobat pads them out longer
   375  		if len(*O) < 48 {
   376  			return crypter, fmt.Errorf("Length(O) < 48 (%d)", len(*O))
   377  		}
   378  	} else if len(*O) != 32 {
   379  		return crypter, fmt.Errorf("Length(O) != 32 (%d)", len(*O))
   380  	}
   381  	crypter.O = []byte(*O)
   382  
   383  	U, ok := ed.Get("U").(*PdfObjectString)
   384  	if !ok {
   385  		return crypter, errors.New("Encrypt dictionary missing U")
   386  	}
   387  	if crypter.R == 5 || crypter.R == 6 {
   388  		// the spec says =48 bytes, but Acrobat pads them out longer
   389  		if len(*U) < 48 {
   390  			return crypter, fmt.Errorf("Length(U) < 48 (%d)", len(*U))
   391  		}
   392  	} else if len(*U) != 32 {
   393  		// Strictly this does not cause an error.
   394  		// If O is OK and others then can still read the file.
   395  		common.Log.Debug("Warning: Length(U) != 32 (%d)", len(*U))
   396  		//return crypter, errors.New("Length(U) != 32")
   397  	}
   398  	crypter.U = []byte(*U)
   399  
   400  	if crypter.R >= 5 {
   401  		OE, ok := ed.Get("OE").(*PdfObjectString)
   402  		if !ok {
   403  			return crypter, errors.New("Encrypt dictionary missing OE")
   404  		}
   405  		if len(*OE) != 32 {
   406  			return crypter, fmt.Errorf("Length(OE) != 32 (%d)", len(*OE))
   407  		}
   408  		crypter.OE = []byte(*OE)
   409  
   410  		UE, ok := ed.Get("UE").(*PdfObjectString)
   411  		if !ok {
   412  			return crypter, errors.New("Encrypt dictionary missing UE")
   413  		}
   414  		if len(*UE) != 32 {
   415  			return crypter, fmt.Errorf("Length(UE) != 32 (%d)", len(*UE))
   416  		}
   417  		crypter.UE = []byte(*UE)
   418  	}
   419  
   420  	P, ok := ed.Get("P").(*PdfObjectInteger)
   421  	if !ok {
   422  		return crypter, errors.New("Encrypt dictionary missing permissions attr")
   423  	}
   424  	crypter.P = int(*P)
   425  
   426  	if crypter.R == 6 {
   427  		Perms, ok := ed.Get("Perms").(*PdfObjectString)
   428  		if !ok {
   429  			return crypter, errors.New("Encrypt dictionary missing Perms")
   430  		}
   431  		if len(*Perms) != 16 {
   432  			return crypter, fmt.Errorf("Length(Perms) != 16 (%d)", len(*Perms))
   433  		}
   434  		crypter.Perms = []byte(*Perms)
   435  	}
   436  
   437  	em, ok := ed.Get("EncryptMetadata").(*PdfObjectBool)
   438  	if ok {
   439  		crypter.EncryptMetadata = bool(*em)
   440  	} else {
   441  		crypter.EncryptMetadata = true // True by default.
   442  	}
   443  
   444  	// Default: empty ID.
   445  	// Strictly, if file is encrypted, the ID should always be specified
   446  	// but clearly not everyone is following the specification.
   447  	id0 := PdfObjectString("")
   448  	if idArray, ok := trailer.Get("ID").(*PdfObjectArray); ok && len(*idArray) >= 1 {
   449  		id0obj, ok := (*idArray)[0].(*PdfObjectString)
   450  		if !ok {
   451  			return crypter, errors.New("Invalid trailer ID")
   452  		}
   453  		id0 = *id0obj
   454  	} else {
   455  		common.Log.Debug("Trailer ID array missing or invalid!")
   456  	}
   457  	crypter.Id0 = string(id0)
   458  
   459  	return crypter, nil
   460  }
   461  
   462  // GetAccessPermissions returns the PDF access permissions as an AccessPermissions object.
   463  func (crypt *PdfCrypt) GetAccessPermissions() AccessPermissions {
   464  	perms := AccessPermissions{}
   465  
   466  	P := crypt.P
   467  	if P&(1<<2) > 0 {
   468  		perms.Printing = true
   469  	}
   470  	if P&(1<<3) > 0 {
   471  		perms.Modify = true
   472  	}
   473  	if P&(1<<4) > 0 {
   474  		perms.ExtractGraphics = true
   475  	}
   476  	if P&(1<<5) > 0 {
   477  		perms.Annotate = true
   478  	}
   479  	if P&(1<<8) > 0 {
   480  		perms.FillForms = true
   481  	}
   482  	if P&(1<<9) > 0 {
   483  		perms.DisabilityExtract = true
   484  	}
   485  	if P&(1<<10) > 0 {
   486  		perms.RotateInsert = true
   487  	}
   488  	if P&(1<<11) > 0 {
   489  		perms.FullPrintQuality = true
   490  	}
   491  	return perms
   492  }
   493  
   494  // GetP returns the P entry to be used in Encrypt dictionary based on AccessPermissions settings.
   495  func (perms AccessPermissions) GetP() int32 {
   496  	var P int32 = 0
   497  
   498  	if perms.Printing { // bit 3
   499  		P |= (1 << 2)
   500  	}
   501  	if perms.Modify { // bit 4
   502  		P |= (1 << 3)
   503  	}
   504  	if perms.ExtractGraphics { // bit 5
   505  		P |= (1 << 4)
   506  	}
   507  	if perms.Annotate { // bit 6
   508  		P |= (1 << 5)
   509  	}
   510  	if perms.FillForms {
   511  		P |= (1 << 8) // bit 9
   512  	}
   513  	if perms.DisabilityExtract {
   514  		P |= (1 << 9) // bit 10
   515  	}
   516  	if perms.RotateInsert {
   517  		P |= (1 << 10) // bit 11
   518  	}
   519  	if perms.FullPrintQuality {
   520  		P |= (1 << 11) // bit 12
   521  	}
   522  	return P
   523  }
   524  
   525  // Check whether the specified password can be used to decrypt the document.
   526  func (crypt *PdfCrypt) authenticate(password []byte) (bool, error) {
   527  	// Also build the encryption/decryption key.
   528  
   529  	crypt.Authenticated = false
   530  	if crypt.R >= 5 {
   531  		authenticated, err := crypt.alg2a(password)
   532  		if err != nil {
   533  			return false, err
   534  		}
   535  		crypt.Authenticated = authenticated
   536  		return authenticated, err
   537  	}
   538  
   539  	// Try user password.
   540  	common.Log.Trace("Debugging authentication - user pass")
   541  	authenticated, err := crypt.Alg6(password)
   542  	if err != nil {
   543  		return false, err
   544  	}
   545  	if authenticated {
   546  		common.Log.Trace("this.Authenticated = True")
   547  		crypt.Authenticated = true
   548  		return true, nil
   549  	}
   550  
   551  	// Try owner password also.
   552  	// May not be necessary if only want to get all contents.
   553  	// (user pass needs to be known or empty).
   554  	common.Log.Trace("Debugging authentication - owner pass")
   555  	authenticated, err = crypt.Alg7(password)
   556  	if err != nil {
   557  		return false, err
   558  	}
   559  	if authenticated {
   560  		common.Log.Trace("this.Authenticated = True")
   561  		crypt.Authenticated = true
   562  		return true, nil
   563  	}
   564  
   565  	return false, nil
   566  }
   567  
   568  // Check access rights and permissions for a specified password.  If either user/owner password is specified,
   569  // full rights are granted, otherwise the access rights are specified by the Permissions flag.
   570  //
   571  // The bool flag indicates that the user can access and can view the file.
   572  // The AccessPermissions shows what access the user has for editing etc.
   573  // An error is returned if there was a problem performing the authentication.
   574  func (crypt *PdfCrypt) checkAccessRights(password []byte) (bool, AccessPermissions, error) {
   575  	perms := AccessPermissions{}
   576  
   577  	// Try owner password -> full rights.
   578  	var (
   579  		isOwner bool
   580  		err     error
   581  	)
   582  	if crypt.R >= 5 {
   583  		var h []byte
   584  		h, err = crypt.alg12(password)
   585  		if err != nil {
   586  			return false, perms, err
   587  		}
   588  		isOwner = len(h) != 0
   589  	} else {
   590  		isOwner, err = crypt.Alg7(password)
   591  	}
   592  	if err != nil {
   593  		return false, perms, err
   594  	}
   595  	if isOwner {
   596  		// owner -> full rights.
   597  		perms.Annotate = true
   598  		perms.DisabilityExtract = true
   599  		perms.ExtractGraphics = true
   600  		perms.FillForms = true
   601  		perms.FullPrintQuality = true
   602  		perms.Modify = true
   603  		perms.Printing = true
   604  		perms.RotateInsert = true
   605  		return true, perms, nil
   606  	}
   607  
   608  	// Try user password.
   609  	var isUser bool
   610  	if crypt.R >= 5 {
   611  		var h []byte
   612  		h, err = crypt.alg11(password)
   613  		if err != nil {
   614  			return false, perms, err
   615  		}
   616  		isUser = len(h) != 0
   617  	} else {
   618  		isUser, err = crypt.Alg6(password)
   619  	}
   620  	if err != nil {
   621  		return false, perms, err
   622  	}
   623  	if isUser {
   624  		// User password specified correctly -> access granted with specified permissions.
   625  		return true, crypt.GetAccessPermissions(), nil
   626  	}
   627  
   628  	// Cannot even view the file.
   629  	return false, perms, nil
   630  }
   631  
   632  func (crypt *PdfCrypt) paddedPass(pass []byte) []byte {
   633  	key := make([]byte, 32)
   634  	if len(pass) >= 32 {
   635  		for i := 0; i < 32; i++ {
   636  			key[i] = pass[i]
   637  		}
   638  	} else {
   639  		for i := 0; i < len(pass); i++ {
   640  			key[i] = pass[i]
   641  		}
   642  		for i := len(pass); i < 32; i++ {
   643  			key[i] = padding[i-len(pass)]
   644  		}
   645  	}
   646  	return key
   647  }
   648  
   649  // Generates a key for encrypting a specific object based on the
   650  // object and generation number, as well as the document encryption key.
   651  func (crypt *PdfCrypt) makeKey(filter string, objNum, genNum uint32, ekey []byte) ([]byte, error) {
   652  	f, err := crypt.CryptFilters.byName(filter)
   653  	if err != nil {
   654  		return nil, err
   655  	}
   656  	return f.MakeKey(objNum, genNum, ekey)
   657  }
   658  
   659  // Check if object has already been processed.
   660  func (crypt *PdfCrypt) isDecrypted(obj PdfObject) bool {
   661  	_, ok := crypt.DecryptedObjects[obj]
   662  	if ok {
   663  		common.Log.Trace("Already decrypted")
   664  		return true
   665  	}
   666  
   667  	common.Log.Trace("Not decrypted yet")
   668  	return false
   669  }
   670  
   671  // Decrypt a buffer with a selected crypt filter.
   672  func (crypt *PdfCrypt) decryptBytes(buf []byte, filter string, okey []byte) ([]byte, error) {
   673  	common.Log.Trace("Decrypt bytes")
   674  	f, err := crypt.CryptFilters.byName(filter)
   675  	if err != nil {
   676  		return nil, err
   677  	}
   678  	return f.DecryptBytes(buf, okey)
   679  }
   680  
   681  // Decrypt an object with specified key. For numbered objects,
   682  // the key argument is not used and a new one is generated based
   683  // on the object and generation number.
   684  // Traverses through all the subobjects (recursive).
   685  //
   686  // Does not look up references..  That should be done prior to calling.
   687  func (crypt *PdfCrypt) Decrypt(obj PdfObject, parentObjNum, parentGenNum int64) error {
   688  	if crypt.isDecrypted(obj) {
   689  		return nil
   690  	}
   691  
   692  	switch obj := obj.(type) {
   693  	case *PdfIndirectObject:
   694  		crypt.DecryptedObjects[obj] = true
   695  
   696  		common.Log.Trace("Decrypting indirect %d %d obj!", obj.ObjectNumber, obj.GenerationNumber)
   697  
   698  		objNum := obj.ObjectNumber
   699  		genNum := obj.GenerationNumber
   700  
   701  		err := crypt.Decrypt(obj.PdfObject, objNum, genNum)
   702  		if err != nil {
   703  			return err
   704  		}
   705  		return nil
   706  	case *PdfObjectStream:
   707  		// Mark as decrypted first to avoid recursive issues.
   708  		crypt.DecryptedObjects[obj] = true
   709  		dict := obj.PdfObjectDictionary
   710  
   711  		if s, ok := dict.Get("Type").(*PdfObjectName); ok && *s == "XRef" {
   712  			return nil // Cross-reference streams should not be encrypted
   713  		}
   714  
   715  		objNum := obj.ObjectNumber
   716  		genNum := obj.GenerationNumber
   717  		common.Log.Trace("Decrypting stream %d %d !", objNum, genNum)
   718  
   719  		// TODO: Check for crypt filter (V4).
   720  		// The Crypt filter shall be the first filter in the Filter array entry.
   721  
   722  		streamFilter := StandardCryptFilter // Default RC4.
   723  		if crypt.V >= 4 {
   724  			streamFilter = crypt.StreamFilter
   725  			common.Log.Trace("this.StreamFilter = %s", crypt.StreamFilter)
   726  
   727  			if filters, ok := dict.Get("Filter").(*PdfObjectArray); ok {
   728  				// Crypt filter can only be the first entry.
   729  				if firstFilter, ok := (*filters)[0].(*PdfObjectName); ok {
   730  					if *firstFilter == "Crypt" {
   731  						// Crypt filter overriding the default.
   732  						// Default option is Identity.
   733  						streamFilter = "Identity"
   734  
   735  						// Check if valid crypt filter specified in the decode params.
   736  						if decodeParams, ok := dict.Get("DecodeParms").(*PdfObjectDictionary); ok {
   737  							if filterName, ok := decodeParams.Get("Name").(*PdfObjectName); ok {
   738  								if _, ok := crypt.CryptFilters[string(*filterName)]; ok {
   739  									common.Log.Trace("Using stream filter %s", *filterName)
   740  									streamFilter = string(*filterName)
   741  								}
   742  							}
   743  						}
   744  					}
   745  				}
   746  			}
   747  
   748  			common.Log.Trace("with %s filter", streamFilter)
   749  			if streamFilter == "Identity" {
   750  				// Identity: pass unchanged.
   751  				return nil
   752  			}
   753  		}
   754  
   755  		err := crypt.Decrypt(dict, objNum, genNum)
   756  		if err != nil {
   757  			return err
   758  		}
   759  
   760  		okey, err := crypt.makeKey(streamFilter, uint32(objNum), uint32(genNum), crypt.EncryptionKey)
   761  		if err != nil {
   762  			return err
   763  		}
   764  
   765  		obj.Stream, err = crypt.decryptBytes(obj.Stream, streamFilter, okey)
   766  		if err != nil {
   767  			return err
   768  		}
   769  		// Update the length based on the decrypted stream.
   770  		dict.Set("Length", MakeInteger(int64(len(obj.Stream))))
   771  
   772  		return nil
   773  	case *PdfObjectString:
   774  		common.Log.Trace("Decrypting string!")
   775  
   776  		stringFilter := StandardCryptFilter
   777  		if crypt.V >= 4 {
   778  			// Currently only support Identity / RC4.
   779  			common.Log.Trace("with %s filter", crypt.StringFilter)
   780  			if crypt.StringFilter == "Identity" {
   781  				// Identity: pass unchanged: No action.
   782  				return nil
   783  			}
   784  			stringFilter = crypt.StringFilter
   785  		}
   786  
   787  		key, err := crypt.makeKey(stringFilter, uint32(parentObjNum), uint32(parentGenNum), crypt.EncryptionKey)
   788  		if err != nil {
   789  			return err
   790  		}
   791  
   792  		// Overwrite the encrypted with decrypted string.
   793  		decrypted := make([]byte, len(*obj))
   794  		for i := 0; i < len(*obj); i++ {
   795  			decrypted[i] = (*obj)[i]
   796  		}
   797  		common.Log.Trace("Decrypt string: %s : % x", decrypted, decrypted)
   798  		decrypted, err = crypt.decryptBytes(decrypted, stringFilter, key)
   799  		if err != nil {
   800  			return err
   801  		}
   802  		*obj = PdfObjectString(decrypted)
   803  
   804  		return nil
   805  	case *PdfObjectArray:
   806  		for _, o := range *obj {
   807  			err := crypt.Decrypt(o, parentObjNum, parentGenNum)
   808  			if err != nil {
   809  				return err
   810  			}
   811  		}
   812  		return nil
   813  	case *PdfObjectDictionary:
   814  		isSig := false
   815  		if t := obj.Get("Type"); t != nil {
   816  			typeStr, ok := t.(*PdfObjectName)
   817  			if ok && *typeStr == "Sig" {
   818  				isSig = true
   819  			}
   820  		}
   821  		for _, keyidx := range obj.Keys() {
   822  			o := obj.Get(keyidx)
   823  			// How can we avoid this check, i.e. implement a more smart
   824  			// traversal system?
   825  			if isSig && string(keyidx) == "Contents" {
   826  				// Leave the Contents of a Signature dictionary.
   827  				continue
   828  			}
   829  
   830  			if string(keyidx) != "Parent" && string(keyidx) != "Prev" && string(keyidx) != "Last" { // Check not needed?
   831  				err := crypt.Decrypt(o, parentObjNum, parentGenNum)
   832  				if err != nil {
   833  					return err
   834  				}
   835  			}
   836  		}
   837  		return nil
   838  	}
   839  
   840  	return nil
   841  }
   842  
   843  // Check if object has already been processed.
   844  func (crypt *PdfCrypt) isEncrypted(obj PdfObject) bool {
   845  	_, ok := crypt.EncryptedObjects[obj]
   846  	if ok {
   847  		common.Log.Trace("Already encrypted")
   848  		return true
   849  	}
   850  
   851  	common.Log.Trace("Not encrypted yet")
   852  	return false
   853  }
   854  
   855  // Encrypt a buffer with the specified crypt filter and key.
   856  func (crypt *PdfCrypt) encryptBytes(buf []byte, filter string, okey []byte) ([]byte, error) {
   857  	common.Log.Trace("Encrypt bytes")
   858  	f, err := crypt.CryptFilters.byName(filter)
   859  	if err != nil {
   860  		return nil, err
   861  	}
   862  	return f.EncryptBytes(buf, okey)
   863  }
   864  
   865  // Encrypt an object with specified key. For numbered objects,
   866  // the key argument is not used and a new one is generated based
   867  // on the object and generation number.
   868  // Traverses through all the subobjects (recursive).
   869  //
   870  // Does not look up references..  That should be done prior to calling.
   871  func (crypt *PdfCrypt) Encrypt(obj PdfObject, parentObjNum, parentGenNum int64) error {
   872  	if crypt.isEncrypted(obj) {
   873  		return nil
   874  	}
   875  	switch obj := obj.(type) {
   876  	case *PdfIndirectObject:
   877  		crypt.EncryptedObjects[obj] = true
   878  
   879  		common.Log.Trace("Encrypting indirect %d %d obj!", obj.ObjectNumber, obj.GenerationNumber)
   880  
   881  		objNum := obj.ObjectNumber
   882  		genNum := obj.GenerationNumber
   883  
   884  		err := crypt.Encrypt(obj.PdfObject, objNum, genNum)
   885  		if err != nil {
   886  			return err
   887  		}
   888  		return nil
   889  	case *PdfObjectStream:
   890  		crypt.EncryptedObjects[obj] = true
   891  		dict := obj.PdfObjectDictionary
   892  
   893  		if s, ok := dict.Get("Type").(*PdfObjectName); ok && *s == "XRef" {
   894  			return nil // Cross-reference streams should not be encrypted
   895  		}
   896  
   897  		objNum := obj.ObjectNumber
   898  		genNum := obj.GenerationNumber
   899  		common.Log.Trace("Encrypting stream %d %d !", objNum, genNum)
   900  
   901  		// TODO: Check for crypt filter (V4).
   902  		// The Crypt filter shall be the first filter in the Filter array entry.
   903  
   904  		streamFilter := StandardCryptFilter // Default RC4.
   905  		if crypt.V >= 4 {
   906  			// For now.  Need to change when we add support for more than
   907  			// Identity / RC4.
   908  			streamFilter = crypt.StreamFilter
   909  			common.Log.Trace("this.StreamFilter = %s", crypt.StreamFilter)
   910  
   911  			if filters, ok := dict.Get("Filter").(*PdfObjectArray); ok {
   912  				// Crypt filter can only be the first entry.
   913  				if firstFilter, ok := (*filters)[0].(*PdfObjectName); ok {
   914  					if *firstFilter == "Crypt" {
   915  						// Crypt filter overriding the default.
   916  						// Default option is Identity.
   917  						streamFilter = "Identity"
   918  
   919  						// Check if valid crypt filter specified in the decode params.
   920  						if decodeParams, ok := dict.Get("DecodeParms").(*PdfObjectDictionary); ok {
   921  							if filterName, ok := decodeParams.Get("Name").(*PdfObjectName); ok {
   922  								if _, ok := crypt.CryptFilters[string(*filterName)]; ok {
   923  									common.Log.Trace("Using stream filter %s", *filterName)
   924  									streamFilter = string(*filterName)
   925  								}
   926  							}
   927  						}
   928  					}
   929  				}
   930  			}
   931  
   932  			common.Log.Trace("with %s filter", streamFilter)
   933  			if streamFilter == "Identity" {
   934  				// Identity: pass unchanged.
   935  				return nil
   936  			}
   937  		}
   938  
   939  		err := crypt.Encrypt(obj.PdfObjectDictionary, objNum, genNum)
   940  		if err != nil {
   941  			return err
   942  		}
   943  
   944  		okey, err := crypt.makeKey(streamFilter, uint32(objNum), uint32(genNum), crypt.EncryptionKey)
   945  		if err != nil {
   946  			return err
   947  		}
   948  
   949  		obj.Stream, err = crypt.encryptBytes(obj.Stream, streamFilter, okey)
   950  		if err != nil {
   951  			return err
   952  		}
   953  		// Update the length based on the encrypted stream.
   954  		dict.Set("Length", MakeInteger(int64(len(obj.Stream))))
   955  
   956  		return nil
   957  	case *PdfObjectString:
   958  		common.Log.Trace("Encrypting string!")
   959  
   960  		stringFilter := StandardCryptFilter
   961  		if crypt.V >= 4 {
   962  			common.Log.Trace("with %s filter", crypt.StringFilter)
   963  			if crypt.StringFilter == "Identity" {
   964  				// Identity: pass unchanged: No action.
   965  				return nil
   966  			}
   967  			stringFilter = crypt.StringFilter
   968  		}
   969  
   970  		key, err := crypt.makeKey(stringFilter, uint32(parentObjNum), uint32(parentGenNum), crypt.EncryptionKey)
   971  		if err != nil {
   972  			return err
   973  		}
   974  
   975  		encrypted := make([]byte, len(*obj))
   976  		for i := 0; i < len(*obj); i++ {
   977  			encrypted[i] = (*obj)[i]
   978  		}
   979  		common.Log.Trace("Encrypt string: %s : % x", encrypted, encrypted)
   980  		encrypted, err = crypt.encryptBytes(encrypted, stringFilter, key)
   981  		if err != nil {
   982  			return err
   983  		}
   984  		*obj = PdfObjectString(encrypted)
   985  
   986  		return nil
   987  	case *PdfObjectArray:
   988  		for _, o := range *obj {
   989  			err := crypt.Encrypt(o, parentObjNum, parentGenNum)
   990  			if err != nil {
   991  				return err
   992  			}
   993  		}
   994  		return nil
   995  	case *PdfObjectDictionary:
   996  		isSig := false
   997  		if t := obj.Get("Type"); t != nil {
   998  			typeStr, ok := t.(*PdfObjectName)
   999  			if ok && *typeStr == "Sig" {
  1000  				isSig = true
  1001  			}
  1002  		}
  1003  
  1004  		for _, keyidx := range obj.Keys() {
  1005  			o := obj.Get(keyidx)
  1006  			// How can we avoid this check, i.e. implement a more smart
  1007  			// traversal system?
  1008  			if isSig && string(keyidx) == "Contents" {
  1009  				// Leave the Contents of a Signature dictionary.
  1010  				continue
  1011  			}
  1012  			if string(keyidx) != "Parent" && string(keyidx) != "Prev" && string(keyidx) != "Last" { // Check not needed?
  1013  				err := crypt.Encrypt(o, parentObjNum, parentGenNum)
  1014  				if err != nil {
  1015  					return err
  1016  				}
  1017  			}
  1018  		}
  1019  		return nil
  1020  	}
  1021  
  1022  	return nil
  1023  }
  1024  
  1025  // aesZeroIV allocates a zero-filled buffer that serves as an initialization vector for AESv3.
  1026  func (crypt *PdfCrypt) aesZeroIV() []byte {
  1027  	if crypt.ivAESZero == nil {
  1028  		crypt.ivAESZero = make([]byte, aes.BlockSize)
  1029  	}
  1030  	return crypt.ivAESZero
  1031  }
  1032  
  1033  // alg2a retrieves the encryption key from an encrypted document (R >= 5).
  1034  // It returns false if the password was wrong.
  1035  // 7.6.4.3.2 Algorithm 2.A (page 83)
  1036  func (crypt *PdfCrypt) alg2a(pass []byte) (bool, error) {
  1037  	// O & U: 32 byte hash + 8 byte Validation Salt + 8 byte Key Salt
  1038  
  1039  	// step a: Unicode normalization
  1040  	// TODO(dennwc): make sure that UTF-8 strings are normalized
  1041  
  1042  	// step b: truncate to 127 bytes
  1043  	if len(pass) > 127 {
  1044  		pass = pass[:127]
  1045  	}
  1046  
  1047  	// step c: test pass against the owner key
  1048  	h, err := crypt.alg12(pass)
  1049  	if err != nil {
  1050  		return false, err
  1051  	}
  1052  	var (
  1053  		data []byte // data to hash
  1054  		ekey []byte // encrypted file key
  1055  		ukey []byte // user key; set only when using owner's password
  1056  	)
  1057  	if len(h) != 0 {
  1058  		// owner password valid
  1059  
  1060  		// step d: compute an intermediate owner key
  1061  		str := make([]byte, len(pass)+8+48)
  1062  		i := copy(str, pass)
  1063  		i += copy(str[i:], crypt.O[40:48]) // owner Key Salt
  1064  		i += copy(str[i:], crypt.U[0:48])
  1065  
  1066  		data = str
  1067  		ekey = crypt.OE
  1068  		ukey = crypt.U[0:48]
  1069  	} else {
  1070  		// check user password
  1071  		h, err = crypt.alg11(pass)
  1072  		if err == nil && len(h) == 0 {
  1073  			// try default password
  1074  			h, err = crypt.alg11([]byte(""))
  1075  		}
  1076  		if err != nil {
  1077  			return false, err
  1078  		} else if len(h) == 0 {
  1079  			// wrong password
  1080  			return false, nil
  1081  		}
  1082  		// step e: compute an intermediate user key
  1083  		str := make([]byte, len(pass)+8)
  1084  		i := copy(str, pass)
  1085  		i += copy(str[i:], crypt.U[40:48]) // user Key Salt
  1086  
  1087  		data = str
  1088  		ekey = crypt.UE
  1089  		ukey = nil
  1090  	}
  1091  	ekey = ekey[:32]
  1092  
  1093  	// intermediate key
  1094  	ikey := crypt.alg2b(data, pass, ukey)
  1095  
  1096  	ac, err := aes.NewCipher(ikey[:32])
  1097  	if err != nil {
  1098  		panic(err)
  1099  	}
  1100  
  1101  	iv := crypt.aesZeroIV()
  1102  	cbc := cipher.NewCBCDecrypter(ac, iv)
  1103  	fkey := make([]byte, 32)
  1104  	cbc.CryptBlocks(fkey, ekey)
  1105  
  1106  	crypt.EncryptionKey = fkey
  1107  
  1108  	if crypt.R == 5 {
  1109  		return true, nil
  1110  	}
  1111  
  1112  	return crypt.alg13(fkey)
  1113  }
  1114  
  1115  // alg2b computes a hash for R=5 and R=6.
  1116  func (crypt *PdfCrypt) alg2b(data, pwd, userKey []byte) []byte {
  1117  	if crypt.R == 5 {
  1118  		return alg2b_R5(data)
  1119  	}
  1120  	return alg2b(data, pwd, userKey)
  1121  }
  1122  
  1123  // alg2b_R5 computes a hash for R=5, used in a deprecated extension.
  1124  // It's used the same way as a hash described in Algorithm 2.B, but it doesn't use the original password
  1125  // and the user key to calculate the hash.
  1126  func alg2b_R5(data []byte) []byte {
  1127  	h := sha256.New()
  1128  	h.Write(data)
  1129  	return h.Sum(nil)
  1130  }
  1131  
  1132  // repeat repeats first n bytes of buf until the end of the buffer.
  1133  // It assumes that the length of buf is a multiple of n.
  1134  func repeat(buf []byte, n int) {
  1135  	bp := n
  1136  	for bp < len(buf) {
  1137  		copy(buf[bp:], buf[:bp])
  1138  		bp *= 2
  1139  	}
  1140  }
  1141  
  1142  // alg2b computes a hash for R=6.
  1143  // 7.6.4.3.3 Algorithm 2.B (page 83)
  1144  func alg2b(data, pwd, userKey []byte) []byte {
  1145  	var (
  1146  		s256, s384, s512 hash.Hash
  1147  	)
  1148  	s256 = sha256.New()
  1149  	hbuf := make([]byte, 64)
  1150  
  1151  	h := s256
  1152  	h.Write(data)
  1153  	K := h.Sum(hbuf[:0])
  1154  
  1155  	buf := make([]byte, 64*(127+64+48))
  1156  
  1157  	round := func(rnd int) (E []byte) {
  1158  		// step a: repeat pass+K 64 times
  1159  		n := len(pwd) + len(K) + len(userKey)
  1160  		part := buf[:n]
  1161  		i := copy(part, pwd)
  1162  		i += copy(part[i:], K[:])
  1163  		i += copy(part[i:], userKey)
  1164  		if i != n {
  1165  			panic("wrong size")
  1166  		}
  1167  		K1 := buf[:n*64]
  1168  		repeat(K1, n)
  1169  
  1170  		// step b: encrypt K1 with AES-128 CBC
  1171  		ac, err := aes.NewCipher(K[0:16])
  1172  		if err != nil {
  1173  			panic(err)
  1174  		}
  1175  		cbc := cipher.NewCBCEncrypter(ac, K[16:32])
  1176  		cbc.CryptBlocks(K1, K1)
  1177  		E = K1
  1178  
  1179  		// step c: use 16 bytes of E as big-endian int, select the next hash
  1180  		b := 0
  1181  		for i := 0; i < 16; i++ {
  1182  			b += int(E[i] % 3)
  1183  		}
  1184  		var h hash.Hash
  1185  		switch b % 3 {
  1186  		case 0:
  1187  			h = s256
  1188  		case 1:
  1189  			if s384 == nil {
  1190  				s384 = sha512.New384()
  1191  			}
  1192  			h = s384
  1193  		case 2:
  1194  			if s512 == nil {
  1195  				s512 = sha512.New()
  1196  			}
  1197  			h = s512
  1198  		}
  1199  
  1200  		// step d: take the hash of E, use as a new K
  1201  		h.Reset()
  1202  		h.Write(E)
  1203  		K = h.Sum(hbuf[:0])
  1204  
  1205  		return E
  1206  	}
  1207  
  1208  	for i := 0; ; {
  1209  		E := round(i)
  1210  		b := uint8(E[len(E)-1])
  1211  		// from the spec, it appears that i should be incremented after
  1212  		// the test, but that doesn't match what Adobe does
  1213  		i++
  1214  		if i >= 64 && b <= uint8(i-32) {
  1215  			break
  1216  		}
  1217  	}
  1218  	return K[:32]
  1219  }
  1220  
  1221  // Alg2 computes an encryption key.
  1222  // TODO (v3): Unexport.
  1223  func (crypt *PdfCrypt) Alg2(pass []byte) []byte {
  1224  	common.Log.Trace("Alg2")
  1225  	key := crypt.paddedPass(pass)
  1226  
  1227  	h := md5.New()
  1228  	h.Write(key)
  1229  
  1230  	// Pass O.
  1231  	h.Write(crypt.O)
  1232  
  1233  	// Pass P (Lower order byte first).
  1234  	var p uint32 = uint32(crypt.P)
  1235  	var pb = []byte{}
  1236  	for i := 0; i < 4; i++ {
  1237  		pb = append(pb, byte(((p >> uint(8*i)) & 0xff)))
  1238  	}
  1239  	h.Write(pb)
  1240  	common.Log.Trace("go P: % x", pb)
  1241  
  1242  	// Pass ID[0] from the trailer
  1243  	h.Write([]byte(crypt.Id0))
  1244  
  1245  	common.Log.Trace("this.R = %d encryptMetadata %v", crypt.R, crypt.EncryptMetadata)
  1246  	if (crypt.R >= 4) && !crypt.EncryptMetadata {
  1247  		h.Write([]byte{0xff, 0xff, 0xff, 0xff})
  1248  	}
  1249  	hashb := h.Sum(nil)
  1250  
  1251  	if crypt.R >= 3 {
  1252  		for i := 0; i < 50; i++ {
  1253  			h = md5.New()
  1254  			h.Write(hashb[0 : crypt.Length/8])
  1255  			hashb = h.Sum(nil)
  1256  		}
  1257  	}
  1258  
  1259  	if crypt.R >= 3 {
  1260  		return hashb[0 : crypt.Length/8]
  1261  	}
  1262  
  1263  	return hashb[0:5]
  1264  }
  1265  
  1266  // Create the RC4 encryption key.
  1267  func (crypt *PdfCrypt) alg3Key(pass []byte) []byte {
  1268  	h := md5.New()
  1269  	okey := crypt.paddedPass(pass)
  1270  	h.Write(okey)
  1271  
  1272  	if crypt.R >= 3 {
  1273  		for i := 0; i < 50; i++ {
  1274  			hashb := h.Sum(nil)
  1275  			h = md5.New()
  1276  			h.Write(hashb)
  1277  		}
  1278  	}
  1279  
  1280  	encKey := h.Sum(nil)
  1281  	if crypt.R == 2 {
  1282  		encKey = encKey[0:5]
  1283  	} else {
  1284  		encKey = encKey[0 : crypt.Length/8]
  1285  	}
  1286  	return encKey
  1287  }
  1288  
  1289  // Alg3 computes the encryption dictionary’s O (owner password) value.
  1290  // TODO (v3): Unexport.
  1291  func (crypt *PdfCrypt) Alg3(upass, opass []byte) (PdfObjectString, error) {
  1292  	// Return O string val.
  1293  	O := PdfObjectString("")
  1294  
  1295  	var encKey []byte
  1296  	if len(opass) > 0 {
  1297  		encKey = crypt.alg3Key(opass)
  1298  	} else {
  1299  		encKey = crypt.alg3Key(upass)
  1300  	}
  1301  
  1302  	ociph, err := rc4.NewCipher(encKey)
  1303  	if err != nil {
  1304  		return O, errors.New("Failed rc4 ciph")
  1305  	}
  1306  
  1307  	ukey := crypt.paddedPass(upass)
  1308  	encrypted := make([]byte, len(ukey))
  1309  	ociph.XORKeyStream(encrypted, ukey)
  1310  
  1311  	if crypt.R >= 3 {
  1312  		encKey2 := make([]byte, len(encKey))
  1313  		for i := 0; i < 19; i++ {
  1314  			for j := 0; j < len(encKey); j++ {
  1315  				encKey2[j] = encKey[j] ^ byte(i+1)
  1316  			}
  1317  			ciph, err := rc4.NewCipher(encKey2)
  1318  			if err != nil {
  1319  				return O, errors.New("Failed rc4 ciph")
  1320  			}
  1321  			ciph.XORKeyStream(encrypted, encrypted)
  1322  		}
  1323  	}
  1324  
  1325  	O = PdfObjectString(encrypted)
  1326  	return O, nil
  1327  }
  1328  
  1329  // Alg4 computes the encryption dictionary’s U (user password) value (Security handlers of revision 2).
  1330  // TODO (v3): Unexport.
  1331  func (crypt *PdfCrypt) Alg4(upass []byte) (PdfObjectString, []byte, error) {
  1332  	U := PdfObjectString("")
  1333  
  1334  	ekey := crypt.Alg2(upass)
  1335  	ciph, err := rc4.NewCipher(ekey)
  1336  	if err != nil {
  1337  		return U, ekey, errors.New("Failed rc4 ciph")
  1338  	}
  1339  
  1340  	s := []byte(padding)
  1341  	encrypted := make([]byte, len(s))
  1342  	ciph.XORKeyStream(encrypted, s)
  1343  
  1344  	U = PdfObjectString(encrypted)
  1345  	return U, ekey, nil
  1346  }
  1347  
  1348  // Alg5 computes the encryption dictionary’s U (user password) value (Security handlers of revision 3 or greater).
  1349  // TODO (v3): Unexport.
  1350  func (crypt *PdfCrypt) Alg5(upass []byte) (PdfObjectString, []byte, error) {
  1351  	U := PdfObjectString("")
  1352  
  1353  	ekey := crypt.Alg2(upass)
  1354  
  1355  	h := md5.New()
  1356  	h.Write([]byte(padding))
  1357  	h.Write([]byte(crypt.Id0))
  1358  	hash := h.Sum(nil)
  1359  
  1360  	common.Log.Trace("Alg5")
  1361  	common.Log.Trace("ekey: % x", ekey)
  1362  	common.Log.Trace("ID: % x", crypt.Id0)
  1363  
  1364  	if len(hash) != 16 {
  1365  		return U, ekey, errors.New("Hash length not 16 bytes")
  1366  	}
  1367  
  1368  	ciph, err := rc4.NewCipher(ekey)
  1369  	if err != nil {
  1370  		return U, ekey, errors.New("Failed rc4 ciph")
  1371  	}
  1372  	encrypted := make([]byte, 16)
  1373  	ciph.XORKeyStream(encrypted, hash)
  1374  
  1375  	// Do the following 19 times: Take the output from the previous
  1376  	// invocation of the RC4 function and pass it as input to a new
  1377  	// invocation of the function; use an encryption key generated by
  1378  	// taking each byte of the original encryption key obtained in step
  1379  	// (a) and performing an XOR (exclusive or) operation between that
  1380  	// byte and the single-byte value of the iteration counter (from 1 to 19).
  1381  	ekey2 := make([]byte, len(ekey))
  1382  	for i := 0; i < 19; i++ {
  1383  		for j := 0; j < len(ekey); j++ {
  1384  			ekey2[j] = ekey[j] ^ byte(i+1)
  1385  		}
  1386  		ciph, err = rc4.NewCipher(ekey2)
  1387  		if err != nil {
  1388  			return U, ekey, errors.New("Failed rc4 ciph")
  1389  		}
  1390  		ciph.XORKeyStream(encrypted, encrypted)
  1391  		common.Log.Trace("i = %d, ekey: % x", i, ekey2)
  1392  		common.Log.Trace("i = %d -> % x", i, encrypted)
  1393  	}
  1394  
  1395  	bb := make([]byte, 32)
  1396  	for i := 0; i < 16; i++ {
  1397  		bb[i] = encrypted[i]
  1398  	}
  1399  
  1400  	// Append 16 bytes of arbitrary padding to the output from the final
  1401  	// invocation of the RC4 function and store the 32-byte result as
  1402  	// the value of the U entry in the encryption dictionary.
  1403  	_, err = rand.Read(bb[16:32])
  1404  	if err != nil {
  1405  		return U, ekey, errors.New("Failed to gen rand number")
  1406  	}
  1407  
  1408  	U = PdfObjectString(bb)
  1409  	return U, ekey, nil
  1410  }
  1411  
  1412  // Alg6 authenticates the user password.
  1413  // TODO (v3): Unexport.
  1414  func (crypt *PdfCrypt) Alg6(upass []byte) (bool, error) {
  1415  	var uo PdfObjectString
  1416  	var err error
  1417  	var key []byte
  1418  	if crypt.R == 2 {
  1419  		uo, key, err = crypt.Alg4(upass)
  1420  	} else if crypt.R >= 3 {
  1421  		uo, key, err = crypt.Alg5(upass)
  1422  	} else {
  1423  		return false, errors.New("invalid R")
  1424  	}
  1425  
  1426  	if err != nil {
  1427  		return false, err
  1428  	}
  1429  
  1430  	common.Log.Trace("check: % x == % x ?", string(uo), string(crypt.U))
  1431  
  1432  	uGen := string(uo)      // Generated U from specified pass.
  1433  	uDoc := string(crypt.U) // U from the document.
  1434  	if crypt.R >= 3 {
  1435  		// comparing on the first 16 bytes in the case of security
  1436  		// handlers of revision 3 or greater),
  1437  		if len(uGen) > 16 {
  1438  			uGen = uGen[0:16]
  1439  		}
  1440  		if len(uDoc) > 16 {
  1441  			uDoc = uDoc[0:16]
  1442  		}
  1443  	}
  1444  
  1445  	if uGen == uDoc {
  1446  		crypt.EncryptionKey = key
  1447  		return true, nil
  1448  	}
  1449  
  1450  	return false, nil
  1451  }
  1452  
  1453  // Alg7 authenticates the owner password.
  1454  // TODO (v3): Unexport.
  1455  func (crypt *PdfCrypt) Alg7(opass []byte) (bool, error) {
  1456  	encKey := crypt.alg3Key(opass)
  1457  
  1458  	decrypted := make([]byte, len(crypt.O))
  1459  	if crypt.R == 2 {
  1460  		ciph, err := rc4.NewCipher(encKey)
  1461  		if err != nil {
  1462  			return false, errors.New("Failed cipher")
  1463  		}
  1464  		ciph.XORKeyStream(decrypted, crypt.O)
  1465  	} else if crypt.R >= 3 {
  1466  		s := append([]byte{}, crypt.O...)
  1467  		for i := 0; i < 20; i++ {
  1468  			//newKey := encKey
  1469  			newKey := append([]byte{}, encKey...)
  1470  			for j := 0; j < len(encKey); j++ {
  1471  				newKey[j] ^= byte(19 - i)
  1472  			}
  1473  			ciph, err := rc4.NewCipher(newKey)
  1474  			if err != nil {
  1475  				return false, errors.New("Failed cipher")
  1476  			}
  1477  			ciph.XORKeyStream(decrypted, s)
  1478  			s = append([]byte{}, decrypted...)
  1479  		}
  1480  	} else {
  1481  		return false, errors.New("invalid R")
  1482  	}
  1483  
  1484  	auth, err := crypt.Alg6(decrypted)
  1485  	if err != nil {
  1486  		return false, nil
  1487  	}
  1488  
  1489  	return auth, nil
  1490  }
  1491  
  1492  // GenerateParams generates encryption parameters for specified passwords.
  1493  // Can be called only for R>=5.
  1494  func (crypt *PdfCrypt) GenerateParams(upass, opass []byte) error {
  1495  	if crypt.R < 5 {
  1496  		// TODO(dennwc): move code for R<5 from PdfWriter.Encrypt
  1497  		return errors.New("can be used only for R>=5")
  1498  	}
  1499  	crypt.EncryptionKey = make([]byte, 32)
  1500  	if _, err := io.ReadFull(rand.Reader, crypt.EncryptionKey); err != nil {
  1501  		return err
  1502  	}
  1503  	return crypt.generateR6(upass, opass)
  1504  }
  1505  
  1506  // generateR6 is the algorithm opposite to alg2a (R>=5).
  1507  // It generates U,O,UE,OE,Perms fields using AESv3 encryption.
  1508  // There is no algorithm number assigned to this function in the spec.
  1509  func (crypt *PdfCrypt) generateR6(upass, opass []byte) error {
  1510  	// all these field will be populated by functions below
  1511  	crypt.U = nil
  1512  	crypt.O = nil
  1513  	crypt.UE = nil
  1514  	crypt.OE = nil
  1515  	crypt.Perms = nil // populated only for R=6
  1516  
  1517  	if len(upass) > 127 {
  1518  		upass = upass[:127]
  1519  	}
  1520  	if len(opass) > 127 {
  1521  		opass = opass[:127]
  1522  	}
  1523  	// generate U and UE
  1524  	if err := crypt.alg8(upass); err != nil {
  1525  		return err
  1526  	}
  1527  	// generate O and OE
  1528  	if err := crypt.alg9(opass); err != nil {
  1529  		return err
  1530  	}
  1531  	if crypt.R == 5 {
  1532  		return nil
  1533  	}
  1534  	// generate Perms
  1535  	return crypt.alg10()
  1536  }
  1537  
  1538  // alg8 computes the encryption dictionary's U (user password) and UE (user encryption) values (R>=5).
  1539  // 7.6.4.4.6 Algorithm 8 (page 86)
  1540  func (crypt *PdfCrypt) alg8(upass []byte) error {
  1541  	// step a: compute U (user password)
  1542  	var rbuf [16]byte
  1543  	if _, err := io.ReadFull(rand.Reader, rbuf[:]); err != nil {
  1544  		return err
  1545  	}
  1546  	valSalt := rbuf[0:8]
  1547  	keySalt := rbuf[8:16]
  1548  
  1549  	str := make([]byte, len(upass)+len(valSalt))
  1550  	i := copy(str, upass)
  1551  	i += copy(str[i:], valSalt)
  1552  
  1553  	h := crypt.alg2b(str, upass, nil)
  1554  
  1555  	U := make([]byte, len(h)+len(valSalt)+len(keySalt))
  1556  	i = copy(U, h[:32])
  1557  	i += copy(U[i:], valSalt)
  1558  	i += copy(U[i:], keySalt)
  1559  
  1560  	crypt.U = U
  1561  
  1562  	// step b: compute UE (user encryption)
  1563  
  1564  	// str still contains a password, reuse it
  1565  	i = len(upass)
  1566  	i += copy(str[i:], keySalt)
  1567  
  1568  	h = crypt.alg2b(str, upass, nil)
  1569  
  1570  	ac, err := aes.NewCipher(h[:32])
  1571  	if err != nil {
  1572  		panic(err)
  1573  	}
  1574  
  1575  	iv := crypt.aesZeroIV()
  1576  	cbc := cipher.NewCBCEncrypter(ac, iv)
  1577  	UE := make([]byte, 32)
  1578  	cbc.CryptBlocks(UE, crypt.EncryptionKey[:32])
  1579  	crypt.UE = UE
  1580  
  1581  	return nil
  1582  }
  1583  
  1584  // alg9 computes the encryption dictionary's O (owner password) and OE (owner encryption) values (R>=5).
  1585  // 7.6.4.4.7 Algorithm 9 (page 86)
  1586  func (crypt *PdfCrypt) alg9(opass []byte) error {
  1587  	// step a: compute O (owner password)
  1588  	var rbuf [16]byte
  1589  	if _, err := io.ReadFull(rand.Reader, rbuf[:]); err != nil {
  1590  		return err
  1591  	}
  1592  	valSalt := rbuf[0:8]
  1593  	keySalt := rbuf[8:16]
  1594  	userKey := crypt.U[:48]
  1595  
  1596  	str := make([]byte, len(opass)+len(valSalt)+len(userKey))
  1597  	i := copy(str, opass)
  1598  	i += copy(str[i:], valSalt)
  1599  	i += copy(str[i:], userKey)
  1600  
  1601  	h := crypt.alg2b(str, opass, userKey)
  1602  
  1603  	O := make([]byte, len(h)+len(valSalt)+len(keySalt))
  1604  	i = copy(O, h[:32])
  1605  	i += copy(O[i:], valSalt)
  1606  	i += copy(O[i:], keySalt)
  1607  
  1608  	crypt.O = O
  1609  
  1610  	// step b: compute OE (owner encryption)
  1611  
  1612  	// str still contains a password and a user key - reuse both, but overwrite the salt
  1613  	i = len(opass)
  1614  	i += copy(str[i:], keySalt)
  1615  	// i += len(userKey)
  1616  
  1617  	h = crypt.alg2b(str, opass, userKey)
  1618  
  1619  	ac, err := aes.NewCipher(h[:32])
  1620  	if err != nil {
  1621  		panic(err)
  1622  	}
  1623  
  1624  	iv := crypt.aesZeroIV()
  1625  	cbc := cipher.NewCBCEncrypter(ac, iv)
  1626  	OE := make([]byte, 32)
  1627  	cbc.CryptBlocks(OE, crypt.EncryptionKey[:32])
  1628  	crypt.OE = OE
  1629  
  1630  	return nil
  1631  }
  1632  
  1633  // alg10 computes the encryption dictionary's Perms (permissions) value (R=6).
  1634  // 7.6.4.4.8 Algorithm 10 (page 87)
  1635  func (crypt *PdfCrypt) alg10() error {
  1636  	// step a: extend permissions to 64 bits
  1637  	perms := uint64(uint32(crypt.P)) | (math.MaxUint32 << 32)
  1638  
  1639  	// step b: record permissions
  1640  	Perms := make([]byte, 16)
  1641  	binary.LittleEndian.PutUint64(Perms[:8], perms)
  1642  
  1643  	// step c: record EncryptMetadata
  1644  	if crypt.EncryptMetadata {
  1645  		Perms[8] = 'T'
  1646  	} else {
  1647  		Perms[8] = 'F'
  1648  	}
  1649  
  1650  	// step d: write "adb" magic
  1651  	copy(Perms[9:12], "adb")
  1652  
  1653  	// step e: write 4 bytes of random data
  1654  
  1655  	// spec doesn't specify them as generated "from a strong random source",
  1656  	// but we will use the cryptographic random generator anyway
  1657  	if _, err := io.ReadFull(rand.Reader, Perms[12:16]); err != nil {
  1658  		return err
  1659  	}
  1660  
  1661  	// step f: encrypt permissions
  1662  	ac, err := aes.NewCipher(crypt.EncryptionKey[:32])
  1663  	if err != nil {
  1664  		panic(err)
  1665  	}
  1666  
  1667  	ecb := newECBEncrypter(ac)
  1668  	ecb.CryptBlocks(Perms, Perms)
  1669  
  1670  	crypt.Perms = Perms[:16]
  1671  	return nil
  1672  }
  1673  
  1674  // alg11 authenticates the user password (R >= 5) and returns the hash.
  1675  func (crypt *PdfCrypt) alg11(upass []byte) ([]byte, error) {
  1676  	str := make([]byte, len(upass)+8)
  1677  	i := copy(str, upass)
  1678  	i += copy(str[i:], crypt.U[32:40]) // user Validation Salt
  1679  
  1680  	h := crypt.alg2b(str, upass, nil)
  1681  	h = h[:32]
  1682  	if !bytes.Equal(h, crypt.U[:32]) {
  1683  		return nil, nil
  1684  	}
  1685  	return h, nil
  1686  }
  1687  
  1688  // alg12 authenticates the owner password (R >= 5) and returns the hash.
  1689  // 7.6.4.4.10 Algorithm 12 (page 87)
  1690  func (crypt *PdfCrypt) alg12(opass []byte) ([]byte, error) {
  1691  	str := make([]byte, len(opass)+8+48)
  1692  	i := copy(str, opass)
  1693  	i += copy(str[i:], crypt.O[32:40]) // owner Validation Salt
  1694  	i += copy(str[i:], crypt.U[0:48])
  1695  
  1696  	h := crypt.alg2b(str, opass, crypt.U[0:48])
  1697  	h = h[:32]
  1698  	if !bytes.Equal(h, crypt.O[:32]) {
  1699  		return nil, nil
  1700  	}
  1701  	return h, nil
  1702  }
  1703  
  1704  // alg13 validates user permissions (P+EncryptMetadata vs Perms) for R=6.
  1705  // 7.6.4.4.11 Algorithm 13 (page 87)
  1706  func (crypt *PdfCrypt) alg13(fkey []byte) (bool, error) {
  1707  	perms := make([]byte, 16)
  1708  	copy(perms, crypt.Perms[:16])
  1709  
  1710  	ac, err := aes.NewCipher(fkey[:32])
  1711  	if err != nil {
  1712  		panic(err)
  1713  	}
  1714  
  1715  	ecb := newECBDecrypter(ac)
  1716  	ecb.CryptBlocks(perms, perms)
  1717  
  1718  	if !bytes.Equal(perms[9:12], []byte("adb")) {
  1719  		return false, errors.New("decoded permissions are invalid")
  1720  	}
  1721  	p := int(int32(binary.LittleEndian.Uint32(perms[0:4])))
  1722  	if p != crypt.P {
  1723  		return false, errors.New("permissions validation failed")
  1724  	}
  1725  	encMeta := true
  1726  	if perms[8] == 'T' {
  1727  		encMeta = true
  1728  	} else if perms[8] == 'F' {
  1729  		encMeta = false
  1730  	} else {
  1731  		return false, errors.New("decoded metadata encryption flag is invalid")
  1732  	}
  1733  	if encMeta != crypt.EncryptMetadata {
  1734  		return false, errors.New("metadata encryption validation failed")
  1735  	}
  1736  	return true, nil
  1737  }