summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2013-12-07 10:41:55 +1100
committerDamien Miller <djm@mindrot.org>2013-12-07 10:41:55 +1100
commitbcd00abd8451f36142ae2ee10cc657202149201e (patch)
tree946db23f1ec607d9260e46b9f6f2422e0e9c970c /authfile.c
parentf0e9060d236c0e38bec2fa1c6579fb0a2ea6458d (diff)
- markus@cvs.openbsd.org 2013/12/06 13:34:54
[authfile.c authfile.h cipher.c cipher.h key.c packet.c ssh-agent.c] [ssh-keygen.c PROTOCOL.key] new private key format, bcrypt as KDF by default; details in PROTOCOL.key; feedback and lots help from djm; ok djm@
Diffstat (limited to 'authfile.c')
-rw-r--r--authfile.c371
1 files changed, 361 insertions, 10 deletions
diff --git a/authfile.c b/authfile.c
index d0c1089eb..e38a3dd14 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.98 2013/11/21 00:45:43 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.99 2013/12/06 13:34:54 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
@@ -13,7 +13,7 @@
13 * called by a name other than "ssh" or "Secure Shell". 13 * called by a name other than "ssh" or "Secure Shell".
14 * 14 *
15 * 15 *
16 * Copyright (c) 2000 Markus Friedl. All rights reserved. 16 * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
17 * 17 *
18 * Redistribution and use in source and binary forms, with or without 18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions 19 * modification, are permitted provided that the following conditions
@@ -58,6 +58,8 @@
58#include <string.h> 58#include <string.h>
59#include <unistd.h> 59#include <unistd.h>
60 60
61#include <util.h>
62
61#include "xmalloc.h" 63#include "xmalloc.h"
62#include "cipher.h" 64#include "cipher.h"
63#include "buffer.h" 65#include "buffer.h"
@@ -68,6 +70,16 @@
68#include "rsa.h" 70#include "rsa.h"
69#include "misc.h" 71#include "misc.h"
70#include "atomicio.h" 72#include "atomicio.h"
73#include "uuencode.h"
74
75/* openssh private key file format */
76#define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n"
77#define MARK_END "-----END OPENSSH PRIVATE KEY-----\n"
78#define KDFNAME "bcrypt"
79#define AUTH_MAGIC "openssh-key-v1"
80#define SALT_LEN 16
81#define DEFAULT_CIPHERNAME "aes256-cbc"
82#define DEFAULT_ROUNDS 16
71 83
72#define MAX_KEY_FILE_SIZE (1024 * 1024) 84#define MAX_KEY_FILE_SIZE (1024 * 1024)
73 85
@@ -75,6 +87,333 @@
75static const char authfile_id_string[] = 87static const char authfile_id_string[] =
76 "SSH PRIVATE KEY FILE FORMAT 1.1\n"; 88 "SSH PRIVATE KEY FILE FORMAT 1.1\n";
77 89
90static int
91key_private_to_blob2(Key *prv, Buffer *blob, const char *passphrase,
92 const char *comment, const char *ciphername, int rounds)
93{
94 u_char *key, *cp, salt[SALT_LEN];
95 size_t keylen, ivlen, blocksize, authlen;
96 u_int len, check;
97 int i, n;
98 const Cipher *c;
99 Buffer encoded, b, kdf;
100 CipherContext ctx;
101 const char *kdfname = KDFNAME;
102
103 if (rounds <= 0)
104 rounds = DEFAULT_ROUNDS;
105 if (passphrase == NULL || !strlen(passphrase)) {
106 ciphername = "none";
107 kdfname = "none";
108 } else if (ciphername == NULL)
109 ciphername = DEFAULT_CIPHERNAME;
110 else if (cipher_number(ciphername) != SSH_CIPHER_SSH2)
111 fatal("invalid cipher");
112
113 if ((c = cipher_by_name(ciphername)) == NULL)
114 fatal("unknown cipher name");
115 buffer_init(&kdf);
116 blocksize = cipher_blocksize(c);
117 keylen = cipher_keylen(c);
118 ivlen = cipher_ivlen(c);
119 authlen = cipher_authlen(c);
120 key = xcalloc(1, keylen + ivlen);
121 if (strcmp(kdfname, "none") != 0) {
122 arc4random_buf(salt, SALT_LEN);
123 if (bcrypt_pbkdf(passphrase, strlen(passphrase),
124 salt, SALT_LEN, key, keylen + ivlen, rounds) < 0)
125 fatal("bcrypt_pbkdf failed");
126 buffer_put_string(&kdf, salt, SALT_LEN);
127 buffer_put_int(&kdf, rounds);
128 }
129 cipher_init(&ctx, c, key, keylen, key + keylen , ivlen, 1);
130 memset(key, 0, keylen + ivlen);
131 free(key);
132
133 buffer_init(&encoded);
134 buffer_append(&encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC));
135 buffer_put_cstring(&encoded, ciphername);
136 buffer_put_cstring(&encoded, kdfname);
137 buffer_put_string(&encoded, buffer_ptr(&kdf), buffer_len(&kdf));
138 buffer_put_int(&encoded, 1); /* number of keys */
139 key_to_blob(prv, &cp, &len); /* public key */
140 buffer_put_string(&encoded, cp, len);
141
142 memset(cp, 0, len);
143 free(cp);
144
145 buffer_free(&kdf);
146
147 /* set up the buffer that will be encrypted */
148 buffer_init(&b);
149
150 /* Random check bytes */
151 check = arc4random();
152 buffer_put_int(&b, check);
153 buffer_put_int(&b, check);
154
155 /* append private key and comment*/
156 key_private_serialize(prv, &b);
157 buffer_put_cstring(&b, comment);
158
159 /* padding */
160 i = 0;
161 while (buffer_len(&b) % blocksize)
162 buffer_put_char(&b, ++i & 0xff);
163
164 /* length */
165 buffer_put_int(&encoded, buffer_len(&b));
166
167 /* encrypt */
168 cp = buffer_append_space(&encoded, buffer_len(&b) + authlen);
169 if (cipher_crypt(&ctx, 0, cp, buffer_ptr(&b), buffer_len(&b), 0,
170 authlen) != 0)
171 fatal("%s: cipher_crypt failed", __func__);
172 buffer_free(&b);
173 cipher_cleanup(&ctx);
174
175 /* uuencode */
176 len = 2 * buffer_len(&encoded);
177 cp = xmalloc(len);
178 n = uuencode(buffer_ptr(&encoded), buffer_len(&encoded),
179 (char *)cp, len);
180 if (n < 0)
181 fatal("%s: uuencode", __func__);
182
183 buffer_clear(blob);
184 buffer_append(blob, MARK_BEGIN, sizeof(MARK_BEGIN) - 1);
185 for (i = 0; i < n; i++) {
186 buffer_put_char(blob, cp[i]);
187 if (i % 70 == 69)
188 buffer_put_char(blob, '\n');
189 }
190 if (i % 70 != 69)
191 buffer_put_char(blob, '\n');
192 buffer_append(blob, MARK_END, sizeof(MARK_END) - 1);
193 free(cp);
194
195 return buffer_len(blob);
196}
197
198static Key *
199key_parse_private2(Buffer *blob, int type, const char *passphrase,
200 char **commentp)
201{
202 u_char *key = NULL, *cp, *salt = NULL, pad, last;
203 char *comment = NULL, *ciphername = NULL, *kdfname = NULL, *kdfp;
204 u_int keylen = 0, ivlen, blocksize, slen, klen, len, rounds, nkeys;
205 u_int check1, check2, m1len, m2len;
206 size_t authlen;
207 const Cipher *c;
208 Buffer b, encoded, copy, kdf;
209 CipherContext ctx;
210 Key *k = NULL;
211 int dlen, ret, i;
212
213 buffer_init(&b);
214 buffer_init(&kdf);
215 buffer_init(&encoded);
216 buffer_init(&copy);
217
218 /* uudecode */
219 m1len = sizeof(MARK_BEGIN) - 1;
220 m2len = sizeof(MARK_END) - 1;
221 cp = buffer_ptr(blob);
222 len = buffer_len(blob);
223 if (len < m1len || memcmp(cp, MARK_BEGIN, m1len)) {
224 debug("%s: missing begin marker", __func__);
225 goto out;
226 }
227 cp += m1len;
228 len -= m1len;
229 while (len) {
230 if (*cp != '\n' && *cp != '\r')
231 buffer_put_char(&encoded, *cp);
232 last = *cp;
233 len--;
234 cp++;
235 if (last == '\n') {
236 if (len >= m2len && !memcmp(cp, MARK_END, m2len)) {
237 buffer_put_char(&encoded, '\0');
238 break;
239 }
240 }
241 }
242 if (!len) {
243 debug("%s: no end marker", __func__);
244 goto out;
245 }
246 len = buffer_len(&encoded);
247 if ((cp = buffer_append_space(&copy, len)) == NULL) {
248 error("%s: buffer_append_space", __func__);
249 goto out;
250 }
251 if ((dlen = uudecode(buffer_ptr(&encoded), cp, len)) < 0) {
252 error("%s: uudecode failed", __func__);
253 goto out;
254 }
255 if ((u_int)dlen > len) {
256 error("%s: crazy uudecode length %d > %u", __func__, dlen, len);
257 goto out;
258 }
259 buffer_consume_end(&copy, len - dlen);
260 if (buffer_len(&copy) < sizeof(AUTH_MAGIC) ||
261 memcmp(buffer_ptr(&copy), AUTH_MAGIC, sizeof(AUTH_MAGIC))) {
262 error("%s: bad magic", __func__);
263 goto out;
264 }
265 buffer_consume(&copy, sizeof(AUTH_MAGIC));
266
267 ciphername = buffer_get_cstring_ret(&copy, NULL);
268 if (ciphername == NULL ||
269 (c = cipher_by_name(ciphername)) == NULL) {
270 error("%s: unknown cipher name", __func__);
271 goto out;
272 }
273 if ((passphrase == NULL || !strlen(passphrase)) &&
274 strcmp(ciphername, "none") != 0) {
275 /* passphrase required */
276 goto out;
277 }
278 kdfname = buffer_get_cstring_ret(&copy, NULL);
279 if (kdfname == NULL ||
280 (!strcmp(kdfname, "none") && !strcmp(kdfname, "bcrypt"))) {
281 error("%s: unknown kdf name", __func__);
282 goto out;
283 }
284 if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) {
285 error("%s: cipher %s requires kdf", __func__, ciphername);
286 goto out;
287 }
288 /* kdf options */
289 kdfp = buffer_get_string_ptr_ret(&copy, &klen);
290 if (kdfp == NULL) {
291 error("%s: kdf options not set", __func__);
292 goto out;
293 }
294 if (klen > 0) {
295 if ((cp = buffer_append_space(&kdf, klen)) == NULL) {
296 error("%s: kdf alloc failed", __func__);
297 goto out;
298 }
299 memcpy(cp, kdfp, klen);
300 }
301 /* number of keys */
302 if (buffer_get_int_ret(&nkeys, &copy) < 0) {
303 error("%s: key counter missing", __func__);
304 goto out;
305 }
306 if (nkeys != 1) {
307 error("%s: only one key supported", __func__);
308 goto out;
309 }
310 /* pubkey */
311 if ((cp = buffer_get_string_ret(&copy, &len)) == NULL) {
312 error("%s: pubkey not found", __func__);
313 goto out;
314 }
315 free(cp); /* XXX check pubkey against decrypted private key */
316
317 /* size of encrypted key blob */
318 len = buffer_get_int(&copy);
319 blocksize = cipher_blocksize(c);
320 authlen = cipher_authlen(c);
321 if (len < blocksize) {
322 error("%s: encrypted data too small", __func__);
323 goto out;
324 }
325 if (len % blocksize) {
326 error("%s: length not multiple of blocksize", __func__);
327 goto out;
328 }
329
330 /* setup key */
331 keylen = cipher_keylen(c);
332 ivlen = cipher_ivlen(c);
333 key = xcalloc(1, keylen + ivlen);
334 if (!strcmp(kdfname, "bcrypt")) {
335 if ((salt = buffer_get_string_ret(&kdf, &slen)) == NULL) {
336 error("%s: salt not set", __func__);
337 goto out;
338 }
339 if (buffer_get_int_ret(&rounds, &kdf) < 0) {
340 error("%s: rounds not set", __func__);
341 goto out;
342 }
343 if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen,
344 key, keylen + ivlen, rounds) < 0) {
345 error("%s: bcrypt_pbkdf failed", __func__);
346 goto out;
347 }
348 }
349
350 cp = buffer_append_space(&b, len);
351 cipher_init(&ctx, c, key, keylen, key + keylen, ivlen, 0);
352 ret = cipher_crypt(&ctx, 0, cp, buffer_ptr(&copy), len, 0, authlen);
353 cipher_cleanup(&ctx);
354 buffer_consume(&copy, len);
355
356 /* fail silently on decryption errors */
357 if (ret != 0) {
358 debug("%s: decrypt failed", __func__);
359 goto out;
360 }
361
362 if (buffer_len(&copy) != 0) {
363 error("%s: key blob has trailing data (len = %u)", __func__,
364 buffer_len(&copy));
365 goto out;
366 }
367
368 /* check bytes */
369 if (buffer_get_int_ret(&check1, &b) < 0 ||
370 buffer_get_int_ret(&check2, &b) < 0) {
371 error("check bytes missing");
372 goto out;
373 }
374 if (check1 != check2) {
375 debug("%s: decrypt failed: 0x%08x != 0x%08x", __func__,
376 check1, check2);
377 goto out;
378 }
379
380 k = key_private_deserialize(&b);
381
382 /* comment */
383 comment = buffer_get_cstring_ret(&b, NULL);
384
385 i = 0;
386 while (buffer_len(&b)) {
387 if (buffer_get_char_ret(&pad, &b) == -1 ||
388 pad != (++i & 0xff)) {
389 error("%s: bad padding", __func__);
390 key_free(k);
391 k = NULL;
392 goto out;
393 }
394 }
395
396 if (k && commentp) {
397 *commentp = comment;
398 comment = NULL;
399 }
400
401 /* XXX decode pubkey and check against private */
402 out:
403 free(ciphername);
404 free(kdfname);
405 free(salt);
406 free(comment);
407 if (key)
408 memset(key, 0, keylen + ivlen);
409 free(key);
410 buffer_free(&encoded);
411 buffer_free(&copy);
412 buffer_free(&kdf);
413 buffer_free(&b);
414 return k;
415}
416
78/* 417/*
79 * Serialises the authentication (private) key to a blob, encrypting it with 418 * Serialises the authentication (private) key to a blob, encrypting it with
80 * passphrase. The identification of the blob (lowest 64 bits of n) will 419 * passphrase. The identification of the blob (lowest 64 bits of n) will
@@ -149,8 +488,9 @@ key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase,
149 488
150 cipher_set_key_string(&ciphercontext, cipher, passphrase, 489 cipher_set_key_string(&ciphercontext, cipher, passphrase,
151 CIPHER_ENCRYPT); 490 CIPHER_ENCRYPT);
152 cipher_crypt(&ciphercontext, 0, cp, 491 if (cipher_crypt(&ciphercontext, 0, cp,
153 buffer_ptr(&buffer), buffer_len(&buffer), 0, 0); 492 buffer_ptr(&buffer), buffer_len(&buffer), 0, 0) != 0)
493 fatal("%s: cipher_crypt failed", __func__);
154 cipher_cleanup(&ciphercontext); 494 cipher_cleanup(&ciphercontext);
155 memset(&ciphercontext, 0, sizeof(ciphercontext)); 495 memset(&ciphercontext, 0, sizeof(ciphercontext));
156 496
@@ -239,7 +579,8 @@ key_save_private_blob(Buffer *keybuf, const char *filename)
239/* Serialise "key" to buffer "blob" */ 579/* Serialise "key" to buffer "blob" */
240static int 580static int
241key_private_to_blob(Key *key, Buffer *blob, const char *passphrase, 581key_private_to_blob(Key *key, Buffer *blob, const char *passphrase,
242 const char *comment) 582 const char *comment, int force_new_format, const char *new_format_cipher,
583 int new_format_rounds)
243{ 584{
244 switch (key->type) { 585 switch (key->type) {
245 case KEY_RSA1: 586 case KEY_RSA1:
@@ -247,6 +588,10 @@ key_private_to_blob(Key *key, Buffer *blob, const char *passphrase,
247 case KEY_DSA: 588 case KEY_DSA:
248 case KEY_ECDSA: 589 case KEY_ECDSA:
249 case KEY_RSA: 590 case KEY_RSA:
591 if (force_new_format) {
592 return key_private_to_blob2(key, blob, passphrase,
593 comment, new_format_cipher, new_format_rounds);
594 }
250 return key_private_pem_to_blob(key, blob, passphrase, comment); 595 return key_private_pem_to_blob(key, blob, passphrase, comment);
251 default: 596 default:
252 error("%s: cannot save key type %d", __func__, key->type); 597 error("%s: cannot save key type %d", __func__, key->type);
@@ -256,13 +601,15 @@ key_private_to_blob(Key *key, Buffer *blob, const char *passphrase,
256 601
257int 602int
258key_save_private(Key *key, const char *filename, const char *passphrase, 603key_save_private(Key *key, const char *filename, const char *passphrase,
259 const char *comment) 604 const char *comment, int force_new_format, const char *new_format_cipher,
605 int new_format_rounds)
260{ 606{
261 Buffer keyblob; 607 Buffer keyblob;
262 int success = 0; 608 int success = 0;
263 609
264 buffer_init(&keyblob); 610 buffer_init(&keyblob);
265 if (!key_private_to_blob(key, &keyblob, passphrase, comment)) 611 if (!key_private_to_blob(key, &keyblob, passphrase, comment,
612 force_new_format, new_format_cipher, new_format_rounds))
266 goto out; 613 goto out;
267 if (!key_save_private_blob(&keyblob, filename)) 614 if (!key_save_private_blob(&keyblob, filename))
268 goto out; 615 goto out;
@@ -473,8 +820,9 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp)
473 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ 820 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
474 cipher_set_key_string(&ciphercontext, cipher, passphrase, 821 cipher_set_key_string(&ciphercontext, cipher, passphrase,
475 CIPHER_DECRYPT); 822 CIPHER_DECRYPT);
476 cipher_crypt(&ciphercontext, 0, cp, 823 if (cipher_crypt(&ciphercontext, 0, cp,
477 buffer_ptr(&copy), buffer_len(&copy), 0, 0); 824 buffer_ptr(&copy), buffer_len(&copy), 0, 0) != 0)
825 fatal("%s: cipher_crypt failed", __func__);
478 cipher_cleanup(&ciphercontext); 826 cipher_cleanup(&ciphercontext);
479 memset(&ciphercontext, 0, sizeof(ciphercontext)); 827 memset(&ciphercontext, 0, sizeof(ciphercontext));
480 buffer_free(&copy); 828 buffer_free(&copy);
@@ -641,6 +989,8 @@ static Key *
641key_parse_private_type(Buffer *blob, int type, const char *passphrase, 989key_parse_private_type(Buffer *blob, int type, const char *passphrase,
642 char **commentp) 990 char **commentp)
643{ 991{
992 Key *k;
993
644 switch (type) { 994 switch (type) {
645 case KEY_RSA1: 995 case KEY_RSA1:
646 return key_parse_private_rsa1(blob, passphrase, commentp); 996 return key_parse_private_rsa1(blob, passphrase, commentp);
@@ -648,6 +998,8 @@ key_parse_private_type(Buffer *blob, int type, const char *passphrase,
648 case KEY_ECDSA: 998 case KEY_ECDSA:
649 case KEY_RSA: 999 case KEY_RSA:
650 case KEY_UNSPEC: 1000 case KEY_UNSPEC:
1001 if ((k = key_parse_private2(blob, type, passphrase, commentp)))
1002 return k;
651 return key_parse_private_pem(blob, type, passphrase, commentp); 1003 return key_parse_private_pem(blob, type, passphrase, commentp);
652 default: 1004 default:
653 error("%s: cannot parse key type %d", __func__, type); 1005 error("%s: cannot parse key type %d", __func__, type);
@@ -943,4 +1295,3 @@ key_in_file(Key *key, const char *filename, int strict_type)
943 fclose(f); 1295 fclose(f);
944 return ret; 1296 return ret;
945} 1297}
946