[BACK]Return to params.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / cgdconfig

Annotation of src/sbin/cgdconfig/params.c, Revision 1.10

1.10    ! tv          1: /* $NetBSD: params.c,v 1.9.2.1 2004/08/13 15:00:13 tv Exp $ */
1.1       elric       2:
                      3: /*-
1.5       elric       4:  * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
1.1       elric       5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Roland C. Dowdeswell.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *        This product includes software developed by the NetBSD
                     21:  *        Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
                     38:
                     39: #include <sys/cdefs.h>
                     40: #ifndef lint
1.10    ! tv         41: __RCSID("$NetBSD: params.c,v 1.9.2.1 2004/08/13 15:00:13 tv Exp $");
1.1       elric      42: #endif
                     43:
                     44: #include <sys/types.h>
                     45:
1.5       elric      46: #include <err.h>
1.1       elric      47: #include <errno.h>
                     48: #include <stdio.h>
1.5       elric      49: #include <stdlib.h>
1.1       elric      50: #include <string.h>
1.7       itojun     51: #include <err.h>
1.1       elric      52:
                     53: #include "params.h"
1.5       elric      54: #include "pkcs5_pbkdf2.h"
1.1       elric      55: #include "utils.h"
                     56:
1.5       elric      57: /* from cgdparse.y */
                     58: struct params  *cgdparsefile(FILE *);
                     59:
                     60: static void    params_init(struct params *);
                     61:
                     62: static void    print_kvpair_cstr(FILE *, int, const char *, const char *);
                     63: static void    print_kvpair_string(FILE *, int, const char *, const string_t *);
                     64: static void    print_kvpair_int(FILE *, int, const char *, int);
                     65: static void    print_kvpair_b64(FILE *, int, int, const char *, bits_t *);
                     66:
                     67: static void    spaces(FILE *, int);
                     68:
                     69: /* keygen defaults */
                     70: #define DEFAULT_SALTLEN                128
                     71: #define DEFAULT_ITERATION_TIME 2000000         /* 1 second in milliseconds */
                     72:
                     73: /* crypto defaults functions */
                     74: struct crypto_defaults {
                     75:        char    alg[32];
                     76:        int     keylen;
                     77: } crypto_defaults[] = {
                     78:        { "aes-cbc",            128 },
                     79:        { "3des-cbc",           192 },
                     80:        { "blowfish-cbc",       128 }
                     81: };
                     82:
                     83: static int     crypt_defaults_lookup(const char *);
                     84:
                     85: struct params *
                     86: params_new(void)
                     87: {
                     88:        struct params   *p;
                     89:
                     90:        p = malloc(sizeof(*p));
                     91:        params_init(p);
                     92:        return p;
                     93: }
