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

Contents of /trunk/Src/wptKeyEdit.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26