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