• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zhaozg / lua-openssl / 17889091673

21 Sep 2025 04:42AM UTC coverage: 93.583%. Remained the same
17889091673

Pull #325

travis-ci

Copilot
Comprehensive LDoc documentation improvements and fixes

Co-authored-by: zhaozg <542599+zhaozg@users.noreply.github.com>
Pull Request #325: Comprehensive LDoc documentation improvements: 100% module coverage and enhanced function documentation

246 of 252 new or added lines in 15 files covered. (97.62%)

71 existing lines in 2 files now uncovered.

9640 of 10301 relevant lines covered (93.58%)

2241.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.79
/src/bio.c
1
/***
2
bio module to mapping a BIO in openssl to a lua object.
3

4
@module bio
5
@usage
6
  bio = require'openssl'.bio
7
*/
8

9
#include <openssl/bn.h>
10
#include <openssl/ssl.h>
11

12
#include "openssl.h"
13
#include "private.h"
14

15
/*
16
static const int* iMethods[] = {
17
  BIO_TYPE_NONE,
18
  BIO_TYPE_MEM,
19
  BIO_TYPE_SOCKET,
20
  BIO_TYPE_CONNECT,
21
  BIO_TYPE_ACCEPT,
22
  BIO_TYPE_FD,
23
  BIO_TYPE_BIO,
24
  BIO_TYPE_DGRAM,
25

26
  BIO_TYPE_BUFFER,
27

28
  -1
29
};
30
static const char* sMethods[] = {
31
  "none",
32
  "mem",
33
  "socket",
34
  "connect",
35
  "accept",
36
  "fd",
37
  "bio",
38
  "datagram",
39

40
  "buffer",
41
  NULL
42
};
43

44
static LUA_FUNCTION(openssl_bio_new) {
45

46
const char* f = luaL_checkstring(L,1);
47
const char* m = luaL_optstring(L,2,"r");
48
BIO *bio = BIO_new_file(f,m);
49
BIO_f_base64()
50
if(!bio)
51
luaL_error(L, "error opening the file(%s) for mode (%s)", f, m);
52
PUSH_OBJECT(bio,"openssl.bio");
53
return 1;
54
}
55
*/
56

57
/***
58
make string as bio object
59

60
@function mem
61
@tparam[opt=nil] string data, it will be memory buffer data
62
@treturn bio it can be input or output object
63
*/
64
static LUA_FUNCTION(openssl_bio_new_mem)
24✔
65
{
66
  size_t l = 0;
24✔
67
  BIO   *bio = BIO_new(BIO_s_mem());
24✔
68
  if (!bio) {
24✔
69
    luaL_error(L, "Failed to create memory BIO");
×
70
    return 0;
×
71
  }
72

73
  if (lua_isnumber(L, 1)) {
24✔
74
    l = lua_tointeger(L, 1);
4✔
75
    BIO_set_buffer_size(bio, l);
4✔
76
  } else if (lua_isstring(L, 1)) {
20✔
77
    const char *d = (char *)luaL_checklstring(L, 1, &l);
12✔
78
    BIO_write(bio, d, l);
12✔
79
  }
80

81
  PUSH_OBJECT(bio, "openssl.bio");
24✔
82
  return 1;
24✔
83
}
84

85
/***
86
create a pair of connected BIOs
87
@function pair
88
@tparam[opt=0] number buffer1 buffer size for first BIO
89
@tparam[opt=buffer1] number buffer2 buffer size for second BIO
90
@treturn bio first BIO of the pair
91
@treturn bio second BIO of the pair
92
*/
93
static LUA_FUNCTION(openssl_bio_new_pair)
20✔
94
{
95
  size_t b1 = luaL_optint(L, 1, 0);
20✔
96
  size_t b2 = luaL_optint(L, 2, b1);
20✔
97
  BIO   *B1 = NULL;
20✔
98
  BIO   *B2 = NULL;
20✔
99

100
  int ret = BIO_new_bio_pair(&B1, b1, &B2, b2);
20✔
101
  if (ret == 1) {
20✔
102
    PUSH_OBJECT(B1, "openssl.bio");
20✔
103
    PUSH_OBJECT(B2, "openssl.bio");
20✔
104
    ret = 2;
20✔
105
  }
106
  return ret > 0 ? ret : openssl_pushresult(L, ret);
20✔
107
}
108

109
/***
110
destroy a BIO pair connection
111
@function destroy_pair  
112
@tparam bio bio BIO object that is part of a pair
113
@treturn boolean true on success, false on failure
114
*/
115
static LUA_FUNCTION(openssl_bio_destroy_pair)
20✔
116
{
117
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
20✔
118
  int  ret = BIO_destroy_bio_pair(bio);
20✔
119
  return openssl_pushresult(L, ret);
20✔
120
}
121

122
/***
123
create a null BIO that discards all data written to it
124
@function null
125
@treturn bio null BIO object
126
*/
127
static LUA_FUNCTION(openssl_bio_new_null)
4✔
128
{
129
  BIO *bio = BIO_new(BIO_s_null());
4✔
130

131
  PUSH_OBJECT(bio, "openssl.bio");
4✔
132
  return 1;
4✔
133
}
134

