ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/OpenSSL/OpenSSL.xs
Revision: 1.15
Committed: Sun Oct 28 03:24:25 2001 UTC (22 years, 6 months ago) by root
Branch: MAIN
Changes since 1.14: +8 -5 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 stefan 1.1 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5     #include <openssl/bio.h>
6     #include <openssl/err.h>
7     #include <openssl/pem.h>
8     #include <openssl/evp.h>
9     #include <openssl/hmac.h>
10     #include <openssl/x509.h>
11     #include <openssl/x509v3.h>
12     #include <openssl/asn1.h>
13     #include <openssl/bn.h>
14     #include <openssl/pkcs12.h>
15     #include <openssl/rand.h>
16     #include <sys/types.h>
17     #include <openssl/md2.h>
18     #include <openssl/md4.h>
19     #include <openssl/md5.h>
20     #include <openssl/mdc2.h>
21     #include <openssl/ripemd.h>
22     #include <openssl/bn.h>
23     #include <openssl/rsa.h>
24     #include <openssl/sha.h> // fingerprint.
25     #include <openssl/blowfish.h> // single packet blowfish encoding.
26     #include <openssl/rand.h> // random generator.
27    
28     //#define EDEBUG 1
29     #ifdef EDEBUG
30     #define XD(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
31     #else
32     #define XD(...)
33     #endif
34    
35     static const char *ssl_error(void);
36    
37 root 1.8 typedef X509 *OpenSSL__X509;
38     typedef X509_CRL *OpenSSL__CRL;
39     typedef X509_NAME *OpenSSL__Name;
40     typedef PKCS7 *OpenSSL__PKCS7;
41     typedef PKCS12 *OpenSSL__PKCS12;
42     typedef RSA *OpenSSL__RSA;
43     typedef EVP_MD_CTX *OpenSSL__Digest;
44     typedef EVP_CIPHER_CTX *OpenSSL__Cipher;
45 stefan 1.1
46     static inline SV* output_ASN1_INTEGER(ASN1_INTEGER *ai, SV *sv)
47     {
48     if(!ai)
49     croak("got 0-ptr");
50     if(ai->type != V_ASN1_INTEGER)
51     croak("not asn1 integer type (%d)", ai->type);
52     //return newSViv(ASN1_INTEGER_get(ai));
53     sv_setiv(sv, ASN1_INTEGER_get(ai));
54     return sv;
55     }
56    
57     static inline SV* output_ASN1_UTCTIME(ASN1_UTCTIME *s, SV *sv)
58     {
59     struct tm tm;
60     int offs;
61     char buf[64];
62    
63     if(!s)
64     croak("got 0-ptr");
65     if(s->type != V_ASN1_UTCTIME)
66     croak("not asn1 utctime type (%d)", s->type);
67     if(!ASN1_UTCTIME_check(s))
68     croak("invalid UTC time.");
69     // fuck openssl crap.
70     memset(&tm, 0, sizeof tm);
71     #define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
72     tm.tm_year=g2(s->data);
73     if(tm.tm_year < 50)
74     tm.tm_year+=100;
75     tm.tm_mon=g2(s->data+2)-1;
76     tm.tm_mday=g2(s->data+4);
77     tm.tm_hour=g2(s->data+6);
78     tm.tm_min=g2(s->data+8);
79     tm.tm_sec=g2(s->data+10);
80     if(s->data[12] == 'Z')
81     offs=0;
82     else
83     {
84     offs=g2(s->data+13)*60+g2(s->data+15);
85     if(s->data[12] == '-')
86     offs= -offs;
87     }
88     #undef g2
89     if(!strftime(buf, 63, "%a, %d %b %Y %H:%M:%S %z", &tm)) {
90     croak("can't convert time.");
91     }
92     sv_setpv(sv, buf);
93     return sv;
94     }
95    
96 stefan 1.12 long bio_write_cb(struct bio_st *bm, int m, const char *ptr, int l, long x, long y)
97 stefan 1.1 {
98     if(m == BIO_CB_WRITE) {
99     SV *sv = (SV *) BIO_get_callback_arg(bm);
100     sv_catpvn(sv, ptr, l);
101     }
102     if(m == BIO_CB_PUTS) {
103     SV *sv = (SV *) BIO_get_callback_arg(bm);
104     l = strlen(ptr);
105     sv_catpvn(sv, ptr, l);
106     }
107     return l;
108     }
109    
110     static inline BIO* sv_bio_create(void)
111     {
112     SV *sv;
113     BIO *bio;
114     sv = newSVpvn("",0);
115     // mem is completely broken for write, so we use /dev/null
116     // and use callbacks-hooks
117     bio = BIO_new_file("/dev/null", "wb");
118 stefan 1.12 BIO_set_callback(bio, bio_write_cb);
119 stefan 1.1 BIO_set_callback_arg(bio, (void *)sv);
120     return bio;
121     }
122    
123     static inline BIO *sv_bio_create_file(SV *filename)
124     {
125     STRLEN l;
126    
127     return BIO_new_file(SvPV(filename, l), "wb");
128     }
129    
130     static inline SV * sv_bio_final(BIO *bio)
131     {
132     SV* sv;
133    
134     BIO_flush(bio);
135     sv = (SV *) BIO_get_callback_arg(bio);
136     BIO_free_all (bio);
137     // check for file:
138     if(!sv)
139     sv = &PL_sv_undef;
140     return sv;
141     }
142    
143     static inline void sv_bio_error(BIO *bio)
144     {
145     SV *sv;
146     sv = (SV *) BIO_get_callback_arg(bio);
147     if(sv)
148     sv_free(sv);
149     BIO_free_all (bio);
150     }
151    
152     static const char *ssl_error(void) // function leaks. :(
153     {
154     BIO *bio;
155     SV *sv;
156     STRLEN l;
157    
158     bio = sv_bio_create();
159     ERR_print_errors(bio);
160     sv = sv_bio_final(bio);
161     ERR_clear_error();
162     return SvPV(sv, l);
163     }
164    
165     static inline SV* output_BN(BIGNUM *n, SV *sv)
166     {
167     if (!n)
168     croak("parse error :)");
169    
170     sv_setpvn(sv, BN_bn2dec(n), 0);
171     return sv;
172     }
173    
174     static const char * digcvt(char *ret, const char *from, int len)
175     {
176     static const char *htab = "0123456789abcdef";
177     char *to = ret;
178     int i;
179     for(i = 0; i < len; i++) {
180     *to++ = htab[(*from >> 4) & 0xf];
181     *to++ = htab[*from++ & 0xf];
182     }
183     *to = 0;
184     return ret;
185     }
186    
187     /* mutt, anything else is broken ! */
188     static const char B64Chars[64] = {
189     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
190     'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
191     'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
192     't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
193     '8', '9', '+', '/'
194     };
195    
196     static unsigned char *mutt_to_base64 (unsigned char *out, const unsigned char *in, size_t len,
197     size_t olen)
198     {
199     char *o = out;
200     while (len >= 3 && olen > 10)
201     {
202     *out++ = B64Chars[in[0] >> 2];
203     *out++ = B64Chars[((in[0] << 4) & 0x30) | (in[1] >> 4)];
204     *out++ = B64Chars[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
205     *out++ = B64Chars[in[2] & 0x3f];
206     olen -= 4;
207     len -= 3;
208     in += 3;
209     }
210    
211     /* clean up remainder */
212     if (len > 0 && olen > 4)
213     {
214     unsigned char fragment;
215    
216     *out++ = B64Chars[in[0] >> 2];
217     fragment = (in[0] << 4) & 0x30;
218     if (len > 1)
219     fragment |= in[1] >> 4;
220     *out++ = B64Chars[fragment];
221     *out++ = (len < 2) ? '=' : B64Chars[(in[1] << 2) & 0x3c];
222     *out++ = '=';
223     }
224     *out = '\0';
225     return o;
226     }
227    
228     static inline SV* hexsv(unsigned char *s, unsigned len)
229     {
230     char *ret;
231     SV *sv;
232     ret = malloc((len<<1)+1);
233     if(!ret)
234     croak("malloc");
235     sv = newSVpv(digcvt(ret, s,len), len <<1);
236     free(ret);
237     return sv;
238     }
239    
240     static inline SV* base64sv(unsigned char *s, unsigned len)
241     {
242     char *ret;
243     SV *sv;
244     int enc_cnt = ((len+ 2) / 3) << 2;
245     ret = malloc(enc_cnt+1);
246     if(!ret)
247     croak("malloc");
248     sv = newSVpv(mutt_to_base64(ret, s,len, enc_cnt+1), enc_cnt);
249     free(ret);
250     return sv;
251    
252     }
253    
254     #define FLAG_HEX 0x10
255     #define FLAG_BASE64 0x20
256     #define NO_FLAGS(x) ((x) &0xf)
257    
258     static EVP_MD *_mds[9];
259    
260     static int mds_booted = 0;
261    
262     static void mds_boot (void)
263     {
264     if(mds_booted)
265     return;
266     mds_booted = 1;
267     OpenSSL_add_all_digests();
268     _mds[0] = EVP_md2();
269     _mds[1] = EVP_md4();
270     _mds[2] = EVP_md5();
271     _mds[3] = EVP_sha();
272     _mds[4] = EVP_sha1();
273     _mds[5] = EVP_dss();
274     _mds[6] = EVP_dss1();
275     _mds[7] = EVP_mdc2();
276     _mds[8] = EVP_ripemd160();
277     }
278    
279    
280    
281     static char *
282     dofp(X509 *x509, EVP_MD *digest)
283     {
284     unsigned char md[EVP_MAX_MD_SIZE];
285     unsigned static char s[EVP_MAX_MD_SIZE*3];
286     int n, i;
287    
288     if(!X509_digest(x509, digest, md, &n))
289     croak("Digest error: %s", ssl_error());
290     for(i = 0; i < n; i++) {
291     sprintf(&s[i*3], "%02X%c", md[i], (i + 1 == (int) n) ? '\0' : ':');
292     }
293     return s;
294     }
295    
296 stefan 1.12 static inline SV *ol(X509_NAME *x)
297 stefan 1.1 {
298 stefan 1.12 char *p;
299     SV *sv = newSVpvn("",0);
300     X509_NAME_oneline(x, (p=SvGROW(sv,8192)), 8192);
301     SvCUR_set(sv, strlen(p));
302     return sv;
303 stefan 1.1 }
304    
305 stefan 1.12 #if 0
306 stefan 1.1 static void run_sha1(char *digest, const char *msg, int msglen)
307     {
308     SHA_CTX ctx;
309    
310     if(!digest || !msg || msglen < 0)
311     croak("run_sha1: null pointer or illegal message len");
312     SHA1_Init(&ctx);
313     SHA1_Update(&ctx, msg, msglen);
314     SHA1_Final(digest, &ctx);
315     }
316 stefan 1.12 #endif
317 stefan 1.1 static bool is_privkey(RSA *key)
318     {
319     return (key->n && key->e && key->d && key->p && key->q
320     && key->dmp1 && key->dmq1 && key->iqmp && key->d) ? 1 : 0;
321     }
322    
323     typedef struct {
324     EVP_CIPHER *func;
325     char name[20];
326     } cip_list_st;
327    
328     static cip_list_st cip_list[50];
329     static int cip_cnt = 0;
330    
331     static inline char *wappla_fixname(const char *s)
332     {
333     static char x[50];
334     char *p;
335     strcpy(x, s);
336     while((p = strchr(x, '_'))) {
337     *p = '-';
338     }
339     return x;
340     }
341    
342     static inline EVP_CIPHER *lookup_cipher(const char *name)
343     {
344     int i;
345     for(i = 0; i < cip_cnt;i++)
346     if(!strcmp(name, cip_list[i].name))
347     return cip_list[i].func;
348     return 0;
349     }
350    
351     #define ADD_C_(x) cip_list[cip_cnt].func = (EVP_##x()); \
352     strcpy(cip_list[cip_cnt++].name, wappla_fixname(#x))
353    
354     static int cipher_booted = 0;
355    
356     static void cipher_boot(void)
357     {
358     if(cipher_booted)
359     return;
360     cipher_booted++;
361     OpenSSL_add_all_ciphers();
362     #ifndef NO_DES
363     ADD_C_(des_ecb); ADD_C_(des_ede); ADD_C_(des_ede3);
364     ADD_C_(des_cfb); ADD_C_(des_ede_cfb); ADD_C_(des_ede3_cfb);
365     ADD_C_(des_ofb); ADD_C_(des_ede_ofb); ADD_C_(des_ede3_ofb);
366     ADD_C_(des_cbc); ADD_C_(des_ede_cbc); ADD_C_(des_ede3_cbc);
367     ADD_C_(desx_cbc);
368     #endif
369     #ifndef NO_RC4
370     ADD_C_(rc4); ADD_C_(rc4_40);
371     #endif
372     #ifndef NO_IDEA
373     ADD_C_(idea_ecb); ADD_C_(idea_cfb);
374     ADD_C_(idea_ofb); ADD_C_(idea_cbc);
375     #endif
376     #ifndef NI_RC2
377     ADD_C_(rc2_ecb); ADD_C_(rc2_cbc); ADD_C_(rc2_40_cbc);
378     ADD_C_(rc2_64_cbc); ADD_C_(rc2_cfb); ADD_C_(rc2_ofb);
379     #endif
380     #ifndef NO_BF
381     ADD_C_(bf_ecb); ADD_C_(bf_cbc);
382     ADD_C_(bf_cfb); ADD_C_(bf_ofb);
383     #endif
384     #ifndef NO_CAST
385     ADD_C_(cast5_ecb); ADD_C_(cast5_cbc);
386     ADD_C_(cast5_cfb); ADD_C_(cast5_ofb);
387     #endif
388     #ifndef NO_RC5
389     ADD_C_(rc5_32_12_16_cbc); ADD_C_(rc5_32_12_16_ecb);
390     ADD_C_(rc5_32_12_16_cfb); ADD_C_(rc5_32_12_16_ofb);
391     #endif
392     }
393    
394    
395     MODULE = OpenSSL PACKAGE = OpenSSL::RSA
396    
397 root 1.8 OpenSSL::RSA
398 stefan 1.1 new_keygen(bits = 128, e = 35)
399     IV bits
400     IV e
401 root 1.8 CODE:
402     if(!(RETVAL = RSA_generate_key(bits, e, NULL, NULL)))
403 stefan 1.1 croak("RSA_generate_key");
404 root 1.8 OUTPUT:
405     RETVAL
406 stefan 1.1
407 root 1.8 OpenSSL::RSA
408 stefan 1.1 new_pubkey(n, e)
409     char *n
410     char *e
411 root 1.8 CODE:
412     RETVAL = RSA_new();
413     if (!RETVAL)
414 stefan 1.1 croak("can't allocate key");
415 root 1.8 if(!(RETVAL->n = BN_new()) || !BN_dec2bn(&RETVAL->n, n)) {
416     RSA_free(RETVAL); croak("can't initialize n");
417 stefan 1.1 }
418 root 1.8 if(!(RETVAL->e = BN_new()) || !BN_dec2bn(&RETVAL->e, e)) {
419     RSA_free(RETVAL); croak("can't initialize e");
420 stefan 1.1 }
421     //key->p = 0, key->q = 0, key->dmp1 = 0, key->dmq1 = 0, key->iqmp = 0;
422 root 1.8 OUTPUT:
423     RETVAL
424 stefan 1.1
425    
426 root 1.9 OpenSSL::RSA
427 stefan 1.1 new_privkey(n, e, p, q, dmp1, dmq1, iqmp, d)
428     char *n
429     char *e
430     char *p
431     char *q
432     char *dmp1
433     char *dmq1
434     char *iqmp
435     char *d
436 root 1.9 CODE:
437 stefan 1.1 int rc;
438 root 1.9
439     RETVAL = RSA_new();
440     if (!RETVAL)
441 stefan 1.1 croak("can't allocate key");
442 root 1.9 if(!(RETVAL->n = BN_new()) || !BN_dec2bn(&RETVAL->n, n)) {
443     RSA_free(RETVAL); croak("can't initialize n");
444 stefan 1.1 }
445 root 1.9 if(!(RETVAL->e = BN_new()) || !BN_dec2bn(&RETVAL->e, e)) {
446     RSA_free(RETVAL); croak("can't initialize e");
447 stefan 1.1 }
448 root 1.9 if(!(RETVAL->p = BN_new()) || !BN_dec2bn(&RETVAL->p, p)) {
449     RSA_free(RETVAL); croak("can't initialize p");
450 stefan 1.1 }
451 root 1.9 if(!(RETVAL->q = BN_new()) || !BN_dec2bn(&RETVAL->q, q)) {
452     RSA_free(RETVAL); croak("can't initialize q");
453 stefan 1.1 }
454 root 1.9 if(!(RETVAL->dmp1 = BN_new()) || !BN_dec2bn(&RETVAL->dmp1, dmp1)) {
455     RSA_free(RETVAL); croak("can't initialize dmp1");
456 stefan 1.1 }
457 root 1.9 if(!(RETVAL->dmq1 = BN_new()) || !BN_dec2bn(&RETVAL->dmq1, dmq1)) {
458     RSA_free(RETVAL); croak("can't initialize dmq1");
459 stefan 1.1 }
460 root 1.9 if(!(RETVAL->iqmp = BN_new()) || !BN_dec2bn(&RETVAL->iqmp, iqmp)) {
461     RSA_free(RETVAL); croak("can't initialize iqmp");
462 stefan 1.1 }
463 root 1.9 if(!(RETVAL->d = BN_new()) || !BN_dec2bn(&RETVAL->d, d)) {
464     RSA_free(RETVAL); croak("can't initialize d");
465 stefan 1.1 }
466 root 1.9 if((rc = RSA_check_key(RETVAL)) != 1) {
467     RSA_free(RETVAL); croak("RSA_check_key failed (%d).", rc);
468 stefan 1.1 }
469 root 1.9 OUTPUT:
470     RETVAL
471 stefan 1.1
472    
473     void
474     DESTROY(key)
475 root 1.8 OpenSSL::RSA key
476 stefan 1.1 CODE:
477     if (key) {
478     XD("RSA_free(%p)\n", key);
479     RSA_free(key);
480     }
481    
482     IV
483     keysize(key)
484 root 1.8 OpenSSL::RSA key;
485 stefan 1.1 CODE:
486     if (!key || !key->n)
487     croak("invalid key");
488     RETVAL = BN_num_bits(key->n);
489     OUTPUT:
490     RETVAL
491    
492     bool
493     check_key(key)
494 root 1.8 OpenSSL::RSA key;
495 stefan 1.1 PPCODE:
496     if(!key)
497     XSRETURN_NO;
498     if(RSA_check_key(key) == 1)
499     XSRETURN_YES;
500     XSRETURN_NO;
501    
502    
503     BIGNUM *
504     n(key)
505 root 1.8 OpenSSL::RSA key;
506 stefan 1.1 ALIAS:
507     e = 1
508     d = 2
509     p = 3
510     q = 4
511     dmp1 = 5
512     dmq1 = 6
513     iqmp = 7
514     PREINIT:
515     BIGNUM *bn = 0;
516     CODE:
517     if(!key)
518     croak("invalid key");
519     switch(ix) {
520     case 0: bn = key->n; break;
521     case 1: bn = key->e; break;
522     case 2: bn = key->d; break;
523     case 3: bn = key->p; break;
524     case 4: bn = key->q; break;
525     case 5: bn = key->dmp1; break;
526     case 6: bn = key->dmq1; break;
527     case 7: bn = key->iqmp; break;
528     default:
529     croak("huch");
530     }
531     if(!bn)
532     croak("bignum not defined (maybe pubkey ?)");
533     RETVAL = bn;
534     OUTPUT:
535     RETVAL
536    
537    
538     bool
539     is_privkey(key)
540 root 1.8 OpenSSL::RSA key;
541 stefan 1.1 CODE:
542     RETVAL = is_privkey(key);
543     OUTPUT:
544     RETVAL
545    
546     void
547     STORABLE_thaw(osv, cloning, sv)
548     SV *osv
549     bool cloning
550     SV *sv
551     PREINIT:
552     STRLEN len;
553     char *p;
554     unsigned int *i;
555     RSA *key = NULL;
556     PPCODE:
557     if(cloning)
558     return;
559     i = (unsigned int *) SvPV(sv, len);
560     if(i[2] == 0xffffffff) {
561     // public key
562     key = RSA_new();
563     p = (char *) &i[3];
564     key->n = BN_bin2bn(p, i[0], NULL);
565     key->e = BN_bin2bn(&p[i[0]], i[1], NULL);
566     } else if (i[8] == 0xffffffff) {
567     // private key
568     key = RSA_new();
569     p = (char *) &i[9];
570     key->n = BN_bin2bn(p, i[0], NULL);
571     p += i[0];
572     key->e = BN_bin2bn(p, i[1], NULL);
573     p += i[1];
574     key->d = BN_bin2bn(p, i[2], NULL);
575     p += i[2];
576     key->p = BN_bin2bn(p, i[3], NULL);
577     p += i[3];
578     key->q = BN_bin2bn(p, i[4], NULL);
579     p += i[4];
580     key->dmp1 = BN_bin2bn(p, i[5], NULL);
581     p += i[5];
582     key->dmq1 = BN_bin2bn(p, i[6], NULL);
583     p += i[6];
584     key->iqmp = BN_bin2bn(p, i[7], NULL);
585     }
586     if(!key)
587     croak("Illegal Storable format.");
588     sv_setiv(SvRV(osv), (IV) key);
589     //sv_setref_pv(SvRV(osv), "OpenSSL::RSA", newRV_noinc((void *) key);
590     //sv_setiv(osv, (IV) key);
591    
592    
593    
594     void
595     STORABLE_freeze(key, cloning)
596 root 1.8 OpenSSL::RSA key
597 stefan 1.1 bool cloning
598     PREINIT:
599     STRLEN totlen;
600     PPCODE:
601     if(cloning)
602     return;
603     totlen = BN_num_bytes(key->n) + BN_num_bytes(key->e) + 3*sizeof(int);
604     if(!is_privkey(key)) {
605     int *y = malloc(totlen);
606     int *x = y;
607     char *p;
608     *x++ = BN_num_bytes(key->n);
609     *x++ = BN_num_bytes(key->e);
610     *x++ = 0xffffffff;
611     p = (char *) x;
612     p += BN_bn2bin(key->n, p);
613     p += BN_bn2bin(key->e, p);
614     XPUSHs(sv_2mortal(newSVpvn((char *)y, p - (char *) y)));
615     free(y);
616     } else {
617     int *y, *x;
618     char *p;
619     totlen += BN_num_bytes(key->d)
620     + BN_num_bytes(key->p)
621     + BN_num_bytes(key->q)
622     + BN_num_bytes(key->dmp1)
623     + BN_num_bytes(key->dmq1)
624     + BN_num_bytes(key->iqmp) + 6*sizeof(int);
625     y = malloc(totlen);
626     x = y;
627     *x++ = BN_num_bytes(key->n);
628     *x++ = BN_num_bytes(key->e);
629     *x++ = BN_num_bytes(key->d);
630     *x++ = BN_num_bytes(key->p);
631     *x++ = BN_num_bytes(key->q);
632     *x++ = BN_num_bytes(key->dmp1);
633     *x++ = BN_num_bytes(key->dmq1);
634     *x++ = BN_num_bytes(key->iqmp);
635     *x++ = 0xffffffff;
636     p = (char *) x;
637     p += BN_bn2bin(key->n, p);
638     p += BN_bn2bin(key->e, p);
639     p += BN_bn2bin(key->d, p);
640     p += BN_bn2bin(key->p, p);
641     p += BN_bn2bin(key->q, p);
642     p += BN_bn2bin(key->dmp1, p);
643     p += BN_bn2bin(key->dmq1, p);
644     p += BN_bn2bin(key->iqmp, p);
645     XPUSHs(sv_2mortal(newSVpvn((char *)y, p - (char *) y)));
646     free(y);
647     }
648    
649    
650     SV *
651     public_encrypt(key, sv)
652 root 1.8 OpenSSL::RSA key;
653 stefan 1.1 SV *sv;
654     ALIAS:
655     encrypt = 4
656     public_decrypt = 1
657     verify = 5
658     private_encrypt = 2
659     sign = 6
660     private_decrypt = 3
661     decrypt = 7
662     PREINIT:
663     static int (*func[4])(int, unsigned char *, unsigned char *, RSA *, int) = { RSA_public_encrypt, RSA_public_decrypt, RSA_private_encrypt, RSA_private_decrypt };
664     STRLEN len;
665     int keylen;
666     char *p;
667     char *out;
668     STRLEN rc;
669     CODE:
670     if(!SvPOK(sv))
671     croak ("need a string.");
672     p = SvPV(sv, len);
673     keylen = BN_num_bits(key->n);
674     if(!p || len < 1 || (len*8 > (keylen+7)&~0x7))
675     croak("illegal value");
676     RETVAL = NEWSV(0, len + keylen);
677     SvPOK_only(RETVAL);
678     SvCUR_set(RETVAL, len + keylen);
679     out = SvPV_nolen(RETVAL);
680     if((ix&0x3) > 1 && !is_privkey(key))
681     croak("need a private key.");
682     rc = func[ix&0x3](len, p, out, key, RSA_PKCS1_PADDING);
683     if(rc < 0) {
684     sv_free(RETVAL);
685     RETVAL = &PL_sv_undef;
686     croak("crypto error... rc=%d inlen=%d", rc, len);
687     }
688     SvCUR_set(RETVAL, rc);
689     OUTPUT:
690     RETVAL
691    
692    
693     void
694     fingerprint(key)
695 root 1.8 OpenSSL::RSA key
696 stefan 1.1 PREINIT:
697     char *x;
698     char dig[SHA_DIGEST_LENGTH];
699     int nlen, elen;
700     PPCODE:
701     nlen = BN_num_bytes(key->n);
702     elen = BN_num_bytes(key->e);
703     x = malloc(nlen + elen);
704     if(!x)
705     croak("malloc error");
706     BN_bn2bin(key->n, x);
707     BN_bn2bin(key->e, &x[nlen]);
708     //un_sha1(dig, x, nlen+elen);
709     free(x);
710     XPUSHs(sv_2mortal(newSVpvn(dig, SHA_DIGEST_LENGTH)));
711    
712     MODULE = OpenSSL PACKAGE = OpenSSL::Name
713    
714     PROTOTYPES: ENABLE
715    
716 root 1.6 OpenSSL::Name
717 root 1.7 new(class)
718     SV *class
719 root 1.6 CODE:
720     if(!(RETVAL = X509_NAME_new())) {
721 stefan 1.1 croak("X509_NAME_new");
722     }
723 root 1.6 OUTPUT:
724     RETVAL
725 stefan 1.1
726    
727     void
728     add(name, key, string)
729 root 1.6 OpenSSL::Name name
730 stefan 1.1 SV *key
731     SV *string
732     PREINIT:
733     STRLEN l, kl;
734     char *p, *k;
735     int ok;
736     PPCODE:
737     p = SvPV(string, l);
738     if(SvIOK(key)) {
739     ok = X509_NAME_add_entry_by_NID(name, SvIV(key), MBSTRING_ASC, p, -1, -1, 0);
740     } else {
741     k = SvPV(key, kl);
742     ok = X509_NAME_add_entry_by_txt(name, k, MBSTRING_ASC, p, -1, -1, 0);
743     }
744     if(!ok)
745     croak("X509_NAME_add_entry_by_*: %s", ssl_error());
746    
747     IV
748     count(name)
749 root 1.6 OpenSSL::Name name
750 stefan 1.1 CODE:
751     RETVAL = X509_NAME_entry_count(name);
752     OUTPUT:
753     RETVAL
754    
755     void
756     getall(name)
757 root 1.6 OpenSSL::Name name
758 stefan 1.1 PREINIT:
759     int cnt, i;
760     X509_NAME_ENTRY *e;
761     int nid;
762     ASN1_STRING *s;
763     PPCODE:
764     cnt = X509_NAME_entry_count(name);
765     EXTEND(SP, cnt<<1);
766     for(i = 0; i < cnt; i++) {
767     e = X509_NAME_get_entry(name, i);
768     if(!e)
769     croak("X509_NAME_get_entry");
770     nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
771     s = X509_NAME_ENTRY_get_data(e);
772     PUSHs(sv_2mortal(newSVpv(OBJ_nid2ln(nid),0)));
773     PUSHs(sv_2mortal(newSVpvn(s->data, s->length)));
774     }
775    
776     void
777     DESTROY(name)
778 root 1.6 OpenSSL::Name name
779 stefan 1.1 CODE:
780     if(name) {
781     XD("X509_NAME_free(%p)\n", name);
782     X509_NAME_free(name);
783     }
784    
785    
786     MODULE = OpenSSL PACKAGE = OpenSSL::Rand
787    
788     PROTOTYPES: ENABLE
789    
790     BOOT:
791     {
792     int fd;
793     int rc;
794     ERR_load_RAND_strings();
795     fd = open("/dev/urandom", O_RDONLY);
796     if(fd != -1) {
797     char buf[64];
798     rc = read(fd, buf, 64);
799     if(rc < 1) {
800     warn ("read /dev/urandom");
801     } else {
802     RAND_seed(buf, rc);
803     }
804     close(fd);
805     } else {
806     warn ("can't open /dev/urandom");
807     }
808     }
809    
810    
811    
812     SV *
813     randbytes(nr)
814     IV nr
815     ALIAS:
816     randbytes_hex = 1
817     randbytes_base64 = 2
818     PREINIT:
819     char *p;
820     int rc;
821     CODE:
822     p = malloc(nr+1);
823     if(!p)
824     croak("malloc failed");
825     rc = RAND_bytes(p, nr);
826     if(rc != 1) {
827     free(p);
828     croak("RAND_bytes returned %d", rc);
829     }
830     switch(ix) {
831     case 0:
832     RETVAL = newSVpvn(p, nr);
833     break;
834     case 1:
835     RETVAL = hexsv(p, nr);
836     break;
837     default:
838     RETVAL = base64sv(p, nr);
839     break;
840     }
841     free(p);
842     OUTPUT:
843     RETVAL
844    
845    
846     MODULE = OpenSSL PACKAGE = OpenSSL::X509
847    
848     PROTOTYPES: ENABLE
849    
850     BOOT:
851     {
852     // We have joy we have fun we have seasons in the sun...
853     OpenSSL_add_all_algorithms();
854     OpenSSL_add_all_ciphers();
855     OpenSSL_add_all_digests();
856     SSL_load_error_strings();
857     ERR_load_PEM_strings();
858     ERR_load_PKCS7_strings();
859     ERR_load_PKCS12_strings();
860     ERR_load_ASN1_strings();
861     ERR_load_crypto_strings();
862     ERR_load_RAND_strings();
863     ERR_load_X509_strings();
864     ERR_load_X509V3_strings();
865     ERR_load_DH_strings();
866     ERR_load_DSA_strings();
867     ERR_load_RSA_strings();
868     }
869    
870    
871 root 1.4 OpenSSL::X509
872 root 1.7 new(class)
873     SV *class
874 root 1.4 CODE:
875     if ((RETVAL = X509_new ()) == NULL)
876 stefan 1.1 croak("X509_new");
877 root 1.4
878     if (!X509_set_version (RETVAL, 2))
879     {
880     X509_free (RETVAL);
881     croak ("X509_set_version");
882     }
883    
884     ASN1_INTEGER_set (X509_get_serialNumber (RETVAL), 0L);
885     OUTPUT:
886     RETVAL
887 stefan 1.1
888    
889 root 1.9 OpenSSL::X509
890 root 1.7 new_from_string(class,thing)
891     SV *class
892 root 1.5 SV *thing
893 stefan 1.1 ALIAS:
894     new_from_file = 1
895     PREINIT:
896     BIO *bio;
897     STRLEN l;
898 stefan 1.12 char *p;
899 root 1.9 CODE:
900 root 1.5 p = SvPV (thing, l);
901 stefan 1.1 if(ix == 1) {
902     bio = BIO_new_file(p, "r");
903     } else {
904     bio = BIO_new_mem_buf (p, l);
905     }
906     if(!bio)
907     croak(ssl_error());
908    
909 root 1.9 RETVAL = PEM_read_bio_X509 (bio, 0, 0, 0);
910 stefan 1.1 BIO_free (bio);
911 root 1.9 if(!RETVAL)
912 stefan 1.1 croak("PEM_read_bio_X509: %s", ssl_error());
913    
914 root 1.9 OUTPUT:
915     RETVAL
916 stefan 1.1
917     void
918     DESTROY(x509)
919 root 1.2 OpenSSL::X509 x509
920 stefan 1.1 CODE:
921     if (x509) {
922     XD("X509_free(%p)\n", x509);
923 root 1.5 X509_free (x509);
924 stefan 1.1 x509 = 0;
925     }
926    
927    
928     char *
929     fingerprint_md5(x509)
930 root 1.2 OpenSSL::X509 x509
931 stefan 1.1 ALIAS:
932     fingerprint_md2 = 1
933     fingerprint_mdc2 = 2
934     fingerprint_sha1 = 3
935     PREINIT:
936     EVP_MD *mds[] = { EVP_md5(), EVP_md2(), EVP_mdc2(), EVP_sha1() };
937     CODE:
938     RETVAL = dofp(x509, mds[ix]);
939     OUTPUT:
940     RETVAL
941    
942    
943 root 1.6 OpenSSL::Name
944 stefan 1.1 subject(x509)
945 root 1.2 OpenSSL::X509 x509
946 stefan 1.1 CODE:
947 root 1.10 RETVAL = X509_NAME_dup (X509_get_subject_name(x509));
948 stefan 1.1 OUTPUT:
949     RETVAL
950    
951 root 1.6 OpenSSL::Name
952 stefan 1.1 issuer(x509)
953 root 1.2 OpenSSL::X509 x509
954 stefan 1.1 CODE:
955 root 1.10 RETVAL = X509_NAME_dup (X509_get_issuer_name(x509));
956 stefan 1.1 OUTPUT:
957     RETVAL
958    
959    
960 stefan 1.12 SV *
961 stefan 1.1 subject_txt(x509)
962 root 1.2 OpenSSL::X509 x509
963 stefan 1.1 CODE:
964     RETVAL = ol(X509_get_subject_name(x509));
965     OUTPUT:
966     RETVAL
967    
968    
969 stefan 1.12 SV *
970 stefan 1.1 issuer_txt(x509)
971 root 1.2 OpenSSL::X509 x509
972 stefan 1.1 CODE:
973     RETVAL = ol(X509_get_issuer_name(x509));
974     OUTPUT:
975     RETVAL
976    
977     ASN1_INTEGER *
978     serial(x509)
979 root 1.2 OpenSSL::X509 x509
980 stefan 1.1 CODE:
981     RETVAL = X509_get_serialNumber(x509);
982     OUTPUT:
983     RETVAL
984    
985    
986     int
987     version(x509)
988 root 1.2 OpenSSL::X509 x509
989 stefan 1.1 CODE:
990     RETVAL = X509_get_version(x509);
991     OUTPUT:
992     RETVAL
993    
994     ASN1_UTCTIME *
995     notBefore(x509)
996 root 1.2 OpenSSL::X509 x509
997 stefan 1.1 CODE:
998     RETVAL = X509_get_notBefore(x509);
999     OUTPUT:
1000     RETVAL
1001    
1002     ASN1_UTCTIME *
1003     notAfter(x509)
1004 root 1.2 OpenSSL::X509 x509
1005 stefan 1.1 CODE:
1006     RETVAL = X509_get_notAfter(x509);
1007     OUTPUT:
1008     RETVAL
1009    
1010     int
1011     cert_type(x509)
1012 root 1.2 OpenSSL::X509 x509
1013 stefan 1.1 CODE:
1014     RETVAL = X509_certificate_type(x509, 0);
1015     OUTPUT:
1016     RETVAL
1017    
1018     SV*
1019     as_string(x509,...)
1020 root 1.2 OpenSSL::X509 x509
1021 stefan 1.1 ALIAS:
1022     as_file = 1
1023     PROTOTYPE: $;$
1024     PREINIT:
1025     BIO *bio;
1026     CODE:
1027     if((ix != 1 && items > 1) || (ix == 1 && items != 2))
1028     croak("OpenSSL::X509::%s: illegal/missing args", (ix == 1) ? "as_file" : " as_string");
1029     if(items > 1) {
1030     bio = sv_bio_create_file(ST(1));
1031     } else {
1032     bio = sv_bio_create();
1033     }
1034     if(!bio)
1035     croak("sv_bio_create");
1036     if(!PEM_write_bio_X509(bio, x509)) {
1037     sv_bio_error(bio);
1038     croak("PEM_write_bio_X509: %s", ssl_error());
1039     }
1040     RETVAL = sv_bio_final(bio);
1041     OUTPUT:
1042     RETVAL
1043    
1044     SV*
1045     info(x509)
1046 root 1.2 OpenSSL::X509 x509
1047 stefan 1.1 PREINIT:
1048     BIO *bio;
1049     CODE:
1050     bio = sv_bio_create();
1051     if(!X509_print(bio,x509)) {
1052     sv_bio_error(bio);
1053     croak("X509_print: %s", ssl_error());
1054     }
1055     RETVAL = sv_bio_final(bio);
1056     OUTPUT:
1057     RETVAL
1058    
1059     void
1060     set_issuer(x509,name)
1061 root 1.3 OpenSSL::X509 x509
1062 root 1.6 OpenSSL::Name name
1063 stefan 1.1 CODE:
1064     X509_set_issuer_name(x509, X509_NAME_dup(name));
1065    
1066     void
1067     set_subject(x509,name)
1068 root 1.3 OpenSSL::X509 x509
1069 root 1.6 OpenSSL::Name name
1070 stefan 1.1 CODE:
1071     X509_set_subject_name(x509, X509_NAME_dup(name));
1072    
1073     SV *
1074     errstring(x509)
1075 root 1.2 OpenSSL::X509 x509
1076 stefan 1.1 PREINIT:
1077     BIO *bio;
1078     CODE:
1079     bio = sv_bio_create();
1080     ERR_print_errors(bio);
1081     RETVAL = sv_bio_final(bio);
1082     ERR_clear_error();
1083     OUTPUT:
1084     RETVAL
1085    
1086    
1087     MODULE = OpenSSL PACKAGE = OpenSSL::Cipher
1088    
1089     PROTOTYPES: ENABLE
1090    
1091     BOOT:
1092     {
1093     cipher_boot();
1094     }
1095    
1096     void
1097     DESTROY(ctx)
1098 root 1.8 OpenSSL::Cipher ctx
1099 stefan 1.1 CODE:
1100     if(ctx) {
1101     EVP_CIPHER_CTX_cleanup(ctx);
1102     free(ctx);
1103     }
1104    
1105 root 1.9 OpenSSL::Cipher
1106 stefan 1.1 new_decrypt(...)
1107     ALIAS:
1108     new_encrypt = 1
1109     PREINIT:
1110     char *name;
1111     SV *svkey;
1112     EVP_CIPHER *ci;
1113     char *key;
1114     char iv[EVP_MAX_IV_LENGTH];
1115     char k[EVP_MAX_KEY_LENGTH];
1116     int rc;
1117     STRLEN keylen;
1118 root 1.9 CODE:
1119 stefan 1.1 if(items < 2 || items > 3) {
1120     croak("usage: new_[en|de]crypt(ciphname,key)");
1121     }
1122     name = SvPV_nolen(ST(items -2));
1123     svkey = ST(items - 1);
1124     memset(iv, 0, EVP_MAX_IV_LENGTH);
1125     memset(k, 0, EVP_MAX_KEY_LENGTH);
1126    
1127     if(!(ci = lookup_cipher(name)))
1128     croak("OpenSSL::Cipher::new: no such cipher \"%s\"", name);
1129 root 1.9 RETVAL = (EVP_CIPHER_CTX *) malloc(sizeof(EVP_CIPHER_CTX));
1130     if(!RETVAL)
1131 stefan 1.1 croak("malloc error");
1132     key = SvPV(svkey, keylen);
1133     memcpy(k, key, (keylen <= ci->key_len) ? keylen : ci->key_len);
1134 root 1.9 rc = EVP_CipherInit(RETVAL, ci, k, iv, ix);
1135 stefan 1.1 memset(iv, 0, EVP_MAX_IV_LENGTH);
1136     memset(iv, 0, EVP_MAX_KEY_LENGTH);
1137     if(!rc) {
1138 root 1.9 free(RETVAL);
1139 stefan 1.1 croak("EVP_CipherInit");
1140     }
1141 root 1.9 OUTPUT:
1142     RETVAL
1143 stefan 1.1
1144    
1145     SV *
1146     update(ctx,svin)
1147 root 1.8 OpenSSL::Cipher ctx
1148 stefan 1.1 SV *svin
1149     PREINIT:
1150     unsigned char *in, *out;
1151     STRLEN il, ol;
1152     CODE:
1153     in = SvPV(svin, il);
1154     ol = (il + 63) & ~63;
1155     RETVAL = NEWSV(0, ol);
1156     SvPOK_only(RETVAL);
1157     SvCUR_set(RETVAL, ol);
1158     out = SvPV_nolen(RETVAL);
1159     if(!out)
1160     croak("memory");
1161     if(!EVP_CipherUpdate(ctx, out, &ol, in, il)) {
1162     sv_free(RETVAL);
1163     croak("EVP_CipherUpdate");
1164     }
1165     SvCUR_set(RETVAL, ol);
1166     OUTPUT:
1167     RETVAL
1168    
1169     SV *
1170     final(ctx)
1171 root 1.8 OpenSSL::Cipher ctx
1172 stefan 1.1 PREINIT:
1173     STRLEN ol;
1174     unsigned char *out;
1175     CODE:
1176     ol = 256;
1177     RETVAL = NEWSV(0, ol);
1178     SvPOK_only(RETVAL);
1179     SvCUR_set(RETVAL, ol);
1180     out = SvPV_nolen(RETVAL);
1181     if(!out)
1182     croak("memory");
1183     if(!EVP_CipherFinal(ctx, out, &ol)) {
1184     sv_free(RETVAL);
1185     croak("EVP_CipherFinal %s", ssl_error());
1186     }
1187     SvCUR_set(RETVAL, ol);
1188     OUTPUT:
1189     RETVAL
1190    
1191     void
1192     enum_ciphers()
1193     PREINIT:
1194     int i;
1195     PPCODE:
1196     EXTEND(SP, cip_cnt<<1);
1197     for(i = 0; i < cip_cnt; i++) {
1198     PUSHs(sv_2mortal(newSVpv(cip_list[i].name, 0)));
1199     PUSHs(sv_2mortal(newSViv(cip_list[i].func->key_len)));
1200     }
1201    
1202    
1203    
1204    
1205     MODULE = OpenSSL PACKAGE = OpenSSL::Digest
1206    
1207     PROTOTYPES: ENABLE
1208    
1209     BOOT:
1210     {
1211     mds_boot();
1212     }
1213    
1214     SV *
1215 root 1.14 md2(...)
1216 stefan 1.1 ALIAS:
1217     md4 = 0x1
1218     md5 = 0x2
1219     sha = 0x3
1220     sha1 = 0x4
1221     dss = 0x5
1222     dss1 = 0x6
1223     mdc2 = 0x7
1224     ripemd160 = 0x8
1225     md2_hex = 0x10
1226     md4_hex = 0x11
1227     md5_hex = 0x12
1228     sha_hex = 0x13
1229     sha1_hex = 0x14
1230     dss_hex = 0x15
1231     dss1_hex = 0x16
1232     mdc2_hex = 0x17
1233     ripemd160_hex = 0x18
1234     md2_base64 = 0x20
1235     md4_base64 = 0x21
1236     md5_base64 = 0x22
1237     sha_base64 = 0x23
1238     sha1_base64 = 0x24
1239     dss_base64 = 0x25
1240     dss1_base64 = 0x26
1241     mdc2_base64 = 0x27
1242     ripemd160_base64 = 0x28
1243 root 1.14 CODE:
1244 stefan 1.1 EVP_MD_CTX ctx;
1245     STRLEN l;
1246     char *p;
1247     unsigned char md[EVP_MAX_MD_SIZE];
1248     unsigned int md_len;
1249 root 1.14 int i;
1250    
1251 stefan 1.1 EVP_DigestInit(&ctx, _mds[NO_FLAGS(ix)]);
1252 root 1.14
1253     for (i = 0; i < items; i++)
1254     {
1255     p = SvPV(ST(i), l);
1256     EVP_DigestUpdate(&ctx, p, l);
1257     }
1258    
1259 stefan 1.1 EVP_DigestFinal(&ctx, md, &md_len);
1260     switch(ix & ~15) {
1261     case 0:
1262     RETVAL = newSVpvn(md, md_len);
1263     break;
1264     case FLAG_HEX:
1265     RETVAL = hexsv(md, md_len);
1266     break;
1267     default:
1268     RETVAL = base64sv(md, md_len);
1269     break;
1270     }
1271     OUTPUT:
1272     RETVAL
1273    
1274    
1275 root 1.9 OpenSSL::Digest
1276 stefan 1.1 new_md2()
1277     ALIAS:
1278     new_md4 = 0x1
1279     new_md5 = 0x2
1280     mew_sha = 0x3
1281     new_sha1 = 0x4
1282     new_dss = 0x5
1283     new_dss1 = 0x6
1284     new_mdc2 = 0x7
1285     new_ripemd160 = 0x8
1286 root 1.9 CODE:
1287     RETVAL = (EVP_MD_CTX *) malloc(sizeof(EVP_MD_CTX));
1288     if(!RETVAL)
1289 stefan 1.1 croak("out of memory.");
1290 root 1.9 EVP_DigestInit(RETVAL, _mds[NO_FLAGS(ix)]);
1291     OUTPUT:
1292     RETVAL
1293 stefan 1.1
1294     void
1295     DESTROY(ctx)
1296 root 1.8 OpenSSL::Digest ctx
1297 stefan 1.1 CODE:
1298     if(ctx)
1299     free(ctx);
1300    
1301     void
1302 root 1.15 update(ctx, ...)
1303 root 1.8 OpenSSL::Digest ctx
1304 root 1.15 PREINIT:
1305 stefan 1.1 STRLEN l;
1306     char *p;
1307 root 1.15 int i;
1308 stefan 1.1 CODE:
1309 root 1.15 for (i = 1; i < items; i++)
1310     {
1311     p = SvPV(ST(i), l);
1312     EVP_DigestUpdate(ctx, p, l);
1313     }
1314 stefan 1.1
1315     SV *
1316     final(ctx)
1317 root 1.8 OpenSSL::Digest ctx
1318 stefan 1.1 ALIAS:
1319     final_hex = 1
1320     final_base64 = 2
1321     PREINIT:
1322     unsigned char md[EVP_MAX_MD_SIZE];
1323     unsigned int md_len;
1324     CODE:
1325     EVP_DigestFinal(ctx, md, &md_len);
1326     switch(ix) {
1327     case 0:
1328     RETVAL = newSVpvn(md, md_len);
1329     break;
1330     case 1:
1331     RETVAL = hexsv(md, md_len);
1332     break;
1333     default:
1334     RETVAL = base64sv(md, md_len);
1335     break;
1336     }
1337     OUTPUT:
1338     RETVAL
1339    
1340     MODULE = OpenSSL::Digest PACKAGE = OpenSSL::HMAC
1341    
1342     PROTOTYPES: ENABLE
1343    
1344     BOOT:
1345     {
1346     mds_boot();
1347     }
1348    
1349     SV *
1350     md2(svkey, sv)
1351     SV *svkey
1352     SV *sv
1353     ALIAS:
1354     md4 = 0x1
1355     md5 = 0x2
1356     sha = 0x3
1357     sha1 = 0x4
1358     dss = 0x5
1359     dss1 = 0x6
1360     mdc2 = 0x7
1361     ripemd160 = 0x8
1362     md2_hex = 0x10
1363     md4_hex = 0x11
1364     md5_hex = 0x12
1365     sha_hex = 0x13
1366     sha1_hex = 0x14
1367     dss_hex = 0x15
1368     dss1_hex = 0x16
1369     mdc2_hex = 0x17
1370     ripemd160_hex = 0x18
1371     md2_base64 = 0x20
1372     md4_base64 = 0x21
1373     md5_base64 = 0x22
1374     sha_base64 = 0x23
1375     sha1_base64 = 0x24
1376     dss_base64 = 0x25
1377     dss1_base64 = 0x26
1378     mdc2_base64 = 0x27
1379     ripemd160_base64 = 0x28
1380     PREINIT:
1381     STRLEN l, keylen;
1382     char *p;
1383     char *key;
1384     unsigned char md[EVP_MAX_MD_SIZE];
1385     unsigned int md_len;
1386     CODE:
1387     p = SvPV(sv, l);
1388     key = SvPV(svkey, keylen);
1389     if(!HMAC(_mds[NO_FLAGS(ix)], key, keylen, p, l, md, &md_len))
1390     croak("HMAC");
1391     switch(ix & ~15) {
1392     case 0:
1393     RETVAL = newSVpvn(md, md_len);
1394     break;
1395     case FLAG_HEX:
1396     RETVAL = hexsv(md, md_len);
1397     break;
1398     default:
1399     RETVAL = base64sv(md, md_len);
1400     break;
1401     }
1402     OUTPUT:
1403     RETVAL
1404    
1405    
1406 root 1.9 OpenSSL::Digest
1407     new_md2()
1408 stefan 1.1 ALIAS:
1409     new_md4 = 0x1
1410     new_md5 = 0x2
1411     mew_sha = 0x3
1412     new_sha1 = 0x4
1413     new_dss = 0x5
1414     new_dss1 = 0x6
1415     new_mdc2 = 0x7
1416     new_ripemd160 = 0x8
1417 root 1.9 CODE:
1418     RETVAL = (EVP_MD_CTX *) malloc(sizeof(EVP_MD_CTX));
1419     if(!RETVAL)
1420 stefan 1.1 croak("out of memory.");
1421 root 1.9 EVP_DigestInit(RETVAL, _mds[NO_FLAGS(ix)]);
1422     OUTPUT:
1423     RETVAL
1424 stefan 1.1
1425     void
1426     DESTROY(ctx)
1427 root 1.8 OpenSSL::Digest ctx
1428 stefan 1.1 CODE:
1429     if(ctx)
1430     free(ctx);
1431    
1432     void
1433     update(ctx, sv)
1434 root 1.8 OpenSSL::Digest ctx
1435 stefan 1.1 SV *sv
1436     PREINIT:
1437     STRLEN l;
1438     char *p;
1439     CODE:
1440     p = SvPV(sv, l);
1441     EVP_DigestUpdate(ctx, p, l);
1442    
1443    
1444     SV *
1445     final(ctx)
1446 root 1.8 OpenSSL::Digest ctx
1447 stefan 1.1 ALIAS:
1448     final_hex = 1
1449     final_base64 = 2
1450     PREINIT:
1451     unsigned char md[EVP_MAX_MD_SIZE];
1452     unsigned int md_len;
1453     CODE:
1454     EVP_DigestFinal(ctx, md, &md_len);
1455     switch(ix) {
1456     case 0:
1457     RETVAL = newSVpvn(md, md_len);
1458     break;
1459     case 1:
1460     RETVAL = hexsv(md, md_len);
1461     break;
1462     default:
1463     RETVAL = base64sv(md, md_len);
1464     break;
1465     }
1466     OUTPUT:
1467     RETVAL
1468    
1469    
1470     MODULE = OpenSSL PACKAGE = OpenSSL::PKCS7
1471    
1472 root 1.8 OpenSSL::PKCS7
1473 stefan 1.1 new()
1474 root 1.8 CODE:
1475     if(!(RETVAL = PKCS7_new())) {
1476 stefan 1.1 croak("PKCS7_new");
1477     }
1478 root 1.8 OUTPUT:
1479     RETVAL
1480 stefan 1.1
1481    
1482     void
1483     DESTROY(p7)
1484 root 1.8 OpenSSL::PKCS7 p7;
1485 stefan 1.1 CODE:
1486     if(p7) {
1487     XD("PKCS7_free(%p)\n", p7);
1488     PKCS7_free(p7);
1489     }
1490    
1491    
1492     MODULE = OpenSSL PACKAGE = OpenSSL::PKCS12
1493    
1494 root 1.8 OpenSSL::PKCS12
1495     new(class)
1496     SV *class
1497     CODE:
1498     if(!(RETVAL = PKCS12_new())) {
1499 stefan 1.1 croak("PKCS12_new");
1500     }
1501 root 1.8 OUTPUT:
1502     RETVAL
1503 stefan 1.1
1504 root 1.9 OpenSSL::PKCS12
1505 root 1.8 new_from_string(class,sv)
1506     SV *class
1507 stefan 1.1 SV *sv
1508     ALIAS:
1509     new_from_file = 1
1510     PREINIT:
1511     BIO *bio;
1512     char *s;
1513     STRLEN len;
1514 root 1.9 CODE:
1515 stefan 1.1 s = SvPV(sv, len);
1516     if(ix == 1) {
1517     bio = BIO_new_file(s, "r");
1518     } else {
1519     bio = BIO_new_mem_buf (s, len);
1520     }
1521     if(!bio)
1522     croak("BIO_new_mem_buf");
1523 root 1.9 if(!(RETVAL = d2i_PKCS12_bio(bio, 0))) {
1524 stefan 1.1 BIO_free(bio);
1525     croak("d2i_PKCS12_BIO: %s", ssl_error());
1526     }
1527     BIO_free(bio);
1528 root 1.9 OUTPUT:
1529     RETVAL
1530 stefan 1.1
1531    
1532     SV*
1533     mac_ok(p12, pwd)
1534 root 1.8 OpenSSL::PKCS12 p12
1535 stefan 1.1 char *pwd
1536     CODE:
1537    
1538     RETVAL = (PKCS12_verify_mac(p12, pwd, strlen(pwd))) ? &PL_sv_yes : &PL_sv_no;
1539     OUTPUT:
1540     RETVAL
1541    
1542     void
1543     changepass(p12, oldpwd, newpwd)
1544 root 1.8 OpenSSL::PKCS12 p12
1545 stefan 1.1 SV *oldpwd
1546     SV *newpwd
1547     PREINIT:
1548     char *op = 0;
1549     char *np = 0;
1550     CODE:
1551     if(oldpwd != &PL_sv_undef)
1552     op = SvPV_nolen(oldpwd);
1553     if(newpwd != &PL_sv_undef)
1554     np = SvPV_nolen(newpwd);
1555     if(!PKCS12_newpass(p12, op, np)) {
1556     croak("PKCS12_newpass: %s", ssl_error());
1557     }
1558    
1559     SV*
1560     as_string(p12,...)
1561 root 1.8 OpenSSL::PKCS12 p12
1562 stefan 1.1 ALIAS:
1563     as_file = 1
1564     PROTOTYPE: $;$
1565     PREINIT:
1566     BIO *bio;
1567     CODE:
1568     if((ix != 1 && items > 1) || (ix == 1 && items != 2))
1569     croak("OpenSSL::PKCS12::%s: illegal/missing args", (ix == 1) ? "as_file" : "as_string");
1570     if(items > 1) {
1571     bio = sv_bio_create_file(ST(1));
1572     } else {
1573     bio = sv_bio_create();
1574     }
1575     if(!bio)
1576     croak("sv_bio_create");
1577     if(!i2d_PKCS12_bio(bio, p12)) {
1578     sv_bio_error(bio);
1579     croak("i2d_PKCS12_bio: %s", ssl_error());
1580     }
1581     RETVAL = sv_bio_final(bio);
1582     OUTPUT:
1583     RETVAL
1584    
1585     void
1586     DESTROY(p12)
1587 root 1.8 OpenSSL::PKCS12 p12;
1588 stefan 1.1 CODE:
1589     if(p12) {
1590     XD("PKCS12_free(%p)\n", p12);
1591     PKCS12_free(p12);
1592     }
1593    
1594    
1595     MODULE = OpenSSL PACKAGE = OpenSSL::CRL
1596    
1597 root 1.5 OpenSSL::CRL
1598 stefan 1.13 new_from_string(class,thing)
1599     SV *class
1600 stefan 1.1 SV *thing
1601     ALIAS:
1602     new_from_file = 1
1603     PREINIT:
1604     BIO *bio;
1605     STRLEN l;
1606 stefan 1.12 char *p;
1607 root 1.5 CODE:
1608 stefan 1.1 p = SvPV(thing, l);
1609     if(ix == 1) {
1610     bio = BIO_new_file(p, "r");
1611     } else {
1612     bio = BIO_new_mem_buf (p, l);
1613     }
1614     if(!bio)
1615     croak(ssl_error());
1616    
1617 root 1.5 RETVAL = PEM_read_bio_X509_CRL (bio, 0, 0, 0);
1618 stefan 1.1 BIO_free (bio);
1619 root 1.5 if(!RETVAL)
1620 stefan 1.1 croak("PEM_read_bio_X509_CRL: %s", ssl_error());
1621    
1622 root 1.5 OUTPUT:
1623     RETVAL
1624 stefan 1.1
1625     void
1626     DESTROY(crl)
1627 root 1.5 OpenSSL::CRL crl
1628 stefan 1.1 CODE:
1629     if (crl) {
1630     XD("X509_CRL_free (%p)\n", crl);
1631     X509_CRL_free(crl);
1632     crl = 0;
1633     }
1634    
1635     SV*
1636     info(crl)
1637 root 1.5 OpenSSL::CRL crl
1638 stefan 1.1 PREINIT:
1639     BIO *bio;
1640     CODE:
1641     bio = sv_bio_create();
1642     if(!X509_CRL_print(bio,crl)) {
1643     sv_bio_error(bio);
1644     croak("X509_CRL_print: %s", ssl_error());
1645     }
1646     RETVAL = sv_bio_final(bio);
1647     OUTPUT:
1648     RETVAL
1649