summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
committerDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
commit95def09838fc61b37b6ea7cd5c234a465b4b129b (patch)
tree042744f76f40a326b873cb1c3690a6d7d966bc3e /authfile.c
parent4d2f15f895f4c795afc008aeff3fd2ceffbc44f4 (diff)
- Merged very large OpenBSD source code reformat
- OpenBSD CVS updates - [channels.c cipher.c compat.c log-client.c scp.c serverloop.c] [ssh.h sshd.8 sshd.c] syslog changes: * Unified Logmessage for all auth-types, for success and for failed * Standard connections get only ONE line in the LOG when level==LOG: Auth-attempts are logged only, if authentication is: a) successfull or b) with passwd or c) we had more than AUTH_FAIL_LOG failues * many log() became verbose() * old behaviour with level=VERBOSE - [readconf.c readconf.h ssh.1 ssh.h sshconnect.c sshd.c] tranfer s/key challenge/response data in SSH_SMSG_AUTH_TIS_CHALLENGE messages. allows use of s/key in windows (ttssh, securecrt) and ssh-1.2.27 clients without 'ssh -v', ok: niels@ - [sshd.8] -V, for fallback to openssh in SSH2 compatibility mode - [sshd.c] fix sigchld race; cjc5@po.cwru.edu
Diffstat (limited to 'authfile.c')
-rw-r--r--authfile.c597
1 files changed, 291 insertions, 306 deletions
diff --git a/authfile.c b/authfile.c
index 0e77edf99..35a05d389 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,21 +1,21 @@
1/* 1/*
2 2 *
3authfile.c 3 * authfile.c
4 4 *
5Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Author: Tatu Ylonen <ylo@cs.hut.fi>
6 6 *
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 7 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8 All rights reserved 8 * All rights reserved
9 9 *
10Created: Mon Mar 27 03:52:05 1995 ylo 10 * Created: Mon Mar 27 03:52:05 1995 ylo
11 11 *
12This file contains functions for reading and writing identity files, and 12 * This file contains functions for reading and writing identity files, and
13for reading the passphrase from the user. 13 * for reading the passphrase from the user.
14 14 *
15*/ 15 */
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: authfile.c,v 1.3 1999/11/13 02:07:45 damien Exp $"); 18RCSID("$Id: authfile.c,v 1.4 1999/11/24 13:26:22 damien Exp $");
19 19
20#ifdef HAVE_OPENSSL 20#ifdef HAVE_OPENSSL
21#include <openssl/bn.h> 21#include <openssl/bn.h>
@@ -42,93 +42,93 @@ int
42save_private_key(const char *filename, const char *passphrase, 42save_private_key(const char *filename, const char *passphrase,
43 RSA *key, const char *comment) 43 RSA *key, const char *comment)
44{ 44{
45 Buffer buffer, encrypted; 45 Buffer buffer, encrypted;
46 char buf[100], *cp; 46 char buf[100], *cp;
47 int f, i; 47 int f, i;
48 CipherContext cipher; 48 CipherContext cipher;
49 int cipher_type; 49 int cipher_type;
50 u_int32_t rand; 50 u_int32_t rand;
51 51
52 /* If the passphrase is empty, use SSH_CIPHER_NONE to ease converting to 52 /* If the passphrase is empty, use SSH_CIPHER_NONE to ease
53 another cipher; otherwise use SSH_AUTHFILE_CIPHER. */ 53 converting to another cipher; otherwise use
54 if (strcmp(passphrase, "") == 0) 54 SSH_AUTHFILE_CIPHER. */
55 cipher_type = SSH_CIPHER_NONE; 55 if (strcmp(passphrase, "") == 0)
56 else 56 cipher_type = SSH_CIPHER_NONE;
57 cipher_type = SSH_AUTHFILE_CIPHER; 57 else
58 58 cipher_type = SSH_AUTHFILE_CIPHER;
59 /* This buffer is used to built the secret part of the private key. */ 59
60 buffer_init(&buffer); 60 /* This buffer is used to built the secret part of the private key. */
61 61 buffer_init(&buffer);
62 /* Put checkbytes for checking passphrase validity. */ 62
63 rand = arc4random(); 63 /* Put checkbytes for checking passphrase validity. */
64 buf[0] = rand & 0xff; 64 rand = arc4random();
65 buf[1] = (rand >> 8) & 0xff; 65 buf[0] = rand & 0xff;
66 buf[2] = buf[0]; 66 buf[1] = (rand >> 8) & 0xff;
67 buf[3] = buf[1]; 67 buf[2] = buf[0];
68 buffer_append(&buffer, buf, 4); 68 buf[3] = buf[1];
69 69 buffer_append(&buffer, buf, 4);
70 /* Store the private key (n and e will not be stored because they will 70
71 be stored in plain text, and storing them also in encrypted format 71 /* Store the private key (n and e will not be stored because they
72 would just give known plaintext). */ 72 will be stored in plain text, and storing them also in
73 buffer_put_bignum(&buffer, key->d); 73 encrypted format would just give known plaintext). */
74 buffer_put_bignum(&buffer, key->iqmp); 74 buffer_put_bignum(&buffer, key->d);
75 buffer_put_bignum(&buffer, key->q); /* reverse from SSL p */ 75 buffer_put_bignum(&buffer, key->iqmp);
76 buffer_put_bignum(&buffer, key->p); /* reverse from SSL q */ 76 buffer_put_bignum(&buffer, key->q); /* reverse from SSL p */
77 77 buffer_put_bignum(&buffer, key->p); /* reverse from SSL q */
78 /* Pad the part to be encrypted until its size is a multiple of 8. */ 78
79 while (buffer_len(&buffer) % 8 != 0) 79 /* Pad the part to be encrypted until its size is a multiple of 8. */
80 buffer_put_char(&buffer, 0); 80 while (buffer_len(&buffer) % 8 != 0)
81 81 buffer_put_char(&buffer, 0);
82 /* This buffer will be used to contain the data in the file. */ 82
83 buffer_init(&encrypted); 83 /* This buffer will be used to contain the data in the file. */
84 84 buffer_init(&encrypted);
85 /* First store keyfile id string. */ 85
86 cp = AUTHFILE_ID_STRING; 86 /* First store keyfile id string. */
87 for (i = 0; cp[i]; i++) 87 cp = AUTHFILE_ID_STRING;
88 buffer_put_char(&encrypted, cp[i]); 88 for (i = 0; cp[i]; i++)
89 buffer_put_char(&encrypted, 0); 89 buffer_put_char(&encrypted, cp[i]);
90 90 buffer_put_char(&encrypted, 0);
91 /* Store cipher type. */ 91
92 buffer_put_char(&encrypted, cipher_type); 92 /* Store cipher type. */
93 buffer_put_int(&encrypted, 0); /* For future extension */ 93 buffer_put_char(&encrypted, cipher_type);
94 94 buffer_put_int(&encrypted, 0); /* For future extension */
95 /* Store public key. This will be in plain text. */ 95
96 buffer_put_int(&encrypted, BN_num_bits(key->n)); 96 /* Store public key. This will be in plain text. */
97 buffer_put_bignum(&encrypted, key->n); 97 buffer_put_int(&encrypted, BN_num_bits(key->n));
98 buffer_put_bignum(&encrypted, key->e); 98 buffer_put_bignum(&encrypted, key->n);
99 buffer_put_string(&encrypted, comment, strlen(comment)); 99 buffer_put_bignum(&encrypted, key->e);
100 100 buffer_put_string(&encrypted, comment, strlen(comment));
101 /* Allocate space for the private part of the key in the buffer. */ 101
102 buffer_append_space(&encrypted, &cp, buffer_len(&buffer)); 102 /* Allocate space for the private part of the key in the buffer. */
103 103 buffer_append_space(&encrypted, &cp, buffer_len(&buffer));
104 cipher_set_key_string(&cipher, cipher_type, passphrase, 1); 104
105 cipher_encrypt(&cipher, (unsigned char *)cp, 105 cipher_set_key_string(&cipher, cipher_type, passphrase, 1);
106 (unsigned char *)buffer_ptr(&buffer), 106 cipher_encrypt(&cipher, (unsigned char *) cp,
107 buffer_len(&buffer)); 107 (unsigned char *) buffer_ptr(&buffer),
108 memset(&cipher, 0, sizeof(cipher)); 108 buffer_len(&buffer));
109 109 memset(&cipher, 0, sizeof(cipher));
110 /* Destroy temporary data. */ 110
111 memset(buf, 0, sizeof(buf)); 111 /* Destroy temporary data. */
112 buffer_free(&buffer); 112 memset(buf, 0, sizeof(buf));
113 113 buffer_free(&buffer);
114 /* Write to a file. */ 114
115 f = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0600); 115 /* Write to a file. */
116 if (f < 0) 116 f = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
117 return 0; 117 if (f < 0)
118 118 return 0;
119 if (write(f, buffer_ptr(&encrypted), buffer_len(&encrypted)) != 119
120 buffer_len(&encrypted)) 120 if (write(f, buffer_ptr(&encrypted), buffer_len(&encrypted)) !=
121 { 121 buffer_len(&encrypted)) {
122 debug("Write to key file %.200s failed: %.100s", filename, 122 debug("Write to key file %.200s failed: %.100s", filename,
123 strerror(errno)); 123 strerror(errno));
124 buffer_free(&encrypted); 124 buffer_free(&encrypted);
125 close(f); 125 close(f);
126 remove(filename); 126 remove(filename);
127 return 0; 127 return 0;
128 } 128 }
129 close(f); 129 close(f);
130 buffer_free(&encrypted); 130 buffer_free(&encrypted);
131 return 1; 131 return 1;
132} 132}
133 133
134/* Loads the public part of the key file. Returns 0 if an error 134/* Loads the public part of the key file. Returns 0 if an error
@@ -136,70 +136,65 @@ save_private_key(const char *filename, const char *passphrase,
136 non-zero otherwise. */ 136 non-zero otherwise. */
137 137
138int 138int
139load_public_key(const char *filename, RSA *pub, 139load_public_key(const char *filename, RSA * pub,
140 char **comment_return) 140 char **comment_return)
141{ 141{
142 int f, i; 142 int f, i;
143 off_t len; 143 off_t len;
144 Buffer buffer; 144 Buffer buffer;
145 char *cp; 145 char *cp;
146 146
147 /* Read data from the file into the buffer. */ 147 /* Read data from the file into the buffer. */
148 f = open(filename, O_RDONLY); 148 f = open(filename, O_RDONLY);
149 if (f < 0) 149 if (f < 0)
150 return 0; 150 return 0;
151 151
152 len = lseek(f, (off_t)0, SEEK_END); 152 len = lseek(f, (off_t) 0, SEEK_END);
153 lseek(f, (off_t)0, SEEK_SET); 153 lseek(f, (off_t) 0, SEEK_SET);
154 154
155 buffer_init(&buffer); 155 buffer_init(&buffer);
156 buffer_append_space(&buffer, &cp, len); 156 buffer_append_space(&buffer, &cp, len);
157 157
158 if (read(f, cp, (size_t)len) != (size_t)len) 158 if (read(f, cp, (size_t) len) != (size_t) len) {
159 { 159 debug("Read from key file %.200s failed: %.100s", filename,
160 debug("Read from key file %.200s failed: %.100s", filename, 160 strerror(errno));
161 strerror(errno)); 161 buffer_free(&buffer);
162 buffer_free(&buffer); 162 close(f);
163 close(f); 163 return 0;
164 return 0; 164 }
165 } 165 close(f);
166 close(f); 166
167 167 /* Check that it is at least big enought to contain the ID string. */
168 /* Check that it is at least big enought to contain the ID string. */ 168 if (len < strlen(AUTHFILE_ID_STRING) + 1) {
169 if (len < strlen(AUTHFILE_ID_STRING) + 1) 169 debug("Bad key file %.200s.", filename);
170 { 170 buffer_free(&buffer);
171 debug("Bad key file %.200s.", filename); 171 return 0;
172 buffer_free(&buffer); 172 }
173 return 0; 173 /* Make sure it begins with the id string. Consume the id string
174 } 174 from the buffer. */
175 175 for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
176 /* Make sure it begins with the id string. Consume the id string from 176 if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) {
177 the buffer. */ 177 debug("Bad key file %.200s.", filename);
178 for (i = 0; i < (unsigned int)strlen(AUTHFILE_ID_STRING) + 1; i++) 178 buffer_free(&buffer);
179 if (buffer_get_char(&buffer) != (unsigned char)AUTHFILE_ID_STRING[i]) 179 return 0;
180 { 180 }
181 debug("Bad key file %.200s.", filename); 181 /* Skip cipher type and reserved data. */
182 (void) buffer_get_char(&buffer); /* cipher type */
183 (void) buffer_get_int(&buffer); /* reserved */
184
185 /* Read the public key from the buffer. */
186 buffer_get_int(&buffer);
187 pub->n = BN_new();
188 buffer_get_bignum(&buffer, pub->n);
189 pub->e = BN_new();
190 buffer_get_bignum(&buffer, pub->e);
191 if (comment_return)
192 *comment_return = buffer_get_string(&buffer, NULL);
193 /* The encrypted private part is not parsed by this function. */
194
182 buffer_free(&buffer); 195 buffer_free(&buffer);
183 return 0; 196
184 } 197 return 1;
185
186 /* Skip cipher type and reserved data. */
187 (void)buffer_get_char(&buffer); /* cipher type */
188 (void)buffer_get_int(&buffer); /* reserved */
189
190 /* Read the public key from the buffer. */
191 buffer_get_int(&buffer);
192 pub->n = BN_new();
193 buffer_get_bignum(&buffer, pub->n);
194 pub->e = BN_new();
195 buffer_get_bignum(&buffer, pub->e);
196 if (comment_return)
197 *comment_return = buffer_get_string(&buffer, NULL);
198 /* The encrypted private part is not parsed by this function. */
199
200 buffer_free(&buffer);
201
202 return 1;
203} 198}
204 199
205/* Loads the private key from the file. Returns 0 if an error is encountered 200/* Loads the private key from the file. Returns 0 if an error is encountered
@@ -208,149 +203,139 @@ load_public_key(const char *filename, RSA *pub,
208 203
209int 204int
210load_private_key(const char *filename, const char *passphrase, 205load_private_key(const char *filename, const char *passphrase,
211 RSA *prv, char **comment_return) 206 RSA * prv, char **comment_return)
212{ 207{
213 int f, i, check1, check2, cipher_type; 208 int f, i, check1, check2, cipher_type;
214 off_t len; 209 off_t len;
215 Buffer buffer, decrypted; 210 Buffer buffer, decrypted;
216 char *cp; 211 char *cp;
217 CipherContext cipher; 212 CipherContext cipher;
218 BN_CTX *ctx; 213 BN_CTX *ctx;
219 BIGNUM *aux; 214 BIGNUM *aux;
220 struct stat st; 215 struct stat st;
221 216
222 /* Read the file into the buffer. */ 217 /* Read the file into the buffer. */
223 f = open(filename, O_RDONLY); 218 f = open(filename, O_RDONLY);
224 if (f < 0) 219 if (f < 0)
225 return 0; 220 return 0;
226 221
227 /* We assume we are called under uid of the owner of the file */ 222 /* We assume we are called under uid of the owner of the file */
228 if (fstat(f, &st) < 0 || 223 if (fstat(f, &st) < 0 ||
229 (st.st_uid != 0 && st.st_uid != getuid()) || 224 (st.st_uid != 0 && st.st_uid != getuid()) ||
230 (st.st_mode & 077) != 0) { 225 (st.st_mode & 077) != 0) {
231 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 226 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
232 error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @"); 227 error("@ WARNING: UNPROTECTED PRIVATE KEY FILE! @");
233 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"); 228 error("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
234 error("Bad ownership or mode(0%3.3o) for '%s'.", 229 error("Bad ownership or mode(0%3.3o) for '%s'.",
235 st.st_mode & 0777, filename); 230 st.st_mode & 0777, filename);
236 error("It is recommended that your private key files are NOT accessible by others."); 231 error("It is recommended that your private key files are NOT accessible by others.");
237 return 0; 232 return 0;
238 } 233 }
239 234 len = lseek(f, (off_t) 0, SEEK_END);
240 len = lseek(f, (off_t)0, SEEK_END); 235 lseek(f, (off_t) 0, SEEK_SET);
241 lseek(f, (off_t)0, SEEK_SET); 236
242 237 buffer_init(&buffer);
243 buffer_init(&buffer); 238 buffer_append_space(&buffer, &cp, len);
244 buffer_append_space(&buffer, &cp, len); 239
245 240 if (read(f, cp, (size_t) len) != (size_t) len) {
246 if (read(f, cp, (size_t)len) != (size_t)len) 241 debug("Read from key file %.200s failed: %.100s", filename,
247 { 242 strerror(errno));
248 debug("Read from key file %.200s failed: %.100s", filename, 243 buffer_free(&buffer);
249 strerror(errno)); 244 close(f);
250 buffer_free(&buffer); 245 return 0;
251 close(f); 246 }
252 return 0; 247 close(f);
253 } 248
254 close(f); 249 /* Check that it is at least big enought to contain the ID string. */
255 250 if (len < strlen(AUTHFILE_ID_STRING) + 1) {
256 /* Check that it is at least big enought to contain the ID string. */ 251 debug("Bad key file %.200s.", filename);
257 if (len < strlen(AUTHFILE_ID_STRING) + 1) 252 buffer_free(&buffer);
258 { 253 return 0;
259 debug("Bad key file %.200s.", filename); 254 }
260 buffer_free(&buffer); 255 /* Make sure it begins with the id string. Consume the id string
261 return 0; 256 from the buffer. */
262 } 257 for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++)
263 258 if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) {
264 /* Make sure it begins with the id string. Consume the id string from 259 debug("Bad key file %.200s.", filename);
265 the buffer. */ 260 buffer_free(&buffer);
266 for (i = 0; i < (unsigned int)strlen(AUTHFILE_ID_STRING) + 1; i++) 261 return 0;
267 if (buffer_get_char(&buffer) != (unsigned char)AUTHFILE_ID_STRING[i]) 262 }
268 { 263 /* Read cipher type. */
269 debug("Bad key file %.200s.", filename); 264 cipher_type = buffer_get_char(&buffer);
265 (void) buffer_get_int(&buffer); /* Reserved data. */
266
267 /* Read the public key from the buffer. */
268 buffer_get_int(&buffer);
269 prv->n = BN_new();
270 buffer_get_bignum(&buffer, prv->n);
271 prv->e = BN_new();
272 buffer_get_bignum(&buffer, prv->e);
273 if (comment_return)
274 *comment_return = buffer_get_string(&buffer, NULL);
275 else
276 xfree(buffer_get_string(&buffer, NULL));
277
278 /* Check that it is a supported cipher. */
279 if (((cipher_mask() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) &
280 (1 << cipher_type)) == 0) {
281 debug("Unsupported cipher %.100s used in key file %.200s.",
282 cipher_name(cipher_type), filename);
283 buffer_free(&buffer);
284 goto fail;
285 }
286 /* Initialize space for decrypted data. */
287 buffer_init(&decrypted);
288 buffer_append_space(&decrypted, &cp, buffer_len(&buffer));
289
290 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
291 cipher_set_key_string(&cipher, cipher_type, passphrase, 0);
292 cipher_decrypt(&cipher, (unsigned char *) cp,
293 (unsigned char *) buffer_ptr(&buffer),
294 buffer_len(&buffer));
295
270 buffer_free(&buffer); 296 buffer_free(&buffer);
271 return 0; 297
272 } 298 check1 = buffer_get_char(&decrypted);
273 299 check2 = buffer_get_char(&decrypted);
274 /* Read cipher type. */ 300 if (check1 != buffer_get_char(&decrypted) ||
275 cipher_type = buffer_get_char(&buffer); 301 check2 != buffer_get_char(&decrypted)) {
276 (void)buffer_get_int(&buffer); /* Reserved data. */ 302 if (strcmp(passphrase, "") != 0)
277 303 debug("Bad passphrase supplied for key file %.200s.", filename);
278 /* Read the public key from the buffer. */ 304 /* Bad passphrase. */
279 buffer_get_int(&buffer); 305 buffer_free(&decrypted);
280 prv->n = BN_new(); 306fail:
281 buffer_get_bignum(&buffer, prv->n); 307 BN_clear_free(prv->n);
282 prv->e = BN_new(); 308 BN_clear_free(prv->e);
283 buffer_get_bignum(&buffer, prv->e); 309 if (comment_return)
284 if (comment_return) 310 xfree(*comment_return);
285 *comment_return = buffer_get_string(&buffer, NULL); 311 return 0;
286 else 312 }
287 xfree(buffer_get_string(&buffer, NULL)); 313 /* Read the rest of the private key. */
288 314 prv->d = BN_new();
289 /* Check that it is a supported cipher. */ 315 buffer_get_bignum(&decrypted, prv->d);
290 if (((cipher_mask() | SSH_CIPHER_NONE | SSH_AUTHFILE_CIPHER) & 316 prv->iqmp = BN_new();
291 (1 << cipher_type)) == 0) 317 buffer_get_bignum(&decrypted, prv->iqmp); /* u */
292 { 318 /* in SSL and SSH p and q are exchanged */
293 debug("Unsupported cipher %.100s used in key file %.200s.", 319 prv->q = BN_new();
294 cipher_name(cipher_type), filename); 320 buffer_get_bignum(&decrypted, prv->q); /* p */
295 buffer_free(&buffer); 321 prv->p = BN_new();
296 goto fail; 322 buffer_get_bignum(&decrypted, prv->p); /* q */
297 } 323
298 324 ctx = BN_CTX_new();
299 /* Initialize space for decrypted data. */ 325 aux = BN_new();
300 buffer_init(&decrypted); 326
301 buffer_append_space(&decrypted, &cp, buffer_len(&buffer)); 327 BN_sub(aux, prv->q, BN_value_one());
302 328 prv->dmq1 = BN_new();
303 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ 329 BN_mod(prv->dmq1, prv->d, aux, ctx);
304 cipher_set_key_string(&cipher, cipher_type, passphrase, 0); 330
305 cipher_decrypt(&cipher, (unsigned char *)cp, 331 BN_sub(aux, prv->p, BN_value_one());
306 (unsigned char *)buffer_ptr(&buffer), 332 prv->dmp1 = BN_new();
307 buffer_len(&buffer)); 333 BN_mod(prv->dmp1, prv->d, aux, ctx);
308 334
309 buffer_free(&buffer); 335 BN_clear_free(aux);
310 336 BN_CTX_free(ctx);
311 check1 = buffer_get_char(&decrypted); 337
312 check2 = buffer_get_char(&decrypted); 338 buffer_free(&decrypted);
313 if (check1 != buffer_get_char(&decrypted) || 339
314 check2 != buffer_get_char(&decrypted)) 340 return 1;
315 {
316 if (strcmp(passphrase, "") != 0)
317 debug("Bad passphrase supplied for key file %.200s.", filename);
318 /* Bad passphrase. */
319 buffer_free(&decrypted);
320 fail:
321 BN_clear_free(prv->n);
322 BN_clear_free(prv->e);
323 if (comment_return)
324 xfree(*comment_return);
325 return 0;
326 }
327
328 /* Read the rest of the private key. */
329 prv->d = BN_new();
330 buffer_get_bignum(&decrypted, prv->d);
331 prv->iqmp = BN_new();
332 buffer_get_bignum(&decrypted, prv->iqmp); /* u */
333 /* in SSL and SSH p and q are exchanged */
334 prv->q = BN_new();
335 buffer_get_bignum(&decrypted, prv->q); /* p */
336 prv->p = BN_new();
337 buffer_get_bignum(&decrypted, prv->p); /* q */
338
339 ctx = BN_CTX_new();
340 aux = BN_new();
341
342 BN_sub(aux, prv->q, BN_value_one());
343 prv->dmq1 = BN_new();
344 BN_mod(prv->dmq1, prv->d, aux, ctx);
345
346 BN_sub(aux, prv->p, BN_value_one());
347 prv->dmp1 = BN_new();
348 BN_mod(prv->dmp1, prv->d, aux, ctx);
349
350 BN_clear_free(aux);
351 BN_CTX_free(ctx);
352
353 buffer_free(&decrypted);
354
355 return 1;
356} 341}