[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.120

1.120   ! djm         1: /* $OpenBSD: key.c,v 1.119 2014/06/30 12:54:39 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);
1.120   ! djm       346:                /* Old authfile.c ignored all file errors. */
        !           347:                if (r == SSH_ERR_SYSTEM_ERROR)
1.118     djm       348:                        debug("%s: %s", __func__, ssh_err(r));
                    349:                else
                    350:                        error("%s: %s", __func__, ssh_err(r));
                    351:                return NULL;
                    352:        }
                    353:        return ret;
1.93      djm       354:
1.92      djm       355: }
                    356:
1.118     djm       357: Key *
                    358: key_load_public(const char *filename, char **commentp)
1.92      djm       359: {
1.118     djm       360:        int r;
                    361:        Key *ret = NULL;
1.92      djm       362:
1.118     djm       363:        if ((r = sshkey_load_public(filename, &ret, commentp)) != 0) {
                    364:                fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
1.120   ! djm       365:                /* Old authfile.c ignored all file errors. */
        !           366:                if (r == SSH_ERR_SYSTEM_ERROR)
1.118     djm       367:                        debug("%s: %s", __func__, ssh_err(r));
                    368:                else
                    369:                        error("%s: %s", __func__, ssh_err(r));
                    370:                return NULL;
1.92      djm       371:        }
1.118     djm       372:        return ret;
                    373: }
1.92      djm       374:
1.118     djm       375: Key *
                    376: key_load_private(const char *path, const char *passphrase,
                    377:     char **commentp)
                    378: {
                    379:        int r;
                    380:        Key *ret = NULL;
1.92      djm       381:
1.118     djm       382:        if ((r = sshkey_load_private(path, passphrase, &ret, commentp)) != 0) {
                    383:                fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
1.120   ! djm       384:                /* Old authfile.c ignored all file errors. */
        !           385:                if (r == SSH_ERR_SYSTEM_ERROR)
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. */
        !           405:                if (r == SSH_ERR_SYSTEM_ERROR)
1.118     djm       406:                        debug("%s: %s", __func__, ssh_err(r));
                    407:                else
                    408:                        error("%s: %s", __func__, ssh_err(r));
                    409:                return NULL;
1.92      djm       410:        }
                    411:        return ret;
                    412: }
                    413:
1.118     djm       414: Key *
                    415: key_load_private_type(int type, const char *filename, const char *passphrase,
                    416:     char **commentp, int *perm_ok)
1.92      djm       417: {
1.118     djm       418:        int r;
                    419:        Key *ret = NULL;
1.92      djm       420:
1.118     djm       421:        if ((r = sshkey_load_private_type(type, filename, passphrase,
                    422:            &ret, commentp, perm_ok)) != 0) {
                    423:                fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
1.120   ! djm       424:                /* Old authfile.c ignored all file errors. */
        !           425:                if (r == SSH_ERR_SYSTEM_ERROR ||
1.119     djm       426:                    (r == SSH_ERR_KEY_WRONG_PASSPHRASE))
1.118     djm       427:                        debug("%s: %s", __func__, ssh_err(r));
                    428:                else
                    429:                        error("%s: %s", __func__, ssh_err(r));
                    430:                return NULL;
1.92      djm       431:        }
1.118     djm       432:        return ret;
1.92      djm       433: }
                    434:
1.118     djm       435: #ifdef WITH_OPENSSL
                    436: Key *
                    437: key_load_private_pem(int fd, int type, const char *passphrase,
                    438:     char **commentp)
1.92      djm       439: {
1.118     djm       440:        int r;
                    441:        Key *ret = NULL;
1.92      djm       442:
1.118     djm       443:        if ((r = sshkey_load_private_pem(fd, type, passphrase,
                    444:             &ret, commentp)) != 0) {
                    445:                fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
                    446:                error("%s: %s", __func__, ssh_err(r));
                    447:                return NULL;
                    448:        }
                    449:        return ret;
1.92      djm       450: }
1.118     djm       451: #endif /* WITH_OPENSSL */
1.92      djm       452:
1.118     djm       453: int
                    454: key_perm_ok(int fd, const char *filename)
1.107     markus    455: {
1.118     djm       456:        return sshkey_perm_ok(fd, filename) == 0 ? 1 : 0;
1.107     markus    457: }
                    458:
1.118     djm       459: int
                    460: key_in_file(Key *key, const char *filename, int strict_type)
1.107     markus    461: {
1.118     djm       462:        int r;
1.107     markus    463:
1.118     djm       464:        if ((r = sshkey_in_file(key, filename, strict_type)) != 0) {
                    465:                fatal_on_fatal_errors(r, __func__, SSH_ERR_LIBCRYPTO_ERROR);
                    466:                if (r == SSH_ERR_SYSTEM_ERROR && errno == ENOENT)
                    467:                        return 0;
                    468:                error("%s: %s", __func__, ssh_err(r));
                    469:                return r == SSH_ERR_KEY_NOT_FOUND ? 0 : -1;
1.107     markus    470:        }
1.118     djm       471:        return 1;
1.107     markus    472: }