]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - key.c
Vendor import of OpenSSH 6.7p1.
[FreeBSD/FreeBSD.git] / key.c
1 /* $OpenBSD: key.c,v 1.122 2014/07/22 01:18:50 dtucker Exp $ */
2 /*
3  * placed in the public domain
4  */
5
6 #include "includes.h"
7
8 #include <sys/param.h>
9 #include <sys/types.h>
10 #include <errno.h>
11 #include <stdarg.h>
12 #include <stdio.h>
13
14 #define SSH_KEY_NO_DEFINE
15 #include "key.h"
16
17 #include "compat.h"
18 #include "sshkey.h"
19 #include "ssherr.h"
20 #include "log.h"
21 #include "authfile.h"
22
23 void
24 key_add_private(Key *k)
25 {
26         int r;
27
28         if ((r = sshkey_add_private(k)) != 0)
29                 fatal("%s: %s", __func__, ssh_err(r));
30 }
31
32 Key *
33 key_new_private(int type)
34 {
35         Key *ret = NULL;
36
37         if ((ret = sshkey_new_private(type)) == NULL)
38                 fatal("%s: failed", __func__);
39         return ret;
40 }
41
42 u_char*
43 key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
44     u_int *dgst_raw_length)
45 {
46         u_char *ret = NULL;
47         size_t dlen;
48         int r;
49
50         if (dgst_raw_length != NULL)
51                 *dgst_raw_length = 0;
52         if ((r = sshkey_fingerprint_raw(k, dgst_type, &ret, &dlen)) != 0)
53                 fatal("%s: %s", __func__, ssh_err(r));
54         if (dlen > INT_MAX)
55                 fatal("%s: giant len %zu", __func__, dlen);
56         *dgst_raw_length = dlen;
57         return ret;
58 }
59
60 int
61 key_read(Key *ret, char **cpp)
62 {
63         return sshkey_read(ret, cpp) == 0 ? 1 : -1;
64 }
65
66 int
67 key_write(const Key *key, FILE *f)
68 {
69         return sshkey_write(key, f) == 0 ? 1 : 0;
70 }
71
72 Key *
73 key_generate(int type, u_int bits)
74 {
75         int r;
76         Key *ret = NULL;
77
78         if ((r = sshkey_generate(type, bits, &ret)) != 0)
79                 fatal("%s: %s", __func__, ssh_err(r));
80         return ret;
81 }
82
83 void
84 key_cert_copy(const Key *from_key, Key *to_key)
85 {
86         int r;
87
88         if ((r = sshkey_cert_copy(from_key, to_key)) != 0)
89                 fatal("%s: %s", __func__, ssh_err(r));
90 }
91
92 Key *
93 key_from_private(const Key *k)
94 {
95         int r;
96         Key *ret = NULL;
97
98         if ((r = sshkey_from_private(k, &ret)) != 0)
99                 fatal("%s: %s", __func__, ssh_err(r));
100         return ret;
101 }
102
103 static void
104 fatal_on_fatal_errors(int r, const char *func, int extra_fatal)
105 {
106         if (r == SSH_ERR_INTERNAL_ERROR ||
107             r == SSH_ERR_ALLOC_FAIL ||
108             (extra_fatal != 0 && r == extra_fatal))
109                 fatal("%s: %s", func, ssh_err(r));
110 }
111
112 Key *
113 key_from_blob(const u_char *blob, u_int blen)
114 {
115         int r;
116         Key *ret = NULL;
117
118         if ((r = sshkey_from_blob(blob, blen, &ret)) != 0) {
119                 fatal_on_fatal_errors(r, __func__, 0);
120                 error("%s: %s", __func__, ssh_err(r));
121                 return NULL;
122         }
123         return ret;
124 }
125
126 int
127 key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
128 {
129         u_char *blob;
130         size_t blen;
131         int r;
132
133         if (blobp != NULL)
134                 *blobp = NULL;
135         if (lenp != NULL)
136                 *lenp = 0;
137         if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) {
138                 fatal_on_fatal_errors(r, __func__, 0);
139                 error("%s: %s", __func__, ssh_err(r));
140                 return 0;
141         }
142         if (blen > INT_MAX)
143                 fatal("%s: giant len %zu", __func__, blen);
144         if (blobp != NULL)
145                 *blobp = blob;
146         if (lenp != NULL)
147                 *lenp = blen;
148         return blen;
149 }
150
151 int
152 key_sign(const Key *key, u_char **sigp, u_int *lenp,
153     const u_char *data, u_int datalen)
154 {
155         int r;
156         u_char *sig;
157         size_t siglen;
158
159         if (sigp != NULL)
160                 *sigp = NULL;
161         if (lenp != NULL)
162                 *lenp = 0;
163         if ((r = sshkey_sign(key, &sig, &siglen,
164             data, datalen, datafellows)) != 0) {
165                 fatal_on_fatal_errors(r, __func__, 0);
166                 error("%s: %s", __func__, ssh_err(r));
167                 return -1;
168         }
169         if (siglen > INT_MAX)
170                 fatal("%s: giant len %zu", __func__, siglen);
171         if (sigp != NULL)
172                 *sigp = sig;
173         if (lenp != NULL)
174                 *lenp = siglen;
175         return 0;
176 }
177
178 int
179 key_verify(const Key *key, const u_char *signature, u_int signaturelen,
180     const u_char *data, u_int datalen)
181 {
182         int r;
183
184         if ((r = sshkey_verify(key, signature, signaturelen,
185             data, datalen, datafellows)) != 0) {
186                 fatal_on_fatal_errors(r, __func__, 0);
187                 error("%s: %s", __func__, ssh_err(r));
188                 return r == SSH_ERR_SIGNATURE_INVALID ? 0 : -1;
189         }
190         return 1;
191 }
192
193 Key *
194 key_demote(const Key *k)
195 {
196         int r;
197         Key *ret = NULL;
198
199         if ((r = sshkey_demote(k, &ret)) != 0)
200                 fatal("%s: %s", __func__, ssh_err(r));
201         return ret;
202 }
203
204 int
205 key_to_certified(Key *k, int legacy)
206 {
207         int r;
208
209         if ((r = sshkey_to_certified(k, legacy)) != 0) {
210                 fatal_on_fatal_errors(r, __func__, 0);
211                 error("%s: %s", __func__, ssh_err(r));
212                 return -1;
213         }
214         return 0;
215 }
216
217 int
218 key_drop_cert(Key *k)
219 {
220         int r;
221
222         if ((r = sshkey_drop_cert(k)) != 0) {
223                 fatal_on_fatal_errors(r, __func__, 0);
224                 error("%s: %s", __func__, ssh_err(r));
225                 return -1;
226         }
227         return 0;
228 }
229
230 int
231 key_certify(Key *k, Key *ca)
232 {
233         int r;
234
235         if ((r = sshkey_certify(k, ca)) != 0) {
236                 fatal_on_fatal_errors(r, __func__, 0);
237                 error("%s: %s", __func__, ssh_err(r));
238                 return -1;
239         }
240         return 0;
241 }
242
243 int
244 key_cert_check_authority(const Key *k, int want_host, int require_principal,
245     const char *name, const char **reason)
246 {
247         int r;
248
249         if ((r = sshkey_cert_check_authority(k, want_host, require_principal,
250             name, reason)) != 0) {
251                 fatal_on_fatal_errors(r, __func__, 0);
252                 error("%s: %s", __func__, ssh_err(r));
253                 return -1;
254         }
255         return 0;
256 }
257
258 #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
259 int
260 key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
261 {
262         int r;
263
264         if ((r = sshkey_ec_validate_public(group, public)) != 0) {
265                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
266                 error("%s: %s", __func__, ssh_err(r));
267                 return -1;
268         }
269         return 0;
270 }
271
272 int
273 key_ec_validate_private(const EC_KEY *key)
274 {
275         int r;
276
277         if ((r = sshkey_ec_validate_private(key)) != 0) {
278                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
279                 error("%s: %s", __func__, ssh_err(r));
280                 return -1;
281         }
282         return 0;
283 }
284 #endif /* WITH_OPENSSL */
285
286 void
287 key_private_serialize(const Key *key, struct sshbuf *b)
288 {
289         int r;
290
291         if ((r = sshkey_private_serialize(key, b)) != 0)
292                 fatal("%s: %s", __func__, ssh_err(r));
293 }
294
295 Key *
296 key_private_deserialize(struct sshbuf *blob)
297 {
298         int r;
299         Key *ret = NULL;
300
301         if ((r = sshkey_private_deserialize(blob, &ret)) != 0) {
302                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
303                 error("%s: %s", __func__, ssh_err(r));
304                 return NULL;
305         }
306         return ret;
307 }
308
309 /* authfile.c */
310
311 int
312 key_save_private(Key *key, const char *filename, const char *passphrase,
313     const char *comment, int force_new_format, const char *new_format_cipher,
314     int new_format_rounds)
315 {
316         int r;
317
318         if ((r = sshkey_save_private(key, filename, passphrase, comment,
319             force_new_format, new_format_cipher, new_format_rounds)) != 0) {
320                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
321                 error("%s: %s", __func__, ssh_err(r));
322                 return 0;
323         }
324         return 1;
325 }
326
327 int
328 key_load_file(int fd, const char *filename, struct sshbuf *blob)
329 {
330         int r;
331
332         if ((r = sshkey_load_file(fd, filename, blob)) != 0) {
333                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
334                 error("%s: %s", __func__, ssh_err(r));
335                 return 0;
336         }
337         return 1;
338 }
339
340 Key *
341 key_load_cert(const char *filename)
342 {
343         int r;
344         Key *ret = NULL;
345
346         if ((r = sshkey_load_cert(filename, &ret)) != 0) {
347                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
348                 /* Old authfile.c ignored all file errors. */
349                 if (r == SSH_ERR_SYSTEM_ERROR)
350                         debug("%s: %s", __func__, ssh_err(r));
351                 else
352                         error("%s: %s", __func__, ssh_err(r));
353                 return NULL;
354         }
355         return ret;
356
357 }
358
359 Key *
360 key_load_public(const char *filename, char **commentp)
361 {
362         int r;
363         Key *ret = NULL;
364
365         if ((r = sshkey_load_public(filename, &ret, commentp)) != 0) {
366                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
367                 /* Old authfile.c ignored all file errors. */
368                 if (r == SSH_ERR_SYSTEM_ERROR)
369                         debug("%s: %s", __func__, ssh_err(r));
370                 else
371                         error("%s: %s", __func__, ssh_err(r));
372                 return NULL;
373         }
374         return ret;
375 }
376
377 Key *
378 key_load_private(const char *path, const char *passphrase,
379     char **commentp)
380 {
381         int r;
382         Key *ret = NULL;
383
384         if ((r = sshkey_load_private(path, passphrase, &ret, commentp)) != 0) {
385                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
386                 /* Old authfile.c ignored all file errors. */
387                 if (r == SSH_ERR_SYSTEM_ERROR ||
388                     r == SSH_ERR_KEY_WRONG_PASSPHRASE)
389                         debug("%s: %s", __func__, ssh_err(r));
390                 else
391                         error("%s: %s", __func__, ssh_err(r));
392                 return NULL;
393         }
394         return ret;
395 }
396
397 Key *
398 key_load_private_cert(int type, const char *filename, const char *passphrase,
399     int *perm_ok)
400 {
401         int r;
402         Key *ret = NULL;
403
404         if ((r = sshkey_load_private_cert(type, filename, passphrase,
405             &ret, perm_ok)) != 0) {
406                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
407                 /* Old authfile.c ignored all file errors. */
408                 if (r == SSH_ERR_SYSTEM_ERROR ||
409                     r == SSH_ERR_KEY_WRONG_PASSPHRASE)
410                         debug("%s: %s", __func__, ssh_err(r));
411                 else
412                         error("%s: %s", __func__, ssh_err(r));
413                 return NULL;
414         }
415         return ret;
416 }
417
418 Key *
419 key_load_private_type(int type, const char *filename, const char *passphrase,
420     char **commentp, int *perm_ok)
421 {
422         int r;
423         Key *ret = NULL;
424
425         if ((r = sshkey_load_private_type(type, filename, passphrase,
426             &ret, commentp, perm_ok)) != 0) {
427                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
428                 /* Old authfile.c ignored all file errors. */
429                 if (r == SSH_ERR_SYSTEM_ERROR ||
430                     (r == SSH_ERR_KEY_WRONG_PASSPHRASE))
431                         debug("%s: %s", __func__, ssh_err(r));
432                 else
433                         error("%s: %s", __func__, ssh_err(r));
434                 return NULL;
435         }
436         return ret;
437 }
438
439 #ifdef WITH_OPENSSL
440 Key *
441 key_load_private_pem(int fd, int type, const char *passphrase,
442     char **commentp)
443 {
444         int r;
445         Key *ret = NULL;
446
447         if ((r = sshkey_load_private_pem(fd, type, passphrase,
448              &ret, commentp)) != 0) {
449                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
450                 if (r == SSH_ERR_KEY_WRONG_PASSPHRASE)
451                         debug("%s: %s", __func__, ssh_err(r));
452                 else
453                         error("%s: %s", __func__, ssh_err(r));
454                 return NULL;
455         }
456         return ret;
457 }
458 #endif /* WITH_OPENSSL */
459
460 int
461 key_perm_ok(int fd, const char *filename)
462 {
463         return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0;
464 }
465
466 int
467 key_in_file(Key *key, const char *filename, int strict_type)
468 {
469         int r;
470
471         if ((r = sshkey_in_file(key, filename, strict_type)) != 0) {
472                 fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
473                 if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT)
474                         return 0;
475                 error("%s: %s", __func__, ssh_err(r));
476                 return r == SSH_ERR_KEY_NOT_FOUND ? 0 : -1;
477         }
478         return 1;
479 }