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