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

zhaozg / lua-openssl / 25776463823

13 May 2026 03:28AM UTC coverage: 91.231% (-2.6%) from 93.832%
25776463823

Pull #408

travis-ci

zhaozg
feat(pqc): Phase 2.4 - Provider Management for PQC

Add PQC provider management capabilities to the provider module:

- Add `provider.query_pqc_algorithms()` to probe and list available PQC
  algorithms by attempting key generation for known PQC algorithm names
- Add `provider.load_pqc_providers()` to auto-detect and load common
  PQC providers (oqsprovider, liboqs, oqs, oqs-provider)
- Auto-load common PQC providers on module initialization (best-effort)
- Support both old OQS names (DILITHIUM2, KYBER768, etc.) and
  standardized NIST names (ML-DSA-44, ML-KEM-768, SLH-DSA-SHA2-*, etc.)
- Add comprehensive LDoc documentation for all new functions
- Add test suite covering query, load, and combined scenarios

This completes Phase 2.4 of the PQC implementation roadmap.
Pull Request #408: Feat/pqc

913 of 1124 new or added lines in 10 files covered. (81.23%)

45 existing lines in 10 files now uncovered.

9519 of 10434 relevant lines covered (91.23%)

1598.73 hits per line

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

95.0
/src/pkey.c
1
/***
2
 * pkey module - integration layer
3
 *
4
 * This file integrates all pkey sub-modules from src/pkey/ directory.
5
 * It includes the sub-module source files to maintain a single compilation unit,
6
 * ensuring all internal function references are resolved correctly.
7
 *
8
 * @module pkey
9
 * @usage
10
 *   pkey = require'openssl'.pkey
11
 */
12
#include <openssl/dh.h>
13
#include <openssl/dsa.h>
14
#include <openssl/engine.h>
15
#include <openssl/rsa.h>
16

17
#include "openssl.h"
18
#include "private.h"
19

20
/* Suppress deprecation warnings for low-level key APIs in OpenSSL 3.0+ */
21
#if defined(__GNUC__) || defined(__clang__)
22
#pragma GCC diagnostic push
23
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
24
#endif
25

26
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
27
#include <openssl/core_names.h>
28
#include <openssl/params.h>
29
#include <openssl/param_build.h>
30
#endif
31

32
/* ========================================================================
33
 * Compatibility layer (stays in pkey.c for cross-module access)
34
 * ======================================================================== */
35

36
/* Compatibility layer for low-level key access migration to OpenSSL 3.0+ PARAM API */
37
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
38

39
/* Helper: check if private key exists using PARAM API */
40
static int
41
pkey_has_private(EVP_PKEY *pkey)
42
{
43
  BIGNUM *bn = NULL;
44
  int ret = 0;
45
  size_t priv_len = 0;
46

47
  int typ = EVP_PKEY_type(EVP_PKEY_id(pkey));
48

49
  switch (typ) {
50
#ifndef OPENSSL_NO_RSA
51
  case EVP_PKEY_RSA: {
52
    ret = EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_D, &bn);
53
    break;
54
  }
55
#endif
56
#ifndef OPENSSL_NO_DSA
57
  case EVP_PKEY_DSA: {
58
    ret = EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &bn);
59
    if (!ret || bn == NULL) {
60
      /*OpenSSL 3.0 DSA priv key param not working, Fallback to legacy way */
61
      DSA* dsa = (DSA*)EVP_PKEY_get0_DSA(pkey);
62
      if (dsa) {
63
        const BIGNUM* priv_key = NULL;
64
        DSA_get0_key(dsa, NULL, &priv_key);
65
        if (priv_key) {
66
          bn = BN_dup(priv_key);
67
          ret = 1;
68
        }
69
      }
70
    }
71
    break;
72
  }
73
#endif
74
#ifndef OPENSSL_NO_DH
75
  case EVP_PKEY_DH: {
76
    ret = EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &bn);
77
    break;
78
  }
79
#endif
80
#ifndef OPENSSL_NO_EC
81
  case EVP_PKEY_EC:
82
#ifdef EVP_PKEY_SM2
83
  case EVP_PKEY_SM2:
84
#endif
85
  {
86
    ret = EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &bn);
87
    break;
88
  }
89
#endif
90
#ifndef OPENSSL_NO_ED25519
91
  case EVP_PKEY_ED25519: {
92
    ret = EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0, &priv_len);
93
    break;
94
  }
95
#endif
96
#ifndef OPENSSL_NO_ED448
97
  case EVP_PKEY_ED448: {
98
    ret = EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0, &priv_len);
99
    break;
100
  }
101
#endif
102
#ifndef OPENSSL_NO_EX25519
103
  case EVP_PKEY_X25519: {
104
    ret = EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0, &priv_len);
105
    break;
106
  }
107
#endif
108
  default:
109
  {
110
    EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
111
    if (EVP_PKEY_private_check(ctx))
112
      ret = 1;
113
    EVP_PKEY_CTX_free(ctx);
114
    return ret;
115
  }
116
  }
117

118
  if (ret && bn != NULL) {
119
    ret = !BN_is_zero(bn);
120
    BN_free(bn);
121
  } else if (ret && priv_len > 0) {
122
    ret = 1;
123
  }