135
/***
136
make tcp bio from socket fd
137

138
@function socket
139
@tparam number fd
140
@tparam[opt='noclose'] flag support 'close' or 'noclose' when close or gc
141
@treturn bio
142
*/
143
static LUA_FUNCTION(openssl_bio_new_socket)
4✔
144
{
145
  int  s = luaL_checkint(L, 1);
4✔
146
  int  closeflag = luaL_optinteger(L, 2, 0);
4✔
147
  BIO *bio = BIO_new_socket(s, closeflag);
4✔
148

149
  PUSH_OBJECT(bio, "openssl.bio");
4✔
150
  return 1;
4✔
151
}
152

153
/***
154
make dgram bio from socket fd
155

156
@function dgram
157
@tparam number fd
158
@tparam[opt='noclose'] flag support 'close' or 'noclose' when close or gc
159
@treturn bio
160
*/
161
static LUA_FUNCTION(openssl_bio_new_dgram)
4✔
162
{
163
  int  s = luaL_checkint(L, 1);
4✔
164
  int  closeflag = luaL_optinteger(L, 2, 0);
4✔
165
  BIO *bio = BIO_new_dgram(s, closeflag);
4✔
166

167
  PUSH_OBJECT(bio, "openssl.bio");
4✔
168
  return 1;
4✔
169
}
170

171
/***
172
make socket or file bio with fd
173
@function fd
174
@tparam number fd
175
@tparam[opt='noclose'] flag support 'close' or 'noclose' when close or gc
176
@treturn bio
177
*/
178
static LUA_FUNCTION(openssl_bio_new_fd)
4✔
179
{
180
  int  fd = luaL_checkint(L, 1);
4✔
181
  int  closeflag = luaL_optinteger(L, 2, 0);
4✔
182
  BIO *bio = BIO_new_fd(fd, closeflag);
4✔
183

184
  PUSH_OBJECT(bio, "openssl.bio");
4✔
185
  return 1;
4✔
186
}
187

188
/***
189
make file object with file name or path
190
@function file
191
@tparam string file
192
@tparam[opt='r'] string mode
193
@treturn bio
194
*/
195
static LUA_FUNCTION(openssl_bio_new_file)
4✔
196
{
197
  const char *f = luaL_checkstring(L, 1);
4✔
198
  const char *m = luaL_optstring(L, 2, "r");
4✔
199
  BIO        *bio = BIO_new_file(f, m);
4✔
200
  if (bio) {
4✔
201
    PUSH_OBJECT(bio, "openssl.bio");
4✔
202
  }
203

204
  return bio ? 1 : openssl_pushresult(L, 0);
4✔
205
}
206

207
/***
208
make tcp listen socket
209
@function accept
210
@tparam string host_port address like 'host:port'
211
@treturn bio
212
*/
213
static LUA_FUNCTION(openssl_bio_new_accept)
13✔
214
{
215
  const char *port = lua_tostring(L, 1);
13✔
216
  BIO        *b = BIO_new_accept((char *)port);
13✔
217

218
  PUSH_OBJECT(b, "openssl.bio");
13✔
219
  return 1;
13✔
220
}
221

222
/***
223
make tcp client socket
224
@function connect
225
@tparam string host_addr addrees like 'host:port'
226
@tparam[opt=true] boolean connect default connect immediately
227
@treturn bio
228
*/
229

230
/***
231
make tcp client socket
232
@function connect
233
@tparam address table with hostname, ip, port filed
234
@tparam[opt=true] boolean connect default connect immediately
235
@treturn bio
236
*/
237
static int
238
openssl_bio_new_connect(lua_State *L)
912✔
239
{
240
  BIO *bio = NULL;
912✔
241
  int  doconn = 1;
912✔
242
  int  ret = 1;
912✔
243

244
  if (lua_isstring(L, 1)) {
912✔
245
    const char *host = luaL_checkstring(L, 1);
904✔
246
    bio = BIO_new_connect((char *)host);
904✔
247
  } else if (lua_istable(L, 1)) {
8✔
248
    bio = BIO_new(BIO_s_connect());
4✔
249

250
    lua_getfield(L, 1, "hostname");
4✔
251
    if (!lua_isnil(L, -1)) {
4✔
252
      BIO_set_conn_hostname(bio, (char *)lua_tostring(L, -1));
4✔
253
    }
254
    lua_pop(L, 1);
4✔
255

256
    lua_getfield(L, 1, "port");
4✔
257
    if (!lua_isnil(L, -1)) {
4✔
258
      BIO_set_conn_port(bio, (char *)lua_tostring(L, -1));
4✔
259
    }
260
    lua_pop(L, 1);
4✔
261
  } else {
262
    bio = BIO_new(BIO_s_connect());
4✔
263
    doconn = 0;
4✔
264
  }
265

266
  doconn = lua_isnone(L, 2) ? doconn : lua_toboolean(L, 2);
912✔
267
  if (doconn) ret = BIO_do_connect(bio);
912✔
268

269
  if (ret == 1) {
912✔
270
    PUSH_OBJECT(bio, "openssl.bio");
912✔
271
  } else
UNCOV
272
    BIO_free(bio);
×
273
  return ret == 1 ? ret : openssl_pushresult(L, ret);
912✔
274
}
275

