Skip to content

Commit 6b4b09d

Browse files
author
jgoertzen-sb
committed
Add XMSS support to powerdns
1 parent e4313c2 commit 6b4b09d

10 files changed

+110
-58
lines changed

Dockerfile-auth

+12-9
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,31 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get clean
77
# sudo apt install cmake gcc libtool libssl-dev make ninja-build git
88
RUN apt-get install -y --no-install-recommends \
99
# original requirements
10-
cmake gcc libtool libssl-dev make ninja-build git \
10+
cmake gcc libtool make ninja-build git \
1111
# added by us
12-
astyle python3-pytest python3-pytest-xdist unzip xsltproc doxygen \
12+
astyle python3-pytest python3-pytest-xdist unzip xsltproc doxygen libluajit-5.1-dev liblua5.3-dev \
1313
graphviz apt-transport-https ca-certificates build-essential systemd
1414
# ???
1515
# RUN update-ca-certificates
1616

1717
WORKDIR /source/
1818

19+
RUN apt remove openssl libssl-dev -y
1920
RUN git clone --branch openssl-3.2.0 https://github.com/openssl/openssl.git openssl-source/
20-
RUN git clone https://github.com/open-quantum-safe/liboqs.git
21-
RUN mkdir liboqs/build/
22-
RUN cd liboqs/build/ && cmake -GNinja ..
23-
RUN cd liboqs/build/ && ninja
24-
RUN cd liboqs/build/ && ninja install
2521
RUN cd openssl-source/ && ./Configure -lm no-docs --libdir=lib
2622
RUN cd openssl-source/ && make
2723
RUN cd openssl-source/ && make install
24+
RUN git clone --branch stateful-sigs https://github.com/open-quantum-safe/liboqs.git
25+
RUN mkdir liboqs/build/
26+
RUN cd liboqs/build/ && cmake -GNinja -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON ..
27+
RUN cd liboqs/build/ && ninja
28+
RUN cd liboqs/build/ && ninja install
2829
RUN git clone https://github.com/open-quantum-safe/oqs-provider.git
2930
ENV LD_LIBRARY_PATH=/usr/local/lib
30-
RUN cd oqs-provider/ && cmake -S . -B _build && cmake --build _build && ctest --test-dir _build && cmake --install _build
31-
31+
RUN cd oqs-provider/ && cmake -S . -B _build
32+
RUN cd oqs-provider/ && cmake --build _build
33+
RUN cd oqs-provider/ && ctest --test-dir _build
34+
RUN cd oqs-provider/ && cmake --install _build --config DebPack
3235

3336
ENV NO_LUA_JIT="s390x arm64"
3437

Dockerfile-recursor

+13-12
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,28 @@ RUN apt-get install -y --no-install-recommends \
1515
# original requirements
1616
cmake gcc libtool libssl-dev make ninja-build git \
1717
# added by us
18-
astyle python3-pytest python3-pytest-xdist unzip xsltproc doxygen \
18+
astyle python3-pytest python3-pytest-xdist unzip xsltproc doxygen libluajit-5.1-dev liblua5.3-dev \
1919
graphviz apt-transport-https ca-certificates build-essential systemd
2020

2121

2222
WORKDIR /source/
23+
24+
RUN apt remove openssl libssl-dev -y
2325
RUN git clone --branch openssl-3.2.0 https://github.com/openssl/openssl.git openssl-source/
24-
RUN git clone https://github.com/open-quantum-safe/liboqs.git
25-
RUN mkdir liboqs/build/
26-
RUN cd liboqs/build/ && cmake -GNinja ..
27-
RUN cd liboqs/build/ && ninja
28-
RUN cd liboqs/build/ && ninja install
2926
RUN cd openssl-source/ && ./Configure -lm no-docs --libdir=lib
3027
RUN cd openssl-source/ && make
3128
RUN cd openssl-source/ && make install
29+
RUN git clone --branch stateful-sigs https://github.com/open-quantum-safe/liboqs.git
30+
RUN mkdir liboqs/build/
31+
RUN cd liboqs/build/ && cmake -GNinja -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON ..
32+
RUN cd liboqs/build/ && ninja
33+
RUN cd liboqs/build/ && ninja install
3234
RUN git clone https://github.com/open-quantum-safe/oqs-provider.git
33-
ENV LD_LIBRARY_PATH=/usr/local/lib
34-
RUN cd oqs-provider/ && cmake -S . -B _build && cmake --build _build && ctest --test-dir _build && cmake --install _build
35-
35+
#ENV LD_LIBRARY_PATH=/usr/local/lib
36+
RUN cd oqs-provider/ && cmake -S . -B _build
37+
RUN cd oqs-provider/ && cmake --build _build
38+
RUN cd oqs-provider/ && ctest --test-dir _build
39+
RUN cd oqs-provider/ && cmake --install _build --config DebPack
3640
ENV NO_LUA_JIT="s390x arm64"
3741

