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