mbedtls 0.1.0.beta1

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