1.1       elric      94:
1.5       elric      95: static void
1.1       elric      96: params_init(struct params *p)
                     97: {
                     98:
1.5       elric      99:        p->algorithm = NULL;
1.1       elric     100:        p->ivmeth = NULL;
                    101:        p->key = NULL;
                    102:        p->keylen = -1;
                    103:        p->bsize = -1;
1.2       elric     104:        p->verify_method = VERIFY_UNKNOWN;
1.5       elric     105:        p->dep_keygen = NULL;
                    106:        p->keygen = NULL;
1.1       elric     107: }
                    108:
                    109: void
                    110: params_free(struct params *p)
                    111: {
                    112:
1.5       elric     113:        if (!p)
                    114:                return;
                    115:        string_free(p->algorithm);
                    116:        string_free(p->ivmeth);
                    117:        keygen_free(p->dep_keygen);
                    118:        keygen_free(p->keygen);
                    119: }
                    120:
                    121: struct params *
                    122: params_combine(struct params *p1, struct params *p2)
                    123: {
                    124:        struct params *p;
                    125:
                    126:        if (p1)
                    127:                p = p1;
                    128:        else
                    129:                p = params_new();
                    130:
                    131:        if (!p2)
                    132:                return p;
                    133:
                    134:        if (p2->algorithm)
                    135:                string_assign(&p->algorithm, p2->algorithm);
                    136:        if (p2->ivmeth)
                    137:                string_assign(&p->ivmeth, p2->ivmeth);
                    138:        if (p2->keylen != -1)
                    139:                p->keylen = p2->keylen;
                    140:        if (p2->bsize != -1)
                    141:                p->bsize = p2->bsize;
                    142:        if (p2->verify_method != VERIFY_UNKNOWN)
                    143:                p->verify_method = p2->verify_method;
                    144:
                    145:        p->dep_keygen = keygen_combine(p->dep_keygen, p2->dep_keygen);
                    146:        keygen_addlist(&p->keygen, p2->keygen);
                    147:
                    148:        /*
                    149:         * at this point we should have moved all allocated data
                    150:         * in p2 into p, so we can free it.
                    151:         */
                    152:        free(p2);
                    153:        return p;
1.1       elric     154: }
                    155:
                    156: int
                    157: params_filldefaults(struct params *p)
                    158: {
1.5       elric     159:        int     i;
1.1       elric     160:
1.2       elric     161:        if (p->verify_method == VERIFY_UNKNOWN)
                    162:                p->verify_method = VERIFY_NONE;
1.1       elric     163:        if (!p->ivmeth)
1.5       elric     164:                p->ivmeth = string_fromcharstar("encblkno");
1.1       elric     165:        if (p->keylen == -1) {
1.5       elric     166:                i = crypt_defaults_lookup(string_tocharstar(p->algorithm));
                    167:                if (i != -1) {
                    168:                        p->keylen = crypto_defaults[i].keylen;
                    169:                } else {
                    170:                        warnx("could not determine key length for unknown "
                    171:                            "algorithm \"%s\"",
                    172:                            string_tocharstar(p->algorithm));
                    173:                        return -1;
                    174:                }
1.1       elric     175:        }
                    176:        return 0;
                    177: }
                    178:
1.5       elric     179: /*
                    180:  * params_verify traverses the parameters and all of the keygen methods
                    181:  * looking for inconsistencies.  It outputs warnings on non-fatal errors
                    182:  * such as unknown encryption methods, but returns failure on fatal
                    183:  * conditions such as a PKCS5_PBKDF2 keygen without a salt.  It is intended
                    184:  * to run before key generation.
                    185:  */
                    186:
1.1       elric     187: int
1.5       elric     188: params_verify(const struct params *p)
1.1       elric     189: {
                    190:
1.5       elric     191:        if (!p->algorithm) {
                    192:                warnx("unspecified algorithm");
                    193:                return 0;
                    194:        }
                    195:        /*
                    196:         * we only warn for the encryption method so that it is possible
                    197:         * to use an older cgdconfig(8) with a new kernel that supports
                    198:         * additional crypto algorithms.
                    199:         */
                    200:        if (crypt_defaults_lookup(string_tocharstar(p->algorithm)) == -1)
                    201:                warnx("unknown algorithm \"%s\"(warning)",
                    202:                    string_tocharstar(p->algorithm));
                    203:        /* same rationale with IV methods. */
                    204:        if (!p->ivmeth) {
                    205:                warnx("unspecified IV method");
                    206:                return 0;
                    207:        }
                    208:        if (strcmp("encblkno", string_tocharstar(p->ivmeth)))
                    209:                warnx("unknown IV method \"%s\" (warning)",
                    210:                    string_tocharstar(p->ivmeth));
                    211:        if (p->keylen == -1) {
                    212:                warnx("unspecified key length");
                    213:                return 0;
                    214:        }
                    215:
                    216:        return keygen_verify(p->keygen);
1.1       elric     217: }
                    218:
1.5       elric     219: struct params *
                    220: params_algorithm(string_t *in)
