libc/_collate_lookup: Fix segfault seen on ISO-8859-5 locales
[dragonfly.git] / crypto / openssh / key.c
blob206076159a9ce858430a9bc317dd6731ccffa52c
1 /* $OpenBSD: key.c,v 1.122 2014/07/22 01:18:50 dtucker Exp $ */
2 /*
3 * placed in the public domain
4 */
6 #include "includes.h"
8 #include <sys/param.h>
9 #include <sys/types.h>
10 #include <errno.h>
11 #include <stdarg.h>
12 #include <stdio.h>
14 #define SSH_KEY_NO_DEFINE
15 #include "key.h"
17 #include "compat.h"
18 #include "sshkey.h"
19 #include "ssherr.h"
20 #include "log.h"
21 #include "authfile.h"
23 void
24 key_add_private(Key *k)
26 int r;
28 if ((r = sshkey_add_private(k)) != 0)
29 fatal("%s: %s", __func__, ssh_err(r));
32 Key *
33 key_new_private(int type)
35 Key *ret = NULL;
37 if ((ret = sshkey_new_private(type)) == NULL)
38 fatal("%s: failed", __func__);
39 return ret;
42 u_char*
43 key_fingerprint_raw(const Key *k, enum fp_type dgst_type,
44 u_int *dgst_raw_length)
46 u_char *ret = NULL;
47 size_t dlen;
48 int r;
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;
60 int
61 key_read(Key *ret, char **cpp)
63 return sshkey_read(ret, cpp) == 0 ? 1 : -1;
66 int
67 key_write(const Key *key, FILE *f)
69 return sshkey_write(key, f) == 0 ? 1 : 0;
72 Key *
73 key_generate(int type, u_int bits)
75 int r;
76 Key *ret = NULL;
78 if ((r = sshkey_generate(type, bits, &ret)) != 0)
79 fatal("%s: %s", __func__, ssh_err(r));
80 return ret;
83 void
84 key_cert_copy(const Key *from_key, Key *to_key)
86 int r;
88 if ((r = sshkey_cert_copy(from_key, to_key)) != 0)
89 fatal("%s: %s", __func__, ssh_err(r));
92 Key *
93 key_from_private(const Key *k)
95 int r;
96 Key *ret = NULL;
98 if ((r = sshkey_from_private(k, &ret)) != 0)
99 fatal("%s: %s", __func__, ssh_err(r));
100 return ret;
103 static void
104 fatal_on_fatal_errors(int r, const char *func, int extra_fatal)
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));
112 Key *
113 key_from_blob(const u_char *blob, u_int blen)
115 int r;
116 Key *ret = NULL;
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;
123 return ret;
127 key_to_blob(const Key *key, u_char **blobp, u_int *lenp)
129 u_char *blob;
130 size_t blen;
131 int r;
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;
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;
152 key_sign(const Key *key, u_char **sigp, u_int *lenp,
153 const u_char *data, u_int datalen)
155 int r;
156 u_char *sig;
157 size_t siglen;
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;
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;
179 key_verify(const Key *key, const u_char *signature, u_int signaturelen,
180 const u_char *data, u_int datalen)
182 int r;
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;
190 return 1;
193 Key *
194 key_demote(const Key *k)
196 int r;
197 Key *ret = NULL;
199 if ((r = sshkey_demote(k, &ret)) != 0)
200 fatal("%s: %s", __func__, ssh_err(r));
201 return ret;
205 key_to_certified(Key *k, int legacy)
207 int r;
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;
214 return 0;
218 key_drop_cert(Key *k)
220 int r;
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;
227 return 0;
231 key_certify(Key *k, Key *ca)
233 int r;
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;
240 return 0;
244 key_cert_check_authority(const Key *k, int want_host, int require_principal,
245 const char *name, const char **reason)
247 int r;
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;
255 return 0;
258 #if defined(WITH_OPENSSL) && defined(OPENSSL_HAS_ECC)
260 key_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
262 int r;
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;
269 return 0;
273 key_ec_validate_private(const EC_KEY *key)
275 int r;
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;
282 return 0;
284 #endif /* WITH_OPENSSL */
286 void
287 key_private_serialize(const Key *key, struct sshbuf *b)
289 int r;
291 if ((r = sshkey_private_serialize(key, b)) != 0)
292 fatal("%s: %s", __func__, ssh_err(r));
295 Key *
296 key_private_deserialize(struct sshbuf *blob)
298 int r;
299 Key *ret = NULL;
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;
306 return ret;
309 /* authfile.c */
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)
316 int r;
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;
324 return 1;
328 key_load_file(int fd, const char *filename, struct sshbuf *blob)
330 int r;
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;
337 return 1;
340 Key *
341 key_load_cert(const char *filename)
343 int r;
344 Key *ret = NULL;
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;
355 return ret;
359 Key *
360 key_load_public(const char *filename, char **commentp)
362 int r;
363 Key *ret = NULL;
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;
374 return ret;
377 Key *
378 key_load_private(const char *path, const char *passphrase,
379 char **commentp)
381 int r;
382 Key *ret = NULL;
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;
394 return ret;
397 Key *
398 key_load_private_cert(int type, const char *filename, const char *passphrase,
399 int *perm_ok)
401 int r;
402 Key *ret = NULL;
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;
415 return ret;
418 Key *
419 key_load_private_type(int type, const char *filename, const char *passphrase,
420 char **commentp, int *perm_ok)
422 int r;
423 Key *ret = NULL;
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;
436 return ret;
439 #ifdef WITH_OPENSSL
440 Key *
441 key_load_private_pem(int fd, int type, const char *passphrase,
442 char **commentp)
444 int r;
445 Key *ret = NULL;
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;
456 return ret;
458 #endif /* WITH_OPENSSL */
461 key_perm_ok(int fd, const char *filename)
463 return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0;
467 key_in_file(Key *key, const char *filename, int strict_type)
469 int r;
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;
478 return 1;