summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
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__);