1.1       elric     221: {
1.5       elric     222:        struct params *p = params_new();
1.1       elric     223:
1.5       elric     224:        p->algorithm = in;
                    225:        return p;
1.1       elric     226: }
                    227:
1.5       elric     228: struct params *
                    229: params_ivmeth(string_t *in)
                    230: {
                    231:        struct params *p = params_new();
                    232:
                    233:        p->ivmeth = in;
                    234:        return p;
                    235: }
1.1       elric     236:
1.5       elric     237: struct params *
                    238: params_keylen(int in)
1.1       elric     239: {
1.5       elric     240:        struct params *p = params_new();
1.1       elric     241:
1.5       elric     242:        p->keylen = in;
                    243:        return p;
1.1       elric     244: }
                    245:
1.5       elric     246: struct params *
                    247: params_bsize(int in)
                    248: {
                    249:        struct params *p = params_new();
                    250:
                    251:        p->bsize = in;
                    252:        return p;
                    253: }
1.1       elric     254:
1.5       elric     255: struct params *
                    256: params_verify_method(string_t *in)
1.1       elric     257: {
1.5       elric     258:        struct params *p = params_new();
                    259:        const char *vm = string_tocharstar(in);
                    260:
                    261:        if (!strcmp("none", vm))
                    262:                p->verify_method = VERIFY_NONE;
                    263:        if (!strcmp("disklabel", vm))
                    264:                p->verify_method = VERIFY_DISKLABEL;
                    265:        if (!strcmp("ffs", vm))
                    266:                p->verify_method = VERIFY_FFS;
1.8       cb        267:        if (!strcmp("re-enter", vm))
                    268:                p->verify_method = VERIFY_REENTER;
1.1       elric     269:
1.5       elric     270:        string_free(in);
1.1       elric     271:
1.5       elric     272:        if (p->verify_method == VERIFY_UNKNOWN)
                    273:                fprintf(stderr, "params_setverify_method: unrecognized "
                    274:                    "verify method \"%s\"\n", vm);
                    275:        return p;
                    276: }
1.1       elric     277:
1.5       elric     278: struct params *
                    279: params_keygen(struct keygen *in)
                    280: {
                    281:        struct params *p = params_new();
1.1       elric     282:
1.5       elric     283:        p->keygen = in;
                    284:        return p;
                    285: }
1.1       elric     286:
1.5       elric     287: struct params *
                    288: params_dep_keygen(struct keygen *in)
                    289: {
                    290:        struct params *p = params_new();
1.1       elric     291:
1.5       elric     292:        p->dep_keygen = in;
                    293:        return p;
1.1       elric     294: }
                    295:
1.5       elric     296: struct keygen *
                    297: keygen_new(void)
1.1       elric     298: {
1.5       elric     299:        struct keygen *kg;
1.1       elric     300:
1.5       elric     301:        kg = malloc(sizeof(*kg));
                    302:        if (!kg)
                    303:                return NULL;
                    304:        kg->kg_method = KEYGEN_UNKNOWN;
                    305:        kg->kg_iterations = -1;
                    306:        kg->kg_salt = NULL;
                    307:        kg->kg_key = NULL;
                    308:        kg->next = NULL;
                    309:        return kg;
1.1       elric     310: }
                    311:
1.5       elric     312: void
                    313: keygen_free(struct keygen *kg)
1.1       elric     314: {
                    315:
1.5       elric     316:        if (!kg)
                    317:                return;
                    318:        bits_free(kg->kg_salt);
                    319:        bits_free(kg->kg_key);
                    320:        keygen_free(kg->next);
                    321:        free(kg);
1.1       elric     322: }
                    323:
1.5       elric     324: /*
                    325:  * keygen_verify traverses the keygen structures and ensures
                    326:  * that the appropriate information is available.
                    327:  */
                    328:
