File Coverage

DSA.xs
Criterion Covered Total %
statement 210 284 73.9
branch 103 194 53.0
condition n/a
subroutine n/a
pod n/a
total 313 478 65.4


line stmt bran cond sub pod time code
1             /* $Id: */
2              
3              
4             #ifdef __cplusplus
5             extern "C" {
6             #endif
7             #include "EXTERN.h"
8             #include "perl.h"
9             #include "XSUB.h"
10              
11             #include
12             #include
13             #include
14             #include
15             #include
16             #include
17              
18             #ifdef __cplusplus
19             }
20             #endif
21              
22             #if OPENSSL_VERSION_NUMBER < 0x10100000L
23 15           static void DSA_get0_pqg(const DSA *d,
24             const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
25             {
26 15 100         if (p != NULL)
27 7           *p = d->p;
28 15 100         if (q != NULL)
29 7           *q = d->q;
30 15 100         if (g != NULL)
31 7           *g = d->g;
32 15           }
33              
34 6           static int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g)
35             {
36             /* If the fields p, q and g in d are NULL, the corresponding input
37             * parameters MUST be non-NULL.
38             */
39 6 100         if ((d->p == NULL && p == NULL)
    50          
40 6 100         || (d->q == NULL && q == NULL)
    50          
41 6 100         || (d->g == NULL && g == NULL))
    50          
42 0           return 0;
43              
44 6 50         if (p != NULL) {
45 6           BN_free(d->p);
46 6           d->p = p;
47             }
48 6 50         if (q != NULL) {
49 6           BN_free(d->q);
50 6           d->q = q;
51             }
52 6 50         if (g != NULL) {
53 6           BN_free(d->g);
54 6           d->g = g;
55             }
56              
57 6           return 1;
58             }
59              
60 8           static void DSA_get0_key(const DSA *d,
61             const BIGNUM **pub_key, const BIGNUM **priv_key)
62             {
63 8 100         if (pub_key != NULL)
64 5           *pub_key = d->pub_key;
65 8 100         if (priv_key != NULL)
66 3           *priv_key = d->priv_key;
67 8           }
68              
69 5           static int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key)
70             {
71             /* If the field pub_key in d is NULL, the corresponding input
72             * parameters MUST be non-NULL. The priv_key field may
73             * be left NULL.
74             */
75 5 100         if (d->pub_key == NULL && pub_key == NULL)
    50          
76 0           return 0;
77              
78 5 100         if (pub_key != NULL) {
79 3           BN_free(d->pub_key);
80 3           d->pub_key = pub_key;
81             }
82 5 100         if (priv_key != NULL) {
83 2           BN_free(d->priv_key);
84 2           d->priv_key = priv_key;
85             }
86              
87 5           return 1;
88             }
89              
90 6           static void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr,
91             const BIGNUM **ps)
92             {
93 6 100         if (pr != NULL)
94 3           *pr = sig->r;
95 6 100         if (ps != NULL)
96 3           *ps = sig->s;
97 6           }
98              
99 4           static int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s)
100             {
101 4 50         if (r == NULL || s == NULL)
    50          
102 0           return 0;
103 4           BN_clear_free(sig->r);
104 4           BN_clear_free(sig->s);
105 4           sig->r = r;
106 4           sig->s = s;
107 4           return 1;
108             }
109             #endif
110              
111             MODULE = Crypt::OpenSSL::DSA PACKAGE = Crypt::OpenSSL::DSA
112              
113             PROTOTYPES: DISABLE
114              
115             BOOT:
116             #if OPENSSL_VERSION_NUMBER < 0x10100000L
117 3           ERR_load_crypto_strings();
118             #endif
119              
120             DSA *
121             new(CLASS)
122             char * CLASS
123             CODE:
124 2           RETVAL = DSA_new();
125             OUTPUT:
126             RETVAL
127              
128             void
129             DESTROY(dsa)
130             DSA *dsa
131             CODE:
132 11           DSA_free(dsa);
133              
134             DSA *
135             generate_parameters(CLASS, bits, seed = NULL)
136             char * CLASS
137             int bits
138             SV * seed
139             PREINIT:
140             DSA * dsa;
141 3           STRLEN seed_len = 0;
142 3           char * seedpv = NULL;
143             unsigned long err;
144             CODE:
145 3 100         if (seed) {
146 2 50         seedpv = SvPV(seed, seed_len);
147             }
148             #if OPENSSL_VERSION_NUMBER < 0x10100000L
149 3           dsa = DSA_generate_parameters(bits, seedpv, (int)seed_len, NULL, NULL, NULL, NULL);
150 3 50         if (!dsa) {
151             #else
152             dsa = DSA_new();
153             if (!DSA_generate_parameters_ex(dsa, bits, seedpv, (int)seed_len, NULL, NULL, NULL)) {
154             #endif
155 0           err = ERR_get_error();
156 0 0         if (err == 0) {
157 0           croak("DSA_generate_parameters() returned NULL");
158             }
159             else {
160 0           croak("%s", ERR_reason_error_string(err));
161             }
162             }
163 3           RETVAL = dsa;
164             OUTPUT:
165             RETVAL
166              
167             int
168             generate_key(dsa)
169             DSA * dsa
170             CODE:
171 3           RETVAL = DSA_generate_key(dsa);
172             OUTPUT:
173             RETVAL
174              
175             int
176             get_sig_size(dsa)
177             DSA * dsa
178             CODE:
179 0           RETVAL = DSA_size(dsa);
180             OUTPUT:
181             RETVAL
182              
183             DSA_SIG *
184             do_sign(dsa, dgst)
185             DSA * dsa
186             SV * dgst
187             PREINIT:
188             DSA_SIG * sig;
189 1           char * CLASS = "Crypt::OpenSSL::DSA::Signature";
190 1           char * dgst_pv = NULL;
191 1           STRLEN dgst_len = 0;
192             CODE:
193 1 50         dgst_pv = SvPV(dgst, dgst_len);
194 1 50         if (!(sig = DSA_do_sign((const unsigned char *) dgst_pv, (int)dgst_len, dsa))) {
195 0           croak("Error in dsa_sign: %s",ERR_error_string(ERR_get_error(), NULL));
196             }
197 1           RETVAL = sig;
198             OUTPUT:
199             RETVAL
200              
201             SV *
202             sign(dsa, dgst)
203             DSA * dsa
204             SV * dgst
205             PREINIT:
206             unsigned char *sigret;
207             unsigned int siglen;
208 44           char * dgst_pv = NULL;
209 44           STRLEN dgst_len = 0;
210             CODE:
211 44           siglen = DSA_size(dsa);
212 44           sigret = malloc(siglen);
213              
214 44 50         dgst_pv = SvPV(dgst, dgst_len);
215             /* warn("Length of sign [%s] is %d\n", dgst_pv, dgst_len); */
216              
217 44 50         if (!(DSA_sign(0, (const unsigned char *) dgst_pv, (int)dgst_len, sigret, &siglen, dsa))) {
218 0           croak("Error in DSA_sign: %s",ERR_error_string(ERR_get_error(), NULL));
219             }
220 44           RETVAL = newSVpvn(sigret, siglen);
221 44           free(sigret);
222             OUTPUT:
223             RETVAL
224              
225             int
226             verify(dsa, dgst, sigbuf)
227             DSA * dsa
228             SV *dgst
229             SV *sigbuf
230             PREINIT:
231 60           char * dgst_pv = NULL;
232 60           STRLEN dgst_len = 0;
233 60           char * sig_pv = NULL;
234 60           STRLEN sig_len = 0;
235             CODE:
236 60 50         dgst_pv = SvPV(dgst, dgst_len);
237 60 50         sig_pv = SvPV(sigbuf, sig_len);
238 60           RETVAL = DSA_verify(0, dgst_pv, (int)dgst_len, sig_pv, (int)sig_len, dsa);
239 60 50         if (RETVAL == -1)
240 0           croak("Error in DSA_verify: %s",ERR_error_string(ERR_get_error(), NULL));
241             OUTPUT:
242             RETVAL
243              
244             int
245             do_verify(dsa, dgst, sig)
246             DSA *dsa
247             SV *dgst
248             DSA_SIG *sig
249             PREINIT:
250 3           char * dgst_pv = NULL;
251 3           STRLEN dgst_len = 0;
252             CODE:
253 3 50         dgst_pv = SvPV(dgst, dgst_len);
254 3           RETVAL = DSA_do_verify(dgst_pv, (int)dgst_len, sig, dsa);
255 3 50         if (RETVAL == -1)
256 0           croak("Error in DSA_do_verify: %s",ERR_error_string(ERR_get_error(), NULL));
257             OUTPUT:
258             RETVAL
259              
260             DSA *
261             read_params(CLASS, filename)
262             char *CLASS
263             char *filename
264             PREINIT:
265             FILE *f;
266             CODE:
267 0 0         if(!(f = fopen(filename, "r")))
268 0           croak("Can't open file %s", filename);
269 0           RETVAL = PEM_read_DSAparams(f, NULL, NULL, NULL);
270 0           fclose(f);
271             OUTPUT:
272             RETVAL
273              
274             int
275             write_params(dsa, filename)
276             DSA * dsa
277             char *filename
278             PREINIT:
279             FILE *f;
280             CODE:
281 1 50         if(!(f = fopen(filename, "w")))
282 0           croak("Can't open file %s", filename);
283 1           RETVAL = PEM_write_DSAparams(f, dsa);
284 1           fclose(f);
285             OUTPUT:
286             RETVAL
287              
288             DSA *
289             _load_key(CLASS, private_flag_SV, key_string_SV)
290             char *CLASS;
291             SV * private_flag_SV;
292             SV * key_string_SV;
293             PREINIT:
294             STRLEN key_string_length; /* Needed to pass to SvPV */
295             char *key_string;
296             char private_flag;
297             BIO *stringBIO;
298             CODE:
299 2 50         private_flag = SvTRUE( private_flag_SV );
    50          
    0          
    50          
    0          
    0          
    50          
    0          
    0          
    0          
    0          
    0          
    50          
    50          
    100          
    50          
    0          
    100          
    0          
300 2 50         key_string = SvPV( key_string_SV, key_string_length );
301 2 50         if( (stringBIO = BIO_new_mem_buf(key_string, (int)key_string_length)) == NULL )
302 0           croak( "Failed to create memory BIO %s", ERR_error_string(ERR_get_error(), NULL));
303 2           RETVAL = private_flag
304             ? PEM_read_bio_DSAPrivateKey( stringBIO, NULL, NULL, NULL )
305 2 100         : PEM_read_bio_DSA_PUBKEY( stringBIO, NULL, NULL, NULL );
306 2           BIO_set_close(stringBIO, BIO_CLOSE);
307 2           BIO_free( stringBIO );
308 2 50         if ( RETVAL == NULL )
309 0           croak( "Failed to read key %s", ERR_error_string(ERR_get_error(), NULL));
310             OUTPUT:
311             RETVAL
312              
313             DSA *
314             read_pub_key(CLASS, filename)
315             char *CLASS
316             char *filename
317             PREINIT:
318             FILE *f;
319             CODE:
320 2 50         if(!(f = fopen(filename, "r")))
321 0           croak("Can't open file %s", filename);
322 2           RETVAL = PEM_read_DSA_PUBKEY(f, NULL, NULL, NULL);
323 2           fclose(f);
324             OUTPUT:
325             RETVAL
326              
327             int
328             write_pub_key(dsa, filename)
329             DSA * dsa
330             char *filename
331             PREINIT:
332             FILE *f;
333             CODE:
334 2 50         if(!(f = fopen(filename, "w")))
335 0           croak("Can't open file %s", filename);
336 2           RETVAL = PEM_write_DSA_PUBKEY(f, dsa);
337 2           fclose(f);
338             OUTPUT:
339             RETVAL
340              
341             DSA *
342             read_priv_key(CLASS, filename)
343             char *CLASS
344             char *filename
345             PREINIT:
346             FILE *f;
347             CODE:
348 2 50         if(!(f = fopen(filename, "r")))
349 0           croak("Can't open file %s", filename);
350 2           RETVAL = PEM_read_DSAPrivateKey(f, NULL, NULL, NULL);
351 2           fclose(f);
352             OUTPUT:
353             RETVAL
354              
355             int
356             write_priv_key(dsa, filename)
357             DSA * dsa
358             char *filename
359             PREINIT:
360             FILE *f;
361             CODE:
362 2 50         if(!(f = fopen(filename, "w")))
363 0           croak("Can't open file %s", filename);
364 2           RETVAL = PEM_write_DSAPrivateKey(f, dsa, NULL, NULL, 0, NULL, NULL);
365 2           fclose(f);
366             OUTPUT:
367             RETVAL
368              
369             SV *
370             get_p(dsa)
371             DSA *dsa
372             PREINIT:
373             const BIGNUM *p;
374             char *to;
375             int len;
376             int bnlen;
377             CODE:
378 3           DSA_get0_pqg(dsa, &p, NULL, NULL);
379 3           bnlen = BN_num_bytes(p);
380 3           to = malloc(sizeof(char) * bnlen);
381 3           len = BN_bn2bin(p, to);
382 3           RETVAL = newSVpvn(to, len);
383 3           free(to);
384             OUTPUT:
385             RETVAL
386              
387             SV *
388             get_q(dsa)
389             DSA *dsa
390             PREINIT:
391             const BIGNUM *q;
392             char *to;
393             int len;
394             int bnlen;
395             CODE:
396 3           DSA_get0_pqg(dsa, NULL, &q, NULL);
397 3           bnlen = BN_num_bytes(q);
398 3           to = malloc(sizeof(char) * bnlen);
399 3           len = BN_bn2bin(q, to);
400 3           RETVAL = newSVpvn(to, len);
401 3           free(to);
402             OUTPUT:
403             RETVAL
404              
405             SV *
406             get_g(dsa)
407             DSA *dsa
408             PREINIT:
409             const BIGNUM *g;
410             char *to;
411             int len;
412             int bnlen;
413             CODE:
414 3           DSA_get0_pqg(dsa, NULL, NULL, &g);
415 3           bnlen = BN_num_bytes(g);
416 3           to = malloc(sizeof(char) * bnlen);
417 3           len = BN_bn2bin(g, to);
418 3           RETVAL = newSVpvn(to, len);
419 3           free(to);
420             OUTPUT:
421             RETVAL
422              
423             SV *
424             get_pub_key(dsa)
425             DSA *dsa
426             PREINIT:
427             const BIGNUM *pub_key;
428             char *to;
429             int len;
430             int bnlen;
431             CODE:
432 3           DSA_get0_key(dsa, &pub_key, NULL);
433 3           bnlen = BN_num_bytes(pub_key);
434 3           to = malloc(sizeof(char) * bnlen);
435 3           len = BN_bn2bin(pub_key, to);
436 3           RETVAL = newSVpvn(to, len);
437 3           free(to);
438             OUTPUT:
439             RETVAL
440              
441             SV *
442             get_priv_key(dsa)
443             DSA *dsa
444             PREINIT:
445             const BIGNUM *priv_key;
446             char *to;
447             int len;
448             int bnlen;
449             CODE:
450 3           DSA_get0_key(dsa, NULL, &priv_key);
451 3           bnlen = BN_num_bytes(priv_key);
452 3           to = malloc(sizeof(char) * bnlen);
453 3           len = BN_bn2bin(priv_key, to);
454 3           RETVAL = newSVpvn(to, len);
455 3           free(to);
456             OUTPUT:
457             RETVAL
458              
459             void
460             set_p(dsa, p_SV)
461             DSA *dsa
462             SV * p_SV
463             PREINIT:
464             STRLEN len;
465             BIGNUM *p;
466             BIGNUM *q;
467             BIGNUM *g;
468             const BIGNUM *old_q;
469             const BIGNUM *old_g;
470             CODE:
471 2           len = SvCUR(p_SV);
472 2 50         p = BN_bin2bn(SvPV(p_SV, len), (int)len, NULL);
473 2           DSA_get0_pqg(dsa, NULL, &old_q, &old_g);
474 2 50         if (NULL == old_q) {
475 2           q = BN_new();
476             } else {
477 0           q = BN_dup(old_q);
478             }
479 2 50         if (NULL == q) {
480 0           BN_free(p);
481 0           croak("Could not duplicate another prime");
482             }
483 2 50         if (NULL == old_g) {
484 2           g = BN_new();
485             } else {
486 0           g = BN_dup(old_g);
487             }
488 2 50         if (NULL == g) {
489 0           BN_free(p);
490 0           BN_free(q);
491 0           croak("Could not duplicate another prime");
492             }
493 2 50         if (!DSA_set0_pqg(dsa, p, q, g)) {
494 0           BN_free(p);
495 0           BN_free(q);
496 0           BN_free(g);
497 0           croak("Could not set a prime");
498             }
499              
500             void
501             set_q(dsa, q_SV)
502             DSA *dsa
503             SV * q_SV
504             PREINIT:
505             STRLEN len;
506             BIGNUM *p;
507             BIGNUM *q;
508             BIGNUM *g;
509             const BIGNUM *old_p;
510             const BIGNUM *old_g;
511             CODE:
512 2           len = SvCUR(q_SV);
513 2 50         q = BN_bin2bn(SvPV(q_SV, len), (int)len, NULL);
514 2           DSA_get0_pqg(dsa, &old_p, NULL, &old_g);
515 2 50         if (NULL == old_p) {
516 0           p = BN_new();
517             } else {
518 2           p = BN_dup(old_p);
519             }
520 2 50         if (NULL == p) {
521 0           BN_free(q);
522 0           croak("Could not duplicate another prime");
523             }
524 2 50         if (NULL == old_g) {
525 0           g = BN_new();
526             } else {
527 2           g = BN_dup(old_g);
528             }
529 2 50         if (NULL == g) {
530 0           BN_free(p);
531 0           BN_free(q);
532 0           croak("Could not duplicate another prime");
533             }
534 2 50         if (!DSA_set0_pqg(dsa, p, q, g)) {
535 0           BN_free(p);
536 0           BN_free(q);
537 0           BN_free(g);
538 0           croak("Could not set a prime");
539             }
540              
541             void
542             set_g(dsa, g_SV)
543             DSA *dsa
544             SV * g_SV
545             PREINIT:
546             STRLEN len;
547             BIGNUM *p;
548             BIGNUM *q;
549             BIGNUM *g;
550             const BIGNUM *old_p;
551             const BIGNUM *old_q;
552             CODE:
553 2           len = SvCUR(g_SV);
554 2 50         g = BN_bin2bn(SvPV(g_SV, len), (int)len, NULL);
555 2           DSA_get0_pqg(dsa, &old_p, &old_q, NULL);
556 2 50         if (NULL == old_p) {
557 0           p = BN_new();
558             } else {
559 2           p = BN_dup(old_p);
560             }
561 2 50         if (NULL == p) {
562 0           BN_free(g);
563 0           croak("Could not duplicate another prime");
564             }
565 2 50         if (NULL == old_q) {
566 0           q = BN_new();
567             } else {
568 2           q = BN_dup(old_q);
569             }
570 2 50         if (NULL == q) {
571 0           BN_free(p);
572 0           BN_free(g);
573 0           croak("Could not duplicate another prime");
574             }
575 2 50         if (!DSA_set0_pqg(dsa, p, q, g)) {
576 0           BN_free(p);
577 0           BN_free(q);
578 0           BN_free(g);
579 0           croak("Could not set a prime");
580             }
581              
582             void
583             set_pub_key(dsa, pub_key_SV)
584             DSA *dsa
585             SV * pub_key_SV
586             PREINIT:
587             STRLEN len;
588             BIGNUM *pub_key;
589             CODE:
590 2           len = SvCUR(pub_key_SV);
591 2 50         pub_key = BN_bin2bn(SvPV(pub_key_SV, len), (int)len, NULL);
592 2 50         if (!DSA_set0_key(dsa, pub_key, NULL)) {
593 0           BN_free(pub_key);
594 0           croak("Could not set a key");
595             }
596              
597             void
598             set_priv_key(dsa, priv_key_SV)
599             DSA *dsa
600             SV * priv_key_SV
601             PREINIT:
602             STRLEN len;
603             const BIGNUM *old_pub_key;
604             BIGNUM *pub_key;
605             BIGNUM *priv_key;
606             CODE:
607 2           DSA_get0_key(dsa, &old_pub_key, NULL);
608 2 100         if (NULL == old_pub_key) {
609 1           pub_key = BN_new();
610 1 50         if (NULL == pub_key) {
611 0           croak("Could not create a dummy public key");
612             }
613 1 50         if (!DSA_set0_key(dsa, pub_key, NULL)) {
614 0           BN_free(pub_key);
615 0           croak("Could not set a dummy public key");
616             }
617             }
618 2           len = SvCUR(priv_key_SV);
619 2 50         priv_key = BN_bin2bn(SvPV(priv_key_SV, len), (int)len, NULL);
620 2 50         if (!DSA_set0_key(dsa, NULL, priv_key)) {
621 0           BN_free(priv_key);
622 0           croak("Could not set a key");
623             }
624              
625             MODULE = Crypt::OpenSSL::DSA PACKAGE = Crypt::OpenSSL::DSA::Signature
626              
627             DSA_SIG *
628             new(CLASS)
629             char * CLASS
630             CODE:
631 2           RETVAL = DSA_SIG_new();
632             OUTPUT:
633             RETVAL
634              
635             void
636             DESTROY(dsa_sig)
637             DSA_SIG *dsa_sig
638             CODE:
639 3           DSA_SIG_free(dsa_sig);
640              
641             SV *
642             get_r(dsa_sig)
643             DSA_SIG *dsa_sig
644             PREINIT:
645             const BIGNUM *r;
646             char *to;
647             int len;
648             int bnlen;
649             CODE:
650 1           DSA_SIG_get0(dsa_sig, &r, NULL);
651 1           bnlen = BN_num_bytes(r);
652 1           to = malloc(sizeof(char) * bnlen);
653 1           len = BN_bn2bin(r, to);
654 1           RETVAL = newSVpvn(to, len);
655 1           free(to);
656             OUTPUT:
657             RETVAL
658              
659             SV *
660             get_s(dsa_sig)
661             DSA_SIG *dsa_sig
662             PREINIT:
663             const BIGNUM *s;
664             char *to;
665             int len;
666             int bnlen;
667             CODE:
668 1           DSA_SIG_get0(dsa_sig, NULL, &s);
669 1           bnlen = BN_num_bytes(s);
670 1           to = malloc(sizeof(char) * bnlen);
671 1           len = BN_bn2bin(s, to);
672 1           RETVAL = newSVpvn(to, len);
673 1           free(to);
674             OUTPUT:
675             RETVAL
676              
677             void
678             set_r(dsa_sig, r_SV)
679             DSA_SIG *dsa_sig
680             SV * r_SV
681             PREINIT:
682             STRLEN len;
683             BIGNUM *r;
684             BIGNUM *s;
685             const BIGNUM *old_s;
686             CODE:
687 2           len = SvCUR(r_SV);
688 2 50         r = BN_bin2bn(SvPV(r_SV, len), (int)len, NULL);
689 2           DSA_SIG_get0(dsa_sig, NULL, &old_s);
690 2 50         if (NULL == old_s) {
691 2           s = BN_new();
692             } else {
693 0           s = BN_dup(old_s);
694             }
695 2 50         if (NULL == s) {
696 0           BN_free(r);
697 0           croak("Could not duplicate another signature value");
698             }
699 2 50         if (!DSA_SIG_set0(dsa_sig, r, s)) {
700 0           BN_free(r);
701 0           BN_free(s);
702 0           croak("Could not set a signature");
703             }
704              
705             void
706             set_s(dsa_sig, s_SV)
707             DSA_SIG *dsa_sig
708             SV * s_SV
709             PREINIT:
710             STRLEN len;
711             BIGNUM *s;
712             BIGNUM *r;
713             const BIGNUM *old_r;
714             CODE:
715 2           len = SvCUR(s_SV);
716 2 50         s = BN_bin2bn(SvPV(s_SV, len), (int)len, NULL);
717 2           DSA_SIG_get0(dsa_sig, &old_r, NULL);
718 2 50         if (NULL == old_r) {
719 0           r = BN_new();
720             } else {
721 2           r = BN_dup(old_r);
722             }
723 2 50         if (NULL == r) {
724 0           BN_free(s);
725 0           croak("Could not duplicate another signature value");
726             }
727 2 50         if (!DSA_SIG_set0(dsa_sig, r, s)) {
728 0           BN_free(s);
729 0           croak("Could not set a signature");
730             }