23 Commits

Author SHA1 Message Date
ce1189703f Merge pull request #12 from dblacka/davidb/add-ttl-to-keygen
Fixes #11: add TTL to  generated DNSKEYs
2022-06-11 21:23:42 -04:00
bfb5ff45ee Fixes #11: add TTL to generated DNSKEYs
Also, update the gradle wrapper
2022-06-11 21:20:57 -04:00
David Blacka
9fd6c95889 Update dnsjava to 2.1.9; normalize shell wrappers 2019-07-23 13:06:09 +00:00
David Blacka
9004a33d51 Exit with non-zero with exception. Fix dnsjava lib.
It is unclear how we got the version of dnsjava that was checked in.
The same version build from the jdnssec-dnsjava repo was different.
This fixes the "missing CAA" support issue.
2019-02-26 14:26:18 +00:00
David Blacka
0aca329f85 Remove verisignlabs.com website for now
The verisignlabs.com website is non-functional.  Everything is actually here on github.com, though.
2019-01-30 11:37:34 -05:00
David Blacka
507dad3580 Update changelog with release 2018-11-16 15:54:09 +00:00
David Blacka
7d27694d9a Some DNSKeyAlgorithm class cleanup 2018-11-16 13:57:16 +00:00
David Blacka
62b5b0ad23 Updates for gradle; changelog 2018-07-23 19:17:23 +00:00
David Blacka
c37f436e72 Merge branch 'alg-15-support' of https://github.com/pallaviaras/jdnssec-tools into pallaviaras-alg-15-support 2018-07-15 16:57:59 +00:00
David Blacka
781e775b3b Use the actual private key for ed25519 2018-07-15 16:56:15 +00:00
Pallavi
d0e85431c5 Added support for gradle and restructured the source code directory from src to src/main/java directory 2018-07-15 10:59:40 -04:00
David Blacka
55a139db82 Allow for epoch start/expire times; add verboseSigning to jdnssec-signrrset 2018-07-15 14:57:41 +00:00
David Blacka
b291bb430b Use correct encoding for the alg 15 DNSKEYRecord 2018-07-15 12:17:12 +00:00
David Blacka
a9353b3af3 Now able to generated alg 15 keypairs
They _look_ correct, but may not be.
2018-07-15 00:54:10 +00:00
David Blacka
7706b73d8c Start of alg 15/16 support 2018-07-14 22:06:49 +00:00
252c44a155 Merge pull request #6 from chkal/jdk7
Set javac options for source and target to JDK7
2018-03-10 14:26:27 -05:00
Christian Kaltepoth
a7743fa18c Set javac options for source and target to JDK7 2018-02-28 08:47:40 +01:00
4853426d6c Merge pull request #5 from PowerDNS/failure-exit
exit(1) if the zone had errors
2017-06-23 09:55:52 -04:00
de2216f259 Merge pull request #4 from PowerDNS/ecdsa-pad
fix leading zero padding in ECDSA sig conversion
2017-06-23 09:55:28 -04:00
Peter van Dijk
b19bc5ffa3 exit(1) if the zone had errors 2017-06-22 14:34:14 +02:00
Kees Monshouwer
517975ef93 update ChangeLog 2017-06-22 14:32:20 +02:00
Kees Monshouwer
ca2a932485 fix multiple leading zeros padding in ECDSA sig conversion 2017-06-22 14:32:14 +02:00
Peter van Dijk
171594a92d fix leading zero padding in ECDSA sig conversion 2017-02-28 12:24:00 +01:00
45 changed files with 779 additions and 107 deletions

4
.gitignore vendored
View File

@@ -1,5 +1,9 @@
build build
.classpath .classpath
.project .project
.gradle
jdnssec-tools*.tar.gz jdnssec-tools*.tar.gz
docs docs
test-zones
settings.json
.settings

View File

@@ -1,3 +1,35 @@
2019-07-23 David Blacka <davidb@verisign.com>
* Released version 0.16
* Updated to dnsjava 2.1.9
2019-02-26 David Blacka <davidb@verisign.com>
* Released version 0.15
* Ensure when a command line tool throws an exception it exits
with a non-zero exit code.
* Update local dnsjava jar to match actual build for
jdnssec-dnsjava.
2018-11-16 David Blacka <davidb@verisign.com>
* Released version 0.14
2018-07-15 Pallavi Aras
* Add Gradle build support. Adjust ant to use same paths.
2018-07-15 David Blacka <davidb@versigin.com
* Add algorithm 15 support. This included adding a public domain
EdDSA library to the distribution.
* Add minor feature to specify signature inception and expiration
times as UNIX epoch time values.
2017-06-22 Peter van Dijk <peter.van.dijk@powerdns.com>, Kees Monshouwer <mind04@monshouwer.eu>
* Fix leading zero(s) padding in ECDSA sig conversion
2017-01-06 David Blacka <davidb@verisign.com> 2017-01-06 David Blacka <davidb@verisign.com>
* Released version 0.13 * Released version 0.13

View File