276
/***
277
make base64 or buffer bio, which can append to an io BIO object
278
@function filter
279
@tparam string mode support 'base64' or 'buffer'
280
@treturn bio
281
*/
282
/***
283
make digest bio, which can append to an io BIO object
284
@function filter
285
@tparam string mode must be 'digest'
286
@tparam evp_md|string md_alg
287
@treturn bio
288
*/
289
/***
290
make ssl bio
291
@function filter
292
@tparam string mode must be 'ssl'
293
@tparam ssl s
294
@tparam[opt='noclose'] flag support 'close' or 'noclose' when close or gc
295
@treturn bio
296
*/
297

298
/***
299
make cipher filter bio object
300
@function filter
301
@tparam string mode must be 'cipher'
302
@tparam string key
303
@tparam string iv
304
@tparam[opt=true] boolean encrypt
305
@treturn bio
306
*/
307
static LUA_FUNCTION(openssl_bio_new_filter)
24✔
308
{
309
  /* 0         1        2      3      4    5 */
310
  static const char *sType[] = { "base64", "buffer", "cipher", "md", "ssl", NULL };
311
  int                type = luaL_checkoption(L, 1, NULL, sType);
24✔
312
  BIO               *bio = NULL;
24✔
313
  int                ret = 1;
24✔
314
  switch (type) {
24✔
315
  case 0:
4✔
316
    bio = BIO_new(BIO_f_base64());
4✔
317
    break;
4✔
318
  case 1:
4✔
319
    bio = BIO_new(BIO_f_buffer());
4✔
320
    break;
4✔
321
  case 2: {
8✔
322
    const EVP_CIPHER *c = get_cipher(L, 2, NULL);
8✔
323
    size_t            kl, il;
324
    const char       *k = luaL_checklstring(L, 3, &kl);
8✔
325
    const char       *v = luaL_checklstring(L, 4, &il);
8✔
326
    int               encrypt = auxiliar_checkboolean(L, 5);
8✔
327

328
    bio = BIO_new(BIO_f_cipher());
8✔
329
    BIO_set_cipher(bio, c, (const unsigned char *)k, (const unsigned char *)v, encrypt);
8✔
330
  } break;
8✔
331
  case 3: {
4✔
332
    const EVP_MD *md = get_digest(L, 2, NULL);
4✔
333

334
    bio = BIO_new(BIO_f_md());
4✔
335
    ret = BIO_set_md(bio, md);
4✔
336
  } break;
4✔
337
  case 4: {
4✔
338
    SSL *ssl = CHECK_OBJECT(2, SSL, "openssl.ssl");
4✔
339
    int  closeflag = luaL_optinteger(L, 3, 0);
4✔
340

341
    bio = BIO_new(BIO_f_ssl());
4✔
342
    ret = BIO_set_ssl(bio, ssl, closeflag);
4✔
343
  } break;
4✔
UNCOV
344
  default:
×
UNCOV
345
    ret = 0;
×
346
  }
347
  if (ret == 1 && bio) {
24✔
348
    PUSH_OBJECT(bio, "openssl.bio");
24✔
349
    return 1;
24✔
350
  } else {
UNCOV
351
    if (bio) BIO_free_all(bio);
×
UNCOV
352
    return openssl_pushresult(L, ret);
×
353
  }
354
}
355

356
/* bio object method */
357
/***
358
openssl.bio object
359
@type bio
360
*/
361

362
/***
363
read data from bio object
364
@function read
365
@tparam number len
366
@treturn string string length may be less than param len
367
*/
368
static LUA_FUNCTION(openssl_bio_read)
241,216✔
369
{
370
  BIO  *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
241,216✔
371
  int   len = luaL_optint(L, 2, BIO_pending(bio));
241,216✔
372
  char *buf = NULL;
241,216✔
373
  int   ret = 1;
241,216✔
374

375
  luaL_argcheck(L, bio, 1, "Already closed");
241,216✔
376
  len = len > 0 ? len : 4096;
241,216✔
377
  buf = malloc(len);
241,216✔
378
  if (!buf) {
241,216✔
UNCOV
379
    luaL_error(L, "Memory allocation failed");
×
UNCOV
380
    return 0;
×
381
  }
382
  len = BIO_read(bio, buf, len);
241,216✔
383

384
  if (len > 0) {
241,216✔
385
    lua_pushlstring(L, buf, len);
240,008✔
386
    ret = 1;
240,008✔
387
  } else if (BIO_should_retry(bio)) {
1,208✔
388
    lua_pushlstring(L, buf, 0);
4✔
389
    ret = 1;
4✔
390
  } else {
391
    lua_pushnil(L);
1,204✔
392
    lua_pushinteger(L, len);
1,204✔
393
    ret = 2;
1,204✔
394
  };
395
  free(buf);
241,216✔
396
  return ret;
241,216✔
397
}
398

