1 /* seckey-cert.c - secret key certificate packet handling
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002 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 3 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, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <assert.h>
25 #include "util.h"
26 #include "memory.h"
27 #include "packet.h"
28 #include "mpi.h"
29 #include "keydb.h"
30 #include "cipher.h"
31 #include "main.h"
32 #include "options.h"
33 #include "i18n.h"
34 #include "status.h"
35
36
37 static int
do_check(PKT_secret_key * sk,const char * tryagain_text,int mode,int * canceled)38 do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
39 int *canceled )
40 {
41 byte *buffer;
42 u16 csum=0;
43 int i, res;
44 unsigned nbytes;
45
46 if( sk->is_protected ) { /* remove the protection */
47 DEK *dek = NULL;
48 u32 keyid[4]; /* 4! because we need two of them */
49 CIPHER_HANDLE cipher_hd=NULL;
50 PKT_secret_key *save_sk;
51
52 if( sk->protect.s2k.mode == 1001 ) {
53 log_info(_("secret key parts are not available\n"));
54 return G10ERR_GENERAL;
55 }
56 if( sk->protect.algo == CIPHER_ALGO_NONE )
57 BUG();
58 if( check_cipher_algo( sk->protect.algo ) ) {
59 log_info(_("protection algorithm %d%s is not supported\n"),
60 sk->protect.algo,sk->protect.algo==1?" (IDEA)":"" );
61 return G10ERR_CIPHER_ALGO;
62 }
63 if(check_digest_algo(sk->protect.s2k.hash_algo))
64 {
65 log_info(_("protection digest %d is not supported\n"),
66 sk->protect.s2k.hash_algo);
67 return G10ERR_DIGEST_ALGO;
68 }
69 keyid_from_sk( sk, keyid );
70 keyid[2] = keyid[3] = 0;
71 if( !sk->is_primary ) {
72 keyid[2] = sk->main_keyid[0];
73 keyid[3] = sk->main_keyid[1];
74 }
75 dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo,
76 &sk->protect.s2k, mode,
77 tryagain_text, canceled );
78 if (!dek && canceled && *canceled)
79 return G10ERR_GENERAL;
80
81 cipher_hd = cipher_open( sk->protect.algo,
82 CIPHER_MODE_AUTO_CFB, 1);
83 cipher_setkey( cipher_hd, dek->key, dek->keylen );
84 xfree(dek);
85 save_sk = copy_secret_key( NULL, sk );
86 cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen );
87 csum = 0;
88 if( sk->version >= 4 ) {
89 unsigned int ndata;
90 byte *p, *data;
91 u16 csumc = 0;
92
93 i = pubkey_get_npkey(sk->pubkey_algo);
94 if (!mpi_is_opaque (sk->skey[i]))
95 p = NULL;
96 else
97 p = mpi_get_opaque (sk->skey[i], &ndata);
98 if (!p)
99 BUG ();
100 if ( ndata > 1 )
101 csumc = p[ndata-2] << 8 | p[ndata-1];
102 data = xmalloc_secure( ndata );
103 cipher_decrypt( cipher_hd, data, p, ndata );
104 mpi_free( sk->skey[i] ); sk->skey[i] = NULL ;
105 p = data;
106 if (sk->protect.sha1chk) {
107 /* This is the new SHA1 checksum method to detect
108 tampering with the key as used by the Klima/Rosa
109 attack */
110 sk->csum = 0;
111 csum = 1;
112 if( ndata < 20 )
113 log_error("not enough bytes for SHA-1 checksum\n");
114 else {
115 MD_HANDLE h = md_open (DIGEST_ALGO_SHA1, 1);
116 if (!h)
117 BUG(); /* algo not available */
118 md_write (h, data, ndata - 20);
119 md_final (h);
120 if (!memcmp (md_read (h, DIGEST_ALGO_SHA1),
121 data + ndata - 20, 20) ) {
122 /* digest does match. We have to keep the old
123 style checksum in sk->csum, so that the
124 test used for unprotected keys does work.
125 This test gets used when we are adding new
126 keys. */
127 sk->csum = csum = checksum (data, ndata-20);
128 }
129 md_close (h);
130 }
131 }
132 else {
133 if( ndata < 2 ) {
134 log_error("not enough bytes for checksum\n");
135 sk->csum = 0;
136 csum = 1;
137 }
138 else {
139 csum = checksum( data, ndata-2);
140 sk->csum = data[ndata-2] << 8 | data[ndata-1];
141 if ( sk->csum != csum ) {
142 /* This is a PGP 7.0.0 workaround */
143 sk->csum = csumc; /* take the encrypted one */
144 }
145 }
146 }
147
148 /* Must check it here otherwise the mpi_read_xx would fail
149 because the length may have an arbitrary value */
150 if( sk->csum == csum ) {
151 for( ; i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
152 nbytes = ndata;
153 sk->skey[i] = mpi_read_from_buffer(p, &nbytes, 1 );
154 if (!sk->skey[i])
155 {
156 /* Checksum was okay, but not correctly
157 decrypted. */
158 sk->csum = 0;
159 csum = 1;
160 break;
161 }
162 ndata -= nbytes;
163 p += nbytes;
164 }
165 /* Note: at this point ndata should be 2 for a simple
166 checksum or 20 for the sha1 digest */
167 }
168 xfree(data);
169 }
170 else {
171 for(i=pubkey_get_npkey(sk->pubkey_algo);
172 i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
173 byte *p;
174 unsigned int ndata;
175
176 if (!mpi_is_opaque (sk->skey[i]))
177 p = NULL;
178 else
179 p = mpi_get_opaque (sk->skey[i], &ndata);
180 if (!p || !(ndata >= 2))
181 BUG ();
182 assert (ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2);
183 buffer = xmalloc_secure (ndata);
184 cipher_sync (cipher_hd);
185 buffer[0] = p[0];
186 buffer[1] = p[1];
187 cipher_decrypt (cipher_hd, buffer+2, p+2, ndata-2);
188 csum += checksum (buffer, ndata);
189 mpi_free (sk->skey[i]);
190 sk->skey[i] = mpi_read_from_buffer (buffer, &ndata, 1);
191 xfree (buffer);
192 if (!sk->skey[i])
193 {
194 /* Checksum was okay, but not correctly
195 decrypted. */
196 sk->csum = 0;
197 csum = 1;
198 break;
199 }
200 /* csum += checksum_mpi (sk->skey[i]); */
201 }
202 }
203 cipher_close( cipher_hd );
204 /* now let's see whether we have used the right passphrase */
205 if( csum != sk->csum ) {
206 copy_secret_key( sk, save_sk );
207 passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
208 free_secret_key( save_sk );
209 return G10ERR_BAD_PASS;
210 }
211 /* the checksum may fail, so we also check the key itself */
212 res = pubkey_check_secret_key( sk->pubkey_algo, sk->skey );
213 if( res ) {
214 copy_secret_key( sk, save_sk );
215 passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
216 free_secret_key( save_sk );
217 return G10ERR_BAD_PASS;
218 }
219 free_secret_key( save_sk );
220 sk->is_protected = 0;
221 }
222 else { /* not protected, assume it is okay if the checksum is okay */
223 csum = 0;
224 for(i=pubkey_get_npkey(sk->pubkey_algo);
225 i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
226 csum += checksum_mpi( sk->skey[i] );
227 }
228 if( csum != sk->csum )
229 return G10ERR_CHECKSUM;
230 }
231
232 return 0;
233 }
234
235
236
237 /****************
238 * Check the secret key
239 * Ask up to 3 (or n) times for a correct passphrase
240 * If n is negative, disable the key info prompt and make n=abs(n)
241 */
242 int
check_secret_key(PKT_secret_key * sk,int n)243 check_secret_key( PKT_secret_key *sk, int n )
244 {
245 int rc = G10ERR_BAD_PASS;
246 int i,mode;
247
248 if (sk && sk->is_protected && sk->protect.s2k.mode == 1002)
249 return 0; /* Let the card support stuff handle this. */
250
251 if(n<0)
252 {
253 n=abs(n);
254 mode=1;
255 }
256 else
257 mode=0;
258
259 if( n < 1 )
260 n = (opt.batch && !opt.use_agent)? 1 : 3; /* use the default value */
261
262 for(i=0; i < n && rc == G10ERR_BAD_PASS; i++ ) {
263 int canceled = 0;
264 const char *tryagain = NULL;
265 if (i) {
266 tryagain = N_("Invalid passphrase; please try again");
267 log_info (_("%s ...\n"), _(tryagain));
268 }
269 rc = do_check( sk, tryagain, mode, &canceled );
270 if( rc == G10ERR_BAD_PASS && is_status_enabled() ) {
271 u32 kid[2];
272 char buf[50];
273
274 keyid_from_sk( sk, kid );
275 sprintf(buf, "%08lX%08lX", (ulong)kid[0], (ulong)kid[1]);
276 write_status_text( STATUS_BAD_PASSPHRASE, buf );
277 }
278 if( have_static_passphrase() || canceled)
279 break;
280 }
281
282 if( !rc )
283 write_status( STATUS_GOOD_PASSPHRASE );
284
285 return rc;
286 }
287
288 /****************
289 * check whether the secret key is protected.
290 * Returns: 0 not protected, -1 on error or the protection algorithm
291 * -2 indicates a card stub.
292 * -3 indicates a not-online stub.
293 */
294 int
is_secret_key_protected(PKT_secret_key * sk)295 is_secret_key_protected( PKT_secret_key *sk )
296 {
297 return sk->is_protected?
298 sk->protect.s2k.mode == 1002? -2 :
299 sk->protect.s2k.mode == 1001? -3 : sk->protect.algo : 0;
300 }
301
302
303
304 /****************
305 * Protect the secret key with the passphrase from DEK
306 */
307 int
protect_secret_key(PKT_secret_key * sk,DEK * dek)308 protect_secret_key( PKT_secret_key *sk, DEK *dek )
309 {
310 int i,j, rc = 0;
311 byte *buffer;
312 unsigned nbytes;
313 u16 csum;
314
315 if( !dek )
316 return 0;
317
318 if( !sk->is_protected ) { /* okay, apply the protection */
319 CIPHER_HANDLE cipher_hd=NULL;
320
321 if( check_cipher_algo( sk->protect.algo ) )
322 rc = G10ERR_CIPHER_ALGO; /* unsupport protection algorithm */
323 else {
324 print_cipher_algo_note( sk->protect.algo );
325 cipher_hd = cipher_open( sk->protect.algo,
326 CIPHER_MODE_AUTO_CFB, 1 );
327 if( cipher_setkey( cipher_hd, dek->key, dek->keylen ) )
328 log_info(_("WARNING: Weak key detected"
329 " - please change passphrase again.\n"));
330 sk->protect.ivlen = cipher_get_blocksize( sk->protect.algo );
331 assert( sk->protect.ivlen <= DIM(sk->protect.iv) );
332 if( sk->protect.ivlen != 8 && sk->protect.ivlen != 16 )
333 BUG(); /* yes, we are very careful */
334 randomize_buffer(sk->protect.iv, sk->protect.ivlen, 1);
335 cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen );
336 if( sk->version >= 4 ) {
337 byte *bufarr[PUBKEY_MAX_NSKEY];
338 unsigned narr[PUBKEY_MAX_NSKEY];
339 unsigned nbits[PUBKEY_MAX_NSKEY];
340 int ndata=0;
341 byte *p, *data;
342
343 for(j=0, i = pubkey_get_npkey(sk->pubkey_algo);
344 i < pubkey_get_nskey(sk->pubkey_algo); i++, j++ ) {
345 assert( !mpi_is_opaque( sk->skey[i] ) );
346 bufarr[j] = mpi_get_buffer( sk->skey[i], &narr[j], NULL );
347 nbits[j] = mpi_get_nbits( sk->skey[i] );
348 ndata += narr[j] + 2;
349 }
350 for( ; j < PUBKEY_MAX_NSKEY; j++ )
351 bufarr[j] = NULL;
352 ndata += opt.simple_sk_checksum? 2 : 20; /* for checksum */
353
354 data = xmalloc_secure( ndata );
355 p = data;
356 for(j=0; j < PUBKEY_MAX_NSKEY && bufarr[j]; j++ ) {
357 p[0] = nbits[j] >> 8 ;
358 p[1] = nbits[j];
359 p += 2;
360 memcpy(p, bufarr[j], narr[j] );
361 p += narr[j];
362 xfree(bufarr[j]);
363 }
364
365 if (opt.simple_sk_checksum) {
366 log_info (_("generating the deprecated 16-bit checksum"
367 " for secret key protection\n"));
368 csum = checksum( data, ndata-2);
369 sk->csum = csum;
370 *p++ = csum >> 8;
371 *p++ = csum;
372 sk->protect.sha1chk = 0;
373 }
374 else {
375 MD_HANDLE h = md_open (DIGEST_ALGO_SHA1, 1);
376 if (!h)
377 BUG(); /* algo not available */
378 md_write (h, data, ndata - 20);
379 md_final (h);
380 memcpy (p, md_read (h, DIGEST_ALGO_SHA1), 20);
381 p += 20;
382 md_close (h);
383 sk->csum = csum = 0;
384 sk->protect.sha1chk = 1;
385 }
386 assert( p == data+ndata );
387
388 cipher_encrypt( cipher_hd, data, data, ndata );
389 for(i = pubkey_get_npkey(sk->pubkey_algo);
390 i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
391 mpi_free( sk->skey[i] );
392 sk->skey[i] = NULL;
393 }
394 i = pubkey_get_npkey(sk->pubkey_algo);
395 sk->skey[i] = mpi_set_opaque(NULL, data, ndata );
396 }
397 else {
398 csum = 0;
399 for(i=pubkey_get_npkey(sk->pubkey_algo);
400 i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
401 byte *data;
402 unsigned int nbits;
403
404 csum += checksum_mpi (sk->skey[i]);
405 buffer = mpi_get_buffer( sk->skey[i], &nbytes, NULL );
406 cipher_sync (cipher_hd);
407 assert ( !mpi_is_opaque (sk->skey[i]) );
408 data = xmalloc (nbytes+2);
409 nbits = mpi_get_nbits (sk->skey[i]);
410 assert (nbytes == (nbits + 7)/8);
411 data[0] = nbits >> 8;
412 data[1] = nbits;
413 cipher_encrypt (cipher_hd, data+2, buffer, nbytes);
414 xfree( buffer );
415
416 mpi_free (sk->skey[i]);
417 sk->skey[i] = mpi_set_opaque (NULL, data, nbytes+2);
418 }
419 sk->csum = csum;
420 }
421 sk->is_protected = 1;
422 cipher_close( cipher_hd );
423 }
424 }
425 return rc;
426 }
427
428