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

1.130   ! djm         1: /* $OpenBSD: key.c,v 1.129 2015/12/04 16:41:28 markus 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,
1.129     markus    133:     const u_char *data, u_int datalen, const char *alg)
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,
1.129     markus    144:            data, datalen, alg, datafellows)) != 0) {
1.118     djm       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.128     djm       185: key_to_certified(Key *k)
1.83      djm       186: {
1.118     djm       187:        int r;
1.83      djm       188:
1.128     djm       189:        if ((r = sshkey_to_certified(k)) != 0) {
1.118     djm       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.130   ! djm       215:        if ((r = sshkey_certify(k, ca, NULL)) != 0) {
1.118     djm       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: