/[winpt]/trunk/Src/wptKeyEdit.cpp
ViewVC logotype

Contents of /trunk/Src/wptKeyEdit.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 328 - (show annotations)
Fri Sep 25 16:07:38 2009 UTC (15 years, 5 months ago) by twoaday
File size: 22301 byte(s)


1 /* wptKeyEdit.cpp - GPG key edit abstraction
2 * Copyright (C) 2005, 2006 Timo Schulz
3 * Copyright (C) 2005 g10 Code GmbH
4 *
5 * This file is part of WinPT.
6 *
7 * WinPT is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * WinPT is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with WinPT; if not, write to the Free Software Foundation,
19 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <windows.h>
27 #include <time.h>
28
29 #include "gpgme.h"
30 #include "wptCommonCtl.h"
31 #include "wptContext.h"
32 #include "wptKeyEdit.h"
33 #include "wptTypes.h"
34 #include "wptW32API.h"
35 #include "wptGPG.h"
36 #include "wptErrors.h"
37 #include "wptUTF8.h"
38
39
40 /* Parse the colon status information of @line and store
41 the information in @rev.
42 Return value: 0 on success. */
43 static gpgme_error_t
44 rev_key_colon_handler (gpg_desig_rev_t *rev, char *line)
45 {
46 char *p, *pend;
47 gpg_desig_rev_t r, t;
48 int field = 0;
49
50 if (!line || strlen (line) < 3)
51 return gpg_error (GPG_ERR_EOF);
52 if (strncmp (line, "rvk", 3))
53 return 0; /* skip this line. */
54
55 log_debug ("rev_key: line=%s\r\n", line);
56
57 r = (gpg_desig_rev_t)calloc (1, sizeof *r);
58 if (!r)
59 return gpg_error (GPG_ERR_ENOMEM);
60 if (!*rev)
61 *rev = r;
62 else {
63 for (t=*rev; t->next; t=t->next)
64 ;
65 t->next = r;
66 }
67
68 p = strdup (line);
69 if (!p)
70 return gpg_error (GPG_ERR_ENOMEM);
71
72 for (;;) {
73 field++;
74 pend = strsep (&p, ":");
75 if (pend == NULL)
76 break;
77 switch (field) {
78 case 4:
79 r->pubkey_algo = (gpgme_pubkey_algo_t)atol (pend);
80 break;
81
82 case 10:
83 strncpy (r->fpr, pend, 40);
84 r->fpr[40] = 0;
85 break;
86 }
87 }
88 free (p);
89 return 0;
90 }
91
92
93 /* Parse the colon data output of edit key from @line and
94 store the information in the @inf context.
95 Return value: 0 on success. */
96 static gpgme_error_t
97 uid_inf_colon_handler (gpg_uid_info_t *inf, char *line)
98 {
99 gpg_uid_info_t i, t;
100 char *p, *pend;
101 char *name;
102 int field = 0, len = 0;
103
104 if (!line || strlen (line) < 3 || strncmp (line, "uid", 3))
105 return gpg_error (GPG_ERR_EOF);
106
107 i = (gpg_uid_info_t)calloc (1, sizeof *i);
108 if (!i)
109 return gpg_error (GPG_ERR_ENOMEM);
110 if (!*inf)
111 *inf = i;
112 else {
113 for (t=*inf; t->next; t=t->next)
114 ;
115 t->next = i;
116 }
117
118 p = strdup (line);
119 if (!p)
120 return gpg_error (GPG_ERR_ENOMEM);;
121 for (;;) {
122 field++;
123 pend = strsep (&p, ":");
124 if (pend == NULL)
125 break;
126
127 switch (field) {
128 case 2: /* trust info */
129 break;
130
131 case 10: /* user ID */
132 name = (char *)calloc (1, strlen (pend)+1);
133 if (!name)
134 return gpg_error (GPG_ERR_ENOMEM);;
135 gpg_decode_c_string (pend, &name, strlen (pend)+ 1);
136 i->name = utf8_to_native (name);
137 safe_free (name);
138 if (strchr (pend, '<') != NULL && strchr (pend, '>') != NULL) {
139 int pos = strchr (i->name, '<')- i->name + 1;
140 int end = strchr (i->name, '>') - i->name;
141 i->email = (char*) calloc (1, end-pos+2);
142 if (!i->email)
143 return gpg_error (GPG_ERR_ENOMEM);;
144 memcpy (i->email, i->name+pos, (end-pos));
145 }
146 break;
147
148 case 13: /* preferences */
149 if (strstr (pend, "mdc")) {
150 const char *s = "no-ks-modify";
151 len = strlen (pend) - 4; /* ,mdc */
152 if (strstr (pend, s)) {
153 i->flags.no_ks_modify = 1;
154 len -= strlen (s)+1; /* ',' + s */
155 }
156 i->prefs = (char*)calloc (1, len+1);
157 if (!i->prefs)
158 return gpg_error (GPG_ERR_ENOMEM);
159 memcpy (i->prefs, pend, len);
160 i->prefs[len] = '\0';
161 i->flags.mdc = 1;
162 }
163 else {
164 i->prefs = strdup (pend);
165 if (!i->prefs)
166 return gpg_error (GPG_ERR_ENOMEM);
167 i->flags.mdc = 0;
168 }
169 break;
170
171 case 14: /* index/flags */
172 i->index = atoi (pend);
173 if (strchr (pend, 'r'))
174 i->flags.revoked = 1;
175 if (strchr (pend, 'p'))
176 i->flags.primary = 1;
177 break;
178 }
179 }
180 free (p);
181 return 0;
182 }
183
184
185 /* Release the context in @inf. */
186 void
187 gpg_uid_info_release (gpg_uid_info_t list)
188 {
189 gpg_uid_info_t i;
190
191 while (list) {
192 i = list->next;
193 if (list->name) {
194 if (list->name)
195 free (list->name);
196 list->name = NULL;
197 }
198 if (list->prefs) {
199 if (list->prefs)
200 free (list->prefs);
201 list->prefs = NULL;
202 }
203 free (list);
204 list = i;
205 }
206 }
207
208
209 /* Release the context in @rev. */
210 void
211 gpg_desig_rev_release (gpg_desig_rev_t rev)
212 {
213 gpg_desig_rev_t r;
214
215 while (rev) {
216 r = rev->next;
217 free (rev);
218 rev = r;
219 }
220 }
221
222
223 static gpgme_error_t
224 list2_handler (void *opaque, gpgme_status_code_t code, const char *key, int fd)
225 {
226 DWORD n;
227 const char *s;
228
229 if (!strcmp (key, "keyedit.prompt")) {
230 s = "quit\n";
231 WriteFile ((HANDLE)fd, s, strlen (s), &n, NULL);
232 }
233 return 0;
234 }
235
236
237 /* Dummy handler to get the colon data and then quit. */
238 static gpgme_error_t
239 list_handler (void *opaque, gpgme_status_code_t code, const char *key, int fd)
240 {
241 static int step = 0;
242 const char *s = "";
243 DWORD n;
244
245 if (!strcmp (key, "keyedit.prompt") && step == 0) {
246 step = 1;
247 s = "list\n";
248 WriteFile ((HANDLE)fd, s, strlen (s), &n, NULL);
249 }
250 else if (!strcmp (key, "keyedit.prompt") && step == 1) {
251 step = 0;
252 s = "quit\n";
253 WriteFile ((HANDLE)fd, s, strlen (s), &n, NULL);
254 }
255
256 return 0;
257 }
258
259
260 /* Return all designated revokers for this key. If no revoker
261 was set, @r_rev is NULL.
262 Return value: 0 on success. */
263 gpgme_error_t
264 GpgKeyEdit::getDesignatedRevoker (gpg_desig_rev_t *r_rev)
265 {
266 gpgme_data_t out = NULL;
267 gpg_desig_rev_t rev = NULL;
268 gpgme_error_t err;
269 char buf[256];
270
271 if (!this->key)
272 return gpg_error (GPG_ERR_INV_OBJ);
273
274 err = gpgme_data_new (&out);
275 if (err)
276 goto leave;
277 err = gpgme_op_edit (ctx, key, list2_handler, NULL, out);
278 if (err)
279 goto leave;
280
281 gpgme_data_rewind (out);
282 while (gpg_data_readline (out, buf, DIM (buf)-1) > 0)
283 rev_key_colon_handler (&rev, buf);
284 *r_rev = rev;
285
286 leave:
287 if (out)
288 gpgme_data_release (out);
289 if (err) {
290 gpg_desig_rev_release (rev);
291 *r_rev = NULL;
292 }
293 return err;
294 }
295
296
297 /* Retrieve all user ID information of the key set via setKey
298 in @r_inf. The result also contains the user ID number which
299 is needed to securely delete the user-ID. */
300 gpgme_error_t
301 GpgKeyEdit::getUseridInfo (gpg_uid_info_t *r_uinf)
302 {
303 gpgme_data_t out = NULL;
304 gpgme_error_t err;
305 gpg_uid_info_t inf = NULL;
306 char buf[256];
307
308 if (!this->key)
309 return gpg_error (GPG_ERR_INV_OBJ);
310
311 err = gpgme_data_new (&out);
312 if (err)
313 goto leave;
314 err = gpgme_op_edit (ctx, key, list_handler, NULL, out);
315 if (err)
316 goto leave;
317
318 gpgme_data_rewind (out);
319 while (gpg_data_readline (out, buf, DIM (buf) -1) > 0)
320 uid_inf_colon_handler (&inf, buf);
321
322 *r_uinf = inf;
323
324 leave:
325 if (out)
326 gpgme_data_release (out);
327 if (err) {
328 gpg_uid_info_release (inf);
329 *r_uinf = NULL;
330 }
331 return err;
332 }
333
334
335 /* Clear object. */
336 void
337 GpgKeyEdit::clear (void)
338 {
339 pass = NULL;
340 name = NULL;
341 cmt = NULL;
342 email = NULL;
343 type = 0;
344 cnt = 0;
345 cmd_sent = 0;
346 resval = 0;
347 uid_index = -1;
348 sig_index = -1;
349 key_index = -1;
350 key_has_passwd = true;
351 }
352
353
354 GpgKeyEdit::GpgKeyEdit (void)
355 {
356 clear ();
357 key = NULL;
358 gpgme_new (&ctx); /*FIXME */
359
360 }
361
362
363 /* Construct an object with the given key in @key. */
364 GpgKeyEdit::GpgKeyEdit (gpgme_key_t _key)
365 {
366 clear ();
367 this->key = _key;
368 gpgme_new (&ctx); /* FIXME */
369 }
370
371 /* Construct an object and fetch the key with the keyid @keyid. */
372 GpgKeyEdit::GpgKeyEdit (const char *_keyid)
373 {
374 clear ();
375 get_pubkey (_keyid, &this->key); /*FIXME: check return code*/
376 gpgme_new (&ctx); /* FIXME */
377 }
378
379 /* Delete the given object. */
380 GpgKeyEdit::~GpgKeyEdit (void)
381 {
382 free_if_alloc (name);
383 free_if_alloc (cmt);
384 free_if_alloc (email);
385 gpgme_release (ctx);
386 }
387
388
389 /* Reset the state of the object. */
390 void
391 GpgKeyEdit::reset (void)
392 {
393 cmd_sent = 0;
394 cnt = 0;
395 }
396
397
398 /* Return true if type has a non-zero value. */
399 bool
400 GpgKeyEdit::isValid (void)
401 {
402 return type != 0;
403 }
404
405
406 /* Return the GPGME key. */
407 gpgme_key_t
408 GpgKeyEdit::getKey (void)
409 {
410 return key;
411 }
412
413
414 /* Set the GPGME callback to @cb. The hook value can be
415 given in @cb_value. */
416 void
417 GpgKeyEdit::setCallback (gpgme_progress_cb_t cb, void *cb_value)
418 {
419 gpgme_set_progress_cb (ctx, cb, cb_value);
420 }
421
422
423 /* Clear the stored passphrase. */
424 void
425 GpgKeyEdit::clearPassphrase (void)
426 {
427 if (pass)
428 pass = NULL;
429 }
430
431
432
433 /* Inidicate that a key is protected by a passphrase or not. */
434 void
435 GpgKeyEdit::setNoPassphrase (bool val)
436 {
437 key_has_passwd = !val;
438 }
439
440
441 void
442 GpgKeyEdit::setPassphraseCallback (gpgme_passphrase_cb_t cb, void *cb_value)
443 {
444 key_has_passwd = false;
445 gpgme_set_passphrase_cb (ctx, cb, cb_value);
446 }
447
448
449 bool
450 GpgKeyEdit::usePassphraseCallback (void)
451 {
452 gpgme_passphrase_cb_t cb_ptr;
453 void *cb_value;
454
455 gpgme_get_passphrase_cb (ctx, &cb_ptr, &cb_value);
456 if (cb_ptr)
457 return true;
458 return false;
459 }
460
461 /* Set the passphrase to @pass. */
462 void
463 GpgKeyEdit::setPassphrase (const char *_pass)
464 {
465 this->pass = _pass;
466 }
467
468
469 /* Kludge to allow to handle admin and user PINs. */
470 void
471 GpgKeyEdit::setPassphrase2 (const char *_pass2)
472 {
473 this->new_pass = _pass2;
474 }
475
476 /* Set the current key to @key. */
477 void
478 GpgKeyEdit::setKey (gpgme_key_t _key)
479 {
480 this->key = _key;
481 }
482
483 /* Set the keyid of the destination key to @keyid. */
484 void
485 GpgKeyEdit::setKeyID (const char *_keyid)
486 {
487 if (!_keyid)
488 return;
489 get_pubkey (_keyid, &this->key); /* FIXME: check return code */
490 }
491
492
493 /* Set the local user for the operation to @locusr. */
494 void
495 GpgKeyEdit::setLocalUser (gpgme_key_t locusr)
496 {
497 gpgme_signers_add (ctx, locusr);
498 }
499
500 /* Set the result of the operation to @val. */
501 void
502 GpgKeyEdit::setResult (int val)
503 {
504 resval |= val;
505 }
506
507
508 /* Return the result of the operation. */
509 int
510 GpgKeyEdit::getResult(void)
511 {
512 return resval;
513 }
514
515
516 /* Return the amount of days the key is valid. */
517 int
518 GpgKeyEdit::getValidDays (void)
519 {
520 return valid;
521 }
522
523
524 int
525 GpgKeyEdit::getType (void)
526 {
527 return type;
528 }
529
530
531 /* Add the notation data from @notation to the user ID
532 with the index @_uid_idx.
533 Return value: 0 on success. */
534 gpgme_error_t
535 GpgKeyEdit::addNotation (int _uid_idx, const char *_notation)
536 {
537 if (!key)
538 return gpg_error (GPG_ERR_INV_OBJ);
539 if (key_has_passwd && !this->pass)
540 return gpg_error (GPG_ERR_INV_PASSPHRASE);
541
542 type = GPG_EDITKEY_NOTATION;
543 this->uid_index = _uid_idx;
544 this->notation = (char*)_notation;
545 return gpg_editkey (this->ctx, this->key, this);
546 }
547
548
549 /* Sign the key stored in the object with the
550 signing mode @mode and the signature class @sig_class.
551 Return value: 0 on success. */
552 gpgme_error_t
553 GpgKeyEdit::signKey (int mode, int _sig_class, const char *_exp_date)
554 {
555 if (!this->key)
556 return gpg_error (GPG_ERR_INV_OBJ);
557 if (key_has_passwd && !this->pass)
558 return gpg_error (GPG_ERR_INV_PASSPHRASE);
559
560 type = mode;
561 this->exp_date = _exp_date;
562 this->sig_class = _sig_class;
563 return gpg_editkey (this->ctx, this->key, this);
564 }
565
566
567 /* Sign a single user-id with the index @_uid_index.
568 All other parameters are equal to signKey().
569 Return value: 0 on success. */
570 gpgme_error_t
571 GpgKeyEdit::signUserid (int _uid_idx, int mode, int _sig_class,
572 const char *_exp_date)
573 {
574 if (!this->key)
575 return gpg_error (GPG_ERR_INV_OBJ);
576 if (key_has_passwd && !this->pass)
577 return gpg_error (GPG_ERR_INV_PASSPHRASE);
578
579 this->uid_index = _uid_idx;
580 type = mode;
581 this->exp_date = _exp_date;
582 this->sig_class = _sig_class;
583 return gpg_editkey (this->ctx, this->key, this);
584 }
585
586
587 /* Set the ownertrust of the key stored in the object
588 to the trust value @trust.
589 Return value: 0 on success. */
590 gpgme_error_t
591 GpgKeyEdit::setTrust (gpgme_validity_t trust)
592 {
593 if (!this->key)
594 return gpg_error (GPG_ERR_INV_OBJ);
595
596 type = GPG_EDITKEY_TRUST;
597 this->trust_id = (int)trust;
598 return gpg_editkey (this->ctx, this->key, this);
599 }
600
601 /* Add a user ID to the given key with the @name as the
602 name, @cmt as the comment (or NULL) and @email as the email.
603 Return value: 0 on success. */
604 gpgme_error_t
605 GpgKeyEdit::addUserid (const char *_name, const char *_cmt, const char *_email)
606 {
607 if (!this->key)
608 return gpg_error (GPG_ERR_INV_OBJ);
609 if (key_has_passwd && !this->pass)
610 return gpg_error (GPG_ERR_INV_PASSPHRASE);
611
612 type = GPG_EDITKEY_ADDUID;
613 free_if_alloc (this->name);
614 this->name = m_strdup (_name);
615 free_if_alloc (this->cmt);
616 this->cmt = NULL;
617 if (_cmt != NULL)
618 this->cmt = m_strdup (_cmt);
619 free_if_alloc (this->email);
620 this->email = m_strdup (_email);
621 if (!this->email || !this->name)
622 BUG (NULL);
623 return gpg_editkey (this->ctx, this->key, this);
624 }
625
626 /* Delete the user-ID with the index @uid_index of the given key.
627 Return value: 0 on success. */
628 gpgme_error_t
629 GpgKeyEdit::delUserid (int _uid_index)
630 {
631 if (!this->key)
632 return gpg_error (GPG_ERR_INV_OBJ);
633
634 type = GPG_EDITKEY_DELUID;
635 this->uid_index = _uid_index;
636 return gpg_editkey (this->ctx, this->key, this);
637 }
638
639 /* Delete the subkey with the index @key_index.
640 Return value: 0 on success. */
641 gpgme_error_t
642 GpgKeyEdit::delKey (int _key_index)
643 {
644 if (!this->key)
645 return gpg_error (GPG_ERR_INV_OBJ);
646
647 type = GPG_EDITKEY_DELKEY;
648 this->key_index = _key_index;
649 return gpg_editkey (this->ctx, this->key, this);
650 }
651
652
653 /* Add a new key on a smart card.
654 The type is given in @type. */
655 gpgme_error_t
656 GpgKeyEdit::addCardKey (int _type)
657 {
658 if (!this->key)
659 return gpg_error (GPG_ERR_INV_OBJ);
660 if (!this->pass)
661 return gpg_error (GPG_ERR_INV_PASSPHRASE);
662 if (_type < 1 || _type > 3)
663 return gpg_error (GPG_ERR_INV_VALUE);
664
665 type = GPG_EDITKEY_ADDCARDKEY;
666 this->key_index = _type;
667 return gpg_editkey (this->ctx, this->key, this);
668 }
669
670
671 /* Add a new subkey to the given key.
672 The new key will have @pubkey_algo as the algorithm
673 and a size of @pubkey_size bits. If valid > 0, the
674 key expires in @valid days.
675 Return value: 0 on success. */
676 gpgme_error_t
677 GpgKeyEdit::addSubkey (gpgme_pubkey_algo_t _pubkey_algo,
678 unsigned int _pubkey_size, long _valid)
679 {
680 if (!this->key)
681 return gpg_error (GPG_ERR_INV_OBJ);
682 if (key_has_passwd && !this->pass)
683 return gpg_error (GPG_ERR_INV_PASSPHRASE);
684
685 type = GPG_EDITKEY_ADDKEY;
686 this->pubkey_algo = _pubkey_algo;
687 this->pubkey_size = _pubkey_size;
688 this->valid = _valid;
689 return gpg_editkey (this->ctx, this->key, this);
690 }
691
692 /* Change the passphrase of the given key to @new_pass.
693 If allow_empty != 0, it is allowed to provide an empty passphrase.
694 Return value: 0 on success. */
695 gpgme_error_t
696 GpgKeyEdit::changePassphrase (const char *_new_pass, int allow_empty)
697 {
698 if (!this->key)
699 return gpg_error (GPG_ERR_INV_OBJ);
700 if (key_has_passwd && !this->pass)
701 return gpg_error (GPG_ERR_INV_PASSPHRASE);
702
703 type = GPG_EDITKEY_PASSWD;
704 this->new_pass = _new_pass;
705 this->flags = allow_empty? 1 : 0;
706 return gpg_editkey (this->ctx, this->key, this);
707 }
708
709 /* Set the primary user-ID of the given key to user-ID with
710 the index @uid_index.
711 Return value: 0 on success. */
712 gpgme_error_t
713 GpgKeyEdit::setPrimaryUserid (int _uid_index)
714 {
715 if (!this->key)
716 return gpg_error (GPG_ERR_INV_OBJ);
717 if (key_has_passwd && !this->pass)
718 return gpg_error (GPG_ERR_INV_PASSPHRASE);
719
720 type = GPG_EDITKEY_PRIMARY;
721 this->uid_index = _uid_index;
722 return gpg_editkey (this->ctx, this->key, this);
723 }
724
725 /* Set the expire date of the subkey with the index @key_index.
726 @exp_timestamp is used to calculate the days the key is valid.
727 if @exp_days is true, exp_timestamp is already converted to days.
728 Return value: 0 on success. */
729 gpgme_error_t
730 GpgKeyEdit::setKeyExpireDate (int _key_index, long exp_timestamp,
731 bool exp_days)
732 {
733 if (!this->key)
734 return gpg_error (GPG_ERR_INV_OBJ);
735 if (key_has_passwd && !this->pass)
736 return gpg_error (GPG_ERR_INV_PASSPHRASE);
737 if (!exp_days && exp_timestamp > 0 && exp_timestamp < time (NULL))
738 return gpg_error (GPG_ERR_INV_ARG);
739
740 type = GPG_EDITKEY_EXPIRE;
741 if (!exp_days && exp_timestamp > 0) {
742 valid = exp_timestamp - time (NULL);
743 valid /= 86400;
744 }
745 else
746 valid = exp_timestamp;
747 this->key_index = _key_index;
748 return gpg_editkey (this->ctx, this->key, this);
749 }
750
751 /* Revoke the userid given by the index @uid_index.
752 Return value: 0 on success. */
753 gpgme_error_t
754 GpgKeyEdit::revokeUserid (int _uid_index)
755 {
756 if (!this->key)
757 return gpg_error (GPG_ERR_INV_OBJ);
758 if (key_has_passwd && !this->pass)
759 return gpg_error (GPG_ERR_INV_PASSPHRASE);
760
761 type = GPG_EDITKEY_REVUID;
762 this->uid_index = _uid_index;
763 return gpg_editkey (this->ctx, this->key, this);
764 }
765
766
767 /* Revoke a signature on the user-ID with the index @uid_index
768 and the signature index @sig_index.
769 Return value: 0 on success. */
770 gpgme_error_t
771 GpgKeyEdit::revokeSignature (int _uid_index, int _sig_index)
772 {
773 if (!this->key)
774 return gpg_error (GPG_ERR_INV_OBJ);
775 if (key_has_passwd && !this->pass)
776 return gpg_error (GPG_ERR_INV_PASSPHRASE);
777
778 type = GPG_EDITKEY_REVSIG;
779 this->uid_index = _uid_index;
780 this->sig_index = _sig_index;
781 return gpg_editkey (this->ctx, this->key, this);
782 }
783
784
785 /* Revoke the subkey with the index @key_index. Optionally
786 a reason can be provided in @reason with a text to describe
787 more details in @cmt.
788 Return value: 0 on success. */
789 gpgme_error_t
790 GpgKeyEdit::revokeSubkey (int _key_index, int _reason, const char *_cmt)
791 {
792 if (!this->key)
793 return gpg_error (GPG_ERR_INV_OBJ);
794 if (key_has_passwd && !this->pass)
795 return gpg_error (GPG_ERR_INV_PASSPHRASE);
796
797 type = GPG_EDITKEY_REVKEY;
798 this->key_index = _key_index;
799 this->reason = _reason;
800 free_if_alloc (this->cmt);
801 this->cmt = NULL;
802 if (_cmt)
803 this->cmt = m_strdup (_cmt);
804 return gpg_editkey (this->ctx, this->key, this);
805 }
806
807
808 /* Add a designated revoker to the key. @uid stores
809 the user-ID of the key who is allowed to be a
810 designated revoker.
811 Return value: 0 on success. */
812 gpgme_error_t
813 GpgKeyEdit::addDesignatedRevoker (const char *uid)
814 {
815 if (!this->key)
816 return gpg_error (GPG_ERR_INV_OBJ);
817 if (key_has_passwd && !this->pass)
818 return gpg_error (GPG_ERR_INV_PASSPHRASE);
819
820 type = GPG_EDITKEY_ADDREV;
821 free_if_alloc (this->name);
822 this->name = m_strdup (uid);
823 return gpg_editkey (this->ctx, this->key, this);
824 }
825
826 /* Add a photo-ID to the key. The JPG image is given
827 in the file with the name @jpg_file.
828 Return value: 0 on success. */
829 gpgme_error_t
830 GpgKeyEdit::addPhotoid (const char *jpg_file)
831 {
832 if (!this->key)
833 return gpg_error (GPG_ERR_INV_OBJ);
834 if (key_has_passwd && !this->pass)
835 return gpg_error (GPG_ERR_INV_PASSPHRASE);
836
837 type = GPG_EDITKEY_ADDPHOTO;
838 this->url = jpg_file;
839 return gpg_editkey (this->ctx, this->key, this);
840 }
841
842 /* Enable the given key. */
843 gpgme_error_t
844 GpgKeyEdit::enable (void)
845 {
846 if (!this->key)
847 return gpg_error (GPG_ERR_INV_OBJ);
848 type = GPG_EDITKEY_ENABLE;
849 return gpg_editkey (this->ctx, this->key, this);
850 }
851
852 /* Disable the given key. */
853 gpgme_error_t
854 GpgKeyEdit::disable (void)
855 {
856 if (!this->key)
857 return gpg_error (GPG_ERR_INV_OBJ);
858 type = GPG_EDITKEY_DISABLE;
859 return gpg_editkey (this->ctx, this->key, this);
860 }
861
862
863 /* Remove unusable parts and all signatures from a key. */
864 gpgme_error_t
865 GpgKeyEdit::minimizeKey (void)
866 {
867 if (!this->key)
868 return gpg_error (GPG_ERR_INV_OBJ);
869 type = GPG_EDITKEY_MINIMIZE;
870 return gpg_editkey (this->ctx, this->key, this);
871 }
872
873
874 /* Remove unusable parts from a key. */
875 gpgme_error_t
876 GpgKeyEdit::cleanKey (void)
877 {
878 if (!this->key)
879 return gpg_error (GPG_ERR_INV_OBJ);
880 type = GPG_EDITKEY_CLEAN;
881 return gpg_editkey (this->ctx, this->key, this);
882 }
883
884
885 /* Update the user-ID preferences of the user-ID with the
886 index @uid_index to the prefs given in @new_prefs.
887 Return value: 0 on success. */
888 gpgme_error_t
889 GpgKeyEdit::setUseridPreferences (int _uid_index, const char *_new_prefs)
890 {
891 if (!this->key)
892 return gpg_error (GPG_ERR_INV_OBJ);
893 if (key_has_passwd && !this->pass)
894 return gpg_error (GPG_ERR_INV_PASSPHRASE);
895 type = GPG_EDITKEY_SETPREF;
896 this->uid_index = _uid_index;
897 this->new_prefs = _new_prefs;
898 return gpg_editkey (this->ctx, this->key, this);
899 }
900
901
902 /* Delete a signature from the user-ID with the index @uid_index.
903 The index of the signature is given in @sig_index.
904 Return value: 0 on success. */
905 gpgme_error_t
906 GpgKeyEdit::delUseridSignature (int _uid_index, int _sig_index)
907 {
908 if (!this->key)
909 return gpg_error (GPG_ERR_INV_OBJ);
910 type = GPG_EDITKEY_DELSIG;
911 this->uid_index = _uid_index;
912 this->sig_index = _sig_index;
913 return gpg_editkey (this->ctx, this->key, this);
914 }
915
916 /* Set the preferred keyserver for the given key to @url.
917 If @_uid_index is -1, set the keyserver for all user-ids.
918 Return value: 0 on success. */
919 gpgme_error_t
920 GpgKeyEdit::setPreferredKeyserver (int _uid_index, const char *_url)
921 {
922 if (!this->key)
923 return gpg_error (GPG_ERR_INV_OBJ);
924 if (key_has_passwd && !this->pass)
925 return gpg_error (GPG_ERR_INV_PASSPHRASE);
926 if (!_url)
927 return gpg_error (GPG_ERR_INV_ARG);
928
929 type = GPG_EDITKEY_KEYSERV;
930 this->url = _url;
931 this->uid_index = _uid_index;
932 return gpg_editkey (this->ctx, this->key, this);
933 }
934
935
936 /* Return the saved user-id index. */
937 int
938 GpgKeyEdit::getUseridIndex (void)
939 {
940 return uid_index;
941 }
942
943
944 /* Return the saved key index. */
945 int
946 GpgKeyEdit::getKeyIndex (void)
947 {
948 return key_index;
949 }
950
951
952 /* Return the saved sig index. */
953 int
954 GpgKeyEdit::getSigIndex (void)
955 {
956 return sig_index;
957 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26