1.1       elric     329: int
1.5       elric     330: keygen_verify(const struct keygen *kg)
1.1       elric     331: {
                    332:
1.5       elric     333:        if (!kg)
                    334:                return 1;
                    335:        switch (kg->kg_method) {
1.9       dan       336:        case KEYGEN_PKCS5_PBKDF2_OLD:
1.5       elric     337:                if (kg->kg_iterations == -1) {
                    338:                        warnx("keygen pkcs5_pbkdf2 must provide `iterations'");
                    339:                        return 0;
                    340:                }
                    341:                if (kg->kg_key)
                    342:                        warnx("keygen pkcs5_pbkdf2 does not need a `key'");
                    343:                if (!kg->kg_salt) {
                    344:                        warnx("keygen pkcs5_pbkdf2 must provide a salt");
                    345:                        return 0;
                    346:                }
                    347:                break;
1.9       dan       348:        case KEYGEN_PKCS5_PBKDF2_SHA1:
                    349:                if (kg->kg_iterations == -1) {
                    350:                        warnx("keygen pkcs5_pbkdf2/sha1 must provide `iterations'");
                    351:                        return 0;
                    352:                }
                    353:                if (kg->kg_key)
                    354:                        warnx("keygen pkcs5_pbkdf2/sha1 does not need a `key'");
                    355:                if (!kg->kg_salt) {
                    356:                        warnx("keygen pkcs5_pbkdf2/sha1 must provide a salt");
                    357:                        return 0;
                    358:                }
                    359:                break;
1.5       elric     360:        case KEYGEN_STOREDKEY:
                    361:                if (kg->kg_iterations != -1)
                    362:                        warnx("keygen storedkey does not need `iterations'");
                    363:                if (!kg->kg_key) {
                    364:                        warnx("keygen storedkey must provide a key");
                    365:                        return 0;
                    366:                }
                    367:                if (kg->kg_salt)
                    368:                        warnx("keygen storedkey does not need `salt'");
                    369:                break;
                    370:        case KEYGEN_RANDOMKEY:
1.10    ! tv        371:        case KEYGEN_URANDOMKEY:
1.5       elric     372:                if (kg->kg_iterations != -1)
1.10    ! tv        373:                        warnx("keygen [u]randomkey does not need `iterations'");
1.5       elric     374:                if (kg->kg_key)
1.10    ! tv        375:                        warnx("keygen [u]randomkey does not need `key'");
1.5       elric     376:                if (kg->kg_salt)
1.10    ! tv        377:                        warnx("keygen [u]randomkey does not need `salt'");
1.5       elric     378:                break;
1.1       elric     379:        }
1.5       elric     380:        return keygen_verify(kg->next);
1.1       elric     381: }
                    382:
1.5       elric     383: struct keygen *
                    384: keygen_generate(int method)
1.1       elric     385: {
1.5       elric     386:        struct keygen *kg;
                    387:
                    388:        kg = keygen_new();
                    389:        if (!kg)
                    390:                return NULL;
1.1       elric     391:
1.5       elric     392:        kg->kg_method = method;
                    393:        return kg;
1.1       elric     394: }
                    395:
1.5       elric     396: /*
                    397:  * keygen_filldefaults walks the keygen list and fills in
                    398:  * default values.  The defaults may be either calibrated
                    399:  * or randomly generated so this function is designed to be
                    400:  * called when generating a new parameters file, not when
                    401:  * reading a parameters file.
                    402:  */
                    403:
