summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2011-01-24 12:43:25 +0000
committerColin Watson <cjwatson@debian.org>2011-01-24 12:43:25 +0000
commit626f1d986ff72aa514da63e34744e1de9cf21b9a (patch)
treed215a5280bc2e57251e4a9e08bfd3674ad824a94 /authfile.c
parent6ed622cb6fe8f71bbe0d998cdd12280410bfb420 (diff)
parent0970072c89b079b022538e3c366fbfa2c53fc821 (diff)
* New upstream release (http://www.openssh.org/txt/release-5.7):
- Implement Elliptic Curve Cryptography modes for key exchange (ECDH) and host/user keys (ECDSA) as specified by RFC5656. ECDH and ECDSA offer better performance than plain DH and DSA at the same equivalent symmetric key length, as well as much shorter keys. - sftp(1)/sftp-server(8): add a protocol extension to support a hard link operation. It is available through the "ln" command in the client. The old "ln" behaviour of creating a symlink is available using its "-s" option or through the preexisting "symlink" command. - scp(1): Add a new -3 option to scp: Copies between two remote hosts are transferred through the local host (closes: #508613). - ssh(1): "atomically" create the listening mux socket by binding it on a temporary name and then linking it into position after listen() has succeeded. This allows the mux clients to determine that the server socket is either ready or stale without races (closes: #454784). Stale server sockets are now automatically removed (closes: #523250). - ssh(1): install a SIGCHLD handler to reap expired child process (closes: #594687). - ssh(1)/ssh-agent(1): honour $TMPDIR for client xauth and ssh-agent temporary directories (closes: #357469, although only if you arrange for ssh-agent to actually see $TMPDIR since the setgid bit will cause it to be stripped off).
Diffstat (limited to 'authfile.c')
-rw-r--r--authfile.c474
1 files changed, 283 insertions, 191 deletions
diff --git a/authfile.c b/authfile.c
index e748ec0a2..be650af67 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.82 2010/08/04 05:49:22 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.87 2010/11/29 18:57:04 markus Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -75,19 +75,18 @@ static const char authfile_id_string[] =
75 "SSH PRIVATE KEY FILE FORMAT 1.1\n"; 75 "SSH PRIVATE KEY FILE FORMAT 1.1\n";
76 76
77/* 77/*
78 * Saves the authentication (private) key in a file, encrypting it with 78 * Serialises the authentication (private) key to a blob, encrypting it with
79 * passphrase. The identification of the file (lowest 64 bits of n) will 79 * passphrase. The identification of the blob (lowest 64 bits of n) will
80 * precede the key to provide identification of the key without needing a 80 * precede the key to provide identification of the key without needing a
81 * passphrase. 81 * passphrase.
82 */ 82 */
83
84static int 83static int
85key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, 84key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase,
86 const char *comment) 85 const char *comment)
87{ 86{
88 Buffer buffer, encrypted; 87 Buffer buffer, encrypted;
89 u_char buf[100], *cp; 88 u_char buf[100], *cp;
90 int fd, i, cipher_num; 89 int i, cipher_num;
91 CipherContext ciphercontext; 90 CipherContext ciphercontext;
92 Cipher *cipher; 91 Cipher *cipher;
93 u_int32_t rnd; 92 u_int32_t rnd;
@@ -158,156 +157,222 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
158 memset(buf, 0, sizeof(buf)); 157 memset(buf, 0, sizeof(buf));
159 buffer_free(&buffer); 158 buffer_free(&buffer);
160 159
161 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); 160 buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted));
162 if (fd < 0) {
163 error("open %s failed: %s.", filename, strerror(errno));
164 buffer_free(&encrypted);
165 return 0;
166 }
167 if (atomicio(vwrite, fd, buffer_ptr(&encrypted),
168 buffer_len(&encrypted)) != buffer_len(&encrypted)) {
169 error("write to key file %s failed: %s", filename,
170 strerror(errno));
171 buffer_free(&encrypted);
172 close(fd);
173 unlink(filename);
174 return 0;
175 }
176 close(fd);
177 buffer_free(&encrypted); 161 buffer_free(&encrypted);
162
178 return 1; 163 return 1;
179} 164}
180 165
181/* save SSH v2 key in OpenSSL PEM format */ 166/* convert SSH v2 key in OpenSSL PEM format */
182static int 167static int
183key_save_private_pem(Key *key, const char *filename, const char *_passphrase, 168key_private_pem_to_blob(Key *key, Buffer *blob, const char *_passphrase,
184 const char *comment) 169 const char *comment)
185{ 170{
186 FILE *fp;
187 int fd;
188 int success = 0; 171 int success = 0;
189 int len = strlen(_passphrase); 172 int blen, len = strlen(_passphrase);
190 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; 173 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
191#if (OPENSSL_VERSION_NUMBER < 0x00907000L) 174#if (OPENSSL_VERSION_NUMBER < 0x00907000L)
192 const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL; 175 const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
193#else 176#else
194 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; 177 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
195#endif 178#endif
179 const u_char *bptr;
180 BIO *bio;
196 181
197 if (len > 0 && len <= 4) { 182 if (len > 0 && len <= 4) {
198 error("passphrase too short: have %d bytes, need > 4", len); 183 error("passphrase too short: have %d bytes, need > 4", len);
199 return 0; 184 return 0;
200 } 185 }
201 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); 186 if ((bio = BIO_new(BIO_s_mem())) == NULL) {
202 if (fd < 0) { 187 error("%s: BIO_new failed", __func__);
203 error("open %s failed: %s.", filename, strerror(errno));
204 return 0;
205 }
206 fp = fdopen(fd, "w");
207 if (fp == NULL) {
208 error("fdopen %s failed: %s.", filename, strerror(errno));
209 close(fd);
210 return 0; 188 return 0;
211 } 189 }
212 switch (key->type) { 190 switch (key->type) {
213 case KEY_DSA: 191 case KEY_DSA:
214 success = PEM_write_DSAPrivateKey(fp, key->dsa, 192 success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
215 cipher, passphrase, len, NULL, NULL); 193 cipher, passphrase, len, NULL, NULL);
216 break; 194 break;
195#ifdef OPENSSL_HAS_ECC
196 case KEY_ECDSA:
197 success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
198 cipher, passphrase, len, NULL, NULL);
199 break;
200#endif
217 case KEY_RSA: 201 case KEY_RSA:
218 success = PEM_write_RSAPrivateKey(fp, key->rsa, 202 success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
219 cipher, passphrase, len, NULL, NULL); 203 cipher, passphrase, len, NULL, NULL);
220 break; 204 break;
221 } 205 }
222 fclose(fp); 206 if (success) {
207 if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0)
208 success = 0;
209 else
210 buffer_append(blob, bptr, blen);
211 }
212 BIO_free(bio);
223 return success; 213 return success;
224} 214}
225 215
226int 216/* Save a key blob to a file */
227key_save_private(Key *key, const char *filename, const char *passphrase, 217static int
218key_save_private_blob(Buffer *keybuf, const char *filename)
219{
220 int fd;
221
222 if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) {
223 error("open %s failed: %s.", filename, strerror(errno));
224 return 0;
225 }
226 if (atomicio(vwrite, fd, buffer_ptr(keybuf),
227 buffer_len(keybuf)) != buffer_len(keybuf)) {
228 error("write to key file %s failed: %s", filename,
229 strerror(errno));
230 close(fd);
231 unlink(filename);
232 return 0;
233 }
234 close(fd);
235 return 1;
236}
237
238/* Serialise "key" to buffer "blob" */
239static int
240key_private_to_blob(Key *key, Buffer *blob, const char *passphrase,
228 const char *comment) 241 const char *comment)
229{ 242{
230 switch (key->type) { 243 switch (key->type) {
231 case KEY_RSA1: 244 case KEY_RSA1:
232 return key_save_private_rsa1(key, filename, passphrase, 245 return key_private_rsa1_to_blob(key, blob, passphrase, comment);
233 comment);
234 case KEY_DSA: 246 case KEY_DSA:
247 case KEY_ECDSA:
235 case KEY_RSA: 248 case KEY_RSA:
236 return key_save_private_pem(key, filename, passphrase, 249 return key_private_pem_to_blob(key, blob, passphrase, comment);
237 comment);
238 default: 250 default:
239 break; 251 error("%s: cannot save key type %d", __func__, key->type);
252 return 0;
240 } 253 }
241 error("key_save_private: cannot save key type %d", key->type); 254}
242 return 0; 255
256int
257key_save_private(Key *key, const char *filename, const char *passphrase,
258 const char *comment)
259{
260 Buffer keyblob;
261 int success = 0;
262
263 buffer_init(&keyblob);
264 if (!key_private_to_blob(key, &keyblob, passphrase, comment))
265 goto out;
266 if (!key_save_private_blob(&keyblob, filename))
267 goto out;
268 success = 1;
269 out:
270 buffer_free(&keyblob);
271 return success;
243} 272}
244 273
245/* 274/*
246 * Loads the public part of the ssh v1 key file. Returns NULL if an error was 275 * Parse the public, unencrypted portion of a RSA1 key.
247 * encountered (the file does not exist or is not readable), and the key
248 * otherwise.
249 */ 276 */
250
251static Key * 277static Key *
252key_load_public_rsa1(int fd, const char *filename, char **commentp) 278key_parse_public_rsa1(Buffer *blob, char **commentp)
253{ 279{
254 Buffer buffer;
255 Key *pub; 280 Key *pub;
256 struct stat st; 281
257 char *cp; 282 /* Check that it is at least big enough to contain the ID string. */
258 u_int i; 283 if (buffer_len(blob) < sizeof(authfile_id_string)) {
284 debug3("Truncated RSA1 identifier");
285 return NULL;
286 }
287
288 /*
289 * Make sure it begins with the id string. Consume the id string
290 * from the buffer.
291 */
292 if (memcmp(buffer_ptr(blob), authfile_id_string,
293 sizeof(authfile_id_string)) != 0) {
294 debug3("Incorrect RSA1 identifier");
295 return NULL;
296 }
297 buffer_consume(blob, sizeof(authfile_id_string));
298
299 /* Skip cipher type and reserved data. */
300 (void) buffer_get_char(blob); /* cipher type */
301 (void) buffer_get_int(blob); /* reserved */
302
303 /* Read the public key from the buffer. */
304 (void) buffer_get_int(blob);
305 pub = key_new(KEY_RSA1);
306 buffer_get_bignum(blob, pub->rsa->n);
307 buffer_get_bignum(blob, pub->rsa->e);
308 if (commentp)
309 *commentp = buffer_get_string(blob, NULL);
310 /* The encrypted private part is not parsed by this function. */
311 buffer_clear(blob);
312
313 return pub;
314}
315
316/* Load the contents of a key file into a buffer */
317static int
318key_load_file(int fd, const char *filename, Buffer *blob)
319{
259 size_t len; 320 size_t len;
321 u_char *cp;
322 struct stat st;
260 323
261 if (fstat(fd, &st) < 0) { 324 if (fstat(fd, &st) < 0) {
262 error("fstat for key file %.200s failed: %.100s", 325 error("%s: fstat of key file %.200s%sfailed: %.100s", __func__,
263 filename, strerror(errno)); 326 filename == NULL ? "" : filename,
264 return NULL; 327 filename == NULL ? "" : " ",
328 strerror(errno));
329 close(fd);
330 return 0;
265 } 331 }
266 if (st.st_size > 1*1024*1024) { 332 if (st.st_size > 1*1024*1024) {
267 error("key file %.200s too large", filename); 333 error("%s: key file %.200s%stoo large", __func__,
268 return NULL; 334 filename == NULL ? "" : filename,
335 filename == NULL ? "" : " ");
336 close(fd);
337 return 0;
269 } 338 }
270 len = (size_t)st.st_size; /* truncated */ 339 len = (size_t)st.st_size; /* truncated */
271 340
272 buffer_init(&buffer); 341 buffer_init(blob);
273 cp = buffer_append_space(&buffer, len); 342 cp = buffer_append_space(blob, len);
274 343
275 if (atomicio(read, fd, cp, len) != len) { 344 if (atomicio(read, fd, cp, len) != len) {
276 debug("Read from key file %.200s failed: %.100s", filename, 345 debug("%s: read from key file %.200s%sfailed: %.100s", __func__,
346 filename == NULL ? "" : filename,
347 filename == NULL ? "" : " ",
277 strerror(errno)); 348 strerror(errno));
278 buffer_free(&buffer); 349 buffer_clear(blob);
279 return NULL; 350 close(fd);
351 return 0;
280 } 352 }
353 return 1;
354}
281 355
282 /* Check that it is at least big enough to contain the ID string. */ 356/*
283 if (len < sizeof(authfile_id_string)) { 357 * Loads the public part of the ssh v1 key file. Returns NULL if an error was
284 debug3("Not a RSA1 key file %.200s.", filename); 358 * encountered (the file does not exist or is not readable), and the key
359 * otherwise.
360 */
361static Key *
362key_load_public_rsa1(int fd, const char *filename, char **commentp)
363{
364 Buffer buffer;
365 Key *pub;
366
367 buffer_init(&buffer);
368 if (!key_load_file(fd, filename, &buffer)) {
285 buffer_free(&buffer); 369 buffer_free(&buffer);
286 return NULL; 370 return NULL;
287 } 371 }
288 /*
289 * Make sure it begins with the id string. Consume the id string
290 * from the buffer.
291 */
292 for (i = 0; i < sizeof(authfile_id_string); i++)
293 if (buffer_get_char(&buffer) != authfile_id_string[i]) {
294 debug3("Not a RSA1 key file %.200s.", filename);
295 buffer_free(&buffer);
296 return NULL;
297 }
298 /* Skip cipher type and reserved data. */
299 (void) buffer_get_char(&buffer); /* cipher type */
300 (void) buffer_get_int(&buffer); /* reserved */
301
302 /* Read the public key from the buffer. */
303 (void) buffer_get_int(&buffer);
304 pub = key_new(KEY_RSA1);
305 buffer_get_bignum(&buffer, pub->rsa->n);
306 buffer_get_bignum(&buffer, pub->rsa->e);
307 if (commentp)
308 *commentp = buffer_get_string(&buffer, NULL);
309 /* The encrypted private part is not parsed by this function. */
310 372
373 pub = key_parse_public_rsa1(&buffer, commentp);
374 if (pub == NULL)
375 debug3("Could not load \"%s\" as a RSA1 public key", filename);
311 buffer_free(&buffer); 376 buffer_free(&buffer);
312 return pub; 377 return pub;
313} 378}
@@ -330,113 +395,73 @@ key_load_public_type(int type, const char *filename, char **commentp)
330 return NULL; 395 return NULL;
331} 396}
332 397
333/*
334 * Loads the private key from the file. Returns 0 if an error is encountered
335 * (file does not exist or is not readable, or passphrase is bad). This
336 * initializes the private key.
337 * Assumes we are called under uid of the owner of the file.
338 */
339
340static Key * 398static Key *
341key_load_private_rsa1(int fd, const char *filename, const char *passphrase, 399key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp)
342 char **commentp)
343{ 400{
344 u_int i;
345 int check1, check2, cipher_type; 401 int check1, check2, cipher_type;
346 size_t len; 402 Buffer decrypted;
347 Buffer buffer, decrypted;
348 u_char *cp; 403 u_char *cp;
349 CipherContext ciphercontext; 404 CipherContext ciphercontext;
350 Cipher *cipher; 405 Cipher *cipher;
351 Key *prv = NULL; 406 Key *prv = NULL;
352 struct stat st;
353
354 if (fstat(fd, &st) < 0) {
355 error("fstat for key file %.200s failed: %.100s",
356 filename, strerror(errno));
357 close(fd);
358 return NULL;
359 }
360 if (st.st_size > 1*1024*1024) {
361 error("key file %.200s too large", filename);
362 close(fd);
363 return (NULL);
364 }
365 len = (size_t)st.st_size; /* truncated */
366
367 buffer_init(&buffer);
368 cp = buffer_append_space(&buffer, len);
369
370 if (atomicio(read, fd, cp, len) != len) {
371 debug("Read from key file %.200s failed: %.100s", filename,
372 strerror(errno));
373 buffer_free(&buffer);
374 close(fd);
375 return NULL;
376 }
377 407
378 /* Check that it is at least big enough to contain the ID string. */ 408 /* Check that it is at least big enough to contain the ID string. */
379 if (len < sizeof(authfile_id_string)) { 409 if (buffer_len(blob) < sizeof(authfile_id_string)) {
380 debug3("Not a RSA1 key file %.200s.", filename); 410 debug3("Truncated RSA1 identifier");
381 buffer_free(&buffer);
382 close(fd);
383 return NULL; 411 return NULL;
384 } 412 }
413
385 /* 414 /*
386 * Make sure it begins with the id string. Consume the id string 415 * Make sure it begins with the id string. Consume the id string
387 * from the buffer. 416 * from the buffer.
388 */ 417 */
389 for (i = 0; i < sizeof(authfile_id_string); i++) 418 if (memcmp(buffer_ptr(blob), authfile_id_string,
390 if (buffer_get_char(&buffer) != authfile_id_string[i]) { 419 sizeof(authfile_id_string)) != 0) {
391 debug3("Not a RSA1 key file %.200s.", filename); 420 debug3("Incorrect RSA1 identifier");
392 buffer_free(&buffer); 421 return NULL;
393 close(fd); 422 }
394 return NULL; 423 buffer_consume(blob, sizeof(authfile_id_string));
395 }
396 424
397 /* Read cipher type. */ 425 /* Read cipher type. */
398 cipher_type = buffer_get_char(&buffer); 426 cipher_type = buffer_get_char(blob);
399 (void) buffer_get_int(&buffer); /* Reserved data. */ 427 (void) buffer_get_int(blob); /* Reserved data. */
400 428
401 /* Read the public key from the buffer. */ 429 /* Read the public key from the buffer. */
402 (void) buffer_get_int(&buffer); 430 (void) buffer_get_int(blob);
403 prv = key_new_private(KEY_RSA1); 431 prv = key_new_private(KEY_RSA1);
404 432
405 buffer_get_bignum(&buffer, prv->rsa->n); 433 buffer_get_bignum(blob, prv->rsa->n);
406 buffer_get_bignum(&buffer, prv->rsa->e); 434 buffer_get_bignum(blob, prv->rsa->e);
407 if (commentp) 435 if (commentp)
408 *commentp = buffer_get_string(&buffer, NULL); 436 *commentp = buffer_get_string(blob, NULL);
409 else 437 else
410 xfree(buffer_get_string(&buffer, NULL)); 438 (void)buffer_get_string_ptr(blob, NULL);
411 439
412 /* Check that it is a supported cipher. */ 440 /* Check that it is a supported cipher. */
413 cipher = cipher_by_number(cipher_type); 441 cipher = cipher_by_number(cipher_type);
414 if (cipher == NULL) { 442 if (cipher == NULL) {
415 debug("Unsupported cipher %d used in key file %.200s.", 443 debug("Unsupported RSA1 cipher %d", cipher_type);
416 cipher_type, filename);
417 buffer_free(&buffer);
418 goto fail; 444 goto fail;
419 } 445 }
420 /* Initialize space for decrypted data. */ 446 /* Initialize space for decrypted data. */
421 buffer_init(&decrypted); 447 buffer_init(&decrypted);
422 cp = buffer_append_space(&decrypted, buffer_len(&buffer)); 448 cp = buffer_append_space(&decrypted, buffer_len(blob));
423 449
424 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ 450 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
425 cipher_set_key_string(&ciphercontext, cipher, passphrase, 451 cipher_set_key_string(&ciphercontext, cipher, passphrase,
426 CIPHER_DECRYPT); 452 CIPHER_DECRYPT);
427 cipher_crypt(&ciphercontext, cp, 453 cipher_crypt(&ciphercontext, cp,
428 buffer_ptr(&buffer), buffer_len(&buffer)); 454 buffer_ptr(blob), buffer_len(blob));
429 cipher_cleanup(&ciphercontext); 455 cipher_cleanup(&ciphercontext);
430 memset(&ciphercontext, 0, sizeof(ciphercontext)); 456 memset(&ciphercontext, 0, sizeof(ciphercontext));
431 buffer_free(&buffer); 457 buffer_clear(blob);
432 458
433 check1 = buffer_get_char(&decrypted); 459 check1 = buffer_get_char(&decrypted);
434 check2 = buffer_get_char(&decrypted); 460 check2 = buffer_get_char(&decrypted);
435 if (check1 != buffer_get_char(&decrypted) || 461 if (check1 != buffer_get_char(&decrypted) ||
436 check2 != buffer_get_char(&decrypted)) { 462 check2 != buffer_get_char(&decrypted)) {
437 if (strcmp(passphrase, "") != 0) 463 if (strcmp(passphrase, "") != 0)
438 debug("Bad passphrase supplied for key file %.200s.", 464 debug("Bad passphrase supplied for RSA1 key");
439 filename);
440 /* Bad passphrase. */ 465 /* Bad passphrase. */
441 buffer_free(&decrypted); 466 buffer_free(&decrypted);
442 goto fail; 467 goto fail;
@@ -455,38 +480,37 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
455 480
456 /* enable blinding */ 481 /* enable blinding */
457 if (RSA_blinding_on(prv->rsa, NULL) != 1) { 482 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
458 error("key_load_private_rsa1: RSA_blinding_on failed"); 483 error("%s: RSA_blinding_on failed", __func__);
459 goto fail; 484 goto fail;
460 } 485 }
461 close(fd);
462 return prv; 486 return prv;
463 487
464fail: 488fail:
465 if (commentp) 489 if (commentp)
466 xfree(*commentp); 490 xfree(*commentp);
467 close(fd);
468 key_free(prv); 491 key_free(prv);
469 return NULL; 492 return NULL;
470} 493}
471 494
472Key * 495static Key *
473key_load_private_pem(int fd, int type, const char *passphrase, 496key_parse_private_pem(Buffer *blob, int type, const char *passphrase,
474 char **commentp) 497 char **commentp)
475{ 498{
476 FILE *fp;
477 EVP_PKEY *pk = NULL; 499 EVP_PKEY *pk = NULL;
478 Key *prv = NULL; 500 Key *prv = NULL;
479 char *name = "<no key>"; 501 char *name = "<no key>";
502 BIO *bio;
480 503
481 fp = fdopen(fd, "r"); 504 if ((bio = BIO_new_mem_buf(buffer_ptr(blob),
482 if (fp == NULL) { 505 buffer_len(blob))) == NULL) {
483 error("fdopen failed: %s", strerror(errno)); 506 error("%s: BIO_new_mem_buf failed", __func__);
484 close(fd);
485 return NULL; 507 return NULL;
486 } 508 }
487 pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase); 509
510 pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase);
511 BIO_free(bio);
488 if (pk == NULL) { 512 if (pk == NULL) {
489 debug("PEM_read_PrivateKey failed"); 513 debug("%s: PEM_read_PrivateKey failed", __func__);
490 (void)ERR_get_error(); 514 (void)ERR_get_error();
491 } else if (pk->type == EVP_PKEY_RSA && 515 } else if (pk->type == EVP_PKEY_RSA &&
492 (type == KEY_UNSPEC||type==KEY_RSA)) { 516 (type == KEY_UNSPEC||type==KEY_RSA)) {
@@ -498,7 +522,7 @@ key_load_private_pem(int fd, int type, const char *passphrase,
498 RSA_print_fp(stderr, prv->rsa, 8); 522 RSA_print_fp(stderr, prv->rsa, 8);
499#endif 523#endif
500 if (RSA_blinding_on(prv->rsa, NULL) != 1) { 524 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
501 error("key_load_private_pem: RSA_blinding_on failed"); 525 error("%s: RSA_blinding_on failed", __func__);
502 key_free(prv); 526 key_free(prv);
503 prv = NULL; 527 prv = NULL;
504 } 528 }
@@ -511,11 +535,31 @@ key_load_private_pem(int fd, int type, const char *passphrase,
511#ifdef DEBUG_PK 535#ifdef DEBUG_PK
512 DSA_print_fp(stderr, prv->dsa, 8); 536 DSA_print_fp(stderr, prv->dsa, 8);
513#endif 537#endif
538#ifdef OPENSSL_HAS_ECC
539 } else if (pk->type == EVP_PKEY_EC &&
540 (type == KEY_UNSPEC||type==KEY_ECDSA)) {
541 prv = key_new(KEY_UNSPEC);
542 prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
543 prv->type = KEY_ECDSA;
544 if ((prv->ecdsa_nid = key_ecdsa_key_to_nid(prv->ecdsa)) == -1 ||
545 key_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
546 key_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
547 EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
548 key_ec_validate_private(prv->ecdsa) != 0) {
549 error("%s: bad ECDSA key", __func__);
550 key_free(prv);
551 prv = NULL;
552 }
553 name = "ecdsa w/o comment";
554#ifdef DEBUG_PK
555 if (prv != NULL && prv->ecdsa != NULL)
556 key_dump_ec_key(prv->ecdsa);
557#endif
558#endif /* OPENSSL_HAS_ECC */
514 } else { 559 } else {
515 error("PEM_read_PrivateKey: mismatch or " 560 error("%s: PEM_read_PrivateKey: mismatch or "
516 "unknown EVP_PKEY save_type %d", pk->save_type); 561 "unknown EVP_PKEY save_type %d", __func__, pk->save_type);
517 } 562 }
518 fclose(fp);
519 if (pk != NULL) 563 if (pk != NULL)
520 EVP_PKEY_free(pk); 564 EVP_PKEY_free(pk);
521 if (prv != NULL && commentp) 565 if (prv != NULL && commentp)
@@ -525,6 +569,23 @@ key_load_private_pem(int fd, int type, const char *passphrase,
525 return prv; 569 return prv;
526} 570}
527 571
572Key *
573key_load_private_pem(int fd, int type, const char *passphrase,
574 char **commentp)
575{
576 Buffer buffer;
577 Key *prv;
578
579 buffer_init(&buffer);
580 if (!key_load_file(fd, NULL, &buffer)) {
581 buffer_free(&buffer);
582 return NULL;
583 }
584 prv = key_parse_private_pem(&buffer, type, passphrase, commentp);
585 buffer_free(&buffer);
586 return prv;
587}
588
528int 589int
529key_perm_ok(int fd, const char *filename) 590key_perm_ok(int fd, const char *filename)
530{ 591{
@@ -553,11 +614,31 @@ key_perm_ok(int fd, const char *filename)
553 return 1; 614 return 1;
554} 615}
555 616
617static Key *
618key_parse_private_type(Buffer *blob, int type, const char *passphrase,
619 char **commentp)
620{
621 switch (type) {
622 case KEY_RSA1:
623 return key_parse_private_rsa1(blob, passphrase, commentp);
624 case KEY_DSA:
625 case KEY_ECDSA:
626 case KEY_RSA:
627 case KEY_UNSPEC:
628 return key_parse_private_pem(blob, type, passphrase, commentp);
629 default:
630 break;
631 }
632 return NULL;
633}
634
556Key * 635Key *
557key_load_private_type(int type, const char *filename, const char *passphrase, 636key_load_private_type(int type, const char *filename, const char *passphrase,
558 char **commentp, int *perm_ok) 637 char **commentp, int *perm_ok)
559{ 638{
560 int fd; 639 int fd;
640 Key *ret;
641 Buffer buffer;
561 642
562 fd = open(filename, O_RDONLY); 643 fd = open(filename, O_RDONLY);
563 if (fd < 0) { 644 if (fd < 0) {
@@ -576,21 +657,17 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
576 } 657 }
577 if (perm_ok != NULL) 658 if (perm_ok != NULL)
578 *perm_ok = 1; 659 *perm_ok = 1;
579 switch (type) { 660
580 case KEY_RSA1: 661 buffer_init(&buffer);
581 return key_load_private_rsa1(fd, filename, passphrase, 662 if (!key_load_file(fd, filename, &buffer)) {
582 commentp); 663 buffer_free(&buffer);
583 /* closes fd */
584 case KEY_DSA:
585 case KEY_RSA:
586 case KEY_UNSPEC:
587 return key_load_private_pem(fd, type, passphrase, commentp);
588 /* closes fd */
589 default:
590 close(fd); 664 close(fd);
591 break; 665 return NULL;
592 } 666 }
593 return NULL; 667 close(fd);
668 ret = key_parse_private_type(&buffer, type, passphrase, commentp);
669 buffer_free(&buffer);
670 return ret;
594} 671}
595 672
596Key * 673Key *
@@ -598,6 +675,7 @@ key_load_private(const char *filename, const char *passphrase,
598 char **commentp) 675 char **commentp)
599{ 676{
600 Key *pub, *prv; 677 Key *pub, *prv;
678 Buffer buffer, pubcopy;
601 int fd; 679 int fd;
602 680
603 fd = open(filename, O_RDONLY); 681 fd = open(filename, O_RDONLY);
@@ -611,20 +689,33 @@ key_load_private(const char *filename, const char *passphrase,
611 close(fd); 689 close(fd);
612 return NULL; 690 return NULL;
613 } 691 }
614 pub = key_load_public_rsa1(fd, filename, commentp); 692
615 lseek(fd, (off_t) 0, SEEK_SET); /* rewind */ 693 buffer_init(&buffer);
694 if (!key_load_file(fd, filename, &buffer)) {
695 buffer_free(&buffer);
696 close(fd);
697 return NULL;
698 }
699 close(fd);
700
701 buffer_init(&pubcopy);
702 buffer_append(&pubcopy, buffer_ptr(&buffer), buffer_len(&buffer));
703 /* it's a SSH v1 key if the public key part is readable */
704 pub = key_parse_public_rsa1(&pubcopy, commentp);
705 buffer_free(&pubcopy);
616 if (pub == NULL) { 706 if (pub == NULL) {
617 /* closes fd */ 707 prv = key_parse_private_type(&buffer, KEY_UNSPEC,
618 prv = key_load_private_pem(fd, KEY_UNSPEC, passphrase, NULL); 708 passphrase, NULL);
619 /* use the filename as a comment for PEM */ 709 /* use the filename as a comment for PEM */
620 if (commentp && prv) 710 if (commentp && prv)
621 *commentp = xstrdup(filename); 711 *commentp = xstrdup(filename);
622 } else { 712 } else {
623 /* it's a SSH v1 key if the public key part is readable */
624 key_free(pub); 713 key_free(pub);
625 /* closes fd */ 714 /* key_parse_public_rsa1() has already loaded the comment */
626 prv = key_load_private_rsa1(fd, filename, passphrase, NULL); 715 prv = key_parse_private_type(&buffer, KEY_RSA1, passphrase,
716 NULL);
627 } 717 }
718 buffer_free(&buffer);
628 return prv; 719 return prv;
629} 720}
630 721
@@ -722,6 +813,7 @@ key_load_private_cert(int type, const char *filename, const char *passphrase,
722 switch (type) { 813 switch (type) {
723 case KEY_RSA: 814 case KEY_RSA:
724 case KEY_DSA: 815 case KEY_DSA:
816 case KEY_ECDSA:
725 break; 817 break;
726 default: 818 default:
727 error("%s: unsupported key type", __func__); 819 error("%s: unsupported key type", __func__);