3 * $Id: key-pack.c,v 1.2 2004/03/28 01:58:47 mdw Exp $
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 /*----- Revision history --------------------------------------------------*
32 * $Log: key-pack.c,v $
33 * Revision 1.2 2004/03/28 01:58:47 mdw
34 * Generate, store and retreive elliptic curve keys.
36 * Revision 1.1 2000/06/17 10:42:41 mdw
37 * Packing and unpacking structured keys.
41 /*----- Header files ------------------------------------------------------*/
43 #include <mLib/dstr.h>
48 /*----- Generic packing and unpacking -------------------------------------*/
50 /* --- @key_pack@ --- *
52 * Arguments: @key_packdef *kp@ = pointer to packing structure
53 * @key_data *kd@ = pointer to destination key data
54 * @dstr *d@ = pointer to tag string for the key data
56 * Returns: Error code, or zero.
58 * Use: Packs a key from a data structure.
61 int key_pack(key_packdef
*kp
, key_data
*kd
, dstr
*d
)
63 switch (kp
->kd
.e
& KF_ENCMASK
) {
65 /* --- Binary and integer keys are easy --- */
68 kd
->u
.k
= *(key_bin
*)kp
->p
;
71 kd
->u
.m
= *(mp
**)kp
->p
;
74 kd
->u
.p
= *(char **)kp
->p
;
77 kd
->u
.e
= *(ec
*)kp
->p
;
80 /* --- Encrypted keys are a little tricky --- *
82 * This works rather differently to unpacking.
87 int err
= key_pack(kp
->p
, &kkd
, d
);
89 if (key_plock(d
->buf
, &kkd
, kd
))
96 /* --- Structured keys, as ever, are a nuisance --- */
105 for (p
= kp
->p
; p
->name
; p
++) {
109 kkd
= key_structcreate(kd
, p
->name
);
110 if ((err
= key_pack(&p
->kp
, kkd
, d
)) != 0) {
121 return (KERR_BADTYPE
);
124 /* --- @key_unpack@ --- *
126 * Arguments: @key_packdef *kp@ = pointer to packing structure
127 * @key_data *kd@ = pointer to source key data
128 * @dstr *d@ = pointer to tag string for the key data
130 * Returns: Error code, or zero.
132 * Use: Unpacks a key into an appropriate data structure.
135 int key_unpack(key_packdef
*kp
, key_data
*kd
, dstr
*d
)
137 unsigned e
= kp
->kd
.e
& KF_ENCMASK
;
140 /* --- Decrypt the encrypted key --- */
142 while ((kd
->e
& KF_ENCMASK
) == KENC_ENCRYPT
) {
143 if (key_punlock(d
->buf
, kd
, &kp
->kd
)) {
151 /* --- Ensure that the key has the right type --- */
153 if ((kd
->e
& KF_ENCMASK
) != e
) {
158 /* --- Unpack the key --- *
160 * Only three possibilities left now.
165 /* --- Binary and integer keys are easy --- */
168 *(key_bin
*)kp
->p
= kd
->u
.k
;
171 *(mp
**)kp
->p
= kd
->u
.m
;
174 *(char **)kp
->p
= kd
->u
.p
;
177 *(ec
*)kp
->p
= kd
->u
.e
;
180 /* --- Structured keys take a little care --- */
183 key_packstruct
*p
, *q
;
186 /* --- Iterate over the requested subparts --- */
189 for (p
= kp
->p
; p
->name
; p
++) {
192 /* --- Build the name --- */
197 /* --- Find and unpack the subkey --- */
199 if ((kkd
= key_structfind(kd
, p
->name
)) == 0) {
200 if (!(p
->kp
.kd
.e
& KF_OPT
)) {
204 } else if ((err
= key_unpack(&p
->kp
, kkd
, d
)) != 0) {
216 /* --- Tidy up if something went wrong --- */
219 for (q
= kp
->p
; q
< p
; q
++)
220 key_unpackdone(&q
->kp
);
227 /* --- Something went wrong --- */
235 /* --- @key_unpackdone@ --- *
237 * Arguments: @key_packdef *kp@ = pointer to packing definition
241 * Use: Frees the key components contained within a packing
242 * definition, created during key unpacking.
245 void key_unpackdone(key_packdef
*kp
)
247 if (kp
->kd
.e
& KF_TEMP
)
248 key_destroy(&kp
->kd
);
249 if ((kp
->kd
.e
& KF_ENCMASK
) == KENC_STRUCT
) {
251 for (p
= kp
->p
; p
->name
; p
++)
252 key_unpackdone(&p
->kp
);
256 /*----- That's all, folks -------------------------------------------------*/