1.1       elric     404: int
1.5       elric     405: keygen_filldefaults(struct keygen *kg, int keylen)
1.1       elric     406: {
                    407:
1.5       elric     408:        if (!kg)
                    409:                return 0;
                    410:        switch (kg->kg_method) {
1.1       elric     411:        case KEYGEN_RANDOMKEY:
1.10    ! tv        412:        case KEYGEN_URANDOMKEY:
1.5       elric     413:                break;
1.9       dan       414:        case KEYGEN_PKCS5_PBKDF2_OLD:
                    415:        case KEYGEN_PKCS5_PBKDF2_SHA1:
1.10    ! tv        416:                kg->kg_salt = bits_getrandombits(DEFAULT_SALTLEN, 1);
1.5       elric     417:                kg->kg_iterations =
                    418:                    pkcs5_pbkdf2_calibrate(keylen, DEFAULT_ITERATION_TIME);
                    419:                if (kg->kg_iterations < 1) {
                    420:                        fprintf(stderr, "%s: could not calibrate "
                    421:                            "pkcs5_pbkdf2\n", getprogname());
                    422:                        return -1;
                    423:                }
                    424:                break;
                    425:        case KEYGEN_STOREDKEY:
                    426:                /* Generate a random stored key */
1.10    ! tv        427:                kg->kg_key = bits_getrandombits(keylen, 1);
1.5       elric     428:                if (!kg->kg_key) {
                    429:                        warnx("can't generate random bits for storedkey");
                    430:                        return -1;
                    431:                }
1.1       elric     432:                break;
                    433:        default:
                    434:                return -1;
                    435:        }
                    436:
1.5       elric     437:        return keygen_filldefaults(kg->next, keylen);
1.1       elric     438: }
                    439:
1.5       elric     440: struct keygen *
                    441: keygen_combine(struct keygen *kg1, struct keygen *kg2)
1.1       elric     442: {
1.5       elric     443:        struct keygen *kg;
1.1       elric     444:
1.5       elric     445:        if (!kg1 && !kg2)
                    446:                return NULL;
1.1       elric     447:
1.5       elric     448:        if (kg1)
                    449:                kg = kg1;
                    450:        else
                    451:                kg = keygen_new();
1.1       elric     452:
1.5       elric     453:        if (!kg2)
                    454:                return kg;
1.1       elric     455:
1.5       elric     456:        if (kg2->kg_method != KEYGEN_UNKNOWN)
                    457:                kg->kg_method = kg2->kg_method;
                    458:        if (kg2->kg_iterations > 0)
                    459:                kg->kg_iterations = kg2->kg_iterations;
                    460:        if (kg2->kg_salt)
                    461:                bits_assign(&kg->kg_salt, kg2->kg_salt);
                    462:        if (kg2->kg_key)
                    463:                bits_assign(&kg->kg_key, kg2->kg_key);
                    464:        return kg;
1.1       elric     465: }
                    466:
1.5       elric     467: struct keygen *
                    468: keygen_method(string_t *in)
1.1       elric     469: {
1.5       elric     470:        struct keygen *kg = keygen_new();
                    471:        const char *kgm = string_tocharstar(in);
1.1       elric     472:
1.5       elric     473:        if (!strcmp("pkcs5_pbkdf2", kgm))
1.9       dan       474:                kg->kg_method = KEYGEN_PKCS5_PBKDF2_OLD;
                    475:        if (!strcmp("pkcs5_pbkdf2/sha1", kgm))
                    476:                kg->kg_method = KEYGEN_PKCS5_PBKDF2_SHA1;
1.5       elric     477:        if (!strcmp("randomkey", kgm))
                    478:                kg->kg_method = KEYGEN_RANDOMKEY;
                    479:        if (!strcmp("storedkey", kgm))
                    480:                kg->kg_method = KEYGEN_STOREDKEY;
1.10    ! tv        481:        if (!strcmp("urandomkey", kgm))
        !           482:                kg->kg_method = KEYGEN_URANDOMKEY;
1.1       elric     483:
1.5       elric     484:        string_free(in);
1.4       elric     485:
1.5       elric     486:        if (kg->kg_method == KEYGEN_UNKNOWN)
                    487:                fprintf(stderr, "unrecognized key generation method "
                    488:                    "\"%s\"\n", kgm);
                    489:        return kg;
1.4       elric     490: }
                    491:
1.5       elric     492: struct keygen *
                    493: keygen_set_method(struct keygen *kg, string_t *in)
1.2       elric     494: {
                    495:
1.5       elric     496:        return keygen_combine(kg, keygen_method(in));
1.2       elric     497: }
                    498:
