diff --git a/CHANGES b/CHANGES index e53bdc4f59..8aa287d905 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +2999. [func] Add GOST support (RFC 5933). [RT #20639] + 2998. [func] Add isc_task_beginexclusive and isc_task_endexclusive to the task api. [RT #22776] diff --git a/bin/dnssec/dnssec-dsfromkey.c b/bin/dnssec/dnssec-dsfromkey.c index 499255e26e..d21052a340 100644 --- a/bin/dnssec/dnssec-dsfromkey.c +++ b/bin/dnssec/dnssec-dsfromkey.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-dsfromkey.c,v 1.18 2010/01/11 23:48:37 tbox Exp $ */ +/* $Id: dnssec-dsfromkey.c,v 1.19 2010/12/23 04:07:59 marka Exp $ */ /*! \file */ @@ -299,7 +299,7 @@ usage(void) { fprintf(stderr, " -K : directory in which to find " "key file or keyset file\n"); fprintf(stderr, " -a algorithm: digest algorithm " - "(SHA-1 or SHA-256)\n"); + "(SHA-1, SHA-256 or GOST)\n"); fprintf(stderr, " -1: use SHA-1\n"); fprintf(stderr, " -2: use SHA-256\n"); fprintf(stderr, " -l: add lookaside zone and print DLV records\n"); @@ -414,6 +414,10 @@ main(int argc, char **argv) { else if (strcasecmp(algname, "SHA256") == 0 || strcasecmp(algname, "SHA-256") == 0) dtype = DNS_DSDIGEST_SHA256; +#ifdef HAVE_OPENSSL_GOST + else if (strcasecmp(algname, "GOST") == 0) + dtype = DNS_DSDIGEST_GOST; +#endif else fatal("unknown algorithm %s", algname); } diff --git a/bin/dnssec/dnssec-dsfromkey.docbook b/bin/dnssec/dnssec-dsfromkey.docbook index df24df14e8..f420f5972c 100644 --- a/bin/dnssec/dnssec-dsfromkey.docbook +++ b/bin/dnssec/dnssec-dsfromkey.docbook @@ -17,7 +17,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + August 26, 2009 @@ -105,8 +105,8 @@ Select the digest algorithm. The value of - must be one of SHA-1 (SHA1) or - SHA-256 (SHA256). These values are case insensitive. + must be one of SHA-1 (SHA1), + SHA-256 (SHA256) or GOST. These values are case insensitive. diff --git a/bin/dnssec/dnssec-keyfromlabel.c b/bin/dnssec/dnssec-keyfromlabel.c index b9d2ed4859..db3894fbb5 100644 --- a/bin/dnssec/dnssec-keyfromlabel.c +++ b/bin/dnssec/dnssec-keyfromlabel.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-keyfromlabel.c,v 1.31 2010/01/19 23:48:55 tbox Exp $ */ +/* $Id: dnssec-keyfromlabel.c,v 1.32 2010/12/23 04:07:59 marka Exp $ */ /*! \file */ @@ -55,7 +55,7 @@ int verbose; static const char *algs = "RSA | RSAMD5 | DH | DSA | RSASHA1 |" " NSEC3DSA | NSEC3RSASHA1 |" - " RSASHA256 | RSASHA512"; + " RSASHA256 | RSASHA512 | ECCGOST"; ISC_PLATFORM_NORETURN_PRE static void usage(void) ISC_PLATFORM_NORETURN_POST; @@ -364,7 +364,8 @@ main(int argc, char **argv) { if (use_nsec3 && alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 && - alg != DST_ALG_RSASHA256 && alg != DST_ALG_RSASHA512) { + alg != DST_ALG_RSASHA256 && alg != DST_ALG_RSASHA512 && + alg != DST_ALG_ECCGOST) { fatal("%s is incompatible with NSEC3; " "do not use the -3 option", algname); } diff --git a/bin/dnssec/dnssec-keyfromlabel.docbook b/bin/dnssec/dnssec-keyfromlabel.docbook index 2284f46478..2cd84d6315 100644 --- a/bin/dnssec/dnssec-keyfromlabel.docbook +++ b/bin/dnssec/dnssec-keyfromlabel.docbook @@ -17,7 +17,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + February 8, 2008 @@ -93,7 +93,7 @@ Selects the cryptographic algorithm. The value of must be one of RSAMD5, RSASHA1, - DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512. + DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST. These values are case insensitive. diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c index a9fe4f9433..9af739f769 100644 --- a/bin/dnssec/dnssec-keygen.c +++ b/bin/dnssec/dnssec-keygen.c @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-keygen.c,v 1.114 2010/08/16 23:46:51 tbox Exp $ */ +/* $Id: dnssec-keygen.c,v 1.115 2010/12/23 04:07:59 marka Exp $ */ /*! \file */ @@ -84,7 +84,7 @@ usage(void) { fprintf(stderr, " -a :\n"); fprintf(stderr, " RSA | RSAMD5 | DSA | RSASHA1 | NSEC3RSASHA1" " | NSEC3DSA |\n"); - fprintf(stderr, " RSASHA256 | RSASHA512 |\n"); + fprintf(stderr, " RSASHA256 | RSASHA512 | ECCGOST |\n"); fprintf(stderr, " DH | HMAC-MD5 | HMAC-SHA1 | HMAC-SHA224 | " "HMAC-SHA256 | \n"); fprintf(stderr, " HMAC-SHA384 | HMAC-SHA512\n"); @@ -101,6 +101,7 @@ usage(void) { fprintf(stderr, " DSA:\t\t[512..1024] and divisible by 64\n"); fprintf(stderr, " NSEC3DSA:\t[512..1024] and divisible " "by 64\n"); + fprintf(stderr, " ECCGOST:\tignored\n"); fprintf(stderr, " HMAC-MD5:\t[1..512]\n"); fprintf(stderr, " HMAC-SHA1:\t[1..160]\n"); fprintf(stderr, " HMAC-SHA224:\t[1..224]\n"); @@ -129,6 +130,7 @@ usage(void) { "records with (default: 0)\n"); fprintf(stderr, " -T : DNSKEY | KEY (default: DNSKEY; " "use KEY for SIG(0))\n"); + fprintf(stderr, " ECCGOST:\tignored\n"); fprintf(stderr, " -t : " "AUTHCONF | NOAUTHCONF | NOAUTH | NOCONF " "(default: AUTHCONF)\n"); @@ -542,7 +544,8 @@ main(int argc, char **argv) { if (use_nsec3 && alg != DST_ALG_NSEC3DSA && alg != DST_ALG_NSEC3RSASHA1 && - alg != DST_ALG_RSASHA256 && alg!= DST_ALG_RSASHA512) { + alg != DST_ALG_RSASHA256 && alg!= DST_ALG_RSASHA512 && + alg != DST_ALG_ECCGOST) { fatal("%s is incompatible with NSEC3; " "do not use the -3 option", algname); } @@ -574,9 +577,8 @@ main(int argc, char **argv) { fprintf(stderr, "key size not " "specified; defaulting " "to %d\n", size); - } else { + } else if (alg != DST_ALG_ECCGOST) fatal("key size not specified (-b option)"); - } } if (!oldstyle && prepub > 0) { @@ -703,6 +705,8 @@ main(int argc, char **argv) { if (size != 0 && !dsa_size_ok(size)) fatal("invalid DSS key size: %d", size); break; + case DST_ALG_ECCGOST: + break; case DST_ALG_HMACMD5: options |= DST_TYPE_KEY; if (size < 1 || size > 512) @@ -767,7 +771,8 @@ main(int argc, char **argv) { if (!(alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_RSASHA1 || alg == DNS_KEYALG_NSEC3RSASHA1 || alg == DNS_KEYALG_RSASHA256 || - alg == DNS_KEYALG_RSASHA512) && rsa_exp != 0) + alg == DNS_KEYALG_RSASHA512 || alg == DST_ALG_ECCGOST) && + rsa_exp != 0) fatal("specified RSA exponent for a non-RSA key"); if (alg != DNS_KEYALG_DH && generator != 0) @@ -839,6 +844,7 @@ main(int argc, char **argv) { case DNS_KEYALG_DSA: case DNS_KEYALG_NSEC3DSA: + case DST_ALG_ECCGOST: show_progress = ISC_TRUE; /* fall through */ diff --git a/bin/dnssec/dnssec-keygen.docbook b/bin/dnssec/dnssec-keygen.docbook index 3efc6df4e5..f0cf7f5f08 100644 --- a/bin/dnssec/dnssec-keygen.docbook +++ b/bin/dnssec/dnssec-keygen.docbook @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + June 30, 2000 @@ -114,7 +114,7 @@ Selects the cryptographic algorithm. For DNSSEC keys, the value of must be one of RSAMD5, RSASHA1, - DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256 or RSASHA512. + DSA, NSEC3RSASHA1, NSEC3DSA, RSASHA256, RSASHA512 or ECCGOST. For TSIG/TKEY, the value must be DH (Diffie Hellman), HMAC-MD5, HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384, or HMAC-SHA512. These values are @@ -184,7 +184,7 @@ Use an NSEC3-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by - default. Note that RSASHA256 and RSASHA512 algorithms + default. Note that RSASHA256, RSASHA512 and ECCGOST algorithms are NSEC3-capable. diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in index 9116a75bac..c4a0f28a8d 100644 --- a/bin/tests/system/conf.sh.in +++ b/bin/tests/system/conf.sh.in @@ -15,7 +15,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: conf.sh.in,v 1.56 2010/12/18 01:56:19 each Exp $ +# $Id: conf.sh.in,v 1.57 2010/12/23 04:07:59 marka Exp $ # # Common configuration data for system tests, to be sourced into @@ -53,7 +53,7 @@ JOURNALPRINT=$TOP/bin/tools/named-journalprint # load on the machine to make it unusable to other users. # v6synth SUBDIRS="acl allow_query addzone autosign cacheclean checkconf checknames - dlv @DLZ_SYSTEM_TEST@ dlzexternal dns64 dnssec forward glue ixfr limits + dlv @DLZ_SYSTEM_TEST@ dlzexternal dns64 dnssec forward glue gost ixfr limits lwresd masterfile masterformat metadata notify nsupdate pending pkcs11 resolver rrsetorder sortlist smartsign staticstub stub tkey tsig tsiggss unknown upforwd views xfer xferquota zonechecks" diff --git a/bin/tests/system/gost/clean.sh b/bin/tests/system/gost/clean.sh new file mode 100644 index 0000000000..ae56d12ede --- /dev/null +++ b/bin/tests/system/gost/clean.sh @@ -0,0 +1,24 @@ +#!/bin/sh +# +# Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: clean.sh,v 1.2 2010/12/23 04:07:59 marka Exp $ + +rm -f */K* */dsset-* */*.signed */trusted.conf +rm -f ns1/root.db +rm -f dig.out* +rm -f random.data +rm -f */named.run +rm -f */named.memstats diff --git a/bin/tests/system/gost/ns1/named.conf b/bin/tests/system/gost/ns1/named.conf new file mode 100644 index 0000000000..9fbce1e030 --- /dev/null +++ b/bin/tests/system/gost/ns1/named.conf @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: named.conf,v 1.2 2010/12/23 04:08:00 marka Exp $ */ + +// NS1 + +controls { /* empty */ }; + +options { + query-source address 10.53.0.1; + notify-source 10.53.0.1; + transfer-source 10.53.0.1; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.1; }; + listen-on-v6 { none; }; + recursion no; + notify yes; + dnssec-enable yes; + dnssec-validation yes; +}; + +zone "." { + type master; + file "root.db.signed"; +}; + +include "trusted.conf"; diff --git a/bin/tests/system/gost/ns1/root.db.in b/bin/tests/system/gost/ns1/root.db.in new file mode 100644 index 0000000000..779d90b0ee --- /dev/null +++ b/bin/tests/system/gost/ns1/root.db.in @@ -0,0 +1,26 @@ +; Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +; $Id: root.db.in,v 1.2 2010/12/23 04:08:00 marka Exp $ + +$TTL 300 +. IN SOA marka.isc.org. a.root.servers.nil. ( + 2010121600 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +. NS a.root-servers.nil. +a.root-servers.nil. A 10.53.0.1 diff --git a/bin/tests/system/gost/ns1/sign.sh b/bin/tests/system/gost/ns1/sign.sh new file mode 100644 index 0000000000..70fc41055c --- /dev/null +++ b/bin/tests/system/gost/ns1/sign.sh @@ -0,0 +1,47 @@ +#!/bin/sh -e +# +# Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: sign.sh,v 1.2 2010/12/23 04:08:00 marka Exp $ + +SYSTEMTESTTOP=../.. +. $SYSTEMTESTTOP/conf.sh + +RANDFILE=../random.data + +zone=. +infile=root.db.in +zonefile=root.db + +key1=`$KEYGEN -q -r $RANDFILE -a ECCGOST -n zone $zone` +key2=`$KEYGEN -q -r $RANDFILE -a ECCGOST -n zone -f KSK $zone` +$DSFROMKEY -a gost $key2.key > dsset-gost + +cat $infile $key1.key $key2.key > $zonefile + +$SIGNER -P -g -r $RANDFILE -o $zone $zonefile > /dev/null + +# Configure the resolving server with a trusted key. + +cat $key1.key | grep -v '^; ' | $PERL -n -e ' +local ($dn, $class, $type, $flags, $proto, $alg, @rest) = split; +local $key = join("", @rest); +print < trusted.conf +cp trusted.conf ../ns2/trusted.conf diff --git a/bin/tests/system/gost/ns2/named.conf b/bin/tests/system/gost/ns2/named.conf new file mode 100644 index 0000000000..99efc0c296 --- /dev/null +++ b/bin/tests/system/gost/ns2/named.conf @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: named.conf,v 1.2 2010/12/23 04:08:00 marka Exp $ */ + +// NS2 + +controls { /* empty */ }; + +options { + query-source address 10.53.0.2; + notify-source 10.53.0.2; + transfer-source 10.53.0.2; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.2; }; + listen-on-v6 { none; }; + recursion yes; + notify yes; + dnssec-enable yes; + dnssec-validation yes; +}; + +zone "." { + type hint; + file "../../common/root.hint"; +}; + +include "trusted.conf"; diff --git a/bin/tests/system/gost/prereq.sh.in b/bin/tests/system/gost/prereq.sh.in new file mode 100644 index 0000000000..2ca7bc9714 --- /dev/null +++ b/bin/tests/system/gost/prereq.sh.in @@ -0,0 +1,24 @@ +#!/bin/sh -e +# +# Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: prereq.sh.in,v 1.2 2010/12/23 04:07:59 marka Exp $ + +OPENSSL_GOST="@OPENSSL_GOST@" +if ! test -n "$OPENSSL_GOST" +then + echo "I:This test requires a openssl version with gost support." >&2 + exit 1 +fi diff --git a/bin/tests/system/gost/setup.sh b/bin/tests/system/gost/setup.sh new file mode 100644 index 0000000000..0d62f5c268 --- /dev/null +++ b/bin/tests/system/gost/setup.sh @@ -0,0 +1,21 @@ +#!/bin/sh -e +# +# Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: setup.sh,v 1.2 2010/12/23 04:08:00 marka Exp $ + +../../../tools/genrandom 400 random.data + +cd ns1 && sh sign.sh diff --git a/bin/tests/system/gost/tests.sh b/bin/tests/system/gost/tests.sh new file mode 100644 index 0000000000..8f1321e00a --- /dev/null +++ b/bin/tests/system/gost/tests.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: tests.sh,v 1.2 2010/12/23 04:08:00 marka Exp $ + +SYSTEMTESTTOP=.. +. $SYSTEMTESTTOP/conf.sh + +status=0 +n=0 + +rm -f dig.out.* + +DIGOPTS="+tcp +noadd +nosea +nostat +nocmd +dnssec -p 5300" + +# Check the example. domain + +echo "I:checking that positive validation works works ($n)" +ret=0 +$DIG $DIGOPTS . @10.53.0.1 soa > dig.out.ns1.test$n || ret=1 +$DIG $DIGOPTS . @10.53.0.2 soa > dig.out.ns2.test$n || ret=1 +$PERL ../digcomp.pl dig.out.ns1.test$n dig.out.ns2.test$n || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:exit status: $status" +exit $status diff --git a/configure.in b/configure.in index 565f413cec..d4dfa54ca0 100644 --- a/configure.in +++ b/configure.in @@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl esyscmd([sed "s/^/# /" COPYRIGHT])dnl AC_DIVERT_POP()dnl -AC_REVISION($Revision: 1.508 $) +AC_REVISION($Revision: 1.509 $) AC_INIT(lib/dns/name.c) AC_PREREQ(2.59) @@ -517,6 +517,7 @@ then fi done fi +OPENSSL_GOST="" case "$use_openssl" in no) AC_MSG_RESULT(no) @@ -672,6 +673,42 @@ esac AC_MSG_RESULT(no) fi AC_CHECK_FUNCS(EVP_sha256 EVP_sha512) + + AC_MSG_CHECKING(for OpenSSL GOST support) + have_gost="" + AC_TRY_RUN([ +#include +#include +int main() { +#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) + ENGINE *e; + + OPENSSL_config(NULL); + + e = ENGINE_by_id("gost"); + if (e == NULL) + return (1); + if (ENGINE_init(e) <= 0) + return (1); + return (0); +#else + return (1); +#endif +} +], + [AC_MSG_RESULT(yes) + have_gost="yes"], + [AC_MSG_RESULT(no) + have_gost="no"]) + case $have_gost in + yes) + OPENSSL_GOST="yes" + AC_DEFINE(HAVE_OPENSSL_GOST, 1, + [Define if your OpenSSL version supports GOST.]) + ;; + *) + ;; + esac CFLAGS="$saved_cflags" LIBS="$saved_libs" OPENSSLLINKOBJS='${OPENSSLLINKOBJS}' @@ -689,6 +726,7 @@ AC_SUBST(USE_OPENSSL) AC_SUBST(DST_OPENSSL_INC) AC_SUBST(OPENSSLLINKOBJS) AC_SUBST(OPENSSLLINKSRCS) +AC_SUBST(OPENSSL_GOST) DNS_CRYPTO_LIBS="$DNS_CRYPTO_LIBS $DNS_OPENSSL_LIBS" # @@ -840,7 +878,12 @@ case "$use_gssapi" in # -L/usr/local/lib to LIBS, which can make the # -lgssapi_krb5 test succeed with shared libraries even # when you are trying to build with KTH in /usr/lib. - LIBS="-L$use_gssapi/lib $TRY_LIBS" + if test "$use_gssapi" = "/usr" + then + LIBS="$TRY_LIBS" + else + LIBS="-L$use_gssapi/lib $TRY_LIBS" + fi AC_MSG_CHECKING(linking as $TRY_LIBS) AC_TRY_LINK( , [gss_acquire_cred();krb5_init_context()], gssapi_linked=yes, gssapi_linked=no) @@ -3289,6 +3332,7 @@ AC_CONFIG_FILES([ bin/tests/sockaddr/Makefile bin/tests/system/Makefile bin/tests/system/conf.sh + bin/tests/system/gost/prereq.sh bin/tests/system/filter-aaaa/Makefile bin/tests/system/lwresd/Makefile bin/tests/system/tkey/Makefile diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in index 5e26cd9bc2..6c9df3c0ee 100644 --- a/lib/dns/Makefile.in +++ b/lib/dns/Makefile.in @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.172 2010/12/08 02:46:16 marka Exp $ +# $Id: Makefile.in,v 1.173 2010/12/23 04:07:58 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -47,7 +47,7 @@ LIBS = @LIBS@ # Alphabetically OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \ - opensslrsa_link.@O@ + opensslgost_link.@O@ opensslrsa_link.@O@ DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \ dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \ @@ -75,8 +75,8 @@ DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \ OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} # Alphabetically -OPENSSLLINKSRCS = openssl_link.c openssldh_link.c \ - openssldsa_link.c opensslrsa_link.c +OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \ + opensslgost_link.c opensslrsa_link.c DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \ dst_api.c dst_lib.c dst_parse.c \ diff --git a/lib/dns/ds.c b/lib/dns/ds.c index e994cc560c..03bc7771d6 100644 --- a/lib/dns/ds.c +++ b/lib/dns/ds.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ds.c,v 1.11 2007/06/19 23:47:16 tbox Exp $ */ +/* $Id: ds.c,v 1.12 2010/12/23 04:07:58 marka Exp $ */ /*! \file */ @@ -38,6 +38,13 @@ #include +#ifdef HAVE_OPENSSL_GOST +#include +#include + +extern const EVP_MD * EVP_gost(void); +#endif + isc_result_t dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, unsigned int digest_type, unsigned char *buffer, @@ -49,6 +56,12 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, isc_region_t r; isc_buffer_t b; dns_rdata_ds_t ds; + isc_sha1_t sha1; + isc_sha256_t sha256; +#ifdef HAVE_OPENSSL_GOST + EVP_MD_CTX ctx; + const EVP_MD *md; +#endif REQUIRE(key != NULL); REQUIRE(key->type == dns_rdatatype_dnskey); @@ -63,8 +76,8 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, memset(buffer, 0, DNS_DS_BUFFERSIZE); isc_buffer_init(&b, buffer, DNS_DS_BUFFERSIZE); - if (digest_type == DNS_DSDIGEST_SHA1) { - isc_sha1_t sha1; + switch (digest_type) { + case DNS_DSDIGEST_SHA1: isc_sha1_init(&sha1); dns_name_toregion(name, &r); isc_sha1_update(&sha1, r.base, r.length); @@ -72,8 +85,33 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, INSIST(r.length >= 4); isc_sha1_update(&sha1, r.base, r.length); isc_sha1_final(&sha1, digest); - } else { - isc_sha256_t sha256; + break; +#ifdef HAVE_OPENSSL_GOST +#define CHECK(x) \ + if ((x) != 1) { \ + EVP_MD_CTX_cleanup(&ctx); \ + return (DST_R_OPENSSLFAILURE); \ + } + + case DNS_DSDIGEST_GOST: + md = EVP_gost(); + if (md == NULL) + return (DST_R_OPENSSLFAILURE); + EVP_MD_CTX_init(&ctx); + CHECK(EVP_DigestInit(&ctx, md)); + dns_name_toregion(name, &r); + CHECK(EVP_DigestUpdate(&ctx, + (const void *) r.base, + (size_t) r.length)); + dns_rdata_toregion(key, &r); + INSIST(r.length >= 4); + CHECK(EVP_DigestUpdate(&ctx, + (const void *) r.base, + (size_t) r.length)); + CHECK(EVP_DigestFinal(&ctx, digest, NULL)); + break; +#endif + default: isc_sha256_init(&sha256); dns_name_toregion(name, &r); isc_sha256_update(&sha256, r.base, r.length); @@ -81,6 +119,7 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, INSIST(r.length >= 4); isc_sha256_update(&sha256, r.base, r.length); isc_sha256_final(digest, &sha256); + break; } ds.mctx = NULL; @@ -89,8 +128,19 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, ds.algorithm = r.base[3]; ds.key_tag = dst_region_computeid(&r, ds.algorithm); ds.digest_type = digest_type; - ds.length = (digest_type == DNS_DSDIGEST_SHA1) ? - ISC_SHA1_DIGESTLENGTH : ISC_SHA256_DIGESTLENGTH; + switch (digest_type) { + case DNS_DSDIGEST_SHA1: + ds.length = ISC_SHA1_DIGESTLENGTH; + break; +#ifdef HAVE_OPENSSL_GOST + case DNS_DSDIGEST_GOST: + ds.length = ISC_GOST_DIGESTLENGTH; + break; +#endif + default: + ds.length = ISC_SHA256_DIGESTLENGTH; + break; + } ds.digest = digest; return (dns_rdata_fromstruct(rdata, key->rdclass, dns_rdatatype_ds, @@ -99,6 +149,12 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key, isc_boolean_t dns_ds_digest_supported(unsigned int digest_type) { +#ifdef HAVE_OPENSSL_GOST + return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 || + digest_type == DNS_DSDIGEST_SHA256 || + digest_type == DNS_DSDIGEST_GOST)); +#else return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 || digest_type == DNS_DSDIGEST_SHA256)); +#endif } diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index 231e30965d..b8cf968dd5 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -31,7 +31,7 @@ /* * Principal Author: Brian Wellington - * $Id: dst_api.c,v 1.54 2010/12/18 01:56:22 each Exp $ + * $Id: dst_api.c,v 1.55 2010/12/23 04:07:58 marka Exp $ */ /*! \file */ @@ -223,6 +223,9 @@ dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx, RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_NSEC3DSA])); #endif RETERR(dst__openssldh_init(&dst_t_func[DST_ALG_DH])); +#ifdef HAVE_OPENSSL_GOST + RETERR(dst__opensslgost_init(&dst_t_func[DST_ALG_ECCGOST])); +#endif #endif /* OPENSSL */ #ifdef GSSAPI RETERR(dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI])); @@ -1113,6 +1116,9 @@ dst_key_sigsize(const dst_key_t *key, unsigned int *n) { case DST_ALG_NSEC3DSA: *n = DNS_SIG_DSASIGSIZE; break; + case DST_ALG_ECCGOST: + *n = DNS_SIG_GOSTSIGSIZE; + break; case DST_ALG_HMACMD5: *n = 16; break; @@ -1375,6 +1381,7 @@ issymmetric(const dst_key_t *key) { case DST_ALG_DSA: case DST_ALG_NSEC3DSA: case DST_ALG_DH: + case DST_ALG_ECCGOST: return (ISC_FALSE); case DST_ALG_HMACMD5: case DST_ALG_GSSAPI: @@ -1647,7 +1654,8 @@ algorithm_status(unsigned int alg) { alg == DST_ALG_DSA || alg == DST_ALG_DH || alg == DST_ALG_HMACMD5 || alg == DST_ALG_NSEC3DSA || alg == DST_ALG_NSEC3RSASHA1 || - alg == DST_ALG_RSASHA256 || alg == DST_ALG_RSASHA512) + alg == DST_ALG_RSASHA256 || alg == DST_ALG_RSASHA512 || + alg == DST_ALG_ECCGOST) return (DST_R_NOCRYPTO); #endif return (DST_R_UNSUPPORTEDALG); diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h index 5ba2094510..bdd96f5027 100644 --- a/lib/dns/dst_internal.h +++ b/lib/dns/dst_internal.h @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst_internal.h,v 1.26 2010/12/18 01:56:22 each Exp $ */ +/* $Id: dst_internal.h,v 1.27 2010/12/23 04:07:58 marka Exp $ */ #ifndef DST_DST_INTERNAL_H #define DST_DST_INTERNAL_H 1 @@ -209,6 +209,9 @@ isc_result_t dst__opensslrsa_init(struct dst_func **funcp, isc_result_t dst__openssldsa_init(struct dst_func **funcp); isc_result_t dst__openssldh_init(struct dst_func **funcp); isc_result_t dst__gssapi_init(struct dst_func **funcp); +#ifdef HAVE_OPENSSL_GOST +isc_result_t dst__opensslgost_init(struct dst_func **funcp); +#endif /*% * Destructors diff --git a/lib/dns/dst_parse.c b/lib/dns/dst_parse.c index fd2f1d115c..bba0101a32 100644 --- a/lib/dns/dst_parse.c +++ b/lib/dns/dst_parse.c @@ -31,7 +31,7 @@ /*% * Principal Author: Brian Wellington - * $Id: dst_parse.c,v 1.26 2010/01/11 10:49:14 fdupont Exp $ + * $Id: dst_parse.c,v 1.27 2010/12/23 04:07:58 marka Exp $ */ #include @@ -104,6 +104,8 @@ static struct parse_map map[] = { {TAG_DSA_PRIVATE, "Private_value(x):"}, {TAG_DSA_PUBLIC, "Public_value(y):"}, + {TAG_GOST_PRIVASN1, "GostAsn1:"}, + {TAG_HMACMD5_KEY, "Key:"}, {TAG_HMACMD5_BITS, "Bits:"}, @@ -239,6 +241,15 @@ check_dsa(const dst_private_t *priv) { return (0); } +static int +check_gost(const dst_private_t *priv) { + if (priv->nelements != GOST_NTAGS) + return (-1); + if (priv->elements[0].tag != TAG(DST_ALG_ECCGOST, 0)) + return (-1); + return (0); +} + static int check_hmac_md5(const dst_private_t *priv, isc_boolean_t old) { int i, j; @@ -296,6 +307,8 @@ check_data(const dst_private_t *priv, const unsigned int alg, return (check_dh(priv)); case DST_ALG_DSA: return (check_dsa(priv)); + case DST_ALG_ECCGOST: + return (check_gost(priv)); case DST_ALG_HMACMD5: return (check_hmac_md5(priv, old)); case DST_ALG_HMACSHA1: @@ -587,6 +600,9 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, case DST_ALG_RSASHA512: fprintf(fp, "(RSASHA512)\n"); break; + case DST_ALG_ECCGOST: + fprintf(fp, "(ECC-GOST)\n"); + break; case DST_ALG_HMACMD5: fprintf(fp, "(HMAC_MD5)\n"); break; diff --git a/lib/dns/dst_parse.h b/lib/dns/dst_parse.h index ceb8b188bd..3878fd46df 100644 --- a/lib/dns/dst_parse.h +++ b/lib/dns/dst_parse.h @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst_parse.h,v 1.15 2009/10/26 21:18:24 each Exp $ */ +/* $Id: dst_parse.h,v 1.16 2010/12/23 04:07:58 marka Exp $ */ /*! \file */ #ifndef DST_DST_PARSE_H @@ -78,6 +78,9 @@ #define TAG_DSA_PRIVATE ((DST_ALG_DSA << TAG_SHIFT) + 3) #define TAG_DSA_PUBLIC ((DST_ALG_DSA << TAG_SHIFT) + 4) +#define GOST_NTAGS 1 +#define TAG_GOST_PRIVASN1 ((DST_ALG_ECCGOST << TAG_SHIFT) + 0) + #define OLD_HMACMD5_NTAGS 1 #define HMACMD5_NTAGS 2 #define TAG_HMACMD5_KEY ((DST_ALG_HMACMD5 << TAG_SHIFT) + 0) diff --git a/lib/dns/include/dns/ds.h b/lib/dns/include/dns/ds.h index b59fb83902..4f579ef000 100644 --- a/lib/dns/include/dns/ds.h +++ b/lib/dns/include/dns/ds.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ds.h,v 1.10 2007/06/19 23:47:16 tbox Exp $ */ +/* $Id: ds.h,v 1.11 2010/12/23 04:07:58 marka Exp $ */ #ifndef DNS_DS_H #define DNS_DS_H 1 @@ -26,6 +26,11 @@ #define DNS_DSDIGEST_SHA1 (1) #define DNS_DSDIGEST_SHA256 (2) +#define DNS_DSDIGEST_GOST (3) + +/* should not be here... */ + +#define ISC_GOST_DIGESTLENGTH 32U /* * Assuming SHA-256 digest type. diff --git a/lib/dns/include/dns/keyvalues.h b/lib/dns/include/dns/keyvalues.h index cc36d286e4..711e755792 100644 --- a/lib/dns/include/dns/keyvalues.h +++ b/lib/dns/include/dns/keyvalues.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: keyvalues.h,v 1.27 2009/10/22 02:21:31 each Exp $ */ +/* $Id: keyvalues.h,v 1.28 2010/12/23 04:07:58 marka Exp $ */ #ifndef DNS_KEYVALUES_H #define DNS_KEYVALUES_H 1 @@ -70,6 +70,7 @@ #define DNS_KEYALG_NSEC3RSASHA1 7 #define DNS_KEYALG_RSASHA256 8 #define DNS_KEYALG_RSASHA512 10 +#define DNS_KEYALG_ECCGOST 12 #define DNS_KEYALG_INDIRECT 252 #define DNS_KEYALG_PRIVATEDNS 253 #define DNS_KEYALG_PRIVATEOID 254 /*%< Key begins with OID giving alg */ @@ -98,4 +99,6 @@ #define DNS_SIG_DSAMINBYTES 213 #define DNS_SIG_DSAMAXBYTES 405 +#define DNS_SIG_GOSTSIGSIZE 64 + #endif /* DNS_KEYVALUES_H */ diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h index 8ee9da686d..5bda746be2 100644 --- a/lib/dns/include/dst/dst.h +++ b/lib/dns/include/dst/dst.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dst.h,v 1.28 2010/12/18 01:56:22 each Exp $ */ +/* $Id: dst.h,v 1.29 2010/12/23 04:07:59 marka Exp $ */ #ifndef DST_DST_H #define DST_DST_H 1 @@ -58,6 +58,7 @@ typedef struct dst_context dst_context_t; #define DST_ALG_NSEC3RSASHA1 7 #define DST_ALG_RSASHA256 8 #define DST_ALG_RSASHA512 10 +#define DST_ALG_ECCGOST 12 #define DST_ALG_HMACMD5 157 #define DST_ALG_GSSAPI 160 #define DST_ALG_HMACSHA1 161 /* XXXMPA */ diff --git a/lib/dns/opensslgost_link.c b/lib/dns/opensslgost_link.c new file mode 100644 index 0000000000..dde005acd9 --- /dev/null +++ b/lib/dns/opensslgost_link.c @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: opensslgost_link.c,v 1.2 2010/12/23 04:07:58 marka Exp $ */ + +#include + +#ifdef HAVE_OPENSSL_GOST + +#include +#include +#include +#include + +#include + +#include "dst_internal.h" +#include "dst_openssl.h" +#include "dst_parse.h" + +#include +#include +#include +#include + +static ENGINE *e = NULL; +static const EVP_MD *opensslgost_digest; +extern const EVP_MD *EVP_gost(void); + +const EVP_MD *EVP_gost(void) { + return (opensslgost_digest); +} + +#define DST_RET(a) {ret = a; goto err;} + +static isc_result_t opensslgost_todns(const dst_key_t *key, + isc_buffer_t *data); + +static isc_result_t +opensslgost_createctx(dst_key_t *key, dst_context_t *dctx) { + EVP_MD_CTX *evp_md_ctx; + const EVP_MD *md = EVP_gost(); + + UNUSED(key); + + if (md == NULL) + return (DST_R_OPENSSLFAILURE); + + evp_md_ctx = EVP_MD_CTX_create(); + if (evp_md_ctx == NULL) + return (ISC_R_NOMEMORY); + + if (!EVP_DigestInit_ex(evp_md_ctx, md, NULL)) { + EVP_MD_CTX_destroy(evp_md_ctx); + return (ISC_R_FAILURE); + } + dctx->ctxdata.evp_md_ctx = evp_md_ctx; + + return (ISC_R_SUCCESS); +} + +static void +opensslgost_destroyctx(dst_context_t *dctx) { + EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; + + if (evp_md_ctx != NULL) { + EVP_MD_CTX_destroy(evp_md_ctx); + dctx->ctxdata.evp_md_ctx = NULL; + } +} + +static isc_result_t +opensslgost_adddata(dst_context_t *dctx, const isc_region_t *data) { + EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; + + if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) + return (ISC_R_FAILURE); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +opensslgost_sign(dst_context_t *dctx, isc_buffer_t *sig) { + dst_key_t *key = dctx->key; + isc_region_t r; + unsigned int siglen = 0; + EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; + EVP_PKEY *pkey = key->keydata.pkey; + + isc_buffer_availableregion(sig, &r); + + if (r.length < (unsigned int) EVP_PKEY_size(pkey)) + return (ISC_R_NOSPACE); + + if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) + return (ISC_R_FAILURE); + + isc_buffer_add(sig, siglen); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +opensslgost_verify(dst_context_t *dctx, const isc_region_t *sig) { + dst_key_t *key = dctx->key; + int status = 0; + EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; + EVP_PKEY *pkey = key->keydata.pkey; + + status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey); + if (status != 1) + return (dst__openssl_toresult(DST_R_VERIFYFAILURE)); + + return (ISC_R_SUCCESS); +} + +static isc_boolean_t +opensslgost_compare(const dst_key_t *key1, const dst_key_t *key2) { + EVP_PKEY *pkey1, *pkey2; + + pkey1 = key1->keydata.pkey; + pkey2 = key2->keydata.pkey; + + if (pkey1 == NULL && pkey2 == NULL) + return (ISC_TRUE); + else if (pkey1 == NULL || pkey2 == NULL) + return (ISC_FALSE); + + if (EVP_PKEY_cmp(pkey1, pkey2) != 1) + return (ISC_FALSE); + return (ISC_TRUE); +} + +static int +progress_cb(EVP_PKEY_CTX *ctx) +{ + union { + void *dptr; + void (*fptr)(int); + } u; + int p; + + u.dptr = EVP_PKEY_CTX_get_app_data(ctx); + p = EVP_PKEY_CTX_get_keygen_info(ctx, 0); + if (u.fptr != NULL) + u.fptr(p); + return (1); +} + +static isc_result_t +opensslgost_generate(dst_key_t *key, int unused, void (*callback)(int)) { + EVP_PKEY_CTX *ctx; + union { + void *dptr; + void (*fptr)(int); + } u; + EVP_PKEY *pkey = NULL; + + UNUSED(unused); + ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL); + if (ctx == NULL) + goto err; + if (callback != NULL) { + u.fptr = callback; + EVP_PKEY_CTX_set_app_data(ctx, u.dptr); + EVP_PKEY_CTX_set_cb(ctx, &progress_cb); + } + if (EVP_PKEY_keygen_init(ctx) <= 0) + goto err; + if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0) + goto err; + if (EVP_PKEY_keygen(ctx, &pkey) <= 0) + goto err; + key->keydata.pkey = pkey; + EVP_PKEY_CTX_free(ctx); + return (ISC_R_SUCCESS); + +err: + if (pkey != NULL) + EVP_PKEY_free(pkey); + if (ctx != NULL) + EVP_PKEY_CTX_free(ctx); + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); +} + +static isc_boolean_t +opensslgost_isprivate(const dst_key_t *key) { + EVP_PKEY *pkey = key->keydata.pkey; + EC_KEY *ec; + + INSIST(pkey != NULL); + + ec = EVP_PKEY_get0(pkey); + return (ISC_TF(ec != NULL && EC_KEY_get0_private_key(ec) != NULL)); +} + +static void +opensslgost_destroy(dst_key_t *key) { + EVP_PKEY *pkey = key->keydata.pkey; + + EVP_PKEY_free(pkey); + key->keydata.pkey = NULL; +} + +unsigned char gost_prefix[37] = { + 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, + 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, + 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01, + 0x03, 0x43, 0x00, 0x04, 0x40 +}; + +static isc_result_t +opensslgost_todns(const dst_key_t *key, isc_buffer_t *data) { + EVP_PKEY *pkey; + isc_region_t r; + unsigned char der[37 + 64], *p; + int len; + + REQUIRE(key->keydata.pkey != NULL); + + pkey = key->keydata.pkey; + + isc_buffer_availableregion(data, &r); + if (r.length < 64) + return (ISC_R_NOSPACE); + + p = der; + len = i2d_PUBKEY(pkey, &p); + INSIST(len == sizeof(der)); + INSIST(memcmp(gost_prefix, der, 37) == 0); + memcpy(r.base, der + 37, 64); + isc_buffer_add(data, 64); + + return (ISC_R_SUCCESS); +} + +static isc_result_t +opensslgost_fromdns(dst_key_t *key, isc_buffer_t *data) { + isc_region_t r; + EVP_PKEY *pkey = NULL; + unsigned char der[37 + 64]; + const unsigned char *p; + + isc_buffer_remainingregion(data, &r); + if (r.length == 0) + return (ISC_R_SUCCESS); + + if (r.length != 64) + return (DST_R_INVALIDPUBLICKEY); + memcpy(der, gost_prefix, 37); + memcpy(der + 37, r.base, 64); + isc_buffer_forward(data, 64); + + p = der; + if (d2i_PUBKEY(&pkey, &p, (long) sizeof(der)) == NULL) + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + key->keydata.pkey = pkey; + + return (ISC_R_SUCCESS); +} + +static isc_result_t +opensslgost_tofile(const dst_key_t *key, const char *directory) { + EVP_PKEY *pkey; + dst_private_t priv; + isc_result_t result; + unsigned char *der, *p; + int len; + + if (key->keydata.pkey == NULL) + return (DST_R_NULLKEY); + + pkey = key->keydata.pkey; + + len = i2d_PrivateKey(pkey, NULL); + der = isc_mem_get(key->mctx, (size_t) len); + if (der == NULL) + return (ISC_R_NOMEMORY); + + p = der; + if (i2d_PrivateKey(pkey, &p) != len) { + result = dst__openssl_toresult(DST_R_OPENSSLFAILURE); + goto fail; + } + + priv.elements[0].tag = TAG_GOST_PRIVASN1; + priv.elements[0].length = len; + priv.elements[0].data = der; + priv.nelements = GOST_NTAGS; + + result = dst__privstruct_writefile(key, &priv, directory); + fail: + if (der != NULL) + isc_mem_put(key->mctx, der, (size_t) len); + return (result); +} + +static isc_result_t +opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { + dst_private_t priv; + isc_result_t ret; + isc_mem_t *mctx = key->mctx; + EVP_PKEY *pkey = NULL; + const unsigned char *p; + + UNUSED(pub); + + /* read private key file */ + ret = dst__privstruct_parse(key, DST_ALG_ECCGOST, lexer, mctx, &priv); + if (ret != ISC_R_SUCCESS) + return (ret); + + INSIST(priv.elements[0].tag == TAG_GOST_PRIVASN1); + p = priv.elements[0].data; + if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p, + (long) priv.elements[0].length) == NULL) + DST_RET(DST_R_INVALIDPRIVATEKEY); + key->keydata.pkey = pkey; + key->key_size = EVP_PKEY_bits(pkey); + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (ISC_R_SUCCESS); + + err: + if (pkey != NULL) + EVP_PKEY_free(pkey); + opensslgost_destroy(key); + dst__privstruct_free(&priv, mctx); + memset(&priv, 0, sizeof(priv)); + return (ret); +} + +static void +opensslgost_cleanup(void) { + if (e != NULL) { + ENGINE_finish(e); + ENGINE_free(e); + e = NULL; + } +} + +static dst_func_t opensslgost_functions = { + opensslgost_createctx, + opensslgost_destroyctx, + opensslgost_adddata, + opensslgost_sign, + opensslgost_verify, + NULL, /*%< computesecret */ + opensslgost_compare, + NULL, /*%< paramcompare */ + opensslgost_generate, + opensslgost_isprivate, + opensslgost_destroy, + opensslgost_todns, + opensslgost_fromdns, + opensslgost_tofile, + opensslgost_parse, + opensslgost_cleanup, + NULL, /*%< fromlabel */ +}; + +isc_result_t +dst__opensslgost_init(dst_func_t **funcp) { + REQUIRE(funcp != NULL); + + /* check if the gost engine works properly */ + e = ENGINE_by_id("gost"); + if (e == NULL) + return (DST_R_OPENSSLFAILURE); + if (ENGINE_init(e) <= 0) { + ENGINE_free(e); + e = NULL; + return (DST_R_OPENSSLFAILURE); + } + /* better than to rely on digest_gost symbol */ + opensslgost_digest = ENGINE_get_digest(e, NID_id_GostR3411_94); + /* from openssl.cnf */ + if ((opensslgost_digest == NULL) || + (ENGINE_register_pkey_asn1_meths(e) <= 0) || + (ENGINE_ctrl_cmd_string(e, + "CRYPT_PARAMS", + "id-Gost28147-89-CryptoPro-A-ParamSet", + 0) <= 0)) { + ENGINE_finish(e); + ENGINE_free(e); + e = NULL; + return (DST_R_OPENSSLFAILURE); + } + + if (*funcp == NULL) + *funcp = &opensslgost_functions; + return (ISC_R_SUCCESS); +} + +#else /* HAVE_OPENSSL_GOST */ + +#include + +EMPTY_TRANSLATION_UNIT + +#endif /* HAVE_OPENSSL_GOST */ +/*! \file */ diff --git a/lib/dns/rcode.c b/lib/dns/rcode.c index 46b6c01c0e..fd9d2fe0d3 100644 --- a/lib/dns/rcode.c +++ b/lib/dns/rcode.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rcode.c,v 1.15 2010/11/17 23:47:08 tbox Exp $ */ +/* $Id: rcode.c,v 1.16 2010/12/23 04:07:58 marka Exp $ */ #include #include @@ -107,6 +107,7 @@ { DNS_KEYALG_NSEC3RSASHA1, "NSEC3RSASHA1", 0 }, \ { DNS_KEYALG_RSASHA256, "RSASHA256", 0 }, \ { DNS_KEYALG_RSASHA512, "RSASHA512", 0 }, \ + { DNS_KEYALG_ECCGOST, "ECCGOST", 0 }, \ { DNS_KEYALG_INDIRECT, "INDIRECT", 0 }, \ { DNS_KEYALG_PRIVATEDNS, "PRIVATEDNS", 0 }, \ { DNS_KEYALG_PRIVATEOID, "PRIVATEOID", 0 }, \ diff --git a/lib/dns/rdata/generic/dlv_32769.c b/lib/dns/rdata/generic/dlv_32769.c index d222922078..963cedb951 100644 --- a/lib/dns/rdata/generic/dlv_32769.c +++ b/lib/dns/rdata/generic/dlv_32769.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dlv_32769.c,v 1.8 2009/12/04 22:06:37 tbox Exp $ */ +/* $Id: dlv_32769.c,v 1.9 2010/12/23 04:07:59 marka Exp $ */ /* draft-ietf-dnsext-delegation-signer-05.txt */ @@ -74,12 +74,20 @@ fromtext_dlv(ARGS_FROMTEXT) { /* * Digest. */ - if (c == DNS_DSDIGEST_SHA1) + switch (c) { + case DNS_DSDIGEST_SHA1: length = ISC_SHA1_DIGESTLENGTH; - else if (c == DNS_DSDIGEST_SHA256) + break; + case DNS_DSDIGEST_SHA256: length = ISC_SHA256_DIGESTLENGTH; - else + break; + case DNS_DSDIGEST_GOST: + length = ISC_GOST_DIGESTLENGTH; + break; + default: length = -1; + break; + } return (isc_hex_tobuffer(lexer, target, -1)); } @@ -152,7 +160,9 @@ fromwire_dlv(ARGS_FROMWIRE) { (sr.base[3] == DNS_DSDIGEST_SHA1 && sr.length < 4 + ISC_SHA1_DIGESTLENGTH) || (sr.base[3] == DNS_DSDIGEST_SHA256 && - sr.length < 4 + ISC_SHA256_DIGESTLENGTH)) + sr.length < 4 + ISC_SHA256_DIGESTLENGTH) || + (sr.base[3] == DNS_DSDIGEST_GOST && + sr.length < 4 + ISC_GOST_DIGESTLENGTH)) return (ISC_R_UNEXPECTEDEND); /* @@ -164,6 +174,8 @@ fromwire_dlv(ARGS_FROMWIRE) { sr.length = 4 + ISC_SHA1_DIGESTLENGTH; else if (sr.base[3] == DNS_DSDIGEST_SHA256) sr.length = 4 + ISC_SHA256_DIGESTLENGTH; + else if (sr.base[3] == DNS_DSDIGEST_GOST) + sr.length = 4 + ISC_GOST_DIGESTLENGTH; isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); @@ -213,6 +225,9 @@ fromstruct_dlv(ARGS_FROMSTRUCT) { case DNS_DSDIGEST_SHA256: REQUIRE(dlv->length == ISC_SHA256_DIGESTLENGTH); break; + case DNS_DSDIGEST_GOST: + REQUIRE(dlv->length == ISC_GOST_DIGESTLENGTH); + break; } UNUSED(type); diff --git a/lib/dns/rdata/generic/ds_43.c b/lib/dns/rdata/generic/ds_43.c index c592093d1c..c903db0f6c 100644 --- a/lib/dns/rdata/generic/ds_43.c +++ b/lib/dns/rdata/generic/ds_43.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ds_43.c,v 1.14 2009/12/04 22:06:37 tbox Exp $ */ +/* $Id: ds_43.c,v 1.15 2010/12/23 04:07:59 marka Exp $ */ /* draft-ietf-dnsext-delegation-signer-05.txt */ @@ -74,12 +74,20 @@ fromtext_ds(ARGS_FROMTEXT) { /* * Digest. */ - if (c == DNS_DSDIGEST_SHA1) + switch (c) { + case DNS_DSDIGEST_SHA1: length = ISC_SHA1_DIGESTLENGTH; - else if (c == DNS_DSDIGEST_SHA256) + break; + case DNS_DSDIGEST_SHA256: length = ISC_SHA256_DIGESTLENGTH; - else + break; + case DNS_DSDIGEST_GOST: + length = ISC_GOST_DIGESTLENGTH; + break; + default: length = -1; + break; + } return (isc_hex_tobuffer(lexer, target, length)); } @@ -152,7 +160,9 @@ fromwire_ds(ARGS_FROMWIRE) { (sr.base[3] == DNS_DSDIGEST_SHA1 && sr.length < 4 + ISC_SHA1_DIGESTLENGTH) || (sr.base[3] == DNS_DSDIGEST_SHA256 && - sr.length < 4 + ISC_SHA256_DIGESTLENGTH)) + sr.length < 4 + ISC_SHA256_DIGESTLENGTH) || + (sr.base[3] == DNS_DSDIGEST_GOST && + sr.length < 4 + ISC_GOST_DIGESTLENGTH)) return (ISC_R_UNEXPECTEDEND); /* @@ -164,6 +174,8 @@ fromwire_ds(ARGS_FROMWIRE) { sr.length = 4 + ISC_SHA1_DIGESTLENGTH; else if (sr.base[3] == DNS_DSDIGEST_SHA256) sr.length = 4 + ISC_SHA256_DIGESTLENGTH; + else if (sr.base[3] == DNS_DSDIGEST_GOST) + sr.length = 4 + ISC_GOST_DIGESTLENGTH; isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); @@ -213,6 +225,9 @@ fromstruct_ds(ARGS_FROMSTRUCT) { case DNS_DSDIGEST_SHA256: REQUIRE(ds->length == ISC_SHA256_DIGESTLENGTH); break; + case DNS_DSDIGEST_GOST: + REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH); + break; } UNUSED(type); diff --git a/lib/dns/validator.c b/lib/dns/validator.c index 15cdcf9e9a..876e73dc18 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.c,v 1.196 2010/11/16 01:14:51 marka Exp $ */ +/* $Id: validator.c,v 1.197 2010/12/23 04:07:58 marka Exp $ */ #include @@ -253,9 +253,17 @@ dlv_algorithm_supported(dns_validator_t *val) { dlv.algorithm)) continue; +#ifdef HAVE_OPENSSL_GOST + if (dlv.digest_type != DNS_DSDIGEST_SHA256 && + dlv.digest_type != DNS_DSDIGEST_SHA1 && + dlv.digest_type != DNS_DSDIGEST_GOST) + continue; +#else if (dlv.digest_type != DNS_DSDIGEST_SHA256 && dlv.digest_type != DNS_DSDIGEST_SHA1) continue; +#endif + return (ISC_TRUE); } @@ -2137,7 +2145,7 @@ dlv_validatezonekey(dns_validator_t *val) { dns_rdataset_t trdataset; isc_boolean_t supported_algorithm; isc_result_t result; - isc_uint8_t digest_type; + char digest_types[256]; validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey"); @@ -2154,7 +2162,7 @@ dlv_validatezonekey(dns_validator_t *val) { * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256 * is present. */ - digest_type = DNS_DSDIGEST_SHA1; + memset(digest_types, 1, sizeof(digest_types)); for (result = dns_rdataset_first(&val->dlv); result == ISC_R_SUCCESS; result = dns_rdataset_next(&val->dlv)) { @@ -2170,7 +2178,7 @@ dlv_validatezonekey(dns_validator_t *val) { if (dlv.digest_type == DNS_DSDIGEST_SHA256 && dlv.length == ISC_SHA256_DIGESTLENGTH) { - digest_type = DNS_DSDIGEST_SHA256; + digest_types[DNS_DSDIGEST_SHA1] = 0; break; } } @@ -2188,7 +2196,7 @@ dlv_validatezonekey(dns_validator_t *val) { dlv.digest_type)) continue; - if (dlv.digest_type != digest_type) + if (digest_types[dlv.digest_type] == 0) continue; if (!dns_resolver_algorithm_supported(val->view->resolver, @@ -2271,7 +2279,7 @@ validatezonekey(dns_validator_t *val) { dst_key_t *dstkey; isc_boolean_t supported_algorithm; isc_boolean_t atsep = ISC_FALSE; - isc_uint8_t digest_type; + char digest_types[256]; /* * Caller must be holding the validator lock. @@ -2502,7 +2510,7 @@ validatezonekey(dns_validator_t *val) { * need to ignore DNS_DSDIGEST_SHA1 if a DNS_DSDIGEST_SHA256 * is present. */ - digest_type = DNS_DSDIGEST_SHA1; + memset(digest_types, 1, sizeof(digest_types)); for (result = dns_rdataset_first(val->dsset); result == ISC_R_SUCCESS; result = dns_rdataset_next(val->dsset)) { @@ -2518,7 +2526,7 @@ validatezonekey(dns_validator_t *val) { if (ds.digest_type == DNS_DSDIGEST_SHA256 && ds.length == ISC_SHA256_DIGESTLENGTH) { - digest_type = DNS_DSDIGEST_SHA256; + digest_types[DNS_DSDIGEST_SHA1] = 0; break; } } @@ -2536,7 +2544,7 @@ validatezonekey(dns_validator_t *val) { ds.digest_type)) continue; - if (ds.digest_type != digest_type) + if (digest_types[ds.digest_type] == 0) continue; if (!dns_resolver_algorithm_supported(val->view->resolver, diff --git a/lib/export/dns/Makefile.in b/lib/export/dns/Makefile.in index c35f850737..4ce2803810 100644 --- a/lib/export/dns/Makefile.in +++ b/lib/export/dns/Makefile.in @@ -12,7 +12,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.7 2010/06/09 23:50:58 tbox Exp $ +# $Id: Makefile.in,v 1.8 2010/12/23 04:07:59 marka Exp $ top_srcdir = @top_srcdir@ srcdir = @top_srcdir@/lib/dns @@ -44,7 +44,7 @@ LIBS = @LIBS@ # Alphabetically OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \ - opensslrsa_link.@O@ + opensslgost_link.@O@ opensslrsa_link.@O@ DSTOBJS = @OPENSSLLINKOBJS@ \ dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \ @@ -71,8 +71,8 @@ OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} ${PORTDNSOBJS} # Alphabetically -OPENSSLLINKSRCS = openssl_link.c openssldh_link.c \ - openssldsa_link.c opensslrsa_link.c +OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \ + opensslgost_link.c opensslrsa_link.c DSTSRCS = @OPENSSLLINKSRCS@ \ dst_api.c dst_lib.c dst_parse.c \