• 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.76
/src/asn1.c
1
/***
2
asn1 module to generate or parse ASN.1 data.
3
Provide asn1\_object, asn1\_string, asn1\_object as lua object.
4

5
@module asn1
6
@usage
7
  asn1 = require('openssl').asn1
8
*/
9

10
#include <openssl/asn1.h>
11

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

15
static LuaL_Enumeration asn1_const[] = {
16
  /* 0 */
17
  { "UNIVERSAL",         V_ASN1_UNIVERSAL         },
18
  { "APPLICATION",       V_ASN1_APPLICATION       },
19
  { "CONTEXT_SPECIFIC",  V_ASN1_CONTEXT_SPECIFIC  },
20
  { "PRIVATE",           V_ASN1_PRIVATE           },
21
  /* 4 */
22
  { "CONSTRUCTED",       V_ASN1_CONSTRUCTED       },
23
  { "PRIMITIVE_TAG",     V_ASN1_PRIMITIVE_TAG     },
24
  { "PRIMATIVE_TAG",     V_ASN1_PRIMATIVE_TAG     },
25
  { "APP_CHOOSE",        V_ASN1_APP_CHOOSE        },
26
  { "OTHER",             V_ASN1_OTHER             },
27
  { "ANY",               V_ASN1_ANY               },
28

29
  { "NEG",               V_ASN1_NEG               },
30
  /* 11 */
31

32
  { "UNDEF",             V_ASN1_UNDEF             },
33
  { "EOC",               V_ASN1_EOC               },
34
  { "BOOLEAN",           V_ASN1_BOOLEAN           },
35
  { "INTEGER",           V_ASN1_INTEGER           },
36
  { "NEG_INTEGER",       V_ASN1_NEG_INTEGER       },
37
  { "BIT_STRING",        V_ASN1_BIT_STRING        },
38
  { "OCTET_STRING",      V_ASN1_OCTET_STRING      },
39
  { "NULL",              V_ASN1_NULL              },
40
  { "OBJECT",            V_ASN1_OBJECT            },
41
  { "OBJECT_DESCRIPTOR", V_ASN1_OBJECT_DESCRIPTOR },
42
  { "EXTERNAL",          V_ASN1_EXTERNAL          },
43
  { "REAL",              V_ASN1_REAL              },
44
  { "ENUMERATED",        V_ASN1_ENUMERATED        },
45
  { "NEG_ENUMERATED",    V_ASN1_NEG_ENUMERATED    },
46
  { "UTF8STRING",        V_ASN1_UTF8STRING        },
47
  { "SEQUENCE",          V_ASN1_SEQUENCE          },
48
  { "SET",               V_ASN1_SET               },
49
  { "NUMERICSTRING",     V_ASN1_NUMERICSTRING     },
50
  { "PRINTABLESTRING",   V_ASN1_PRINTABLESTRING   },
51
  { "T61STRING",         V_ASN1_T61STRING         },
52
  { "TELETEXSTRING",     V_ASN1_TELETEXSTRING     },
53
  { "VIDEOTEXSTRING",    V_ASN1_VIDEOTEXSTRING    },
54
  { "IA5STRING",         V_ASN1_IA5STRING         },
55
  { "UTCTIME",           V_ASN1_UTCTIME           },
56
  { "GENERALIZEDTIME",   V_ASN1_GENERALIZEDTIME   },
57

58
  { "GRAPHICSTRING",     V_ASN1_GRAPHICSTRING     },
59
  { "ISO64STRING",       V_ASN1_ISO64STRING       },
60
  { "VISIBLESTRING",     V_ASN1_VISIBLESTRING     },
61
  { "GENERALSTRING",     V_ASN1_GENERALSTRING     },
62
  { "UNIVERSALSTRING",   V_ASN1_UNIVERSALSTRING   },
63
  { "BMPSTRING",         V_ASN1_BMPSTRING         },
64
  /* 43 */
65
  { NULL,                0                        }
66
};
67

68
#define CLS_IDX_OFFSET 0
69
#define CLS_IDX_LENGTH 4
70

71
#define TAG_IDX_OFFSET 11
72
#define TAG_IDX_LENGTH 31
73

74
/***
75
create asn1_type object
76
@function new_type
77
@tparam boolean|number|string|asn1_string value value to create ASN1_TYPE from
78
@treturn asn1_type|nil new ASN1_TYPE object or nil on error
79
*/
80
static int
81
openssl_asn1type_new(lua_State *L)
152✔
82
{
83
  ASN1_TYPE   *at = ASN1_TYPE_new();
152✔
84
  ASN1_STRING *s = NULL;
152✔
85
  int          ret = 0;
152✔
86
  int          type = lua_type(L, 1);
152✔
87

88
  luaL_argcheck(L,
152✔
89
                type == LUA_TBOOLEAN || type == LUA_TNUMBER || type == LUA_TSTRING
90
                  || (type == LUA_TUSERDATA && GET_GROUP(1, ASN1_STRING, "openssl.asn1group")),
91
                1,
92
                "only accept boolean, number, string or asn1_string");
93

94
  if (lua_isboolean(L, 1)) {
152✔
95
    int b = lua_toboolean(L, 1);
4✔
96
    ASN1_TYPE_set(at, V_ASN1_BOOLEAN, b ? &b : 0);
4✔
97
    ret = 1;
4✔
98
  } else if (lua_type(L, 1) == LUA_TNUMBER) {
148✔
99
    long          n = lua_tointeger(L, 1);
4✔
100
    ASN1_INTEGER *ai = ASN1_INTEGER_new();
4✔
101
    if (ASN1_INTEGER_set(ai, n) == 1) {
4✔
102
      ASN1_TYPE_set(at, V_ASN1_INTEGER, ai);
4✔
103
      ret = 1;
4✔
104
    } else {
105
      ASN1_INTEGER_free(ai);
×
106
    }
107
  } else if (lua_isstring(L, 1)) {
144✔
108
    size_t      size;
109
    const char *octet = luaL_checklstring(L, 1, &size);
36✔
110
    ret = ASN1_TYPE_set_octetstring(at, (unsigned char *)octet, size);
36✔
111
  } else if ((s = GET_GROUP(1, ASN1_STRING, "openssl.asn1group")) != NULL) {
108✔
112
    ret = ASN1_TYPE_set1(at, ASN1_STRING_type(s), s);
108✔
113
  }
114

115
  if (ret == 1)
152✔
116
    PUSH_OBJECT(at, "openssl.asn1_type");
152✔
117
  else
118
    ASN1_TYPE_free(at);
×
119
  return ret;
152✔
120
}
121

122
/***
123
parse der encoded string
124
@function get_object
125
@tparam string der string
126
@tparam[opt=1] number start offset to parse
127
@tparam[opt=-i] number stop offset to parse
128
 this like string.sub()
129
@treturn[1] number tag
130
@treturn[1] number class
131
@treturn[1] number parsed data start offset
132
@treturn[1] number parsed data stop offset
133
@treturn[1] boolean true for constructed data
134
@treturn[2] nil for fail
135
@treturn[2] string error msg
136
@treturn[2] number inner error code
137
*/
138
static int
139
openssl_get_object(lua_State *L)
80✔
140
{
141
  size_t      l = 0;
80✔
142
  const char *asn1s = luaL_checklstring(L, 1, &l);
80✔
143
  size_t      start = posrelat(luaL_optinteger(L, 2, 1), l);
80✔
144
  size_t      stop = posrelat(luaL_optinteger(L, 3, l), l);
80✔
145

146
  const unsigned char *p = (const unsigned char *)asn1s + start - 1;
80✔
147
  long                 len = 0;
80✔
148
  int                  tag = 0;
80✔
149
  int class = 0;
80✔
150
  int ret;
151

152
  luaL_argcheck(L, start > 0 && start < l, 2, "start out of length of asn1 string");
80✔
153
  luaL_argcheck(L, stop > start, 3, "stop must be greater than start");
64✔
154
  luaL_argcheck(L, stop <= l, 3, "stop out of length of asn1 string");
64✔
155

156
  p = (const unsigned char *)asn1s + start - 1;
56✔
157
  ret = ASN1_get_object(&p, &len, &tag, &class, stop - start + 1);
56✔
158
  if (ret & 0x80) {
56✔
159
    lua_pushnil(L);
×
160
    lua_pushstring(L, "arg #1 with error encoding");
×
161
    lua_pushinteger(L, ret);
×
162
    return 3;
×
163
  }
164
  lua_pushinteger(L, tag);
56✔
165
  lua_pushinteger(L, class);
56✔
166
  lua_pushinteger(L, p - (const unsigned char *)asn1s + 1);
56✔
167
  lua_pushinteger(L, p + len - (const unsigned char *)asn1s);
56✔
168

169
  lua_pushboolean(L, ret & V_ASN1_CONSTRUCTED);
56✔
170
  return 5;
56✔
171
}
172