1.5       elric     499: struct keygen *
                    500: keygen_salt(bits_t *in)
1.2       elric     501: {
1.5       elric     502:        struct keygen *kg = keygen_new();
1.2       elric     503:
1.5       elric     504:        kg->kg_salt = in;
                    505:        return kg;
1.2       elric     506: }
                    507:
1.5       elric     508: struct keygen *
                    509: keygen_iterations(int in)
1.1       elric     510: {
1.5       elric     511:        struct keygen *kg = keygen_new();
1.1       elric     512:
1.5       elric     513:        kg->kg_iterations = in;
                    514:        return kg;
1.1       elric     515: }
                    516:
1.5       elric     517: void
                    518: keygen_addlist(struct keygen **l, struct keygen *e)
1.1       elric     519: {
1.5       elric     520:        struct keygen *t;
1.1       elric     521:
1.5       elric     522:        if (*l) {
                    523:                t = *l;
                    524:                for (;t->next; t = t->next)
                    525:                        ;
                    526:                t->next = e;
                    527:        } else {
                    528:                *l = e;
                    529:        }
1.1       elric     530: }
                    531:
1.5       elric     532: struct keygen *
                    533: keygen_key(bits_t *in)
1.1       elric     534: {
1.5       elric     535:        struct keygen *kg = keygen_new();
1.1       elric     536:
1.5       elric     537:        kg->kg_key = in;
                    538:        return kg;
1.1       elric     539: }
                    540:
1.5       elric     541: struct params *
                    542: params_fget(FILE *f)
1.1       elric     543: {
1.5       elric     544:        struct params *p;
                    545:
                    546:        p = cgdparsefile(f);
1.1       elric     547:
1.5       elric     548:        if (!p)
                    549:                return NULL;
1.1       elric     550:
1.5       elric     551:        /*
                    552:         * We deal with the deprecated keygen structure by prepending it
                    553:         * to the list of keygens, so that the rest of the code does not
                    554:         * have to deal with this backwards compat issue.  The deprecated
                    555:         * ``xor_key'' field may be stored in p->dep_keygen->kg_key.  If
1.6       elric     556:         * it exists, we construct a storedkey keygen struct as well.  Also,
                    557:         * default the iteration count to 128 as the old code did.
1.5       elric     558:         */
1.1       elric     559:
1.5       elric     560:        if (p->dep_keygen) {
1.6       elric     561:                if (p->dep_keygen->kg_iterations == -1)
                    562:                        p->dep_keygen->kg_iterations = 128;
1.5       elric     563:                p->dep_keygen->next = p->keygen;
                    564:                if (p->dep_keygen->kg_key) {
                    565:                        p->keygen = keygen_generate(KEYGEN_STOREDKEY);
                    566:                        p->keygen->kg_key = p->dep_keygen->kg_key;
                    567:                        p->dep_keygen->kg_key = NULL;
                    568:                        p->keygen->next = p->dep_keygen;
                    569:                } else {
                    570:                        p->keygen = p->dep_keygen;
                    571:                }
                    572:                p->dep_keygen = NULL;
                    573:        }
                    574:        return p;
1.1       elric     575: }
                    576:
1.5       elric     577: struct params *
                    578: params_cget(const char *fn)
1.1       elric     579: {
1.5       elric     580:        struct params   *p;
                    581:        FILE            *f;
1.1       elric     582:
1.5       elric     583:        f = fopen(fn, "r");
                    584:        if (!f) {
                    585:                fprintf(stderr, "failed to open params file \"%s\": %s\n",
                    586:                    fn, strerror(errno));
                    587:                return NULL;
1.1       elric     588:        }
1.5       elric     589:        p = params_fget(f);
                    590:        fclose(f);
                    591:        return p;
1.1       elric     592: }
                    593:
1.5       elric     594: #define WRAP_COL       50
                    595: #define TAB_COL                8
                    596:
                    597: static void
                    598: spaces(FILE *f, int len)
