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