173
/***
174
do der encode and return encoded string partly head or full
175
@function put_object
176
@tparam number tag
177
@tparam number class
178
@tparam[opt=nil] number|string length or date to encode, defualt will make
179
indefinite length constructed
180
@tparam[opt=nil] boolean constructed or not
181
@treturn string der encoded string or head when not give data
182
*/
183
static int
184
openssl_put_object(lua_State *L)
28✔
185
{
186
  int            tag = luaL_checkint(L, 1);
28✔
187
  int            cls = luaL_checkint(L, 2);
28✔
188
  int            length = 0;
28✔
189
  int            constructed;
190
  unsigned char *p1, *p2;
191
  const char    *dat = NULL;
28✔
192
  luaL_Buffer    B;
193

194
  luaL_argcheck(L,
28✔
195
                lua_isnone(L, 3) || lua_type(L, 3) == LUA_TNUMBER || lua_isstring(L, 3),
196
                3,
197
                "if exist only accept string or number");
198
  luaL_argcheck(L, lua_isnone(L, 4) || lua_isboolean(L, 4), 4, "if exist must be boolean type");
28✔
199

200
  if (lua_isnone(L, 3)) {
28✔
201
    /* constructed == 2 for indefinite length constructed */
202
    constructed = 2;
×
203
    length = 0;
×
204
  } else {
205
    if (lua_type(L, 3) == LUA_TNUMBER) {
28✔
206
      length = lua_tointeger(L, 3);
12✔
207
    } else if (lua_isstring(L, 3)) {
16✔
208
      size_t l;
209
      dat = lua_tolstring(L, 3, &l);
16✔
210
      length = (int)l;
16✔
211
    }
212

213
    constructed = lua_isnone(L, 4) ? 0 : lua_toboolean(L, 4);
28✔
214
  }
215
  luaL_buffinit(L, &B);
28✔
216
  p1 = (unsigned char *)luaL_prepbuffer(&B);
28✔
217
  p2 = p1;
28✔
218

219
  ASN1_put_object(&p2, constructed, length, tag, cls);
28✔
220
  luaL_addsize(&B, p2 - p1);
28✔
221
  if (dat) {
28✔
222
    luaL_addlstring(&B, dat, length);
16✔
223
  }
224
  luaL_pushresult(&B);
28✔
225
  return 1;
28✔
226
};
227

228
/***
229
make tag, class number to string
230

231
@function tostring
232
@tparam number clsortag which to string
233
@tparam string range only accept 'class' or 'tag'
234
@treturn string result
235
*/
236
static int
237
openssl_asn1_tostring(lua_State *L)
8✔
238
{
239
  int         val = luaL_checkint(L, 1);
8✔
240
  const char *range = luaL_optstring(L, 2, NULL);
8✔
241
  int         i, ret = 0;
8✔
242

243
  if (range == NULL) {
8✔
244
    for (i = 0; i < sizeof(asn1_const) / sizeof(LuaL_Enumeration) - 1; i++) {
×
245
      if (asn1_const[i].val == val) {
×
246
        lua_pushstring(L, asn1_const[i + CLS_IDX_OFFSET].name);
×
247
        ret = 1;
×
248
      }
249
    }
250
  } else if (strcmp("tag", range) == 0) {
8✔
251
    for (i = 0; i < TAG_IDX_LENGTH; i++) {
128✔
252
      if (asn1_const[i + TAG_IDX_OFFSET].val == val) {
124✔
253
        lua_pushstring(L, asn1_const[i + TAG_IDX_OFFSET].name);
4✔
254
        ret = 1;
4✔
255
      }
256
    }
257
  } else if (strcmp("class", range) == 0) {
4✔
258
    for (i = 0; i < CLS_IDX_LENGTH; i++) {
20✔
259
      if (asn1_const[i + CLS_IDX_OFFSET].val == val) {
16✔
260
        lua_pushstring(L, asn1_const[i + CLS_IDX_OFFSET].name);
4✔
261
        ret = 1;
4✔
262
      }
263
    }
264
  }
265

266
  return ret;
8✔
267
}
268

269
/***
270
create asn1_string object
271

272
<br/><p> asn1_string object support types:   "integer", "enumerated", "bit",
273
"octet", "utf8", "numeric", "printable", "t61", "teletex", "videotex", "ia5",
274
"graphics", "iso64", "visible", "general", "unversal", "bmp", "utctime" </p>
275

276
@function new_string
277
@tparam string data to create new asn1_string
278
@tparam[opt] string type asn1 string type, defult with 'utf8'
279
@treturn asn1_string
280
@see asn1_string
281
*/
282
static int
283
openssl_asn1string_new(lua_State *L)
216✔
284
{
285
  size_t       size = 0;
216✔
286
  const char  *data = luaL_checklstring(L, 1, &size);
216✔
287
  int          type = luaL_optint(L, 2, V_ASN1_UTF8STRING);
216✔
288
  ASN1_STRING *s = ASN1_STRING_type_new(type);
216✔
289
  ASN1_STRING_set(s, data, size);
216✔
290
  PUSH_OBJECT(s, "openssl.asn1_string");
216✔
291
  return 1;
216✔
292
}
293

294
/***
295
create asn1_integer object
296

297
@function new_integer
298
@tparam number|bn integer to create new asn1_integer
299
@treturn asn1_integer
300
@see asn1_integer
301
*/
302
static int
303
openssl_asn1int_new(lua_State *L)
24✔
304
{
305
  ASN1_INTEGER *ai = ASN1_INTEGER_new();
24✔
306
  if (lua_isinteger(L, 1)) {
24✔
307
    long v = luaL_checklong(L, 1);
4✔
308
    ASN1_INTEGER_set(ai, v);
4✔
309
  } else if (!lua_isnone(L, 1)) {
20✔
310
    BIGNUM *bn = BN_get(L, 1);
12✔
311
    if (bn != NULL) {
12✔
312
      ai = BN_to_ASN1_INTEGER(bn, ai);
8✔
313
      BN_free(bn);
8✔
314
    }
315
  }
316
  PUSH_OBJECT(ai, "openssl.asn1_integer");
24✔
317
  return 1;
24✔
318
}
319

320
/***
321
create asn1_time object
322
@function new_generalizedtime
323
@tparam none|number|string time
324
@treturn asn1_time
325
*/
326
static int
327
openssl_asn1generalizedtime_new(lua_State *L)
20✔
328
{
329
  ASN1_GENERALIZEDTIME *a = NULL;
20✔
330
  int                   ret = 0;
20✔
331
  luaL_argcheck(L,
332
                1,
333
                lua_isnone(L, 1) || lua_isnumber(L, 1) || lua_isstring(L, 1),
334
                "must be number, string or none");
335
  a = ASN1_GENERALIZEDTIME_new();
20✔
336
  if (lua_isnumber(L, 1)) {
20✔
337
    ASN1_GENERALIZEDTIME_set(a, luaL_checkinteger(L, 1));
8✔
338
    ret = 1;
8✔
339
  } else if (lua_isstring(L, 1))
12✔
340
    ret = ASN1_GENERALIZEDTIME_set_string(a, lua_tostring(L, 1));
4✔
341
  else
342
    ret = 1;
8✔
343

344
  if (ret == 1)
20✔
345
    PUSH_OBJECT(a, "openssl.asn1_time");
20✔
346
  else
347
    ASN1_GENERALIZEDTIME_free(a);
×
348

349
  return ret == 1 ? 1 : 0;
20✔
350
}
351