124

125
  return ret;
126
}
127

128
/* Helper: check if key matches expected type */
129
static int
130
pkey_is_type(EVP_PKEY *pkey, int expected_type)
131
{
132
  /* In OpenSSL 3.0+, if EVP_PKEY_id returns the expected type, the key exists */
133
  return pkey != NULL && EVP_PKEY_type(EVP_PKEY_id(pkey)) == expected_type;
134
}
135
#endif
136

137
int
138
openssl_pkey_is_private(EVP_PKEY *pkey)
598✔
139
{
140
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
141
  return pkey_has_private(pkey);
142
#else
143
  /* OpenSSL 1.x way */
144
  int ret = 0;
598✔
145
  int typ = EVP_PKEY_type(EVP_PKEY_id(pkey));
598✔
146

147
  switch (typ) {
598✔
148
#ifndef OPENSSL_NO_RSA
149
  case EVP_PKEY_RSA: {
180✔
150
    RSA          *rsa = (RSA *)EVP_PKEY_get0_RSA(pkey);
180✔
151
    const BIGNUM *d = NULL;
180✔
152

153
    RSA_get0_key(rsa, NULL, NULL, &d);
180✔
154
    ret = d != NULL;
180✔
155
    break;
180✔
156
  }
157
#endif
158
#ifndef OPENSSL_NO_DSA
159
  case EVP_PKEY_DSA: {
138✔
160
    DSA          *dsa = (DSA *)EVP_PKEY_get0_DSA(pkey);
138✔
161
    const BIGNUM *p = NULL;
138✔
162
    DSA_get0_key(dsa, NULL, &p);
138✔
163
    ret = p != NULL;
138✔
164
    break;
138✔
165
  }
166
#endif
167
#ifndef OPENSSL_NO_DH
168
  case EVP_PKEY_DH: {
120✔
169
    DH           *dh = (DH *)EVP_PKEY_get0_DH(pkey);
120✔
170
    const BIGNUM *p = NULL;
120✔
171
    DH_get0_key(dh, NULL, &p);
120✔
172
    ret = p != NULL;
120✔
173
    break;
120✔
174
  }
175
#endif
176
#ifndef OPENSSL_NO_EC
177
  case EVP_PKEY_EC:
160✔
178
#ifdef EVP_PKEY_SM2
179
  case EVP_PKEY_SM2:
180
#endif
181
  {
182
    EC_KEY       *ec = (EC_KEY *)EVP_PKEY_get0_EC_KEY(pkey);
160✔
183
    const BIGNUM *p = EC_KEY_get0_private_key(ec);
160✔
184
    ret = p != NULL;
160✔
185
    break;
160✔
186
  }
187
#endif
UNCOV
188
  default:
×
UNCOV
189
    break;
×
190
  }
191

192
  return ret;
598✔
193
#endif
194
}
195

196
#if defined(OPENSSL_SUPPORT_SM2)
197
static int
198
openssl_pkey_is_sm2(const EVP_PKEY *pkey)
14✔
199
{
200
  int id;
201
#if OPENSSL_VERSION_NUMBER > 0x30000000
202
  id = EVP_PKEY_get_id(pkey);
203
  if (id == NID_sm2) return 1;
204
#else
205
  id = EVP_PKEY_id(pkey);
14✔
206
  if (id == EVP_PKEY_SM2) return 1;
14✔
207
#endif
208

209
  id = EVP_PKEY_base_id(pkey);
14✔
210
  if (id == EVP_PKEY_EC) {
14✔
211
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
212
    /* OpenSSL 3.0+ way: use PARAM API to get curve name */
213
    char curve_name[256];
214
    size_t curve_name_len = sizeof(curve_name);
215
    if (EVP_PKEY_get_utf8_string_param(pkey, OSSL_PKEY_PARAM_GROUP_NAME,
216
                                        curve_name, sizeof(curve_name), &curve_name_len)) {
217
      /* Check if the group name is SM2 */
218
      if (strcmp(curve_name, "SM2") == 0) {
219
        return 1;
220
      }
221
      /* Convert group name to NID and check */
222
      int curve = OBJ_sn2nid(curve_name);
223
      return curve == NID_sm2;
224
    }
225
#else
226
    /* OpenSSL 1.x way */
227
    const EC_KEY   *ec = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)pkey);
2✔
228
    const EC_GROUP *grp = EC_KEY_get0_group(ec);
2✔
229
    int             curve = EC_GROUP_get_curve_name(grp);
2✔
230
    return curve == NID_sm2;
2✔
231
#endif
232
  }
233
  return 0;
12✔
234
}
235
#endif
236

237
/* ========================================================================
238
 * Include sub-modules
239
 * ======================================================================== */
240

241
#include "pkey/read.c"
242
#include "pkey/new.c"
243
#include "pkey/sign.c"
244
#include "pkey/derive.c"
245
#include "pkey/seal.c"
246
#include "pkey/kem.c"
247
#include "pkey/engine.c"
248
#include "pkey/sm2.c"
249
#include "pkey/core.c"
250

251
#if defined(__GNUC__) || defined(__clang__)
252
#pragma GCC diagnostic pop
253
#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