3842
# Reusable layer for base update
@@ -59,9 +63,6 @@ COPY .git /source/.git
5963
COPY builder-support/helpers/install_rust.sh /source/install_rust.sh
6064
RUN /source/install_rust.sh
6165

62-
COPY builder-support/helpers/install_rust.sh /source/install_rust.sh
63-
RUN /source/install_rust.sh
64-
6566
# build and install (TODO: before we hit this line, rearrange /source structure if we are coming from a tarball)
6667
WORKDIR /source/pdns/recursordist
6768

PQC.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ An example can be found down belox (this is only meant as inspiration):
3737
throw runtime_error(getName()+" unknown algorithm "+std::to_string(d_algorithm));
3838
}
3939
```
40-
**Important:** The NID of the new algorithm shoudl correspond to the NID declared in the OQS library.
40+
**Important:** The NID of the new algorithm should correspond to the NID declared in the OQS library.
4141

4242
The *convertToISCVector()* function must also be changed to support the new algorithm like follows:
4343
```

pdns/Makefile.am

+3
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ pdns_server_SOURCES = \
243243
iputils.cc iputils.hh \
244244
ixfr.cc ixfr.hh \
245245
json.cc json.hh \
246+
liboqssigners.cc liboqssigners.hh \
246247
lock.hh \
247248
logger.cc logger.hh \
248249
logging.hh \
@@ -376,6 +377,7 @@ pdnsutil_SOURCES = \
376377
ipcipher.cc ipcipher.hh \
377378
iputils.cc iputils.hh \
378379
json.cc \
380+
liboqssigners.cc liboqssigners.hh \
379381
logger.cc \
380382
lua-auth4.cc lua-auth4.hh \
381383
lua-base4.cc lua-base4.hh \
@@ -1362,6 +1364,7 @@ testrunner_SOURCES = \
13621364
ipcipher.cc ipcipher.hh \
13631365
iputils.cc \
13641366
ixfr.cc ixfr.hh \
1367+
liboqssigners.cc liboqssigners.hh \
13651368
logger.cc \
13661369
lua-auth4.hh lua-auth4.cc \
13671370
lua-base4.hh lua-base4.cc \

pdns/dbdnsseckeeper.cc

+11-11
Original file line numberDiff line numberDiff line change
@@ -86,34 +86,34 @@ bool DNSSECKeeper::isPresigned(const DNSName& name, bool useCache)
8686
}
8787

8888

