chiark / gitweb /
d14ad70d81b636a001062488f8dfb90a6bc0a38e
[catacomb-perl] / key.xs
1 # ---?---
2 #
3 # $Id$
4 #
5 # Key-management interface
6 #
7 # (c) 2001 Straylight/Edgeware
8 #
9
10 #----- Licensing notice -----------------------------------------------------
11 #
12 # This file is part of the Perl interface to Catacomb.
13 #
14 # Catacomb/Perl is free software; you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation; either version 2 of the License, or
17 # (at your option) any later version.
18
19 # Catacomb/Perl 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 General Public License for more details.
23
24 # You should have received a copy of the GNU General Public License
25 # along with Catacomb/Perl; if not, write to the Free Software Foundation,
26 # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27
28 MODULE = Catacomb PACKAGE = Catacomb::Key PREFIX = key_
29
30 SV *
31 DESTROY(k)
32         Key *k
33         CODE:
34         keyfile_dec(k->kf);
35         DESTROY(k);
36         XSRETURN_YES;
37
38 bool
39 key_chkident(me, p)
40         SV *me
41         char *p
42         C_ARGS:
43         p
44
45 bool
46 key_chkcomment(me, p)
47         SV *me
48         char *p
49         C_ARGS:
50         p
51
52 time_t
53 exp(k)
54         Key *k
55         CODE:
56         RETVAL = k->k->exp;
57         OUTPUT:
58         RETVAL
59
60 time_t
61 del(k)
62         Key *k
63         CODE:
64         RETVAL = k->k->del;
65         OUTPUT:
66         RETVAL
67
68 Key_DataImpl *
69 _data(k)
70         Key *k
71         CODE:
72         RETVAL = &k->k->k;
73         OUTPUT:
74         RETVAL
75
76 char *
77 comment(k)
78         Key *k
79         CODE:
80         RETVAL = k->k->c;
81         OUTPUT:
82         RETVAL
83
84 U32
85 id(k)
86         Key *k
87         CODE:
88         RETVAL = k->k->id;
89         OUTPUT:
90         RETVAL
91
92 char *
93 tag(k)
94         Key *k
95         CODE:
96         RETVAL = k->k->tag;
97         OUTPUT:
98         RETVAL
99
100 char *
101 type(k)
102         Key *k
103         CODE:
104         RETVAL = k->k->type;
105         OUTPUT:
106         RETVAL
107
108 KeyErr
109 key_setcomment(k, p)
110         Key *k
111         char *p
112         C_ARGS:
113         &k->kf->kf, k->k, p
114
115 KeyErr
116 key_settag(k, p)
117         Key *k
118         char *p
119         C_ARGS:
120         &k->kf->kf, k->k, p
121
122 KeyErr
123 key_delete(k)
124         Key *k
125         C_ARGS:
126         &k->kf->kf, k->k
127
128 SV *
129 fulltag(k)
130         Key *k
131         PREINIT:
132         dstr d = DSTR_INIT;
133         CODE:
134         key_fulltag(k->k, &d);
135         RETVAL = newSVpvn(d.buf, d.len);
136         dstr_destroy(&d);
137         OUTPUT:
138         RETVAL
139
140 const char *
141 key_getattr(k, a)
142         Key *k
143         char *a
144         C_ARGS:
145         &k->kf->kf, k->k, a
146
147 KeyErr
148 putattr(k, a, v = &PL_sv_undef)
149         Key *k
150         char *a
151         SV *v
152         PREINIT:
153         char *vv;
154         STRLEN len;
155         CODE:
156         if (!SvOK(v))
157           vv = 0;
158         else
159           vv = SvPV(v, len);
160         RETVAL = key_putattr(&k->kf->kf, k->k, a, vv);
161         OUTPUT:
162         RETVAL
163
164 Key_AttrIter *
165 attriter(k)
166         Key *k
167         CODE:
168         RETVAL = CREATE(Key_AttrIter);
169         key_mkattriter(&RETVAL->i, k->k);
170         RETVAL->kf = k->kf;
171         k->kf->ref++;
172         OUTPUT:
173         RETVAL
174
175 bool
176 expiredp(k)
177         Key *k
178         CODE:
179         RETVAL = key_expired(k->k);
180         OUTPUT:
181         RETVAL
182
183 KeyErr
184 key_expire(k)
185         Key *k
186         C_ARGS:
187         &k->kf->kf, k->k
188
189 KeyErr
190 key_used(k, t)
191         Key *k
192         time_t t
193         C_ARGS:
194         &k->kf->kf, k->k, t
195
196 bool
197 key_fingerprint(k, h, kf = 0)
198         Key *k
199         ghash *h
200         Key_Filter *kf
201         C_ARGS:
202         k->k, h, kf
203
204 const char *
205 key_strerror(me, err)
206         SV *me
207         int err
208         C_ARGS:
209         err
210
211 MODULE = Catacomb PACKAGE = Catacomb::Key::AttrIter
212
213 void
214 next(i)
215         Key_AttrIter *i
216         PREINIT:
217         const char *a, *v;
218         PPCODE:
219         if (key_nextattr(&i->i, &a, &v)) {
220           XPUSHs(sv_2mortal(newSVpv(a, 0)));
221           if (GIMME_V == G_ARRAY)
222             XPUSHs(sv_2mortal(newSVpv(v, 0)));
223         }
224
225 SV *
226 DESTROY(i)
227         Key_AttrIter *i
228         CODE:
229         keyfile_dec(i->kf);
230         DESTROY(i);
231         XSRETURN_YES;
232
233 MODULE = Catacomb PACKAGE = Catacomb::Key::Filter
234
235 Key_Filter *
236 new(me, f = 0, m = 0)
237         SV *me
238         SV *f
239         SV *m
240         PREINIT:
241         char *p;
242         STRLEN len;
243         CODE:
244         RETVAL = CREATE(Key_Filter);
245         if (!f || !SvOK(f))
246           RETVAL->f = RETVAL->m = 0;
247         else if (m) {
248           RETVAL->f = SvUV(f);
249           RETVAL->m = SvUV(m);
250         } else {
251           p = SvPV(f, len);
252           if (key_readflags(p, 0, &RETVAL->f, &RETVAL->m)) {
253             DESTROY(RETVAL);
254             RETVAL = 0;
255           }
256         }
257         OUTPUT:
258         RETVAL
259
260 SV *
261 DESTROY(kf)
262         Key_Filter *kf
263         CODE:
264         if (!kf)
265           XSRETURN_UNDEF;
266         DESTROY(kf);
267         XSRETURN_YES;
268
269 SV *
270 tostring(kf)
271         Key_Filter *kf
272         PREINIT:
273         dstr d = DSTR_INIT;
274         CODE:
275         if (!kf)
276           XSRETURN_UNDEF;
277         key_writeflags(kf->f, &d);
278         RETVAL = newSVpvn(d.buf, d.len);
279         dstr_destroy(&d);
280         OUTPUT:
281         RETVAL
282
283 UV
284 f(kf)
285         Key_Filter *kf
286         CODE:
287         RETVAL = kf ? kf->f : 0;
288         OUTPUT:
289         RETVAL
290
291 UV
292 m(kf)
293         Key_Filter *kf
294         CODE:
295         RETVAL = kf ? kf->m : 0;
296         OUTPUT:
297         RETVAL
298
299 MODULE = Catacomb PACKAGE = Catacomb::Key::DataImpl PREFIX = key_
300
301 Key_DataImpl *
302 new(me)
303         SV *me
304         CODE:
305         RETVAL = CREATE(key_data);
306         RETVAL->e = 0;
307         RETVAL->u.k.k = 0;
308         RETVAL->u.k.sz = 0;
309         OUTPUT:
310         RETVAL
311
312 SV *
313 free(kd)
314         Key_DataImpl *kd
315         CODE:
316         key_destroy(kd);
317         DESTROY(kd);
318         XSRETURN_YES;
319
320 SV *
321 clear(kd)
322         Key_DataImpl *kd
323         CODE:
324         key_destroy(kd);
325         kd->e = 0;
326         kd->u.k.k = 0;
327         kd->u.k.sz = 0;
328         XSRETURN_YES;
329
330 SV *
331 setbinary(kd, sv)
332         Key_DataImpl *kd
333         SV *sv
334         PREINIT:
335         char *p;
336         STRLEN len;
337         CODE:
338         p = SvPV(sv, len);
339         key_destroy(kd);
340         key_binary(kd, p, len);
341         XSRETURN_YES;
342
343 SV *
344 setencrypted(kd, sv)
345         Key_DataImpl *kd
346         SV *sv
347         PREINIT:
348         char *p;
349         STRLEN len;
350         CODE:
351         p = SvPV(sv, len);
352         key_destroy(kd);
353         key_encrypted(kd, p, len);
354         XSRETURN_YES;
355
356 SV *
357 setmp(kd, x)
358         Key_DataImpl *kd
359         mp *x
360         CODE:
361         key_destroy(kd);
362         key_mp(kd, x);
363         XSRETURN_YES;
364
365 SV *
366 setstring(kd, p)
367         Key_DataImpl *kd
368         char *p
369         CODE:
370         key_destroy(kd);
371         key_string(kd, p);
372         XSRETURN_YES;
373
374 SV *
375 setec(kd, p)
376         Key_DataImpl *kd
377         ec *p
378         CODE:
379         key_destroy(kd);
380         key_ec(kd, p);
381         XSRETURN_YES;
382
383 U32
384 flags(kd)
385         Key_DataImpl *kd
386         CODE:
387         RETVAL = kd->e;
388         OUTPUT: 
389         RETVAL
390
391 SV *
392 setflags(kd, f)
393         Key_DataImpl *kd
394         U32 f
395         CODE:
396         if (f & KF_ENCMASK)
397           croak("can't change encoding flags");
398         kd->e = (kd->e & KF_ENCMASK) | (f & ~KF_ENCMASK);
399         XSRETURN_YES;
400
401 SV *
402 getbinary(kd)
403         Key_DataImpl *kd
404         CODE:
405         if ((kd->e & KF_ENCMASK) != KENC_BINARY)
406           croak("key is not binary");
407         RETVAL = newSVpvn(kd->u.k.k, kd->u.k.sz);
408         OUTPUT:
409         RETVAL
410
411 SV *
412 getencrypted(kd)
413         Key_DataImpl *kd
414         CODE:
415         if ((kd->e & KF_ENCMASK) != KENC_ENCRYPT)
416           croak("key is not encrypted");
417         RETVAL = newSVpvn(kd->u.k.k, kd->u.k.sz);
418         OUTPUT:
419         RETVAL
420
421 mp *
422 getmp(kd)
423         Key_DataImpl *kd
424         CODE:
425         if ((kd->e & KF_ENCMASK) != KENC_MP)
426           croak("key is not bignum");
427         RETVAL = MP_COPY(kd->u.m);
428         OUTPUT:
429         RETVAL
430
431 ec *
432 getec(kd)
433         Key_DataImpl *kd
434         CODE:
435         if ((kd->e & KF_ENCMASK) != KENC_EC)
436           croak("key is not a curve point");
437         RETVAL = CREATE(ec);
438         EC_CREATE(RETVAL);
439         EC_COPY(RETVAL, &kd->u.e);
440         OUTPUT:
441         RETVAL
442
443 char *
444 getstring(kd)
445         Key_DataImpl *kd
446         CODE:
447         if ((kd->e & KF_ENCMASK) != KENC_STRING)
448           croak("key is not string");
449         RETVAL = kd->u.p;
450         OUTPUT:
451         RETVAL
452
453 SV *
454 setstruct(kd)
455         Key_DataImpl *kd
456         CODE:
457         key_destroy(kd);
458         key_structure(kd);
459         XSRETURN_YES;
460
461 Key_DataImpl *
462 key_structfind(kd, tag)
463         Key_DataImpl *kd
464         char *tag
465         INIT:
466         if ((kd->e & KF_ENCMASK) != KENC_STRUCT)
467           XSRETURN_UNDEF;
468
469 Key_DataImpl *
470 key_structcreate(kd, tag)
471         Key_DataImpl *kd
472         char *tag
473         INIT:
474         if ((kd->e & KF_ENCMASK) != KENC_STRUCT)
475           croak("key is not structured");
476
477 Key_StructIter *
478 structiter(kd)
479         Key_DataImpl *kd
480         CODE:
481         if ((kd->e & KF_ENCMASK) != KENC_STRUCT)
482           croak("key is not structured");
483         RETVAL = CREATE(Key_StructIter);
484         sym_mkiter(RETVAL, &kd->u.s);
485         OUTPUT:
486         RETVAL
487
488 SV *
489 structdel(kd, tag)
490         Key_DataImpl *kd
491         char *tag
492         PREINIT:
493         key_struct *ks;
494         CODE:
495         if ((kd->e & KF_ENCMASK) != KENC_STRUCT)
496           croak("key is not structured");
497         if ((ks = sym_find(&kd->u.s, tag, -1, 0, 0)) == 0)
498           XSRETURN_UNDEF;
499         key_destroy(&ks->k);
500         sym_remove(&kd->u.s, ks);
501         XSRETURN_YES;
502
503 bool
504 key_match(kd, kf)
505         Key_DataImpl *kd
506         Key_Filter *kf
507
508 bool
509 set(kd, kkd, kf = 0)
510         Key_DataImpl *kd
511         Key_DataImpl *kkd
512         Key_Filter *kf
513         CODE:
514         key_destroy(kd);
515         kd->e = 0;
516         kd->u.k.k = 0;
517         kd->u.k.sz = 0;
518         RETVAL = key_copy(kd, kkd, kf);
519         OUTPUT:
520         RETVAL
521
522 Key_DataImpl *
523 lock(kd, key)
524         Key_DataImpl *kd
525         SV *key
526         PREINIT:
527         STRLEN len;
528         char *p;
529         CODE:
530         if ((kd->e & KF_ENCMASK) == KENC_ENCRYPT)
531           croak("already encrypted");
532         RETVAL = CREATE(Key_DataImpl);
533         p = SvPV(key, len);
534         key_lock(RETVAL, kd, p, len);
535         OUTPUT:
536         RETVAL
537
538 Key_DataImpl *
539 unlock(kd, key)
540         Key_DataImpl *kd
541         SV *key
542         PREINIT:
543         STRLEN len;
544         char *p;
545         int rc;
546         CODE:
547         if ((kd->e & KF_ENCMASK) != KENC_ENCRYPT)
548           croak("not encrypted");
549         RETVAL = CREATE(Key_DataImpl);
550         p = SvPV(key, len);
551         if ((rc = key_unlock(RETVAL, kd, p, len)) != 0) {
552           DESTROY(RETVAL);
553           keyerr(rc);
554           RETVAL = 0;
555         }
556         OUTPUT:
557         RETVAL
558
559 Key_DataImpl *
560 plock(kd, tag)
561         Key_DataImpl *kd
562         char *tag
563         PREINIT:
564         int rc;
565         CODE:
566         if ((kd->e & KF_ENCMASK) == KENC_ENCRYPT)
567           croak("already encrypted");
568         RETVAL = CREATE(Key_DataImpl);
569         if ((rc = key_plock(tag, kd, RETVAL)) != 0) {
570           DESTROY(RETVAL);
571           keyerr(rc);
572           RETVAL = 0;
573         }
574         OUTPUT:
575         RETVAL
576
577 Key_DataImpl *
578 punlock(kd, tag)
579         Key_DataImpl *kd
580         char *tag
581         PREINIT:
582         int rc;
583         CODE:
584         if ((kd->e & KF_ENCMASK) != KENC_ENCRYPT)
585           croak("not encrypted");
586         RETVAL = CREATE(Key_DataImpl);
587         if ((rc = key_punlock(tag, kd, RETVAL)) != 0) {
588           DESTROY(RETVAL);
589           keyerr(rc);
590           RETVAL = 0;
591         }
592         OUTPUT:
593         RETVAL
594
595 void
596 read(me, p)
597         SV *me
598         char *p
599         PREINIT:
600         key_data *kd;
601         char *pp;
602         PPCODE:
603         kd = CREATE(key_data);
604         if (key_read(p, kd, &pp))
605           DESTROY(kd);
606         else {
607           XPUSHs(RET(kd, "Catacomb::Key::DataImpl"));
608           if (GIMME_V == G_ARRAY)
609             XPUSHs(sv_2mortal(newSVpvn(pp, strlen(pp))));
610         }
611
612 SV *
613 write(kd, kf = 0)
614         Key_DataImpl *kd
615         Key_Filter *kf
616         PREINIT:
617         dstr d = DSTR_INIT;
618         CODE:
619         if (key_write(kd, &d, kf))
620           RETVAL = newSVpvn(d.buf, d.len);
621         else
622           RETVAL = &PL_sv_undef;
623         dstr_destroy(&d);
624         OUTPUT:
625         RETVAL
626
627 Key_DataImpl *
628 decode(me, sv)
629         SV *me
630         SV *sv
631         PREINIT:
632         char *p;
633         STRLEN len;
634         CODE:
635         p = SvPV(sv, len);
636         RETVAL = CREATE(key_data);
637         if (key_decode(p, len, RETVAL)) {
638           DESTROY(RETVAL);
639           RETVAL = 0;
640         }
641         OUTPUT:
642         RETVAL
643
644 SV *
645 encode(kd, kf = 0)
646         Key_DataImpl *kd
647         Key_Filter *kf
648         PREINIT:
649         dstr d = DSTR_INIT;
650         CODE:
651         if (key_encode(kd, &d, kf))
652           RETVAL = newSVpvn(d.buf, d.len);
653         else
654           RETVAL = &PL_sv_undef;
655         dstr_destroy(&d);
656         OUTPUT:
657         RETVAL
658
659 MODULE = Catacomb PACKAGE = Catacomb::Key::StructIter
660
661 SV *
662 next(i)
663         Key_StructIter *i
664         PREINIT:
665         key_struct *s;
666         CODE:
667         if ((s = sym_next(i)) == 0)
668           XSRETURN_UNDEF;
669         RETVAL = newSVpvn(SYM_NAME(s), SYM_LEN(s));
670         OUTPUT:
671         RETVAL
672
673 SV *
674 DESTROY(i)
675         Key_StructIter *i
676         CODE:
677         DESTROY(i);
678         XSRETURN_YES;
679
680 MODULE = Catacomb PACKAGE = Catacomb::Key::Data
681
682 void
683 readflags(me, p)
684         SV *me
685         char *p
686         PREINIT:
687         unsigned f, m;
688         PPCODE:
689         if (key_readflags(p, &p, &f, &m) || *p)
690           croak("bad flags string");
691         XPUSHs(sv_2mortal(newSVuv(m)));
692         XPUSHs(sv_2mortal(newSVuv(f)));
693
694 SV *
695 getflags(me, f)
696         SV *me
697         U32 f
698         PREINIT:
699         dstr d = DSTR_INIT;
700         CODE:
701         key_writeflags(f, &d);
702         RETVAL = newSVpvn(d.buf, d.len);
703         dstr_destroy(&d);
704         OUTPUT:
705         RETVAL
706
707 MODULE = Catacomb PACKAGE = Catacomb::Key::File PREFIX = key_
708
709 Key_File *
710 new(me, file, how = KOPEN_READ, report = &PL_sv_undef)
711         SV *me
712         char *file
713         unsigned how
714         SV *report
715         CODE:
716         RETVAL = CREATE(key_file);
717         if (key_open(&RETVAL->kf, file, how, keyreport, report)) {
718           DESTROY(RETVAL);
719           RETVAL = 0;
720         }
721         OUTPUT:
722         RETVAL
723
724 SV *
725 DESTROY(kf)
726         Key_File *kf
727         CODE:
728         keyfile_dec(kf);
729         XSRETURN_UNDEF;
730
731 KeyErr
732 merge(kf, name, fp, report = &PL_sv_undef)
733         Key_File *kf
734         char *name
735         FILE *fp
736         SV *report
737         CODE:
738         RETVAL = key_merge(&kf->kf, name, fp, keyreport, report);
739         OUTPUT:
740         RETVAL
741
742 bool
743 key_extract(kf, k, fp, kfilt = 0)
744         Key_File *kf
745         Key *k
746         FILE *fp
747         Key_Filter *kfilt
748         C_ARGS:
749         &kf->kf, k->k, fp, kfilt
750
751 int
752 key_save(kf)
753         Key_File *kf
754         C_ARGS:
755         &kf->kf
756
757 Key *
758 bytype(kf, type)
759         Key_File *kf
760         char *type
761         CODE:
762         RETVAL = CREATE(Key);
763         if ((RETVAL->k = key_bytype(&kf->kf, type)) != 0) {
764           kf->ref++;
765           RETVAL->kf = kf;
766         } else {
767           DESTROY(RETVAL);
768           RETVAL = 0;
769         }
770         OUTPUT:
771         RETVAL
772
773 Key *
774 byid(kf, id)
775         Key_File *kf
776         U32 id
777         CODE:
778         RETVAL = CREATE(Key);
779         if ((RETVAL->k = key_byid(&kf->kf, id)) != 0) {
780           kf->ref++;
781           RETVAL->kf = kf;
782         } else {
783           DESTROY(RETVAL);
784           RETVAL = 0;
785         }
786         OUTPUT:
787         RETVAL
788
789 Key *
790 bytag(kf, tag)
791         Key_File *kf
792         char *tag
793         CODE:
794         RETVAL = CREATE(Key);
795         if ((RETVAL->k = key_bytag(&kf->kf, tag)) != 0) {
796           kf->ref++;
797           RETVAL->kf = kf;
798         } else {
799           DESTROY(RETVAL);
800           RETVAL = 0;
801         }
802         OUTPUT:
803         RETVAL
804
805 Key *
806 newkey(kf, id, type, exp)
807         Key_File *kf
808         U32 id
809         const char *type
810         time_t exp
811         PREINIT:
812         int err;
813         CODE:
814         RETVAL = CREATE(Key);
815         if ((RETVAL->k = key_new(&kf->kf, id, type, exp, &err)) == 0) {
816           DESTROY(RETVAL);
817           keyerr(err);
818           RETVAL = 0;
819         } else {
820           kf->ref++;
821           RETVAL->kf = kf;
822         }
823         OUTPUT:
824         RETVAL
825         
826
827 Key_FileIter *
828 iterate(kf)
829         Key_File *kf
830         CODE:
831         RETVAL = CREATE(Key_FileIter);
832         key_mkiter(&RETVAL->i, &kf->kf);
833         RETVAL->kf = kf;
834         kf->ref++;
835         OUTPUT: 
836         RETVAL
837
838 MODULE = Catacomb PACKAGE = Catacomb::Key::FileIter
839
840 Key *
841 next(ki)
842         Key_FileIter *ki
843         CODE:
844         RETVAL = CREATE(Key);
845         if ((RETVAL->k = key_next(&ki->i)) == 0) {
846           DESTROY(RETVAL);
847           RETVAL = 0;
848         } else {
849           RETVAL->kf = ki->kf;
850           ki->kf->ref++;
851         }
852         OUTPUT:
853         RETVAL
854
855 SV *
856 DESTROY(ki)
857         Key_FileIter *ki
858         CODE:
859         keyfile_dec(ki->kf);
860         DESTROY(ki);
861         XSRETURN_YES;
862
863 #----- That's all, folks ----------------------------------------------------