]>
Commit | Line | Data |
---|---|---|
8073036d RE |
1 | |
2 | #include "openssl.h" | |
58964a49 RE |
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= | |
8073036d | 48 | SSL_get_ex_new_index(0,"OpenSSL::SSL",ex_new,NULL,ex_cleanup); |
58964a49 RE |
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 | ||
8073036d | 61 | MODULE = OpenSSL::SSL PACKAGE = OpenSSL::SSL::CTX PREFIX = p5_SSL_CTX_ |
58964a49 | 62 | |
49b81422 | 63 | PROTOTYPES: ENABLE |
58964a49 RE |
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 | |
49b81422 | 79 | croak("Usage: OpenSSL::SSL::CTX::new(type)"); |
58964a49 RE |
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(); | |
49b81422 UM |
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(); | |
58964a49 RE |
105 | else |
106 | { | |
49b81422 | 107 | croak("Not a valid SSL method name, should be 'SSLv[23] [client|server]'"); |
58964a49 RE |
108 | } |
109 | EXTEND(sp,1); | |
110 | PUSHs(sv_newmortal()); | |
111 | ctx=SSL_CTX_new(meth); | |
8073036d | 112 | sv_setref_pv(ST(0), "OpenSSL::SSL::CTX", (void*)ctx); |
58964a49 RE |
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) | |
8073036d | 124 | croak("OpenSSL::SSL::CTX::use_PrivateKey_file(ssl_ctx,file[,type])"); |
58964a49 RE |
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))) | |
8073036d | 150 | croak("Usage: OpenSSL::SSL_CTX::set_options(ssl_ctx[,option,value]+)"); |
58964a49 RE |
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 | { | |
8073036d | 165 | croak("OpenSSL::SSL_CTX::set_options(): unknown option"); |
58964a49 RE |
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 | ||
8073036d | 178 | MODULE = OpenSSL::SSL PACKAGE = OpenSSL::SSL PREFIX = p5_SSL_ |
58964a49 RE |
179 | |
180 | void | |
181 | p5_SSL_new(...) | |
182 | PREINIT: | |
183 | SV *sv_ctx; | |
184 | SSL_CTX *ctx; | |
185 | SSL *ssl; | |
58964a49 RE |
186 | SV *arg; |
187 | PPCODE: | |
188 | pr_name("p5_SSL_new"); | |
189 | if ((items != 1) && (items != 2)) | |
8073036d RE |
190 | croak("Usage: OpenSSL::SSL::new(ssl_ctx)"); |
191 | if (sv_derived_from(ST(items-1),"OpenSSL::SSL::CTX")) | |
58964a49 RE |
192 | { |
193 | IV tmp = SvIV((SV*)SvRV(ST(items-1))); | |
194 | ctx=(SSL_CTX *)tmp; | |
195 | sv_ctx=ST(items-1); | |
196 | } | |
197 | else | |
8073036d | 198 | croak("ssl_ctx is not of type OpenSSL::SSL::CTX"); |
58964a49 RE |
199 | |
200 | EXTEND(sp,1); | |
201 | PUSHs(sv_newmortal()); | |
202 | ssl=SSL_new(ctx); | |
8073036d | 203 | sv_setref_pv(ST(0), "OpenSSL::SSL", (void*)ssl); |
58964a49 RE |
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 | |
49b81422 UM |
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 | |
58964a49 RE |
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) | |
dfeab068 | 251 | croak("Offset outside string"); |
58964a49 RE |
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))) | |
8073036d | 327 | croak("Usage: OpenSSL::SSL::set_options(ssl[,option,value]+)"); |
58964a49 RE |
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 | { | |
8073036d | 349 | croak("OpenSSL::SSL::set_options(): unknown option"); |
58964a49 RE |
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); | |
49b81422 | 372 | #ifdef DEBUG |
58964a49 | 373 | fprintf(stderr,"SSL_DESTROY %d\n",ssl->references); |
49b81422 | 374 | #endif |
58964a49 RE |
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 | ||
8073036d | 433 | MODULE = OpenSSL::SSL PACKAGE = OpenSSL::SSL::CIPHER PREFIX = p5_SSL_CIPHER_ |
58964a49 RE |
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 | ||
8073036d | 464 | MODULE = OpenSSL::SSL PACKAGE = OpenSSL::BIO PREFIX = p5_BIO_ |
58964a49 RE |
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 |