5 * Packing and unpacking key data
7 * (c) 1999 Straylight/Edgeware
10 /*----- Licensing notice --------------------------------------------------*
12 * This file is part of Catacomb.
14 * Catacomb is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Library General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
19 * Catacomb is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Library General Public License for more details.
24 * You should have received a copy of the GNU Library General Public
25 * License along with Catacomb; if not, write to the Free
26 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
30 /*----- Header files ------------------------------------------------------*/
32 #include <mLib/dstr.h>
37 /*----- Generic packing and unpacking -------------------------------------*/
39 /* --- @key_pack@ --- *
41 * Arguments: @key_packdef *kp@ = pointer to packing structure
42 * @key_data **kd@ = where to put the key data pointer
43 * @dstr *d@ = pointer to tag string for the key data
45 * Returns: Error code, or zero.
47 * Use: Packs a key from a data structure.
50 int key_pack(key_packdef *kp, key_data **kd, dstr *d)
52 switch (kp->e & KF_ENCMASK) {
54 /* --- Binary and integer keys are easy --- */
58 *kd = key_newbinary(kp->e, b->k, b->sz);
62 *kd = key_newmp(kp->e, *(mp **)kp->p);
65 *kd = key_newstring(kp->e, *(char **)kp->p);
68 *kd = key_newec(kp->e, (ec *)kp->p);
71 /* --- Encrypted keys are a little tricky --- *
73 * This works rather differently to unpacking.
78 int err = key_pack(kp->p, &kkd, d);
80 err = key_plock(kd, kkd, d->buf);
86 /* --- Structured keys, as ever, are a nuisance --- */
93 *kd = key_newstruct();
95 for (p = kp->p; p->name; p++) {
99 if ((err = key_pack(&p->kp, &kkd, d)) != 0) {
103 key_structsteal(*kd, p->name, kkd);
114 /* --- @key_unpack@ --- *
116 * Arguments: @key_packdef *kp@ = pointer to packing structure
117 * @key_data *kd@ = pointer to source key data
118 * @dstr *d@ = pointer to tag string for the key data
120 * Returns: Error code, or zero.
122 * Use: Unpacks a key into an appropriate data structure.
125 int key_unpack(key_packdef *kp, key_data *kd, dstr *d)
127 unsigned e = kp->e & KF_ENCMASK;
130 /* --- Decrypt the encrypted key --- */
132 if ((kd->e & KF_ENCMASK) == KENC_ENCRYPT) {
133 if ((err = key_punlock(&kp->kd, kd, d->buf)) != 0)
138 /* --- Ensure that the key has the right type --- */
140 if ((kd->e & KF_ENCMASK) != e) {
141 err = KERR_WRONGTYPE;
145 /* --- Unpack the key --- *
147 * Only three possibilities left now.
152 /* --- Binary and integer keys are easy --- */
155 *(key_bin *)kp->p = kd->u.k;
158 *(mp **)kp->p = kd->u.m;
161 *(char **)kp->p = kd->u.p;
164 *(ec *)kp->p = kd->u.e;
167 /* --- Structured keys take a little care --- */
170 key_packstruct *p, *q;
173 /* --- Iterate over the requested subparts --- */
176 for (p = kp->p; p->name; p++) {
179 /* --- Build the name --- */
184 /* --- Find and unpack the subkey --- */
186 if ((kkd = key_structfind(kd, p->name)) == 0) {
187 if (!(p->kp.e & KF_OPT)) {
191 } else if ((err = key_unpack(&p->kp, kkd, d)) != 0) {
203 /* --- Tidy up if something went wrong --- */
206 for (q = kp->p; q < p; q++)
207 key_unpackdone(&q->kp);
217 /* --- Something went wrong --- */
227 /* --- @key_unpackdone@ --- *
229 * Arguments: @key_packdef *kp@ = pointer to packing definition
233 * Use: Frees the key components contained within a packing
234 * definition, created during key unpacking.
237 void key_unpackdone(key_packdef *kp)
243 if ((kp->e & KF_ENCMASK) == KENC_STRUCT) {
245 for (p = kp->p; p->name; p++)
246 key_unpackdone(&p->kp);
250 /*----- That's all, folks -------------------------------------------------*/