399
/***
400
get line from bio object
401
@function gets
402
@tparam[opt=256] number max line len
403
@treturn string string length may be less than param len
404
*/
405
static LUA_FUNCTION(openssl_bio_gets)
4✔
406
{
407
  BIO  *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
4✔
408
  int   len = luaL_optint(L, 2, BIO_pending(bio));
4✔
409
  char *buf;
410
  int   ret = 1;
4✔
411
  len = len > 0 ? len : 1024;
4✔
412

413
  luaL_argcheck(L, bio, 1, "Already closed");
4✔
414
  buf = malloc(len);
4✔
415
  len = BIO_gets(bio, buf, len);
4✔
416
  if (len > 0) {
4✔
417
    lua_pushlstring(L, buf, len);
4✔
418
    ret = 1;
4✔
UNCOV
419
  } else if (BIO_should_retry(bio)) {
×
UNCOV
420
    lua_pushstring(L, "");
×
UNCOV
421
    ret = 1;
×
422
  } else {
UNCOV
423
    lua_pushnil(L);
×
UNCOV
424
    lua_pushinteger(L, len);
×
UNCOV
425
    ret = 2;
×
426
  };
427
  free(buf);
4✔
428
  return ret;
4✔
429
}
430

431
/***
432
write data to bio object
433
@function write
434
@tparam string data
435
@treturn number length success write
436
*/
437
static LUA_FUNCTION(openssl_bio_write)
240,020✔
438
{
439
  BIO        *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
240,020✔
440
  size_t      size = 0;
240,020✔
441
  const char *d = luaL_checklstring(L, 2, &size);
240,020✔
442
  int         ret = 1;
240,020✔
443
  int         len = luaL_optint(L, 3, size);
240,020✔
444

445
  luaL_argcheck(L, bio, 1, "Already closed");
240,020✔
446
  len = BIO_write(bio, d, len);
240,020✔
447
  if (len > 0) {
240,020✔
448
    lua_pushinteger(L, len);
240,020✔
449
    ret = 1;
240,020✔
UNCOV
450
  } else if (BIO_should_retry(bio)) {
×
UNCOV
451
    lua_pushinteger(L, 0);
×
UNCOV
452
    ret = 1;
×
453
  } else {
UNCOV
454
    lua_pushnil(L);
×
UNCOV
455
    lua_pushinteger(L, len);
×
UNCOV
456
    ret = 2;
×
457
  };
458
  return ret;
240,020✔
459
}
460

461
/***
462
put line to bio object
463
@function puts
464
@tparam string data
465
@treturn number length success write
466
*/
467
static LUA_FUNCTION(openssl_bio_puts)
4✔
468
{
469
  BIO        *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
4✔
470
  const char *s = luaL_checkstring(L, 2);
4✔
471
  int         ret = 1;
4✔
472
  int         len = BIO_puts(bio, s);
4✔
473

474
  luaL_argcheck(L, bio, 1, "Already closed");
4✔
475
  if (len > 0) {
4✔
476
    lua_pushinteger(L, len);
4✔
477
    ret = 1;
4✔
UNCOV
478
  } else if (BIO_should_retry(bio)) {
×
UNCOV
479
    lua_pushinteger(L, 0);
×
UNCOV
480
    ret = 1;
×
481
  } else {
UNCOV
482
    lua_pushnil(L);
×
UNCOV
483
    lua_pushinteger(L, len);
×
UNCOV
484
    ret = 2;
×
485
  };
486
  return ret;
4✔
487
}
488

489
/***
490
flush buffer of bio object
491
@function flush
492
@treturn boolean true for success, others for fail
493
*/
494
static LUA_FUNCTION(openssl_bio_flush)
60,008✔
495
{
496
  int  ret;
497
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
60,008✔
498
  luaL_argcheck(L, bio, 1, "Already closed");
60,008✔
499

500
  ret = BIO_flush(bio);
60,008✔
501
  lua_pushinteger(L, ret);
60,008✔
502
  return 1;
60,008✔
503
}
504

505
static LUA_FUNCTION(openssl_bio_free)
7,460✔
506
{
507
  int  flags;
508
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
7,460✔
509
  if (bio == NULL) return 0;
7,460✔
510

511
  flags = lua_toboolean(L, 2);
3,754✔
512
  if (flags)
3,754✔
513
    BIO_free_all(bio);
900✔
514
  else
515
    BIO_free(bio);
2,854✔
516

517
  *(void **)lua_touserdata(L, 1) = NULL;
3,754✔
518

519
  return 0;
3,754✔
520
}
521

522
/***
523
get type of bio
524
@function type
525
@treturn string
526
*/
527
static LUA_FUNCTION(openssl_bio_type)
4✔
528
{
529
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
4✔
530
  luaL_argcheck(L, bio, 1, "Already closed");
4✔
531

532
  lua_pushstring(L, BIO_method_name(bio));
4✔
533
  return 1;
4✔
534
}
535

536
/***
537
set nonblock for bio object
538
@function nbio
539
@tparam boolean nonblock
540
@treturn boolean result, true for success, others for fail
541
*/
542
static LUA_FUNCTION(openssl_bio_nbio)
8✔
543
{
544
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
8✔
545
  int  nbio = lua_toboolean(L, 2);
8✔
546
  int  ret;
547

548
  luaL_argcheck(L, bio, 1, "Already closed");
8✔
549
  ret = BIO_set_nbio(bio, nbio);
8✔
550
  return openssl_pushresult(L, ret);
8✔
551
}
552

