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

zhaozg / lua-openssl / 19382677979

15 Nov 2025 01:59AM UTC coverage: 93.785% (+0.2%) from 93.612%
19382677979

push

travis-ci

zhaozg
chore: make RSA compat with OpenSSL v3

34 of 34 new or added lines in 2 files covered. (100.0%)

24 existing lines in 2 files now uncovered.

10397 of 11086 relevant lines covered (93.78%)

2306.34 hits per line

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

98.92
/src/dsa.c
1
/*=========================================================================*\
2
* dsa.c
3
* DSA routines for lua-openssl binding
4
*
5
* Author:  george zhao <zhaozg(at)gmail.com>
6
\*=========================================================================*/
7

8
/***
9
dsa module for lua-openssl binding
10

11
Digital Signature Algorithm (DSA) is a Federal Information Processing
12
Standard for digital signatures. DSA is used for digital signing and
13
signature verification. The module provides functionality for DSA key
14
generation, signature creation and verification.
15

16
@module dsa
17
@usage
18
  dsa = require('openssl').dsa
19
*/
20
#include <openssl/dsa.h>
21
#include <openssl/engine.h>
22

23
#include "openssl.h"
24
#include "private.h"
25

26
#if !defined(OPENSSL_NO_DSA)
27

28
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
29
EVP_PKEY* openssl_new_pkey_dsa_with(const BIGNUM *p,
2✔
30
                                 const BIGNUM *q,
31
                                 const BIGNUM *g,
32
                                 const BIGNUM *pub_key,
33
                                 const BIGNUM *priv_key)
34
{
35
  EVP_PKEY *pkey = NULL;
2✔
36
  OSSL_PARAM_BLD *param_bld = OSSL_PARAM_BLD_new();
2✔
37
  if (param_bld) {
2✔
38
    EVP_PKEY_CTX *ctx = NULL;
2✔
39
    OSSL_PARAM *params = NULL;
2✔
40

41
    if (p && !OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_P, p)) goto cleanup;
2✔
42
    if (q && !OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_Q, q)) goto cleanup;
2✔
43
    if (g && !OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_FFC_G, g)) goto cleanup;
2✔
44
    if (pub_key && !OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PUB_KEY, pub_key)) goto cleanup;
2✔
45

46
    if (priv_key && !OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_PRIV_KEY, priv_key)) goto cleanup;
2✔
47
    params = OSSL_PARAM_BLD_to_param(param_bld);
2✔
48
    if (!params) goto cleanup;
2✔
49

50
    ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
2✔
51
    if (!ctx) goto cleanup;
2✔
52

53
    if (EVP_PKEY_fromdata_init(ctx) <= 0) goto cleanup;
2✔
54
    if (EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0) {
2✔
55
      pkey = NULL;
56
    }
57
  cleanup:
2✔
58
    OSSL_PARAM_free(params);
2✔
59
    OSSL_PARAM_BLD_free(param_bld);
2✔
60
    EVP_PKEY_CTX_free(ctx);
2✔
61
  }
62
  return pkey;
2✔
63
}
64
#endif
65

66
static int openssl_dsa_free(lua_State *L)
22✔
67
{
68
  DSA *dsa = CHECK_OBJECT(1, DSA, "openssl.dsa");
22✔
69
#if defined(__GNUC__) || defined(__clang__)
70
#pragma GCC diagnostic push
71
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
72
#endif
73
  DSA_free(dsa);
22✔
74
#if defined(__GNUC__) || defined(__clang__)
75
#pragma GCC diagnostic pop
76
#endif
77
  return 0;
22✔
78
};
79