1.1       elric     599: {
                    600:
1.5       elric     601:        while (len-- > 0)
                    602:                fputc(' ', f);
1.1       elric     603: }
                    604:
1.5       elric     605: static void
                    606: print_kvpair_cstr(FILE *f, int ts, const char *key, const char *val)
1.1       elric     607: {
                    608:
1.5       elric     609:        spaces(f, ts);
                    610:        fprintf(f, "%s %s;\n", key, val);
1.1       elric     611: }
                    612:
                    613: static void
1.5       elric     614: print_kvpair_string(FILE *f, int ts, const char *key, const string_t *val)
1.1       elric     615: {
                    616:
1.5       elric     617:        print_kvpair_cstr(f, ts, key, string_tocharstar(val));
1.1       elric     618: }
                    619:
                    620: static void
1.5       elric     621: print_kvpair_int(FILE *f, int ts, const char *key, int val)
1.1       elric     622: {
1.5       elric     623:        char    *tmp;
                    624:
                    625:        if (!key || val == -1)
                    626:                return;
1.1       elric     627:
1.5       elric     628:        asprintf(&tmp, "%d", val);
1.7       itojun    629:        if (!tmp)
                    630:                err(1, "malloc");
1.5       elric     631:        print_kvpair_cstr(f, ts, key, tmp);
                    632:        free(tmp);
1.1       elric     633: }
                    634:
                    635: /*
                    636:  * prints out a base64 encoded k-v pair to f.  It encodes the length
                    637:  * of the bitstream as a 32bit unsigned integer in network byte order
                    638:  * up front.
                    639:  */
                    640:
                    641: static void
1.5       elric     642: print_kvpair_b64(FILE *f, int curpos, int ts, const char *key, bits_t *val)
1.1       elric     643: {
1.5       elric     644:        string_t        *str;
                    645:        int              i;
                    646:        int              len;
                    647:        int              pos;
                    648:        const char      *out;
1.1       elric     649:
1.5       elric     650:        if (!key || !val)
1.1       elric     651:                return;
                    652:
1.5       elric     653:        str = bits_encode(val);
                    654:        out = string_tocharstar(str);
                    655:        len = strlen(out);
                    656:
                    657:        spaces(f, ts);
                    658:        fprintf(f, "%s ", key);
                    659:        curpos += ts + strlen(key) + 1;
                    660:        ts = curpos;
                    661:
                    662:        for (i=0, pos=curpos; i < len; i++, pos++) {
                    663:                if (pos > WRAP_COL) {
                    664:                        fprintf(f, " \\\n");
                    665:                        spaces(f, ts);
                    666:                        pos = ts;
                    667:                }
                    668:                fputc(out[i], f);
                    669:        }
                    670:        fprintf(f, ";\n");
                    671:        string_free(str);
                    672: }
