7
7
#include "dyn_buff.h"
8
8
#include "native.h"
9
9
10
+ struct Datagram {
11
+ UnifexPayload * packet ;
12
+ struct Datagram * next ;
13
+ };
14
+
10
15
static void ssl_info_cb (const SSL * ssl , int where , int ret );
11
16
static int verify_cb (int preverify_ok , X509_STORE_CTX * ctx );
12
- static int read_pending_data (UnifexPayload * gen_packets , int pending_data_len ,
13
- State * state );
17
+ static void read_pending_data (UnifexPayload * * * payloads , int * size ,
18
+ State * state );
14
19
static void cert_to_payload (UnifexEnv * env , X509 * x509 , UnifexPayload * payload );
15
20
static void pkey_to_payload (UnifexEnv * env , EVP_PKEY * pkey ,
16
21
UnifexPayload * payload );
@@ -21,6 +26,7 @@ UNIFEX_TERM handle_regular_read(State *state, char data[], int ret);
21
26
UNIFEX_TERM handle_read_error (State * state , int ret );
22
27
UNIFEX_TERM handle_handshake_in_progress (State * state , int ret );
23
28
UNIFEX_TERM handle_handshake_finished (State * state );
29
+ static UnifexPayload * * to_payload_array (struct Datagram * dgram_list , int len );
24
30
25
31
int handle_load (UnifexEnv * env , void * * priv_data ) {
26
32
UNIFEX_UNUSED (env );
@@ -242,23 +248,19 @@ UNIFEX_TERM do_handshake(UnifexEnv *env, State *state) {
242
248
if (pending_data_len > 0 ) {
243
249
DEBUG ("WBIO: pending data: %ld bytes" , pending_data_len );
244
250
245
- char * pending_data = (char * )malloc (pending_data_len * sizeof (char ));
246
- memset (pending_data , 0 , pending_data_len );
247
- BIO * wbio = SSL_get_wbio (state -> ssl );
248
- int read_bytes = BIO_read (wbio , pending_data , pending_data_len );
249
- if (read_bytes <= 0 ) {
250
- DEBUG ("WBIO: read error" );
251
+ UnifexPayload * * gen_packets ;
252
+ int gen_packets_size ;
253
+ read_pending_data (& gen_packets , & gen_packets_size , state );
254
+
255
+ if (gen_packets == NULL ) {
251
256
return unifex_raise (state -> env , "Handshake failed: write BIO error" );
252
257
} else {
253
- DEBUG ("WBIO: read: %d bytes" , read_bytes );
254
- UnifexPayload gen_packets ;
255
- unifex_payload_alloc (env , UNIFEX_PAYLOAD_BINARY , pending_data_len ,
256
- & gen_packets );
257
- memcpy (gen_packets .data , pending_data , pending_data_len );
258
- gen_packets .size = (unsigned int )pending_data_len ;
259
258
int timeout = get_timeout (state -> ssl );
260
- UNIFEX_TERM res_term = do_handshake_result (env , & gen_packets , timeout );
261
- unifex_payload_release (& gen_packets );
259
+ UNIFEX_TERM res_term =
260
+ do_handshake_result (env , gen_packets , gen_packets_size , timeout );
261
+ for (int i = 0 ; i < gen_packets_size ; i ++ ) {
262
+ unifex_payload_release (gen_packets [i ]);
263
+ }
262
264
return res_term ;
263
265
}
264
266
}
@@ -285,19 +287,21 @@ UNIFEX_TERM write_data(UnifexEnv *env, State *state, UnifexPayload *payload) {
285
287
return unifex_raise (env , "No data to read from BIO after writing" );
286
288
}
287
289
288
- UnifexPayload res_payload ;
289
- unifex_payload_alloc (env , UNIFEX_PAYLOAD_BINARY , pending_data_len , & res_payload );
290
-
291
- int read_bytes = BIO_read (wbio , res_payload .data , pending_data_len );
292
- if (read_bytes <= 0 || (size_t ) read_bytes != pending_data_len ) {
290
+ UnifexPayload * * gen_packets = NULL ;
291
+ int gen_packets_size = 0 ;
292
+ read_pending_data (& gen_packets , & gen_packets_size , state );
293
+ if (gen_packets == NULL ) {
293
294
DEBUG ("Unable to read data from BIO after writing" );
294
295
return unifex_raise (env , "Unable to read data from BIO after writing" );
295
296
}
296
297
297
- DEBUG ("Wrote %d bytes of data" , read_bytes );
298
- res_payload .size = (unsigned int ) pending_data_len ;
299
- UNIFEX_TERM res_term = write_data_result_ok (env , & res_payload );
300
- unifex_payload_release (& res_payload );
298
+ UNIFEX_TERM res_term =
299
+ write_data_result_ok (env , gen_packets , gen_packets_size );
300
+
301
+ for (int i = 0 ; i < gen_packets_size ; i ++ ) {
302
+ unifex_payload_release (gen_packets [i ]);
303
+ }
304
+
301
305
return res_term ;
302
306
}
303
307
@@ -333,12 +337,14 @@ UNIFEX_TERM handle_data(UnifexEnv *env, State *state, UnifexPayload *payload) {
333
337
334
338
UNIFEX_TERM handle_regular_read (State * state , char data [], int ret ) {
335
339
if (ret > 0 ) {
336
- UnifexPayload packets ;
337
- unifex_payload_alloc (state -> env , UNIFEX_PAYLOAD_BINARY , ret , & packets );
338
- memcpy (packets .data , data , ret );
339
- packets .size = (unsigned int )ret ;
340
- UNIFEX_TERM res_term = handle_data_result_ok (state -> env , & packets );
341
- unifex_payload_release (& packets );
340
+ UnifexPayload * * packets = calloc (1 , sizeof (UnifexPayload * ));
341
+ UnifexPayload packet ;
342
+ packets [0 ] = & packet ;
343
+ unifex_payload_alloc (state -> env , UNIFEX_PAYLOAD_BINARY , ret , packets [0 ]);
344
+ memcpy (packets [0 ]-> data , data , ret );
345
+ packets [0 ]-> size = (unsigned int )ret ;
346
+ UNIFEX_TERM res_term = handle_data_result_ok (state -> env , packets , 1 );
347
+ unifex_payload_release (packets [0 ]);
342
348
return res_term ;
343
349
}
344
350
@@ -369,7 +375,8 @@ UNIFEX_TERM handle_read_error(State *state, int ret) {
369
375
370
376
UNIFEX_TERM handle_handshake_finished (State * state ) {
371
377
UNIFEX_TERM res_term ;
372
- UnifexPayload gen_packets ;
378
+ UnifexPayload * * gen_packets = NULL ;
379
+ int gen_packets_size = 0 ;
373
380
KeyingMaterial * keying_material = export_keying_material (state -> ssl );
374
381
if (keying_material == NULL ) {
375
382
DEBUG ("Cannot export keying material" );
@@ -393,10 +400,9 @@ UNIFEX_TERM handle_handshake_finished(State *state) {
393
400
size_t pending_data_len = BIO_ctrl_pending (SSL_get_wbio (state -> ssl ));
394
401
DEBUG ("WBIO: pending data: %ld bytes" , pending_data_len );
395
402
396
- unifex_payload_alloc (state -> env , UNIFEX_PAYLOAD_BINARY , pending_data_len ,
397
- & gen_packets );
398
403
if (pending_data_len > 0 ) {
399
- if (read_pending_data (& gen_packets , pending_data_len , state ) < 0 ) {
404
+ read_pending_data (& gen_packets , & gen_packets_size , state );
405
+ if (gen_packets == NULL ) {
400
406
res_term = unifex_raise (state -> env , "Handshake failed: write BIO error" );
401
407
goto cleanup ;
402
408
}
@@ -416,10 +422,14 @@ UNIFEX_TERM handle_handshake_finished(State *state) {
416
422
417
423
res_term = handle_data_result_handshake_finished (
418
424
state -> env , local_keying_material , remote_keying_material ,
419
- keying_material -> protection_profile , & gen_packets );
425
+ keying_material -> protection_profile , gen_packets , gen_packets_size );
420
426
421
427
cleanup :
422
- unifex_payload_release (& gen_packets );
428
+
429
+ for (int i = 0 ; i < gen_packets_size ; i ++ ) {
430
+ unifex_payload_release (gen_packets [i ]);
431
+ }
432
+
423
433
unifex_payload_release (& client_keying_material );
424
434
unifex_payload_release (& server_keying_material );
425
435
return res_term ;
@@ -434,16 +444,20 @@ UNIFEX_TERM handle_handshake_in_progress(State *state, int ret) {
434
444
DEBUG ("WBIO: pending data: %ld bytes" , pending_data_len );
435
445
436
446
if (pending_data_len > 0 ) {
437
- UnifexPayload gen_packets ;
438
- unifex_payload_alloc ( state -> env , UNIFEX_PAYLOAD_BINARY , pending_data_len ,
439
- & gen_packets );
440
- if (read_pending_data ( & gen_packets , pending_data_len , state ) < 0 ) {
447
+ UnifexPayload * * gen_packets = NULL ;
448
+ int gen_packets_size = 0 ;
449
+ read_pending_data ( & gen_packets , & gen_packets_size , state );
450
+ if (gen_packets == NULL ) {
441
451
return unifex_raise (state -> env , "Handshake failed: write BIO error" );
442
452
}
443
453
int timeout = get_timeout (state -> ssl );
444
454
UNIFEX_TERM res_term = handle_data_result_handshake_packets (
445
- state -> env , & gen_packets , timeout );
446
- unifex_payload_release (& gen_packets );
455
+ state -> env , gen_packets , gen_packets_size , timeout );
456
+
457
+ for (int i = 0 ; i < gen_packets_size ; i ++ ) {
458
+ unifex_payload_release (gen_packets [i ]);
459
+ }
460
+
447
461
return res_term ;
448
462
} else {
449
463
return handle_data_result_handshake_want_read (state -> env );
@@ -458,20 +472,22 @@ UNIFEX_TERM handle_timeout(UnifexEnv *env, State *state) {
458
472
if (result != 1 )
459
473
return handle_timeout_result_ok (env );
460
474
461
- BIO * wbio = SSL_get_wbio (state -> ssl );
462
- size_t pending_data_len = BIO_ctrl_pending (wbio );
463
- UnifexPayload gen_packets ;
464
- unifex_payload_alloc (env , UNIFEX_PAYLOAD_BINARY , pending_data_len ,
465
- & gen_packets );
475
+ UnifexPayload * * gen_packets = NULL ;
476
+ int gen_packets_size = 0 ;
477
+ read_pending_data (& gen_packets , & gen_packets_size , state );
466
478
467
- if (read_pending_data ( & gen_packets , pending_data_len , state ) < 0 ) {
479
+ if (gen_packets == NULL ) {
468
480
return unifex_raise (state -> env ,
469
481
"Retransmit handshake failed: write BIO error" );
470
482
} else {
471
483
int timeout = get_timeout (state -> ssl );
472
- UNIFEX_TERM res_term =
473
- handle_timeout_result_retransmit (env , & gen_packets , timeout );
474
- unifex_payload_release (& gen_packets );
484
+ UNIFEX_TERM res_term = handle_timeout_result_retransmit (
485
+ env , gen_packets , gen_packets_size , timeout );
486
+
487
+ for (int i = 0 ; i < gen_packets_size ; i ++ ) {
488
+ unifex_payload_release (gen_packets [i ]);
489
+ }
490
+
475
491
return res_term ;
476
492
}
477
493
}
@@ -511,22 +527,84 @@ static int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) {
511
527
}
512
528
}
513
529
514
- static int read_pending_data (UnifexPayload * gen_packets , int pending_data_len ,
515
- State * state ) {
516
- char * pending_data = (char * )malloc (pending_data_len * sizeof (char ));
517
- memset (pending_data , 0 , pending_data_len );
518
- BIO * wbio = SSL_get_wbio (state -> ssl );
519
- int read_bytes = BIO_read (wbio , pending_data , pending_data_len );
520
- if (read_bytes <= 0 ) {
521
- DEBUG ("WBIO: read error" );
522
- } else {
523
- DEBUG ("WBIO: read: %d bytes" , read_bytes );
524
- memcpy (gen_packets -> data , pending_data , pending_data_len );
525
- gen_packets -> size = (unsigned int )pending_data_len ;
530
+ static UnifexPayload * * to_payload_array (struct Datagram * dgram_list , int len ) {
531
+
532
+ UnifexPayload * * payloads = calloc (len , sizeof (UnifexPayload * ));
533
+
534
+ for (int i = 0 ; i < len ; i ++ ) {
535
+ DEBUG ("%d" , i );
536
+ payloads [i ] = NULL ;
537
+ }
538
+
539
+ struct Datagram * itr = dgram_list ;
540
+
541
+ for (int i = 0 ; i < len ; i ++ ) {
542
+ DEBUG ("size, %d" , itr -> packet -> size );
543
+ itr = itr -> next ;
544
+ }
545
+
546
+ itr = dgram_list ;
547
+ for (int i = 0 ; i < len ; i ++ ) {
548
+ DEBUG ("to payload array 3, %d" , len );
549
+ payloads [i ] = itr -> packet ;
550
+ itr = itr -> next ;
551
+ }
552
+
553
+ DEBUG ("to payload array" );
554
+
555
+ // itr = dgram_list;
556
+ // struct Datagram *next = dgram_list->next;
557
+
558
+ // for (int i = 0; i < len; i++) {
559
+ // free(itr);
560
+ // itr = next;
561
+ // next = itr->next;
562
+ // DEBUG("dupa2");
563
+ // }
564
+
565
+ return payloads ;
566
+ }
567
+
568
+ static void read_pending_data (UnifexPayload * * * payloads , int * size ,
569
+ State * state ) {
570
+
571
+ struct Datagram * dgram_list = NULL ;
572
+ struct Datagram * itr = NULL ;
573
+ * size = 0 ;
574
+
575
+ size_t pending_data_len = 0 ;
576
+ while ((pending_data_len = BIO_ctrl_pending (SSL_get_wbio (state -> ssl ))) > 0 ) {
577
+ struct Datagram * dgram = calloc (1 , sizeof (struct Datagram ));
578
+ UnifexPayload * payload = calloc (1 , sizeof (UnifexPayload ));
579
+ unifex_payload_alloc (state -> env , UNIFEX_PAYLOAD_BINARY , pending_data_len ,
580
+ payload );
581
+ dgram -> packet = payload ;
582
+ dgram -> next = NULL ;
583
+
584
+ BIO * wbio = SSL_get_wbio (state -> ssl );
585
+ int read_bytes = BIO_read (wbio , payload -> data , pending_data_len );
586
+ if (read_bytes <= 0 ) {
587
+ DEBUG ("WBIO: read error" );
588
+ // TODO cleanup
589
+ * size = 0 ;
590
+ return ;
591
+ } else {
592
+ DEBUG ("WBIO: read: %d bytes" , read_bytes );
593
+ dgram -> packet -> size = (unsigned int )pending_data_len ;
594
+ }
595
+
596
+ if (dgram_list == NULL ) {
597
+ dgram_list = dgram ;
598
+ itr = dgram_list ;
599
+ } else {
600
+ itr -> next = dgram ;
601
+ itr = itr -> next ;
602
+ }
603
+
604
+ (* size )++ ;
526
605
}
527
- free (pending_data );
528
606
529
- return read_bytes ;
607
+ * payloads = to_payload_array ( dgram_list , * size ) ;
530
608
}
531
609
532
610
static void cert_to_payload (UnifexEnv * env , X509 * x509 ,
0 commit comments