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