352
/***
353
create asn1_time object
354
@function new_utctime
355
@tparam none|number|string time
356
@treturn asn1_time
357
*/
358
static int
359
openssl_asn1utctime_new(lua_State *L)
24✔
360
{
361
  ASN1_UTCTIME *a = NULL;
24✔
362
  int           ret = 0;
24✔
363
  luaL_argcheck(L,
364
                1,
365
                lua_isnone(L, 1) || lua_isnumber(L, 1) || lua_isstring(L, 1),
366
                "must be number, string or none");
367
  a = ASN1_UTCTIME_new();
24✔
368
  if (lua_isnumber(L, 1)) {
24✔
369
    time_t t = luaL_checkinteger(L, 1);
8✔
370
    ASN1_TIME_set(a, t);
8✔
371
    ret = 1;
8✔
372
  } else if (lua_isstring(L, 1))
16✔
373
    ret = ASN1_TIME_set_string(a, lua_tostring(L, 1));
4✔
374
  else if (lua_isnone(L, 1)) {
12✔
375
    time_t t = time(NULL);
12✔
376
    ASN1_TIME_set(a, t);
12✔
377
    ret = 1;
12✔
378
  }
379

380
  if (ret == 1)
24✔
381
    PUSH_OBJECT(a, "openssl.asn1_time");
24✔
382
  else
383
    ASN1_UTCTIME_free(a);
×
384

385
  return ret == 1 ? 1 : 0;
24✔
386
}
387

388
/***
389
get nid for txt, which can be short name, long name, or numerical oid
390

391
@function txt2nid
392
@tparam string txt which get to nid
393
@treturn integer nid or nil on fail
394
*/
395
static int
396
openssl_txt2nid(lua_State *L)
16✔
397
{
398
  const char *txt = luaL_checkstring(L, 1);
16✔
399
  int         nid = OBJ_txt2nid(txt);
16✔
400
  int         ret = 1;
16✔
401
  if (nid != NID_undef) {
16✔
402
    lua_pushinteger(L, nid);
12✔
403
  } else
404
    ret = openssl_pushresult(L, 0);
4✔
405

406
  return ret;
16✔
407
}
408

409
/***
410
create asn1_object object
411

412
@function new_object
413
@tparam string name_or_oid  short name,long name or oid string
414
@tparam[opt] boolean no_name  true for only oid string, default is false
415
@treturn asn1_object mapping to ASN1_OBJECT in openssl
416
@see asn1_object
417
*/
418

419
/***
420
create asn1_object object
421

422
@function new_object
423
@tparam integer nid ident to asn1_object
424
@treturn asn1_object mapping to ASN1_OBJECT in openssl
425
@see asn1_object
426
*/
427

428
/***
429
create asn1_object object
430

431
@function new_object
432
@tparam table options have sn, ln, oid keys to create asn1_object
433
@treturn asn1_object mapping to ASN1_OBJECT in openssl
434
@see asn1_object
435
*/
436
static int
437
openssl_asn1object_new(lua_State *L)
128✔
438
{
439
  int ret = 0;
128✔
440
  if (lua_type(L, 1) == LUA_TNUMBER) {
128✔
441
    int          nid = luaL_checkint(L, 1);
4✔
442
    ASN1_OBJECT *obj = OBJ_nid2obj(nid);
4✔
443
    if (obj) {
4✔
444
      PUSH_OBJECT(obj, "openssl.asn1_object");
4✔
445
      ret = 1;
4✔
446
    }
447
  } else if (lua_isstring(L, 1)) {
124✔
448
    const char *txt = luaL_checkstring(L, 1);
76✔
449
    int         no_name = lua_isnone(L, 2) ? 0 : lua_toboolean(L, 2);
76✔
450

451
    ASN1_OBJECT *obj = OBJ_txt2obj(txt, no_name);
76✔
452
    if (obj) {
76✔
453
      PUSH_OBJECT(obj, "openssl.asn1_object");
60✔
454
      ret = 1;
60✔
455
    }
456
  } else if (lua_istable(L, 1)) {
48✔
457
    const char  *oid, *sn, *ln;
458
    ASN1_OBJECT *obj;
459
    int          nid;
460

461
    lua_getfield(L, 1, "oid");
16✔
462
    luaL_argcheck(L, lua_isstring(L, -1), 1, "not have oid field or is not string");
16✔
463
    oid = luaL_checkstring(L, -1);
16✔
464
    lua_pop(L, 1);
16✔
465

466
    lua_getfield(L, 1, "sn");
16✔
467
    luaL_argcheck(L, lua_isstring(L, -1), 1, "not have sn field or is not string");
16✔
468
    sn = luaL_checkstring(L, -1);
16✔
469
    lua_pop(L, 1);
16✔
470

471
    lua_getfield(L, 1, "ln");
16✔
472
    luaL_argcheck(L, lua_isstring(L, -1), 1, "not have ln field or is not string");
16✔
473
    ln = luaL_checkstring(L, -1);
16✔
474
    lua_pop(L, 1);
16✔
475

476
    luaL_argcheck(L, OBJ_txt2nid(oid) == NID_undef, 1, "oid already exist");
16✔
477
    luaL_argcheck(L, OBJ_sn2nid(sn) == NID_undef, 1, "sn already exist");
16✔
478
    luaL_argcheck(L, OBJ_ln2nid(ln) == NID_undef, 1, "ln already exist");
16✔
479

480
    nid = OBJ_create(oid, sn, ln);
16✔
481
    if (nid != NID_undef) {
16✔
482
      obj = OBJ_nid2obj(nid);
16✔
483
      PUSH_OBJECT(obj, "openssl.asn1_object");
16✔
484
      ret = 1;
16✔
485
    }
486
  } else if (lua_isnone(L, 1)) {
32✔
487
    ASN1_OBJECT *obj = ASN1_OBJECT_new();
32✔
488
    PUSH_OBJECT(obj, "openssl.asn1_object");
32✔
489
    ret = 1;
32✔
490
  }
491

492
  return ret;
128✔
493
}
494

495
/***
496
convert der encoded asn1type string to object
497
@function asn1type_di2
498
@tparam string der
499
@treturn asn1type object for success, and nil for fail
500
*/
501
static int
502
openssl_asn1type_d2i(lua_State *L)
120✔
503
{
504
  size_t               size;
505
  const unsigned char *data = (const unsigned char *)luaL_checklstring(L, 1, &size);
120✔
506
  ASN1_TYPE           *at = d2i_ASN1_TYPE(NULL, &data, size);
120✔
507
  int                  ret = 0;
120✔
508
  if (at) {
120✔
509
    PUSH_OBJECT(at, "openssl.asn1_type");
120✔
510
    ret = 1;
120✔
511
  }
512
  return ret;
120✔
513
}
514

515
static luaL_Reg R[] = {
516
  { "new_object",          openssl_asn1object_new          },
517

518
  { "new_integer",         openssl_asn1int_new             },
519
  { "new_string",          openssl_asn1string_new          },
520
  { "new_utctime",         openssl_asn1utctime_new         },
521
  { "new_generalizedtime", openssl_asn1generalizedtime_new },
522

523
  { "new_type",            openssl_asn1type_new            },
524
  { "d2i_asn1type",        openssl_asn1type_d2i            },
525

526
  { "get_object",          openssl_get_object              },
527
  { "put_object",          openssl_put_object              },
528

529
  { "tostring",            openssl_asn1_tostring           },
530
  { "txt2nid",             openssl_txt2nid                 },
531

532
  { NULL,                  NULL                            }
533
};
534

535
static int
536
openssl_asn1type_type(lua_State *L)
4✔
537
{
538
  ASN1_TYPE *at = CHECK_OBJECT(1, ASN1_TYPE, "openssl.asn1_type");
4✔
539
  lua_pushinteger(L, at->type);
4✔
540
  return 1;
4✔
541
}
542

543
static int
544
openssl_asn1type_octet(lua_State *L)
12✔
545
{
546
  ASN1_TYPE *at = CHECK_OBJECT(1, ASN1_TYPE, "openssl.asn1_type");
12✔
547
  if (lua_isnone(L, 2)) {
12✔
548
    unsigned char *octet;
549
    int            len = ASN1_TYPE_get_octetstring(at, NULL, 0);
8✔
550
    int            ret = 0;
8✔
551
    octet = OPENSSL_malloc(len + 1);
8✔
552
    len = ASN1_TYPE_get_octetstring(at, octet, len + 1);
8✔
553
    if (len >= 0) {
8✔
554
      lua_pushlstring(L, (const char *)octet, (size_t)len);
8✔
555
      ret = 1;
8✔
556
    }
557
    OPENSSL_free(octet);
8✔
558
    return ret;
8✔
559
  } else {
560
    size_t      size;
561
    const char *octet = luaL_checklstring(L, 2, &size);
4✔
562
    int         ret = ASN1_TYPE_set_octetstring(at, (unsigned char *)octet, size);
4✔
563
    return openssl_pushresult(L, ret);
4✔
564
  }
565
}
566

