Commit 446f4492 authored by Jan Včelák's avatar Jan Včelák 🚀

[dnssec] import some base code

parent c907cd67
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
SUBDIRS = libtap src tests samples doc man patches SUBDIRS = libtap dnssec src tests samples doc man patches
...@@ -101,6 +101,9 @@ if test "$enable_systemd" = yes; then ...@@ -101,6 +101,9 @@ if test "$enable_systemd" = yes; then
AC_DEFINE([ENABLE_SYSTEMD_NOTIFY], [1], [Use systemd notifications.]) AC_DEFINE([ENABLE_SYSTEMD_NOTIFY], [1], [Use systemd notifications.])
fi fi
# GnuTLS crypto backend
PKG_CHECK_MODULES([gnutls], [gnutls nettle])
# Debug modules # Debug modules
AC_ARG_ENABLE([debug], AC_ARG_ENABLE([debug],
AS_HELP_STRING([--enable-debug=server,zones,xfr,packet,rr,ns,loader,dnssec], AS_HELP_STRING([--enable-debug=server,zones,xfr,packet,rr,ns,loader,dnssec],
...@@ -364,6 +367,8 @@ AC_CONFIG_FILES([Makefile ...@@ -364,6 +367,8 @@ AC_CONFIG_FILES([Makefile
src/Makefile src/Makefile
tests/Makefile tests/Makefile
src/zscanner/Makefile src/zscanner/Makefile
dnssec/Makefile
dnssec/tests/Makefile
man/khost.1 man/khost.1
man/knotc.8 man/knotc.8
man/knotd.8 man/knotd.8
...@@ -388,5 +393,6 @@ echo " ...@@ -388,5 +393,6 @@ echo "
Ragel: ${RAGEL} ${FSM_TYPE} Ragel: ${RAGEL} ${FSM_TYPE}
Utils with IDN: ${libidn} Utils with IDN: ${libidn}
Use systemd notifications: ${enable_systemd} Use systemd notifications: ${enable_systemd}
GnuTLS: CFLAGS: ${gnutls_CFLAGS} LIBS: ${gnutls_LIBS}
Continue with 'make' command" Continue with 'make' command"
/Makefile
/Makefile.in
...@@ -5,8 +5,11 @@ SUBDIRS = tests ...@@ -5,8 +5,11 @@ SUBDIRS = tests
lib_LTLIBRARIES = libdnssec.la lib_LTLIBRARIES = libdnssec.la
libdnssec_la_CFLAGS = $(AM_CFLAGS) $(GNUTLS_CFLAGS) -fvisibility=hidden libdnssec_la_CFLAGS = $(AM_CFLAGS) $(gnutls_CFLAGS) -fvisibility=hidden
libdnssec_la_LDFLAGS = $(GNUTLS_LIBS) -version-info 0:1:0 libdnssec_la_LDFLAGS = $(gnutls_LIBS) -version-info 0:1:0
libdnssec_la_SOURCES = \ libdnssec_la_SOURCES = \
src/key.c \ src/binary.h src/binary.c \
src/key.h src/binary.h src/binary.c \
src/key.h src/key.c \
src/keystore.h src/keystore.c \
src/sign.h src/sign.c
#include <assert.h>
#include <nettle/base64.h>
#include "binary.h"
#include "error.h"
static size_t base64_decode_raw(const uint8_t *src, size_t src_len,
uint8_t *dst, size_t dst_max_size)
{
assert(src);
assert(dst);
struct base64_decode_ctx ctx;
base64_decode_init(&ctx);
unsigned dst_size = dst_max_size;
int result = base64_decode_update(&ctx, &dst_size, dst, src_len, src);
if (result != 1) {
return 0;
}
return (size_t) dst_size;
}
int dnssec_binary_from_base64(dnssec_binary_t *binary, const uint8_t *base64, size_t base64_size)
{
if (!binary || !base64) {
return DNSSEC_EINVAL;
}
size_t raw_size = BASE64_DECODE_LENGTH(base64_size);
uint8_t *raw = malloc(raw_size);
if (raw == NULL) {
return DNSSEC_ENOMEM;
}
size_t real_size = base64_decode_raw(base64, base64_size, raw, raw_size);
if (real_size == 0) {
free(raw);
return DNSSEC_EINVAL;
}
if (real_size < raw_size) {
raw = realloc(raw, real_size);
}
binary->data = raw;
binary->size = real_size;
return DNSSEC_EOK;
}
void dnssec_binary_free(dnssec_binary_t *binary)
{
if (!binary) {
return;
}
free(binary->data);
binary->data = NULL;
binary->size = 0;
}
...@@ -3,7 +3,16 @@ ...@@ -3,7 +3,16 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include "shared.h"
#define _cleanup_binary_ _cleanup_(dnssec_binary_free)
typedef struct dnssec_binary { typedef struct dnssec_binary {
uint8_t *data; uint8_t *data;
size_t size; size_t size;
} dnssec_binary_t; } dnssec_binary_t;
int dnssec_binary_from_base64(dnssec_binary_t *binary, const uint8_t *base64,
size_t base64_size);
void dnssec_binary_free(dnssec_binary_t *binary);
#pragma once #pragma once
#include <errno.h>
#define errno2error(errno) (-(100 + (errno)))
enum dnssec_error { enum dnssec_error {
DNSSEC_EOK = 0, DNSSEC_EOK = 0,
DNSSEC_EINVAL = -1, /* Directly mapped error codes. */
DNSSEC_ENOMEM = errno2error(ENOMEM),
DNSSEC_EINVAL = errno2error(EINVAL),
// DNSSEC_ENOTSUP = errno2error(ENOTSUP),
// DNSSEC_EBUSY = errno2error(EBUSY),
// DNSSEC_EAGAIN = errno2error(EAGAIN),
// DNSSEC_EACCES = errno2error(EACCES),
// DNSSEC_ECONNREFUSED = errno2error(ECONNREFUSED),
// DNSSEC_EISCONN = errno2error(EISCONN),
// DNSSEC_EADDRINUSE = errno2error(EADDRINUSE),
// DNSSEC_ENOENT = errno2error(ENOENT),
// DNSSEC_ERANGE = errno2error(ERANGE),
DNSSEC_ERROR = -1000, DNSSEC_ERROR = -1000,
}; };
#undef errno2error
#include <string.h>
#include <gnutls/abstract.h>
#include "key.h"
#include "error.h"
typedef uint8_t dnssec_key_id_t[20];
struct dnssec_key {
dnssec_key_id_t id;
uint16_t keytag;
struct {
uint16_t flags;
uint8_t algorithm;
dnssec_binary_t public_key;
} rdata;
gnutls_pubkey_t public_key;
gnutls_privkey_t private_key;
};
int dnssec_key_new(dnssec_key_t **key_ptr)
{
if (!key_ptr) {
return DNSSEC_EINVAL;
}
dnssec_key_t *key = malloc(sizeof(dnssec_key_t));
if (!key) {
return DNSSEC_ENOMEM;
}
memset(key, 0, sizeof(dnssec_key_t));
*key_ptr = key;
return DNSSEC_EOK;
}
void dnssec_key_free(dnssec_key_t **key_ptr)
{
if (!key_ptr || !*key_ptr) {
return;
}
dnssec_key_t *key = *key_ptr;
dnssec_binary_free(&key->rdata.public_key);
gnutls_privkey_deinit(key->private_key);
gnutls_pubkey_deinit(key->public_key);
free(key);
*key_ptr = NULL;
}
int dnssec_key_from_rsa_params(dnssec_key_t *key,
dnssec_key_algorithm_t algorithm,
const dnssec_binary_t *modulus,
const dnssec_binary_t *public_exponent,
const dnssec_binary_t *private_exponent,
const dnssec_binary_t *first_prime,
const dnssec_binary_t *second_prime,
const dnssec_binary_t *coefficient)
{
// int result;
// gnutls_x509_privkey_import_rsa_raw(key, m, e, d, p, q, u);
return DNSSEC_ERROR;
}
int dnssec_key_from_dsa_params(dnssec_key_t *key,
dnssec_key_algorithm_t algorithm,
const dnssec_binary_t *p,
const dnssec_binary_t *q,
const dnssec_binary_t *g,
const dnssec_binary_t *y,
const dnssec_binary_t *x)
{
// gnutls_x509_privkey_import_dsa_raw()
return DNSSEC_ERROR;
}
int dnssec_key_from_ecdsa_params(dnssec_key_t *key,
dnssec_key_algorithm_t algorithm,
const dnssec_binary_t *x_coordinate,
const dnssec_binary_t *y_coordinate,
const dnssec_binary_t *private_key)
{
// gnutls_x509_privkey_import_ecc_raw()
return DNSSEC_ERROR;
}
int dnssec_key_from_params(dnssec_key_t *key, uint16_t flags, uint8_t protocol,
uint8_t algorithm, const dnssec_binary_t *public_key)
{
return DNSSEC_ERROR;
}
int dnssec_key_from_dnskey(dnssec_key_t *key, const dnssec_binary_t *rdata)
{
if (!key || !rdata) {
return DNSSEC_EINVAL;
}
return DNSSEC_ERROR;
}
int dnssec_key_get_dnskey(const dnssec_key_t *key, dnssec_binary_t *rdata)
{
if (!key || !rdata) {
return DNSSEC_EINVAL;
}
return DNSSEC_ERROR;
}
int dnssec_key_get_ds(const dnssec_key_t *key, dnssec_key_digest_t digest,
dnssec_binary_t *rdata)
{
return DNSSEC_ERROR;
}
#pragma once #pragma once
#include <gnutls/abstract.h>
#include <stdint.h> #include <stdint.h>
#include "binary.h" #include "binary.h"
#include "shared.h"
enum dnssec_dnskey_algorithm { typedef enum dnssec_key_algorithm {
DNSKEY_ALGORITHM_INVALID = 0, DNSSEC_KEY_ALGORITHM_INVALID = 0,
DNSSEC_KEY_ALGORITHM_DSA_SHA1 = 3,
DNSSEC_KEY_ALGORITHM_RSA_SHA1 = 5,
DNSSEC_KEY_ALGORITHM_DSA_SHA1_NSEC3 = 6,
DNSSEC_KEY_ALGORITHM_RSA_SHA1_NSEC3 = 7,
DNSSEC_KEY_ALGORITHM_RSA_SHA256 = 8,
DNSSEC_KEY_ALGORITHM_RSA_SHA512 = 10,
DNSSEC_KEY_ALGORITHM_ECDSA_P256_SHA256 = 13,
DNSSEC_KEY_ALGORITHM_ECDSA_P384_SHA384 = 14,
} dnssec_key_algorithm_t;
DNSKEY_ALGORITHM_DSA_SHA1 = 3, typedef enum dnssec_key_digest {
DNSKEY_ALGORITHM_RSA_SHA1 = 5, DNSSEC_KEY_DIGEST_INVALID = 0,
DNSKEY_ALGORITHM_DSA_SHA1_NSEC3 = 6, DNSSEC_KEY_DIGEST_SHA1 = 1,
DNSKEY_ALGORITHM_RSA_SHA1_NSEC3 = 7, DNSSEC_KEY_DIGEST_SHA256 = 2,
DNSKEY_ALGORITHM_RSA_SHA256 = 8, DNSSEC_KEY_DIGEST_SHA384 = 4,
DNSKEY_ALGORITHM_RSA_SHA512 = 10, } dnssec_key_digest_t;
DNSKEY_ALGORITHM_ECDSA_P256_SHA256 = 13,
DNSKEY_ALGORITHM_ECDSA_P384_SHA384 = 14
};
typedef uint8_t dnssec_key_id_t[20]; struct dnssec_key;
typedef struct dnssec_key dnssec_key_t;
typedef struct dnssec_key { #define _cleanup_key_ _cleanup_(dnssec_key_free)
dnssec_key_id_t id;
uint16_t keytag;
struct { int dnssec_key_new(dnssec_key_t **key);
uint16_t flags; void dnssec_key_free(dnssec_key_t **key);
uint8_t algorithm;
dnssec_binary_t *public_key;
} dnskey_rdata;
void *public_key; // LEGACY API
void *private_key;
} dnssec_key_t;
int dnssec_key_to_dnskey(const dnssec_key_t *key, dnssec_binary_t *dnskey); int dnssec_key_from_rsa_params(dnssec_key_t *key,
int dnssec_dnskey_to_key(const dnssec_binary_t *dnskey, dnssec_key_t *key); dnssec_key_algorithm_t algorithm,
const dnssec_binary_t *modulus,
const dnssec_binary_t *public_exponent,
const dnssec_binary_t *private_exponent,
const dnssec_binary_t *first_prime,
const dnssec_binary_t *second_prime,
const dnssec_binary_t *coefficient);
uint8_t dnssec_key_get_algorithm(const dnssec_key_t *key); int dnssec_key_from_dsa_params(dnssec_key_t *key,
uint16_t dnssec_key_get_keytag(const dnssec_key_t *key); dnssec_key_algorithm_t algorithm,
const dnssec_binary_t *p,
const dnssec_binary_t *q,
const dnssec_binary_t *g,
const dnssec_binary_t *y,
const dnssec_binary_t *x);
int dnssec_key_from_ecdsa_params(dnssec_key_t *key,
dnssec_key_algorithm_t algorithm,
const dnssec_binary_t *x_coordinate,
const dnssec_binary_t *y_coordinate,
const dnssec_binary_t *private_key);
// TODO: PKCS 8
// TODO: PKCS 11
// FORMAT CONVERSION
int dnssec_key_from_params(dnssec_key_t *key, uint16_t flags, uint8_t protocol,
uint8_t algorithm, const dnssec_binary_t *public_key);
int dnssec_key_from_dnskey(dnssec_key_t *key, const dnssec_binary_t *rdata);
int dnssec_key_get_dnskey(const dnssec_key_t *key, dnssec_binary_t *rdata);
int dnssec_key_get_ds(const dnssec_key_t *key, dnssec_key_digest_t digest,
dnssec_binary_t *rdata);
// HASH FUNCTIONS
#pragma once
#include <gnutls/abstract.h>
typedef gnutls_pubkey_t public_key_t;
typedef gnutls_privkey_t private_key_t;
#include "error.h" #include "error.h"
#include "keystore.h" #include "keystore.h"
#if 0
dnssec_keystore_t *dnssec_keystore_open(const char *path); dnssec_keystore_t *dnssec_keystore_open(const char *path);
int dnssec_keystore_close(dnssec_keystore_t **keystore) int dnssec_keystore_close(dnssec_keystore_t **keystore)
...@@ -11,3 +13,5 @@ int dnssec_keystore_close(dnssec_keystore_t **keystore) ...@@ -11,3 +13,5 @@ int dnssec_keystore_close(dnssec_keystore_t **keystore)
return DNSSEC_EOK; return DNSSEC_EOK;
} }
#endif
#pragma once
#define _unused_ __attribute__((unused))
#define _cleanup_(var) __attribute__((cleanup(var)))
#define _destructor_ __attribute__((destructor))
#define _public_ __attribute__((visibility("default")))
#define _hidden_ __attribute__((visibility("hidden")))
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#include "error.h"
#include "key.h"
#include "sign.h"
struct dnssec_sign_ctx {
const dnssec_key_t *key;
const gnutls_hash_hd_t *digest;
int a[10];
};
dnssec_sign_ctx_t *dnssec_sign_new(dnssec_key_t *key)
{
if (!key) {
return NULL;
}
dnssec_sign_ctx_t *result = malloc(sizeof(*result));
assert(sizeof(*result) == sizeof(dnssec_sign_ctx_t));
memset(result, 0, sizeof(*result));
result->key = key;
return result;
}
void dnssec_sign_free(dnssec_sign_ctx_t *ctx)
{
free(ctx);
}
int dnssec_sign_init(dnssec_sign_ctx_t *ctx)
{
return DNSSEC_ERROR;
}
int dnssec_sign_add(dnssec_sign_ctx_t *ctx, uint8_t *data, size_t size)
{
return DNSSEC_ERROR;
}
size_t dnssec_sign_size(dnssec_sign_ctx_t *ctx)
{
return 0;
}
int dnssec_sign_write(dnssec_sign_ctx_t *ctx, uint8_t *data, size_t size)
{
return DNSSEC_ERROR;
}
int dnssec_sign_verify(dnssec_sign_ctx_t *ctx, uint8_t *data, size_t size)
{
return DNSSEC_ERROR;
}
#pragma once
#include <stdint.h>
struct dnssec_sign_ctx;
typedef struct dnssec_sign_ctx dnssec_sign_ctx_t;
dnssec_sign_ctx_t *dnssec_sign_new(dnssec_key_t *key);
void dnssec_sign_free(dnssec_sign_ctx_t *ctx);
int dnssec_sign_init(dnssec_sign_ctx_t *ctx);
int dnssec_sign_add(dnssec_sign_ctx_t *ctx, uint8_t *data, size_t size);
size_t dnssec_sign_size(dnssec_sign_ctx_t *ctx);
int dnssec_sign_write(dnssec_sign_ctx_t *ctx, uint8_t *data, size_t size);
int dnssec_sign_verify(dnssec_sign_ctx_t *ctx, uint8_t *data, size_t size);
/Makefile
/Makefile.in
# test binaries
binary
key
sign
AM_CPPFLAGS = -I$(top_srcdir)/libtap AM_CPPFLAGS = -I$(top_srcdir)/libtap -I../src
LDADD = $(top_builddir)/libtap/libtap.a LDADD = $(top_builddir)/libtap/libtap.a \
../libdnssec.la
check_PROGRAMS = \ check_PROGRAMS = \
key binary \
key \
sign
check-compile-only: $(check_PROGRAMS) check-compile-only: $(check_PROGRAMS)
......
#include <tap/basic.h>
#include <string.h>
#include "binary.h"
#include "error.h"
typedef struct test_string {
const char *encoded;
size_t encoded_size;
const char *decoded;
size_t decoded_size;
} test_string_t;
int main(void)
{
plan_lazy();
test_string_t data[] = {
{ "YQ==", 4, "a", 1 },
{ "YWI=", 4, "ab", 2 },
{ "YWJj", 4, "abc", 3 },
{ "YWJjZA==", 8, "abcd", 4 },
{ "YWJjZGU=", 8, "abcde", 5 },
{ "YWJjZGVm", 8, "abcdef", 6 },
{ NULL }
};
for (int i = 0; data[i].encoded != NULL; i++) {
test_string_t *ts = &data[i];
dnssec_binary_t _cleanup_binary_ binary = { 0 };
int r = dnssec_binary_from_base64(&binary,
(const uint8_t *)ts->encoded,
ts->encoded_size);
ok(r == DNSSEC_EOK, "[%d] conversion performed", i);
ok(binary.size == ts->decoded_size &&
memcmp(binary.data, ts->decoded, binary.size) == 0,
"[%d] conversion is correct", i);
}
return 0;
}
#include <config.h>
#include <tap/basic.h> #include <tap/basic.h>
int main(int argc, char *argv[]) #include <binary.h>
#include <key.h>
static int legacy_main(void)
{
dnssec_key_t _cleanup_key_ *rsa_key = NULL;
dnssec_key_t _cleanup_key_ *dsa_key = NULL;
dnssec_key_t _cleanup_key_ *ecdsa_key = NULL;
}
int main(void)
{ {
plan_lazy(); plan_lazy();
ok(1, "foo"); legacy_main();
ok(0, "err");
return 0; return 0;
} }
#include <tap/basic.h>
int main(void)
{
plan_lazy();
ok(1, "sign");
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment