Second round of fixing the OpenSSL perl/ stuff. It now at least compiled fine
[openssl.git] / perl / openssl_ssl.xs
1
2 #include "openssl.h"
3
4 static int p5_ssl_ex_ssl_ptr=0;
5 static int p5_ssl_ex_ssl_info_callback=0;
6 static int p5_ssl_ex_ssl_ctx_ptr=0;
7 static int p5_ssl_ctx_ex_ssl_info_callback=0;
8
9 typedef struct ssl_ic_args_st {
10         SV *cb;
11         SV *arg;
12         } SSL_IC_ARGS;
13
14 static void p5_ssl_info_callback(ssl,mode,ret)
15 SSL *ssl;
16 int mode;
17 int ret;
18         {
19         int i;
20         SV *me,*cb;
21
22         me=(SV *)SSL_get_ex_data(ssl,p5_ssl_ex_ssl_ptr);
23         cb=(SV *)SSL_get_ex_data(ssl,p5_ssl_ex_ssl_info_callback);
24         if (cb == NULL)
25                 cb=(SV *)SSL_CTX_get_ex_data(
26                         SSL_get_SSL_CTX(ssl),p5_ssl_ctx_ex_ssl_info_callback);
27         if (cb != NULL)
28                 {
29                 dSP;
30
31                 PUSHMARK(sp);
32                 XPUSHs(me);
33                 XPUSHs(sv_2mortal(newSViv(mode)));
34                 XPUSHs(sv_2mortal(newSViv(ret)));
35                 PUTBACK;
36
37                 i=perl_call_sv(cb,G_DISCARD);
38                 }
39         else
40                 {
41                 croak("Internal error in SSL p5_ssl_info_callback");
42                 }
43         }
44
45 int boot_ssl()
46         {
47         p5_ssl_ex_ssl_ptr=              
48                 SSL_get_ex_new_index(0,"OpenSSL::SSL",ex_new,NULL,ex_cleanup);
49         p5_ssl_ex_ssl_info_callback=
50                 SSL_get_ex_new_index(0,"ssl_info_callback",NULL,NULL,
51                         ex_cleanup);
52         p5_ssl_ex_ssl_ctx_ptr=
53                 SSL_get_ex_new_index(0,"ssl_ctx_ptr",NULL,NULL,
54                         ex_cleanup);
55         p5_ssl_ctx_ex_ssl_info_callback=
56                 SSL_CTX_get_ex_new_index(0,"ssl_ctx_info_callback",NULL,NULL,
57                         ex_cleanup);
58         return(1);
59         }
60
61 MODULE =  OpenSSL::SSL  PACKAGE = OpenSSL::SSL::CTX PREFIX = p5_SSL_CTX_
62
63 VERSIONCHECK: DISABLE
64
65 void
66 p5_SSL_CTX_new(...)
67         PREINIT:
68                 SSL_METHOD *meth;
69                 SSL_CTX *ctx;
70                 char *method;
71         PPCODE:
72                 pr_name("p5_SSL_CTX_new");
73                 if ((items == 1) && SvPOK(ST(0)))
74                         method=SvPV(ST(0),na);
75                 else if ((items == 2) && SvPOK(ST(1)))
76                         method=SvPV(ST(1),na);
77                 else
78                         croak("Usage: OpenSSL::SSL_CTX::new(type)");
79                         
80                 if (strcmp(method,"SSLv3") == 0)
81                         meth=SSLv3_method();
82                 else if (strcmp(method,"SSLv3_client") == 0)
83                         meth=SSLv3_client_method();
84                 else if (strcmp(method,"SSLv3_server") == 0)
85                         meth=SSLv3_server_method();
86                 else if (strcmp(method,"SSLv23") == 0)
87                         meth=SSLv23_method();
88                 else if (strcmp(method,"SSLv23_client") == 0)
89                         meth=SSLv23_client_method();
90                 else if (strcmp(method,"SSLv23_server") == 0)
91                         meth=SSLv23_server_method();
92                 else if (strcmp(method,"SSLv2") == 0)
93                         meth=SSLv2_method();
94                 else if (strcmp(method,"SSLv2_client") == 0)
95                         meth=SSLv2_client_method();
96                 else if (strcmp(method,"SSLv2_server") == 0)
97                         meth=SSLv2_server_method();
98                 else
99                         {
100                         croak("Not passed a valid SSL method name, should be 'SSLv[23] [client|server]'");
101                         }
102                 EXTEND(sp,1);
103                 PUSHs(sv_newmortal());
104                 ctx=SSL_CTX_new(meth);
105                 sv_setref_pv(ST(0), "OpenSSL::SSL::CTX", (void*)ctx);
106
107 int
108 p5_SSL_CTX_use_PrivateKey_file(ctx,file,...)
109         SSL_CTX *ctx;
110         char *file;
111         PREINIT:
112                 int i=SSL_FILETYPE_PEM;
113                 char *ptr;
114         CODE:
115                 pr_name("p5_SSL_CTX_use_PrivateKey_file");
116                 if (items > 3)
117                         croak("OpenSSL::SSL::CTX::use_PrivateKey_file(ssl_ctx,file[,type])");
118                 if (items == 3)
119                         {
120                         ptr=SvPV(ST(2),na);
121                         if (strcmp(ptr,"der") == 0)
122                                 i=SSL_FILETYPE_ASN1;
123                         else
124                                 i=SSL_FILETYPE_PEM;
125                         }
126                 RETVAL=SSL_CTX_use_RSAPrivateKey_file(ctx,file,i);
127         OUTPUT:
128                 RETVAL
129
130 int
131 p5_SSL_CTX_set_options(ctx,...)
132         SSL_CTX *ctx;
133         PREINIT:
134                 int i;
135                 char *ptr;
136                 SV *sv;
137         CODE:
138                 pr_name("p5_SSL_CTX_set_options");
139
140                 for (i=1; i<items; i++)
141                         {
142                         if (!SvPOK(ST(i)))
143                                 croak("Usage: OpenSSL::SSL_CTX::set_options(ssl_ctx[,option,value]+)");
144                         ptr=SvPV(ST(i),na);
145                         if (strcmp(ptr,"-info_callback") == 0)
146                                 {
147                                 SSL_CTX_set_info_callback(ctx,
148                                         p5_ssl_info_callback);
149                                 sv=sv_mortalcopy(ST(i+1));
150                                 SvREFCNT_inc(sv);
151                                 SSL_CTX_set_ex_data(ctx,
152                                         p5_ssl_ctx_ex_ssl_info_callback,
153                                                 (char *)sv);
154                                 i++;
155                                 }
156                         else
157                                 {
158                                 croak("OpenSSL::SSL_CTX::set_options(): unknown option");
159                                 }
160                         }
161
162 void
163 p5_SSL_CTX_DESTROY(ctx)
164         SSL_CTX *ctx
165         PREINIT:
166                 SV *sv;
167         PPCODE:
168                 pr_name_d("p5_SSL_CTX_DESTROY",ctx->references);
169                 SSL_CTX_free(ctx);
170
171 MODULE =  OpenSSL::SSL  PACKAGE = OpenSSL::SSL PREFIX = p5_SSL_
172
173 void
174 p5_SSL_new(...)
175         PREINIT:
176                 SV *sv_ctx;
177                 SSL_CTX *ctx;
178                 SSL *ssl;
179                 int i;
180                 SV *arg;
181         PPCODE:
182                 pr_name("p5_SSL_new");
183                 if ((items != 1) && (items != 2))
184                         croak("Usage: OpenSSL::SSL::new(ssl_ctx)");
185                 if (sv_derived_from(ST(items-1),"OpenSSL::SSL::CTX"))
186                         {
187                         IV tmp = SvIV((SV*)SvRV(ST(items-1)));
188                         ctx=(SSL_CTX *)tmp;
189                         sv_ctx=ST(items-1);
190                         }
191                 else
192                         croak("ssl_ctx is not of type OpenSSL::SSL::CTX");
193
194                 EXTEND(sp,1);
195                 PUSHs(sv_newmortal());
196                 ssl=SSL_new(ctx);
197                 sv_setref_pv(ST(0), "OpenSSL::SSL", (void*)ssl);
198
199                 /* Now this is being a little hairy, we keep a pointer to
200                  * our perl reference.  We need to do a different one
201                  * to the one we return because it will have it's reference
202                  * count droped to 0 apon return and if we up its reference
203                  * count, it will never be DESTROYED */
204                 arg=newSVsv(ST(0));
205                 SSL_set_ex_data(ssl,p5_ssl_ex_ssl_ptr,(char *)arg);
206                 SvREFCNT_inc(sv_ctx);
207                 SSL_set_ex_data(ssl,p5_ssl_ex_ssl_ctx_ptr,(char *)sv_ctx);
208
209 int
210 p5_SSL_connect(ssl)
211         SSL *ssl;
212         CODE:
213                 RETVAL=SSL_connect(ssl);
214         OUTPUT:
215                 RETVAL
216
217 int
218 p5_SSL_accept(ssl)
219         SSL *ssl;
220         CODE:
221                 RETVAL=SSL_connect(ssl);
222         OUTPUT:
223                 RETVAL
224
225 int
226 p5_SSL_sysread(ssl,in,num, ...)
227         SSL *ssl;
228         SV *in;
229         int num;
230         PREINIT:
231                 int i,n,olen;
232                 int offset;
233                 char *p;
234         CODE:
235                 offset=0;
236                 if (!SvPOK(in))
237                         sv_setpvn(in,"",0);
238                 SvPV(in,olen);
239                 if (items > 3)
240                         {
241                         offset=SvIV(ST(3));
242                         if (offset < 0)
243                                 {
244                                 if (-offset > olen)
245                                         croak("Offset outside string");
246                                 offset+=olen;
247                                 }
248                         }
249                 if ((num+offset) > olen)
250                         {
251                         SvGROW(in,num+offset+1);
252                         p=SvPV(in,i);
253                         memset(&(p[olen]),0,(num+offset)-olen+1);
254                         }
255                 p=SvPV(in,n);
256
257                 i=SSL_read(ssl,p+offset,num);
258                 RETVAL=i;
259                 if (i <= 0) i=0;
260                 SvCUR_set(in,offset+i);
261         OUTPUT:
262                 RETVAL
263
264 int
265 p5_SSL_syswrite(ssl,in, ...)
266         SSL *ssl;
267         SV *in;
268         PREINIT:
269                 char *ptr;
270                 int len,in_len;
271                 int offset=0;
272                 int n;
273         CODE:
274                 ptr=SvPV(in,in_len);
275                 if (items > 2)
276                         {
277                         len=SvOK(ST(2))?SvIV(ST(2)):in_len;
278                         if (items > 3)
279                                 {
280                                 offset=SvIV(ST(3));
281                                 if (offset < 0)
282                                         {
283                                         if (-offset > in_len)
284                                                 croak("Offset outside string");
285                                         offset+=in_len;
286                                         }
287                                 else if ((offset >= in_len) && (in_len > 0))
288                                         croak("Offset outside string");
289                                 }
290                         if (len >= (in_len-offset))
291                                 len=in_len-offset;
292                         }
293                 else
294                         len=in_len;
295
296                 RETVAL=SSL_write(ssl,ptr+offset,len);
297         OUTPUT:
298                 RETVAL
299
300 void
301 p5_SSL_set_bio(ssl,bio)
302         SSL *ssl;
303         BIO *bio;
304         CODE:
305                 bio->references++;
306                 SSL_set_bio(ssl,bio,bio);
307
308 int
309 p5_SSL_set_options(ssl,...)
310         SSL *ssl;
311         PREINIT:
312                 int i;
313                 char *ptr;
314                 SV *sv;
315         CODE:
316                 pr_name("p5_SSL_set_options");
317
318                 for (i=1; i<items; i++)
319                         {
320                         if (!SvPOK(ST(i)))
321                                 croak("Usage: OpenSSL::SSL::set_options(ssl[,option,value]+)");
322                         ptr=SvPV(ST(i),na);
323                         if (strcmp(ptr,"-info_callback") == 0)
324                                 {
325                                 SSL_set_info_callback(ssl,
326                                         p5_ssl_info_callback);
327                                 sv=sv_mortalcopy(ST(i+1));
328                                 SvREFCNT_inc(sv);
329                                 SSL_set_ex_data(ssl,
330                                         p5_ssl_ex_ssl_info_callback,(char *)sv);
331                                 i++;
332                                 }
333                         else if (strcmp(ptr,"-connect_state") == 0)
334                                 {
335                                 SSL_set_connect_state(ssl);
336                                 }
337                         else if (strcmp(ptr,"-accept_state") == 0)
338                                 {
339                                 SSL_set_accept_state(ssl);
340                                 }
341                         else
342                                 {
343                                 croak("OpenSSL::SSL::set_options(): unknown option");
344                                 }
345                         }
346
347 void
348 p5_SSL_state(ssl)
349         SSL *ssl;
350         PREINIT:
351                 int state;
352         PPCODE:
353                 pr_name("p5_SSL_state");
354                 EXTEND(sp,1);
355                 PUSHs(sv_newmortal());
356                 state=SSL_state(ssl);
357                 sv_setpv(ST(0),SSL_state_string_long(ssl));
358                 sv_setiv(ST(0),state);
359                 SvPOK_on(ST(0));
360
361 void
362 p5_SSL_DESTROY(ssl)
363         SSL *ssl;
364         CODE:
365         pr_name_dd("p5_SSL_DESTROY",ssl->references,ssl->ctx->references);
366         fprintf(stderr,"SSL_DESTROY %d\n",ssl->references);
367         SSL_free(ssl);
368
369 int
370 p5_SSL_references(ssl)
371         SSL *ssl;
372         CODE:
373                 RETVAL=ssl->references;
374         OUTPUT:
375                 RETVAL
376
377 int
378 p5_SSL_do_handshake(ssl)
379         SSL *ssl;
380         CODE:
381                 RETVAL=SSL_do_handshake(ssl);
382         OUTPUT:
383                 RETVAL
384
385 int
386 p5_SSL_renegotiate(ssl)
387         SSL *ssl;
388         CODE:
389                 RETVAL=SSL_renegotiate(ssl);
390         OUTPUT:
391                 RETVAL
392
393 int
394 p5_SSL_shutdown(ssl)
395         SSL *ssl;
396         CODE:
397                 RETVAL=SSL_shutdown(ssl);
398         OUTPUT:
399                 RETVAL
400
401 char *
402 p5_SSL_get_version(ssl)
403         SSL *ssl;
404         CODE:
405                 RETVAL=SSL_get_version(ssl);
406         OUTPUT:
407                 RETVAL
408
409 SSL_CIPHER *
410 p5_SSL_get_current_cipher(ssl)
411         SSL *ssl;
412         CODE:
413                 RETVAL=SSL_get_current_cipher(ssl);
414         OUTPUT:
415                 RETVAL
416
417 X509 *
418 p5_SSL_get_peer_certificate(ssl)
419         SSL *ssl
420         CODE:
421                 RETVAL=SSL_get_peer_certificate(ssl);
422         OUTPUT:
423                 RETVAL
424
425 MODULE =  OpenSSL::SSL  PACKAGE = OpenSSL::SSL::CIPHER PREFIX = p5_SSL_CIPHER_
426
427 int
428 p5_SSL_CIPHER_get_bits(sc)
429         SSL_CIPHER *sc
430         PREINIT:
431                 int i,ret;
432         PPCODE:
433                 EXTEND(sp,2);
434                 PUSHs(sv_newmortal());
435                 PUSHs(sv_newmortal());
436                 ret=SSL_CIPHER_get_bits(sc,&i);
437                 sv_setiv(ST(0),(IV)ret);
438                 sv_setiv(ST(1),(IV)i);
439
440 char *
441 p5_SSL_CIPHER_get_version(sc)
442         SSL_CIPHER *sc
443         CODE:
444                 RETVAL=SSL_CIPHER_get_version(sc);
445         OUTPUT:
446                 RETVAL
447
448 char *
449 p5_SSL_CIPHER_get_name(sc)
450         SSL_CIPHER *sc
451         CODE:
452                 RETVAL=SSL_CIPHER_get_name(sc);
453         OUTPUT:
454                 RETVAL
455
456 MODULE =  OpenSSL::SSL  PACKAGE = OpenSSL::BIO PREFIX = p5_BIO_
457
458 void
459 p5_BIO_get_ssl(bio)
460         BIO *bio;
461         PREINIT:
462                 SSL *ssl;
463                 SV *ret;
464                 int i;
465         PPCODE:
466                 if ((i=BIO_get_ssl(bio,&ssl)) > 0)
467                         {
468                         ret=(SV *)SSL_get_ex_data(ssl,p5_ssl_ex_ssl_ptr);
469                         ret=sv_mortalcopy(ret);
470                         }
471                 else
472                         ret= &sv_undef;
473                 EXTEND(sp,1);
474                 PUSHs(ret);
475