1 /* seckey-cert.c - secret key certificate packet handling
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3 * 2006 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 2 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, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
41 do_check( PKT_secret_key
*sk
, const char *tryagain_text
, int mode
,
50 if( sk
->is_protected
) { /* remove the protection */
52 u32 keyid
[4]; /* 4! because we need two of them */
53 gcry_cipher_hd_t cipher_hd
=NULL
;
54 PKT_secret_key
*save_sk
;
56 if( sk
->protect
.s2k
.mode
== 1001 ) {
57 log_info(_("secret key parts are not available\n"));
58 return G10ERR_GENERAL
;
60 if( sk
->protect
.algo
== CIPHER_ALGO_NONE
)
62 if( openpgp_cipher_test_algo( sk
->protect
.algo
) ) {
63 log_info(_("protection algorithm %d%s is not supported\n"),
64 sk
->protect
.algo
,sk
->protect
.algo
==1?" (IDEA)":"" );
65 if (sk
->protect
.algo
==CIPHER_ALGO_IDEA
)
67 write_status (STATUS_RSA_OR_IDEA
);
70 return G10ERR_CIPHER_ALGO
;
72 if(gcry_md_test_algo (sk
->protect
.s2k
.hash_algo
))
74 log_info(_("protection digest %d is not supported\n"),
75 sk
->protect
.s2k
.hash_algo
);
76 return G10ERR_DIGEST_ALGO
;
78 keyid_from_sk( sk
, keyid
);
79 keyid
[2] = keyid
[3] = 0;
80 if( !sk
->is_primary
) {
81 keyid
[2] = sk
->main_keyid
[0];
82 keyid
[3] = sk
->main_keyid
[1];
84 dek
= passphrase_to_dek( keyid
, sk
->pubkey_algo
, sk
->protect
.algo
,
85 &sk
->protect
.s2k
, mode
,
86 tryagain_text
, canceled
);
87 if (!dek
&& canceled
&& *canceled
)
88 return G10ERR_GENERAL
;
91 err
= gcry_cipher_open (&cipher_hd
, sk
->protect
.algo
,
94 | (sk
->protect
.algo
>= 100 ?
95 0 : GCRY_CIPHER_ENABLE_SYNC
)));
97 log_fatal ("cipher open failed: %s\n", gpg_strerror (err
) );
99 err
= gcry_cipher_setkey (cipher_hd
, dek
->key
, dek
->keylen
);
101 log_fatal ("set key failed: %s\n", gpg_strerror (err
) );
104 save_sk
= copy_secret_key( NULL
, sk
);
106 gcry_cipher_setiv ( cipher_hd
, sk
->protect
.iv
, sk
->protect
.ivlen
);
109 if( sk
->version
>= 4 ) {
111 unsigned int ndatabits
;
115 i
= pubkey_get_npkey(sk
->pubkey_algo
);
117 assert ( gcry_mpi_get_flag (sk
->skey
[i
], GCRYMPI_FLAG_OPAQUE
));
118 p
= gcry_mpi_get_opaque ( sk
->skey
[i
], &ndatabits
);
119 ndata
= (ndatabits
+7)/8;
122 csumc
= p
[ndata
-2] << 8 | p
[ndata
-1];
123 data
= xmalloc_secure ( ndata
);
124 gcry_cipher_decrypt ( cipher_hd
, data
, ndata
, p
, ndata
);
125 gcry_mpi_release (sk
->skey
[i
]); sk
->skey
[i
] = NULL
;
128 if (sk
->protect
.sha1chk
) {
129 /* This is the new SHA1 checksum method to detect
130 tampering with the key as used by the Klima/Rosa
135 log_error("not enough bytes for SHA-1 checksum\n");
139 if ( gcry_md_open (&h
, DIGEST_ALGO_SHA1
, 1))
140 BUG(); /* Algo not available. */
141 gcry_md_write (h
, data
, ndata
- 20);
143 if (!memcmp (gcry_md_read (h
, DIGEST_ALGO_SHA1
),
144 data
+ ndata
- 20, 20) )
146 /* Digest does match. We have to keep the old
147 style checksum in sk->csum, so that the
148 test used for unprotected keys does work.
149 This test gets used when we are adding new
151 sk
->csum
= csum
= checksum (data
, ndata
-20);
158 log_error("not enough bytes for checksum\n");
163 csum
= checksum( data
, ndata
-2);
164 sk
->csum
= data
[ndata
-2] << 8 | data
[ndata
-1];
165 if ( sk
->csum
!= csum
) {
166 /* This is a PGP 7.0.0 workaround */
167 sk
->csum
= csumc
; /* take the encrypted one */
172 /* Must check it here otherwise the mpi_read_xx would fail
173 because the length may have an arbitrary value */
174 if( sk
->csum
== csum
) {
175 for( ; i
< pubkey_get_nskey(sk
->pubkey_algo
); i
++ ) {
176 if ( gcry_mpi_scan( &sk
->skey
[i
], GCRYMPI_FMT_PGP
,
179 /* Checksum was okay, but not correctly
188 /* Note: at this point ndata should be 2 for a simple
189 checksum or 20 for the sha1 digest */
194 for(i
=pubkey_get_npkey(sk
->pubkey_algo
);
195 i
< pubkey_get_nskey(sk
->pubkey_algo
); i
++ ) {
198 unsigned int ndatabits
;
200 assert (gcry_mpi_get_flag (sk
->skey
[i
], GCRYMPI_FLAG_OPAQUE
));
201 p
= gcry_mpi_get_opaque (sk
->skey
[i
], &ndatabits
);
202 ndata
= (ndatabits
+7)/8;
204 assert (ndata
== ((p
[0] << 8 | p
[1]) + 7)/8 + 2);
205 buffer
= xmalloc_secure (ndata
);
206 gcry_cipher_sync (cipher_hd
);
209 gcry_cipher_decrypt (cipher_hd
, buffer
+2, ndata
-2,
211 csum
+= checksum (buffer
, ndata
);
212 gcry_mpi_release (sk
->skey
[i
]);
214 err
= gcry_mpi_scan( &sk
->skey
[i
], GCRYMPI_FMT_USG
,
215 buffer
, ndata
, &ndata
);
219 /* Checksum was okay, but not correctly
225 /* csum += checksum_mpi (sk->skey[i]); */
228 gcry_cipher_close ( cipher_hd
);
230 /* Now let's see whether we have used the correct passphrase. */
231 if( csum
!= sk
->csum
) {
232 copy_secret_key( sk
, save_sk
);
233 passphrase_clear_cache ( keyid
, NULL
, sk
->pubkey_algo
);
234 free_secret_key( save_sk
);
235 return gpg_error (GPG_ERR_BAD_PASSPHRASE
);
238 /* The checksum may fail, so we also check the key itself. */
239 res
= pk_check_secret_key ( sk
->pubkey_algo
, sk
->skey
);
241 copy_secret_key( sk
, save_sk
);
242 passphrase_clear_cache ( keyid
, NULL
, sk
->pubkey_algo
);
243 free_secret_key( save_sk
);
244 return gpg_error (GPG_ERR_BAD_PASSPHRASE
);
246 free_secret_key( save_sk
);
247 sk
->is_protected
= 0;
249 else { /* not protected, assume it is okay if the checksum is okay */
251 for(i
=pubkey_get_npkey(sk
->pubkey_algo
);
252 i
< pubkey_get_nskey(sk
->pubkey_algo
); i
++ ) {
253 csum
+= checksum_mpi( sk
->skey
[i
] );
255 if( csum
!= sk
->csum
)
256 return G10ERR_CHECKSUM
;
265 * Check the secret key
266 * Ask up to 3 (or n) times for a correct passphrase
267 * If n is negative, disable the key info prompt and make n=abs(n)
270 check_secret_key( PKT_secret_key
*sk
, int n
)
272 int rc
= gpg_error (GPG_ERR_BAD_PASSPHRASE
);
275 if (sk
&& sk
->is_protected
&& sk
->protect
.s2k
.mode
== 1002)
276 return 0; /* Let the scdaemon handle this. */
287 n
= (opt
.batch
&& !opt
.use_agent
)? 1 : 3; /* use the default value */
289 for(i
=0; i
< n
&& gpg_err_code (rc
) == GPG_ERR_BAD_PASSPHRASE
; i
++ ) {
291 const char *tryagain
= NULL
;
293 tryagain
= N_("Invalid passphrase; please try again");
294 log_info (_("%s ...\n"), _(tryagain
));
296 rc
= do_check( sk
, tryagain
, mode
, &canceled
);
297 if ( gpg_err_code (rc
) == GPG_ERR_BAD_PASSPHRASE
298 && is_status_enabled () ) {
302 keyid_from_sk( sk
, kid
);
303 sprintf(buf
, "%08lX%08lX", (ulong
)kid
[0], (ulong
)kid
[1]);
304 write_status_text( STATUS_BAD_PASSPHRASE
, buf
);
306 if( have_static_passphrase() || canceled
)
311 write_status( STATUS_GOOD_PASSPHRASE
);
317 * check whether the secret key is protected.
318 * Returns: 0 not protected, -1 on error or the protection algorithm
319 * -2 indicates a card stub.
320 * -3 indicates a not-online stub.
323 is_secret_key_protected( PKT_secret_key
*sk
)
325 return sk
->is_protected
?
326 sk
->protect
.s2k
.mode
== 1002? -2 :
327 sk
->protect
.s2k
.mode
== 1001? -3 : sk
->protect
.algo
: 0;
333 * Protect the secret key with the passphrase from DEK
336 protect_secret_key( PKT_secret_key
*sk
, DEK
*dek
)
346 if( !sk
->is_protected
) { /* okay, apply the protection */
347 gcry_cipher_hd_t cipher_hd
=NULL
;
349 if ( openpgp_cipher_test_algo ( sk
->protect
.algo
) ) {
350 /* Unsupport protection algorithm. */
351 rc
= gpg_error (GPG_ERR_CIPHER_ALGO
);
354 print_cipher_algo_note( sk
->protect
.algo
);
356 if ( gcry_cipher_open (&cipher_hd
, sk
->protect
.algo
,
357 GCRY_CIPHER_MODE_CFB
,
359 | (sk
->protect
.algo
>= 100 ?
360 0 : GCRY_CIPHER_ENABLE_SYNC
))) )
362 if ( gcry_cipher_setkey ( cipher_hd
, dek
->key
, dek
->keylen
) )
363 log_info(_("WARNING: Weak key detected"
364 " - please change passphrase again.\n"));
365 sk
->protect
.ivlen
= gcry_cipher_get_algo_blklen (sk
->protect
.algo
);
366 assert( sk
->protect
.ivlen
<= DIM(sk
->protect
.iv
) );
367 if( sk
->protect
.ivlen
!= 8 && sk
->protect
.ivlen
!= 16 )
368 BUG(); /* yes, we are very careful */
369 gcry_create_nonce (sk
->protect
.iv
, sk
->protect
.ivlen
);
370 gcry_cipher_setiv (cipher_hd
, sk
->protect
.iv
, sk
->protect
.ivlen
);
371 if( sk
->version
>= 4 ) {
372 byte
*bufarr
[PUBKEY_MAX_NSKEY
];
373 unsigned narr
[PUBKEY_MAX_NSKEY
];
374 unsigned nbits
[PUBKEY_MAX_NSKEY
];
378 for (j
=0, i
= pubkey_get_npkey(sk
->pubkey_algo
);
379 i
< pubkey_get_nskey(sk
->pubkey_algo
); i
++, j
++ )
381 assert (!gcry_mpi_get_flag (sk
->skey
[i
],
382 GCRYMPI_FLAG_OPAQUE
));
383 if (gcry_mpi_aprint (GCRYMPI_FMT_USG
, bufarr
+j
,
384 narr
+j
, sk
->skey
[i
]))
386 nbits
[j
] = gcry_mpi_get_nbits (sk
->skey
[i
]);
387 ndata
+= narr
[j
] + 2;
389 for ( ; j
< PUBKEY_MAX_NSKEY
; j
++ )
392 ndata
+= opt
.simple_sk_checksum
? 2 : 20; /* for checksum */
394 data
= xmalloc_secure( ndata
);
396 for(j
=0; j
< PUBKEY_MAX_NSKEY
&& bufarr
[j
]; j
++ ) {
397 p
[0] = nbits
[j
] >> 8 ;
400 memcpy(p
, bufarr
[j
], narr
[j
] );
405 if (opt
.simple_sk_checksum
) {
406 log_info (_("generating the deprecated 16-bit checksum"
407 " for secret key protection\n"));
408 csum
= checksum( data
, ndata
-2);
412 sk
->protect
.sha1chk
= 0;
417 if (gcry_md_open (&h
, GCRY_MD_SHA1
, 1))
418 BUG(); /* Algo not available. */
419 gcry_md_write (h
, data
, ndata
- 20);
421 memcpy (p
, gcry_md_read (h
, DIGEST_ALGO_SHA1
), 20);
425 sk
->protect
.sha1chk
= 1;
427 assert( p
== data
+ndata
);
429 gcry_cipher_encrypt (cipher_hd
, data
, ndata
, NULL
, 0);
430 for (i
= pubkey_get_npkey(sk
->pubkey_algo
);
431 i
< pubkey_get_nskey(sk
->pubkey_algo
); i
++ )
433 gcry_mpi_release (sk
->skey
[i
]);
436 i
= pubkey_get_npkey(sk
->pubkey_algo
);
437 sk
->skey
[i
] = gcry_mpi_set_opaque (NULL
, data
, ndata
*8 );
441 for(i
=pubkey_get_npkey(sk
->pubkey_algo
);
442 i
< pubkey_get_nskey(sk
->pubkey_algo
); i
++ ) {
446 csum
+= checksum_mpi (sk
->skey
[i
]);
448 if (gcry_mpi_aprint (GCRYMPI_FMT_USG
, &buffer
,
449 &nbytes
, sk
->skey
[i
] ))
451 gcry_cipher_sync (cipher_hd
);
452 assert (!gcry_mpi_get_flag (sk
->skey
[i
],
453 GCRYMPI_FLAG_OPAQUE
));
455 data
= xmalloc (nbytes
+2); /* fixme: need xtrymalloc. */
456 nbits
= gcry_mpi_get_nbits (sk
->skey
[i
]);
457 assert (nbytes
== (nbits
+ 7)/8);
458 data
[0] = nbits
>> 8;
460 gcry_cipher_encrypt (cipher_hd
, data
+2, nbytes
,
464 gcry_mpi_release (sk
->skey
[i
]);
465 sk
->skey
[i
] = gcry_mpi_set_opaque (NULL
,
466 data
, (nbytes
+2)*8 );
470 sk
->is_protected
= 1;
471 gcry_cipher_close (cipher_hd
);