567
static int
568
openssl_asn1type_cmp(lua_State *L)
120✔
569
{
570
  ASN1_TYPE *at = CHECK_OBJECT(1, ASN1_TYPE, "openssl.asn1_type");
120✔
571
  ASN1_TYPE *ot = CHECK_OBJECT(2, ASN1_TYPE, "openssl.asn1_type");
120✔
572
  int        ret = ASN1_TYPE_cmp(at, ot);
120✔
573
  lua_pushboolean(L, ret == 0);
120✔
574
  return 1;
120✔
575
}
576

577
static int
578
openssl_asn1type_free(lua_State *L)
272✔
579
{
580
  ASN1_TYPE *at = CHECK_OBJECT(1, ASN1_TYPE, "openssl.asn1_type");
272✔
581
  ASN1_TYPE_free(at);
272✔
582
  return 0;
272✔
583
}
584

585
static int
586
openssl_asn1type_asn1string(lua_State *L)
4✔
587
{
588
  ASN1_TYPE *at = CHECK_OBJECT(1, ASN1_TYPE, "openssl.asn1_type");
4✔
589
  int        ret = 0;
4✔
590
  if (at->type != V_ASN1_BOOLEAN && at->type != V_ASN1_OBJECT) {
4✔
591
    ASN1_STRING *as = ASN1_STRING_dup(at->value.asn1_string);
4✔
592
    PUSH_OBJECT(as, "openssl.asn1_string");
4✔
593
    ret = 1;
4✔
594
  }
595
  return ret;
4✔
596
}
597

598
static int
599
openssl_asn1type_i2d(lua_State *L)
152✔
600
{
601
  ASN1_TYPE     *at = CHECK_OBJECT(1, ASN1_TYPE, "openssl.asn1_type");
152✔
602
  unsigned char *out = NULL;
152✔
603
  int            len = i2d_ASN1_TYPE(at, &out);
152✔
604
  int            ret = 0;
152✔
605
  if (len > 0) {
152✔
606
    lua_pushlstring(L, (const char *)out, (size_t)len);
152✔
607
    OPENSSL_free(out);
152✔
608
    ret = 1;
152✔
609
  }
610
  return ret;
152✔
611
}
612

613
int
614
openssl_push_asn1type(lua_State *L, const ASN1_TYPE *type)
124✔
615
{
616
  lua_newtable(L);
124✔
617

618
#define P(V, v)                                                                                    \
619
  case V_##V: {                                                                                    \
620
    V *s = (V *)type->value.ptr;                                                                   \
621
    AUXILIAR_SETLSTR(L, -1, "value", (const char *)s->data, s->length);                            \
622
    break;                                                                                         \
623
  }
624

625
  switch (type->type) {
124✔
626
  case V_ASN1_BOOLEAN:
4✔
627
    AUXILIAR_SET(L, -1, "value", type->value.boolean, boolean);
4✔
628
    break;
4✔
UNCOV
629
  case V_ASN1_OBJECT: {
×
UNCOV
630
    ASN1_OBJECT *o = OBJ_dup(type->value.object);
×
631

UNCOV
632
    lua_pushliteral(L, "value");
×
UNCOV
633
    PUSH_OBJECT(o, "openssl.asn1_object");
×
UNCOV
634
    lua_rawset(L, -3);
×
635

UNCOV
636
    break;
×
637
  }
638
    P(ASN1_INTEGER, integer);
4✔
639
    P(ASN1_ENUMERATED, enumerated);
4✔
640
    P(ASN1_BIT_STRING, bit_string);
8✔
641
    P(ASN1_OCTET_STRING, octet_string);
28✔
642
    P(ASN1_PRINTABLESTRING, printablestring);
4✔
643
    P(ASN1_T61STRING, t61string);
4✔
644
    P(ASN1_IA5STRING, ia5string);
4✔
645
    P(ASN1_GENERALSTRING, generalstring);
4✔
646
    P(ASN1_BMPSTRING, bmpstring);
4✔
UNCOV
647
    P(ASN1_UNIVERSALSTRING, universalstring);
×
648
    P(ASN1_UTCTIME, utctime);
4✔
UNCOV
649
    P(ASN1_GENERALIZEDTIME, generalizedtime);
×
650
    P(ASN1_VISIBLESTRING, visiblestring);
4✔
651
    P(ASN1_UTF8STRING, utf8string);
4✔
652

653
  default: {
44✔
654
    ASN1_STRING *s = (ASN1_STRING *)type->value.asn1_string;
44✔
655
    AUXILIAR_SETLSTR(L, -1, "value", (const char *)s->data, s->length);
44✔
656
    break;
44✔
657
  }
658
  }
659
#undef P
660

661
  {
662
    unsigned char *dat = NULL;
124✔
663
    int            i = i2d_ASN1_TYPE((ASN1_TYPE *)type, &dat);
124✔
664
    if (i > 0) {
124✔
665
      AUXILIAR_SETLSTR(L, -1, "der", (const char *)dat, i);
124✔
666
      OPENSSL_free(dat);
124✔
667
    }
668
  }
669

670
  lua_pushinteger(L, type->type);
124✔
671
  lua_setfield(L, -2, "type");
124✔
672
  return 1;
124✔
673
}
674

675
static int
676
openssl_asn1type_info(lua_State *L)
104✔
677
{
678
  ASN1_TYPE *type = CHECK_OBJECT(1, ASN1_TYPE, "openssl.asn1_type");
104✔
679
  return openssl_push_asn1type(L, type);
104✔
680
}
681

682
static luaL_Reg asn1type_funcs[] = {
683
  { "type",       openssl_asn1type_type       },
684
  { "octet",      openssl_asn1type_octet      },
685
  { "cmp",        openssl_asn1type_cmp        },
686
  { "info",       openssl_asn1type_info       },
687

688
  { "i2d",        openssl_asn1type_i2d        },
689
  { "asn1string", openssl_asn1type_asn1string },
690

691
  { "__tostring", auxiliar_tostring           },
692
  { "__eq",       openssl_asn1type_cmp        },
693
  { "__gc",       openssl_asn1type_free       },
694

695
  { NULL,         NULL                        }
696
};
697

698
/***
699
openssl.asn1_object object
700
@type asn1_object
701
*/
702
/***
703
get nid of asn1_object.
704

705
@function nid
706
@treturn integer nid of asn1_object
707
*/
708
static int
709
openssl_asn1object_nid(lua_State *L)
32✔
710
{
711
  ASN1_OBJECT *o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object");
32✔
712
  lua_pushinteger(L, OBJ_obj2nid(o));
32✔
713
  return 1;
32✔
714
}
715

716
/***
717
get name of asn1_object.
718

719
@function name
720
@treturn string short name and followed by long name of asn1_object
721
*/
722
static int
723
openssl_asn1object_name(lua_State *L)
4✔
724
{
725
  ASN1_OBJECT *o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object");
4✔
726
  int          nid = OBJ_obj2nid(o);
4✔
727
  lua_pushstring(L, OBJ_nid2sn(nid));
4✔
728
  lua_pushstring(L, OBJ_nid2ln(nid));
4✔
729
  return 2;
4✔
730
}
731

732
/***
733
get long name of asn1_object.
734

735
@function ln
736
@treturn string long name of asn1_object
737
*/
738
static int
739
openssl_asn1object_ln(lua_State *L)
20✔
740
{
741
  ASN1_OBJECT *o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object");
20✔
742
  const char  *s = OBJ_nid2ln(OBJ_obj2nid(o));
20✔
743
  int          ret = 0;
20✔
744
  if (s) {
20✔
745
    lua_pushstring(L, s);
20✔
746
    ret = 1;
20✔
747
  }
748
  return ret;
20✔
749
}
750

751
/***
752
get short name of asn1_object.
753
@function sn
754
@treturn string short name of asn1_object
755
*/
756
static int
757
openssl_asn1object_sn(lua_State *L)
12✔
758
{
759
  ASN1_OBJECT *o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object");
12✔
760
  const char  *s = OBJ_nid2sn(OBJ_obj2nid(o));
12✔
761
  int          ret = 0;
12✔
762
  if (s) {
12✔
763
    lua_pushstring(L, s);
12✔
764
    ret = 1;
12✔
765
  }
766
  return ret;
12✔
767
}
768

769
/***
770
get text of asn1_object.
771

772
@function txt
773
@tparam[opt] boolean no_name true for only oid or name, default with false
774
@treturn string long or short name, even oid of asn1_object
775
*/
776
static int
777
openssl_asn1object_txt(lua_State *L)
72✔
778
{
779
  ASN1_OBJECT *o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object");
72✔
780
  int          no_name = lua_isnone(L, 2) ? 0 : lua_toboolean(L, 2);
72✔
781

782
  luaL_Buffer B;
783
  luaL_buffinit(L, &B);
72✔
784

785
  luaL_addsize(&B, OBJ_obj2txt(luaL_prepbuffer(&B), LUAL_BUFFERSIZE, o, no_name));
72✔
786
  luaL_pushresult(&B);
72✔
787
  return 1;
72✔
788
}
789

