+ /* --- 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);
+ k->u.p = xstrdup(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: {
+ qd_parse qd;
+ qd.p = p;
+ qd.e = 0;
+ EC_CREATE(&k->u.e);
+ if (!ec_ptparse(&qd, &k->u.e))
+ return (-1);
+ p = qd.p;
+ } break;
+