[BACK]Return to key.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

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: }