790
/***
791
compare two asn1_objects, if equals return true
792

793
@function equals
794
@tparam asn1_object another to compre
795
@treturn boolean true if equals
796
*/
797
static int
798
openssl_asn1object_equals(lua_State *L)
84✔
799
{
800
  ASN1_OBJECT *o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object");
84✔
801
  ASN1_OBJECT *a = CHECK_OBJECT(2, ASN1_OBJECT, "openssl.asn1_object");
84✔
802

803
  lua_pushboolean(L, OBJ_cmp(o, a) == 0);
84✔
804
  return 1;
84✔
805
}
806

807
/***
808
get data of asn1_object
809

810
@function data
811
@treturn string asn1_object data
812
*/
813
static int
814
openssl_asn1object_data(lua_State *L)
20✔
815
{
816
  ASN1_OBJECT *s = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object");
20✔
817
  BIO         *bio = BIO_new(BIO_s_mem());
20✔
818
  BUF_MEM     *buf;
819

820
  i2a_ASN1_OBJECT(bio, s);
20✔
821
  BIO_get_mem_ptr(bio, &buf);
20✔
822
  lua_pushlstring(L, buf->data, buf->length);
20✔
823
  BIO_free(bio);
20✔
824
  return 1;
20✔
825
}
826

827
static int
828
openssl_asn1object_free(lua_State *L)
436✔
829
{
830
  ASN1_OBJECT *s = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object");
436✔
831
  ASN1_OBJECT_free(s);
436✔
832
  return 0;
436✔
833
}
834

835
/***
836
make a clone of asn1_object
837

838
@function dup
839
@treturn asn1_object clone for self
840
*/
841
static int
842
openssl_asn1object_dup(lua_State *L)
4✔
843
{
844
  ASN1_OBJECT *o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object");
4✔
845
  ASN1_OBJECT *a = OBJ_dup(o);
4✔
846

847
  PUSH_OBJECT(a, "openssl.asn1_object");
4✔
848
  return 1;
4✔
849
}
850

851
/***
852
read der in to asn1_object
853

854
@function d2i
855
@treturn boolean
856
*/
857
static int
858
openssl_asn1object_d2i(lua_State *L)
32✔
859
{
860
  size_t               l;
861
  ASN1_OBJECT         *o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object");
32✔
862
  const unsigned char *p = (const unsigned char *)luaL_checklstring(L, 2, &l);
32✔
863

864
  lua_pushboolean(L, d2i_ASN1_OBJECT(&o, &p, l) != NULL);
32✔
865
  return 1;
32✔
866
}
867

868
/***
869
get der encoded of asn1_object
870

871
@function i2d
872
@treturn string
873
*/
874
static int
875
openssl_asn1object_i2d(lua_State *L)
32✔
876
{
877
  ASN1_OBJECT *o = CHECK_OBJECT(1, ASN1_OBJECT, "openssl.asn1_object");
32✔
878
  int          ret = i2d_ASN1_OBJECT(o, NULL);
32✔
879
  if (ret > 0) {
32✔
880
    unsigned char *p, *O;
881
    p = O = OPENSSL_malloc(ret);
32✔
882
    ret = i2d_ASN1_OBJECT(o, &p);
32✔
883
    if (ret > 0) {
32✔
884
      lua_pushlstring(L, (const char *)O, ret);
32✔
885
      ret = 1;
32✔
886
    }
887
    OPENSSL_free(O);
32✔
888
  }
889
  return ret == 1 ? 1 : 0;
32✔
890
}
891

892
static luaL_Reg asn1obj_funcs[] = {
893
  { "nid",        openssl_asn1object_nid    },
894
  { "name",       openssl_asn1object_name   },
895
  { "ln",         openssl_asn1object_ln     },
896
  { "sn",         openssl_asn1object_sn     },
897
  { "txt",        openssl_asn1object_txt    },
898
  { "dup",        openssl_asn1object_dup    },
899
  { "data",       openssl_asn1object_data   },
900
  { "equals",     openssl_asn1object_equals },
901
  { "d2i",        openssl_asn1object_d2i    },
902
  { "i2d",        openssl_asn1object_i2d    },
903

904
  { "__eq",       openssl_asn1object_equals },
905
  { "__gc",       openssl_asn1object_free   },
906
  { "__tostring", auxiliar_tostring         },
907

908
  { NULL,         NULL                      }
909
};
910

911
/***
912
openssl.asn1_integer object
913
@type asn1_integer
914
*/
915
static int
916
openssl_asn1int_bn(lua_State *L)
8✔
917
{
918
  ASN1_INTEGER *ai = CHECK_OBJECT(1, ASN1_INTEGER, "openssl.asn1_integer");
8✔
919
  if (lua_isnone(L, 2)) {
8✔
920
    BIGNUM *B = ASN1_INTEGER_to_BN(ai, NULL);
4✔
921
    PUSH_OBJECT(B, "openssl.bn");
4✔
922
  } else {
923
    BIGNUM *B = BN_get(L, 2);
4✔
924
    BN_to_ASN1_INTEGER(B, ai);
4✔
925
    BN_free(B);
4✔
926
    lua_pushvalue(L, 1);
4✔
927
  }
928
  return 1;
8✔
929
}
930

931
/***
932
openssl.asn1_string object
933
@type asn1_string
934
*/
935

936
/***
937
@function set
938
*/
939
static int
940
openssl_asn1group_set(lua_State *L)
20✔
941
{
942
  ASN1_STRING *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group");
20✔
943
  int          ret = 1;
20✔
944

945
  switch (s->type) {
20✔
946
  case V_ASN1_INTEGER: {
4✔
947
    ASN1_INTEGER *ai = CHECK_OBJECT(1, ASN1_INTEGER, "openssl.asn1_integer");
4✔
948
    long          v = luaL_checklong(L, 2);
4✔
949
    ret = ASN1_INTEGER_set(ai, v);
4✔
950
    return openssl_pushresult(L, ret);
4✔
951
  }
952
  case V_ASN1_UTCTIME: {
8✔
953
    ASN1_TIME *a = CHECK_OBJECT(1, ASN1_TIME, "openssl.asn1_time");
8✔
954
    if (lua_type(L, 2) == LUA_TNUMBER) {
8✔
955
      time_t t = luaL_checkinteger(L, 2);
4✔
956
      ASN1_UTCTIME_set(a, t);
4✔
957
    } else if (lua_isstring(L, 2)) {
4✔
958
      ret = ASN1_TIME_set_string(a, lua_tostring(L, 2));
4✔
959
    } else
UNCOV
960
      luaL_error(L, "only accpet number or string");
×
961
    return openssl_pushresult(L, ret);
8✔
962
  }
963
  case V_ASN1_GENERALIZEDTIME: {
8✔
964
    ASN1_TIME *a = CHECK_OBJECT(1, ASN1_TIME, "openssl.asn1_time");
8✔
965
    if (lua_type(L, 2) == LUA_TNUMBER) {
8✔
966
      time_t t = luaL_checkinteger(L, 2);
4✔
967
      ASN1_GENERALIZEDTIME_set(a, t);
4✔
968
    } else if (lua_isstring(L, 2)) {
4✔
969
      ret = ASN1_GENERALIZEDTIME_set_string(a, lua_tostring(L, 2));
4✔
970
    } else
UNCOV
971
      luaL_error(L, "only accpet number or string");
×
972
    return openssl_pushresult(L, ret);
8✔
973
  }
UNCOV
974
  default:
×
UNCOV
975
    break;
×
976
  }
UNCOV
977
  return 0;
×
978
}
979

980
static time_t
981
ASN1_TIME_get(ASN1_TIME *time, time_t off)
8✔
982
{
983
  struct tm   t;
984
  const char *str = (const char *)time->data;
8✔
985
  size_t      i = 0;
8✔
986

987
  memset(&t, 0, sizeof(t));
8✔
988

989
  if (time->type == V_ASN1_UTCTIME) /* two digit year */ {
8✔
990
    t.tm_year = (str[i++] - '0') * 10;
4✔
991
    t.tm_year += (str[i++] - '0');
4✔
992
    if (t.tm_year < 70) t.tm_year += 100;
4✔
993
  } else if (time->type == V_ASN1_GENERALIZEDTIME) /* four digit year */ {
4✔
994
    t.tm_year = (str[i++] - '0') * 1000;
4✔
995
    t.tm_year += (str[i++] - '0') * 100;
4✔
996
    t.tm_year += (str[i++] - '0') * 10;
4✔
997
    t.tm_year += (str[i++] - '0');
4✔
998
    t.tm_year -= 1900;
4✔
999
  }
1000
  t.tm_mon = (str[i++] - '0') * 10;
8✔
1001
  t.tm_mon += (str[i++] - '0') - 1;  // -1 since January is 0 not 1.
8✔
1002
  t.tm_mday = (str[i++] - '0') * 10;
8✔
1003
  t.tm_mday += (str[i++] - '0');
8✔
1004
  t.tm_hour = (str[i++] - '0') * 10;
8✔
1005
  t.tm_hour += (str[i++] - '0');
8✔
1006
  t.tm_min = (str[i++] - '0') * 10;
8✔
1007
  t.tm_min += (str[i++] - '0');
8✔
1008
  t.tm_sec = (str[i++] - '0') * 10;
8✔
1009
  t.tm_sec += (str[i++] - '0');
8✔
1010

1011
  /* Note: we did not adjust the time based on time zone information */
1012
  return mktime(&t) + off;
8✔
1013
}
1014

1015
/***
1016
@function get
1017
@treturn userdata object created
1018
*/
1019
static int
1020
openssl_asn1group_get(lua_State *L)
12✔
1021
{
1022
  ASN1_STRING *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group");
12✔
1023
  int          ret = 0;
12✔
1024
  switch (s->type) {
12✔
1025
  case V_ASN1_INTEGER: {
4✔
1026
    ASN1_INTEGER *ai = CHECK_OBJECT(1, ASN1_INTEGER, "openssl.asn1_integer");
4✔
1027
    BIGNUM       *bn = ASN1_INTEGER_to_BN(ai, NULL);
4✔
1028
    PUSH_OBJECT(bn, "openssl.bn");
4✔
1029
    ret = 1;
4✔
1030
    break;
4✔
1031
  }
1032
  case V_ASN1_UTCTIME:
8✔
1033
  case V_ASN1_GENERALIZEDTIME: {
1034
    ASN1_TIME *at = CHECK_OBJECT(1, ASN1_TIME, "openssl.asn1_time");
8✔
1035
    time_t     get = ASN1_TIME_get(at, 0);
8✔
1036
    lua_pushnumber(L, (lua_Number)get);
8✔
1037
    ret = 1;
8✔
1038
    break;
8✔
1039
  }
UNCOV
1040
  default:
×
UNCOV
1041
    break;
×
1042
  }
1043
  return ret;
12✔
1044
}
1045

1046
/***
1047
@function i2d
1048
@treturn string result
1049
*/
1050
static int
1051
openssl_asn1group_i2d(lua_State *L)
24✔
1052
{
1053
  ASN1_STRING   *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group");
24✔
1054
  int            len = 0;
24✔
1055
  unsigned char *out = NULL;
24✔
1056

1057
#define P(T)                                                                                       \
1058
  case V_##T: {                                                                                    \
1059
    T *v = (T *)s;                                                                                 \
1060
    len = i2d_##T(v, &out);                                                                        \
1061
    break;                                                                                         \
1062
  }
1063

1064
  switch (s->type) {
24✔
1065
    /*
1066
    P(ASN1_BOOLEAN);
1067
    case V_ASN1_BOOLEAN:
1068
    {
1069
      ASN1_BOOLEAN b = (ASN1_BOOLEAN)(intptr_t)s;
1070
      len = i2d_ASN1_BOOLEAN(b, &out);
1071
      break;
1072
    }
1073
    */
1074
    P(ASN1_INTEGER);
16✔
1075
    /*
1076
    P(ASN1_NEG_INTEGER);
1077
    */
UNCOV
1078
    P(ASN1_BIT_STRING);
×
UNCOV
1079
    P(ASN1_OCTET_STRING);
×
UNCOV
1080
    P(ASN1_NULL);
×
UNCOV
1081
    P(ASN1_OBJECT);
×
1082
    /*
1083
    P(ASN1_OBJECT_DESCRIPTOR);
1084
    P(ASN1_EXTERNAL);
1085
    P(ASN1_REAL);
1086
    */
UNCOV
1087
    P(ASN1_ENUMERATED);
×
1088
    /*
1089
    P(ASN1_NEG_ENUMERATED);
1090
    */
1091
    P(ASN1_UTF8STRING);
×
1092
    /*
1093
    P(ASN1_SEQUENCE);
1094
    P(ASN1_SET);
1095
    P(ASN1_NUMERICSTRING);
1096
    */
UNCOV
1097
    P(ASN1_PRINTABLESTRING);
×
UNCOV
1098
    P(ASN1_T61STRING);
×
1099
    /*
1100
    P(ASN1_TELETEXSTRING);
1101
    P(ASN1_VIDEOTEXSTRING);
1102
    */
1103
    P(ASN1_IA5STRING);
×
1104
    P(ASN1_UTCTIME);
4✔
1105
    P(ASN1_GENERALIZEDTIME);
4✔
1106
    /*
1107
    P(ASN1_GRAPHICSTRING);
1108
    P(ASN1_ISO64STRING);
1109
    */
1110
    P(ASN1_VISIBLESTRING);
×
UNCOV
1111
    P(ASN1_GENERALSTRING);
×
UNCOV
1112
    P(ASN1_UNIVERSALSTRING);
×
UNCOV
1113
    P(ASN1_BMPSTRING);
×
UNCOV
1114
  default:
×
1115
    break;
×
1116
  }
1117
#undef P
1118

1119
  if (len > 0) {
24✔
1120
    lua_pushlstring(L, (const char *)out, len);
24✔
1121
    OPENSSL_free(out);
24✔
1122
    return 1;
24✔
1123
  }
1124
  return openssl_pushresult(L, len);
×
1125
}
1126

1127
/***
1128
@function d2i
1129
@treturn boolean success status
1130
*/
1131
static int
1132
openssl_asn1group_d2i(lua_State *L)
12✔
1133
{
1134
  size_t               len;
1135
  ASN1_STRING         *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group");
12✔
1136
  const unsigned char *der = (const unsigned char *)luaL_checklstring(L, 2, &len);
12✔
1137

1138
#define P(T)                                                                                       \
1139
  case V_##T: {                                                                                    \
1140
    T *v = (T *)s;                                                                                 \
1141
    v = d2i_##T(&v, &der, (long)len);                                                              \
1142
    if (v == NULL)                                                                                 \
1143
      return openssl_pushresult(L, -1);                                                            \
1144
    else                                                                                           \
1145
      lua_pushvalue(L, 1);                                                                         \
1146
    break;                                                                                         \
1147
  }
1148

1149
  switch (s->type) {
12✔
1150
    /*
1151
    P(ASN1_BOOLEAN);
1152
    case V_ASN1_BOOLEAN:
1153
    {
1154
      ASN1_BOOLEAN b = (ASN1_BOOLEAN)(intptr_t)s;
1155
      b = d2i_ASN1_BOOLEAN(&b, &der, (long)len);
1156
      lua_pushboolean(L, b);
1157
      return 1;
1158
    }
1159
    */
1160
    P(ASN1_INTEGER);
4✔
1161
    /*
1162
    P(ASN1_NEG_INTEGER);
1163
    */
UNCOV
1164
    P(ASN1_BIT_STRING);
×
UNCOV
1165
    P(ASN1_OCTET_STRING);
×
UNCOV
1166
    P(ASN1_NULL);
×
UNCOV
1167
    P(ASN1_OBJECT);
×
1168
    /*
1169
    P(ASN1_OBJECT_DESCRIPTOR);
1170
    P(ASN1_EXTERNAL);
1171
    P(ASN1_REAL);
1172
    */
UNCOV
1173
    P(ASN1_ENUMERATED);
×
1174
    /*
1175
    P(ASN1_NEG_ENUMERATED);
1176
    */
1177
    P(ASN1_UTF8STRING);
×
1178
    /*
1179
    P(ASN1_SEQUENCE);
1180
    P(ASN1_SET);
1181
    P(ASN1_NUMERICSTRING);
1182
    */
UNCOV
1183
    P(ASN1_PRINTABLESTRING);
×
UNCOV
1184
    P(ASN1_T61STRING);
×
1185
    /*
1186
    P(ASN1_TELETEXSTRING);
1187
    P(ASN1_VIDEOTEXSTRING);
1188
    */
1189
    P(ASN1_IA5STRING);
×
1190
    P(ASN1_UTCTIME);
4✔
1191
    P(ASN1_GENERALIZEDTIME);
4✔
1192
    /*
1193
    P(ASN1_GRAPHICSTRING);
1194
    P(ASN1_ISO64STRING);
1195
    */
1196
    P(ASN1_VISIBLESTRING);
×
UNCOV
1197
    P(ASN1_GENERALSTRING);
×
UNCOV
1198
    P(ASN1_UNIVERSALSTRING);
×
UNCOV
1199
    P(ASN1_BMPSTRING);
×
UNCOV
1200
  default:
×
1201
    return 0;
×
1202
  }