89-
bool DNSSECKeeper::addKey(const DNSName& name, bool setSEPBit, int algorithm, int64_t& id, int bits, bool active, bool published)
89+
bool DNSSECKeeper::addKey(const DNSName& name, bool setSEPBit, int algorithm, int64_t& id, int key_param, bool active, bool published)
9090
{
91-
if(!bits) {
91+
if(!key_param) {
9292
if(algorithm <= 10)
93-
throw runtime_error("Creating an algorithm " +std::to_string(algorithm)+" ("+algorithm2name(algorithm)+") key requires the size (in bits) to be passed.");
93+
throw runtime_error("Creating an algorithm " +std::to_string(algorithm)+" ("+algorithm2name(algorithm)+") key requires the size (in bits) to be passed via key_param.");
9494
else {
9595
if(algorithm == DNSSECKeeper::ECCGOST || algorithm == DNSSECKeeper::ECDSA256 || algorithm == DNSSECKeeper::ED25519)
96-
bits = 256;
96+
key_param = 256;
9797
else if(algorithm == DNSSECKeeper::ECDSA384)
98-
bits = 384;
98+
key_param = 384;
9999
else if(algorithm == DNSSECKeeper::ED448)
100-
bits = 456;
100+
key_param = 456;
101101
else if(algorithm == DNSSECKeeper::FALCON512)
102-
bits = 10248;
102+
key_param = 10248;
103103
else if(algorithm == DNSSECKeeper::DILITHIUM2)
104-
bits = 20224;
104+
key_param = 20224;
105105
else if(algorithm == DNSSECKeeper::SPHINCSSHA256128S)
106-
bits = 512;
106+
key_param = 512;
107107
else {
108108
throw runtime_error("Can not guess key size for algorithm "+std::to_string(algorithm));
109109
}
110110
}
111111
}
112112
shared_ptr<DNSCryptoKeyEngine> dpk(DNSCryptoKeyEngine::make(algorithm));
113113
try{
114-
dpk->create(bits);
114+
dpk->create(key_param);
115115
} catch (const std::runtime_error& error){
116-
throw runtime_error("The algorithm does not support the given bit size.");
116+
throw runtime_error("The algorithm does not support the given key parameter.");
117117
}
118118
DNSSECPrivateKey dspk;
119119
dspk.setKey(dpk, setSEPBit ? 257 : 256, algorithm);

pdns/dnsseckeeper.hh

+24-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <boost/multi_index/ordered_index.hpp>
3030
#include <boost/multi_index/key_extractors.hpp>
3131
#include <boost/multi_index/sequenced_index.hpp>
32+
#include "liboqssigners.hh"
3233
#include "dnssecinfra.hh"
3334
#include "dnsrecords.hh"
3435
#include "ueberbackend.hh"
@@ -56,7 +57,9 @@ public:
5657
ED448=16,
5758
FALCON512=17,
5859
DILITHIUM2=18,
59-
SPHINCSSHA256128S=19
60+
SPHINCSSHA256128S=19,
61+
XMSS=20,
62+
XMSSMT=21,
6063
};
6164

6265
enum dsdigestalgorithm_t : uint8_t {
@@ -117,6 +120,8 @@ public:
117120
if (pdns_iequals(algorithm, "falcon512")) return FALCON512;
118121
if (pdns_iequals(algorithm, "dilithium2")) return DILITHIUM2;
119122
if (pdns_iequals(algorithm, "sphincs+-sha256-128s")) return SPHINCSSHA256128S;
123+
if (pdns_iequals(algorithm, "xmss")) return XMSS;
124+
if (pdns_iequals(algorithm, "xmssmt")) return XMSSMT;
120125
if (pdns_iequals(algorithm, "indirect")) return 252;
121126
if (pdns_iequals(algorithm, "privatedns")) return 253;
122127
if (pdns_iequals(algorithm, "privateoid")) return 254;
@@ -165,6 +170,10 @@ public:
165170
return "dilithium2";
166171
case SPHINCSSHA256128S:
167172
return "sphincs+-sha256-128s";
173+
case XMSS:
174+
return "xmss";
175+
case XMSSMT:
176+
return "xmssmt";
168177
case 252:
169178
return "INDIRECT";
170179
case 253:
@@ -175,6 +184,19 @@ public:
175184
return "Unallocated/Reserved";
176185
}
177186
}
187+
188+
static int setupParam(string &algorithm, int param)
189+
{
190+
if (algorithm.rfind("xmssmt", 0) == 0) {
191+
param = xmssmtPdnsName2Param(algorithm);
192+
algorithm = "xmssmt";
193+
}
194+
else if (algorithm.rfind("xmss", 0) == 0) {
195+
param = xmssPdnsName2Param(algorithm);
196+
algorithm = "xmss";
197+
}
198+
return param;
199+
}
178200

179201
private:
180202
UeberBackend* d_keymetadb;
@@ -207,7 +229,7 @@ public:
207229
keyset_t getEntryPoints(const DNSName& zname);
208230
keyset_t getKeys(const DNSName& zone, bool useCache = true);
209231
DNSSECPrivateKey getKeyById(const DNSName& zone, unsigned int id);
210-
bool addKey(const DNSName& zname, bool setSEPBit, int algorithm, int64_t& id, int bits=0, bool active=true, bool published=true);
232+
bool addKey(const DNSName& zname, bool setSEPBit, int algorithm, int64_t& id, int key_param=0, bool active=true, bool published=true);
211233
bool addKey(const DNSName& zname, const DNSSECPrivateKey& dpk, int64_t& id, bool active=true, bool published=true);
212234
bool removeKey(const DNSName& zname, unsigned int id);
213235
bool activateKey(const DNSName& zname, unsigned int id);

