1 /* seckey-cert.c - Not anymore used
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/>.
21 #error Not anymore used - only kept for reference in the repository.
40 xxxx_do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
49 if( sk->is_protected ) { /* remove the protection */
51 u32 keyid[4]; /* 4! because we need two of them */
52 gcry_cipher_hd_t cipher_hd=NULL;
53 PKT_secret_key *save_sk;
55 if( sk->protect.s2k.mode == 1001 ) {
56 log_info(_("secret key parts are not available\n"));
57 return GPG_ERR_UNUSABLE_SECKEY;
59 if( sk->protect.algo == CIPHER_ALGO_NONE )
61 if( openpgp_cipher_test_algo( sk->protect.algo ) ) {
62 log_info(_("protection algorithm %d%s is not supported\n"),
63 sk->protect.algo,sk->protect.algo==1?" (IDEA)":"" );
64 return GPG_ERR_CIPHER_ALGO;
66 if(gcry_md_test_algo (sk->protect.s2k.hash_algo))
68 log_info(_("protection digest %d is not supported\n"),
69 sk->protect.s2k.hash_algo);
70 return GPG_ERR_DIGEST_ALGO;
72 keyid_from_sk( sk, keyid );
73 keyid[2] = keyid[3] = 0;
74 if (!sk->flags.primary)
76 keyid[2] = sk->main_keyid[0];
77 keyid[3] = sk->main_keyid[1];
79 dek = passphrase_to_dek( keyid, sk->pubkey_algo, sk->protect.algo,
80 &sk->protect.s2k, mode,
81 tryagain_text, canceled );
82 if (!dek && canceled && *canceled)
83 return GPG_ERR_CANCELED;
86 err = openpgp_cipher_open (&cipher_hd, sk->protect.algo,
89 | (sk->protect.algo >= 100 ?
90 0 : GCRY_CIPHER_ENABLE_SYNC)));
92 log_fatal ("cipher open failed: %s\n", gpg_strerror (err) );
94 err = gcry_cipher_setkey (cipher_hd, dek->key, dek->keylen);
96 log_fatal ("set key failed: %s\n", gpg_strerror (err) );
99 save_sk = copy_secret_key( NULL, sk );
101 gcry_cipher_setiv ( cipher_hd, sk->protect.iv, sk->protect.ivlen );
104 if( sk->version >= 4 ) {
106 unsigned int ndatabits;
110 i = pubkey_get_npkey(sk->pubkey_algo);
112 assert ( gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE ));
113 p = gcry_mpi_get_opaque ( sk->skey[i], &ndatabits );
114 ndata = (ndatabits+7)/8;
117 csumc = buf16_to_u16 (p+ndata-2);
118 data = xmalloc_secure ( ndata );
119 gcry_cipher_decrypt ( cipher_hd, data, ndata, p, ndata );
120 gcry_mpi_release (sk->skey[i]); sk->skey[i] = NULL ;
123 if (sk->protect.sha1chk) {
124 /* This is the new SHA1 checksum method to detect
125 tampering with the key as used by the Klima/Rosa
130 log_error("not enough bytes for SHA-1 checksum\n");
134 if ( gcry_md_open (&h, DIGEST_ALGO_SHA1, 1))
135 BUG(); /* Algo not available. */
136 gcry_md_write (h, data, ndata - 20);
138 if (!memcmp (gcry_md_read (h, DIGEST_ALGO_SHA1),
139 data + ndata - 20, 20) )
141 /* Digest does match. We have to keep the old
142 style checksum in sk->csum, so that the
143 test used for unprotected keys does work.
144 This test gets used when we are adding new
146 sk->csum = csum = checksum (data, ndata-20);
153 log_error("not enough bytes for checksum\n");
158 csum = checksum( data, ndata-2);
159 sk->csum = data[ndata-2] << 8 | data[ndata-1];
160 if ( sk->csum != csum ) {
161 /* This is a PGP 7.0.0 workaround */
162 sk->csum = csumc; /* take the encrypted one */
167 /* Must check it here otherwise the mpi_read_xx would fail
168 because the length may have an arbitrary value */
169 if( sk->csum == csum ) {
170 for( ; i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
171 if ( gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP,
174 /* Checksum was okay, but not correctly
183 /* Note: at this point ndata should be 2 for a simple
184 checksum or 20 for the sha1 digest */
189 for(i=pubkey_get_npkey(sk->pubkey_algo);
190 i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
193 unsigned int ndatabits;
195 assert (gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
196 p = gcry_mpi_get_opaque (sk->skey[i], &ndatabits);
197 ndata = (ndatabits+7)/8;
199 assert (ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2);
200 buffer = xmalloc_secure (ndata);
201 gcry_cipher_sync (cipher_hd);
204 gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2,
206 csum += checksum (buffer, ndata);
207 gcry_mpi_release (sk->skey[i]);
209 err = gcry_mpi_scan( &sk->skey[i], GCRYMPI_FMT_PGP,
210 buffer, ndata, &ndata );
214 /* Checksum was okay, but not correctly
220 /* csum += checksum_mpi (sk->skey[i]); */
223 gcry_cipher_close ( cipher_hd );
225 /* Now let's see whether we have used the correct passphrase. */
226 if( csum != sk->csum ) {
227 copy_secret_key( sk, save_sk );
228 passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
229 free_secret_key( save_sk );
230 return gpg_error (GPG_ERR_BAD_PASSPHRASE);
233 /* The checksum may fail, so we also check the key itself. */
234 res = pk_check_secret_key ( sk->pubkey_algo, sk->skey );
236 copy_secret_key( sk, save_sk );
237 passphrase_clear_cache ( keyid, NULL, sk->pubkey_algo );
238 free_secret_key( save_sk );
239 return gpg_error (GPG_ERR_BAD_PASSPHRASE);
241 free_secret_key( save_sk );
242 sk->is_protected = 0;
244 else { /* not protected, assume it is okay if the checksum is okay */
246 for(i=pubkey_get_npkey(sk->pubkey_algo);
247 i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
248 csum += checksum_mpi( sk->skey[i] );
250 if( csum != sk->csum )
251 return GPG_ERR_CHECKSUM;