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