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