1 /* seckey-cert.c - secret key certificate packet handling
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3 * 2006, 2009 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 <http://www.gnu.org/licenses/>.
39 do_check( PKT_secret_key
*sk
, const char *tryagain_text
, int mode
,
48 if( sk
->is_protected
) { /* remove the protection */
50 u32 keyid
[4]; /* 4! because we need two of them */
51 gcry_cipher_hd_t cipher_hd
=NULL
;
52 PKT_secret_key
*save_sk
;
54 if( sk
->protect
.s2k
.mode
== 1001 ) {
55 log_info(_("secret key parts are not available\n"));
56 return G10ERR_UNU_SECKEY
;
58 if( sk
->protect
.algo
== CIPHER_ALGO_NONE
)
60 if( openpgp_cipher_test_algo( sk
->protect
.algo
) ) {
61 log_info(_("protection algorithm %d%s is not supported\n"),
62 sk
->protect
.algo
,sk
->protect
.algo
==1?" (IDEA)":"" );
63 if (sk
->protect
.algo
==CIPHER_ALGO_IDEA
)
65 write_status (STATUS_RSA_OR_IDEA
);
68 return G10ERR_CIPHER_ALGO
;
70 if(gcry_md_test_algo (sk
->protect
.s2k
.hash_algo
))
72 log_info(_("protection digest %d is not supported\n"),
73 sk
->protect
.s2k
.hash_algo
);
74 return G10ERR_DIGEST_ALGO
;
76 keyid_from_sk( sk
, keyid
);
77 keyid
[2] = keyid
[3] = 0;
78 if( !sk
->is_primary
) {
79 keyid
[2] = sk
->main_keyid
[0];
80 keyid
[3] = sk
->main_keyid
[1];
82 dek
= passphrase_to_dek( keyid
, sk
->pubkey_algo
, sk
->protect
.algo
,
83 &sk
->protect
.s2k
, mode
,
84 tryagain_text
, canceled
);
85 if (!dek
&& canceled
&& *canceled
)
86 return G10ERR_GENERAL
;
89 err
= openpgp_cipher_open (&cipher_hd
, sk
->protect
.algo
,
92 | (sk
->protect
.algo
>= 100 ?
93 0 : GCRY_CIPHER_ENABLE_SYNC
)));
95 log_fatal ("cipher open failed: %s\n", gpg_strerror (err
) );
97 err
= gcry_cipher_setkey (cipher_hd
, dek
->key
, dek
->keylen
);
99 log_fatal ("set key failed: %s\n", gpg_strerror (err
) );
102 save_sk
= copy_secret_key( NULL
, sk
);
104 gcry_cipher_setiv ( cipher_hd
, sk
->protect
.iv
, sk
->protect
.ivlen
);
107 if( sk
->version
>= 4 ) {
109 unsigned int ndatabits
;
113 i
= pubkey_get_npkey(sk
->pubkey_algo
);
115 assert ( gcry_mpi_get_flag (sk
->skey
[i
], GCRYMPI_FLAG_OPAQUE
));
116 p
= gcry_mpi_get_opaque ( sk
->skey
[i
], &ndatabits
);
117 ndata
= (ndatabits
+7)/8;
120 csumc
= p
[ndata
-2] << 8 | p
[ndata
-1];
121 data
= xmalloc_secure ( ndata
);
122 gcry_cipher_decrypt ( cipher_hd
, data
, ndata
, p
, ndata
);
123 gcry_mpi_release (sk
->skey
[i
]); sk
->skey
[i
] = NULL
;
126 if (sk
->protect
.sha1chk
) {
127 /* This is the new SHA1 checksum method to detect
128 tampering with the key as used by the Klima/Rosa
133 log_error("not enough bytes for SHA-1 checksum\n");
137 if ( gcry_md_open (&h
, DIGEST_ALGO_SHA1
, 1))
138 BUG(); /* Algo not available. */
139 gcry_md_write (h
, data
, ndata
- 20);
141 if (!memcmp (gcry_md_read (h
, DIGEST_ALGO_SHA1
),
142 data
+ ndata
- 20, 20) )
144 /* Digest does match. We have to keep the old
145 style checksum in sk->csum, so that the
146 test used for unprotected keys does work.
147 This test gets used when we are adding new
149 sk
->csum
= csum
= checksum (data
, ndata
-20);
156 log_error("not enough bytes for checksum\n");
161 csum
= checksum( data
, ndata
-2);
162 sk
->csum
= data
[ndata
-2] << 8 | data
[ndata
-1];
163 if ( sk
->csum
!= csum
) {
164 /* This is a PGP 7.0.0 workaround */
165 sk
->csum
= csumc
; /* take the encrypted one */
170 /* Must check it here otherwise the mpi_read_xx would fail
171 because the length may have an arbitrary value */
172 if( sk
->csum
== csum
) {
173 for( ; i
< pubkey_get_nskey(sk
->pubkey_algo
); i
++ ) {
174 if ( gcry_mpi_scan( &sk
->skey
[i
], GCRYMPI_FMT_PGP
,
177 /* Checksum was okay, but not correctly
186 /* Note: at this point ndata should be 2 for a simple
187 checksum or 20 for the sha1 digest */
192 for(i
=pubkey_get_npkey(sk
->pubkey_algo
);
193 i
< pubkey_get_nskey(sk
->pubkey_algo
); i
++ ) {
196 unsigned int ndatabits
;
198 assert (gcry_mpi_get_flag (sk
->skey
[i
], GCRYMPI_FLAG_OPAQUE
));
199 p
= gcry_mpi_get_opaque (sk
->skey
[i
], &ndatabits
);
200 ndata
= (ndatabits
+7)/8;
202 assert (ndata
== ((p
[0] << 8 | p
[1]) + 7)/8 + 2);
203 buffer
= xmalloc_secure (ndata
);
204 gcry_cipher_sync (cipher_hd
);
207 gcry_cipher_decrypt (cipher_hd
, buffer
+2, ndata
-2,
209 csum
+= checksum (buffer
, ndata
);
210 gcry_mpi_release (sk
->skey
[i
]);
212 err
= gcry_mpi_scan( &sk
->skey
[i
], GCRYMPI_FMT_PGP
,
213 buffer
, ndata
, &ndata
);
217 /* Checksum was okay, but not correctly
223 /* csum += checksum_mpi (sk->skey[i]); */
226 gcry_cipher_close ( cipher_hd
);
228 /* Now let's see whether we have used the correct passphrase. */
229 if( csum
!= sk
->csum
) {
230 copy_secret_key( sk
, save_sk
);
231 passphrase_clear_cache ( keyid
, NULL
, sk
->pubkey_algo
);
232 free_secret_key( save_sk
);
233 return gpg_error (GPG_ERR_BAD_PASSPHRASE
);
236 /* The checksum may fail, so we also check the key itself. */
237 res
= pk_check_secret_key ( sk
->pubkey_algo
, sk
->skey
);
239 copy_secret_key( sk
, save_sk
);
240 passphrase_clear_cache ( keyid
, NULL
, sk
->pubkey_algo
);
241 free_secret_key( save_sk
);
242 return gpg_error (GPG_ERR_BAD_PASSPHRASE
);
244 free_secret_key( save_sk
);
245 sk
->is_protected
= 0;
247 else { /* not protected, assume it is okay if the checksum is okay */
249 for(i
=pubkey_get_npkey(sk
->pubkey_algo
);
250 i
< pubkey_get_nskey(sk
->pubkey_algo
); i
++ ) {
251 csum
+= checksum_mpi( sk
->skey
[i
] );
253 if( csum
!= sk
->csum
)
254 return G10ERR_CHECKSUM
;
263 * Check the secret key
264 * Ask up to 3 (or n) times for a correct passphrase
265 * If n is negative, disable the key info prompt and make n=abs(n)
268 check_secret_key( PKT_secret_key
*sk
, int n
)
270 int rc
= gpg_error (GPG_ERR_BAD_PASSPHRASE
);
273 if (sk
&& sk
->is_protected
&& sk
->protect
.s2k
.mode
== 1002)
274 return 0; /* Let the scdaemon handle this. */
285 n
= 3; /* Use the default value */
287 for(i
=0; i
< n
&& gpg_err_code (rc
) == GPG_ERR_BAD_PASSPHRASE
; i
++ ) {
289 const char *tryagain
= NULL
;
291 tryagain
= N_("Invalid passphrase; please try again");
292 log_info (_("%s ...\n"), _(tryagain
));
294 rc
= do_check( sk
, tryagain
, mode
, &canceled
);
295 if ( gpg_err_code (rc
) == GPG_ERR_BAD_PASSPHRASE
296 && is_status_enabled () ) {
300 keyid_from_sk( sk
, kid
);
301 sprintf(buf
, "%08lX%08lX", (ulong
)kid
[0], (ulong
)kid
[1]);
302 write_status_text( STATUS_BAD_PASSPHRASE
, buf
);
304 if( have_static_passphrase() || canceled
)
309 write_status( STATUS_GOOD_PASSPHRASE
);
315 * check whether the secret key is protected.
316 * Returns: 0 not protected, -1 on error or the protection algorithm
317 * -2 indicates a card stub.
318 * -3 indicates a not-online stub.
321 is_secret_key_protected( PKT_secret_key
*sk
)
323 return sk
->is_protected
?
324 sk
->protect
.s2k
.mode
== 1002? -2 :
325 sk
->protect
.s2k
.mode
== 1001? -3 : sk
->protect
.algo
: 0;
331 * Protect the secret key with the passphrase from DEK
334 protect_secret_key( PKT_secret_key
*sk
, DEK
*dek
)
344 if( !sk
->is_protected
) { /* okay, apply the protection */
345 gcry_cipher_hd_t cipher_hd
=NULL
;
347 if ( openpgp_cipher_test_algo ( sk
->protect
.algo
) ) {
348 /* Unsupport protection algorithm. */
349 rc
= gpg_error (GPG_ERR_CIPHER_ALGO
);
352 print_cipher_algo_note( sk
->protect
.algo
);
354 if ( openpgp_cipher_open (&cipher_hd
, sk
->protect
.algo
,
355 GCRY_CIPHER_MODE_CFB
,
357 | (sk
->protect
.algo
>= 100 ?
358 0 : GCRY_CIPHER_ENABLE_SYNC
))) )
360 if ( gcry_cipher_setkey ( cipher_hd
, dek
->key
, dek
->keylen
) )
361 log_info(_("WARNING: Weak key detected"
362 " - please change passphrase again.\n"));
363 sk
->protect
.ivlen
= openpgp_cipher_get_algo_blklen (sk
->protect
.algo
);
364 assert( sk
->protect
.ivlen
<= DIM(sk
->protect
.iv
) );
365 if( sk
->protect
.ivlen
!= 8 && sk
->protect
.ivlen
!= 16 )
366 BUG(); /* yes, we are very careful */
367 gcry_create_nonce (sk
->protect
.iv
, sk
->protect
.ivlen
);
368 gcry_cipher_setiv (cipher_hd
, sk
->protect
.iv
, sk
->protect
.ivlen
);
369 if( sk
->version
>= 4 ) {
370 byte
*bufarr
[PUBKEY_MAX_NSKEY
];
371 size_t narr
[PUBKEY_MAX_NSKEY
];
372 unsigned int nbits
[PUBKEY_MAX_NSKEY
];
376 for (j
=0, i
= pubkey_get_npkey(sk
->pubkey_algo
);
377 i
< pubkey_get_nskey(sk
->pubkey_algo
); i
++, j
++ )
379 assert (!gcry_mpi_get_flag (sk
->skey
[i
],
380 GCRYMPI_FLAG_OPAQUE
));
381 if (gcry_mpi_aprint (GCRYMPI_FMT_USG
, bufarr
+j
,
382 narr
+j
, sk
->skey
[i
]))
384 nbits
[j
] = gcry_mpi_get_nbits (sk
->skey
[i
]);
385 ndata
+= narr
[j
] + 2;
387 for ( ; j
< PUBKEY_MAX_NSKEY
; j
++ )
390 ndata
+= opt
.simple_sk_checksum
? 2 : 20; /* for checksum */
392 data
= xmalloc_secure( ndata
);
394 for(j
=0; j
< PUBKEY_MAX_NSKEY
&& bufarr
[j
]; j
++ ) {
395 p
[0] = nbits
[j
] >> 8 ;
398 memcpy(p
, bufarr
[j
], narr
[j
] );
403 if (opt
.simple_sk_checksum
) {
404 log_info (_("generating the deprecated 16-bit checksum"
405 " for secret key protection\n"));
406 csum
= checksum( data
, ndata
-2);
410 sk
->protect
.sha1chk
= 0;
415 if (gcry_md_open (&h
, GCRY_MD_SHA1
, 1))
416 BUG(); /* Algo not available. */
417 gcry_md_write (h
, data
, ndata
- 20);
419 memcpy (p
, gcry_md_read (h
, DIGEST_ALGO_SHA1
), 20);
423 sk
->protect
.sha1chk
= 1;
425 assert( p
== data
+ndata
);
427 gcry_cipher_encrypt (cipher_hd
, data
, ndata
, NULL
, 0);
428 for (i
= pubkey_get_npkey(sk
->pubkey_algo
);
429 i
< pubkey_get_nskey(sk
->pubkey_algo
); i
++ )
431 gcry_mpi_release (sk
->skey
[i
]);
434 i
= pubkey_get_npkey(sk
->pubkey_algo
);
435 sk
->skey
[i
] = gcry_mpi_set_opaque (NULL
, data
, ndata
*8 );
439 for(i
=pubkey_get_npkey(sk
->pubkey_algo
);
440 i
< pubkey_get_nskey(sk
->pubkey_algo
); i
++ ) {
444 csum
+= checksum_mpi (sk
->skey
[i
]);
446 if (gcry_mpi_aprint (GCRYMPI_FMT_USG
, &buffer
,
447 &nbytes
, sk
->skey
[i
] ))
449 gcry_cipher_sync (cipher_hd
);
450 assert (!gcry_mpi_get_flag (sk
->skey
[i
],
451 GCRYMPI_FLAG_OPAQUE
));
453 data
= xmalloc (nbytes
+2); /* fixme: need xtrymalloc. */
454 nbits
= gcry_mpi_get_nbits (sk
->skey
[i
]);
455 assert (nbytes
== (nbits
+ 7)/8);
456 data
[0] = nbits
>> 8;
458 gcry_cipher_encrypt (cipher_hd
, data
+2, nbytes
,
462 gcry_mpi_release (sk
->skey
[i
]);
463 sk
->skey
[i
] = gcry_mpi_set_opaque (NULL
,
464 data
, (nbytes
+2)*8 );
468 sk
->is_protected
= 1;
469 gcry_cipher_close (cipher_hd
);