1203
#undef P
1204

1205
  return 1;
12✔
1206
}
1207

1208
/***
1209
get type of asn1_string
1210

1211
@function type
1212
@treturn string type of asn1_string
1213
@see new_string
1214
*/
1215
static int
1216
openssl_asn1group_type(lua_State *L)
12✔
1217
{
1218
  ASN1_STRING *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group");
12✔
1219
  int          type = ASN1_STRING_type(s);
12✔
1220
  int          i, ret = 1;
12✔
1221
  lua_pushinteger(L, type);
12✔
1222
  for (i = 0; i < TAG_IDX_LENGTH; i++) {
212✔
1223
    if (type == asn1_const[i + TAG_IDX_OFFSET].val) {
212✔
1224
      lua_pushstring(L, asn1_const[i + TAG_IDX_OFFSET].name);
12✔
1225
      ret += 1;
12✔
1226
      break;
12✔
1227
    }
1228
  }
1229
  return ret;
12✔
1230
}
1231

1232
/***
1233
get length two asn1_string
1234

1235
@function length
1236
@treturn integer length of asn1_string
1237
@usage
1238
  local astr = asn1.new_string('ABCD')
1239
  print('length:',#astr)
1240
  print('length:',astr:length())
1241
  assert(#astr==astr:length,"must equals")
1242
*/
1243
static int
1244
openssl_asn1group_length(lua_State *L)
12✔
1245
{
1246
  ASN1_STRING *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group");
12✔
1247
  lua_pushinteger(L, ASN1_STRING_length(s));
12✔
1248
  return 1;
12✔
1249
}
1250

1251
/***
1252
get data of asn1_string
1253

1254
@function data
1255
@treturn string raw data of asn1_string
1256
*/
1257

1258
/***
1259
set data of asn1_string
1260

1261
@function data
1262
@tparam string data set to asn1_string
1263
@treturn boolean success if value set true, or follow by errmsg
1264
@treturn string fail error message
1265
*/
1266
static int
1267
openssl_asn1group_data(lua_State *L)
8✔
1268
{
1269
  ASN1_STRING *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group");
8✔
1270
  if (lua_isnone(L, 2))
8✔
1271
    lua_pushlstring(L, (const char *)ASN1_STRING_get0_data(s), ASN1_STRING_length(s));
4✔
1272
  else {
1273
    size_t      l;
1274
    const char *data = luaL_checklstring(L, 2, &l);
4✔
1275
    int         ret = ASN1_STRING_set(s, data, l);
4✔
1276
    lua_pushboolean(L, ret);
4✔
1277
  }
1278
  return 1;
8✔
1279
}
1280

1281
/***
1282
compare two asn1_string, if equals return true
1283

1284
@function equals
1285
@tparam asn1_string another to compre
1286
@treturn boolean true if equals
1287
@usage
1288
  local obj = astr:dup()
1289
  assert(obj==astr, "must equals")
1290
*/
1291
static int
1292
openssl_asn1group_eq(lua_State *L)
52✔
1293
{
1294
  ASN1_STRING *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group");
52✔
1295
  ASN1_STRING *ss = CHECK_GROUP(2, ASN1_STRING, "openssl.asn1group");
52✔
1296

1297
  lua_pushboolean(L, (s->type == ss->type && ASN1_STRING_cmp(s, ss) == 0));
52✔
1298
  return 1;
52✔
1299
}
1300

1301
static int
1302
openssl_asn1group_free(lua_State *L)
976✔
1303
{
1304
  ASN1_STRING *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group");
976✔
1305
  ASN1_STRING_free(s);
976✔
1306
  return 0;
976✔
1307
}
1308

1309
/***
1310
convert asn1_string to lua string
1311

1312
@function __tostring
1313
@treturn string result format match with type:data
1314
*/
1315
static int
1316
openssl_asn1group_tostring(lua_State *L)
84✔
1317
{
1318
  ASN1_STRING *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group");
84✔
1319
  int          ret = 0;
84✔
1320

1321
  if (s) {
84✔
1322
    int type = ASN1_STRING_type(s);
84✔
1323

1324
    switch (type) {
84✔
1325
    case V_ASN1_INTEGER:
4✔
1326
    case V_ASN1_BIT_STRING: {
1327
      BIGNUM *bn
1328
        = BN_bin2bn((const unsigned char *)ASN1_STRING_get0_data(s), ASN1_STRING_length(s), NULL);
4✔
1329
      char *str = BN_bn2hex(bn);
4✔
1330
      lua_pushstring(L, str);
4✔
1331
      BN_free(bn);
4✔
1332
      OPENSSL_free(str);
4✔
1333
      break;
4✔
1334
    }
1335
    default:
80✔
1336
      lua_pushlstring(L, (const char *)ASN1_STRING_get0_data(s), ASN1_STRING_length(s));
80✔
1337
      break;
80✔
1338
    }
1339
    ret = 1;
84✔
1340
  }
1341
  return ret;
84✔
1342
}
1343

1344
/***
1345
get data as printable encode string
1346

1347
@function toprint
1348
@treturn string printable encoded string
1349
*/
1350
static int
1351
openssl_asn1group_toprint(lua_State *L)
36✔
1352
{
1353
  ASN1_STRING  *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group");
36✔
1354
  unsigned long flags = luaL_optint(L, 2, 0);
36✔
1355
  BIO          *out = BIO_new(BIO_s_mem());
36✔
1356
  BUF_MEM      *mem;
1357
  switch (s->type) {
36✔
1358
  case V_ASN1_UTCTIME: {
12✔
1359
    ASN1_TIME *a = (ASN1_TIME *)s;
12✔
1360
    ASN1_TIME_print(out, a);
12✔
1361
    break;
12✔
1362
  }
1363
  case V_ASN1_GENERALIZEDTIME: {
4✔
1364
    ASN1_GENERALIZEDTIME *a = (ASN1_GENERALIZEDTIME *)s;
4✔
1365
    ASN1_GENERALIZEDTIME_print(out, a);
4✔
1366
    break;
4✔
1367
  }
1368
  default:
20✔
1369
    ASN1_STRING_print_ex(out, s, flags);
20✔
1370
  }
1371

1372
  BIO_get_mem_ptr(out, &mem);
36✔
1373
  lua_pushlstring(L, mem->data, mem->length);
36✔
1374
  BIO_free(out);
36✔
1375
  return 1;
36✔
1376
}
1377

1378
/***
1379
get data as utf8 encode string
1380

1381
@function toutf8
1382
@treturn string utf8 encoded string
1383
*/
1384
static int
1385
openssl_asn1group_toutf8(lua_State *L)
12✔
1386
{
1387
  ASN1_STRING   *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group");
12✔
1388
  unsigned char *out = NULL;
12✔
1389
  int            len = ASN1_STRING_to_UTF8(&out, s);
12✔
1390
  if (out) {
12✔
1391
    lua_pushlstring(L, (const char *)out, len);
12✔
1392
    OPENSSL_free(out);
12✔
1393
  }
1394
  return 1;
12✔
1395
}
1396

1397
/***
1398
duplicate a new asn1_string
1399

1400
@function dup
1401
@treturn asn1_string clone for self
1402
*/
1403
static int
1404
openssl_asn1group_dup(lua_State *L)
4✔
1405
{
1406
  ASN1_STRING *s = CHECK_GROUP(1, ASN1_STRING, "openssl.asn1group");
4✔
1407
  openssl_push_asn1(L, s, s->type);
4✔
1408
  return 1;
4✔
1409
}
1410

1411
static int
1412
openssl_asn1time_check(lua_State *L)
8✔
1413
{
1414
  ASN1_TIME *a = CHECK_OBJECT(1, ASN1_TIME, "openssl.asn1_time");
8✔
1415
  int        ret = ASN1_TIME_check(a);
8✔
1416
  return openssl_pushresult(L, ret);
8✔
1417
}
1418

