7 class DecryptError (Exception):
10 class Crypto (object):
11 def __init__(me
, c
, h
, m
, ck
, mk
):
16 if me
.c
.__class__
.blksz
:
17 iv
= _C
.rand
.block(me
.c
.__class__
.blksz
)
21 y
= iv
+ me
.c
.encrypt(pt
)
22 t
= me
.m().hash(y
).done()
25 t
= ct
[:me
.m
.__class__
.tagsz
]
26 y
= ct
[me
.m
.__class__
.tagsz
:]
27 if t
!= me
.m().hash(y
).done():
29 iv
= y
[:me
.c
.__class__
.blksz
]
30 if me
.c
.__class__
.blksz
: me
.c
.setiv(iv
)
31 return me
.c
.decrypt(y
[me
.c
.__class__
.blksz
:])
34 def __init__(me
, pp
, c
, h
, m
, salt
= None):
35 if not salt
: salt
= _C
.rand
.block(h
.hashsz
)
36 tag
= '%s\0%s' %
(pp
, salt
)
37 Crypto
.__init__(me
, c
, h
, m
,
38 h().hash('cipher:' + tag
).done(),
39 h().hash('mac:' + tag
).done())
42 class Buffer (object):
48 if n
+ i
> len(me
.str):
49 raise IndexError, 'buffer underflow'
51 return me
.str[i
:i
+ n
]
55 return _S
.unpack(fmt
, me
.get(_S
.calcsize(fmt
)))
57 return me
.get(me
.unpack('>H')[0])
59 if me
.i
!= len(me
.str):
60 raise ValueError, 'junk at end of buffer'
63 return _S
.pack('>H', len(s
)) + s
65 class PWIter (object):
68 me
.k
= me
.pw
.db
.firstkey()
76 k
= me
.pw
.db
.nextkey(k
)
77 me
.k
= me
.pw
.db
.nextkey(k
)
78 return me
.pw
.unpack(me
.pw
.db
[k
])[0]
80 def __init__(me
, file, mode
= 'r'):
81 me
.db
= _G
.open(file, mode
)
82 c
= _C
.gcciphers
[me
.db
['cipher']]
83 h
= _C
.gchashes
[me
.db
['hash']]
84 m
= _C
.gcmacs
[me
.db
['mac']]
86 ppk
= PPK(_C
.ppread(tag
), c
, h
, m
, me
.db
['salt'])
88 buf
= Buffer(ppk
.decrypt(me
.db
['key']))
92 me
.ck
= buf
.getstring()
93 me
.mk
= buf
.getstring()
95 me
.k
= Crypto(c
, h
, m
, me
.ck
, me
.mk
)
96 me
.magic
= me
.k
.decrypt(me
.db
['magic'])
97 def keyxform(me
, key
):
98 return '$' + me
.k
.h().hash(me
.magic
).hash(key
).done()
102 ppk
= PPK(_C
.ppread(tag
, _C
.PMODE_VERIFY
),
103 me
.k
.c
.__class__
, me
.k
.h
, me
.k
.m
.__class__
)
104 me
.db
['key'] = ppk
.encrypt(_wrapstr(me
.ck
) + _wrapstr(me
.mk
))
105 me
.db
['salt'] = ppk
.salt
106 def pack(me
, key
, value
):
107 w
= _wrapstr(key
) + _wrapstr(value
)
108 pl
= (len(w
) + 255) & ~
255
109 w
+= '\0' * (pl
- len(w
))
110 return me
.k
.encrypt(w
)
112 buf
= Buffer(me
.k
.decrypt(p
))
113 key
= buf
.getstring()
114 value
= buf
.getstring()
116 def __getitem__(me
, key
):
117 return me
.unpack(me
.db
[me
.keyxform(key
)])[1]
118 def __setitem__(me
, key
, value
):
119 me
.db
[me
.keyxform(key
)] = me
.pack(key
, value
)
120 def __delitem__(me
, key
):
121 del me
.db
[me
.keyxform(key
)]