@@ -1,13 +1,12 @@
# jdnssec-tools # jdnssec-tools
* http://www.verisignlabs.com/jdnssec-tools/
* https://github.com/dblacka/jdnssec-tools/wiki * https://github.com/dblacka/jdnssec-tools/wiki
Author: David Blacka (davidb@verisign.com) Author: David Blacka (davidb@verisign.com)
This is a collection of DNSSEC tools written in Java. They are intended to be an addition or replacement for the DNSSEC tools that are part of BIND 9. This is a collection of DNSSEC tools written in Java. They are intended to be an addition or replacement for the DNSSEC tools that are part of BIND 9.
These tools depend upon DNSjava (http://www.xbill.org/dnsjava), the Jakarta Commons CLI and Logging libraries (https://commons.apache.org/proper/commons-cli), and Sun's Java Cryptography extensions. A copy of each of these libraries is included in the distribution. Currently, these tools use a custom version of the DNSjava library with minor modifications, which is provided. These tools depend upon DNSjava (https://github.com/dnsjava/dnsjava), the Jakarta Commons CLI and Logging libraries (https://commons.apache.org/proper/commons-cli), and Sun's Java Cryptography extensions. A copy of each of these libraries is included in the distribution. Currently, these tools use a custom version of the DNSjava library with minor modifications, which is provided.
See the "licenses" directory for the licensing information of this package and the other packages that are distributed with it. See the "licenses" directory for the licensing information of this package and the other packages that are distributed with it.
@@ -34,8 +33,14 @@ Building from source:
ant ant
4. You can build the distribution tarballs with 'ant dist'. You can run the tools directly from the build area (without building the jdnssec-tools.jar file) by using the ./bin/_jdnssec_* wrappers. 4. You can build the distribution tarballs with 'ant dist'. You can run the tools directly from the build area (without building the jdnssec-tools.jar file) by using the ./bin/\_jdnssec_* wrappers.
5. Alternatively, build the project using gradle:
gradlew clean
gradlew assemble -i
The resulting jar file gets generated in build/libs.
The source for this project is available in git on github: https://github.com/dblacka/jdnssec-tools The source for this project is available in git on github: https://github.com/dblacka/jdnssec-tools
@@ -43,4 +48,4 @@ Source for the modified DNSjava library can be found on github as well: https://
--- ---
Questions or comments may be directed to the author (mailto:davidb@verisign.com) or sent to the dnssec@verisignlabs.com mailing list (https://lists.verisignlabs.com/mailman/listinfo/dnssec). Questions or comments may be directed to the author (mailto:davidb@verisign.com), or by creating issues in the [github issue tracker](https://github.com/dblacka/jdnssec-tools/issues).

View File

@@ -1 +1 @@
version=0.13 version=0.16.1

View File

@@ -1,16 +1,21 @@
#! /bin/sh #! /bin/sh
thisdir=`dirname $0` thisdir=$(dirname $0)
basedir=`cd $thisdir/..; pwd` basedir=$(cd $thisdir/.. || exit; pwd)
ulimit_max=`ulimit -H -n` ulimit_max=$(ulimit -H -n)
if [ $ulimit_max != "unlimited" ]; then if [ $ulimit_max != "unlimited" ]; then
ulimit -n $ulimit_max ulimit -n $ulimit_max
fi fi
# set the classpath # set the classpath
for i in $basedir/lib/*.jar $basedir/lib/*.zip $basedir/build/lib/*.jar; do for i in "$basedir"/lib/*.jar "$basedir"/lib/*.zip "$basedir"/build/libs/*.jar; do
CLASSPATH="$CLASSPATH":"$i" if ! [ -f $i ]; then continue; fi
if [ -z "$CLASSPATH" ]; then
CLASSPATH=$i
else
CLASSPATH="$CLASSPATH":"$i"
fi
done done
export CLASSPATH export CLASSPATH

View File

@@ -1,16 +1,21 @@
#! /bin/sh #! /bin/sh
thisdir=`dirname $0` thisdir=$(dirname $0)
basedir=`cd $thisdir/..; pwd` basedir=$(cd $thisdir/.. || exit; pwd)
ulimit_max=`ulimit -H -n` ulimit_max=$(ulimit -H -n)
if [ $ulimit_max != "unlimited" ]; then if [ $ulimit_max != "unlimited" ]; then
ulimit -n $ulimit_max ulimit -n $ulimit_max
fi fi
# set the classpath # set the classpath
for i in $basedir/lib/*.jar $basedir/lib/*.zip $basedir/build/lib/*.jar; do for i in "$basedir"/lib/*.jar "$basedir"/lib/*.zip "$basedir"/build/libs/*.jar; do
CLASSPATH="$CLASSPATH":"$i" if ! [ -f $i ]; then continue; fi
if [ -z "$CLASSPATH" ]; then
CLASSPATH=$i
else
CLASSPATH="$CLASSPATH":"$i"
fi
done done
export CLASSPATH export CLASSPATH

View File

@@ -1,16 +1,21 @@
#! /bin/sh #! /bin/sh
thisdir=`dirname $0` thisdir=$(dirname $0)
basedir=`cd $thisdir/..; pwd` basedir=$(cd $thisdir/.. || exit; pwd)
ulimit_max=`ulimit -H -n` ulimit_max=$(ulimit -H -n)
if [ $ulimit_max != "unlimited" ]; then if [ $ulimit_max != "unlimited" ]; then
ulimit -n $ulimit_max ulimit -n $ulimit_max
fi fi
# set the classpath # set the classpath
for i in $basedir/lib/*.jar $basedir/lib/*.zip $basedir/build/lib/*.jar; do for i in "$basedir"/lib/*.jar "$basedir"/lib/*.zip "$basedir"/build/libs/*.jar; do
CLASSPATH="$CLASSPATH":"$i" if ! [ -f $i ]; then continue; fi
if [ -z "$CLASSPATH" ]; then
CLASSPATH=$i
else
CLASSPATH="$CLASSPATH":"$i"
fi
done done
export CLASSPATH export CLASSPATH

View File

@@ -1,11 +1,21 @@
#! /bin/sh #! /bin/sh
thisdir=`dirname $0` thisdir=$(dirname $0)
basedir=`cd $thisdir/..; pwd` basedir=$(cd $thisdir/.. || exit; pwd)
ulimit_max=`ulimit -H -n`
if [ $ulimit_max != "unlimited" ]; then
ulimit -n $ulimit_max
fi
# set the classpath # set the classpath
for i in $basedir/lib/*.jar $basedir/lib/*.zip $basedir/build/lib/*.jar; do for i in "$basedir"/lib/*.jar "$basedir"/lib/*.zip "$basedir"/build/libs/*.jar; do
CLASSPATH="$CLASSPATH":"$i" if ! [ -f $i ]; then continue; fi
if [ -z "$CLASSPATH" ]; then
CLASSPATH=$i
else
CLASSPATH="$CLASSPATH":"$i"
fi
done done
export CLASSPATH export CLASSPATH

View File

@@ -1,11 +1,21 @@
#! /bin/sh #! /bin/sh
thisdir=`dirname $0` thisdir=$(dirname $0)
basedir=`cd $thisdir/..; pwd` basedir=$(cd $thisdir/.. || exit; pwd)
ulimit_max=`ulimit -H -n`
if [ $ulimit_max != "unlimited" ]; then
ulimit -n $ulimit_max
fi
# set the classpath # set the classpath
for i in $basedir/lib/*.jar $basedir/lib/*.zip $basedir/build/lib/*.jar; do for i in "$basedir"/lib/*.jar "$basedir"/lib/*.zip "$basedir"/build/libs/*.jar; do
CLASSPATH="$CLASSPATH":"$i" if ! [ -f $i ]; then continue; fi
if [ -z "$CLASSPATH" ]; then
CLASSPATH=$i
else
CLASSPATH="$CLASSPATH":"$i"
fi
done done
export CLASSPATH export CLASSPATH

View File

@@ -1,16 +1,21 @@
#! /bin/sh #! /bin/sh
thisdir=`dirname $0` thisdir=$(dirname $0)
basedir=`cd $thisdir/..; pwd` basedir=$(cd $thisdir/.. || exit; pwd)
ulimit_max=`ulimit -H -n` ulimit_max=$(ulimit -H -n)
if [ $ulimit_max != "unlimited" ]; then if [ $ulimit_max != "unlimited" ]; then
ulimit -n $ulimit_max ulimit -n $ulimit_max
fi fi
# set the classpath # set the classpath
for i in $basedir/lib/*.jar $basedir/lib/*.zip $basedir/build/lib/*.jar; do for i in "$basedir"/lib/*.jar "$basedir"/lib/*.zip "$basedir"/build/libs/*.jar; do
CLASSPATH="$CLASSPATH":"$i" if ! [ -f $i ]; then continue; fi
if [ -z "$CLASSPATH" ]; then
CLASSPATH=$i
else
CLASSPATH="$CLASSPATH":"$i"
fi
done done
export CLASSPATH export CLASSPATH

View File

@@ -1,7 +1,7 @@
#! /bin/sh #! /bin/sh
thisdir=`dirname $0` thisdir=$(dirname $0)
basedir=`cd $thisdir/..; pwd` basedir=$(cd $thisdir/.. || exit; pwd)
ulimit_max=`ulimit -H -n` ulimit_max=`ulimit -H -n`
if [ $ulimit_max != "unlimited" ]; then if [ $ulimit_max != "unlimited" ]; then
@@ -9,8 +9,13 @@ if [ $ulimit_max != "unlimited" ]; then
fi fi
# set the classpath # set the classpath
for i in $basedir/lib/*.jar $basedir/lib/*.zip $basedir/build/lib/*.jar; do for i in "$basedir"/lib/*.jar "$basedir"/lib/*.zip "$basedir"/build/libs/*.jar; do
CLASSPATH="$CLASSPATH":"$i" if ! [ -f "$i" ]; then continue; fi
if [ -z "$CLASSPATH" ]; then
CLASSPATH=$i
else
CLASSPATH="$CLASSPATH":"$i"
fi
done done
export CLASSPATH export CLASSPATH

View File

@@ -1,16 +1,21 @@
#! /bin/sh #! /bin/sh
thisdir=`dirname $0` thisdir=$(dirname $0)
basedir=`cd $thisdir/..; pwd` basedir=$(cd $thisdir/.. || exit; pwd)
ulimit_max=`ulimit -H -n` ulimit_max=$(ulimit -H -n)
if [ $ulimit_max != "unlimited" ]; then if [ $ulimit_max != "unlimited" ]; then
ulimit -n $ulimit_max ulimit -n $ulimit_max
fi fi
# set the classpath # set the classpath
for i in $basedir/lib/*.jar $basedir/lib/*.zip $basedir/build/lib/*.jar; do for i in "$basedir"/lib/*.jar "$basedir"/lib/*.zip "$basedir"/build/libs/*.jar; do
CLASSPATH="$CLASSPATH":"$i" if ! [ -f $i ]; then continue; fi
if [ -z "$CLASSPATH" ]; then
CLASSPATH=$i
else
CLASSPATH="$CLASSPATH":"$i"
fi
done done
export CLASSPATH export CLASSPATH

25
build.gradle Normal file
View File

@@ -0,0 +1,25 @@
/**
Declares dependencies for Jdnssec-tools
**/
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
jar {
baseName = 'jdnssec-tools'
version = '0.16'
}
repositories {
mavenCentral()
}
sourceCompatibility = 1.7
targetCompatibility = 1.7
dependencies {
compile fileTree(dir: 'lib', include: '*.jar')
}

View File

@@ -19,8 +19,8 @@
<property name="build.dir" value="build" /> <property name="build.dir" value="build" />
<property name="build.dest" value="${build.dir}/classes" /> <property name="build.dest" value="${build.dir}/classes" />
<property name="build.lib.dest" value="${build.dir}/lib" /> <property name="build.lib.dest" value="${build.dir}/libs" />
<property name="build.src" value="src" /> <property name="build.src" value="src/main/java" />
<property name="packages" value="com.verisignlabs.dnssec.*" /> <property name="packages" value="com.verisignlabs.dnssec.*" />
<property name="doc.dir" value="docs" /> <property name="doc.dir" value="docs" />
@@ -46,7 +46,9 @@
classpathref="project.classpath" classpathref="project.classpath"
deprecation="true" deprecation="true"
includeantruntime="false" includeantruntime="false"
includes="com/verisignlabs/dnssec/" /> includes="com/verisignlabs/dnssec/"
source="1.7"
target="1.7" />
</target> </target>
<target name="sectools-jar" depends="usage,sectools"> <target name="sectools-jar" depends="usage,sectools">

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
gradlew vendored Executable file
View File

@@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
gradlew.bat vendored Normal file
View File

@@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

Binary file not shown.

Binary file not shown.

BIN
lib/eddsa-0.3.0.jar Normal file

Binary file not shown.

View File

@@ -65,7 +65,7 @@ public abstract class CLBase
/** /**
* The base constructor. This will setup the command line options. * The base constructor. This will setup the command line options.
* *
* @param usage * @param usage
* The command line usage string (e.g., * The command line usage string (e.g.,
* "jdnssec-foo [..options..] zonefile") * "jdnssec-foo [..options..] zonefile")
@@ -106,7 +106,7 @@ public abstract class CLBase
/** /**
* This is an overridable method for subclasses to add their own command * This is an overridable method for subclasses to add their own command
* line options. * line options.
* *
* @param opts * @param opts
* the options object to add (via OptionBuilder, typically) new * the options object to add (via OptionBuilder, typically) new
* options to. * options to.
@@ -121,7 +121,7 @@ public abstract class CLBase
* Subclasses generally override processOptions() rather than this method. * Subclasses generally override processOptions() rather than this method.
* This method create the parsing objects and processes the standard * This method create the parsing objects and processes the standard
* options. * options.
* *
* @param args * @param args
* The command line arguments. * The command line arguments.
* @throws ParseException * @throws ParseException
@@ -188,7 +188,7 @@ public abstract class CLBase
/** /**
* Process additional tool-specific options. Subclasses generally override * Process additional tool-specific options. Subclasses generally override
* this. * this.
* *
* @param cli * @param cli
* The {@link CommandLine} object containing the parsed command * The {@link CommandLine} object containing the parsed command
* line state. * line state.
@@ -247,9 +247,22 @@ public abstract class CLBase
} }
} }
public static long parseLong(String s, long def)
{
try
{
long v = Long.parseLong(s);
return v;
}
catch (NumberFormatException e)
{
return def;
}
}
/** /**
* Calculate a date/time from a command line time/offset duration string. * Calculate a date/time from a command line time/offset duration string.
* *
* @param start * @param start
* the start time to calculate offsets from. * the start time to calculate offsets from.
* @param duration * @param duration
@@ -272,6 +285,11 @@ public abstract class CLBase
long offset = (long) parseInt(duration.substring(1), 0) * 1000; long offset = (long) parseInt(duration.substring(1), 0) * 1000;
return new Date(start.getTime() + offset); return new Date(start.getTime() + offset);
} }
if (duration.length() <= 10)
{
long epoch = parseLong(duration, 0) * 1000;
return new Date(epoch);
}
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss"); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT")); dateFormatter.setTimeZone(TimeZone.getTimeZone("GMT"));
@@ -320,6 +338,7 @@ public abstract class CLBase
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace(); e.printStackTrace();
System.exit(1);
} }
} }
} }

View File

@@ -42,7 +42,7 @@ import com.verisignlabs.dnssec.security.*;
* RRset. Note that it will sign any RRset with any private key without * RRset. Note that it will sign any RRset with any private key without
* consideration of whether or not the RRset *should* be signed in the context * consideration of whether or not the RRset *should* be signed in the context
* of a zone. * of a zone.
* *
* @author David Blacka * @author David Blacka
*/ */
public class SignRRset extends CLBase public class SignRRset extends CLBase
@@ -61,6 +61,7 @@ public class SignRRset extends CLBase
public String inputfile = null; public String inputfile = null;
public String outputfile = null; public String outputfile = null;
public boolean verifySigs = false; public boolean verifySigs = false;
public boolean verboseSigning = false;
public CLIState() public CLIState()
{ {
@@ -74,6 +75,7 @@ public class SignRRset extends CLBase
{ {
// boolean options // boolean options
opts.addOption("a", "verify", false, "verify generated signatures>"); opts.addOption("a", "verify", false, "verify generated signatures>");
opts.addOption("V", "verbose-signing", false, "Display verbose signing activity.");
OptionBuilder.hasArg(); OptionBuilder.hasArg();
OptionBuilder.withArgName("dir"); OptionBuilder.withArgName("dir");
@@ -104,6 +106,7 @@ public class SignRRset extends CLBase
String optstr = null; String optstr = null;
if (cli.hasOption('a')) verifySigs = true; if (cli.hasOption('a')) verifySigs = true;
if (cli.hasOption('V')) verboseSigning = true;
if ((optstr = cli.getOptionValue('D')) != null) if ((optstr = cli.getOptionValue('D')) != null)
{ {
@@ -155,7 +158,7 @@ public class SignRRset extends CLBase
/** /**
* Verify the generated signatures. * Verify the generated signatures.
* *
* @param zonename * @param zonename
* the origin name of the zone. * the origin name of the zone.
* @param records * @param records
@@ -198,7 +201,7 @@ public class SignRRset extends CLBase
/** /**
* Load the key pairs from the key files. * Load the key pairs from the key files.
* *
* @param keyfiles * @param keyfiles
* a string array containing the base names or paths of the keys * a string array containing the base names or paths of the keys
* to be loaded. * to be loaded.
@@ -310,7 +313,7 @@ public class SignRRset extends CLBase
state.outputfile = state.inputfile + ".signed"; state.outputfile = state.inputfile + ".signed";
} }
JCEDnsSecSigner signer = new JCEDnsSecSigner(); JCEDnsSecSigner signer = new JCEDnsSecSigner(state.verboseSigning);
List<RRSIGRecord> sigs = signer.signRRset(rrset, keypairs, state.start, state.expire); List<RRSIGRecord> sigs = signer.signRRset(rrset, keypairs, state.start, state.expire);
for (RRSIGRecord s : sigs) for (RRSIGRecord s : sigs)
@@ -355,7 +358,7 @@ public class SignRRset extends CLBase
{ {
SignRRset tool = new SignRRset(); SignRRset tool = new SignRRset();
tool.state = new CLIState(); tool.state = new CLIState();
tool.run(tool.state, args); tool.run(tool.state, args);
} }
} }

View File

@@ -147,13 +147,13 @@ public class VerifyZone extends CLBase
if (errors > 0) if (errors > 0)
{ {
System.out.println("zone did not verify."); System.out.println("zone did not verify.");
System.exit(1);
} }
else else
{ {
System.out.println("zone verified."); System.out.println("zone verified.");
System.exit(0);
} }
System.exit(0);
} }
public static void main(String[] args) public static void main(String[] args)

View File

@@ -355,6 +355,8 @@ public class BINDKeyUtils
StringBuffer buf = new StringBuffer(); StringBuffer buf = new StringBuffer();
buf.append(rec.getName()); buf.append(rec.getName());
buf.append(" ");
buf.append(rec.getTTL());
buf.append(" IN DNSKEY "); buf.append(" IN DNSKEY ");
buf.append(rec.getFlags() & 0xFFFF); buf.append(rec.getFlags() & 0xFFFF);
buf.append(" "); buf.append(" ");

View File

@@ -1,11 +1,11 @@
/* /*
* $Id$ * $Id$
* *
* Copyright (c) 2006 VeriSign. All rights reserved. * Copyright (c) 2006 VeriSign. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, * 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in * this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of * binary form must reproduce the above copyright notice, this list of
@@ -13,7 +13,7 @@
* materials provided with the distribution. 3. The name of the author may not * materials provided with the distribution. 3. The name of the author may not
* be used to endorse or promote products derived from this software without * be used to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
@@ -24,7 +24,7 @@
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
*/ */
package com.verisignlabs.dnssec.security; package com.verisignlabs.dnssec.security;
@@ -39,15 +39,20 @@ import java.util.logging.Logger;
import org.xbill.DNS.DNSSEC; import org.xbill.DNS.DNSSEC;
// for now, we need to import the EdDSA parameter spec classes
// because they have no generic form in java.security.spec.*
// sadly, this will currently fail if you don't have the lib.
import net.i2p.crypto.eddsa.spec.*;
/** /**
* This class handles translating DNS signing algorithm identifiers into various * This class handles translating DNS signing algorithm identifiers into various
* usable java implementations. * usable java implementations.
* *
* Besides centralizing the logic surrounding matching a DNSKEY algorithm * Besides centralizing the logic surrounding matching a DNSKEY algorithm
* identifier with various crypto implementations, it also handles algorithm * identifier with various crypto implementations, it also handles algorithm
* aliasing -- that is, defining a new algorithm identifier to be equivalent to * aliasing -- that is, defining a new algorithm identifier to be equivalent to
* an existing identifier. * an existing identifier.
* *
* @author David Blacka (orig) * @author David Blacka (orig)
* @author $Author: davidb $ (latest) * @author $Author: davidb $ (latest)
* @version $Revision: 2098 $ * @version $Revision: 2098 $
@@ -64,6 +69,7 @@ public class DnsKeyAlgorithm
public static final int DSA = 3; public static final int DSA = 3;
public static final int ECC_GOST = 4; public static final int ECC_GOST = 4;
public static final int ECDSA = 5; public static final int ECDSA = 5;
public static final int EDDSA = 6;
private static class AlgEntry private static class AlgEntry
{ {
@@ -90,6 +96,17 @@ public class DnsKeyAlgorithm
} }
} }
private static class EdAlgEntry extends AlgEntry
{
public EdDSAParameterSpec ed_spec;
public EdAlgEntry(int algorithm, String sigName, int baseType, EdDSAParameterSpec spec)
{
super(algorithm, sigName, baseType);
this.ed_spec = spec;
}
}
/** /**
* This is a mapping of algorithm identifier to Entry. The Entry contains the * This is a mapping of algorithm identifier to Entry. The Entry contains the
* data needed to map the algorithm to the various crypto implementations. * data needed to map the algorithm to the various crypto implementations.
@@ -113,6 +130,8 @@ public class DnsKeyAlgorithm
private KeyPairGenerator mECGOSTKeyGenerator; private KeyPairGenerator mECGOSTKeyGenerator;
/** This is a cached key pair generator for ECDSA_P256 keys. */ /** This is a cached key pair generator for ECDSA_P256 keys. */
private KeyPairGenerator mECKeyGenerator; private KeyPairGenerator mECKeyGenerator;
/** This is a cached key pair generator for EdDSA keys. */
private KeyPairGenerator mEdKeyGenerator;
private Logger log = Logger.getLogger(this.getClass().toString()); private Logger log = Logger.getLogger(this.getClass().toString());
@@ -132,6 +151,17 @@ public class DnsKeyAlgorithm
} }
catch (ReflectiveOperationException e) { } catch (ReflectiveOperationException e) { }
// Attempt to add the EdDSA-Java provider.
try
{
Class<?> eddsa_provider_class = Class.forName("net.i2p.crypto.eddsa.EdDSASecurityProvider");
Provider eddsa_provider = (Provider) eddsa_provider_class.newInstance();
Security.addProvider(eddsa_provider);
}
catch (ReflectiveOperationException e) {
log.warning("Unable to load EdDSA provider");
}
initialize(); initialize();
} }
@@ -170,7 +200,7 @@ public class DnsKeyAlgorithm
addMnemonic("RSASHA512", DNSSEC.Algorithm.RSASHA512); addMnemonic("RSASHA512", DNSSEC.Algorithm.RSASHA512);
// ECC-GOST is not supported by Java 1.8's Sun crypto provider. The // ECC-GOST is not supported by Java 1.8's Sun crypto provider. The
// bouncycastle.org provider, however, does. // bouncycastle.org provider, however, does support it.
// GostR3410-2001-CryptoPro-A is the named curve in the BC provider, but we // GostR3410-2001-CryptoPro-A is the named curve in the BC provider, but we
// will get the parameters directly. // will get the parameters directly.
addAlgorithm(DNSSEC.Algorithm.ECC_GOST, "GOST3411withECGOST3410", ECC_GOST, null); addAlgorithm(DNSSEC.Algorithm.ECC_GOST, "GOST3411withECGOST3410", ECC_GOST, null);
@@ -184,6 +214,13 @@ public class DnsKeyAlgorithm
addAlgorithm(DNSSEC.Algorithm.ECDSAP384SHA384, "SHA384withECDSA", ECDSA, "secp384r1"); addAlgorithm(DNSSEC.Algorithm.ECDSAP384SHA384, "SHA384withECDSA", ECDSA, "secp384r1");
addMnemonic("ECDSAP384SHA384", DNSSEC.Algorithm.ECDSAP384SHA384); addMnemonic("ECDSAP384SHA384", DNSSEC.Algorithm.ECDSAP384SHA384);
addMnemonic("ECDSA-P384", DNSSEC.Algorithm.ECDSAP384SHA384); addMnemonic("ECDSA-P384", DNSSEC.Algorithm.ECDSAP384SHA384);
// EdDSA is not supported by either the Java 1.8 Sun crypto
// provider or bouncycastle. It is added by the Ed25519-Java
// library. We don't have a corresponding constant in
// org.xbill.DNS.DNSSEC yet, though.
addAlgorithm(15, "NONEwithEdDSA", EDDSA, "Ed25519");
addMnemonic("ED25519", 15);
} }
private void addAlgorithm(int algorithm, String sigName, int baseType) private void addAlgorithm(int algorithm, String sigName, int baseType)
@@ -193,19 +230,43 @@ public class DnsKeyAlgorithm
private void addAlgorithm(int algorithm, String sigName, int baseType, String curveName) private void addAlgorithm(int algorithm, String sigName, int baseType, String curveName)
{ {
ECParameterSpec ec_spec = ECSpecFromAlgorithm(algorithm); if (baseType == ECDSA)
if (ec_spec == null) ec_spec = ECSpecFromName(curveName); {
if (ec_spec == null) return; ECParameterSpec ec_spec = ECSpecFromAlgorithm(algorithm);
// Check to see if we can get a Signature object for this algorithm. if (ec_spec == null) ec_spec = ECSpecFromName(curveName);
try { if (ec_spec == null) return;
Signature.getInstance(sigName);
} catch (NoSuchAlgorithmException e) { // Check to see if we can get a Signature object for this algorithm.
// If not, do not add the algorithm. try {
return; Signature.getInstance(sigName);
} catch (NoSuchAlgorithmException e) {
// for now, let's find out
log.severe("could not get signature for " + sigName + ": " + e.getMessage());
// If not, do not add the algorithm.
return;
}
ECAlgEntry entry = new ECAlgEntry(algorithm, sigName, baseType, ec_spec);
mAlgorithmMap.put(algorithm, entry);
}
else if (baseType == EDDSA)
{
EdDSAParameterSpec ed_spec = EdDSASpecFromName(curveName);
if (ed_spec == null) return;
// Check to see if we can get a Signature object for this algorithm.
try {
Signature.getInstance(sigName);
} catch (NoSuchAlgorithmException e) {
// for now, let's find out
log.severe("could not get signature for " + sigName + ": " + e.getMessage());
// If not, do not add the algorithm.
return;
}
EdAlgEntry entry = new EdAlgEntry(algorithm, sigName, baseType, ed_spec);
mAlgorithmMap.put(algorithm, entry);
} }
ECAlgEntry entry = new ECAlgEntry(algorithm, sigName, baseType, ec_spec);
mAlgorithmMap.put(algorithm, entry);
} }
private void addMnemonic(String m, int alg) private void addMnemonic(String m, int alg)
@@ -230,7 +291,7 @@ public class DnsKeyAlgorithm
if (!mAlgorithmMap.containsKey(original_algorithm)) if (!mAlgorithmMap.containsKey(original_algorithm))
{ {
log.warning("Unable to alias algorith " + alias log.warning("Unable to alias algorithm " + alias
+ " to unknown algorithm identifier " + original_algorithm); + " to unknown algorithm identifier " + original_algorithm);
return; return;
} }
@@ -273,7 +334,7 @@ public class DnsKeyAlgorithm
} }
} }
// Fetch the curve parameters from a named curve. // Fetch the curve parameters from a named ECDSA curve.
private ECParameterSpec ECSpecFromName(String stdName) private ECParameterSpec ECSpecFromName(String stdName)
{ {
try try
@@ -292,6 +353,24 @@ public class DnsKeyAlgorithm
return null; return null;
} }
// Fetch the curve parameters from a named EdDSA curve.
private EdDSAParameterSpec EdDSASpecFromName(String stdName)
{
try
{
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(stdName);
if (spec != null) return spec;
throw new InvalidParameterSpecException("Edwards Curve " + stdName + " not found.");
}
// catch (NoSuchAlgorithmException e) {
// log.info("Edwards Curve not supported by any crypto provider: " + e.getMessage());
// }
catch (InvalidParameterSpecException e) {
log.info("Edwards Curve " + stdName + " not supported");
}
return null;
}
public String[] supportedAlgMnemonics() public String[] supportedAlgMnemonics()
{ {
Set<Integer> keyset = mAlgorithmMap.keySet(); Set<Integer> keyset = mAlgorithmMap.keySet();
@@ -306,6 +385,7 @@ public class DnsKeyAlgorithm
return result; return result;
} }
/** /**
* Return a Signature object for the specified DNSSEC algorithm. * Return a Signature object for the specified DNSSEC algorithm.
* @param algorithm The DNSSEC algorithm (by number). * @param algorithm The DNSSEC algorithm (by number).
@@ -350,10 +430,28 @@ public class DnsKeyAlgorithm
return ec_entry.ec_spec; return ec_entry.ec_spec;
} }
/** Given one of the EdDSA algorithms (Ed25519, Ed448) return the
* elliptic curve parameters.
*
* @param algorithm
* The DNSSEC algorithm number.
* @return The stored EdDSAParameterSpec for that algorithm, or
* null if not a recognized/supported EdDSA algorithm.
*/
public EdDSAParameterSpec getEdwardsCurveParams(int algorithm)
{
AlgEntry entry = getEntry(algorithm);
if (entry == null) return null;
if (!(entry instanceof EdAlgEntry)) return null;
EdAlgEntry ed_entry = (EdAlgEntry) entry;
return ed_entry.ed_spec;
}
/** /**
* Translate a possible algorithm alias back to the original DNSSEC algorithm * Translate a possible algorithm alias back to the original DNSSEC algorithm
* number * number
* *
* @param algorithm * @param algorithm
* a DNSSEC algorithm that may be an alias. * a DNSSEC algorithm that may be an alias.
* @return -1 if the algorithm isn't recognised, the orignal algorithm number * @return -1 if the algorithm isn't recognised, the orignal algorithm number
@@ -368,7 +466,7 @@ public class DnsKeyAlgorithm
/** /**
* Test if a given algorithm is supported. * Test if a given algorithm is supported.
* *
* @param algorithm The DNSSEC algorithm number. * @param algorithm The DNSSEC algorithm number.
* @return true if the algorithm is a recognized and supported algorithm or alias. * @return true if the algorithm is a recognized and supported algorithm or alias.
*/ */
@@ -381,7 +479,7 @@ public class DnsKeyAlgorithm
/** /**
* Given an algorithm mnemonic, convert the mnemonic to a DNSSEC algorithm * Given an algorithm mnemonic, convert the mnemonic to a DNSSEC algorithm
* number. * number.
* *
* @param s * @param s
* The mnemonic string. This is case-insensitive. * The mnemonic string. This is case-insensitive.
* @return -1 if the mnemonic isn't recognized or supported, the algorithm * @return -1 if the mnemonic isn't recognized or supported, the algorithm
@@ -396,7 +494,7 @@ public class DnsKeyAlgorithm
/** /**
* Given a DNSSEC algorithm number, return the "preferred" mnemonic. * Given a DNSSEC algorithm number, return the "preferred" mnemonic.
* *
* @param algorithm * @param algorithm
* A DNSSEC algorithm number. * A DNSSEC algorithm number.
* @return The preferred mnemonic string, or null if not supported or * @return The preferred mnemonic string, or null if not supported or
@@ -507,8 +605,29 @@ public class DnsKeyAlgorithm
pair = mECKeyGenerator.generateKeyPair(); pair = mECKeyGenerator.generateKeyPair();
break; break;
} }
default: case EDDSA:
throw new NoSuchAlgorithmException("Alg " + algorithm); {
if (mEdKeyGenerator == null)
{
mEdKeyGenerator = KeyPairGenerator.getInstance("EdDSA");
}
EdDSAParameterSpec ed_spec = getEdwardsCurveParams(algorithm);
try
{
mEdKeyGenerator.initialize(ed_spec, new SecureRandom());
}
catch (InvalidAlgorithmParameterException e)
{
// Fold the InvalidAlgorithmParameterException into our existing
// thrown exception. Ugly, but requires less code change.
throw new NoSuchAlgorithmException("invalid key parameter spec");
}
pair = mEdKeyGenerator.generateKeyPair();
break;
}
default:
throw new NoSuchAlgorithmException("Alg " + algorithm);
} }
return pair; return pair;

View File

@@ -36,6 +36,11 @@ import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHParameterSpec;
import javax.crypto.spec.DHPrivateKeySpec; import javax.crypto.spec.DHPrivateKeySpec;
// For now, just import the native EdDSA classes
import net.i2p.crypto.eddsa.EdDSAPublicKey;
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
import net.i2p.crypto.eddsa.spec.*;
import org.xbill.DNS.DNSKEYRecord; import org.xbill.DNS.DNSKEYRecord;
import org.xbill.DNS.DNSSEC; import org.xbill.DNS.DNSSEC;
import org.xbill.DNS.DNSSEC.DNSSECException; import org.xbill.DNS.DNSSEC.DNSSECException;
@@ -45,7 +50,7 @@ import org.xbill.DNS.utils.base64;
/** /**
* This class handles conversions between JCA key formats and DNSSEC and BIND9 * This class handles conversions between JCA key formats and DNSSEC and BIND9
* key formats. * key formats.
* *
* @author David Blacka (original) * @author David Blacka (original)
* @author $Author$ (latest) * @author $Author$ (latest)
* @version $Revision$ * @version $Revision$
@@ -56,16 +61,17 @@ public class DnsKeyConverter
private KeyFactory mDSAKeyFactory; private KeyFactory mDSAKeyFactory;
private KeyFactory mDHKeyFactory; private KeyFactory mDHKeyFactory;
private KeyFactory mECKeyFactory; private KeyFactory mECKeyFactory;
private KeyFactory mEdKeyFactory;
private DnsKeyAlgorithm mAlgorithms; private DnsKeyAlgorithm mAlgorithms;
public DnsKeyConverter() public DnsKeyConverter()
{ {
mAlgorithms = DnsKeyAlgorithm.getInstance(); mAlgorithms = DnsKeyAlgorithm.getInstance();
} }
/** /**
* Given a DNS KEY record, return the JCA public key * Given a DNS KEY record, return the JCA public key
* *
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
*/ */
public PublicKey parseDNSKEYRecord(DNSKEYRecord pKeyRecord) public PublicKey parseDNSKEYRecord(DNSKEYRecord pKeyRecord)
@@ -89,8 +95,20 @@ public class DnsKeyConverter
pKeyRecord.getKey()); pKeyRecord.getKey());
} }
// do not rely on DNSJava's method for EdDSA for now.
if (mAlgorithms.baseType(originalAlgorithm) == DnsKeyAlgorithm.EDDSA)
{
try {
return parseEdDSADNSKEYRecord(pKeyRecord);
} catch (InvalidKeySpecException e) {
// just to be expedient, recast this as a NoSuchAlgorithmException.
throw new NoSuchAlgorithmException(e.getMessage());
}
}
try try
{ {
// This uses DNSJava's DNSSEC.toPublicKey() method.
return pKeyRecord.getPublicKey(); return pKeyRecord.getPublicKey();
} }
catch (DNSSECException e) catch (DNSSECException e)
@@ -99,6 +117,20 @@ public class DnsKeyConverter
} }
} }
/** Since we don't (yet) have support in DNSJava for parsing the
newer EdDSA algorithms, here is a local version. */
private PublicKey parseEdDSADNSKEYRecord(DNSKEYRecord pKeyRecord)
throws IllegalArgumentException, NoSuchAlgorithmException, InvalidKeySpecException
{
byte[] seed = pKeyRecord.getKey();
EdDSAPublicKeySpec spec = new EdDSAPublicKeySpec
(seed, mAlgorithms.getEdwardsCurveParams(pKeyRecord.getAlgorithm()));
KeyFactory factory = KeyFactory.getInstance("EdDSA");
return factory.generatePublic(spec);
}
/** /**
* Given a JCA public key and the ancillary data, generate a DNSKEY record. * Given a JCA public key and the ancillary data, generate a DNSKEY record.
*/ */
@@ -107,6 +139,9 @@ public class DnsKeyConverter
{ {
try try
{ {
if (mAlgorithms.baseType(alg) == DnsKeyAlgorithm.EDDSA) {
return generateEdDSADNSKEYRecord(name, dclass, ttl, flags, alg, key);
}
return new DNSKEYRecord(name, dclass, ttl, flags, DNSKEYRecord.Protocol.DNSSEC, alg, return new DNSKEYRecord(name, dclass, ttl, flags, DNSKEYRecord.Protocol.DNSSEC, alg,
key); key);
} }
@@ -117,6 +152,15 @@ public class DnsKeyConverter
} }
} }
private DNSKEYRecord generateEdDSADNSKEYRecord(Name name, int dclass, long ttl,
int flags, int alg, PublicKey key)
{
EdDSAPublicKey ed_key = (EdDSAPublicKey) key;
byte[] key_data = ed_key.getAbyte();
return new DNSKEYRecord(name, dclass, ttl, flags, DNSKEYRecord.Protocol.DNSSEC, alg,
key_data);
}
// Private Key Specific Parsing routines // Private Key Specific Parsing routines
/** /**
@@ -204,6 +248,8 @@ public class DnsKeyConverter
return parsePrivateECDSA(lines, alg); return parsePrivateECDSA(lines, alg);
case DnsKeyAlgorithm.ECDSA: case DnsKeyAlgorithm.ECDSA:
return parsePrivateECDSA(lines, alg); return parsePrivateECDSA(lines, alg);
case DnsKeyAlgorithm.EDDSA:
return parsePrivateEdDSA(lines, alg);
default: default:
throw new IOException("unsupported private key algorithm: " + val); throw new IOException("unsupported private key algorithm: " + val);
} }
@@ -230,7 +276,7 @@ public class DnsKeyConverter
/** /**
* Given the rest of the RSA BIND9 string format private key, parse and * Given the rest of the RSA BIND9 string format private key, parse and
* translate into a JCA private key * translate into a JCA private key
* *
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
* if the RSA algorithm is not available. * if the RSA algorithm is not available.
*/ */
@@ -319,7 +365,7 @@ public class DnsKeyConverter
/** /**
* Given the remaining lines in a BIND9 style DH private key, parse the key * Given the remaining lines in a BIND9 style DH private key, parse the key
* info and translate it into a JCA private key. * info and translate it into a JCA private key.
* *
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
* if the DH algorithm is not available. * if the DH algorithm is not available.
*/ */
@@ -375,7 +421,7 @@ public class DnsKeyConverter
/** /**
* Given the remaining lines in a BIND9 style DSA private key, parse the key * Given the remaining lines in a BIND9 style DSA private key, parse the key
* info and translate it into a JCA private key. * info and translate it into a JCA private key.
* *
* @throws NoSuchAlgorithmException * @throws NoSuchAlgorithmException
* if the DSA algorithm is not available. * if the DSA algorithm is not available.
*/ */
@@ -487,6 +533,60 @@ public class DnsKeyConverter
} }
} }
/**
* Given the remaining lines in a BIND9-style ECDSA private key, parse the key
* info and translate it into a JCA private key object.
* @param lines The remaining lines in a private key file (after
* @throws NoSuchAlgorithmException
* If elliptic curve is not available.
*/
private PrivateKey parsePrivateEdDSA(StringTokenizer lines, int algorithm)
throws NoSuchAlgorithmException
{
byte[] seed = null;
while (lines.hasMoreTokens())
{
String line = lines.nextToken();
if (line == null) continue;
if (line.startsWith("#")) continue;
String val = value(line);
if (val == null) continue;
byte[] data = base64.fromString(val);
if (line.startsWith("PrivateKey: "))
{
seed = data;
}
}
if (mEdKeyFactory == null)
{
mEdKeyFactory = KeyFactory.getInstance("EdDSA");
}
EdDSAParameterSpec ed_spec = mAlgorithms.getEdwardsCurveParams(algorithm);
if (ed_spec == null)
{
throw new NoSuchAlgorithmException("DNSSEC algorithm " + algorithm +
" is not a recognized Edwards Curve algorithm");
}
KeySpec spec = new EdDSAPrivateKeySpec(seed, ed_spec);
try
{
return mEdKeyFactory.generatePrivate(spec);
}
catch (InvalidKeySpecException e)
{
e.printStackTrace();
return null;
}
}
/** /**
* Given a private key and public key, generate the BIND9 style private key * Given a private key and public key, generate the BIND9 style private key
* format. * format.
@@ -509,6 +609,11 @@ public class DnsKeyConverter
{ {
return generatePrivateEC((ECPrivateKey) priv, (ECPublicKey) pub, alg); return generatePrivateEC((ECPrivateKey) priv, (ECPublicKey) pub, alg);
} }
else if (priv instanceof EdDSAPrivateKey && pub instanceof EdDSAPublicKey)
{
return generatePrivateED((EdDSAPrivateKey) priv, (EdDSAPublicKey) pub, alg);
}
return null; return null;
} }
@@ -630,4 +735,22 @@ public class DnsKeyConverter
return sw.toString(); return sw.toString();
} }
/**
* Given an edwards curve key pair, and the actual algorithm (which will
* describe the curve used), return the BIND9-style text encoding.
*/
private String generatePrivateED(EdDSAPrivateKey priv, EdDSAPublicKey pub, int alg)
{
StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw);
out.println("Private-key-format: v1.2");
out.println("Algorithm: " + alg + " (" + mAlgorithms.algToString(alg)
+ ")");
out.print("PrivateKey: ");
out.println(base64.toString(priv.getSeed()));
return sw.toString();
}
} }