1419
static int
1420
openssl_asn1time_adj(lua_State *L)
8✔
1421
{
1422
  ASN1_TIME *at = CHECK_OBJECT(1, ASN1_TIME, "openssl.asn1_time");
8✔
1423
  time_t     t = luaL_checkinteger(L, 2);
8✔
1424
  int        offset_day = luaL_optint(L, 3, 0);
8✔
1425
  long       offset_sec = luaL_optlong(L, 4, 0);
8✔
1426

1427
  switch (at->type) {
8✔
1428
  case V_ASN1_UTCTIME: {
4✔
1429
    ASN1_UTCTIME *a = (ASN1_UTCTIME *)at;
4✔
1430
    ASN1_UTCTIME_adj(a, t, offset_day, offset_sec);
4✔
1431
    break;
4✔
1432
  }
1433
  case V_ASN1_GENERALIZEDTIME: {
4✔
1434
    ASN1_GENERALIZEDTIME *a = (ASN1_UTCTIME *)at;
4✔
1435
    ASN1_GENERALIZEDTIME_adj(a, t, offset_day, offset_sec);
4✔
1436
    break;
4✔
1437
  }
1438
  }
1439
  lua_pushvalue(L, 1);
8✔
1440
  return 1;
8✔
1441
}
1442

1443
#if !defined(LIBRESSL_VERSION_NUMBER)
1444
static int
1445
openssl_asn1time_diff(lua_State *L)
16✔
1446
{
1447
  int        day, sec, ret;
1448
  ASN1_TIME *from = CHECK_OBJECT(1, ASN1_TIME, "openssl.asn1_time");
16✔
1449
  ASN1_TIME *to = lua_isnoneornil(L, 2) ? NULL : CHECK_OBJECT(2, ASN1_TIME, "openssl.asn1_time");
16✔
1450

1451
  luaL_argcheck(L, to->type == from->type, 2, "asn1_time with mismatched type");
16✔
1452

1453
  ret = ASN1_TIME_diff(&day, &sec, from, to);
16✔
1454
  if (ret == 1) {
16✔
1455
    lua_pushinteger(L, day);
16✔
1456
    lua_pushinteger(L, sec);
16✔
1457
  }
1458
  return ret == 1 ? 2 : openssl_pushresult(L, ret);
16✔
1459
}
1460
#endif
1461

1462
static luaL_Reg asn1str_funcs[] = {
1463
  /* asn1string */
1464
  { "length",     openssl_asn1group_length   },
1465
  { "type",       openssl_asn1group_type     },
1466
  { "data",       openssl_asn1group_data     },
1467

1468
  { "dup",        openssl_asn1group_dup      },
1469

1470
  { "toutf8",     openssl_asn1group_toutf8   },
1471
  { "toprint",    openssl_asn1group_toprint  },
1472
  { "tostring",   openssl_asn1group_tostring },
1473

1474
  { "__len",      openssl_asn1group_length   },
1475
  { "__tostring", auxiliar_tostring          },
1476

1477
  { "__eq",       openssl_asn1group_eq       },
1478
  { "__gc",       openssl_asn1group_free     },
1479

1480
  { "set",        openssl_asn1group_set      },
1481
  { "get",        openssl_asn1group_get      },
1482
  { "i2d",        openssl_asn1group_i2d      },
1483
  { "d2i",        openssl_asn1group_d2i      },
1484

1485
  /* asn1int */
1486
  { "bn",         openssl_asn1int_bn         },
1487

1488
  /* asn1time,asn1generalizedtime */
1489
  { "adj",        openssl_asn1time_adj       },
1490
#if !defined(LIBRESSL_VERSION_NUMBER)
1491
  { "diff",       openssl_asn1time_diff      },
1492
#endif
1493
  { "check",      openssl_asn1time_check     },
1494

1495
  { NULL,         NULL                       }
1496
};
1497

1498
int
1499
luaopen_asn1(lua_State *L)
43✔
1500
{
1501
  auxiliar_newclass(L, "openssl.asn1_object", asn1obj_funcs);
43✔
1502
  auxiliar_newclass(L, "openssl.asn1_type", asn1type_funcs);
43✔
1503

1504
  auxiliar_newclass(L, "openssl.asn1_string", asn1str_funcs);
43✔
1505
  auxiliar_newclass(L, "openssl.asn1_integer", asn1str_funcs);
43✔
1506
  auxiliar_newclass(L, "openssl.asn1_time", asn1str_funcs);
43✔
1507

1508
  auxiliar_add2group(L, "openssl.asn1_time", "openssl.asn1group");
43✔
1509
  auxiliar_add2group(L, "openssl.asn1_string", "openssl.asn1group");
43✔
1510
  auxiliar_add2group(L, "openssl.asn1_integer", "openssl.asn1group");
43✔
1511

1512
  lua_newtable(L);
43✔
1513
  luaL_setfuncs(L, R, 0);
43✔
1514

1515
  auxiliar_enumerate(L, -1, asn1_const);
43✔
1516

1517
  return 1;
43✔
1518
}
1519

1520
ASN1_OBJECT *
1521
openssl_get_asn1object(lua_State *L, int idx, int nil)
944✔
1522
{
1523
  ASN1_OBJECT *obj = NULL;
944✔
1524

1525
  if (lua_isstring(L, idx)) {
944✔
1526
    obj = OBJ_txt2obj(lua_tostring(L, idx), 0);
888✔
1527
  } else if (auxiliar_getclassudata(L, "openssl.asn1_object", idx) != NULL) {
56✔
1528
    ASN1_OBJECT *in = CHECK_OBJECT(idx, ASN1_OBJECT, "openssl.asn1_object");
56✔
1529
    obj = OBJ_dup(in);
56✔
1530
  }
1531

1532
  return obj;
944✔
1533
}
1534

1535
int
1536
openssl_push_asn1object(lua_State *L, const ASN1_OBJECT *obj)
316✔
1537
{
1538
  ASN1_OBJECT *dup = OBJ_dup(obj);
316✔
1539
  PUSH_OBJECT(dup, "openssl.asn1_object");
316✔
1540
  return 1;
316✔
1541
}
1542

1543
int
1544
openssl_push_asn1(lua_State *L, const ASN1_STRING *string, int type)
672✔
1545
{
1546
  if ((string->type & V_ASN1_GENERALIZEDTIME) == V_ASN1_GENERALIZEDTIME && type == V_ASN1_UTCTIME)
672✔
1547
    type = V_ASN1_GENERALIZEDTIME;
12✔
1548
  else if ((string->type & V_ASN1_UTCTIME) == V_ASN1_UTCTIME && type == V_ASN1_GENERALIZEDTIME)
660✔
UNCOV
1549
    type = V_ASN1_UTCTIME;
×
1550
  else if (type == V_ASN1_UNDEF)
660✔
1551
    type = string->type;
76✔
1552

1553
  switch (type) {
672✔
1554
  case V_ASN1_INTEGER: {
100✔
1555
    ASN1_INTEGER *dup = ASN1_INTEGER_dup((ASN1_INTEGER *)string);
100✔
1556
    PUSH_OBJECT(dup, "openssl.asn1_integer");
100✔
1557
    return 1;
100✔
1558
  }
1559
  case V_ASN1_UTCTIME:
256✔
1560
  case V_ASN1_GENERALIZEDTIME: {
1561
    ASN1_TIME *dup = (ASN1_TIME *)ASN1_STRING_dup(string);
256✔
1562
    PUSH_OBJECT(dup, "openssl.asn1_time");
256✔
1563
    return 1;
256✔
1564
  }
1565
  case V_ASN1_OCTET_STRING:
316✔
1566
  case V_ASN1_BIT_STRING:
1567
  default: {
1568
    ASN1_STRING *dup = ASN1_STRING_dup(string);
316✔
1569
    PUSH_OBJECT(dup, "openssl.asn1_string");
316✔
1570
    return 1;
316✔
1571
  }
1572
  }
1573
}
1574

1575
int
1576
openssl_push_asn1integer_as_bn(lua_State *L, const ASN1_INTEGER *ai)
132✔
1577
{
1578
  if (ai != NULL) {
132✔
1579
    BIGNUM *bn = ASN1_INTEGER_to_BN(ai, NULL);
84✔
1580
    PUSH_OBJECT(bn, "openssl.bn");
84✔
1581
  } else
1582
    lua_pushnil(L);
48✔
1583
  return 1;
132✔
1584
}
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