553
static LUA_FUNCTION(openssl_bio_retry)
8✔
554
{
555
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
8✔
556
  int  retry;
557
  luaL_argcheck(L, bio, 1, "Already closed");
8✔
558

559
  retry = BIO_should_retry(bio);
8✔
560
  if (retry) {
8✔
UNCOV
561
    lua_pushboolean(L, 1);
×
UNCOV
562
    lua_pushboolean(L, BIO_should_read(bio));
×
UNCOV
563
    lua_pushboolean(L, BIO_should_write(bio));
×
UNCOV
564
    lua_pushboolean(L, BIO_should_io_special(bio));
×
UNCOV
565
    return 4;
×
566
  } else
567
    lua_pushboolean(L, 0);
8✔
568
  return 1;
8✔
569
}
570

571
/***
572
reset bio
573
@function reset
574
*/
575
static LUA_FUNCTION(openssl_bio_reset)
4✔
576
{
577
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
4✔
578
  luaL_argcheck(L, bio, 1, "Already closed");
4✔
579

580
  (void)BIO_reset(bio);
4✔
581
  return 0;
4✔
582
}
583

584
/* filter bio object */
585
/***
586
push bio append to chain of bio, if want to free a chain use free_all()
587
@function push
588
@tparam bio append
589
@treturn bio
590
*/
591
static LUA_FUNCTION(openssl_bio_push)
16✔
592
{
593
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
16✔
594
  BIO *append = CHECK_OBJECT(2, BIO, "openssl.bio");
16✔
595
  luaL_argcheck(L, bio, 1, "Already closed");
16✔
596
  luaL_argcheck(L, append, 2, "Already closed");
16✔
597

598
  bio = BIO_push(bio, append);
16✔
599
  if (bio) {
16✔
600
    lua_pushvalue(L, 1);
16✔
601
  } else
UNCOV
602
    lua_pushnil(L);
×
603
  return 1;
16✔
604
}
605

606
/***
607
remove bio from chain
608
@function pop
609
@tparam bio toremove
610
*/
611
static LUA_FUNCTION(openssl_bio_pop)
8✔
612
{
613
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
8✔
614
  BIO *end;
615
  luaL_argcheck(L, bio, 1, "Already closed");
8✔
616

617
  end = BIO_pop(bio);
8✔
618
  if (end == NULL) {
8✔
619
    lua_pushnil(L);
4✔
620
  } else {
621
    BIO_up_ref(end);
4✔
622
    PUSH_OBJECT(end, "openssl.bio");
4✔
623
  }
624
  return 1;
8✔
625
}
626

627
/* mem */
628
/***
629
get mem data, only support mem bio object
630
@function get_mem
631
@treturn string
632
*/
633
static LUA_FUNCTION(openssl_bio_get_mem)
12✔
634
{
635
  BUF_MEM *mem;
636
  BIO     *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
12✔
637
  int      ret;
638

639
  luaL_argcheck(L, bio, 1, "Already closed");
12✔
640
  ret = BIO_get_mem_ptr(bio, &mem);
12✔
641
  if (ret == 1) {
12✔
642
    lua_pushlstring(L, mem->data, mem->length);
12✔
643
  }
644
  return ret == 1 ? 1 : openssl_pushresult(L, ret);
12✔
645
}
646

647
static LUA_FUNCTION(openssl_bio_get_md)
8✔
648
{
649
  int  ret = 0;
8✔
650
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
8✔
651

652
  luaL_argcheck(L, bio, 1, "Already closed");
8✔
653
  bio = BIO_find_type(bio, BIO_TYPE_MD);
8✔
654

655
  if (bio) {
8✔
656
    EVP_MD *md;
657
    BIO_get_md(bio, &md);
4✔
658
    PUSH_OBJECT(bio, "openssl.bio");
4✔
659
    BIO_up_ref(bio);
4✔
660
    PUSH_OBJECT(md, "openssl.evp_digest");
4✔
661
    ret = 2;
4✔
662
  }
663
  return ret;
8✔
664
}
665

666
static LUA_FUNCTION(openssl_bio_next)
4✔
667
{
668
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
4✔
669

670
  luaL_argcheck(L, bio, 1, "Already closed");
4✔
671
  bio = BIO_next(bio);
4✔
672
  if (bio) {
4✔
673
    PUSH_OBJECT(bio, "openssl.bio");
4✔
674
    BIO_up_ref(bio);
4✔
675
  }
676
  return bio ? 1 : 0;
4✔
677
}
678

679
static LUA_FUNCTION(openssl_bio_cipher_status)
8✔
680
{
681
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
8✔
682

683
  luaL_argcheck(L, bio, 1, "Already closed");
8✔
684
  lua_pushboolean(L, BIO_get_cipher_status(bio));
8✔
685
  return 1;
8✔
686
}
687