80
/***
81
parse DSA key parameters and components
82
@function parse
83
@treturn table DSA parameters including bits, p, q, g, public key, and private key (if present)
84
*/
85
static int openssl_dsa_parse(lua_State *L)
16✔
86
{
87
  const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *pri = NULL;
16✔
88
  DSA          *dsa = CHECK_OBJECT(1, DSA, "openssl.dsa");
16✔
89
  lua_newtable(L);
16✔
90

91
#if defined(__GNUC__) || defined(__clang__)
92
#pragma GCC diagnostic push
93
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
94
#endif
95
  lua_pushinteger(L, DSA_bits(dsa));
16✔
96
  lua_setfield(L, -2, "bits");
16✔
97

98
  DSA_get0_pqg(dsa, &p, &q, &g);
16✔
99
  DSA_get0_key(dsa, &pub, &pri);
16✔
100
#if defined(__GNUC__) || defined(__clang__)
101
#pragma GCC diagnostic pop
102
#endif
103

104
  OPENSSL_PKEY_GET_BN(p, p);
16✔
105
  OPENSSL_PKEY_GET_BN(q, q);
16✔
106
  OPENSSL_PKEY_GET_BN(g, g);
16✔
107
  OPENSSL_PKEY_GET_BN(pri, priv_key);
16✔
108
  OPENSSL_PKEY_GET_BN(pub, pub_key);
16✔
109
  return 1;
16✔
110
}
111

112
/***
113
set engine for DSA operations
114
@function set_engine
115
@tparam engine engine the engine to use for DSA operations
116
@treturn boolean true on success, false on failure
117
*/
118
static int
119
openssl_dsa_set_engine(lua_State *L)
4✔
120
{
121
#ifndef OPENSSL_NO_ENGINE
122
  DSA              *dsa = CHECK_OBJECT(1, DSA, "openssl.dsa");
4✔
123
  ENGINE           *e = CHECK_OBJECT(2, ENGINE, "openssl.engine");
4✔
124
#if defined(__GNUC__) || defined(__clang__)
125
#pragma GCC diagnostic push
126
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
127
#endif
128
  const DSA_METHOD *m = ENGINE_get_DSA(e);
4✔
129
  if (m) {
4✔
130
    int r = DSA_set_method(dsa, m);
4✔
131
    return openssl_pushresult(L, r);
4✔
132
  }
133
#if defined(__GNUC__) || defined(__clang__)
134
#pragma GCC diagnostic pop
135
#endif
136
#endif
UNCOV
137
  return 0;
×
138
}
139

140
/***
141
generate DSA key pair with specified parameters
142
@function generate_key
143
@tparam[opt=1024] number bits key size in bits
144
@tparam[opt] string seed random seed for parameter generation
145
@tparam[opt] engine eng engine to use for key generation
146
@treturn dsa|nil generated DSA key pair or nil on error
147
*/
148
static int
149
openssl_dsa_generate_key(lua_State *L)
4✔
150
{
151
  int         bits = luaL_optint(L, 1, 1024);
4✔
152
  size_t      seed_len = 0;
4✔
153
  const char *seed = luaL_optlstring(L, 2, NULL, &seed_len);
4✔
154
  ENGINE     *eng = lua_isnoneornil(L, 3) ? NULL : CHECK_OBJECT(3, ENGINE, "openssl.engine");
4✔
155
  DSA        *dsa = NULL;
4✔
156
  int         ret = 0;
4✔
157

158
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
159
  /* OpenSSL 3.0+ - Use EVP_PKEY APIs to avoid deprecation warnings */
160
  EVP_PKEY_CTX *pctx = NULL;
2✔
161
  EVP_PKEY_CTX *kctx = NULL;
2✔
162
  EVP_PKEY     *param_pkey = NULL;
2✔
163
  EVP_PKEY     *pkey = NULL;
2✔
164

165
  /* Create context for parameter generation */
166
  pctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL);
2✔
167
  if (!pctx) {
2✔
168
    return openssl_pushresult(L, 0);
169
  }
170

171
  /* Initialize parameter generation */
172
  ret = EVP_PKEY_paramgen_init(pctx);
2✔
173
  if (ret != 1) {
2✔
174
    EVP_PKEY_CTX_free(pctx);
175
    return openssl_pushresult(L, ret);
176
  }
177

178
  /* Set key size */
179
  ret = EVP_PKEY_CTX_set_dsa_paramgen_bits(pctx, bits);
2✔
180
  if (ret != 1) {
2✔
181
    EVP_PKEY_CTX_free(pctx);
182
    return openssl_pushresult(L, ret);
183
  }
184

185
  /* Set seed if provided */
186
  if (seed && seed_len > 0) {
2✔
187
    ret = EVP_PKEY_CTX_ctrl(pctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN,
188
                            EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, (void *)seed);
189
    /* Note: seed handling may not work the same way in OpenSSL 3.0 */
190
    /* We continue even if this fails, as the seed is optional */
191
  }
192

193
  /* Generate parameters */
194
  ret = EVP_PKEY_paramgen(pctx, &param_pkey);
2✔
195
  EVP_PKEY_CTX_free(pctx);
2✔
196

197
  if (ret != 1 || !param_pkey) {
2✔
198
    if (param_pkey) EVP_PKEY_free(param_pkey);
199
    return openssl_pushresult(L, ret);
200
  }
201

202
  /* Create key generation context from parameters */
203
  kctx = EVP_PKEY_CTX_new(param_pkey, eng);
2✔
204
  EVP_PKEY_free(param_pkey);
2✔
205

206
  if (!kctx) {
2✔
207
    return openssl_pushresult(L, 0);
208
  }
209

210
  /* Initialize key generation */
211
  ret = EVP_PKEY_keygen_init(kctx);
2✔
212
  if (ret != 1) {
2✔
213
    EVP_PKEY_CTX_free(kctx);
214
    return openssl_pushresult(L, ret);
215
  }
216

217
  /* Generate key pair */
218
  ret = EVP_PKEY_keygen(kctx, &pkey);
2✔
219
  EVP_PKEY_CTX_free(kctx);
2✔
220

221
  if (ret == 1 && pkey) {
2✔
222
    /* Extract DSA from EVP_PKEY for compatibility with Lua API */
223
#if defined(__GNUC__) || defined(__clang__)
224
#pragma GCC diagnostic push
225
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
226
#endif
227
    dsa = EVP_PKEY_get1_DSA(pkey);
2✔
228
#if defined(__GNUC__) || defined(__clang__)
229
#pragma GCC diagnostic pop
230
#endif
231

232
    EVP_PKEY_free(pkey);
2✔
233

234
    if (dsa) {
2✔
235
      PUSH_OBJECT(dsa, "openssl.dsa");
2✔
236
      return 1;
2✔
237
    }
238
  }
239

240
  if (pkey) EVP_PKEY_free(pkey);
241
  return openssl_pushresult(L, ret);
242
#else
243
  /* OpenSSL 1.x - Use legacy DSA APIs */
244
  dsa = eng ? DSA_new_method(eng) : DSA_new();
2✔
245
  ret = DSA_generate_parameters_ex(dsa, bits, (byte *)seed, seed_len, NULL, NULL, NULL);
2✔
246
  if (ret == 1) ret = DSA_generate_key(dsa);
2✔
247
  if (ret == 1) {
2✔
248
    PUSH_OBJECT(dsa, "openssl.dsa");
2✔
249
    return 1;
2✔
250
  }
251
  DSA_free(dsa);
252
  return openssl_pushresult(L, ret);
253
#endif
254
}
255

256
static luaL_Reg dsa_funs[] = {
257
  { "parse",      openssl_dsa_parse      },
258
  { "set_engine", openssl_dsa_set_engine },
259

260
  { "__gc",       openssl_dsa_free       },
261
  { "__tostring", auxiliar_tostring      },
262

263
  { NULL,         NULL                   }
264
};
265

266
static luaL_Reg R[] = {
267
  { "generate_key", openssl_dsa_generate_key },
268

269
  { NULL,           NULL                     }
270
};
271

272
int
273
luaopen_dsa(lua_State *L)
43✔
274
{
275
  auxiliar_newclass(L, "openssl.dsa", dsa_funs);
43✔
276

277
  lua_newtable(L);
43✔
278
  luaL_setfuncs(L, R, 0);
43✔
279

280
  return 1;
43✔
281
}
282
#endif
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

© 2026 Coveralls, Inc