Skip to content
Snippets Groups Projects
Commit 085153cf authored by Jan Včelák's avatar Jan Včelák :rocket:
Browse files

libknot/sign: implement dnssec keys creation (RSA only at the moment)

refs #2353
parent 50dd793e
No related branches found
No related tags found
No related merge requests found
......@@ -54,8 +54,12 @@ src/libknot/zone/zone-contents.c
src/libknot/zone/zone-contents.h
src/libknot/zone/zone-tree.h
src/libknot/zone/zone-tree.c
src/libknot/sign/bnutils.h
src/libknot/sign/bnutils.c
src/libknot/sign/key.c
src/libknot/sign/key.h
src/libknot/sign/sig0.c
src/libknot/sign/sig0.h
src/Makefile.am
src/common/hattrie
src/common/hattrie/ahtable.c
......
......@@ -191,7 +191,11 @@ libknot_la_SOURCES = \
libknot/binary.h \
libknot/binary.c \
libknot/sign/key.h \
libknot/sign/key.c
libknot/sign/key.c \
libknot/sign/bnutils.h \
libknot/sign/bnutils.c \
libknot/sign/sig0.h \
libknot/sign/sig0.c
libknots_la_SOURCES = \
common/slab/slab.c \
......
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stddef.h>
#include <string.h>
#include "sign/bnutils.h"
#include "common/base64.h"
BIGNUM *knot_b64_to_bignum(const char *input)
{
size_t size = strlen(input);
uint8_t *decoded;
int32_t decoded_size;
BIGNUM *result;
decoded_size = base64_decode_alloc((uint8_t *)input, size, &decoded);
if (decoded_size < 0) {
return NULL;
}
result = BN_bin2bn((unsigned char *)decoded, (int)decoded_size, NULL);
free(decoded);
return result;
}
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _KNOT_SIGN_BNUTILS_H_
#define _KNOT_SIGN_BNUTILS_H_
#include <openssl/bn.h>
/*!
* \brief Convert Base64 encoded number into OpenSSL BIGNUM format.
*
* \param input Base64 encoded input number
* \return Input number represented in OpenSSL BIGNUM format.
*/
BIGNUM *knot_b64_to_bignum(const char *input);
#endif // _KNOT_SIGN_BNUTILS_H_
......@@ -27,6 +27,7 @@
#include "common/getline_wrap.h"
#include "dname.h"
#include "sign/key.h"
#include "sign/sig0.h"
#include "tsig.h"
/*!
......@@ -80,11 +81,11 @@ static char *get_key_name_from_public_key(const char *filename)
* derived from the previous part of the string. Otherwise, just append the
* extensions.
*/
static int get_key_filenames(const char *input, char **public, char **private)
static int get_key_filenames(const char *input, char **pubname, char **privname)
{
assert(input);
assert(public);
assert(private);
assert(pubname);
assert(privname);
char *name_end = strrchr(input, '.');
size_t base_length;
......@@ -98,15 +99,15 @@ static int get_key_filenames(const char *input, char **public, char **private)
base_length = strlen(input);
}
*public = strndup_with_suffix(input, base_length, ".public");
if (!*public) {
*pubname = strndup_with_suffix(input, base_length, ".public");
if (!*pubname) {
return KNOT_ENOMEM;
}
*private = strndup_with_suffix(input, base_length, ".private");
if (!*private) {
free(*public);
*public = NULL;
*privname = strndup_with_suffix(input, base_length, ".private");
if (!*privname) {
free(*pubname);
*pubname = NULL;
return KNOT_ENOMEM;
}
......@@ -299,7 +300,9 @@ knot_key_type_t knot_get_key_type(const knot_key_params_t *key_params)
return KNOT_KEY_TSIG;
}
//! \todo DNSSEC key recognition
if (key_params->prime_one) {
return KNOT_KEY_DNSSEC;
}
//! \todo TKEY key recognition
......
......@@ -66,17 +66,4 @@ int knot_tsig_key_from_params(const knot_key_params_t *params,
int knot_tsig_key_free(knot_tsig_key_t *key);
/*----------------------------------------------------------------------------*/
enum knot_dnssec_key_usage {
KNOT_KEY_USAGE_NONE = 0,
KNOT_KEY_USAGE_ZONE_SIGN = 1,
KNOT_KEY_USAGE_TRANSACTION_SIGN = 2
};
typedef enum knot_dnssec_key_usage knot_dnssec_key_usage_t;
//int knot_dnssec_key_from_key_params(const knot_key_params_t *params, knot_dnssec_key_t *key);
#endif // _KNOT_SIGN_KEY_H_
#include <openssl/rsa.h>
#include "common/errcode.h"
#include "sign/key.h"
#include "sign/sig0.h"
#include "sign/bnutils.h"
static int create_rsa_context(const knot_key_params_t *params, void **context)
{
if (!context)
return KNOT_EINVAL;
RSA *rsa = RSA_new();
if (rsa == NULL)
return KNOT_ERROR;
rsa->n = knot_b64_to_bignum(params->modulus);
rsa->e = knot_b64_to_bignum(params->public_exponent);
rsa->d = knot_b64_to_bignum(params->private_exponent);
rsa->p = knot_b64_to_bignum(params->prime_one);
rsa->q = knot_b64_to_bignum(params->prime_two);
rsa->dmp1 = knot_b64_to_bignum(params->exponent_one);
rsa->dmq1 = knot_b64_to_bignum(params->exponent_two);
rsa->iqmp = knot_b64_to_bignum(params->coefficient);
if (RSA_check_key(rsa) != 1) {
RSA_free(rsa);
return KNOT_EINVAL; //! \todo Better error code?
}
*context = (void *)rsa;
return KNOT_EOK;
}
static int free_rsa_context(void *context)
{
if (!context)
return KNOT_EINVAL;
RSA_free((RSA *)context);
return KNOT_EOK;
}
int knot_dnssec_key_from_params(const knot_key_params_t *params,
knot_dnssec_key_t *key)
{
if (!key || !params)
return KNOT_EINVAL;
char *name = strdup(params->name);
if (!name)
return KNOT_ENOMEM;
void *context;
int result = create_rsa_context(params, &context);
if (result != KNOT_EOK) {
free(name);
return result;
}
key->name = name;
key->algorithm = params->algorithm;
key->context = context;
return KNOT_EOK;
}
int knot_dnssec_key_free(knot_dnssec_key_t *key)
{
if (!key)
return KNOT_EINVAL;
if (key->name)
free(key->name);
if (key->context)
free_rsa_context(key->context);
memset(key, '\0', sizeof(knot_dnssec_key_t));
return KNOT_EOK;
}
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _KNOT_SIGN_SIG1_H_
#define _KNOT_SIGN_SIG0_H_
#include "sign/key.h"
#if 0
/*!
* \brief DNSSEC Algorithm Numbers
*
* http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xml
*/
enum knot_dnssec_algorithm {
// 0 reserved
KNOT_DNSSEC_ALG_RSAMD5 = 1,
KNOT_DNSSEC_ALG_DH = 2,
KNOT_DNSSEC_ALG_DSA = 3,
// 4 reserved
KNOT_DNSSEC_ALG_RSASHA1 = 5,
KNOT_DNSSEC_ALG_DSA_NSEC3_SHA1 = 6,
KNOT_DNSSEC_ALG_RSASHA1_NSEC3_SHA1 = 7,
KNOT_DNSSEC_ALG_RSASHA256 = 8,
// 9 reserved
KNOT_DNSSEC_ALG_RSASHA512 = 10,
// 11 reserved
KNOT_DNSSEC_ALG_ECC_GOST = 12,
KNOT_DNSSEC_ALG_ECDSAP256SHA256 = 13,
KNOT_DNSSEC_ALG_ECDSAP384SHA384 = 14,
// 15-122 unassigned
// 123-151 reserved
// 252 reserved for indirect keys
// 253 private algorithm
// 254 private algorithm OID
// 255 reserved
};
typedef enum knot_dnssec_algorithm knot_dnssec_algorithm_t;
#endif
enum knot_dnssec_key_usage {
KNOT_KEY_USAGE_NONE = 0,
KNOT_KEY_USAGE_ZONE_SIGN = 1,
KNOT_KEY_USAGE_TRANSACTION_SIGN = 2
};
typedef enum knot_dnssec_key_usage knot_dnssec_key_usage_t;
/*!
* \brief DNSSEC key representation.
*/
struct knot_dnssec_key {
char *name; //!< Key name.
knot_dnssec_algorithm_t algorithm; //!< Algorithm identification.
void *context; //!< Algorithm dependent data.
};
typedef struct knot_dnssec_key knot_dnssec_key_t;
int knot_dnssec_key_from_params(const knot_key_params_t *params,
knot_dnssec_key_t *key);
int knot_dnssec_key_free(knot_dnssec_key_t *key);
#endif // _KNOT_SIGN_SIG0_H_
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment