1
16
17
18
19
20 package gofpdf
21
22 import (
23 "crypto/md5"
24 "crypto/rc4"
25 "encoding/binary"
26 "math/rand"
27 )
28
29
30 const (
31 CnProtectPrint = 4
32 CnProtectModify = 8
33 CnProtectCopy = 16
34 CnProtectAnnotForms = 32
35 )
36
37 type protectType struct {
38 encrypted bool
39 uValue []byte
40 oValue []byte
41 pValue int
42 padding []byte
43 encryptionKey []byte
44 objNum int
45 rc4cipher *rc4.Cipher
46 rc4n uint32
47 }
48
49 func (p *protectType) rc4(n uint32, buf *[]byte) {
50 if p.rc4cipher == nil || p.rc4n != n {
51 p.rc4cipher, _ = rc4.NewCipher(p.objectKey(n))
52 p.rc4n = n
53 }
54 p.rc4cipher.XORKeyStream(*buf, *buf)
55 }
56
57 func (p *protectType) objectKey(n uint32) []byte {
58 var nbuf, b []byte
59 nbuf = make([]byte, 8, 8)
60 binary.LittleEndian.PutUint32(nbuf, n)
61 b = append(b, p.encryptionKey...)
62 b = append(b, nbuf[0], nbuf[1], nbuf[2], 0, 0)
63 s := md5.Sum(b)
64 return s[0:10]
65 }
66
67 func oValueGen(userPass, ownerPass []byte) (v []byte) {
68 var c *rc4.Cipher
69 tmp := md5.Sum(ownerPass)
70 c, _ = rc4.NewCipher(tmp[0:5])
71 size := len(userPass)
72 v = make([]byte, size, size)
73 c.XORKeyStream(v, userPass)
74 return
75 }
76
77 func (p *protectType) uValueGen() (v []byte) {
78 var c *rc4.Cipher
79 c, _ = rc4.NewCipher(p.encryptionKey)
80 size := len(p.padding)
81 v = make([]byte, size, size)
82 c.XORKeyStream(v, p.padding)
83 return
84 }
85
86 func (p *protectType) setProtection(privFlag byte, userPassStr, ownerPassStr string) {
87 privFlag = 192 | (privFlag & (CnProtectCopy | CnProtectModify | CnProtectPrint | CnProtectAnnotForms))
88 p.padding = []byte{
89 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41,
90 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
91 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80,
92 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A,
93 }
94 userPass := []byte(userPassStr)
95 var ownerPass []byte
96 if ownerPassStr == "" {
97 ownerPass = make([]byte, 8, 8)
98 binary.LittleEndian.PutUint64(ownerPass, uint64(rand.Int63()))
99 } else {
100 ownerPass = []byte(ownerPassStr)
101 }
102 userPass = append(userPass, p.padding...)[0:32]
103 ownerPass = append(ownerPass, p.padding...)[0:32]
104 p.encrypted = true
105 p.oValue = oValueGen(userPass, ownerPass)
106 var buf []byte
107 buf = append(buf, userPass...)
108 buf = append(buf, p.oValue...)
109 buf = append(buf, privFlag, 0xff, 0xff, 0xff)
110 sum := md5.Sum(buf)
111 p.encryptionKey = sum[0:5]
112 p.uValue = p.uValueGen()
113 p.pValue = -(int(privFlag^255) + 1)
114 }
115
View as plain text