github.com/pdfcpu/pdfcpu@v0.11.1/pkg/cli/test/encryption_test.go (about)

     1  /*
     2  Copyright 2019 The pdfcpu Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  	http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package test
    18  
    19  import (
    20  	"path/filepath"
    21  	"strings"
    22  	"testing"
    23  
    24  	"github.com/pdfcpu/pdfcpu/pkg/cli"
    25  	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
    26  )
    27  
    28  func confForAlgorithm(aes bool, keyLength int) *model.Configuration {
    29  	c := model.NewDefaultConfiguration()
    30  	c.EncryptUsingAES = aes
    31  	c.EncryptKeyLength = keyLength
    32  	return c
    33  }
    34  
    35  func testEncryptDecryptUseCase1(t *testing.T, fileName string, aes bool, keyLength int) {
    36  	t.Helper()
    37  	msg := "testEncryptDecryptUseCase1"
    38  
    39  	inFile := filepath.Join(inDir, fileName)
    40  	outFile := filepath.Join(outDir, "test.pdf")
    41  	t.Log(inFile)
    42  
    43  	// Encrypt opw and upw
    44  	t.Log("Encrypt")
    45  	conf := confForAlgorithm(aes, keyLength)
    46  	conf.UserPW = "upw"
    47  	conf.OwnerPW = "opw"
    48  
    49  	cmd := cli.EncryptCommand(inFile, outFile, conf)
    50  	if _, err := cli.Process(cmd); err != nil {
    51  		t.Fatalf("%s: encrypt to %s: %v\n", msg, outFile, err)
    52  	}
    53  
    54  	// Validate wrong opw
    55  	t.Log("Validate wrong opw fails")
    56  	conf = confForAlgorithm(aes, keyLength)
    57  	conf.OwnerPW = "opwWrong"
    58  	if err := validateFile(t, outFile, conf); err == nil {
    59  		t.Fatalf("%s: validate %s using wrong opw should fail!\n", msg, outFile)
    60  	}
    61  
    62  	// Validate opw
    63  	t.Log("Validate opw")
    64  	conf = confForAlgorithm(aes, keyLength)
    65  	conf.OwnerPW = "opw"
    66  	if err := validateFile(t, outFile, conf); err != nil {
    67  		t.Fatalf("%s: validate %s using opw: %v\n", msg, outFile, err)
    68  	}
    69  
    70  	// Validate wrong upw
    71  	t.Log("Validate wrong upw fails")
    72  	conf = confForAlgorithm(aes, keyLength)
    73  	conf.UserPW = "upwWrong"
    74  	if err := validateFile(t, outFile, conf); err == nil {
    75  		t.Fatalf("%s: validate %s using wrong upw should fail!\n", msg, outFile)
    76  	}
    77  
    78  	// Validate upw
    79  	t.Log("Validate upw")
    80  	conf = confForAlgorithm(aes, keyLength)
    81  	conf.UserPW = "upw"
    82  	if err := validateFile(t, outFile, conf); err != nil {
    83  		t.Fatalf("%s: validate %s using upw: %v\n", msg, outFile, err)
    84  	}
    85  
    86  	// Change upw to "" = remove document open password.
    87  	t.Log("ChangeUserPW to \"\"")
    88  	conf = confForAlgorithm(aes, keyLength)
    89  	conf.OwnerPW = "opw"
    90  	pwOld := "upw"
    91  	pwNew := ""
    92  	cmd = cli.ChangeUserPWCommand(outFile, "", &pwOld, &pwNew, conf)
    93  	if _, err := cli.Process(cmd); err != nil {
    94  		t.Fatalf("%s: %s change userPW to \"\": %v\n", msg, outFile, err)
    95  	}
    96  
    97  	// Validate upw
    98  	t.Log("Validate upw")
    99  	conf = confForAlgorithm(aes, keyLength)
   100  	conf.UserPW = ""
   101  	if err := validateFile(t, outFile, conf); err != nil {
   102  		t.Fatalf("%s: validate %s using upw: %v\n", msg, outFile, err)
   103  	}
   104  
   105  	// Validate no pw
   106  	t.Log("Validate upw")
   107  	conf = confForAlgorithm(aes, keyLength)
   108  	if err := validateFile(t, outFile, conf); err != nil {
   109  		t.Fatalf("%s: validate %s: %v\n", msg, outFile, err)
   110  	}
   111  
   112  	// Change opw
   113  	t.Log("ChangeOwnerPW")
   114  	conf = confForAlgorithm(aes, keyLength)
   115  	conf.UserPW = ""
   116  	pwOld = "opw"
   117  	pwNew = "opwNew"
   118  	cmd = cli.ChangeOwnerPWCommand(outFile, "", &pwOld, &pwNew, conf)
   119  	if _, err := cli.Process(cmd); err != nil {
   120  		t.Fatalf("%s: %s change opw: %v\n", msg, outFile, err)
   121  	}
   122  
   123  	// Decrypt wrong upw
   124  	t.Log("Decrypt wrong upw fails")
   125  	conf = confForAlgorithm(aes, keyLength)
   126  	conf.UserPW = "upwWrong"
   127  	cmd = cli.DecryptCommand(outFile, "", conf)
   128  	if _, err := cli.Process(cmd); err == nil {
   129  		t.Fatalf("%s: %s decrypt using wrong upw should fail\n", msg, outFile)
   130  	}
   131  
   132  	// Decrypt wrong opw succeeds on empty upw
   133  	t.Log("Decrypt wrong opw succeeds on empty upw")
   134  	conf = confForAlgorithm(aes, keyLength)
   135  	conf.OwnerPW = "opwWrong"
   136  	cmd = cli.DecryptCommand(outFile, "", conf)
   137  	if _, err := cli.Process(cmd); err != nil {
   138  		t.Fatalf("%s: %s decrypt wrong opw, empty upw: %v\n", msg, outFile, err)
   139  	}
   140  }
   141  
   142  func ensurePermissionsNone(t *testing.T, listPermOutput []string) {
   143  	t.Helper()
   144  	if len(listPermOutput) == 0 || !strings.HasPrefix(listPermOutput[1], "permission bits: 000000000000") {
   145  		t.Fail()
   146  	}
   147  }
   148  
   149  func ensurePermissionsAll(t *testing.T, listPermOutput []string) {
   150  	t.Helper()
   151  	if len(listPermOutput) == 0 || !strings.HasPrefix(listPermOutput[1], "permission bits: 111100111100") {
   152  		t.Fail()
   153  	}
   154  }
   155  
   156  func testEncryptDecryptUseCase2(t *testing.T, fileName string, aes bool, keyLength int) {
   157  	t.Helper()
   158  	msg := "testEncryptDecryptUseCase2"
   159  
   160  	inFile := filepath.Join(inDir, fileName)
   161  	outFile := filepath.Join(outDir, "test.pdf")
   162  	t.Log(inFile)
   163  
   164  	// Encrypt
   165  	t.Log("Encrypt")
   166  	conf := confForAlgorithm(aes, keyLength)
   167  	conf.UserPW = "upw"
   168  	conf.OwnerPW = "opw"
   169  	cmd := cli.EncryptCommand(inFile, outFile, conf)
   170  	if _, err := cli.Process(cmd); err != nil {
   171  		t.Fatalf("%s: encrypt to %s: %v\n", msg, outFile, err)
   172  	}
   173  
   174  	// Encrypt already encrypted
   175  	t.Log("Encrypt already encrypted")
   176  	conf = confForAlgorithm(aes, keyLength)
   177  	conf.UserPW = "upw"
   178  	conf.OwnerPW = "opw"
   179  	cmd = cli.EncryptCommand(outFile, "", conf)
   180  	if _, err := cli.Process(cmd); err == nil {
   181  		t.Fatalf("%s encrypt encrypted %s\n", msg, outFile)
   182  	}
   183  
   184  	// Validate using wrong owner pw
   185  	t.Log("Validate wrong ownerPW")
   186  	conf = confForAlgorithm(aes, keyLength)
   187  	conf.UserPW = "upw"
   188  	conf.OwnerPW = "opwWrong"
   189  	if err := validateFile(t, outFile, conf); err != nil {
   190  		t.Fatalf("%s: validate %s using wrong ownerPW: %v\n", msg, outFile, err)
   191  	}
   192  
   193  	// Optimize using wrong owner pw
   194  	t.Log("Optimize wrong ownerPW")
   195  	conf = confForAlgorithm(aes, keyLength)
   196  	conf.UserPW = "upw"
   197  	conf.OwnerPW = "opwWrong"
   198  	if err := optimizeFile(t, outFile, conf); err != nil {
   199  		t.Fatalf("%s: optimize %s using wrong ownerPW: %v\n", msg, outFile, err)
   200  	}
   201  
   202  	// Trim using wrong owner pw, falls back to upw and fails with insufficient permissions.
   203  	t.Log("Trim wrong ownerPW, fallback to upw and fail with insufficient permissions.")
   204  	conf = confForAlgorithm(aes, keyLength)
   205  	conf.UserPW = "upw"
   206  	conf.OwnerPW = "opwWrong"
   207  	selectedPages := []string(nil) // writes w/o trimming anything, but sufficient for testing.
   208  	cmd = cli.TrimCommand(outFile, "", selectedPages, conf)
   209  	if _, err := cli.Process(cmd); err == nil {
   210  		t.Fatalf("%s: trim %s using wrong ownerPW should fail: \n", msg, outFile)
   211  	}
   212  
   213  	// Set permissions
   214  	t.Log("Add user access permissions")
   215  	conf = confForAlgorithm(aes, keyLength)
   216  	conf.UserPW = "upw"
   217  	conf.OwnerPW = "opw"
   218  	conf.Permissions = model.PermissionsAll
   219  	cmd = cli.SetPermissionsCommand(outFile, "", conf)
   220  	if _, err := cli.Process(cmd); err != nil {
   221  		t.Fatalf("%s: %s add permissions: %v\n", msg, outFile, err)
   222  	}
   223  
   224  	// List permissions
   225  	conf = model.NewDefaultConfiguration()
   226  	conf.OwnerPW = "opw"
   227  	cmd = cli.ListPermissionsCommand([]string{outFile}, conf)
   228  	list, err := cli.Process(cmd)
   229  	if err != nil {
   230  		t.Fatalf("%s: list permissions for %s: %v\n", msg, outFile, err)
   231  	}
   232  	ensurePermissionsAll(t, list)
   233  
   234  	// Split using wrong owner pw, falls back to upw
   235  	t.Log("Split wrong ownerPW")
   236  	conf = confForAlgorithm(aes, keyLength)
   237  	conf.UserPW = "upw"
   238  	conf.OwnerPW = "opwWrong"
   239  	cmd = cli.SplitCommand(outFile, outDir, 1, conf)
   240  	if _, err := cli.Process(cmd); err != nil {
   241  		t.Fatalf("%s: trim %s using wrong ownerPW falls back to upw: \n", msg, outFile)
   242  	}
   243  
   244  	// Validate
   245  	t.Log("Validate")
   246  	conf = confForAlgorithm(aes, keyLength)
   247  	conf.UserPW = "upw"
   248  	conf.OwnerPW = "opw"
   249  	if err := validateFile(t, outFile, conf); err != nil {
   250  		t.Fatalf("%s: validate %s: %v\n", msg, outFile, err)
   251  	}
   252  
   253  	// ChangeUserPW using wrong userpw
   254  	t.Log("ChangeUserPW wrong userpw")
   255  	conf = confForAlgorithm(aes, keyLength)
   256  	conf.OwnerPW = "opw"
   257  	pwOld := "upwWrong"
   258  	pwNew := "upwNew"
   259  	cmd = cli.ChangeUserPWCommand(outFile, "", &pwOld, &pwNew, conf)
   260  	if _, err := cli.Process(cmd); err == nil {
   261  		t.Fatalf("%s: %s change userPW using wrong userPW should fail:\n", msg, outFile)
   262  	}
   263  
   264  	// ChangeUserPW
   265  	t.Log("ChangeUserPW")
   266  	conf = confForAlgorithm(aes, keyLength)
   267  	conf.OwnerPW = "opw"
   268  	pwOld = "upw"
   269  	pwNew = "upwNew"
   270  	cmd = cli.ChangeUserPWCommand(outFile, "", &pwOld, &pwNew, conf)
   271  	if _, err := cli.Process(cmd); err != nil {
   272  		t.Fatalf("%s: %s change upw: %v\n", msg, outFile, err)
   273  	}
   274  
   275  	// ChangeOwnerPW
   276  	t.Log("ChangeOwnerPW")
   277  	conf = confForAlgorithm(aes, keyLength)
   278  	conf.UserPW = "upwNew"
   279  	pwOld = "opw"
   280  	pwNew = "opwNew"
   281  	cmd = cli.ChangeOwnerPWCommand(outFile, "", &pwOld, &pwNew, conf)
   282  	if _, err := cli.Process(cmd); err != nil {
   283  		t.Fatalf("%s: %s change opw: %v\n", msg, outFile, err)
   284  	}
   285  
   286  	// Decrypt using wrong pw
   287  	t.Log("\nDecrypt using wrong pw")
   288  	conf = confForAlgorithm(aes, keyLength)
   289  	conf.UserPW = "upwWrong"
   290  	conf.OwnerPW = "opwWrong"
   291  	cmd = cli.DecryptCommand(outFile, "", conf)
   292  	if _, err := cli.Process(cmd); err == nil {
   293  		t.Fatalf("%s: decrypt using wrong pw %s\n", msg, outFile)
   294  	}
   295  
   296  	// Decrypt
   297  	t.Log("\nDecrypt")
   298  	conf = confForAlgorithm(aes, keyLength)
   299  	conf.UserPW = "upwNew"
   300  	conf.OwnerPW = "opwNew"
   301  	cmd = cli.DecryptCommand(outFile, "", conf)
   302  	if _, err := cli.Process(cmd); err != nil {
   303  		t.Fatalf("%s: decrypt %s: %v\n", msg, outFile, err)
   304  	}
   305  }
   306  
   307  func testEncryptDecryptUseCase3(t *testing.T, fileName string, aes bool, keyLength int) {
   308  	// Test for setting only the owner password.
   309  	t.Helper()
   310  	msg := "testEncryptDecryptUseCase3"
   311  
   312  	inFile := filepath.Join(inDir, fileName)
   313  	outFile := filepath.Join(outDir, "test.pdf")
   314  	t.Log(inFile)
   315  
   316  	// Encrypt opw only
   317  	t.Log("Encrypt opw only")
   318  	conf := confForAlgorithm(aes, keyLength)
   319  	conf.OwnerPW = "opw"
   320  	cmd := cli.EncryptCommand(inFile, outFile, conf)
   321  	if _, err := cli.Process(cmd); err != nil {
   322  		t.Fatalf("%s: encrypt with opw only to to %s: %v\n", msg, outFile, err)
   323  	}
   324  
   325  	// Validate wrong opw succeeds with fallback to empty upw
   326  	t.Log("Validate wrong opw succeeds with fallback to empty upw")
   327  	conf = confForAlgorithm(aes, keyLength)
   328  	conf.OwnerPW = "opwWrong"
   329  	if err := validateFile(t, outFile, conf); err != nil {
   330  		t.Fatalf("%s: validate %s using wrong opw succeeds falling back to empty upw: %v\n", msg, outFile, err)
   331  	}
   332  
   333  	// Validate opw
   334  	t.Log("Validate opw")
   335  	conf = confForAlgorithm(aes, keyLength)
   336  	conf.OwnerPW = "opw"
   337  	if err := validateFile(t, outFile, conf); err != nil {
   338  		t.Fatalf("%s: validate %s using opw: %v\n", msg, outFile, err)
   339  	}
   340  
   341  	// Validate wrong upw
   342  	t.Log("Validate wrong upw fails")
   343  	conf = confForAlgorithm(aes, keyLength)
   344  	conf.UserPW = "upwWrong"
   345  	if err := validateFile(t, outFile, conf); err == nil {
   346  		t.Fatalf("%s: validate %s using wrong upw should fail!\n", msg, outFile)
   347  	}
   348  
   349  	// Validate no pw using empty upw
   350  	t.Log("Validate no pw using empty upw")
   351  	conf = confForAlgorithm(aes, keyLength)
   352  	if err := validateFile(t, outFile, conf); err != nil {
   353  		t.Fatalf("%s validate %s no pw using empty upw: %v\n", msg, outFile, err)
   354  	}
   355  
   356  	// Optimize wrong opw, succeeds with fallback to empty upw
   357  	t.Log("Optimize wrong opw succeeds with fallback to empty upw")
   358  	conf = confForAlgorithm(aes, keyLength)
   359  	conf.OwnerPW = "opwWrong"
   360  	if err := optimizeFile(t, outFile, conf); err != nil {
   361  		t.Fatalf("%s: optimize %s using wrong opw succeeds falling back to empty upw: %v\n", msg, outFile, err)
   362  	}
   363  
   364  	// Optimize opw
   365  	t.Log("Optimize opw")
   366  	conf = confForAlgorithm(aes, keyLength)
   367  	conf.OwnerPW = "opw"
   368  	if err := optimizeFile(t, outFile, conf); err != nil {
   369  		t.Fatalf("%s: optimize %s using opw: %v\n", msg, outFile, err)
   370  	}
   371  
   372  	// Optimize wrong upw
   373  	t.Log("Optimize wrong upw fails")
   374  	conf = confForAlgorithm(aes, keyLength)
   375  	conf.UserPW = "upwWrong"
   376  	if err := optimizeFile(t, outFile, conf); err == nil {
   377  		t.Fatalf("%s: optimize %s using wrong upw should fail!\n", msg, outFile)
   378  	}
   379  
   380  	// Optimize empty upw
   381  	t.Log("Optimize empty upw")
   382  	conf = confForAlgorithm(aes, keyLength)
   383  	conf.UserPW = ""
   384  	if err := optimizeFile(t, outFile, conf); err != nil {
   385  		t.Fatalf("TestEncrypt%s: optimize %s using upw: %v\n", msg, outFile, err)
   386  	}
   387  
   388  	// Change opw wrong upw
   389  	t.Log("ChangeOwnerPW wrong upw fails")
   390  	conf = confForAlgorithm(aes, keyLength)
   391  	conf.UserPW = "upw"
   392  	pwOld := "opw"
   393  	pwNew := "opwNew"
   394  	cmd = cli.ChangeOwnerPWCommand(outFile, "", &pwOld, &pwNew, conf)
   395  	if _, err := cli.Process(cmd); err == nil {
   396  		t.Fatalf("%s: %s change opw using wrong upw should fail\n", msg, outFile)
   397  	}
   398  
   399  	// Change opw wrong opwOld
   400  	t.Log("ChangeOwnerPW wrong opwOld fails")
   401  	conf = confForAlgorithm(aes, keyLength)
   402  	conf.UserPW = ""
   403  	pwOld = "opwOldWrong"
   404  	pwNew = "opwNew"
   405  	cmd = cli.ChangeOwnerPWCommand(outFile, "", &pwOld, &pwNew, conf)
   406  	if _, err := cli.Process(cmd); err == nil {
   407  		t.Fatalf("%s: %s change opw using wrong upwOld should fail\n", msg, outFile)
   408  	}
   409  
   410  	// Change opw
   411  	t.Log("ChangeOwnerPW")
   412  	conf = confForAlgorithm(aes, keyLength)
   413  	conf.UserPW = ""
   414  	pwOld = "opw"
   415  	pwNew = "opwNew"
   416  	cmd = cli.ChangeOwnerPWCommand(outFile, "", &pwOld, &pwNew, conf)
   417  	if _, err := cli.Process(cmd); err != nil {
   418  		t.Fatalf("%s: %s change opw: %v\n", msg, outFile, err)
   419  	}
   420  
   421  	// Decrypt wrong upw
   422  	t.Log("Decrypt wrong upw fails")
   423  	conf = confForAlgorithm(aes, keyLength)
   424  	conf.UserPW = "upwWrong"
   425  	cmd = cli.DecryptCommand(outFile, "", conf)
   426  	if _, err := cli.Process(cmd); err == nil {
   427  		t.Fatalf("%s: %s decrypt using wrong upw should fail \n", msg, outFile)
   428  	}
   429  
   430  	// Decrypt wrong opw succeeds because of fallback to empty upw.
   431  	t.Log("Decrypt wrong opw succeeds because of fallback to empty upw")
   432  	conf = confForAlgorithm(aes, keyLength)
   433  	conf.OwnerPW = "opw"
   434  	cmd = cli.DecryptCommand(outFile, outFile, conf)
   435  	if _, err := cli.Process(cmd); err != nil {
   436  		t.Fatalf("%s: %s decrypt using opw: %v\n", msg, outFile, err)
   437  	}
   438  }
   439  
   440  func testPermissionsOPWOnly(t *testing.T, fileName string, aes bool, keyLength int) {
   441  	t.Helper()
   442  	msg := "TestPermissionsOPWOnly"
   443  
   444  	inFile := filepath.Join(inDir, fileName)
   445  	outFile := filepath.Join(outDir, "test.pdf")
   446  	t.Log(inFile)
   447  
   448  	cmd := cli.ListPermissionsCommand([]string{inFile}, nil)
   449  	list, err := cli.Process(cmd)
   450  	if err != nil {
   451  		t.Fatalf("%s: list permissions %s: %v\n", msg, inFile, err)
   452  	}
   453  	if len(list) == 0 || list[1] != "Full access" {
   454  		t.Fail()
   455  	}
   456  
   457  	conf := confForAlgorithm(aes, keyLength)
   458  	conf.OwnerPW = "opw"
   459  	cmd = cli.EncryptCommand(inFile, outFile, conf)
   460  	if _, err := cli.Process(cmd); err != nil {
   461  		t.Fatalf("%s: encrypt %s: %v\n", msg, outFile, err)
   462  	}
   463  
   464  	cmd = cli.ListPermissionsCommand([]string{outFile}, nil)
   465  	if list, err = cli.Process(cmd); err != nil {
   466  		t.Fatalf("%s: list permissions %s: %v\n", msg, outFile, err)
   467  	}
   468  	ensurePermissionsNone(t, list)
   469  
   470  	conf = confForAlgorithm(aes, keyLength)
   471  	conf.OwnerPW = "opw"
   472  	conf.Permissions = model.PermissionsAll
   473  	cmd = cli.SetPermissionsCommand(outFile, "", conf)
   474  	if _, err = cli.Process(cmd); err != nil {
   475  		t.Fatalf("%s: set all permissions for %s: %v\n", msg, outFile, err)
   476  	}
   477  
   478  	cmd = cli.ListPermissionsCommand([]string{outFile}, nil)
   479  	if list, err = cli.Process(cmd); err != nil {
   480  		t.Fatalf("%s: list permissions for %s: %v\n", msg, outFile, err)
   481  	}
   482  	ensurePermissionsAll(t, list)
   483  
   484  	conf = confForAlgorithm(aes, keyLength)
   485  	conf.Permissions = model.PermissionsNone
   486  	cmd = cli.SetPermissionsCommand(outFile, "", conf)
   487  	if _, err = cli.Process(cmd); err == nil {
   488  		t.Fatalf("%s: clear all permissions w/o opw for %s\n", msg, outFile)
   489  	}
   490  
   491  	conf = confForAlgorithm(aes, keyLength)
   492  	conf.OwnerPW = "opw"
   493  	conf.Permissions = model.PermissionsNone
   494  	cmd = cli.SetPermissionsCommand(outFile, "", conf)
   495  	if _, err = cli.Process(cmd); err != nil {
   496  		t.Fatalf("%s: clear all permissions for %s: %v\n", msg, outFile, err)
   497  	}
   498  }
   499  
   500  func testPermissions(t *testing.T, fileName string, aes bool, keyLength int) {
   501  	t.Helper()
   502  	msg := "TestPermissions"
   503  
   504  	inFile := filepath.Join(inDir, fileName)
   505  	outFile := filepath.Join(outDir, "test.pdf")
   506  	t.Log(inFile)
   507  
   508  	cmd := cli.ListPermissionsCommand([]string{inFile}, nil)
   509  	list, err := cli.Process(cmd)
   510  	if err != nil {
   511  		t.Fatalf("%s: list permissions %s: %v\n", msg, inFile, err)
   512  	}
   513  	if len(list) == 0 || list[1] != "Full access" {
   514  		t.Fail()
   515  	}
   516  
   517  	conf := confForAlgorithm(aes, keyLength)
   518  	conf.UserPW = "upw"
   519  	conf.OwnerPW = "opw"
   520  	cmd = cli.EncryptCommand(inFile, outFile, conf)
   521  	if _, err := cli.Process(cmd); err != nil {
   522  		t.Fatalf("%s: encrypt %s: %v\n", msg, outFile, err)
   523  	}
   524  
   525  	cmd = cli.ListPermissionsCommand([]string{outFile}, nil)
   526  	if _, err = cli.Process(cmd); err == nil {
   527  		t.Fatalf("%s: list permissions w/o pw %s\n", msg, outFile)
   528  	}
   529  
   530  	conf = confForAlgorithm(aes, keyLength)
   531  	conf.UserPW = "upw"
   532  	cmd = cli.ListPermissionsCommand([]string{outFile}, conf)
   533  	if list, err = cli.Process(cmd); err != nil {
   534  		t.Fatalf("%s: list permissions %s: %v\n", msg, outFile, err)
   535  	}
   536  	ensurePermissionsNone(t, list)
   537  
   538  	conf = model.NewDefaultConfiguration()
   539  	conf.OwnerPW = "opw"
   540  	cmd = cli.ListPermissionsCommand([]string{outFile}, conf)
   541  	if list, err = cli.Process(cmd); err != nil {
   542  		t.Fatalf("%s: list permissions %s: %v\n", msg, outFile, err)
   543  	}
   544  	ensurePermissionsNone(t, list)
   545  
   546  	conf = confForAlgorithm(aes, keyLength)
   547  	conf.Permissions = model.PermissionsAll
   548  	cmd = cli.SetPermissionsCommand(outFile, "", conf)
   549  	if _, err = cli.Process(cmd); err == nil {
   550  		t.Fatalf("%s: set all permissions w/o pw for %s\n", msg, outFile)
   551  	}
   552  
   553  	conf = confForAlgorithm(aes, keyLength)
   554  	conf.UserPW = "upw"
   555  	conf.Permissions = model.PermissionsAll
   556  	cmd = cli.SetPermissionsCommand(outFile, "", conf)
   557  	if _, err = cli.Process(cmd); err == nil {
   558  		t.Fatalf("%s: set all permissions w/o opw for %s\n", msg, outFile)
   559  	}
   560  
   561  	conf = confForAlgorithm(aes, keyLength)
   562  	conf.OwnerPW = "opw"
   563  	conf.Permissions = model.PermissionsAll
   564  	cmd = cli.SetPermissionsCommand(outFile, "", conf)
   565  	if _, err = cli.Process(cmd); err == nil {
   566  		t.Fatalf("%s: set all permissions w/o both pws for %s\n", msg, outFile)
   567  	}
   568  
   569  	conf = confForAlgorithm(aes, keyLength)
   570  	conf.OwnerPW = "opw"
   571  	conf.UserPW = "upw"
   572  	conf.Permissions = model.PermissionsAll
   573  	cmd = cli.SetPermissionsCommand(outFile, "", conf)
   574  	if _, err = cli.Process(cmd); err != nil {
   575  		t.Fatalf("%s: set all permissions for %s: %v\n", msg, outFile, err)
   576  	}
   577  
   578  	cmd = cli.ListPermissionsCommand([]string{outFile}, nil)
   579  	if _, err = cli.Process(cmd); err == nil {
   580  		t.Fatalf("%s: list permissions w/o pw %s\n", msg, outFile)
   581  	}
   582  
   583  	conf = confForAlgorithm(aes, keyLength)
   584  	conf.OwnerPW = "opw"
   585  	cmd = cli.ListPermissionsCommand([]string{outFile}, conf)
   586  	if list, err = cli.Process(cmd); err != nil {
   587  		t.Fatalf("%s: list permissions for %s: %v\n", msg, outFile, err)
   588  	}
   589  	ensurePermissionsAll(t, list)
   590  }
   591  
   592  func testEncryptDecryptFile(t *testing.T, fileName string, mode string, keyLength int) {
   593  	t.Helper()
   594  	testEncryptDecryptUseCase1(t, fileName, mode == "aes", keyLength)
   595  	testEncryptDecryptUseCase2(t, fileName, mode == "aes", keyLength)
   596  	testEncryptDecryptUseCase3(t, fileName, mode == "aes", keyLength)
   597  	testPermissionsOPWOnly(t, fileName, mode == "aes", keyLength)
   598  	testPermissions(t, fileName, mode == "aes", keyLength)
   599  }
   600  
   601  func TestEncryptDecrypt(t *testing.T) {
   602  	for _, fileName := range []string{
   603  		"5116.DCT_Filter.pdf",
   604  		"adobe_errata.pdf",
   605  	} {
   606  		testEncryptDecryptFile(t, fileName, "rc4", 40)
   607  		testEncryptDecryptFile(t, fileName, "rc4", 128)
   608  		testEncryptDecryptFile(t, fileName, "aes", 40)
   609  		testEncryptDecryptFile(t, fileName, "aes", 128)
   610  		testEncryptDecryptFile(t, fileName, "aes", 256)
   611  	}
   612  }