See ChangeLog: Fri Oct 6 14:29:16 CEST 2000 Werner Koch
[gnupg.git] / g10 / delkey.c
1 /* delkey.c - delete keys
2  *      Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <ctype.h>
28
29 #include "options.h"
30 #include "packet.h"
31 #include "errors.h"
32 #include "iobuf.h"
33 #include "keydb.h"
34 #include <gcrypt.h>
35 #include "util.h"
36 #include "main.h"
37 #include "trustdb.h"
38 #include "filter.h"
39 #include "ttyio.h"
40 #include "status.h"
41 #include "i18n.h"
42
43
44 /****************
45  * Delete a public or secret key from a keyring.
46  */
47 int
48 delete_key( const char *username, int secret )
49 {
50     int rc = 0;
51     KBNODE keyblock = NULL;
52     KBNODE node;
53     KBPOS kbpos;
54     PKT_public_key *pk = NULL;
55     PKT_secret_key *sk = NULL;
56     u32 keyid[2];
57     int okay=0;
58     int yes;
59
60     /* search the userid */
61     rc = secret? find_secret_keyblock_byname( &keyblock, username )
62                : find_keyblock_byname( &keyblock, username );
63     if( rc ) {
64         log_error(_("%s: user not found: %s\n"), username, gpg_errstr(rc) );
65         write_status_text( STATUS_DELETE_PROBLEM, "1" );
66         goto leave;
67     }
68
69     /* get the keyid from the keyblock */
70     node = find_kbnode( keyblock, secret? PKT_SECRET_KEY:PKT_PUBLIC_KEY );
71     if( !node ) {
72         log_error("Oops; key not found anymore!\n");
73         rc = GPGERR_GENERAL;
74         goto leave;
75     }
76
77     if( secret ) {
78         sk = node->pkt->pkt.secret_key;
79         keyid_from_sk( sk, keyid );
80     }
81     else {
82         pk = node->pkt->pkt.public_key;
83         keyid_from_pk( pk, keyid );
84         rc = seckey_available( keyid );
85         if( !rc ) {
86             log_error(_(
87             "there is a secret key for this public key!\n"));
88             log_info(_(
89             "use option \"--delete-secret-key\" to delete it first.\n"));
90             write_status_text( STATUS_DELETE_PROBLEM, "2" );
91             rc = -1;
92         }
93         else if( rc != GPGERR_NO_SECKEY ) {
94             log_error("%s: get secret key: %s\n", username, gpg_errstr(rc) );
95         }
96         else
97             rc = 0;
98     }
99
100     if( rc )
101         rc = 0;
102     else if( opt.batch && secret )
103         log_error(_("can't do that in batchmode\n"));
104     else if( opt.batch && opt.answer_yes )
105         okay++;
106     else if( opt.batch )
107         log_error(_("can't do that in batchmode without \"--yes\"\n"));
108     else {
109         char *p;
110         size_t n;
111
112         if( secret )
113             tty_printf("sec  %4u%c/%08lX %s   ",
114                       nbits_from_sk( sk ),
115                       pubkey_letter( sk->pubkey_algo ),
116                       keyid[1], datestr_from_sk(sk) );
117         else
118             tty_printf("pub  %4u%c/%08lX %s   ",
119                       nbits_from_pk( pk ),
120                       pubkey_letter( pk->pubkey_algo ),
121                       keyid[1], datestr_from_pk(pk) );
122         p = get_user_id( keyid, &n );
123         tty_print_utf8_string( p, n );
124         gcry_free(p);
125         tty_printf("\n\n");
126
127         yes = cpr_get_answer_is_yes( secret? "delete_key.secret.okay"
128                                            : "delete_key.okay",
129                               _("Delete this key from the keyring? "));
130         if( !cpr_enabled() && secret && yes ) {
131             /* I think it is not required to check a passphrase; if
132              * the user is so stupid as to let others access his secret keyring
133              * (and has no backup) - it is up him to read some very
134              * basic texts about security.
135              */
136             yes = cpr_get_answer_is_yes("delete_key.secret.okay",
137                          _("This is a secret key! - really delete? "));
138         }
139         if( yes )
140             okay++;
141     }
142
143
144     if( okay ) {
145         rc = delete_keyblock( &kbpos );
146         if( rc ) {
147             log_error("delete_keyblock failed: %s\n", gpg_errstr(rc) );
148             goto leave;
149         }
150     }
151
152   leave:
153     release_kbnode( keyblock );
154     return rc;
155 }
156