3 * Packing and unpacking key data
5 * (c) 1999 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of Catacomb.
12 * Catacomb is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Library General Public License as
14 * published by the Free Software Foundation; either version 2 of the
15 * License, or (at your option) any later version.
17 * Catacomb is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Library General Public License for more details.
22 * You should have received a copy of the GNU Library General Public
23 * License along with Catacomb; if not, write to the Free
24 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
28 /*----- Header files ------------------------------------------------------*/
30 #include <mLib/dstr.h>
34 /*----- Generic packing and unpacking -------------------------------------*/
36 /* --- @key_pack@ --- *
38 * Arguments: @key_packdef *kp@ = pointer to packing structure
39 * @key_data **kd@ = where to put the key data pointer
40 * @dstr *d@ = pointer to tag string for the key data
42 * Returns: Error code, or zero.
44 * Use: Packs a key from a data structure.
47 int key_pack(key_packdef
*kp
, key_data
**kd
, dstr
*d
)
49 switch (kp
->e
& KF_ENCMASK
) {
51 /* --- Binary and integer keys are easy --- */
55 *kd
= key_newbinary(kp
->e
, b
->k
, b
->sz
);
59 *kd
= key_newmp(kp
->e
, *(mp
**)kp
->p
);
62 *kd
= key_newstring(kp
->e
, *(char **)kp
->p
);
65 *kd
= key_newec(kp
->e
, (ec
*)kp
->p
);
68 /* --- Encrypted keys are a little tricky --- *
70 * This works rather differently to unpacking.
75 int err
= key_pack(kp
->p
, &kkd
, d
);
77 err
= key_plock(kd
, kkd
, d
->buf
);
83 /* --- Structured keys, as ever, are a nuisance --- */
90 *kd
= key_newstruct();
92 for (p
= kp
->p
; p
->name
; p
++) {
96 if ((err
= key_pack(&p
->kp
, &kkd
, d
)) != 0) {
100 key_structsteal(*kd
, p
->name
, kkd
);
111 /* --- @key_unpack@ --- *
113 * Arguments: @key_packdef *kp@ = pointer to packing structure
114 * @key_data *kd@ = pointer to source key data
115 * @dstr *d@ = pointer to tag string for the key data
117 * Returns: Error code, or zero.
119 * Use: Unpacks a key into an appropriate data structure.
122 int key_unpack(key_packdef
*kp
, key_data
*kd
, dstr
*d
)
124 unsigned e
= kp
->e
& KF_ENCMASK
;
127 /* --- Decrypt the encrypted key --- */
129 if ((kd
->e
& KF_ENCMASK
) == KENC_ENCRYPT
) {
130 if ((err
= key_punlock(&kp
->kd
, kd
, d
->buf
)) != 0)
135 /* --- Ensure that the key has the right type --- */
137 if ((kd
->e
& KF_ENCMASK
) != e
) {
138 err
= KERR_WRONGTYPE
;
142 /* --- Unpack the key --- *
144 * Only three possibilities left now.
149 /* --- Binary and integer keys are easy --- */
152 *(key_bin
*)kp
->p
= kd
->u
.k
;
155 *(mp
**)kp
->p
= kd
->u
.m
;
158 *(char **)kp
->p
= kd
->u
.p
;
161 *(ec
*)kp
->p
= kd
->u
.e
;
164 /* --- Structured keys take a little care --- */
167 key_packstruct
*p
, *q
;
170 /* --- Iterate over the requested subparts --- */
173 for (p
= kp
->p
; p
->name
; p
++) {
176 /* --- Build the name --- */
181 /* --- Find and unpack the subkey --- */
183 if ((kkd
= key_structfind(kd
, p
->name
)) == 0) {
184 if (!(p
->kp
.e
& KF_OPT
)) {
188 } else if ((err
= key_unpack(&p
->kp
, kkd
, d
)) != 0) {
200 /* --- Tidy up if something went wrong --- */
203 for (q
= kp
->p
; q
< p
; q
++)
204 key_unpackdone(&q
->kp
);
214 /* --- Something went wrong --- */
224 /* --- @key_unpackdone@ --- *
226 * Arguments: @key_packdef *kp@ = pointer to packing definition
230 * Use: Frees the key components contained within a packing
231 * definition, created during key unpacking.
234 void key_unpackdone(key_packdef
*kp
)
240 if ((kp
->e
& KF_ENCMASK
) == KENC_STRUCT
) {
242 for (p
= kp
->p
; p
->name
; p
++)
243 key_unpackdone(&p
->kp
);
247 /*----- That's all, folks -------------------------------------------------*/