1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/* Copyright 2013, Sebastian Reichel <sre@ring0.de>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
[DBus (name = "io.mainframe.shopsystem.PGP")]
public class PGPKeyArchive {
private string keyring;
private GPG.Context gpg;
public PGPKeyArchive(string keyring) {
/* check version (important!) */
GPG.check_version();
/* initialize default context */
GPG.Context.Context(out gpg);
/* TODO TODO TODO */
#if 0
if(keyring.has_prefix("\"") && keyring.has_suffix("\""))
this.keyring = keyring.substring(1,keyring.length-2);
#endif
this.keyring = keyring;
/* TODO: check existence of keyring */
/* set home directory */
var info = gpg.get_engine_info();
gpg.set_engine_info(info.protocol, info.file_name, keyring);
/* enable ascii armor */
gpg.set_armor(true);
}
public string[] import_archive(uint8[] data) throws DBusError, IOError {
string[] result = {};
unowned Archive.Entry entry;
var archive = new Archive.Read();
/* support all formats & compression types */
archive.support_compression_all();
archive.support_format_all();
/* load test archive for now */
if(archive.open_memory(data, data.length) != Archive.Result.OK)
return result;
while(archive.next_header(out entry) == Archive.Result.OK) {
var name = entry.pathname();
var size = entry.size();
var content = new uint8[size];
/* skip entries, which contain a slash */
if(name.contains("/"))
continue;
/* skip files, which are big (probably not a minimal pgp key) */
if(size > 50000)
continue;
if(archive.read_data((void*) content, (ssize_t) size) == size) {
if(!((string) content).has_prefix("-----BEGIN PGP PUBLIC KEY BLOCK-----"))
continue;
/* put byte data into GPG.Data object */
GPG.Data gpgdata;
GPG.Data.create_from_memory(out gpgdata, content, false);
/* import keys */
gpg.op_import(gpgdata);
/* get result */
unowned GPG.ImportResult importresult = gpg.op_import_result();
/* add imported fingerprints to result */
for(unowned GPG.ImportStatus st = importresult.imports; st != null; st = st.next) {
if(!(st.fpr in result) && (st.status & GPG.ImportStatusFlags.NEW) != 0)
result += st.fpr;
}
}
}
return result;
}
public string[] list_keys() throws DBusError, IOError {
string[] result = {};
GPG.Key key;
gpg.op_keylist_start();
while(gpg.op_keylist_next(out key) == GPGError.ErrorCode.NO_ERROR) {
result += key.subkeys[0].fpr;
}
gpg.op_keylist_end();
return result;
}
public string get_key(string fingerprint) throws DBusError, IOError {
GPG.Data keydata;
GPG.Data.create(out keydata);
if(gpg.op_export(fingerprint, 0, keydata) == GPGError.ErrorCode.NO_ERROR) {
long size = keydata.seek(0, Posix.FILE.SEEK_END);
keydata.seek(0, Posix.FILE.SEEK_SET);
stdout.printf("size: %ld\n", size);
uint8[] data = new uint8[size];
keydata.read(data);
return (string) data;
} else {
stdout.printf("error!\n");
return "";
}
}
}
|