688
/* network socket */
689
/***
690
setup ready and accept client connect
691
@function accept
692
@tparam[opt=false] boolean setup true for setup accept bio, false or none will accept client connect
693
@treturn[1] boolean result only when setup is true
694
@treturn[2] bio accpeted bio object
695
*/
696
static LUA_FUNCTION(openssl_bio_accept)
1,818✔
697
{
698
  int  ret;
699
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
1,818✔
700
  int  first = lua_isnone(L, 2) ? 0 : lua_toboolean(L, 2);
1,818✔
701

702
  luaL_argcheck(L, bio, 1, "Already closed");
1,818✔
703
  ret = BIO_do_accept(bio);
1,818✔
704
  if (ret == 1) {
1,818✔
705
    if (!first) {
1,818✔
706
      BIO *nb = BIO_pop(bio);
1,800✔
707

708
      PUSH_OBJECT(nb, "openssl.bio");
1,800✔
709
      return 1;
1,800✔
710
    }
711
  }
712
  return openssl_pushresult(L, ret);
18✔
713
}
714

715
/***
716
shutdown SSL or TCP connection
717
@function shutdown
718
*/
719
static LUA_FUNCTION(openssl_bio_shutdown)
2,710✔
720
{
721
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
2,710✔
722

723
  luaL_argcheck(L, bio, 1, "Already closed");
2,710✔
724
  luaL_argcheck(L,
2,710✔
725
                BIO_method_type(bio) & (BIO_TYPE_SSL | BIO_TYPE_SOCKET | BIO_TYPE_FD),
726
                1,
727
                "don't know howto shutdown");
728

729
  if (BIO_method_type(bio) & BIO_TYPE_SSL) {
2,710✔
730
    BIO_ssl_shutdown(bio);
2,710✔
UNCOV
731
  } else if (BIO_method_type(bio) & (BIO_TYPE_SOCKET | BIO_TYPE_FD)) {
×
UNCOV
732
    (void)BIO_shutdown_wr(bio);
×
733
  }
734

735
  lua_pushvalue(L, 1);
2,710✔
736
  return 1;
2,710✔
737
}
738

739
/***
740
get ssl object assosited with bio object
741
@function get_ssl
742
@treturn ssl
743
*/
744
static LUA_FUNCTION(openssl_bio_get_ssl)
1,200✔
745
{
746
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
1,200✔
747
  SSL *ssl = NULL;
1,200✔
748
  int  ret;
749

750
  luaL_argcheck(L, bio, 1, "Already closed");
1,200✔
751
  ret = BIO_get_ssl(bio, &ssl);
1,200✔
752
  if (ret == 1) {
1,200✔
753
    PUSH_OBJECT(ssl, "openssl.ssl");
1,200✔
754
    SSL_up_ref(ssl);
1,200✔
755
    openssl_newvalue(L, ssl);
1,200✔
756
  }
757
  return ret == 1 ? ret : openssl_pushresult(L, ret);
1,200✔
758
}
759

760
/***
761
do TCP or SSL connect
762
@function connect
763
@treturn booolean result true for success and others for fail
764
*/
765
static LUA_FUNCTION(openssl_bio_connect)
900✔
766
{
767
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
900✔
768
  int  ret;
769

770
  luaL_argcheck(L, bio, 1, "Already closed");
900✔
771
  ret = BIO_do_connect(bio);
900✔
772
  return openssl_pushresult(L, ret);
900✔
773
}
774

775
/***
776
do handshake of TCP or SSL connection
777
@function handshake
778
@treturn boolean result true for success, and others for fail
779
*/
780
static LUA_FUNCTION(openssl_bio_handshake)
1,800✔
781
{
782
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
1,800✔
783
  int  ret;
784

785
  luaL_argcheck(L, bio, 1, "Already closed");
1,800✔
786
  ret = BIO_do_handshake(bio);
1,800✔
787
  return openssl_pushresult(L, ret);
1,800✔
788
}
789

790
/***
791
get fd of bio object
792
@function fd
793
@treturn number
794
*/
795
/***
796
set fd of bio object
797
@function fd
798
@tparam number fd
799
@treturn number fd
800
*/
801
static LUA_FUNCTION(openssl_bio_fd)
8✔
802
{
803
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
8✔
804
  int  type;
805

806
  luaL_argcheck(L, bio, 1, "Already closed");
8✔
807
  type = BIO_method_type(bio);
8✔
808
  luaL_argcheck(
8✔
809
    L,
810
    type & (BIO_TYPE_FD | BIO_TYPE_CONNECT | BIO_TYPE_ACCEPT | BIO_TYPE_DGRAM | BIO_TYPE_SOCKET),
811
    1,
812
    "not a supported BIO type");
813

814
  if (!lua_isnone(L, 2)) {
8✔
815
    int fd = luaL_checkint(L, 2);
4✔
816
    BIO_set_fd(bio, fd, BIO_NOCLOSE);
4✔
817
  }
818
  lua_pushnumber(L, BIO_get_fd(bio, 0));
8✔
819
  return 1;
8✔
820
}
821

822
/* BIO_s_file() */
823
/*
824
# define BIO_set_fp(b,fp,c)      BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)
825
# define BIO_get_fp(b,fpp)       BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp)
826
*/
827