View File

@@ -38,11 +38,11 @@ import org.xbill.DNS.utils.hexdump;
/** /**
* This class contains routines for signing DNS zones. * This class contains routines for signing DNS zones.
* *
* In particular, it contains both an ability to sign an individual RRset and * In particular, it contains both an ability to sign an individual RRset and
* the ability to sign an entire zone. It primarily glues together the more * the ability to sign an entire zone. It primarily glues together the more
* basic primitives found in {@link SignUtils}. * basic primitives found in {@link SignUtils}.
* *
* @author David Blacka (original) * @author David Blacka (original)
* @author $Author$ * @author $Author$
* @version $Revision$ * @version $Revision$
@@ -69,7 +69,7 @@ public class JCEDnsSecSigner
/** /**
* Cryptographically generate a new DNSSEC key. * Cryptographically generate a new DNSSEC key.
* *
* @param owner * @param owner
* the KEY RR's owner name. * the KEY RR's owner name.
* @param ttl * @param ttl
@@ -114,7 +114,7 @@ public class JCEDnsSecSigner
/** /**
* Sign an RRset. * Sign an RRset.
* *
* @param rrset * @param rrset
* the RRset to sign -- any existing signatures are ignored. * the RRset to sign -- any existing signatures are ignored.
* @param keypars * @param keypars
@@ -211,7 +211,7 @@ public class JCEDnsSecSigner
/** /**
* Create a completely self-signed DNSKEY RRset. * Create a completely self-signed DNSKEY RRset.
* *
* @param keypairs * @param keypairs
* the public & private keypairs to use in the keyset. * the public & private keypairs to use in the keyset.
* @param start * @param start
@@ -244,7 +244,7 @@ public class JCEDnsSecSigner
/** /**
* Conditionally sign an RRset and add it to the toList. * Conditionally sign an RRset and add it to the toList.
* *
* @param toList * @param toList
* the list to which we are adding the processed RRsets. * the list to which we are adding the processed RRsets.
* @param zonename * @param zonename
@@ -263,7 +263,7 @@ public class JCEDnsSecSigner
* if true, sign the zone apex keyset with both KSKs and ZSKs. * if true, sign the zone apex keyset with both KSKs and ZSKs.
* @param last_cut * @param last_cut
* the name of the last delegation point encountered. * the name of the last delegation point encountered.
* *
* @return the name of the new last_cut. * @return the name of the new last_cut.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -324,7 +324,7 @@ public class JCEDnsSecSigner
* signing variants (NSEC with or without Opt-In, NSEC3 with or without * signing variants (NSEC with or without Opt-In, NSEC3 with or without
* Opt-Out, etc.) External users of this class are expected to use the * Opt-Out, etc.) External users of this class are expected to use the
* appropriate public signZone* methods instead of this. * appropriate public signZone* methods instead of this.
* *
* @param zonename * @param zonename
* The name of the zone * The name of the zone
* @param records * @param records
@@ -363,7 +363,7 @@ public class JCEDnsSecSigner
* values will use the SOA TTL. * values will use the SOA TTL.
* @return an ordered list of {@link org.xbill.DNS.Record} objects, * @return an ordered list of {@link org.xbill.DNS.Record} objects,
* representing the signed zone. * representing the signed zone.
* *
* @throws IOException * @throws IOException
* @throws GeneralSecurityException * @throws GeneralSecurityException
*/ */
@@ -459,7 +459,7 @@ public class JCEDnsSecSigner
/** /**
* Given a zone, sign it using standard NSEC records. * Given a zone, sign it using standard NSEC records.
* *
* @param zonename * @param zonename
* The name of the zone. * The name of the zone.
* @param records * @param records
@@ -478,7 +478,7 @@ public class JCEDnsSecSigner
* the key signing keys). * the key signing keys).
* @param ds_digest_alg * @param ds_digest_alg
* The digest algorithm to use when generating DS records. * The digest algorithm to use when generating DS records.
* *
* @return an ordered list of {@link org.xbill.DNS.Record} objects, * @return an ordered list of {@link org.xbill.DNS.Record} objects,
* representing the signed zone. * representing the signed zone.
*/ */
@@ -494,7 +494,7 @@ public class JCEDnsSecSigner
/** /**
* Given a zone, sign it using NSEC3 records. * Given a zone, sign it using NSEC3 records.
* *
* @param signer * @param signer
* A signer (utility) object used to actually sign stuff. * A signer (utility) object used to actually sign stuff.
* @param zonename * @param zonename
@@ -529,7 +529,7 @@ public class JCEDnsSecSigner
* values will use the SOA TTL. * values will use the SOA TTL.
* @return an ordered list of {@link org.xbill.DNS.Record} objects, * @return an ordered list of {@link org.xbill.DNS.Record} objects,
* representing the signed zone. * representing the signed zone.
* *
* @throws IOException * @throws IOException
* @throws GeneralSecurityException * @throws GeneralSecurityException
*/ */
@@ -558,7 +558,7 @@ public class JCEDnsSecSigner
/** /**
* Given a zone, sign it using experimental Opt-In NSEC records (see RFC * Given a zone, sign it using experimental Opt-In NSEC records (see RFC
* 4956). * 4956).
* *
* @param zonename * @param zonename
* the name of the zone. * the name of the zone.
* @param records * @param records

View File

@@ -526,10 +526,19 @@ public class SignUtils
s_src_pos = (byte) (r_src_pos + r_src_len); s_pad = 0; s_src_pos = (byte) (r_src_pos + r_src_len); s_pad = 0;
len = (byte) (6 + r_src_len + s_src_len); len = (byte) (6 + r_src_len + s_src_len);
if (signature[r_src_pos] < 0) { // leading zeroes are forbidden
r_pad = 1; len++; while (signature[r_src_pos] == 0 && r_src_len > 0) {
r_src_pos++; r_src_len--; len--;
} }
if (signature[s_src_pos] < 0) { while (signature[s_src_pos] == 0 && s_src_len > 0) {
s_src_pos++; s_src_len--; len--;
}
// except when they are mandatory
if (r_src_len > 0 && signature[r_src_pos] < 0) {
r_pad = 1; len++;
}
if (s_src_len > 0 && signature[s_src_pos] < 0) {
s_pad = 1; len++; s_pad = 1; len++;
} }
byte[] sig = new byte[len]; byte[] sig = new byte[len];