• 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

93.33
/src/pkey/read.c
1
/***
2
 * pkey read module
3
 * Read public/private key from data
4
 */
5
#include "pkey.h"
6

7
/* Suppress deprecation warnings */
8
#if defined(__GNUC__) || defined(__clang__)
9
#pragma GCC diagnostic push
10
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
11
#endif
12

13
/***
14
 * read public/private key from data
15
 * @function read
16
 * @tparam string|openssl.bio input string data or bio object
17
 * @tparam[opt=false] boolean priv prikey set true when input is private key
18
 * @tparam[opt='auto'] string format format or encoding of input, support 'auto','pem','der'
19
 * @tparam[opt] string passhprase when input is private key, or key types 'ec','rsa','dsa','dh'
20
 * @treturn openssl.evp_pkey public key
21
 * @treturn[2] nil
22
 * @treturn[2] string error message
23
 *
24
 * For PQC algorithms (ML-DSA, ML-KEM, SLH-DSA, etc.), uses generic
25
 * SubjectPublicKeyInfo (PEM_read_bio_PUBKEY/d2i_PUBKEY_bio) for public keys
26
 * and PKCS#8 PrivateKeyInfo (d2i_PKCS8PrivateKey_bio/d2i_PrivateKey_bio)
27
 * for private keys.
28
 * @see pkey
29
 */
30
int
31
openssl_pkey_read(lua_State *L)
362✔
32
{
33
  EVP_PKEY   *key = NULL;
362✔
34
  BIO        *in = load_bio_object(L, 1);
362✔
35
  int         priv = lua_isnone(L, 2) ? 0 : auxiliar_checkboolean(L, 2);
362✔
36
  int         fmt = luaL_checkoption(L, 3, "auto", format);
362✔
37
  const char *passphrase = luaL_optstring(L, 4, NULL);
362✔
38
  int         type = passphrase != NULL ? evp_pkey_name2type(passphrase) : -1;
362✔
39

40
  if (fmt == FORMAT_AUTO) {
362✔
41
    fmt = bio_is_der(in) ? FORMAT_DER : FORMAT_PEM;
36✔
42
  }
43

44
  if (!priv) {
362✔
45
    if (fmt == FORMAT_PEM) {
40✔
46
      switch (type) {
16✔
47
#ifndef OPENSSL_NO_RSA
48
      case EVP_PKEY_RSA: {
2✔
49
        RSA *rsa = PEM_read_bio_RSAPublicKey(in, NULL, NULL, NULL);
2✔
50
        if (rsa) {
2✔
51
          key = EVP_PKEY_new();
2✔
52
          EVP_PKEY_assign_RSA(key, rsa);
2✔
53
        }
54
        break;
2✔
55
      }
56
#endif
57
#ifndef OPENSSL_NO_DSA
58
      case EVP_PKEY_DSA: {
2✔
59
        DSA *dsa = PEM_read_bio_DSA_PUBKEY(in, NULL, NULL, NULL);
2✔
60
        if (dsa) {
2✔
61
          key = EVP_PKEY_new();
2✔
62
          EVP_PKEY_assign_DSA(key, dsa);
2✔
63
        }
64
        break;
2✔
65
      }
66
#endif
67
#ifndef OPENSSL_NO_EC
68
      case EVP_PKEY_EC: {
2✔
69
        EC_KEY *ec = PEM_read_bio_EC_PUBKEY(in, NULL, NULL, NULL);
2✔
70
        if (ec) {
2✔
71
          key = EVP_PKEY_new();
2✔
72
          EVP_PKEY_assign_EC_KEY(key, ec);
2✔
73
        }
74
        break;
2✔
75
      }
76
#endif
77
      default: {
10✔
78
        /* For unknown types (including PQC), use generic SubjectPublicKeyInfo */
79
        key = PEM_read_bio_PUBKEY(in, NULL, NULL, NULL);
10✔
80
        break;
10✔
81
      }
82
      }
83
      (void)BIO_reset(in);
16✔
84
    } else if (fmt == FORMAT_DER) {
24✔
85
      switch (type) {
24✔
86
#ifndef OPENSSL_NO_RSA
87
      case EVP_PKEY_RSA: {
2✔
88
        RSA *rsa = d2i_RSAPublicKey_bio(in, NULL);
2✔
89
        if (rsa) {
2✔
90
          key = EVP_PKEY_new();
2✔
91
          EVP_PKEY_assign_RSA(key, rsa);
2✔
92
        }
93
        break;
2✔
94
      }
95
#endif
96
#ifndef OPENSSL_NO_DSA
97
      case EVP_PKEY_DSA: {
2✔
98
        DSA *dsa = d2i_DSA_PUBKEY_bio(in, NULL);
2✔
99
        if (dsa) {
2✔
100
          key = EVP_PKEY_new();
2✔
101
          EVP_PKEY_assign_DSA(key, dsa);
2✔
102
        }
103
        break;
2✔
104
      }
105
#endif
106
#ifndef OPENSSL_NO_EC
107
      case EVP_PKEY_EC: {
2✔
108
        EC_KEY *ec = d2i_EC_PUBKEY_bio(in, NULL);
2✔
109
        if (ec) {
2✔
110
          key = EVP_PKEY_new();
2✔
111
          EVP_PKEY_assign_EC_KEY(key, ec);
2✔
112
        }
113
        break;
2✔
114
      }
115
#endif
116
      default:
18✔
117
        /* For unknown types (including PQC), use generic SubjectPublicKeyInfo */
118
        key = d2i_PUBKEY_bio(in, NULL);
18✔
119
        break;
18✔
120
      }
121
      (void)BIO_reset(in);
24✔
122
    }
123
  } else {
124
    if (fmt == FORMAT_PEM) {
322✔
125
      key = PEM_read_bio_PrivateKey(in, NULL, NULL, (void *)passphrase);
270✔
126
      (void)BIO_reset(in);
270✔
127
    } else if (fmt == FORMAT_DER) {
52✔
128
      switch (type) {
52✔
129
#ifndef OPENSSL_NO_RSA
130
      case EVP_PKEY_RSA: {
2✔
131
        RSA *rsa = d2i_RSAPrivateKey_bio(in, NULL);
2✔
132
        if (rsa) {
2✔
133
          key = EVP_PKEY_new();
2✔
134
          EVP_PKEY_assign_RSA(key, rsa);
2✔
135
        }
136
        break;
2✔
137
      }
138
#endif
139
#ifndef OPENSSL_NO_DSA
NEW
140
      case EVP_PKEY_DSA: {
×
NEW
141
        DSA *dsa = d2i_DSAPrivateKey_bio(in, NULL);
×
NEW
142
        if (dsa) {
×
NEW
143
          key = EVP_PKEY_new();
×
NEW
144
          EVP_PKEY_assign_DSA(key, dsa);
×
145
        }
NEW
146
        break;
×
147
      }
148
#endif
149
#ifndef OPENSSL_NO_EC
150
      case EVP_PKEY_EC: {
2✔
151
        EC_KEY *ec = d2i_ECPrivateKey_bio(in, NULL);
2✔
152
        if (ec) {
2✔
153
          key = EVP_PKEY_new();
2✔
154
          EVP_PKEY_assign_EC_KEY(key, ec);
2✔
155
        }
156
        break;
2✔
157
      }
158
#endif
159
      default: {
48✔
160
        /* For unknown types (including PQC), try PKCS#8 or generic PrivateKeyInfo */
161
        if (passphrase)
48✔
162
          key = d2i_PKCS8PrivateKey_bio(in, NULL, NULL, (void *)passphrase);
16✔
163
        else
164
          key = d2i_PrivateKey_bio(in, NULL);
32✔
165
        break;
48✔
166
      }
167
      }
168
      (void)BIO_reset(in);
52✔
169
    }
170
  }
171
  BIO_free(in);
362✔
172
  if (key) PUSH_OBJECT(key, "openssl.evp_pkey");
362✔
173

174
  return key ? 1 : openssl_pushresult(L, 0);
362✔
175
}
176

177
#if defined(__GNUC__) || defined(__clang__)
178
#pragma GCC diagnostic pop
179
#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