828
static LUA_FUNCTION(openssl_bio_seek)
4✔
829
{
830
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
4✔
831
  int  type, ofs, ret;
832

833
  luaL_argcheck(L, bio, 1, "Already closed");
4✔
834
  type = BIO_method_type(bio);
4✔
835
  luaL_argcheck(L, type & (BIO_TYPE_FD | BIO_TYPE_FILE), 1, "not a fd or file BIO type");
4✔
836

837
  ofs = luaL_checkint(L, 2);
4✔
838
  ret = BIO_seek(bio, ofs);
4✔
839
  if (ret < 0) return openssl_pushresult(L, ret);
4✔
840
  lua_pushinteger(L, ret);
4✔
841
  return 1;
4✔
842
}
843

844
static LUA_FUNCTION(openssl_bio_tell)
4✔
845
{
846
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
4✔
847
  int  type, ret;
848

849
  luaL_argcheck(L, bio, 1, "Already closed");
4✔
850
  type = BIO_method_type(bio);
4✔
851
  luaL_argcheck(L, type & (BIO_TYPE_FD | BIO_TYPE_FILE), 1, "not a fd or file BIO type");
4✔
852

853
  ret = BIO_tell(bio);
4✔
854
  if (ret < 0) return openssl_pushresult(L, ret);
4✔
855
  lua_pushinteger(L, ret);
4✔
856
  return 1;
4✔
857
}
858

859
#if OPENSSL_VERSION_NUMBER < 0x10100000L                                                           \
860
  || defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050000fL
861
void
862
BIO_info_callback(BIO *bio, int cmd, const char *argp, int argi, long argl, long ret)
863
{
864
  BIO   *b;
865
  char   buf[256];
866
  char  *p;
867
  size_t p_maxlen;
868
  (void)argl;
869
  (void)argp;
870

871
  snprintf(buf, sizeof buf, "BIO[%p]:", bio);
872
  p = &(buf[14]);
873
  p_maxlen = sizeof buf - 14;
874
  switch (cmd) {
875
  case BIO_CB_FREE:
876
    snprintf(p, p_maxlen, "Free - %s\n", BIO_method_name(bio));
877
    break;
878
  case BIO_CB_READ:
879
    if (BIO_method_type(bio) & BIO_TYPE_DESCRIPTOR)
880
      snprintf(p,
881
               p_maxlen,
882
               "read(%lu,%lu) - %s fd=%lu\n",
883
               (unsigned long)BIO_number_read(bio),
884
               (unsigned long)argi,
885
               BIO_method_name(bio),
886
               (unsigned long)BIO_number_read(bio));
887
    else
888
      snprintf(p,
889
               p_maxlen,
890
               "read(%lu,%lu) - %s\n",
891
               (unsigned long)BIO_number_read(bio),
892
               (unsigned long)argi,
893
               BIO_method_name(bio));
894
    break;
895
  case BIO_CB_WRITE:
896
    if (BIO_method_type(bio) & BIO_TYPE_DESCRIPTOR)
897
      snprintf(p,
898
               p_maxlen,
899
               "write(%lu,%lu) - %s fd=%lu\n",
900
               (unsigned long)BIO_number_written(bio),
901
               (unsigned long)argi,
902
               BIO_method_name(bio),
903
               (unsigned long)BIO_number_written(bio));
904
    else
905
      snprintf(p,
906
               p_maxlen,
907
               "write(%lu,%lu) - %s\n",
908
               (unsigned long)BIO_number_written(bio),
909
               (unsigned long)argi,
910
               BIO_method_name(bio));
911
    break;
912
  case BIO_CB_PUTS:
913
    snprintf(p, p_maxlen, "puts() - %s\n", BIO_method_name(bio));
914
    break;
915
  case BIO_CB_GETS:
916
    snprintf(p, p_maxlen, "gets(%lu) - %s\n", (unsigned long)argi, BIO_method_name(bio));
917
    break;
918
  case BIO_CB_CTRL:
919
    snprintf(p, p_maxlen, "ctrl(%lu) - %s\n", (unsigned long)argi, BIO_method_name(bio));
920
    break;
921
  case BIO_CB_RETURN | BIO_CB_READ:
922
    snprintf(p, p_maxlen, "read return %ld\n", ret);
923
    break;
924
  case BIO_CB_RETURN | BIO_CB_WRITE:
925
    snprintf(p, p_maxlen, "write return %ld\n", ret);
926
    break;
927
  case BIO_CB_RETURN | BIO_CB_GETS:
928
    snprintf(p, p_maxlen, "gets return %ld\n", ret);
929
    break;
930
  case BIO_CB_RETURN | BIO_CB_PUTS:
931
    snprintf(p, p_maxlen, "puts return %ld\n", ret);
932
    break;
933
  case BIO_CB_RETURN | BIO_CB_CTRL:
934
    snprintf(p, p_maxlen, "ctrl return %ld\n", ret);
935
    break;
936
  default:
937
    snprintf(p, p_maxlen, "bio callback - unknown type (%d)\n", cmd);
938
    break;
939
  }
940

941
  b = (BIO *)BIO_get_callback_arg(bio);
942
  if (b != NULL) BIO_write(b, buf, strlen(buf));
943
#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16)
944
  else
945
    fputs(buf, stderr);
946
#endif
947
}
948

