polarssl 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ void Init_ctr_drbg();
@@ -0,0 +1,72 @@
1
+ /*
2
+ * Wrapping code for the PolarSSL::Entropy class.
3
+ *
4
+ * Copyright (C) 2013 Michiel Sikkes
5
+ *
6
+ * This file is part of polarssl-ruby (http://github.com/michiels/polarssl-ruby)
7
+ *
8
+ * All rights reserved.
9
+ *
10
+ * This program is free software: you can redistribute it and/or modify
11
+ * it under the terms of the GNU Lesser General Public License as published by
12
+ * the Free Software Foundation, either version 3 of the License, or
13
+ * (at your option) any later version.
14
+ *
15
+ * This program is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ * GNU Lesser General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU Lesser General Public License
21
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
22
+ */
23
+
24
+ #include "polarssl.h"
25
+ #include "polarssl/entropy.h"
26
+ #include "ruby.h"
27
+
28
+ static VALUE R_entropy_allocate();
29
+ static VALUE R_entropy_initialize();
30
+ static VALUE R_entropy_gather();
31
+
32
+ void Init_entropy()
33
+ {
34
+ VALUE cEntropy = rb_define_class_under( rb_mPolarSSL, "Entropy", rb_cObject );
35
+
36
+ rb_define_alloc_func( cEntropy, R_entropy_allocate );
37
+ rb_define_method( cEntropy, "initialize", R_entropy_initialize, 0 );
38
+ rb_define_method( cEntropy, "gather", R_entropy_gather, 0 );
39
+ }
40
+
41
+ static VALUE R_entropy_allocate( VALUE klass )
42
+ {
43
+ entropy_context *entropy;
44
+
45
+ return Data_Make_Struct( klass, entropy_context, 0, -1, entropy );
46
+ }
47
+
48
+ static VALUE R_entropy_initialize( VALUE self )
49
+ {
50
+ entropy_context *entropy;
51
+
52
+ Data_Get_Struct( self, entropy_context, entropy );
53
+ entropy_init( entropy );
54
+
55
+ return self;
56
+ }
57
+
58
+ static VALUE R_entropy_gather(VALUE self)
59
+ {
60
+ entropy_context *entropy;
61
+ VALUE ret;
62
+
63
+ Data_Get_Struct( self, entropy_context, entropy );
64
+
65
+ if( entropy_gather( entropy ) == 0 ) {
66
+ ret = Qtrue;
67
+ } else {
68
+ ret = Qfalse;
69
+ }
70
+
71
+ return ret;
72
+ }
@@ -0,0 +1 @@
1
+ void Init_entropy();
@@ -0,0 +1,13 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS = "-g -Wall -Wdeclaration-after-statement " + $CFLAGS
4
+
5
+ unless find_header('polarssl/entropy.h')
6
+ abort "libpolarssl is missing. please install libpolarssl"
7
+ end
8
+
9
+ unless find_library('polarssl', 'entropy_init')
10
+ abort "libpolarssl is missing. please install libpolarssl"
11
+ end
12
+
13
+ create_makefile('polarssl/polarssl')
@@ -0,0 +1,39 @@
1
+ /*
2
+ * Wrapping code and entrypoint for the PolarSSL module.
3
+ *
4
+ * Copyright (C) 2013 Michiel Sikkes
5
+ *
6
+ * This file is part of polarssl-ruby (http://github.com/michiels/polarssl-ruby)
7
+ *
8
+ * All rights reserved.
9
+ *
10
+ * This program is free software: you can redistribute it and/or modify
11
+ * it under the terms of the GNU Lesser General Public License as published by
12
+ * the Free Software Foundation, either version 3 of the License, or
13
+ * (at your option) any later version.
14
+ *
15
+ * This program is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ * GNU Lesser General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU Lesser General Public License
21
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
22
+ */
23
+
24
+
25
+ #include "ruby.h"
26
+ #include "entropy.h"
27
+ #include "ctr_drbg.h"
28
+ #include "ssl.h"
29
+
30
+ VALUE rb_mPolarSSL;
31
+
32
+ void Init_polarssl()
33
+ {
34
+ rb_mPolarSSL = rb_define_module( "PolarSSL" );
35
+
36
+ Init_entropy( );
37
+ Init_ctr_drbg( );
38
+ Init_ssl( );
39
+ }
@@ -0,0 +1,3 @@
1
+ #include "ruby.h"
2
+
3
+ extern VALUE rb_mPolarSSL;
@@ -0,0 +1,415 @@
1
+ /*
2
+ * Wrapping code for the PolarSSL::SSL class.
3
+ *
4
+ * Copyright (C) 2013 Michiel Sikkes
5
+ *
6
+ * This file is part of polarssl-ruby (http://github.com/michiels/polarssl-ruby)
7
+ *
8
+ * All rights reserved.
9
+ *
10
+ * This program is free software: you can redistribute it and/or modify
11
+ * it under the terms of the GNU Lesser General Public License as published by
12
+ * the Free Software Foundation, either version 3 of the License, or
13
+ * (at your option) any later version.
14
+ *
15
+ * This program is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ * GNU Lesser General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU Lesser General Public License
21
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
22
+ */
23
+
24
+
25
+ #include "polarssl.h"
26
+ #include "polarssl/ssl.h"
27
+ #include "polarssl/ctr_drbg.h"
28
+ #include "polarssl/net.h"
29
+ #include "polarssl/version.h"
30
+ #include "ruby/io.h"
31
+
32
+ VALUE e_MallocFailed;
33
+ VALUE e_NetWantRead;
34
+ VALUE e_NetWantWrite;
35
+ VALUE e_SSLError;
36
+
37
+ static VALUE R_ssl_allocate();
38
+ static VALUE R_ssl_set_endpoint();
39
+ static VALUE R_ssl_set_authmode();
40
+ static VALUE R_ssl_set_rng();
41
+ static VALUE R_ssl_set_socket();
42
+ static VALUE R_ssl_handshake();
43
+ static VALUE R_ssl_write();
44
+ static VALUE R_ssl_read();
45
+ static VALUE R_ssl_close_notify();
46
+ static VALUE R_close();
47
+
48
+ void my_debug( void *ctx, int level, const char *str )
49
+ {
50
+ fprintf( (FILE *)ctx, "%s", str );
51
+ }
52
+
53
+ void Init_ssl(void)
54
+ {
55
+ /* Document-class: PolarSSL::SSL
56
+ * This class is the base for doing SSL communication over a socket.
57
+ *
58
+ * == Sample
59
+ *
60
+ * require 'polarssl'
61
+ *
62
+ * socket = TCPSocket.new('polarssl.org', 443)
63
+ *
64
+ * entropy = PolarSSL::Entropy.new
65
+ * ctr_drbg = PolarSSL::CtrDrbg.new(entropy)
66
+ * ssl = PolarSSL::SSL.new
67
+ *
68
+ * ssl.set_endpoint(PolarSSL::SSL::SSL_IS_CLIENT)
69
+ * ssl.set_authmode(PolarSSL::SSL::SSL_VERIFY_NONE)
70
+ * ssl.set_rng(ctr_drbg)
71
+ *
72
+ * ssl.set_socket(socket)
73
+ *
74
+ * ssl.handshake
75
+ *
76
+ * ssl.write("GET / HTTP/1.0\r\nHost: polarssl.org\r\n\r\n")
77
+ *
78
+ * while chunk = ssl.read(1024)
79
+ * response << chunk
80
+ * end
81
+ *
82
+ * puts response
83
+ *
84
+ * ssl.close_notify
85
+ *
86
+ * socket.close
87
+ *
88
+ * ssl.close
89
+ */
90
+ VALUE cSSL = rb_define_class_under( rb_mPolarSSL, "SSL", rb_path2class("Object") );
91
+
92
+ /* Document-class: PolarSSL::MallocFailed
93
+ * Raised when not enough memory can be allocated for initializing the ssl context with ssl_init();
94
+ */
95
+ e_MallocFailed = rb_define_class_under( rb_mPolarSSL, "MallocFailed", rb_path2class("StandardError") );
96
+
97
+ /* Document-class: PolarSSL::NetWantRead
98
+ * Raised when the ssl connection expects a read.
99
+ */
100
+ e_NetWantRead = rb_define_class_under( rb_mPolarSSL, "NetWantRead", rb_eStandardError );
101
+
102
+ /* Document-class: PolarSSL::NetWantWrite
103
+ * Raised when the ssl connection expects a write.
104
+ */
105
+ e_NetWantWrite = rb_define_class_under( rb_mPolarSSL, "NetWantWrite", rb_eStandardError );
106
+
107
+ /* Document-class: PolarSSL::SSL::Error
108
+ * Raised when an SSL error occurs.
109
+ */
110
+ e_SSLError = rb_define_class_under( cSSL, "Error", rb_eRuntimeError );
111
+
112
+ /*
113
+ * 0: Endpoint mode for acting as a client.
114
+ */
115
+ rb_define_const( cSSL, "SSL_IS_CLIENT", INT2NUM( SSL_IS_CLIENT ) );
116
+
117
+ /*
118
+ * 0: Certificate verification mode for doing no verification.
119
+ */
120
+ rb_define_const( cSSL, "SSL_VERIFY_NONE", INT2NUM( SSL_VERIFY_NONE ) );
121
+
122
+ /*
123
+ * 1: Certificate verification mode for optional verification.
124
+ */
125
+ rb_define_const( cSSL, "SSL_VERIFY_OPTIONAL", INT2NUM( SSL_VERIFY_OPTIONAL ) );
126
+
127
+ /*
128
+ * 2: Certificate verification mode for having required verification.
129
+ */
130
+ rb_define_const( cSSL, "SSL_VERIFY_REQUIRED", INT2NUM( SSL_VERIFY_REQUIRED ) );
131
+
132
+ rb_define_alloc_func( cSSL, R_ssl_allocate );
133
+ rb_define_method( cSSL, "set_endpoint", R_ssl_set_endpoint, 1 );
134
+ rb_define_method( cSSL, "set_authmode", R_ssl_set_authmode, 1 );
135
+ rb_define_method( cSSL, "set_rng", R_ssl_set_rng, 1 );
136
+ rb_define_method( cSSL, "set_socket", R_ssl_set_socket, 1);
137
+ rb_define_method( cSSL, "handshake", R_ssl_handshake, 0 );
138
+ rb_define_method( cSSL, "write", R_ssl_write, 1 );
139
+ rb_define_method( cSSL, "read", R_ssl_read, 1 );
140
+ rb_define_method( cSSL, "close_notify", R_ssl_close_notify, 0 );
141
+ rb_define_method( cSSL, "close", R_close, 0 );
142
+ }
143
+
144
+ static VALUE R_ssl_allocate( VALUE klass )
145
+ {
146
+ ssl_context *ssl;
147
+ int ret;
148
+
149
+ #if POLARSSL_VERSION_MAJOR == 1 && POLARSSL_VERSION_MINOR == 1
150
+ ssl_session *ssn;
151
+ #endif
152
+
153
+ ssl = ALLOC( ssl_context );
154
+
155
+ ret = ssl_init( ssl );
156
+
157
+ if ( ret == POLARSSL_ERR_SSL_MALLOC_FAILED )
158
+ rb_raise(e_MallocFailed, "ssl_init() memory allocation failed.");
159
+
160
+ #if POLARSSL_VERSION_MAJOR == 1 && POLARSSL_VERSION_MINOR == 1
161
+ ssn = ALLOC( ssl_session );
162
+ ssl_set_session( ssl, 0, 600, ssn );
163
+ ssl_set_ciphersuites( ssl, ssl_default_ciphersuites );
164
+ #endif
165
+
166
+ // ssl_set_dbg(ssl, my_debug, stdout);
167
+
168
+ return Data_Wrap_Struct( klass, 0, ssl_free, ssl );
169
+ }
170
+
171
+ /*
172
+ * call-seq:
173
+ * set_endpoint( endpoint_mode )
174
+ *
175
+ * Sets the endpoint mode for the current SSL connection to act as a server or a client.
176
+ * Possible values are:
177
+ *
178
+ * * PolarSSL::SSL::SSL_IS_CLIENT
179
+ */
180
+ static VALUE R_ssl_set_endpoint( VALUE self, VALUE endpoint_mode )
181
+ {
182
+ ssl_context *ssl;
183
+
184
+ Check_Type( endpoint_mode, T_FIXNUM );
185
+
186
+ Data_Get_Struct( self, ssl_context, ssl );
187
+
188
+ ssl_set_endpoint( ssl, NUM2INT( endpoint_mode ) );
189
+
190
+ return Qtrue;
191
+ }
192
+
193
+ /*
194
+ * call-seq:
195
+ * set_authmode( authentication_mode )
196
+ *
197
+ * Sets the certificate verification mode for the SSL connection.
198
+ * Possible values are:
199
+ *
200
+ * * PolarSSL::SSL::SSL_VERIFY_NONE
201
+ * * PolarSSL::SSL::SSL_VERIFY_OPTIONAL
202
+ * * PolarSSL::SSL::SSL_VERIFY_REQUIRED
203
+ */
204
+ static VALUE R_ssl_set_authmode( VALUE self, VALUE authmode )
205
+ {
206
+ ssl_context *ssl;
207
+
208
+ Check_Type( authmode, T_FIXNUM );
209
+
210
+ Data_Get_Struct( self, ssl_context, ssl );
211
+
212
+ ssl_set_authmode( ssl, NUM2INT( authmode ) );
213
+
214
+ return Qtrue;
215
+ }
216
+
217
+ /*
218
+ * call-seq:
219
+ * set_rng( random_number_generator )
220
+ *
221
+ * Sets the random number generator to be used for this connection. You need to use
222
+ * an instance of PolarSSL::CtrDrbg for this. Example:
223
+ *
224
+ * entropy = PolarSSL::Entropy.new
225
+ * ctr_drbg = PolarSSL::CtrDrbg.new(entropy)
226
+ *
227
+ * ssl = PolarSSL::SSL.new
228
+ * ssl.set_rng(ctr_drbg)
229
+ *
230
+ * # other ssl connection settings and usage
231
+ *
232
+ */
233
+ static VALUE R_ssl_set_rng( VALUE self, VALUE rng )
234
+ {
235
+ ssl_context *ssl;
236
+ ctr_drbg_context *ctr_drbg;
237
+
238
+ Check_Type( rng, T_DATA );
239
+
240
+ Data_Get_Struct( self, ssl_context, ssl );
241
+ Data_Get_Struct( rng, ctr_drbg_context, ctr_drbg );
242
+
243
+ ssl_set_rng( ssl, ctr_drbg_random, ctr_drbg );
244
+
245
+ return Qtrue;
246
+ }
247
+
248
+ /*
249
+ * call-seq:
250
+ * set_socket( socket )
251
+ *
252
+ * Set the TCPSocket to be used for this SSL connection. Example:
253
+ *
254
+ * socket = TCPSocket.new('polarssl.org', 443)
255
+ *
256
+ * ssl = PolarSSL::SSL.new
257
+ * ssl.set_socket(socket)
258
+ *
259
+ */
260
+ static VALUE R_ssl_set_socket( VALUE self, VALUE socket )
261
+ {
262
+ ssl_context *ssl;
263
+ rb_io_t *fptr;
264
+
265
+ Check_Type( socket, T_FILE );
266
+
267
+ Data_Get_Struct( self, ssl_context, ssl );
268
+
269
+ GetOpenFile( socket, fptr );
270
+
271
+ ssl_set_bio( ssl, net_recv, &fptr->fd, net_send, &fptr->fd );
272
+
273
+ return Qtrue;
274
+ }
275
+
276
+ /*
277
+ * call-seq:
278
+ * handshake() -> true or exception
279
+ *
280
+ * Initiates SSL handshake. When something goes wrong, raises one of:
281
+ *
282
+ * * PolarSSL::NetWantRead,
283
+ * * PolarSSL::NetWantWrite or
284
+ * * PolarSSL::SSL::Error
285
+ */
286
+ static VALUE R_ssl_handshake(VALUE self)
287
+ {
288
+ ssl_context *ssl;
289
+ int ret;
290
+
291
+ Data_Get_Struct( self, ssl_context, ssl );
292
+
293
+ ret = ssl_handshake( ssl );
294
+
295
+ if ( ret < 0 )
296
+ {
297
+ if ( ret == POLARSSL_ERR_NET_WANT_READ )
298
+ {
299
+ rb_raise( e_NetWantRead, "ssl_handshake() returned POLARSSL_ERR_NET_WANT_READ" );
300
+ }
301
+ else if ( ret == POLARSSL_ERR_NET_WANT_WRITE )
302
+ {
303
+ rb_raise( e_NetWantWrite, "ssl_handshake() returned POLARSSL_ERR_NET_WANT_WRITE" );
304
+ }
305
+ else
306
+ {
307
+ rb_raise( e_SSLError, "-0x%x", -ret );
308
+ }
309
+ }
310
+ else
311
+ {
312
+ return Qtrue;
313
+ }
314
+ }
315
+
316
+ /*
317
+ * call-seq:
318
+ * write( string ) -> true or raises
319
+ *
320
+ * Writes to the SSL connection or raises PolarSSL::SSL::Error.
321
+ */
322
+ static VALUE R_ssl_write( VALUE self, VALUE string )
323
+ {
324
+ ssl_context *ssl;
325
+ char *buffer;
326
+ int ret;
327
+
328
+ Check_Type( string, T_STRING );
329
+
330
+ Data_Get_Struct( self, ssl_context, ssl );
331
+
332
+ buffer = RSTRING_PTR( string );
333
+
334
+ ret = ssl_write( ssl, (const unsigned char *) buffer, RSTRING_LEN( string ) );
335
+
336
+ if ( ret < 0 )
337
+ rb_raise( e_SSLError, "-0x%x", -ret );
338
+
339
+ return Qtrue;
340
+ }
341
+
342
+ /*
343
+ * call-seq:
344
+ * read( length ) -> string or raises
345
+ *
346
+ * Reads +length+ bytes from the SSL connection or raises PolarSSL::SSL::Error.
347
+ */
348
+ static VALUE R_ssl_read( VALUE self, VALUE length )
349
+ {
350
+ ssl_context *ssl;
351
+ VALUE result;
352
+ int buffer_size = NUM2INT( length );
353
+ unsigned char buffer[buffer_size];
354
+ int length_to_read;
355
+ int length_read;
356
+
357
+ Check_Type( length, T_FIXNUM );
358
+
359
+ Data_Get_Struct( self, ssl_context, ssl );
360
+
361
+ length_to_read = sizeof( buffer ) - 1;
362
+ length_read = ssl_read( ssl, buffer, length_to_read );
363
+
364
+ if ( length_read == 0 || length_read == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY )
365
+ {
366
+ result = Qnil;
367
+ }
368
+ else if (length_read < 0)
369
+ {
370
+ rb_raise( e_SSLError, "-0x%x", -length_read );
371
+ }
372
+ else
373
+ {
374
+ result = rb_str_new2( (char *)buffer );
375
+ }
376
+
377
+ return result;
378
+ }
379
+
380
+ /*
381
+ * call-seq:
382
+ * close_notify() -> true or raises
383
+ *
384
+ * Notifies the peer to close the connection. true or raises PolarSSL::SSL::Error
385
+ */
386
+ static VALUE R_ssl_close_notify( VALUE self )
387
+ {
388
+ ssl_context *ssl;
389
+ int ret;
390
+ Data_Get_Struct( self, ssl_context, ssl );
391
+
392
+ ret = ssl_close_notify( ssl );
393
+
394
+ if (ret < 0)
395
+ rb_raise( e_SSLError, "-0x%x", -ret );
396
+
397
+ return Qtrue;
398
+ }
399
+
400
+ /*
401
+ * call-seq:
402
+ * close() -> true
403
+ *
404
+ * Final method to be called when done using the SSL connection. This immediately frees
405
+ * any SSL data in the memory instead of waiting for the Ruby garbage collector.
406
+ */
407
+ static VALUE R_close( VALUE self )
408
+ {
409
+ ssl_context *ssl;
410
+ Data_Get_Struct( self, ssl_context, ssl );
411
+
412
+ memset( ssl, 0, sizeof( ssl_context ) );
413
+
414
+ return Qtrue;
415
+ }