Annotation of src/usr.bin/ssh/key.c, Revision 1.118
1.118 ! djm 1: /* $OpenBSD: key.c,v 1.117 2014/04/29 18:01:49 markus 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);
! 420: if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT)
! 421: debug("%s: %s", __func__, ssh_err(r));
! 422: else
! 423: error("%s: %s", __func__, ssh_err(r));
! 424: return NULL;
1.92 djm 425: }
1.118 ! djm 426: return ret;
1.92 djm 427: }
428:
1.118 ! djm 429: #ifdef WITH_OPENSSL
! 430: Key *
! 431: key_load_private_pem(int fd, int type, const char *passphrase,
! 432: char **commentp)
1.92 djm 433: {
1.118 ! djm 434: int r;
! 435: Key *ret = NULL;
1.92 djm 436:
1.118 ! djm 437: if ((r = sshkey_load_private_pem(fd, type, passphrase,
! 438: &ret, commentp)) != 0) {
! 439: fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
! 440: error("%s: %s", __func__, ssh_err(r));
! 441: return NULL;
! 442: }
! 443: return ret;
1.92 djm 444: }
1.118 ! djm 445: #endif /* WITH_OPENSSL */
1.92 djm 446:
1.118 ! djm 447: int
! 448: key_perm_ok(int fd, const char *filename)
1.107 markus 449: {
1.118 ! djm 450: return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0;
1.107 markus 451: }
452:
1.118 ! djm 453: int
! 454: key_in_file(Key *key, const char *filename, int strict_type)
1.107 markus 455: {
1.118 ! djm 456: int r;
1.107 markus 457:
1.118 ! djm 458: if ((r = sshkey_in_file(key, filename, strict_type)) != 0) {
! 459: fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
! 460: if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT)
! 461: return 0;
! 462: error("%s: %s", __func__, ssh_err(r));
! 463: return r == SSH_ERR_KEY_NOT_FOUND ? 0 : -1;
1.107 markus 464: }
1.118 ! djm 465: return 1;
1.107 markus 466: }