1 /* revoke.c - Create recovation certificates.
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
3 * 2004 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * GnuPG is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * GnuPG 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
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <https://www.gnu.org/licenses/>.
38 #include "call-agent.h"
40 struct revocation_reason_info {
47 revocation_reason_build_cb( PKT_signature *sig, void *opaque )
49 struct revocation_reason_info *reason = opaque;
58 ud = native_to_utf8( reason->desc );
61 buffer = xmalloc( buflen );
62 *buffer = reason->code;
64 memcpy(buffer+1, ud, strlen(ud) );
68 build_sig_subpkt( sig, SIGSUBPKT_REVOC_REASON, buffer, buflen );
73 /* Outputs a minimal pk (as defined by 2440) from a keyblock. A
74 minimal pk consists of the public key packet and a user ID. We try
75 and pick a user ID that has a uid signature, and include it if
78 export_minimal_pk(IOBUF out,KBNODE keyblock,
79 PKT_signature *revsig,PKT_signature *revkey)
83 PKT_user_id *uid=NULL;
84 PKT_signature *selfsig=NULL;
88 node=find_kbnode(keyblock,PKT_PUBLIC_KEY);
91 log_error("key incomplete\n");
92 return GPG_ERR_GENERAL;
95 keyid_from_pk(node->pkt->pkt.public_key,keyid);
98 rc=build_packet(out,&pkt);
101 log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
106 pkt.pkttype=PKT_SIGNATURE;
108 /* the revocation itself, if any. 2440 likes this to come first. */
111 pkt.pkt.signature=revsig;
112 rc=build_packet(out,&pkt);
115 log_error("build_packet failed: %s\n", gpg_strerror (rc) );
120 /* If a revkey in a 1F sig is present, include it too */
123 pkt.pkt.signature=revkey;
124 rc=build_packet(out,&pkt);
127 log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
136 node=find_next_kbnode(node,PKT_USER_ID);
139 /* We're out of user IDs - none were self-signed. */
144 log_error(_("key %s has no user IDs\n"),keystr(keyid));
145 return GPG_ERR_GENERAL;
149 if(node->pkt->pkt.user_id->attrib_data)
152 uid=node->pkt->pkt.user_id;
155 while((signode=find_next_kbnode(signode,PKT_SIGNATURE)))
157 if(keyid[0]==signode->pkt->pkt.signature->keyid[0] &&
158 keyid[1]==signode->pkt->pkt.signature->keyid[1] &&
159 IS_UID_SIG(signode->pkt->pkt.signature))
161 selfsig=signode->pkt->pkt.signature;
167 pkt.pkttype=PKT_USER_ID;
170 rc=build_packet(out,&pkt);
173 log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
179 pkt.pkttype=PKT_SIGNATURE;
180 pkt.pkt.signature=selfsig;
182 rc=build_packet(out,&pkt);
185 log_error(_("build_packet failed: %s\n"), gpg_strerror (rc) );
194 * Generate a revocation certificate for UNAME via a designated revoker
197 gen_desig_revoke (ctrl_t ctrl, const char *uname, strlist_t locusr)
200 armor_filter_context_t *afx;
201 PKT_public_key *pk = NULL;
202 PKT_public_key *pk2 = NULL;
203 PKT_signature *sig = NULL;
205 struct revocation_reason_info *reason = NULL;
207 KEYDB_SEARCH_DESC desc;
208 KBNODE keyblock=NULL,node;
211 SK_LIST sk_list=NULL;
215 log_error(_("can't do this in batch mode\n"));
216 return GPG_ERR_GENERAL;
219 afx = new_armor_context ();
221 kdbhd = keydb_new ();
224 rc = gpg_error_from_syserror ();
227 rc = classify_user_id (uname, &desc, 1);
229 rc = keydb_search (kdbhd, &desc, 1, NULL);
231 log_error (_("key \"%s\" not found: %s\n"),uname, gpg_strerror (rc));
235 rc = keydb_get_keyblock (kdbhd, &keyblock );
237 log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
241 /* To parse the revkeys */
242 merge_keys_and_selfsig(keyblock);
244 /* get the key from the keyblock */
245 node = find_kbnode( keyblock, PKT_PUBLIC_KEY );
249 pk=node->pkt->pkt.public_key;
251 keyid_from_pk(pk,keyid);
255 rc = build_sk_list (ctrl, locusr, &sk_list, PUBKEY_USAGE_CERT);
260 /* Are we a designated revoker for this key? */
262 if(!pk->revkey && pk->numrevkeys)
265 for(i=0;i<pk->numrevkeys;i++)
269 free_public_key (pk2);
274 for(list=sk_list;list;list=list->next)
276 byte fpr[MAX_FINGERPRINT_LEN];
279 fingerprint_from_pk (list->pk, fpr, &fprlen);
281 /* Don't get involved with keys that don't have 160
286 if(memcmp(fpr,pk->revkey[i].fpr,20)==0)
291 pk2 = copy_public_key (NULL, list->pk);
297 pk2 = xmalloc_clear (sizeof *pk2);
298 rc = get_pubkey_byfprint (pk2, NULL,
299 pk->revkey[i].fpr, MAX_FINGERPRINT_LEN);
302 /* We have the revocation key. */
305 PKT_signature *revkey = NULL;
309 print_pubkey_info (NULL, pk);
312 tty_printf (_("To be revoked by:\n"));
313 print_seckey_info (pk2);
315 if(pk->revkey[i].class&0x40)
316 tty_printf(_("(This is a sensitive revocation key)\n"));
319 rc = agent_probe_secret_key (ctrl, pk2);
322 tty_printf (_("Secret key is not available.\n"));
326 if( !cpr_get_answer_is_yes("gen_desig_revoke.okay",
327 _("Create a designated revocation certificate for this key? (y/N) ")))
330 /* get the reason for the revocation (this is always v4) */
331 reason = ask_revocation_reason( 1, 0, 1 );
336 tty_printf(_("ASCII armored output forced.\n"));
338 if( (rc = open_outfile (-1, NULL, 0, 1, &out )) )
342 afx->hdrlines = "Comment: A designated revocation certificate"
344 push_armor_filter (afx, out);
347 rc = make_keysig_packet( &sig, pk, NULL, NULL, pk2, 0x20, 0,
349 revocation_reason_build_cb, reason,
352 log_error(_("make_keysig_packet failed: %s\n"), gpg_strerror (rc));
356 /* Spit out a minimal pk as well, since otherwise there is
357 no way to know which key to attach this revocation to.
358 Also include the direct key signature that contains
359 this revocation key. We're allowed to include
360 sensitive revocation keys along with a revocation, as
361 this may be the only time the recipient has seen it.
362 Note that this means that if we have multiple different
363 sensitive revocation keys in a given direct key
364 signature, we're going to include them all here. This
365 is annoying, but the good outweighs the bad, since
366 without including this a sensitive revoker can't really
367 do their job. People should not include multiple
368 sensitive revocation keys in one signature: 2440 says
369 "Note that it may be appropriate to isolate this
370 subpacket within a separate signature so that it is not
371 combined with other subpackets that need to be
378 signode=find_next_kbnode(node,PKT_SIGNATURE);
384 if(keyid[0]==signode->pkt->pkt.signature->keyid[0] &&
385 keyid[1]==signode->pkt->pkt.signature->keyid[1] &&
386 IS_KEY_SIG(signode->pkt->pkt.signature))
390 for(j=0;j<signode->pkt->pkt.signature->numrevkeys;j++)
392 if(pk->revkey[i].class==
393 signode->pkt->pkt.signature->revkey[j].class &&
394 pk->revkey[i].algid==
395 signode->pkt->pkt.signature->revkey[j].algid &&
396 memcmp(pk->revkey[i].fpr,
397 signode->pkt->pkt.signature->revkey[j].fpr,
398 MAX_FINGERPRINT_LEN)==0)
400 revkey=signode->pkt->pkt.signature;
410 rc=export_minimal_pk(out,keyblock,sig,revkey);
414 /* and issue a usage notice */
415 tty_printf(_("Revocation certificate created.\n"));
421 log_error(_("no revocation keys found for \"%s\"\n"),uname);
424 free_public_key (pk);
425 free_public_key (pk2);
427 free_seckey_enc( sig );
429 release_sk_list(sk_list);
435 release_revocation_reason_info( reason );
436 release_armor_context (afx);
441 /* Common core to create the revocation. FILENAME may be NULL to write
442 to stdout or the filename given by --output. REASON describes the
443 revocation reason. PSK is the public primary key - we expect that
444 a corresponding secret key is available. KEYBLOCK is the entire
445 KEYBLOCK which is used in PGP mode to write a a minimal key and not
446 just the naked revocation signature; it may be NULL. If LEADINTEXT
447 is not NULL, it is written right before the (armored) output.*/
449 create_revocation (const char *filename,
450 struct revocation_reason_info *reason,
453 const char *leadintext, int suffix,
454 const char *cache_nonce)
458 armor_filter_context_t *afx;
459 PKT_signature *sig = NULL;
462 afx = new_armor_context ();
464 if ((rc = open_outfile (-1, filename, suffix, 1, &out)))
468 iobuf_writestr (out, leadintext);
471 afx->hdrlines = "Comment: This is a revocation certificate\n";
472 push_armor_filter (afx, out);
474 rc = make_keysig_packet (&sig, psk, NULL, NULL, psk, 0x20, 0,
476 revocation_reason_build_cb, reason, cache_nonce);
479 log_error (_("make_keysig_packet failed: %s\n"), gpg_strerror (rc));
483 if (keyblock && (PGP6 || PGP7 || PGP8))
485 /* Use a minimal pk for PGPx mode, since PGP can't import bare
486 revocation certificates. */
487 rc = export_minimal_pk (out, keyblock, sig, NULL);
494 pkt.pkttype = PKT_SIGNATURE;
495 pkt.pkt.signature = sig;
497 rc = build_packet (out, &pkt);
500 log_error (_("build_packet failed: %s\n"), gpg_strerror (rc));
507 free_seckey_enc (sig);
512 release_armor_context (afx);
517 /* This function is used to generate a standard revocation certificate
518 by gpg's interactive key generation function. The certificate is
519 stored at a dedicated place in a slightly modified form to avoid an
520 accidental import. PSK is the primary key; a corresponding secret
521 key must be available. CACHE_NONCE is optional but can be used to
522 help gpg-agent to avoid an extra passphrase prompt. */
524 gen_standard_revoke (PKT_public_key *psk, const char *cache_nonce)
528 struct revocation_reason_info reason;
529 char *dir, *tmpstr, *fname;
536 dir = get_openpgp_revocdir (gnupg_homedir ());
537 tmpstr = hexfingerprint (psk, NULL, 0);
538 fname = xstrconcat (dir, DIRSEP_S, tmpstr, NULL);
542 keyid_from_pk (psk, keyid);
544 memfp = es_fopenmem (0, "r+");
546 log_fatal ("error creating memory stream\n");
548 orig_codeset = i18n_switchto_utf8 ();
550 es_fprintf (memfp, "%s\n\n",
551 _("This is a revocation certificate for the OpenPGP key:"));
553 print_key_line (memfp, psk, 0);
555 if (opt.keyid_format != KF_NONE)
556 print_fingerprint (memfp, psk, 3);
558 kl = opt.keyid_format == KF_NONE? 0 : keystrlen ();
560 tmpstr = get_user_id (keyid, &len);
561 es_fprintf (memfp, "uid%*s%.*s\n\n",
566 es_fprintf (memfp, "%s\n\n%s\n\n%s\n\n:",
567 _("A revocation certificate is a kind of \"kill switch\" to publicly\n"
568 "declare that a key shall not anymore be used. It is not possible\n"
569 "to retract such a revocation certificate once it has been published."),
570 _("Use it to revoke this key in case of a compromise or loss of\n"
571 "the secret key. However, if the secret key is still accessible,\n"
572 "it is better to generate a new revocation certificate and give\n"
573 "a reason for the revocation. For details see the description of\n"
574 "of the gpg command \"--generate-revocation\" in the "
576 _("To avoid an accidental use of this file, a colon has been inserted\n"
577 "before the 5 dashes below. Remove this colon with a text editor\n"
578 "before importing and publishing this revocation certificate."));
582 i18n_switchback (orig_codeset);
584 if (es_fclose_snatch (memfp, &leadin, NULL))
585 log_fatal ("error snatching memory stream\n");
587 reason.code = 0x00; /* No particular reason. */
589 rc = create_revocation (fname, &reason, psk, NULL, leadin, 3, cache_nonce);
590 if (!rc && !opt.quiet)
591 log_info (_("revocation certificate stored as '%s.rev'\n"), fname);
602 * Generate a revocation certificate for UNAME
605 gen_revoke (const char *uname)
610 kbnode_t keyblock = NULL;
613 struct revocation_reason_info *reason = NULL;
614 KEYDB_SEARCH_DESC desc;
618 log_error(_("can't do this in batch mode\n"));
619 return GPG_ERR_GENERAL;
622 /* Search the userid; we don't want the whole getkey stuff here. */
623 kdbhd = keydb_new ();
626 rc = gpg_error_from_syserror ();
629 rc = classify_user_id (uname, &desc, 1);
631 rc = keydb_search (kdbhd, &desc, 1, NULL);
634 if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
635 log_error (_("secret key \"%s\" not found\n"), uname);
637 log_error (_("secret key \"%s\" not found: %s\n"),
638 uname, gpg_strerror (rc));
642 rc = keydb_get_keyblock (kdbhd, &keyblock );
645 log_error (_("error reading keyblock: %s\n"), gpg_strerror (rc) );
649 rc = keydb_search (kdbhd, &desc, 1, NULL);
650 if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND)
659 /* TRANSLATORS: The %s prints a key specification which
660 for example has been given at the command line. Several lines
661 lines with secret key infos are printed after this message. */
662 log_error (_("'%s' matches multiple secret keys:\n"), uname);
664 info = format_seckey_info (keyblock->pkt->pkt.public_key);
665 log_error (" %s\n", info);
667 release_kbnode (keyblock);
669 rc = keydb_get_keyblock (kdbhd, &keyblock);
672 info = format_seckey_info (keyblock->pkt->pkt.public_key);
673 log_info (" %s\n", info);
675 release_kbnode (keyblock);
678 rc = keydb_search (kdbhd, &desc, 1, NULL);
680 rc = keydb_get_keyblock (kdbhd, &keyblock);
683 rc = GPG_ERR_AMBIGUOUS_NAME;
689 log_error (_("error searching the keyring: %s\n"), gpg_strerror (rc));
693 /* Get the keyid from the keyblock. */
694 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
698 psk = node->pkt->pkt.public_key;
699 rc = agent_probe_secret_key (NULL, psk);
702 log_error (_("secret key \"%s\" not found: %s\n"),
703 uname, gpg_strerror (rc));
707 keyid_from_pk (psk, keyid );
708 print_seckey_info (psk);
711 if (!cpr_get_answer_is_yes ("gen_revoke.okay",
712 _("Create a revocation certificate for this key? (y/N) ")))
718 /* Get the reason for the revocation. */
719 reason = ask_revocation_reason (1, 0, 1);
722 /* User decided to cancel. */
728 tty_printf (_("ASCII armored output forced.\n"));
730 rc = create_revocation (NULL, reason, psk, keyblock, NULL, 0, NULL);
734 /* and issue a usage notice */
736 "Revocation certificate created.\n\n"
737 "Please move it to a medium which you can hide away; if Mallory gets\n"
738 "access to this certificate he can use it to make your key unusable.\n"
739 "It is smart to print this certificate and store it away, just in case\n"
740 "your media become unreadable. But have some caution: The print system of\n"
741 "your machine might store the data and make it available to others!\n"));
744 release_kbnode (keyblock);
745 keydb_release (kdbhd);
746 release_revocation_reason_info( reason );
752 struct revocation_reason_info *
753 ask_revocation_reason( int key_rev, int cert_rev, int hint )
756 char *description = NULL;
757 struct revocation_reason_info *reason;
758 const char *text_0 = _("No reason specified");
759 const char *text_1 = _("Key has been compromised");
760 const char *text_2 = _("Key is superseded");
761 const char *text_3 = _("Key is no longer used");
762 const char *text_4 = _("User ID is no longer valid");
763 const char *code_text = NULL;
770 tty_printf(_("Please select the reason for the revocation:\n"));
771 tty_printf( " 0 = %s\n", text_0 );
773 tty_printf(" 1 = %s\n", text_1 );
775 tty_printf(" 2 = %s\n", text_2 );
777 tty_printf(" 3 = %s\n", text_3 );
779 tty_printf(" 4 = %s\n", text_4 );
780 tty_printf( " Q = %s\n", _("Cancel") );
782 tty_printf(_("(Probably you want to select %d here)\n"), hint );
786 char *answer = cpr_get("ask_revocation_reason.code",
787 _("Your decision? "));
788 trim_spaces( answer );
790 if( *answer == 'q' || *answer == 'Q')
791 return NULL; /* cancel */
792 if( hint && !*answer )
794 else if(!digitp( answer ) )
800 code = 0x00; /* no particular reason */
803 else if( key_rev && n == 1 ) {
804 code = 0x02; /* key has been compromised */
807 else if( key_rev && n == 2 ) {
808 code = 0x01; /* key is superseded */
811 else if( key_rev && n == 3 ) {
812 code = 0x03; /* key is no longer used */
815 else if( cert_rev && n == 4 ) {
816 code = 0x20; /* uid is no longer valid */
820 tty_printf(_("Invalid selection.\n"));
823 tty_printf(_("Enter an optional description; "
824 "end it with an empty line:\n") );
826 char *answer = cpr_get("ask_revocation_reason.text", "> " );
827 trim_trailing_ws( answer, strlen(answer) );
835 char *p = make_printable_string( answer, strlen(answer), 0 );
841 description = xstrdup(answer);
843 char *p = xmalloc( strlen(description) + strlen(answer) + 2 );
844 strcpy(stpcpy(stpcpy( p, description),"\n"),answer);
851 tty_printf(_("Reason for revocation: %s\n"), code_text );
853 tty_printf(_("(No description given)\n") );
855 tty_printf("%s\n", description );
857 } while( !cpr_get_answer_is_yes("ask_revocation_reason.okay",
858 _("Is this okay? (y/N) ")) );
860 reason = xmalloc( sizeof *reason );
862 reason->desc = description;
866 struct revocation_reason_info *
867 get_default_uid_revocation_reason(void)
869 struct revocation_reason_info *reason;
870 reason = xmalloc( sizeof *reason );
871 reason->code = 0x20; /* uid is no longer valid */
872 reason->desc = strdup(""); /* no text */
877 release_revocation_reason_info( struct revocation_reason_info *reason )
880 xfree( reason->desc );