949
/***
950
set callback function of bio information
951
@function set_callback
952
@tparam function callback
953
@treturn boolean result true for success, and others for fail
954
*/
955
static LUA_FUNCTION(openssl_bio_set_callback)
956
{
957
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
958
  int  ret;
959
  luaL_checktype(L, 2, LUA_TFUNCTION);
960

961
  ret = BIO_set_info_callback(bio, BIO_info_callback);
962
  return openssl_pushresult(L, ret);
963
}
964
#endif
965

966
/***
967
return pending length of bytes to read and write
968
@function pending
969
@treturn number pending of read, followed by pending of write
970
*/
971
static LUA_FUNCTION(openssl_bio_pending)
4✔
972
{
973
  BIO *bio = CHECK_OBJECT(1, BIO, "openssl.bio");
4✔
974

975
  luaL_argcheck(L, bio, 1, "Already closed");
4✔
976
  lua_pushinteger(L, BIO_pending(bio));
4✔
977
  lua_pushinteger(L, BIO_wpending(bio));
4✔
978
  return 2;
4✔
979
}
980

981
/***
982
close bio
983
@function close
984
*/
985

986
static luaL_Reg bio_funs[] = {
987
  /* generate operation */
988
  { "read",          openssl_bio_read          },
989
  { "gets",          openssl_bio_gets          },
990
  { "write",         openssl_bio_write         },
991
  { "puts",          openssl_bio_puts          },
992
  { "flush",         openssl_bio_flush         },
993
  { "close",         openssl_bio_free          },
994
  { "type",          openssl_bio_type          },
995
  { "nbio",          openssl_bio_nbio          },
996
  { "reset",         openssl_bio_reset         },
997
  { "retry",         openssl_bio_retry         },
998
  { "pending",       openssl_bio_pending       },
999

1000
#if OPENSSL_VERSION_NUMBER < 0x10100000L                                                           \
1001
  || defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x3050000fL
1002
  { "set_callback",  openssl_bio_set_callback  },
1003
#endif
1004

1005
  /* for filter bio */
1006
  { "push",          openssl_bio_push          },
1007
  { "pop",           openssl_bio_pop           },
1008
  { "next",          openssl_bio_next          },
1009
  { "get_md",        openssl_bio_get_md        },
1010
  { "cipher_status", openssl_bio_cipher_status },
1011
  { "free",          openssl_bio_free          },
1012

1013
  /* for mem */
1014
  { "get_mem",       openssl_bio_get_mem       },
1015

1016
  /* network socket */
1017
  { "accept",        openssl_bio_accept        },
1018
  { "connect",       openssl_bio_connect       },
1019
  { "handshake",     openssl_bio_handshake     },
1020

1021
  { "shutdown",      openssl_bio_shutdown      },
1022

1023
  /* BIO_s_datagram(), BIO_s_fd(), BIO_s_socket(),
1024
   * BIO_s_accept() and BIO_s_connect() */
1025
  { "fd",            openssl_bio_fd            },
1026

1027
  { "ssl",           openssl_bio_get_ssl       },
1028

1029
  /* BIO_s_fd() and BIO_s_file() */
1030
  { "seek",          openssl_bio_seek          },
1031
  { "tell",          openssl_bio_tell          },
1032

1033
  /* BIO_make_bio_pair */
1034
  { "destroy_pair",  openssl_bio_destroy_pair  },
1035

1036
  { "__tostring",    auxiliar_tostring         },
1037
  { "__gc",          openssl_bio_free          },
1038

1039
  { NULL,            NULL                      }
1040
};
1041

1042
static luaL_Reg R[] = {
1043
  { "null",    openssl_bio_new_null    },
1044
  { "mem",     openssl_bio_new_mem     },
1045
  { "pair",    openssl_bio_new_pair    },
1046
  { "socket",  openssl_bio_new_socket  },
1047
  { "dgram",   openssl_bio_new_dgram   },
1048
  { "fd",      openssl_bio_new_fd      },
1049
  { "file",    openssl_bio_new_file    },
1050
  { "filter",  openssl_bio_new_filter  },
1051

1052
  { "accept",  openssl_bio_new_accept  },
1053
  { "connect", openssl_bio_new_connect },
1054

1055
  { NULL,      NULL                    }
1056
};
1057

1058
int
1059
luaopen_bio(lua_State *L)
43✔
1060
{
1061
  auxiliar_newclass(L, "openssl.bio", bio_funs);
43✔
1062

1063
  lua_newtable(L);
43✔
1064
  luaL_setfuncs(L, R, 0);
43✔
1065

1066
  lua_pushinteger(L, BIO_NOCLOSE);
43✔
1067
  lua_setfield(L, -2, "NCLOSE");
43✔
1068

1069
  lua_pushinteger(L, BIO_CLOSE);
43✔
1070
  lua_setfield(L, -2, "CLOSE");
43✔
1071

1072
  return 1;
43✔
1073
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc