See ChangeLog: Tue Aug 31 17:20:44 CEST 1999 Werner Koch
[gnupg.git] / g10 / delkey.c
1 /* delkey.c - delete keys
2  *      Copyright (C) 1998 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 "memory.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( &kbpos, username )
62                : find_keyblock_byname( &kbpos, username );
63     if( rc ) {
64         log_error(_("%s: user not found\n"), username );
65         goto leave;
66     }
67
68     /* read the keyblock */
69     rc = read_keyblock( &kbpos, &keyblock );
70     if( rc ) {
71         log_error("%s: read problem: %s\n", username, g10_errstr(rc) );
72         goto leave;
73     }
74
75     /* get the keyid from the keyblock */
76     node = find_kbnode( keyblock, secret? PKT_SECRET_KEY:PKT_PUBLIC_KEY );
77     if( !node ) {
78         log_error("Oops; key not found anymore!\n");
79         rc = G10ERR_GENERAL;
80         goto leave;
81     }
82
83     if( secret ) {
84         sk = node->pkt->pkt.secret_key;
85         keyid_from_sk( sk, keyid );
86     }
87     else {
88         pk = node->pkt->pkt.public_key;
89         keyid_from_pk( pk, keyid );
90         rc = seckey_available( keyid );
91         if( !rc ) {
92             log_error(_(
93             "there is a secret key for this public key!\n"));
94             log_info(_(
95             "use option \"--delete-secret-key\" to delete it first.\n"));
96             rc = -1;
97         }
98         else if( rc != G10ERR_NO_SECKEY )
99             log_error("%s: get secret key: %s\n", username, g10_errstr(rc) );
100         else
101             rc = 0;
102     }
103
104     if( rc )
105         rc = 0;
106     else if( opt.batch && secret )
107         log_error(_("can't do that in batchmode\n"));
108     else if( opt.batch && opt.answer_yes )
109         okay++;
110     else if( opt.batch )
111         log_error(_("can't do that in batchmode without \"--yes\"\n"));
112     else {
113         char *p;
114         size_t n;
115
116         if( secret )
117             tty_printf("sec  %4u%c/%08lX %s   ",
118                       nbits_from_sk( sk ),
119                       pubkey_letter( sk->pubkey_algo ),
120                       keyid[1], datestr_from_sk(sk) );
121         else
122             tty_printf("pub  %4u%c/%08lX %s   ",
123                       nbits_from_pk( pk ),
124                       pubkey_letter( pk->pubkey_algo ),
125                       keyid[1], datestr_from_pk(pk) );
126         p = get_user_id( keyid, &n );
127         tty_print_string( p, n );
128         m_free(p);
129         tty_printf("\n\n");
130
131         yes = cpr_get_answer_is_yes( secret? "delete_key.secret.okay"
132                                            : "delete_key.okay",
133                               _("Delete this key from the keyring? "));
134         if( !cpr_enabled() && secret && yes ) {
135             /* I think it is not required to check a passphrase; if
136              * the user is so stupid as to let others access his secret keyring
137              * (and has no backup) - it is up him to read some very
138              * basic texts about security.
139              */
140             yes = cpr_get_answer_is_yes("delete_key.secret.okay",
141                          _("This is a secret key! - really delete? "));
142         }
143         if( yes )
144             okay++;
145     }
146
147
148     if( okay ) {
149         rc = delete_keyblock( &kbpos );
150         if( rc ) {
151             log_error("delete_keyblock failed: %s\n", g10_errstr(rc) );
152             goto leave;
153         }
154     }
155
156   leave:
157     release_kbnode( keyblock );
158     return rc;
159 }
160