mutt stable branch with some hacks
at jcs 251 lines 4.4 kB view raw
1/* 2 * Copyright (C) 1997-2002 Thomas Roessler <roessler@does-not-exist.org> 3 * 4 * This program is free software; you can redistribute it 5 * and/or modify it under the terms of the GNU General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later 8 * version. 9 * 10 * This program is distributed in the hope that it will be 11 * useful, but WITHOUT ANY WARRANTY; without even the implied 12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 13 * PURPOSE. See the GNU General Public License for more 14 * details. 15 * 16 * You should have received a copy of the GNU General Public 17 * License along with this program; if not, write to the Free 18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA. 20 */ 21 22/* Generally useful, pgp-related functions. */ 23 24#if HAVE_CONFIG_H 25# include "config.h" 26#endif 27 28#include <stdio.h> 29#include <stdlib.h> 30#include <string.h> 31#include <unistd.h> 32#include <time.h> 33 34#include "mutt.h" 35#include "lib.h" 36#include "pgplib.h" 37 38const char *pgp_pkalgbytype (unsigned char type) 39{ 40 switch (type) 41 { 42 case 1: 43 return "RSA"; 44 case 2: 45 return "RSA"; 46 case 3: 47 return "RSA"; 48 case 16: 49 return "ElG"; 50 case 17: 51 return "DSA"; 52 case 20: 53 return "ElG"; 54 default: 55 return "unk"; 56 } 57} 58 59 60 61/* unused */ 62 63#if 0 64 65static const char *hashalgbytype (unsigned char type) 66{ 67 switch (type) 68 { 69 case 1: 70 return "MD5"; 71 case 2: 72 return "SHA1"; 73 case 3: 74 return "RIPE-MD/160"; 75 case 4: 76 return "HAVAL"; 77 default: 78 return "unknown"; 79 } 80} 81 82#endif 83 84short pgp_canencrypt (unsigned char type) 85{ 86 switch (type) 87 { 88 case 1: 89 case 2: 90 case 16: 91 case 20: 92 return 1; 93 default: 94 return 0; 95 } 96} 97 98short pgp_cansign (unsigned char type) 99{ 100 switch (type) 101 { 102 case 1: 103 case 3: 104 case 17: 105 case 20: 106 return 1; 107 default: 108 return 0; 109 } 110} 111 112/* return values: 113 114 * 1 = sign only 115 * 2 = encrypt only 116 * 3 = both 117 */ 118 119short pgp_get_abilities (unsigned char type) 120{ 121 return (pgp_canencrypt (type) << 1) | pgp_cansign (type); 122} 123 124void pgp_free_sig (pgp_sig_t **sigp) 125{ 126 pgp_sig_t *sp, *q; 127 128 if (!sigp || !*sigp) 129 return; 130 131 for (sp = *sigp; sp; sp = q) 132 { 133 q = sp->next; 134 FREE (&sp); 135 } 136 137 *sigp = NULL; 138} 139 140void pgp_free_uid (pgp_uid_t ** upp) 141{ 142 pgp_uid_t *up, *q; 143 144 if (!upp || !*upp) 145 return; 146 for (up = *upp; up; up = q) 147 { 148 q = up->next; 149 pgp_free_sig (&up->sigs); 150 FREE (&up->addr); 151 FREE (&up); 152 } 153 154 *upp = NULL; 155} 156 157pgp_uid_t *pgp_copy_uids (pgp_uid_t *up, pgp_key_t parent) 158{ 159 pgp_uid_t *l = NULL; 160 pgp_uid_t **lp = &l; 161 162 for (; up; up = up->next) 163 { 164 *lp = safe_calloc (1, sizeof (pgp_uid_t)); 165 (*lp)->trust = up->trust; 166 (*lp)->flags = up->flags; 167 (*lp)->addr = safe_strdup (up->addr); 168 (*lp)->parent = parent; 169 lp = &(*lp)->next; 170 } 171 172 return l; 173} 174 175static void _pgp_free_key (pgp_key_t *kpp) 176{ 177 pgp_key_t kp; 178 179 if (!kpp || !*kpp) 180 return; 181 182 kp = *kpp; 183 184 pgp_free_uid (&kp->address); 185 FREE (&kp->keyid); 186 FREE (&kp->fingerprint); 187 /* mutt_crypt.h: 'typedef struct pgp_keyinfo *pgp_key_t;' */ 188 FREE (kpp); /* __FREE_CHECKED__ */ 189} 190 191pgp_key_t pgp_remove_key (pgp_key_t *klist, pgp_key_t key) 192{ 193 pgp_key_t *last; 194 pgp_key_t p, q, r; 195 196 if (!klist || !*klist || !key) 197 return NULL; 198 199 if (key->parent && key->parent != key) 200 key = key->parent; 201 202 last = klist; 203 for (p = *klist; p && p != key; p = p->next) 204 last = &p->next; 205 206 if (!p) 207 return NULL; 208 209 for (q = p->next, r = p; q && q->parent == p; q = q->next) 210 r = q; 211 212 if (r) 213 r->next = NULL; 214 215 *last = q; 216 return q; 217} 218 219void pgp_free_key (pgp_key_t *kpp) 220{ 221 pgp_key_t p, q, r; 222 223 if (!kpp || !*kpp) 224 return; 225 226 if ((*kpp)->parent && (*kpp)->parent != *kpp) 227 *kpp = (*kpp)->parent; 228 229 /* Order is important here: 230 * 231 * - First free all children. 232 * - If we are an orphan (i.e., our parent was not in the key list), 233 * free our parent. 234 * - free ourselves. 235 */ 236 237 for (p = *kpp; p; p = q) 238 { 239 for (q = p->next; q && q->parent == p; q = r) 240 { 241 r = q->next; 242 _pgp_free_key (&q); 243 } 244 if (p->parent) 245 _pgp_free_key (&p->parent); 246 247 _pgp_free_key (&p); 248 } 249 250 *kpp = NULL; 251}