diff options
author | Jan Vcelak <jan.vcelak@nic.cz> | 2014-02-26 11:42:05 +0100 |
---|---|---|
committer | Jan Vcelak <jan.vcelak@nic.cz> | 2014-03-18 16:30:31 +0100 |
commit | 446f4492ffe9161f4874083ffb8ec1d0b5aec42b (patch) | |
tree | d4b96dbad74d1b1c685c0a8b75112a39fa12271e | |
parent | [dnssec] hook the library subproject to autotools (diff) | |
download | knot-446f4492ffe9161f4874083ffb8ec1d0b5aec42b.tar.xz knot-446f4492ffe9161f4874083ffb8ec1d0b5aec42b.zip |
[dnssec] import some base code
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | dnssec/.gitignore | 2 | ||||
-rw-r--r-- | dnssec/Makefile.am | 11 | ||||
-rw-r--r-- | dnssec/src/binary.c | 63 | ||||
-rw-r--r-- | dnssec/src/binary.h | 9 | ||||
-rw-r--r-- | dnssec/src/error.h | 19 | ||||
-rw-r--r-- | dnssec/src/key.c | 121 | ||||
-rw-r--r-- | dnssec/src/key.h | 91 | ||||
-rw-r--r-- | dnssec/src/keys/crypto.h | 6 | ||||
-rw-r--r-- | dnssec/src/keys/legacy.h | 2 | ||||
-rw-r--r-- | dnssec/src/keystore.c | 4 | ||||
-rw-r--r-- | dnssec/src/shared.h | 8 | ||||
-rw-r--r-- | dnssec/src/sign.c | 62 | ||||
-rw-r--r-- | dnssec/src/sign.h | 15 | ||||
-rw-r--r-- | dnssec/tests/.gitignore | 7 | ||||
-rw-r--r-- | dnssec/tests/Makefile.am | 9 | ||||
-rw-r--r-- | dnssec/tests/binary.c | 43 | ||||
-rw-r--r-- | dnssec/tests/key.c | 18 | ||||
-rw-r--r-- | dnssec/tests/sign.c | 10 |
20 files changed, 469 insertions, 39 deletions
diff --git a/Makefile.am b/Makefile.am index 20ad25258..693ddeb37 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,2 +1,2 @@ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS = libtap src tests samples doc man patches +SUBDIRS = libtap dnssec src tests samples doc man patches diff --git a/configure.ac b/configure.ac index c28e2b0dd..e4f8f6467 100644 --- a/configure.ac +++ b/configure.ac @@ -101,6 +101,9 @@ if test "$enable_systemd" = yes; then AC_DEFINE([ENABLE_SYSTEMD_NOTIFY], [1], [Use systemd notifications.]) fi +# GnuTLS crypto backend +PKG_CHECK_MODULES([gnutls], [gnutls nettle]) + # Debug modules AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug=server,zones,xfr,packet,rr,ns,loader,dnssec], @@ -364,6 +367,8 @@ AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile src/zscanner/Makefile + dnssec/Makefile + dnssec/tests/Makefile man/khost.1 man/knotc.8 man/knotd.8 @@ -388,5 +393,6 @@ echo " Ragel: ${RAGEL} ${FSM_TYPE} Utils with IDN: ${libidn} Use systemd notifications: ${enable_systemd} + GnuTLS: CFLAGS: ${gnutls_CFLAGS} LIBS: ${gnutls_LIBS} Continue with 'make' command" diff --git a/dnssec/.gitignore b/dnssec/.gitignore new file mode 100644 index 000000000..b336cc7ce --- /dev/null +++ b/dnssec/.gitignore @@ -0,0 +1,2 @@ +/Makefile +/Makefile.in diff --git a/dnssec/Makefile.am b/dnssec/Makefile.am index a823dace0..346f893b2 100644 --- a/dnssec/Makefile.am +++ b/dnssec/Makefile.am @@ -5,8 +5,11 @@ SUBDIRS = tests lib_LTLIBRARIES = libdnssec.la -libdnssec_la_CFLAGS = $(AM_CFLAGS) $(GNUTLS_CFLAGS) -fvisibility=hidden -libdnssec_la_LDFLAGS = $(GNUTLS_LIBS) -version-info 0:1:0 +libdnssec_la_CFLAGS = $(AM_CFLAGS) $(gnutls_CFLAGS) -fvisibility=hidden +libdnssec_la_LDFLAGS = $(gnutls_LIBS) -version-info 0:1:0 libdnssec_la_SOURCES = \ - src/key.c \ - src/key.h + src/binary.h src/binary.c \ + src/binary.h src/binary.c \ + src/key.h src/key.c \ + src/keystore.h src/keystore.c \ + src/sign.h src/sign.c diff --git a/dnssec/src/binary.c b/dnssec/src/binary.c new file mode 100644 index 000000000..197a89419 --- /dev/null +++ b/dnssec/src/binary.c @@ -0,0 +1,63 @@ +#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; +} diff --git a/dnssec/src/binary.h b/dnssec/src/binary.h index a4b473a9d..1232fe6d3 100644 --- a/dnssec/src/binary.h +++ b/dnssec/src/binary.h @@ -3,7 +3,16 @@ #include <stdint.h> #include <stdlib.h> +#include "shared.h" + +#define _cleanup_binary_ _cleanup_(dnssec_binary_free) + typedef struct dnssec_binary { uint8_t *data; size_t size; } 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); diff --git a/dnssec/src/error.h b/dnssec/src/error.h index 7ac29f91f..bbcaf023d 100644 --- a/dnssec/src/error.h +++ b/dnssec/src/error.h @@ -1,9 +1,26 @@ #pragma once +#include <errno.h> + +#define errno2error(errno) (-(100 + (errno))) + enum dnssec_error { 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, }; + +#undef errno2error diff --git a/dnssec/src/key.c b/dnssec/src/key.c index e69de29bb..8d583ec30 100644 --- a/dnssec/src/key.c +++ b/dnssec/src/key.c @@ -0,0 +1,121 @@ +#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; +} diff --git a/dnssec/src/key.h b/dnssec/src/key.h index f91b4d747..cd2d02630 100644 --- a/dnssec/src/key.h +++ b/dnssec/src/key.h @@ -1,39 +1,76 @@ #pragma once +#include <gnutls/abstract.h> #include <stdint.h> #include "binary.h" +#include "shared.h" -enum dnssec_dnskey_algorithm { - DNSKEY_ALGORITHM_INVALID = 0, +typedef enum dnssec_key_algorithm { + 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, - DNSKEY_ALGORITHM_RSA_SHA1 = 5, - DNSKEY_ALGORITHM_DSA_SHA1_NSEC3 = 6, - DNSKEY_ALGORITHM_RSA_SHA1_NSEC3 = 7, - DNSKEY_ALGORITHM_RSA_SHA256 = 8, - DNSKEY_ALGORITHM_RSA_SHA512 = 10, - DNSKEY_ALGORITHM_ECDSA_P256_SHA256 = 13, - DNSKEY_ALGORITHM_ECDSA_P384_SHA384 = 14 -}; +typedef enum dnssec_key_digest { + DNSSEC_KEY_DIGEST_INVALID = 0, + DNSSEC_KEY_DIGEST_SHA1 = 1, + DNSSEC_KEY_DIGEST_SHA256 = 2, + DNSSEC_KEY_DIGEST_SHA384 = 4, +} dnssec_key_digest_t; -typedef uint8_t dnssec_key_id_t[20]; +struct dnssec_key; +typedef struct dnssec_key dnssec_key_t; -typedef struct dnssec_key { - dnssec_key_id_t id; - uint16_t keytag; +#define _cleanup_key_ _cleanup_(dnssec_key_free) - struct { - uint16_t flags; - uint8_t algorithm; - dnssec_binary_t *public_key; - } dnskey_rdata; +int dnssec_key_new(dnssec_key_t **key); +void dnssec_key_free(dnssec_key_t **key); - void *public_key; - void *private_key; -} dnssec_key_t; +// LEGACY API -int dnssec_key_to_dnskey(const dnssec_key_t *key, dnssec_binary_t *dnskey); -int dnssec_dnskey_to_key(const dnssec_binary_t *dnskey, dnssec_key_t *key); +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); -uint8_t dnssec_key_get_algorithm(const dnssec_key_t *key); -uint16_t dnssec_key_get_keytag(const dnssec_key_t *key); +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); + +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 diff --git a/dnssec/src/keys/crypto.h b/dnssec/src/keys/crypto.h new file mode 100644 index 000000000..fda4509b1 --- /dev/null +++ b/dnssec/src/keys/crypto.h @@ -0,0 +1,6 @@ +#pragma once + +#include <gnutls/abstract.h> + +typedef gnutls_pubkey_t public_key_t; +typedef gnutls_privkey_t private_key_t; diff --git a/dnssec/src/keys/legacy.h b/dnssec/src/keys/legacy.h new file mode 100644 index 000000000..3f59c932d --- /dev/null +++ b/dnssec/src/keys/legacy.h @@ -0,0 +1,2 @@ +#pragma once + diff --git a/dnssec/src/keystore.c b/dnssec/src/keystore.c index 325cd0e8f..2849ce280 100644 --- a/dnssec/src/keystore.c +++ b/dnssec/src/keystore.c @@ -1,6 +1,8 @@ #include "error.h" #include "keystore.h" +#if 0 + dnssec_keystore_t *dnssec_keystore_open(const char *path); int dnssec_keystore_close(dnssec_keystore_t **keystore) @@ -11,3 +13,5 @@ int dnssec_keystore_close(dnssec_keystore_t **keystore) return DNSSEC_EOK; } + +#endif diff --git a/dnssec/src/shared.h b/dnssec/src/shared.h new file mode 100644 index 000000000..5fd9c74c1 --- /dev/null +++ b/dnssec/src/shared.h @@ -0,0 +1,8 @@ +#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"))) diff --git a/dnssec/src/sign.c b/dnssec/src/sign.c new file mode 100644 index 000000000..f5f1a9106 --- /dev/null +++ b/dnssec/src/sign.c @@ -0,0 +1,62 @@ +#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; +} diff --git a/dnssec/src/sign.h b/dnssec/src/sign.h new file mode 100644 index 000000000..224bcaf68 --- /dev/null +++ b/dnssec/src/sign.h @@ -0,0 +1,15 @@ +#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); diff --git a/dnssec/tests/.gitignore b/dnssec/tests/.gitignore new file mode 100644 index 000000000..65ffebd95 --- /dev/null +++ b/dnssec/tests/.gitignore @@ -0,0 +1,7 @@ +/Makefile +/Makefile.in + +# test binaries +binary +key +sign diff --git a/dnssec/tests/Makefile.am b/dnssec/tests/Makefile.am index 1e441cf0a..ffc5747d9 100644 --- a/dnssec/tests/Makefile.am +++ b/dnssec/tests/Makefile.am @@ -1,8 +1,11 @@ -AM_CPPFLAGS = -I$(top_srcdir)/libtap -LDADD = $(top_builddir)/libtap/libtap.a +AM_CPPFLAGS = -I$(top_srcdir)/libtap -I../src +LDADD = $(top_builddir)/libtap/libtap.a \ + ../libdnssec.la check_PROGRAMS = \ - key + binary \ + key \ + sign check-compile-only: $(check_PROGRAMS) diff --git a/dnssec/tests/binary.c b/dnssec/tests/binary.c new file mode 100644 index 000000000..96945b005 --- /dev/null +++ b/dnssec/tests/binary.c @@ -0,0 +1,43 @@ +#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; +} diff --git a/dnssec/tests/key.c b/dnssec/tests/key.c index 106ed4e82..609d0b8fe 100644 --- a/dnssec/tests/key.c +++ b/dnssec/tests/key.c @@ -1,10 +1,22 @@ -#include <config.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(); - ok(1, "foo"); + legacy_main(); + + ok(0, "err"); + return 0; } diff --git a/dnssec/tests/sign.c b/dnssec/tests/sign.c new file mode 100644 index 000000000..810d5457a --- /dev/null +++ b/dnssec/tests/sign.c @@ -0,0 +1,10 @@ +#include <tap/basic.h> + +int main(void) +{ + plan_lazy(); + + ok(1, "sign"); + + return 0; +} |