pdns/opensslsigners.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1773,7 +1773,7 @@ class OpenSSLPQCDNSCryptoKeyEngine : public DNSCryptoKeyEngine
17731773
d_priv_len = 1281;
17741774
d_pub_len = 897;
17751775
d_sig_len = 666;
1776-
d_algname = "falcon512";
1776+
d_algname = "falconpadded512";
17771777
}
17781778
else if (d_algorithm == DNSSECKeeper::DILITHIUM2) {
17791779
d_priv_len = 2528;

pdns/pdnsutil.cc

+36-22
Original file line numberDiff line numberDiff line change
@@ -2292,19 +2292,19 @@ static bool secureZone(DNSSECKeeper& dk, const DNSName& zone)
22922292

22932293
// parse attribute
22942294
string k_algo = ::arg()["default-ksk-algorithm"];
2295-
int k_size = ::arg().asNum("default-ksk-size");
2295+
int k_param = ::arg().asNum("default-ksk-size");
22962296
string z_algo = ::arg()["default-zsk-algorithm"];
2297-
int z_size = ::arg().asNum("default-zsk-size");
2297+
int z_param = ::arg().asNum("default-zsk-size");
22982298

2299-
if (k_size < 0) {
2299+
if (k_param < 0) {
23002300
throw runtime_error("KSK key size must be equal to or greater than 0");
23012301
}
23022302

23032303
if (k_algo.empty() && z_algo.empty()) {
23042304
throw runtime_error("Zero algorithms given for KSK+ZSK in total");
23052305
}
23062306

2307-
if (z_size < 0) {
2307+
if (z_param < 0) {
23082308
throw runtime_error("ZSK key size must be equal to or greater than 0");
23092309
}
23102310

@@ -2313,6 +2313,8 @@ static bool secureZone(DNSSECKeeper& dk, const DNSName& zone)
23132313
return false;
23142314
}
23152315

2316+
2317+
23162318
DomainInfo di;
23172319
UeberBackend B("default");
23182320
// di.backend and B are mostly identical
@@ -2327,16 +2329,19 @@ static bool secureZone(DNSSECKeeper& dk, const DNSName& zone)
23272329
}
23282330

23292331
if (!k_algo.empty()) { // Add a KSK
2330-
if (k_size)
2331-
cout << "Securing zone with key size " << k_size << endl;
2332+
k_param = DNSSECKeeper::setupParam(k_algo, k_param);
2333+
if (k_param && k_algo != "xmss")
2334+
cout << "Securing zone with key size " << k_param << endl;
2335+
else if (k_param && k_algo == "xmss")
2336+
cout << "Securing zone with xmss oid " << k_param << endl;
23322337
else
23332338
cout << "Securing zone with default key size" << endl;
23342339

23352340
cout << "Adding " << (z_algo.empty() ? "CSK (257)" : "KSK") << " with algorithm " << k_algo << endl;
23362341

23372342
int k_real_algo = DNSSECKeeper::shorthand2algorithm(k_algo);
23382343

2339-
if (!dk.addKey(zone, true, k_real_algo, id, k_size, true, true)) {
2344+
if (!dk.addKey(zone, true, k_real_algo, id, k_param, true, true)) {
23402345
cerr << "No backend was able to secure '" << zone << "', most likely because no DNSSEC" << endl;
23412346
cerr << "capable backends are loaded, or because the backends have DNSSEC disabled." << endl;
23422347
cerr << "For the Generic SQL backends, set the 'gsqlite3-dnssec', 'gmysql-dnssec' or" << endl;
@@ -2346,11 +2351,12 @@ static bool secureZone(DNSSECKeeper& dk, const DNSName& zone)
23462351
}
23472352

23482353
if (!z_algo.empty()) {
2354+
z_param = DNSSECKeeper::setupParam(z_algo, z_param);
23492355
cout << "Adding " << (k_algo.empty() ? "CSK (256)" : "ZSK") << " with algorithm " << z_algo << endl;
23502356

23512357
int z_real_algo = DNSSECKeeper::shorthand2algorithm(z_algo);
23522358

2353-
if (!dk.addKey(zone, false, z_real_algo, id, z_size, true, true)) {
2359+
if (!dk.addKey(zone, false, z_real_algo, id, z_param, true, true)) {
23542360
cerr << "No backend was able to secure '" << zone << "', most likely because no DNSSEC" << endl;
23552361
cerr << "capable backends are loaded, or because the backends have DNSSEC disabled." << endl;
23562362
cerr << "For the Generic SQL backends, set the 'gsqlite3-dnssec', 'gmysql-dnssec' or" << endl;
@@ -3057,47 +3063,55 @@ try {
30573063
// need to get algorithm, bits & ksk or zsk from commandline
30583064
bool keyOrZone = false;
30593065
int tmp_algo = 0;
3060-
int bits = 0;
3066+
int key_param = 0;
3067+
int tmp_param = 0;
30613068
int algorithm = DNSSECKeeper::ECDSA256;
30623069
bool active = false;
30633070
bool published = true;
30643071
for (unsigned int n = 2; n < cmds.size(); ++n) {
3065-
if (pdns_iequals(cmds.at(n), "zsk"))
3072+
std::string cmd = cmds.at(n);
3073+
if (pdns_iequals(cmd, "zsk"))
30663074
keyOrZone = false;
3067-
else if (pdns_iequals(cmds.at(n), "ksk"))
3075+
else if (pdns_iequals(cmd, "ksk"))
30683076
keyOrZone = true;
3069-
else if ((tmp_algo = DNSSECKeeper::shorthand2algorithm(cmds.at(n))) > 0) {
3077+
else if ((tmp_param = DNSSECKeeper::setupParam(cmd, key_param)) != key_param) {
3078+
key_param = tmp_param;
3079+
algorithm = DNSSECKeeper::shorthand2algorithm(cmd);
3080+
}
3081+
else if ((tmp_algo = DNSSECKeeper::shorthand2algorithm(cmd)) > 0) {
30703082
algorithm = tmp_algo;
30713083
}
3072-
else if (pdns_iequals(cmds.at(n), "active")) {
3084+
else if (pdns_iequals(cmd, "active")) {
30733085
active = true;
30743086
}
3075-
else if (pdns_iequals(cmds.at(n), "inactive") || pdns_iequals(cmds.at(n), "passive")) { // 'passive' eventually needs to be removed
3087+
else if (pdns_iequals(cmd, "inactive") || pdns_iequals(cmd, "passive")) { // 'passive' eventually needs to be removed
30763088
active = false;
30773089
}
3078-
else if (pdns_iequals(cmds.at(n), "published")) {
3090+
else if (pdns_iequals(cmd, "published")) {
30793091
published = true;
30803092
}
3081-
else if (pdns_iequals(cmds.at(n), "unpublished")) {
3093+
else if (pdns_iequals(cmd, "unpublished")) {
30823094
published = false;
30833095
}
3084-
else if (pdns::checked_stoi<int>(cmds.at(n)) != 0) {
3085-
pdns::checked_stoi_into(bits, cmds.at(n));
3096+
else if (pdns::checked_stoi<int>(cmd) != 0) {
3097+
pdns::checked_stoi_into(key_param, cmd);
30863098
}
30873099
else {
3088-
cerr << "Unknown algorithm, key flag or size '" << cmds.at(n) << "'" << endl;
3100+
cerr << "Unknown algorithm, key flag or size '" << cmd << "'" << endl;
30893101
return EXIT_FAILURE;
30903102
}
30913103
}
30923104
int64_t id{-1};
3093-
if (!dk.addKey(zone, keyOrZone, algorithm, id, bits, active, published)) {
3105+
if (!dk.addKey(zone, keyOrZone, algorithm, id, key_param, active, published)) {
30943106
cerr << "Adding key failed, perhaps DNSSEC not enabled in configuration?" << endl;
30953107
return 1;
30963108
}
30973109
else {
30983110
cerr << "Added a " << (keyOrZone ? "KSK" : "ZSK") << " with algorithm = " << algorithm << ", active=" << active << endl;
3099-
if (bits)
3100-
cerr << "Requested specific key size of " << bits << " bits" << endl;
3111+
if (key_param && (algorithm == DNSSECKeeper::XMSS || algorithm == DNSSECKeeper::XMSSMT))
3112+
cerr << "Requested xmss(mt) key with oid " << key_param << endl;
3113+
else if (key_param)
3114+
cerr << "Requested specific key size of " << key_param << " bits" << endl;
31013115
if (id == -1) {
31023116
cerr << std::to_string(id) << ": Key was added, but backend does not support returning of key id" << endl;
31033117
}

0 commit comments

Comments
 (0)