3
import os, commands, re, time
6
# emit test case files into test-cases/*
9
# 1: owner1 <user@test>
10
# 2: owner2 <user@test>
11
# 3: other <other@test>
14
homedir = "gpg-keys/full-rings"
15
testcasedir = "gpg-testcases"
16
users = ("owner1", "owner2", "other", "unknown", "trusted", "untrusted")
19
# now what keyid did it get?
20
cmd = "gpg --homedir %s --with-colons --fingerprint %s" % (homedir,name)
21
(s,out) = commands.getstatusoutput(cmd)
23
r = re.search(r'^fpr:::::::::(\w+):',out, re.M)
25
print "problem, out '%s'" % out
27
id = r.group(1) # long form
30
class Encrypt(GnuPGInterface.GnuPG):
32
GnuPGInterface.GnuPG.__init__(self)
33
self.setup_my_options()
35
def setup_my_options(self):
36
self.options.armor = 1
37
self.options.meta_interactive = 0
38
self.options.extra_args.append('--no-secmem-warning')
39
self.options.homedir = homedir
41
def encrypt_string(self, string, recipients):
42
self.options.recipients = recipients # a list!
43
proc = self.run(['--encrypt'], create_fhs=['stdin', 'stdout'])
44
proc.handles['stdin'].write(string)
45
proc.handles['stdin'].close()
46
output = proc.handles['stdout'].read()
47
proc.handles['stdout'].close()
51
def signencrypt_string(self, string, signer, passphrase, recipients):
52
self.options.recipients = recipients # a list!
53
self.options.default_key = signer
54
self.passphrase = passphrase
55
proc = self.run(['--sign', '--encrypt'],
56
create_fhs=['stdin', 'stdout'])
57
proc.handles['stdin'].write(string)
58
proc.handles['stdin'].close()
59
output = proc.handles['stdout'].read()
60
proc.handles['stdout'].close()
64
def sign_string(self, string, signer, passphrase):
65
self.options.recipients = []
66
self.options.default_key = signer
67
self.passphrase = passphrase
68
proc = self.run(['--sign'],
69
create_fhs=['stdin', 'stdout'])
70
proc.handles['stdin'].write(string)
71
proc.handles['stdin'].close()
72
output = proc.handles['stdout'].read()
73
proc.handles['stdout'].close()
77
def sym_string(self, string, passphrase):
78
self.options.recipients = []
79
self.passphrase = passphrase
80
proc = self.run(['--symmetric'],
81
create_fhs=['stdin', 'stdout'])
82
proc.handles['stdin'].write(string)
83
proc.handles['stdin'].close()
84
output = proc.handles['stdout'].read()
85
proc.handles['stdout'].close()
89
def armor_string(self, string):
90
self.options.recipients = []
91
proc = self.run(['--enarmor'],
92
create_fhs=['stdin', 'stdout'])
93
proc.handles['stdin'].write(string)
94
proc.handles['stdin'].close()
95
output = proc.handles['stdout'].read()
96
proc.handles['stdout'].close()
100
def clearsign_string(self, string, signer, passphrase):
101
self.options.recipients = []
102
self.options.default_key = signer
103
self.passphrase = passphrase
104
proc = self.run(['--clearsign'],
105
create_fhs=['stdin', 'stdout'])
106
proc.handles['stdin'].write(string)
107
proc.handles['stdin'].close()
108
output = proc.handles['stdout'].read()
109
proc.handles['stdout'].close()
113
def emit_alist(f, d):
119
f.write("(%s . nil)\n" % (k))
121
f.write("(%s . \"%s\")\n" % (k, d[k]))
124
encryptor = Encrypt()
125
def encrypt(to, plaintext):
126
return encryptor.encrypt_string(plaintext, [to])
127
def signencrypt(to, signer, plaintext):
128
return encryptor.signencrypt_string(plaintext, signer, signer, [to])
129
def sign(signer, plaintext):
130
return encryptor.sign_string(plaintext, signer, signer)
131
def sym(passphrase, plaintext):
132
return encryptor.sym_string(plaintext, passphrase)
133
def armor(plaintext):
134
# note: this isn't very useful, you must use 'gpg --dearmor' to
135
# extract the result, not --decrypt. It also has a different banner.
136
return encryptor.armor_string(plaintext)
137
def clearsign(signer, plaintext):
138
return encryptor.clearsign_string(plaintext, signer, signer)
140
#def encrypt(to, plaintext):
141
#cmd = "gpg --armor --homedir %s --recipient %s --batch --encrypt" % (homedir, to)
142
#(stdout,stdin) = popen2.popen2(cmd)
143
#stdin.write(plaintext)
145
#crypttext = stdout.read()
149
def __init__(self, filename):
150
self.filename = filename
151
self.plaintext = self.make_plaintext()
153
self.d['name'] = self.filename
154
self.d['plaintext'] = self.plaintext
155
self.d['error'] = None
156
self.d['signature_status'] = None
158
def make_plaintext(self):
159
return "This is a plaintext message\n"
160
def date_string(self):
161
# mc-gpg.el takes the YYYY-MM-DD date string from the SIG_ID
162
# status-fs line and delivers it to the user. This appears to be the
163
# GMT date of the signature. Extract the same thing here so we can
164
# tell the test harness what to expect. This needs to run on the
165
# same day as the gpg invocation used to create the signature, but
166
# this whole program only takes a few seconds to execute.
167
return time.strftime("%Y-%m-%d", time.gmtime()) # GMT
169
def encrypted_fields(self, recip):
170
# run this after signed_fields so [signature_status] gets cleared
171
self.d['encryption_id'] = "0x%s" % id[recip][-16:]
172
self.d['passphrase'] = recip
173
if recip == "other" or recip == "unknown":
174
self.d['error'] = "This message is not addressed to you"
175
self.d['plaintext'] = None
176
self.d['signature_status'] = None
178
def symencrypted_fields(self):
179
self.d['encryption_id'] = "***** CONVENTIONAL *****"
180
self.d['passphrase'] = self.passphrase
182
def signed_fields(self, signer):
183
self.d['signature_status'] = ("Good signature from '%s <%s@test>' " + \
184
"TRUST_%s made %s") % \
186
trustmap[signer], self.date_string())
187
if signer == "unknown":
188
self.d['signature_status'] = "cannot check signature " + \
191
# comes from 'cannot check signature' warning
192
def process(self, testcasedir):
193
self.make_crypttext()
194
f = open(os.path.join(testcasedir, self.filename), "w")
195
emit_alist(f, self.d)
199
class E_Case(TestCase):
200
def __init__(self, filename, recip):
201
TestCase.__init__(self, filename)
203
self.encrypted_fields(recip)
204
def make_crypttext(self):
205
self.d['crypttext'] = "\n" + encrypt(self.recip, self.plaintext)
207
class ES_Case(TestCase):
208
def __init__(self, filename, recip, signer):
209
TestCase.__init__(self, filename)
212
self.signed_fields(signer)
213
self.encrypted_fields(recip)
214
def make_crypttext(self):
215
self.d['crypttext'] = "\n" + signencrypt(self.recip,
219
class S_Case(TestCase):
220
def __init__(self, filename, signer):
221
TestCase.__init__(self, filename)
223
self.signed_fields(signer)
224
def make_crypttext(self):
225
self.d['crypttext'] = "\n" + sign(self.signer, self.plaintext)
227
class CS_Case(TestCase):
228
def __init__(self, filename, signer):
229
TestCase.__init__(self, filename)
231
self.signed_fields(signer)
232
def make_crypttext(self):
233
self.d['crypttext'] = "\n" + clearsign(self.signer, self.plaintext)
235
class SYM_Case(TestCase):
236
def __init__(self, filename, passphrase):
237
TestCase.__init__(self, filename)
238
self.passphrase = passphrase
239
self.symencrypted_fields()
240
def make_crypttext(self):
241
self.d['crypttext'] = "\n" + sym(self.passphrase, self.plaintext)
245
E_Case("E.e1r", "owner1").process(d)
246
E_Case("E.e2r", "owner2").process(d)
247
E_Case("E.e3", "other").process(d)
248
E_Case("E.e4", "unknown").process(d)
249
ES_Case("ES.e1r.s1v", "owner1", "owner1").process(d)
250
ES_Case("ES.e1r.s2v", "owner1", "trusted").process(d)
251
ES_Case("ES.e1r.s3v", "owner1", "untrusted").process(d)
252
ES_Case("ES.e1r.s4", "owner1", "unknown").process(d)
253
ES_Case("ES.e3.s1v", "other", "owner1").process(d)
254
ES_Case("ES.e4.s1v", "unknown", "owner1").process(d)
255
S_Case("S.s1v", "owner1").process(d)
256
S_Case("S.s2v", "trusted").process(d)
257
S_Case("S.s3v", "untrusted").process(d)
258
S_Case("S.s4", "unknown").process(d)
259
SYM_Case("SE", "password").process(d)
260
CS_Case("CS.s1v", "owner1").process(d)
261
CS_Case("CS.s2v", "trusted").process(d)
262
CS_Case("CS.s3v", "untrusted").process(d)
263
CS_Case("CS.s4", "unknown").process(d)
271
'owner1': "ULTIMATE",
272
'owner2': "ULTIMATE",
275
'trusted': "MARGINAL",
276
'untrusted': "UNDEFINED",
279
if __name__ == "__main__":
280
if not os.path.isdir(testcasedir):
281
os.mkdir(testcasedir)
286
# hardcoded date in es()
287
# cs(): corrupt the signatures by editing the crypttext after signing