1.1       elric     673:
1.5       elric     674: int
                    675: keygen_fput(struct keygen *kg, int ts, FILE *f)
                    676: {
                    677:        int     curpos = 0;
1.1       elric     678:
1.5       elric     679:        if (!kg)
                    680:                return 0;
                    681:        fprintf(f, "keygen ");
                    682:        curpos += strlen("keygen ");
                    683:        switch (kg->kg_method) {
                    684:        case KEYGEN_STOREDKEY:
                    685:                fprintf(f, "storedkey ");
                    686:                curpos += strlen("storedkey ");
                    687:                print_kvpair_b64(f, curpos, 0, "key", kg->kg_key);
                    688:                break;
                    689:        case KEYGEN_RANDOMKEY:
                    690:                fprintf(f, "randomkey;\n");
                    691:                break;
1.10    ! tv        692:        case KEYGEN_URANDOMKEY:
        !           693:                fprintf(f, "urandomkey;\n");
        !           694:                break;
1.9       dan       695:        case KEYGEN_PKCS5_PBKDF2_OLD:
1.5       elric     696:                fprintf(f, "pkcs5_pbkdf2 {\n");
                    697:                print_kvpair_int(f, ts, "iterations", kg->kg_iterations);
                    698:                print_kvpair_b64(f, 0, ts, "salt", kg->kg_salt);
                    699:                fprintf(f, "};\n");
                    700:                break;
1.9       dan       701:        case KEYGEN_PKCS5_PBKDF2_SHA1:
                    702:                fprintf(f, "pkcs5_pbkdf2/sha1 {\n");
                    703:                print_kvpair_int(f, ts, "iterations", kg->kg_iterations);
                    704:                print_kvpair_b64(f, 0, ts, "salt", kg->kg_salt);
                    705:                fprintf(f, "};\n");
                    706:                break;
1.5       elric     707:        default:
                    708:                fprintf(stderr, "keygen_fput: %d not a valid method\n",
                    709:                    kg->kg_method);
                    710:                break;
1.1       elric     711:        }
1.5       elric     712:        return keygen_fput(kg->next, ts, f);
1.1       elric     713: }
                    714:
                    715: int
                    716: params_fput(struct params *p, FILE *f)
                    717: {
1.5       elric     718:        int     ts = 0;         /* tabstop of 0 spaces */
1.1       elric     719:
1.5       elric     720:        print_kvpair_string(f, ts, "algorithm", p->algorithm);
                    721:        print_kvpair_string(f, ts, "iv-method", p->ivmeth);
                    722:        print_kvpair_int(f, ts, "keylength", p->keylen);
                    723:        print_kvpair_int(f, ts, "blocksize", p->bsize);
1.2       elric     724:        switch (p->verify_method) {
                    725:        case VERIFY_NONE:
1.5       elric     726:                print_kvpair_cstr(f, ts, "verify_method", "none");
1.2       elric     727:                break;
                    728:        case VERIFY_DISKLABEL:
1.5       elric     729:                print_kvpair_cstr(f, ts, "verify_method", "disklabel");
                    730:                break;
                    731:        case VERIFY_FFS:
                    732:                print_kvpair_cstr(f, ts, "verify_method", "ffs");
1.8       cb        733:                break;
                    734:        case VERIFY_REENTER:
                    735:                print_kvpair_cstr(f, ts, "verify_method", "re-enter");
1.2       elric     736:                break;
                    737:        default:
                    738:                fprintf(stderr, "unsupported verify_method (%d)\n",
                    739:                    p->verify_method);
                    740:                return -1;
                    741:        }
1.5       elric     742:        keygen_fput(p->keygen, TAB_COL, f);
1.1       elric     743:        return 0;
                    744: }
                    745:
1.5       elric     746: int
                    747: params_cput(struct params *p, const char *fn)
1.1       elric     748: {
1.5       elric     749:        FILE    *f;
1.1       elric     750:
1.5       elric     751:        if (fn && *fn) {
                    752:                f = fopen(fn, "w");
                    753:                if (!f) {
                    754:                        fprintf(stderr, "could not open outfile \"%s\": %s\n",
                    755:                            fn, strerror(errno));
                    756:                        perror("fopen");
                    757:                        return -1;
                    758:                }
                    759:        } else {
                    760:                f = stdout;
1.1       elric     761:        }
1.5       elric     762:        return params_fput(p, f);
1.1       elric     763: }
                    764:
                    765: static int
1.5       elric     766: crypt_defaults_lookup(const char *alg)
1.1       elric     767: {
1.5       elric     768:        int     i;
1.1       elric     769:
1.5       elric     770:        for (i=0; i < sizeof(crypto_defaults); i++)
                    771:                if (!strcmp(alg, crypto_defaults[i].alg))
                    772:                        break;
1.1       elric     773:
1.5       elric     774:        if (i >= sizeof(crypto_defaults))
                    775:                return -1;
                    776:        else
                    777:                return i;
1.1       elric     778: }

CVSweb <webmaster@jp.NetBSD.org>