X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/ba6e6b64033b1f9de49feccb5c9cd438354481f7..0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a:/key-text.c diff --git a/key-text.c b/key-text.c deleted file mode 100644 index ff9e705..0000000 --- a/key-text.c +++ /dev/null @@ -1,346 +0,0 @@ -/* -*-c-*- - * - * $Id$ - * - * Key textual encoding - * - * (c) 1999 Straylight/Edgeware - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of Catacomb. - * - * Catacomb is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * Catacomb is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with Catacomb; if not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - * MA 02111-1307, USA. - */ - -/*----- Header files ------------------------------------------------------*/ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "key-data.h" -#include "mp.h" -#include "mptext.h" - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @key_read@ --- * - * - * Arguments: @const char *p@ = pointer to textual key representation - * @char **pp@ = where to store the end pointer - * - * Returns: The newly-read key data, or null if it failed. - * - * Use: Parses a textual key description. - */ - -key_data *key_read(const char *p, char **pp) -{ - unsigned e; - key_data *kd; - - /* --- Read the encoding type --- * - * - * The key format is `[FLAGS:]DATA'. If there is no encoding type - * named, assume that it's `binary' for backwards compatibility. - */ - - if (strchr(p, ':') == 0) - e = 0; - else { - char *q; - if (key_readflags(p, &q, &e, 0)) - return (0); - p = q + 1; - } - - /* --- Now scan the data based on the encoding type --- */ - - switch (e & KF_ENCMASK) { - - /* --- Binary encoding --- * - * - * Simply read out the Base64-encoded data. Since `,' and `]' are our - * delimeter characters, and they can't appear in Base64-encoded data, I - * can just do a simple search to find the end of the encoded data. - */ - - case KENC_BINARY: - case KENC_ENCRYPT: { - dstr d = DSTR_INIT; - base64_ctx b; - size_t sz = strcspn(p, ",]"); - - base64_init(&b); - base64_decode(&b, p, sz, &d); - base64_decode(&b, 0, 0, &d); - kd = key_newbinary(e, d.buf, d.len); - dstr_destroy(&d); - p += sz; - } break; - - /* --- Multiprecision integer encoding --- * - * - * Multiprecision integers have a convenient reading function. - */ - - case KENC_MP: { - char *q; - mp *m = mp_readstring(e & KF_BURN ? MP_NEWSEC : MP_NEW, p, &q, 0); - if (!m) - return (0); - kd = key_newmp(e, m); - MP_DROP(m); - p = q; - } break; - - /* --- String encoding --- * - * - * We use form-urlencoding to ensure that evil characters don't get out. - */ - - case KENC_STRING: { - dstr d = DSTR_INIT; - size_t sz = strcspn(p, ",]"); - const char *l = p + sz; - unsigned int ch; - int x, n; - - while (p < l) { - switch (*p) { - case '+': - DPUTC(&d, ' '); break; - case '%': - x = sscanf(p + 1, "%2x%n", &ch, &n); - if (x == 1) { DPUTC(&d, ch); p += n; break; } - default: - DPUTC(&d, *p); break; - } - p++; - } - DPUTZ(&d); - kd = key_newstring(e, d.buf); - dstr_destroy(&d); - } break; - - /* --- Elliptic curve encoding --- * - * - * Again, we have a convenient function. Assume for now that points - * aren't secret. (Reasonably safe.) - */ - - case KENC_EC: { - ec pt = EC_INIT; - qd_parse qd; - qd.p = p; - qd.e = 0; - if (!ec_ptparse(&qd, &pt)) - return (0); - kd = key_newec(e, &pt); - EC_DESTROY(&pt); - p = qd.p; - } break; - - /* --- Structured information encoding --- * - * - * The format for structured key data is `[NAME=KEY,...]', where the - * brackets are part of the syntax. Structured keys have no flags apart - * from the encoding. - * - * The binary encoding only allows names up to 255 bytes long. Check for - * this here. - */ - - case KENC_STRUCT: { - dstr d = DSTR_INIT; - key_data *nkd; - char *q; - - /* --- Read the opening bracket --- */ - - kd = key_newstruct(); - if (*p != '[') - return (0); - p++; - - /* --- Read named key subparts --- */ - - for (;;) { - size_t sz; - - /* --- Stop if there's a close-bracket --- * - * - * This allows `[]' to be an empty structured key, which is good. It - * also makes `[foo=enc:bar,]' legal, and that's less good but I can - * live with it. - */ - - if (*p == ']') - break; - - /* --- Read the name out and check the length --- */ - - if ((q = strchr(p, '=')) == 0) - goto fail; - sz = q - p; - if (sz >= 256) - goto fail; - DRESET(&d); - DPUTM(&d, p, sz); - DPUTZ(&d); - - /* --- Read the key data for the subkey --- */ - - if ((nkd = key_read(q + 1, &q)) == 0) - goto fail; - key_structsteal(kd, d.buf, nkd); - p = q; - - /* --- Read the comma or close-bracket --- */ - - if (*p == ']') - break; - else if (*p == ',') - p++; - else - goto fail; - } - - /* --- Step past the close bracket --- */ - - p++; - dstr_destroy(&d); - break; - - /* --- Tidy up after a failure --- */ - - fail: - dstr_destroy(&d); - return (0); - } break; - - /* --- Anything else is unknown --- */ - - default: - return (0); - } - - /* --- Return the end pointer --- */ - - kd->e = e; - if (pp) - *pp = (char *)p; - return (kd); -} - -/* --- @key_write@ --- * - * - * Arguments: @key_data *k@ = pointer to key data - * @dstr *d@ = destination string to write on - * @const key_filter *kf@ = pointer to key selection block - * - * Returns: Nonzero if an item was actually written. - * - * Use: Writes a key in a textual encoding. - */ - -int key_write(key_data *k, dstr *d, const key_filter *kf) -{ - int rc = 0; - if (!KEY_MATCH(k, kf)) - return (0); - switch (k->e & KF_ENCMASK) { - case KENC_BINARY: - case KENC_ENCRYPT: { - base64_ctx b; - - if ((k->e & KF_ENCMASK) == KENC_BINARY) - key_writeflags(k->e, d); - else - DPUTS(d, "encrypt,secret"); - DPUTC(d, ':'); - base64_init(&b); - b.indent = ""; - b.maxline = 0; - base64_encode(&b, k->u.k.k, k->u.k.sz, d); - base64_encode(&b, 0, 0, d); - rc = 1; - } break; - case KENC_MP: - key_writeflags(k->e, d); - DPUTC(d, ':'); - mp_writedstr(k->u.m, d, 10); - rc = 1; - break; - case KENC_STRING: { - const char *p = k->u.p; - key_writeflags(k->e, d); - DPUTC(d, ':'); - while (*p) { - if (*p == ' ') DPUTC(d, '+'); - else if (!isalnum((unsigned char)*p)) dstr_putf(d, "%%%02x", *p); - else DPUTC(d, *p); - p++; - } - rc = 1; - } break; - case KENC_EC: - key_writeflags(k->e, d); - DPUTS(d, ":0x"); mp_writedstr(k->u.e.x, d, 16); - DPUTS(d, ",0x"); mp_writedstr(k->u.e.y, d, 16); - rc = 1; - break; - case KENC_STRUCT: { - key_subkeyiter i; - const char *tag; - char del = 0; - size_t n = d->len; - - DPUTS(d, "struct:["); - for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, &tag, &k); ) { - size_t o = d->len; - if (del) - DPUTC(d, del); - DPUTS(d, tag); - DPUTC(d, '='); - if (!key_write(k, d, kf)) - d->len = o; - else { - del = ','; - rc = 1; - } - } - if (!rc) - d->len = n; - else - DPUTC(d, ']'); - } break; - } - DPUTZ(d); - - return (rc); -} - -/*----- That's all, folks -------------------------------------------------*/