29 Commits
0.12 ... v0.15

Author SHA1 Message Date
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
David Blacka
fb689c046f Update changelog, set this as a release. 2017-01-06 13:01:05 -05:00
David Blacka
8d3746fc22 Validate the the RRset TTL is <= the OrigTTL. 2017-01-06 12:54:16 -05:00
David Blacka
444601fb2a Detect duplicate RRSIGs as well. 2017-01-06 12:53:57 -05:00
David Blacka
c5896495c7 Either R or S could end up being shorter than the expected length, so adjust for that. 2017-01-05 13:50:48 -05:00
David Blacka
c13d9379b3 Update version, convert readme to markdown. 2016-12-09 17:57:09 -05:00
David Blacka
f170bd170a Elliptic curve support.
Improve usage, unknown algorithm error handling in jdnssec-keygen
Use the bouncycastle crypto provider for ECCGOST if available
2016-12-09 17:52:10 -05:00
David Blacka
6bbcf38fe1 update the embedded dnsjava version to 2.1.7 (jdnssec-dnsjava) 2016-08-22 09:40:47 -04:00
David Blacka
15cb5e2ab7 Fix issue in jdnssec-verifyzone (and ZoneVerifier) where junk in the zone wouldn't be handled correctly (that is, ignored.) 2014-04-22 16:39:00 -04:00
David Blacka
9fad4941a6 Make jdnssec-zoneformat -N also compute NSEC3 original owner names for ENTs 2014-04-22 16:37:58 -04:00
46 changed files with 1759 additions and 682 deletions

1
.gitignore vendored
View File

@@ -1,5 +1,6 @@
build build
.classpath .classpath
.project .project
.gradle
jdnssec-tools*.tar.gz jdnssec-tools*.tar.gz
docs docs

472
ChangeLog
View File

@@ -1,388 +1,446 @@
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>
* Released version 0.13
* ZoneVerifier: detect duplicate RRSIGs as well as other duplicate
RRs.
* DnsSecVerifier: check that the RRset's TTL <= OrigTTL.
2016-12-09 David Blacka <davidb@verisign.com>
* Add key generation, signing, verification support for elliptic
curve algorithms: ECDSA P-256 (13) and ECDSA P-384 (15).
- Opportunistically load the bouncycastle provider for ECCGOST
support.
* DnsKeyAlgorithms: refactoring, new methods to better support
elliptic curve, alias, knowing what algorithms are supported.
* KeyGen: do not display unsupported algorithms.
2016-08-22 David Blacka <davidb@verisign.com>
* Update internal dnsjava to 2.1.7-vrsn-1.
2014-04-22 David Blacka <davidb@verisign.com>
* ZoneFormat: Make -N also compute original ownernames for empty
non-terminal NSEC3 records.
* ZoneVerifier: Improve the zone verifiers handling of "junk" in a
zone (i.e., ignore resource records that aren't actually in the
zone itself.)
2012-07-16 David Blacka <davidb@verisign.com> 2012-07-16 David Blacka <davidb@verisign.com>
* Released version 0.12. * Released version 0.12.
* TypeMap: fix the fromBytes() method, which was incorrect and add * TypeMap: fix the fromBytes() method, which was incorrect and add
a static fromString() method. a static fromString() method.
* ProtoNSEC3: use TypeMap's toString method, rather than fetching * ProtoNSEC3: use TypeMap's toString method, rather than fetching
the array of types and rendering them directly. the array of types and rendering them directly.
2012-05-29 David Blacka <davidb@verisign.com> 2012-05-29 David Blacka <davidb@verisign.com>
* Released version 0.11. * Released version 0.11.
2012-05-26 David Blacka <davidb@verisign.com> 2012-05-26 David Blacka <davidb@verisign.com>
* Update dnsjava to dnsjava-2.1.3-vrsn-1. Update the code to * Update dnsjava to dnsjava-2.1.3-vrsn-1. Update the code to
adjust for API changes in dnsjava-2.1.x. Highlights: adjust for API changes in dnsjava-2.1.x. Highlights:
- no longer use DNSSEC.Failed, DNSSEC.Secure as those constants - no longer use DNSSEC.Failed, DNSSEC.Secure as those constants
are now gone. Instead, any methods returning those constants now are now gone. Instead, any methods returning those constants now
return a boolean, true for DNSSEC.Secure, false for DNSSEC.Failed return a boolean, true for DNSSEC.Secure, false for DNSSEC.Failed
or DNSSEC.Insecure. or DNSSEC.Insecure.
- No longer use KEYConverter. Instead, uses the new DNSKEYRecord - No longer use KEYConverter. Instead, uses the new DNSKEYRecord
constructor. constructor.
- The NSEC3 digest type is now an int (rather than a byte) - The NSEC3 digest type is now an int (rather than a byte)
- Algorithm references are now DNSSEC.Algorithm.<alg> - Algorithm references are now DNSSEC.Algorithm.<alg>
* jdnssec-verifyzone: Add duplicate RR detection (on by default) * jdnssec-verifyzone: Add duplicate RR detection (on by default)
and a command line option to disable it. and a command line option to disable it.
2011-02-14 David Blacka <davidb@verisign.com> 2011-02-14 David Blacka <davidb@verisign.com>
* Released version 0.10.1. * Released version 0.10.1.
2011-02-12 David Blacka <davidb@verisign.com> 2011-02-12 David Blacka <davidb@verisign.com>
* Use Java 1.5 generic types when possible. DNSJava itself still * Use Java 1.5 generic types when possible. DNSJava itself still
doesn't use them, so we have to suppress warnings when we use doesn't use them, so we have to suppress warnings when we use
RRset.rrs(), etc. RRset.rrs(), etc.
* Update commons-cli to version 1.2. * Update commons-cli to version 1.2.
* Refactor all of the command line classes. A new command line * Refactor all of the command line classes. A new command line
base class has been created to eliminate much of the duplicated base class has been created to eliminate much of the duplicated
code. code.
2011-02-09 David Blacka <davidb@verisign.com> 2011-02-09 David Blacka <davidb@verisign.com>
* Enable reading and writing from stdin/stdout for most tools. To * Enable reading and writing from stdin/stdout for most tools. To
do this, use '-' as the zonefile name. do this, use '-' as the zonefile name.
* jdnssec-signzone, jdnssec-signrrset: remove 'multiline' output * jdnssec-signzone, jdnssec-signrrset: remove 'multiline' output
as the default and add a command line switch (-m) to enable it. as the default and add a command line switch (-m) to enable it.
That is, these tools will output each RR on a single line by That is, these tools will output each RR on a single line by
default, adding -m will restore the prior behavior. default, adding -m will restore the prior behavior.
2011-02-08 David Blacka <davidb@verisign.com> 2011-02-08 David Blacka <davidb@verisign.com>
* Minor cleanups to usage statement printing across most of the tools. * Minor cleanups to usage statement printing across most of the tools.
2011-02-03 David Blacka <davidb@verisign.com> 2011-02-03 David Blacka <davidb@verisign.com>
* Released version 0.10 * Released version 0.10
* jdnssec-keygen: update the default algorithm to 8 (instead of 5). * jdnssec-keygen: update the default algorithm to 8 (instead of 5).
* Update logging across all command line tools to use a consistent * Update logging across all command line tools to use a consistent
'-v' option, and consistent, simpler log formatting. '-v' option, and consistent, simpler log formatting.
* jdnssec-verifyzone: resume logging the key information at INFO, * jdnssec-verifyzone: resume logging the key information at INFO,
but make the default log level WARNING. To see the old logging but make the default log level WARNING. To see the old logging
behavior, use -v 4. behavior, use -v 4.
2011-02-02 David Blacka <davidb@verisign.com> 2011-02-02 David Blacka <davidb@verisign.com>
* DnsKeyConverter: support the new BIND 9.7 private key format, * DnsKeyConverter: support the new BIND 9.7 private key format,
which only entails recognizing the new version string, since the which only entails recognizing the new version string, since the
new format is a superset of the old format. new format is a superset of the old format.
2011-01-11 David Blacka <davidb@verisign.com> 2011-01-11 David Blacka <davidb@verisign.com>
* jdnssec-zoneformat: add a -m option for formatting as * jdnssec-zoneformat: add a -m option for formatting as
multiline. Add a -N option for determining the original multiline. Add a -N option for determining the original
ownernames for NSEC3 signed zones. ownernames for NSEC3 signed zones.
2010-12-14 David Blacka <davidb@verisign.com> 2010-12-14 David Blacka <davidb@verisign.com>
* jdnssec-verifyzone: Add options to either fudge or ignore RRSIG * jdnssec-verifyzone: Add options to either fudge or ignore RRSIG
inception and expiration times. inception and expiration times.
2010-12-06 David Blacka <davidb@verisign.com> 2010-12-06 David Blacka <davidb@verisign.com>
* jdnssec-verifyzone: Complete refactored the verification code to * jdnssec-verifyzone: Complete refactored the verification code to
more comprehensively check a zone for DNSSEC validity. Instead of more comprehensively check a zone for DNSSEC validity. Instead of
just verifying signatures, it will also check to see if the NSEC just verifying signatures, it will also check to see if the NSEC
or NSEC3 chains are valid. or NSEC3 chains are valid.
2010-12-05 David Blacka <davidb@verisign.com> 2010-12-05 David Blacka <davidb@verisign.com>
* jdnssec-signzone: Fix a bug that would incorrectly handle * jdnssec-signzone: Fix a bug that would incorrectly handle
delgations below delegations (those should be ignored.) delgations below delegations (those should be ignored.)
* jdnssec-signzone: Make the signer ignore junk below a DNAME. * jdnssec-signzone: Make the signer ignore junk below a DNAME.
This differs from BIND's dnssec-signzone behavior (currently), but This differs from BIND's dnssec-signzone behavior (currently), but
is the correct behavior, as stuff below a DNAME doesn't actually is the correct behavior, as stuff below a DNAME doesn't actually
exist in DNS. Note that if a name in a zone has both a DNAME and exist in DNS. Note that if a name in a zone has both a DNAME and
a NS RRset (and is not at the apex), then the behavior is a bit a NS RRset (and is not at the apex), then the behavior is a bit
undefined. undefined.
* jdnssec-signzone: Fix a bug that would incorrectly set the RRSIG * jdnssec-signzone: Fix a bug that would incorrectly set the RRSIG
bit for NSEC3 RRs corresponding to insecure delegations. bit for NSEC3 RRs corresponding to insecure delegations.
* jdnssec-signzone: add a "verbose signing" option. This will * jdnssec-signzone: add a "verbose signing" option. This will
cause the pre-signed bytes and the raw signature bytes to be cause the pre-signed bytes and the raw signature bytes to be
output when signing. output when signing.
* Other fixes: some minor tweaks and comment fixes. * Other fixes: some minor tweaks and comment fixes.
Unfortunately, also a lot of rewrapping and whitespace changes due Unfortunately, also a lot of rewrapping and whitespace changes due
to Eclipse. Sigh. to Eclipse. Sigh.
2010-01-14 David Blacka <davidb@verisign.com> 2010-01-14 David Blacka <davidb@verisign.com>
* Released version 0.9.6 * Released version 0.9.6
2010-01-09 David Blacka <davidb@verisign.com> 2010-01-09 David Blacka <davidb@verisign.com>
* Upgrade to DNSJava 2.0.8 (plus a few local changes). 2.0.8 * Upgrade to DNSJava 2.0.8 (plus a few local changes). 2.0.8
fixes a major bug in typemap wire conversion. fixes a major bug in typemap wire conversion.
2009-11-02 David Blacka <davidb@verisign.com> 2009-11-02 David Blacka <davidb@verisign.com>
* Released version 0.9.5 * Released version 0.9.5
2009-11-01 David Blacka <davidb@verisign.com> 2009-11-01 David Blacka <davidb@verisign.com>
* Upgrade to DNSJava 2.0.7 (plus a few local changes). * Upgrade to DNSJava 2.0.7 (plus a few local changes).
* DnsKeyAlogorithm: change the RSASHA512 number to 10. * DnsKeyAlogorithm: change the RSASHA512 number to 10.
2009-08-23 David Blacka <davidb@verisign.com> 2009-08-23 David Blacka <davidb@verisign.com>
* Released version 0.9.4 * Released version 0.9.4
2009-07-15 David Blacka <davidb@verisign.com> 2009-07-15 David Blacka <davidb@verisign.com>
* SignUtils: Fix major issue where the code that generates that * SignUtils: Fix major issue where the code that generates that
canonical RRset given signature data wasn't obeying the "Orig TTL" canonical RRset given signature data wasn't obeying the "Orig TTL"
and "Labels" fields. This is a major issue with verification, and "Labels" fields. This is a major issue with verification,
although it doesn't affect signature generation. although it doesn't affect signature generation.
* VerifyZone: Fix bug where the whole-zone security status was * VerifyZone: Fix bug where the whole-zone security status was
still wrong: unsigned RRsets shouldn't make the zone Bogus. still wrong: unsigned RRsets shouldn't make the zone Bogus.
2009-06-12 David Blacka <davidb@verisign.com> 2009-06-12 David Blacka <davidb@verisign.com>
* VerifyZone: Fix bug in verification logic so that RRsets that * VerifyZone: Fix bug in verification logic so that RRsets that
never find a valid signature (i.e., only have signatures by keys never find a valid signature (i.e., only have signatures by keys
that aren't in the zone) are considered Bogus. Note that that aren't in the zone) are considered Bogus. Note that
VerifyZone still can't tell if a RRset that should be signed VerifyZone still can't tell if a RRset that should be signed
wasn't (or vice versa). wasn't (or vice versa).
* dnsjava: Update local copy of dnsjava library. This version * dnsjava: Update local copy of dnsjava library. This version
adds NSEC3 agorithms to DNSSECVerifier and KEYConverter, emulates adds NSEC3 agorithms to DNSSECVerifier and KEYConverter, emulates
DiG's "OPT PSEUDOSECTION" formatting in Message.toString(), and DiG's "OPT PSEUDOSECTION" formatting in Message.toString(), and
adds a minimal DHCIDRecord type. Note that the DNSjava trunk has adds a minimal DHCIDRecord type. Note that the DNSjava trunk has
a different (although functional similar) version of this type. a different (although functional similar) version of this type.
2009-06-09 David Blacka <davidb@verisign.com> 2009-06-09 David Blacka <davidb@verisign.com>
* VerifyZone: Improve the output. * VerifyZone: Improve the output.
* SignKeyset: Add a command line tool for just signing DNSKEY RRsets. * SignKeyset: Add a command line tool for just signing DNSKEY RRsets.
2009-02-10 David Blacka <davidb@verisign.com> 2009-02-10 David Blacka <davidb@verisign.com>
* Released version 0.9.0 * Released version 0.9.0
2009-02-08 David Blacka <davidb@verisign.com> 2009-02-08 David Blacka <davidb@verisign.com>
* KeyGen: make RSA large exponent the default. Make it possible * KeyGen: make RSA large exponent the default. Make it possible
to select small exponent. to select small exponent.
* KeyInfoTool: add more info to the output, handle multiple files * KeyInfoTool: add more info to the output, handle multiple files
on the command line. on the command line.
* DnsKeyAlgorithm: use DNSjava constants, BIND 9.6 mnemonics for * DnsKeyAlgorithm: use DNSjava constants, BIND 9.6 mnemonics for
NSEC3 key aliases. NSEC3 key aliases.
2009-02-07 David Blacka <davidb@verisign.com> 2009-02-07 David Blacka <davidb@verisign.com>
* SignZone: add argument for setting the TTL of the NSEC3PARAM * SignZone: add argument for setting the TTL of the NSEC3PARAM
record. This is so we can match current dnssec-signzone record. This is so we can match current dnssec-signzone
(9.6.0-p1) behavior of using a TTL of zero. (9.6.0-p1) behavior of using a TTL of zero.
* Update dnsjava to 2.0.6-vrsn-2, commons-cli to 1.1 * Update dnsjava to 2.0.6-vrsn-2, commons-cli to 1.1
* SignUtils: fix bug where NSEC3 algorithm and flags were transposed. * SignUtils: fix bug where NSEC3 algorithm and flags were transposed.
* SignUtils: Make sure to use the SOA minimum value for NSEC TTLs, * SignUtils: Make sure to use the SOA minimum value for NSEC TTLs,
instead of the ttl of the "node". instead of the ttl of the "node".
2009-02-04 David Blacka <davidb@verisign.com> 2009-02-04 David Blacka <davidb@verisign.com>
* update to dnsjava-2.0.1-vrsn-4 (updated typecodes for * update to dnsjava-2.0.1-vrsn-4 (updated typecodes for
NSEC3/NSEC3PARAM). NSEC3/NSEC3PARAM).
* SignUtils: use JDK-native SHA-256 code instead of broken * SignUtils: use JDK-native SHA-256 code instead of broken
contributed implementation. contributed implementation.
* DnsKeyAlgorithm: Add RSASHA256 and RSASHA512 algorithm, guessing * DnsKeyAlgorithm: Add RSASHA256 and RSASHA512 algorithm, guessing
at the code points. Note, these require Java 5 or later, or an at the code points. Note, these require Java 5 or later, or an
alternate crypto provider. alternate crypto provider.
* ZoneUtils: add a method to find specific RRs in a list of RRs * ZoneUtils: add a method to find specific RRs in a list of RRs
or RRsets. or RRsets.
* SignZone: make jdnssec-signzone a bit more aggressive in finding * SignZone: make jdnssec-signzone a bit more aggressive in finding
keys. Now it will look for keyfiles matching keys at the zone keys. Now it will look for keyfiles matching keys at the zone
apex, and, failing that, just look for keyfiles named after the apex, and, failing that, just look for keyfiles named after the
zone. Specifying any keys at all on the command line will zone. Specifying any keys at all on the command line will
override this behavior. override this behavior.
2009-02-01 David Blacka <davidb@verisign.com> 2009-02-01 David Blacka <davidb@verisign.com>
* DnsKeyAlgorithm: add official aliases from RFC 5155. * DnsKeyAlgorithm: add official aliases from RFC 5155.
* JCEDnsSecSigner: refactor zone signing methods to remove * JCEDnsSecSigner: refactor zone signing methods to remove
duplicate code. duplicate code.
* SignZone: move the signZone() methods to JCEDnsSecSigner * SignZone: move the signZone() methods to JCEDnsSecSigner
* BINDKeyUtils: close the private key file after reading it. * BINDKeyUtils: close the private key file after reading it.
Patch by Wolfgang Nagele. Patch by Wolfgang Nagele.
2006-12-15 David Blacka <davidb@verisignlabs.com> 2006-12-15 David Blacka <davidb@verisignlabs.com>
* Release version 0.8.4 * Release version 0.8.4
* SignZone: updated internals (and dnsjava lib) to match wire * SignZone: updated internals (and dnsjava lib) to match wire
format changes introduced by the nsec3-08 draft. format changes introduced by the nsec3-08 draft.
2006-10-10 David Blacka <davidb@verisignlabs.com> 2006-10-10 David Blacka <davidb@verisignlabs.com>
* Released version 0.8.3 * Released version 0.8.3
* ZoneFormat: fix RRSIG ordering issue when dealing with multiple * ZoneFormat: fix RRSIG ordering issue when dealing with multiple
RRSIGs for a given RRset. RRSIGs for a given RRset.
* ZoneFormat: lowercase all names in the zone. * ZoneFormat: lowercase all names in the zone.
* Fix packaging errors. * Fix packaging errors.
2006-09-12 David Blacka <davidb@verisignlabs.com> 2006-09-12 David Blacka <davidb@verisignlabs.com>
* Released version 0.8.0. * Released version 0.8.0.
2006-09-10 David Blacka <davidb@fury.blacka.com> 2006-09-10 David Blacka <davidb@fury.blacka.com>
* Added the "KeyInfoTool" command line tool as the start of a tool * Added the "KeyInfoTool" command line tool as the start of a tool
for decoding DNSKEY information. Right now, mostly just useful for decoding DNSKEY information. Right now, mostly just useful
for checking the public exponenent of RSA keys. for checking the public exponenent of RSA keys.
* Added the "-e" option to jdnssec-keygen, to instruct the key * Added the "-e" option to jdnssec-keygen, to instruct the key
generator to use the (common) large exponent in RSA key generator to use the (common) large exponent in RSA key
generation. generation.
2006-08-31 David Blacka <davidb@fury.blacka.com> 2006-08-31 David Blacka <davidb@fury.blacka.com>
* Modified jdnssec-signzone to set the ttls of NSEC3 records (so * Modified jdnssec-signzone to set the ttls of NSEC3 records (so
far) to the SOA minimum value. far) to the SOA minimum value.
* Add NSEC3PARAM support for compatibility with the -07 NSEC3 * Add NSEC3PARAM support for compatibility with the -07 NSEC3
draft. draft.
2006-05-24 David Blacka <davidb@verisignlabs.com> 2006-05-24 David Blacka <davidb@verisignlabs.com>
* Add some error checking for the NSEC3 command line parameters * Add some error checking for the NSEC3 command line parameters
for jdnssec-signzone. for jdnssec-signzone.
* Update local dnsjava build to 2.0.1. This also contains a * Update local dnsjava build to 2.0.1. This also contains a
change to the NSEC3 rdata format (as per the -06pre NSEC3 draft). change to the NSEC3 rdata format (as per the -06pre NSEC3 draft).
The change is the addition of a "next hashed owner name" length The change is the addition of a "next hashed owner name" length
octet. octet.
* Modified the jdnssec-* shell wrappers to also use the local * Modified the jdnssec-* shell wrappers to also use the local
build area version of the jdnssec-tools.jar file. This allows the build area version of the jdnssec-tools.jar file. This allows the
standard jdnssec-* wrappers to work right from the build area. standard jdnssec-* wrappers to work right from the build area.
* Add support of the SHA256 algorithm for DS records. This uses * Add support of the SHA256 algorithm for DS records. This uses
the SHA256 class that I obtained from Scott Rose (thanks Scott!). the SHA256 class that I obtained from Scott Rose (thanks Scott!).
* Change the name of the package and jar file to jdnssec-tools * Change the name of the package and jar file to jdnssec-tools
(from java-dnssec-tools) for consistency. (from java-dnssec-tools) for consistency.
* release version 0.7.0. * release version 0.7.0.
2006-05-23 David Blacka <davidb@verisignlabs.com> 2006-05-23 David Blacka <davidb@verisignlabs.com>
* Add support for algorithm aliases. This feature is so that the * Add support for algorithm aliases. This feature is so that the
user can declare the DNSKEY algorithm x is the same as algorithm 5 user can declare the DNSKEY algorithm x is the same as algorithm 5
(e.g.). So far, this only works with straight integer algorithm (e.g.). So far, this only works with straight integer algorithm
identifiers (no private alg support yet). identifiers (no private alg support yet).
* Fix jdnssec-signzone so that you can specify multiple KSKs on * Fix jdnssec-signzone so that you can specify multiple KSKs on
the command line. Apparently, commons-cli actually does handle the command line. Apparently, commons-cli actually does handle
repeating command line options correctly. repeating command line options correctly.
2006-05-03 David Blacka <davidb@verisignlabs.com> 2006-05-03 David Blacka <davidb@verisignlabs.com>
* Add preliminary implementation of jdnssec-dstool. This is a * Add preliminary implementation of jdnssec-dstool. This is a
simple command line tool that takes a DNSKEY record and converts simple command line tool that takes a DNSKEY record and converts
it into a DS record (or a DLV record). Right now, it requires it into a DS record (or a DLV record). Right now, it requires
that the key is stored in a file ending with '.key'. that the key is stored in a file ending with '.key'.
* release version 0.6.0. * release version 0.6.0.
2006-03-15 David Blacka <davidb@verisignlabs.com> 2006-03-15 David Blacka <davidb@verisignlabs.com>
* Type map changes for NSEC3, corresponding to changes in draft * Type map changes for NSEC3, corresponding to changes in draft
-05pre. Essentially: NSEC3 and RRSIG bits are not set for most -05pre. Essentially: NSEC3 and RRSIG bits are not set for most
(all) NSEC3 records any longer. (all) NSEC3 records any longer.
2006-03-06 David Blacka <davidb@verisignlabs.com> 2006-03-06 David Blacka <davidb@verisignlabs.com>
* release version 0.5.0. * release version 0.5.0.
2006-02-16 David Blacka <davidb@verisignlabs.com> 2006-02-16 David Blacka <davidb@verisignlabs.com>
* Make RecordComparator also compare RDATA so the removeDuplicates * Make RecordComparator also compare RDATA so the removeDuplicates
step actually works reliabled. This was masked by the dupicate step actually works reliabled. This was masked by the dupicate
suppression in org.xbill.DNS.RRset. suppression in org.xbill.DNS.RRset.
* Only allow one command line specified KSK since commons-cli * Only allow one command line specified KSK since commons-cli
doesn't seem to handle multi-arg options correctly. doesn't seem to handle multi-arg options correctly.
* Do not croak on the lack of the command-line keys for now. * Do not croak on the lack of the command-line keys for now.
* New version of local dnsjava build containing NSEC3 changes * New version of local dnsjava build containing NSEC3 changes
corresponding to the -04pre draft. corresponding to the -04pre draft.
2005-11-16 David Blacka <davidb@verisignlabs.com> 2005-11-16 David Blacka <davidb@verisignlabs.com>
* Make jdnssec-verifyzone work with just the zone (which is * Make jdnssec-verifyzone work with just the zone (which is
self-signed anyway). self-signed anyway).
* release version 0.4.2. * release version 0.4.2.
2005-11-09 David Blacka <davidb@verisignlabs.com> 2005-11-09 David Blacka <davidb@verisignlabs.com>
* Add original ownername comments to the NSEC3 generation. * Add original ownername comments to the NSEC3 generation.
2005-11-08 David Blacka <davidb@verisignlabs.com> 2005-11-08 David Blacka <davidb@verisignlabs.com>
* New zone formatter. * New zone formatter.
* Misc bug fixes. * Misc bug fixes.
* release version 0.4.1. * release version 0.4.1.
2005-11-07 David Blacka <davidb@verisignlabs.com> 2005-11-07 David Blacka <davidb@verisignlabs.com>
* Update the local dnsjava build with a bugfix. * Update the local dnsjava build with a bugfix.
* Fix ordering problem with ProtoNSEC3s. * Fix ordering problem with ProtoNSEC3s.
2005-11-06 David Blacka <davidb@verisignlabs.com> 2005-11-06 David Blacka <davidb@verisignlabs.com>
* Actually use the --iterations command line option of * Actually use the --iterations command line option of
jdnssec-signzone. jdnssec-signzone.
2005-10-27 David Blacka <davidb@verisignlabs.com> 2005-10-27 David Blacka <davidb@verisignlabs.com>
* Add NSEC3 support for jdnssec-signzone. * Add NSEC3 support for jdnssec-signzone.
* Remove support for plain Opt-In (until private algorithms work). * Remove support for plain Opt-In (until private algorithms work).
* release version 0.4.0. * release version 0.4.0.
2005-08-14 David Blacka <davidb@verisignlabs.com> 2005-08-14 David Blacka <davidb@verisignlabs.com>
* Move the signZone function into the SignZone class (from the * Move the signZone function into the SignZone class (from the
SignUtils) class. SignUtils) class.
* General cleanup. * General cleanup.
* Add local _jdnssec-* shell wrappers. These use build/classes in * Add local _jdnssec-* shell wrappers. These use build/classes in
the classpath so can be used to run the tools right out of the the classpath so can be used to run the tools right out of the
build area. build area.
2005-08-13 David Blacka <davidb@verisignlabs.com> 2005-08-13 David Blacka <davidb@verisignlabs.com>
* Update to DNSjava 2.0.0 * Update to DNSjava 2.0.0
* Refactor command line parsing. * Refactor command line parsing.
* Switch to using java.util.logging for logging. * Switch to using java.util.logging for logging.

63
README
View File

@@ -1,63 +0,0 @@
jdnssec-tools
http://www.verisignlabs.com/jdnssec-tools/
https://github.com/dblacka/jdnssec-tools/wiki
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.
These tools depend upon DNSjava (http://www.xbill.org/dnsjava), the
Jakarta Commons CLI and Logging libraries (http://jakarta.apache.org),
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.
Getting started:
1. Unpack the binary distribution:
% tar zxvf java-dnssec-tools-x.x.x.tar.gz
2. Run the various tools from their unpacked location:
% cd java-dnssec-tools-x.x.x
% ./bin/jdnssec-signzone -h
Building from source:
1. Unpack the source distribution, preferably into the same directory
that the binary distribution was unpacked.
% tar zxvf java-dnssec-tools-x.x.x-src.tar.gz
2. Edit the build.properties file to suit your environment.
3. Run Ant (see http://ant.apache.org for information about the Ant
build tool).
% 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.
The source for this project is available in git on github:
https://github.com/dblacka/jdnssec-tools
Source for the modified DNSjava library can be found on github as well:
https://github.com/dblacka/jdnssec-dnsjava
---
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).

50
README.md Normal file
View File

@@ -0,0 +1,50 @@
# jdnssec-tools
* https://github.com/dblacka/jdnssec-tools/wiki
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.
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.
See the "licenses" directory for the licensing information of this package and the other packages that are distributed with it.
Getting started:
1. Unpack the binary distribution:
tar zxvf java-dnssec-tools-x.x.x.tar.gz
2. Run the various tools from their unpacked location:
cd java-dnssec-tools-x.x.x
./bin/jdnssec-signzone -h
Building from source:
1. Unpack the source distribution, preferably into the same directory that the binary distribution was unpacked.
tar zxvf java-dnssec-tools-x.x.x-src.tar.gz
2. Edit the build.properties file to suit your environment.
3. Run Ant (see http://ant.apache.org for information about the Ant build tool).
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.
5. Build the project using gradle
./gradlew clean
./gradlew assemble -i
jar file gets generated in build/libs
The source for this project is available in git on github: https://github.com/dblacka/jdnssec-tools
Source for the modified DNSjava library can be found on github as well: https://github.com/dblacka/jdnssec-dnsjava
---
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).

View File

@@ -1 +1 @@
version=0.12 version=0.15

View File

@@ -9,7 +9,7 @@ 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" CLASSPATH="$CLASSPATH":"$i"
done done
export CLASSPATH export CLASSPATH

View File

@@ -9,7 +9,7 @@ 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" CLASSPATH="$CLASSPATH":"$i"
done done
export CLASSPATH export CLASSPATH

View File

@@ -4,7 +4,7 @@ thisdir=`dirname $0`
basedir=`cd $thisdir/..; pwd` basedir=`cd $thisdir/..; pwd`
# 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" CLASSPATH="$CLASSPATH":"$i"
done done
export CLASSPATH export CLASSPATH

View File

@@ -4,7 +4,7 @@ thisdir=`dirname $0`
basedir=`cd $thisdir/..; pwd` basedir=`cd $thisdir/..; pwd`
# 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" CLASSPATH="$CLASSPATH":"$i"
done done
export CLASSPATH export CLASSPATH

View File

@@ -9,7 +9,7 @@ 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" CLASSPATH="$CLASSPATH":"$i"
done done
export CLASSPATH export CLASSPATH

View File

@@ -9,7 +9,7 @@ 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" CLASSPATH="$CLASSPATH":"$i"
done done
export CLASSPATH export CLASSPATH

View File

@@ -9,7 +9,7 @@ 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" CLASSPATH="$CLASSPATH":"$i"
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.15'
}
repositories {
mavenCentral()
}
sourceCompatibility = 1.7
targetCompatibility = 1.7
dependencies {
compile fileTree(dir: 'lib', include: '*.jar')
}

View File

@@ -14,13 +14,13 @@
<property file="build.properties" /> <property file="build.properties" />
<property file="VERSION" /> <property file="VERSION" />
<property name="sectools-distname" value="jdnssec-tools-${version}" /> <property name="sectools-distname" value="jdnssec-tools-${version}" />
<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" />
@@ -41,14 +41,14 @@
</target> </target>
<target name="sectools" depends="prepare-src" > <target name="sectools" depends="prepare-src" >
<javac srcdir="${build.src}" <javac srcdir="${build.src}"
destdir="${build.dest}" destdir="${build.dest}"
classpathref="project.classpath" classpathref="project.classpath"
source="1.5" deprecation="true"
target="1.5"
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">
@@ -57,20 +57,20 @@
includes="com/verisignlabs/dnssec/" /> includes="com/verisignlabs/dnssec/" />
</target> </target>
<target name="compile" <target name="compile"
depends="usage,sectools-jar"> depends="usage,sectools-jar">
</target> </target>
<target name="javadoc" depends="usage"> <target name="javadoc" depends="usage">
<mkdir dir="${javadoc.dest}"/> <mkdir dir="${javadoc.dest}"/>
<javadoc packagenames="${packages}" <javadoc packagenames="${packages}"
classpath="${project.classpath}" classpath="${project.classpath}"
sourcepath="${build.src}" sourcepath="${build.src}"
destdir="${javadoc.dest}" destdir="${javadoc.dest}"
verbose="true" author="true" verbose="true" author="true"
windowtitle="jdnssec-tools-${version}" windowtitle="jdnssec-tools-${version}"
use="true"> use="true">
<link href="http://java.sun.com/j2se/1.4.2/docs/api/" /> <link href="https://docs.oracle.com/javase/8/docs/api/" />
<link href="http://www.xbill.org/dnsjava/doc/" /> <link href="http://www.xbill.org/dnsjava/doc/" />
</javadoc> </javadoc>
</target> </target>
@@ -148,7 +148,7 @@
</tar> </tar>
</target> </target>
<target name="sectools-dist" <target name="sectools-dist"
depends="sectools-bin-dist,sectools-src-dist, sectools-dist-clean"> depends="sectools-bin-dist,sectools-src-dist, sectools-dist-clean">
</target> </target>
@@ -172,4 +172,3 @@
</target> </target>
</project> </project>

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

Binary file not shown.

View File

@@ -0,0 +1,6 @@
#Sat Nov 25 16:14:38 PST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip

164
gradlew vendored Executable file
View File

@@ -0,0 +1,164 @@
#!/usr/bin/env bash
##############################################################################
##
## 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=""
# 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, switch paths to Windows format before running java
if $cygwin ; 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=$((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
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

90
gradlew.bat vendored Normal file
View File

@@ -0,0 +1,90 @@
@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
@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=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@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 init
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 init
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
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
: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 %CMD_LINE_ARGS%
: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

@@ -1,299 +0,0 @@
/*
* $Id$
*
* Copyright (c) 2006 VeriSign. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* 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
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package com.verisignlabs.dnssec.security;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.security.spec.RSAKeyGenParameterSpec;
import java.util.HashMap;
import java.util.logging.Logger;
import org.xbill.DNS.DNSSEC;
/**
* This class handles translating DNS signing algorithm identifiers into various
* usable java implementations.
*
* Besides centralizing the logic surrounding matching a DNSKEY algorithm
* identifier with various crypto implementations, it also handles algorithm
* aliasing -- that is, defining a new algorithm identifier to be equivalent to
* an existing identifier.
*
* @author David Blacka (orig)
* @author $Author: davidb $ (latest)
* @version $Revision: 2098 $
*/
public class DnsKeyAlgorithm
{
public static final int UNKNOWN = -1;
public static final int RSA = 1;
public static final int DH = 2;
public static final int DSA = 3;
private static class Entry
{
public String sigName;
public int baseType;
public Entry(String sigName, int baseType)
{
this.sigName = sigName;
this.baseType = baseType;
}
}
/**
* This is a mapping of algorithm identifier to Entry. The Entry contains the
* data needed to map the algorithm to the various crypto implementations.
*/
private HashMap<Integer, Entry> mAlgorithmMap;
/**
* This is a mapping of algorithm mnemonics to algorithm identifiers.
*/
private HashMap<String, Integer> mMnemonicToIdMap;
/**
* This is a mapping of identifiers to preferred mnemonic -- the preferred one
* is the first defined one
*/
private HashMap<Integer, String> mIdToMnemonicMap;
/** This is a cached key pair generator for RSA keys. */
private KeyPairGenerator mRSAKeyGenerator;
/** This is a cache key pair generator for DSA keys. */
private KeyPairGenerator mDSAKeyGenerator;
private Logger log = Logger.getLogger(this.getClass().toString());
/** This is the global instance for this class. */
private static DnsKeyAlgorithm mInstance = null;
public DnsKeyAlgorithm()
{
mAlgorithmMap = new HashMap<Integer, Entry>();
mMnemonicToIdMap = new HashMap<String, Integer>();
mIdToMnemonicMap = new HashMap<Integer, String>();
// Load the standard DNSSEC algorithms.
addAlgorithm(DNSSEC.Algorithm.RSAMD5, new Entry("MD5withRSA", RSA));
addMnemonic("RSAMD5", DNSSEC.Algorithm.RSAMD5);
addAlgorithm(DNSSEC.Algorithm.DH, new Entry("", DH));
addMnemonic("DH", DNSSEC.Algorithm.DH);
addAlgorithm(DNSSEC.Algorithm.DSA, new Entry("SHA1withDSA", DSA));
addMnemonic("DSA", DNSSEC.Algorithm.DSA);
addAlgorithm(DNSSEC.Algorithm.RSASHA1, new Entry("SHA1withRSA", RSA));
addMnemonic("RSASHA1", DNSSEC.Algorithm.RSASHA1);
addMnemonic("RSA", DNSSEC.Algorithm.RSASHA1);
// Load the (now) standard aliases
addAlias(DNSSEC.Algorithm.DSA_NSEC3_SHA1, "DSA-NSEC3-SHA1", DNSSEC.Algorithm.DSA);
addAlias(DNSSEC.Algorithm.RSA_NSEC3_SHA1, "RSA-NSEC3-SHA1", DNSSEC.Algorithm.RSASHA1);
// Also recognize the BIND 9.6 mnemonics
addMnemonic("NSEC3DSA", DNSSEC.Algorithm.DSA_NSEC3_SHA1);
addMnemonic("NSEC3RSASHA1", DNSSEC.Algorithm.RSA_NSEC3_SHA1);
// Algorithms added by RFC 5702.
// NOTE: these algorithms aren't available in Java 1.4's sunprovider
// implementation (but are in java 1.5's and later).
addAlgorithm(8, new Entry("SHA256withRSA", RSA));
addMnemonic("RSASHA256", 8);
addAlgorithm(10, new Entry("SHA512withRSA", RSA));
addMnemonic("RSASHA512", 10);
}
private void addAlgorithm(int algorithm, Entry entry)
{
mAlgorithmMap.put(algorithm, entry);
}
private void addMnemonic(String m, int alg)
{
mMnemonicToIdMap.put(m.toUpperCase(), alg);
if (!mIdToMnemonicMap.containsKey(alg))
{
mIdToMnemonicMap.put(alg, m);
}
}
public void addAlias(int alias, String mnemonic, int original_algorithm)
{
if (mAlgorithmMap.containsKey(alias))
{
log.warning("Unable to alias algorithm " + alias + " because it already exists.");
return;
}
if (!mAlgorithmMap.containsKey(original_algorithm))
{
log.warning("Unable to alias algorith " + alias
+ " to unknown algorithm identifier " + original_algorithm);
return;
}
mAlgorithmMap.put(alias, mAlgorithmMap.get(original_algorithm));
if (mnemonic != null)
{
addMnemonic(mnemonic, alias);
}
}
private Entry getEntry(int alg)
{
return mAlgorithmMap.get(alg);
}
public Signature getSignature(int algorithm)
{
Entry entry = getEntry(algorithm);
if (entry == null) return null;
Signature s = null;
try
{
s = Signature.getInstance(entry.sigName);
}
catch (NoSuchAlgorithmException e)
{
log.severe("Unable to get signature implementation for algorithm " + algorithm
+ ": " + e);
}
return s;
}
public int stringToAlgorithm(String s)
{
Integer alg = mMnemonicToIdMap.get(s.toUpperCase());
if (alg != null) return alg.intValue();
return -1;
}
public String algToString(int algorithm)
{
return mIdToMnemonicMap.get(algorithm);
}
public int baseType(int algorithm)
{
Entry entry = getEntry(algorithm);
if (entry != null) return entry.baseType;
return UNKNOWN;
}
public int standardAlgorithm(int algorithm)
{
switch (baseType(algorithm))
{
case RSA:
return DNSSEC.Algorithm.RSASHA1;
case DSA:
return DNSSEC.Algorithm.DSA;
case DH:
return DNSSEC.Algorithm.DH;
default:
return UNKNOWN;
}
}
public boolean isDSA(int algorithm)
{
return (baseType(algorithm) == DSA);
}
public KeyPair generateKeyPair(int algorithm, int keysize, boolean useLargeExp)
throws NoSuchAlgorithmException
{
KeyPair pair = null;
switch (baseType(algorithm))
{
case RSA:
if (mRSAKeyGenerator == null)
{
mRSAKeyGenerator = KeyPairGenerator.getInstance("RSA");
}
RSAKeyGenParameterSpec rsa_spec;
if (useLargeExp)
{
rsa_spec = new RSAKeyGenParameterSpec(keysize, RSAKeyGenParameterSpec.F4);
}
else
{
rsa_spec = new RSAKeyGenParameterSpec(keysize, RSAKeyGenParameterSpec.F0);
}
try
{
mRSAKeyGenerator.initialize(rsa_spec);
}
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 = mRSAKeyGenerator.generateKeyPair();
break;
case DSA:
if (mDSAKeyGenerator == null)
{
mDSAKeyGenerator = KeyPairGenerator.getInstance("DSA");
}
mDSAKeyGenerator.initialize(keysize);
pair = mDSAKeyGenerator.generateKeyPair();
break;
default:
throw new NoSuchAlgorithmException("Alg " + algorithm);
}
return pair;
}
public KeyPair generateKeyPair(int algorithm, int keysize)
throws NoSuchAlgorithmException
{
return generateKeyPair(algorithm, keysize, false);
}
public static DnsKeyAlgorithm getInstance()
{
if (mInstance == null) mInstance = new DnsKeyAlgorithm();
return mInstance;
}
}

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

@@ -74,17 +74,18 @@ public class KeyGen extends CLBase
OptionBuilder.withDescription("ZONE | OTHER (default ZONE)"); OptionBuilder.withDescription("ZONE | OTHER (default ZONE)");
opts.addOption(OptionBuilder.create('n')); opts.addOption(OptionBuilder.create('n'));
String[] algStrings = DnsKeyAlgorithm.getInstance().supportedAlgMnemonics();
OptionBuilder.hasArg(); OptionBuilder.hasArg();
OptionBuilder.withArgName("algorithm"); OptionBuilder.withArgName("algorithm");
OptionBuilder.withDescription("RSA | RSASHA1 | RSAMD5 | DH | DSA " OptionBuilder.withDescription(String.join(" | ", algStrings) +
+ "| RSA-NSEC3-SHA1 | DSA-NSEC3-SHA1 " " | alias, RSASHA256 is default.");
+ "| RSASHA256 | RSASHA512 | alias, RSASHA1 is default.");
opts.addOption(OptionBuilder.create('a')); opts.addOption(OptionBuilder.create('a'));
OptionBuilder.hasArg(); OptionBuilder.hasArg();
OptionBuilder.withArgName("size"); OptionBuilder.withArgName("size");
OptionBuilder.withDescription("key size, in bits. (default = 1024)\n" OptionBuilder.withDescription("key size, in bits. default is 1024. "
+ "RSA: [512..4096]\n" + "DSA: [512..1024]\n" + "DH: [128..4096]"); + "RSA: [512..4096], DSA: [512..1024], DH: [128..4096], "
+ "ECDSA: ignored");
opts.addOption(OptionBuilder.create('b')); opts.addOption(OptionBuilder.create('b'));
OptionBuilder.hasArg(); OptionBuilder.hasArg();
@@ -98,7 +99,6 @@ public class KeyGen extends CLBase
OptionBuilder.withArgName("dir"); OptionBuilder.withArgName("dir");
OptionBuilder.withDescription("place generated key files in this " + "directory"); OptionBuilder.withDescription("place generated key files in this " + "directory");
opts.addOption(OptionBuilder.create('d')); opts.addOption(OptionBuilder.create('d'));
opts.addOption(OptionBuilder.create('A'));
} }
protected void processOptions(CommandLine cli) protected void processOptions(CommandLine cli)
@@ -106,7 +106,7 @@ public class KeyGen extends CLBase
{ {
String optstr = null; String optstr = null;
String[] optstrs = null; String[] optstrs = null;
if (cli.hasOption('k')) kskFlag = true; if (cli.hasOption('k')) kskFlag = true;
if (cli.hasOption('e')) useLargeE = true; if (cli.hasOption('e')) useLargeE = true;
@@ -136,6 +136,11 @@ public class KeyGen extends CLBase
if ((optstr = cli.getOptionValue('a')) != null) if ((optstr = cli.getOptionValue('a')) != null)
{ {
algorithm = parseAlg(optstr); algorithm = parseAlg(optstr);
if (algorithm < 0)
{
System.err.println("DNSSEC algorithm " + optstr + " is not supported");
usage();
}
} }
if ((optstr = cli.getOptionValue('b')) != null) if ((optstr = cli.getOptionValue('b')) != null)
@@ -166,7 +171,11 @@ public class KeyGen extends CLBase
DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance(); DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance();
int alg = parseInt(s, -1); int alg = parseInt(s, -1);
if (alg > 0) return alg; if (alg > 0)
{
if (algs.supportedAlgorithm(alg)) return alg;
return -1;
}
return algs.stringToAlgorithm(s); return algs.stringToAlgorithm(s);
} }
@@ -211,7 +220,7 @@ public class KeyGen extends CLBase
{ {
KeyGen tool = new KeyGen(); KeyGen tool = new KeyGen();
tool.state = new CLIState(); tool.state = new CLIState();
tool.run(tool.state, args); tool.run(tool.state, args);
} }
} }

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

@@ -546,6 +546,7 @@ public class SignZone extends CLBase
} }
} }
br.close();
if (res.size() == 0) return null; if (res.size() == 0) return null;
return res; return res;
} }

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

@@ -42,7 +42,7 @@ import com.verisignlabs.dnssec.security.RecordComparator;
/** /**
* This class forms the command line implementation of a zone file normalizer. * This class forms the command line implementation of a zone file normalizer.
* That is, a tool to rewrite zones in a consistent, comparable format. * That is, a tool to rewrite zones in a consistent, comparable format.
* *
* @author David Blacka (original) * @author David Blacka (original)
* @author $Author: davidb $ * @author $Author: davidb $
* @version $Revision: 2218 $ * @version $Revision: 2218 $
@@ -126,13 +126,20 @@ public class ZoneFormat extends CLBase
Collections.sort(zone, new RecordComparator()); Collections.sort(zone, new RecordComparator());
// first, find the NSEC3PARAM record -- this is an inefficient linear // first, find the NSEC3PARAM record -- this is an inefficient linear
// search. // search, although it should be near the head of the list.
NSEC3PARAMRecord nsec3param = null; NSEC3PARAMRecord nsec3param = null;
HashMap<String, String> map = new HashMap<String, String>(); HashMap<String, String> map = new HashMap<String, String>();
base32 b32 = new base32(base32.Alphabet.BASE32HEX, false, true); base32 b32 = new base32(base32.Alphabet.BASE32HEX, false, true);
Name zonename = null;
for (Record r : zone) for (Record r : zone)
{ {
if (r.getType() == Type.SOA)
{
zonename = r.getName();
continue;
}
if (r.getType() == Type.NSEC3PARAM) if (r.getType() == Type.NSEC3PARAM)
{ {
nsec3param = (NSEC3PARAMRecord) r; nsec3param = (NSEC3PARAMRecord) r;
@@ -140,6 +147,8 @@ public class ZoneFormat extends CLBase
} }
} }
// If we couldn't determine a zone name, we have an issue.
if (zonename == null) return;
// If there wasn't one, we have nothing to do. // If there wasn't one, we have nothing to do.
if (nsec3param == null) return; if (nsec3param == null) return;
@@ -150,10 +159,23 @@ public class ZoneFormat extends CLBase
if (r.getName().equals(last_name)) continue; if (r.getName().equals(last_name)) continue;
if (r.getType() == Type.NSEC3) continue; if (r.getType() == Type.NSEC3) continue;
byte[] hash = nsec3param.hashName(r.getName()); Name n = r.getName();
byte[] hash = nsec3param.hashName(n);
String hashname = b32.toString(hash); String hashname = b32.toString(hash);
map.put(hashname, r.getName().toString().toLowerCase()); map.put(hashname, n.toString().toLowerCase());
last_name = r.getName(); last_name = n;
// inefficiently create hashes for the possible ancestor ENTs
for (int i = zonename.labels() + 1; i < n.labels(); ++i)
{
Name parent = new Name(n, n.labels() - i);
byte[] parent_hash = nsec3param.hashName(parent);
String parent_hashname = b32.toString(parent_hash);
if (!map.containsKey(parent_hashname))
{
map.put(parent_hashname, parent.toString().toLowerCase());
}
}
} }
// Final pass, assign the names if we can // Final pass, assign the names if we can

View File

@@ -0,0 +1,647 @@
/*
* $Id$
*
* Copyright (c) 2006 VeriSign. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* 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
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package com.verisignlabs.dnssec.security;
import java.math.BigInteger;
import java.security.*;
import java.security.spec.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Set;
import java.util.logging.Logger;
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
* usable java implementations.
*
* Besides centralizing the logic surrounding matching a DNSKEY algorithm
* identifier with various crypto implementations, it also handles algorithm
* aliasing -- that is, defining a new algorithm identifier to be equivalent to
* an existing identifier.
*
* @author David Blacka (orig)
* @author $Author: davidb $ (latest)
* @version $Revision: 2098 $
*/
public class DnsKeyAlgorithm
{
// Our base algorithm numbers. This is a normalization of the DNSSEC
// algorithms (which are really signature algorithms). Thus RSASHA1,
// RSASHA256, etc. all boil down to 'RSA' here.
public static final int UNKNOWN = -1;
public static final int RSA = 1;
public static final int DH = 2;
public static final int DSA = 3;
public static final int ECC_GOST = 4;
public static final int ECDSA = 5;
public static final int EDDSA = 6;
private static class AlgEntry
{
public int dnssecAlgorithm;
public String sigName;
public int baseType;
public AlgEntry(int algorithm, String sigName, int baseType)
{
this.dnssecAlgorithm = algorithm;
this.sigName = sigName;
this.baseType = baseType;
}
}
private static class ECAlgEntry extends AlgEntry
{
public ECParameterSpec ec_spec;
public ECAlgEntry(int algorithm, String sigName, int baseType, ECParameterSpec spec)
{
super(algorithm, sigName, baseType);
this.ec_spec = spec;
}
}
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
* data needed to map the algorithm to the various crypto implementations.
*/
private HashMap<Integer, AlgEntry> mAlgorithmMap;
/**
* This is a mapping of algorithm mnemonics to algorithm identifiers.
*/
private HashMap<String, Integer> mMnemonicToIdMap;
/**
* This is a mapping of identifiers to preferred mnemonic -- the preferred one
* is the first defined one
*/
private HashMap<Integer, String> mIdToMnemonicMap;
/** This is a cached key pair generator for RSA keys. */
private KeyPairGenerator mRSAKeyGenerator;
/** This is a cached key pair generator for DSA keys. */
private KeyPairGenerator mDSAKeyGenerator;
/** This is a cached key pair generator for ECC GOST keys. */
private KeyPairGenerator mECGOSTKeyGenerator;
/** This is a cached key pair generator for ECDSA_P256 keys. */
private KeyPairGenerator mECKeyGenerator;
/** This is a cached key pair generator for EdDSA keys. */
private KeyPairGenerator mEdKeyGenerator;
private Logger log = Logger.getLogger(this.getClass().toString());
/** This is the global instance for this class. */
private static DnsKeyAlgorithm mInstance = null;
public DnsKeyAlgorithm()
{
// Attempt to add the bouncycastle provider.
// This is so we can use this provider if it is available, but not require
// the user to add it as one of the java.security providers.
try
{
Class<?> bc_provider_class = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider");
Provider bc_provider = (Provider) bc_provider_class.newInstance();
Security.addProvider(bc_provider);
}
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();
}
private void initialize()
{
mAlgorithmMap = new HashMap<Integer, AlgEntry>();
mMnemonicToIdMap = new HashMap<String, Integer>();
mIdToMnemonicMap = new HashMap<Integer, String>();
// Load the standard DNSSEC algorithms.
addAlgorithm(DNSSEC.Algorithm.RSAMD5, "MD5withRSA", RSA);
addMnemonic("RSAMD5", DNSSEC.Algorithm.RSAMD5);
addAlgorithm(DNSSEC.Algorithm.DH, "", DH);
addMnemonic("DH", DNSSEC.Algorithm.DH);
addAlgorithm(DNSSEC.Algorithm.DSA, "SHA1withDSA", DSA);
addMnemonic("DSA", DNSSEC.Algorithm.DSA);
addAlgorithm(DNSSEC.Algorithm.RSASHA1, "SHA1withRSA", RSA);
addMnemonic("RSASHA1", DNSSEC.Algorithm.RSASHA1);
addMnemonic("RSA", DNSSEC.Algorithm.RSASHA1);
// Load the (now) standard aliases
addAlias(DNSSEC.Algorithm.DSA_NSEC3_SHA1, "DSA-NSEC3-SHA1", DNSSEC.Algorithm.DSA);
addAlias(DNSSEC.Algorithm.RSA_NSEC3_SHA1, "RSA-NSEC3-SHA1", DNSSEC.Algorithm.RSASHA1);
// Also recognize the BIND 9.6 mnemonics
addMnemonic("NSEC3DSA", DNSSEC.Algorithm.DSA_NSEC3_SHA1);
addMnemonic("NSEC3RSASHA1", DNSSEC.Algorithm.RSA_NSEC3_SHA1);
// Algorithms added by RFC 5702.
addAlgorithm(DNSSEC.Algorithm.RSASHA256, "SHA256withRSA", RSA);
addMnemonic("RSASHA256", DNSSEC.Algorithm.RSASHA256);
addAlgorithm(DNSSEC.Algorithm.RSASHA512, "SHA512withRSA", RSA);
addMnemonic("RSASHA512", DNSSEC.Algorithm.RSASHA512);
// ECC-GOST is not supported by Java 1.8's Sun crypto provider. The
// bouncycastle.org provider, however, does support it.
// GostR3410-2001-CryptoPro-A is the named curve in the BC provider, but we
// will get the parameters directly.
addAlgorithm(DNSSEC.Algorithm.ECC_GOST, "GOST3411withECGOST3410", ECC_GOST, null);
addMnemonic("ECCGOST", DNSSEC.Algorithm.ECC_GOST);
addMnemonic("ECC-GOST", DNSSEC.Algorithm.ECC_GOST);
addAlgorithm(DNSSEC.Algorithm.ECDSAP256SHA256, "SHA256withECDSA", ECDSA, "secp256r1");
addMnemonic("ECDSAP256SHA256", DNSSEC.Algorithm.ECDSAP256SHA256);
addMnemonic("ECDSA-P256", DNSSEC.Algorithm.ECDSAP256SHA256);
addAlgorithm(DNSSEC.Algorithm.ECDSAP384SHA384, "SHA384withECDSA", ECDSA, "secp384r1");
addMnemonic("ECDSAP384SHA384", 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)
{
mAlgorithmMap.put(algorithm, new AlgEntry(algorithm, sigName, baseType));
}
private void addAlgorithm(int algorithm, String sigName, int baseType, String curveName)
{
if (baseType == ECDSA)
{
ECParameterSpec ec_spec = ECSpecFromAlgorithm(algorithm);
if (ec_spec == null) ec_spec = ECSpecFromName(curveName);
if (ec_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;
}
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);
}
}
private void addMnemonic(String m, int alg)
{
// Do not add mnemonics for algorithms that ended up not actually being supported.
if (!mAlgorithmMap.containsKey(alg)) return;
mMnemonicToIdMap.put(m.toUpperCase(), alg);
if (!mIdToMnemonicMap.containsKey(alg))
{
mIdToMnemonicMap.put(alg, m);
}
}
public void addAlias(int alias, String mnemonic, int original_algorithm)
{
if (mAlgorithmMap.containsKey(alias))
{
log.warning("Unable to alias algorithm " + alias + " because it already exists.");
return;
}
if (!mAlgorithmMap.containsKey(original_algorithm))
{
log.warning("Unable to alias algorithm " + alias
+ " to unknown algorithm identifier " + original_algorithm);
return;
}
mAlgorithmMap.put(alias, mAlgorithmMap.get(original_algorithm));
if (mnemonic != null)
{
addMnemonic(mnemonic, alias);
}
}
private AlgEntry getEntry(int alg)
{
return mAlgorithmMap.get(alg);
}
// For curves where we don't (or can't) get the parameters from a standard
// name, we can construct the parameters here. For now, we only do this for
// the ECC-GOST curve.
private ECParameterSpec ECSpecFromAlgorithm(int algorithm)
{
switch (algorithm)
{
case DNSSEC.Algorithm.ECC_GOST:
{
// From RFC 4357 Section 11.4
BigInteger p = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", 16);
BigInteger a = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94", 16);
BigInteger b = new BigInteger("A6", 16);
BigInteger gx = new BigInteger("1", 16);
BigInteger gy = new BigInteger("8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14", 16);
BigInteger n = new BigInteger( "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893", 16);
EllipticCurve curve = new EllipticCurve(new ECFieldFp(p), a, b);
return new ECParameterSpec(curve, new ECPoint(gx, gy), n, 1);
}
default:
return null;
}
}
// Fetch the curve parameters from a named ECDSA curve.
private ECParameterSpec ECSpecFromName(String stdName)
{
try
{
AlgorithmParameters ap = AlgorithmParameters.getInstance("EC");
ECGenParameterSpec ecg_spec = new ECGenParameterSpec(stdName);
ap.init(ecg_spec);
return ap.getParameterSpec(ECParameterSpec.class);
}
catch (NoSuchAlgorithmException e) {
log.info("Elliptic Curve not supported by any crypto provider: " + e.getMessage());
}
catch (InvalidParameterSpecException e) {
log.info("Elliptic Curve " + stdName + " not supported");
}
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()
{
Set<Integer> keyset = mAlgorithmMap.keySet();
Integer[] algs = keyset.toArray(new Integer[keyset.size()]);
Arrays.sort(algs);
String[] result = new String[algs.length];
for (int i = 0; i < algs.length; i++)
{
result[i] = mIdToMnemonicMap.get(algs[i]);
}
return result;
}
/**
* Return a Signature object for the specified DNSSEC algorithm.
* @param algorithm The DNSSEC algorithm (by number).
* @return a Signature object.
*/
public Signature getSignature(int algorithm)
{
AlgEntry entry = getEntry(algorithm);
if (entry == null) return null;
Signature s = null;
try
{
s = Signature.getInstance(entry.sigName);
}
catch (NoSuchAlgorithmException e)
{
log.severe("Unable to get signature implementation for algorithm " + algorithm
+ ": " + e);
}
return s;
}
/**
* Given one of the ECDSA algorithms (ECDSAP256SHA256, etc.) return
* the elliptic curve parameters.
*
* @param algorithm
* The DNSSEC algorithm number.
* @return The calculated JCA ECParameterSpec for that DNSSEC algorithm, or
* null if not a recognized/supported EC algorithm.
*/
public ECParameterSpec getEllipticCurveParams(int algorithm)
{
AlgEntry entry = getEntry(algorithm);
if (entry == null) return null;
if (!(entry instanceof ECAlgEntry)) return null;
ECAlgEntry ec_entry = (ECAlgEntry) entry;
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
* number
*
* @param algorithm
* a DNSSEC algorithm that may be an alias.
* @return -1 if the algorithm isn't recognised, the orignal algorithm number
* if it is.
*/
public int originalAlgorithm(int algorithm)
{
AlgEntry entry = getEntry(algorithm);
if (entry == null) return -1;
return entry.dnssecAlgorithm;
}
/**
* Test if a given algorithm is supported.
*
* @param algorithm The DNSSEC algorithm number.
* @return true if the algorithm is a recognized and supported algorithm or alias.
*/
public boolean supportedAlgorithm(int algorithm)
{
if (mAlgorithmMap.containsKey(algorithm)) return true;
return false;
}
/**
* Given an algorithm mnemonic, convert the mnemonic to a DNSSEC algorithm
* number.
*
* @param s
* The mnemonic string. This is case-insensitive.
* @return -1 if the mnemonic isn't recognized or supported, the algorithm
* number if it is.
*/
public int stringToAlgorithm(String s)
{
Integer alg = mMnemonicToIdMap.get(s.toUpperCase());
if (alg != null) return alg.intValue();
return -1;
}
/**
* Given a DNSSEC algorithm number, return the "preferred" mnemonic.
*
* @param algorithm
* A DNSSEC algorithm number.
* @return The preferred mnemonic string, or null if not supported or
* recognized.
*/
public String algToString(int algorithm)
{
return mIdToMnemonicMap.get(algorithm);
}
public int baseType(int algorithm)
{
AlgEntry entry = getEntry(algorithm);
if (entry != null) return entry.baseType;
return UNKNOWN;
}
public boolean isDSA(int algorithm)
{
return (baseType(algorithm) == DSA);
}
public KeyPair generateKeyPair(int algorithm, int keysize, boolean useLargeExp)
throws NoSuchAlgorithmException
{
KeyPair pair = null;
switch (baseType(algorithm))
{
case RSA:
{
if (mRSAKeyGenerator == null)
{
mRSAKeyGenerator = KeyPairGenerator.getInstance("RSA");
}
RSAKeyGenParameterSpec rsa_spec;
if (useLargeExp)
{
rsa_spec = new RSAKeyGenParameterSpec(keysize, RSAKeyGenParameterSpec.F4);
}
else
{
rsa_spec = new RSAKeyGenParameterSpec(keysize, RSAKeyGenParameterSpec.F0);
}
try
{
mRSAKeyGenerator.initialize(rsa_spec);
}
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 = mRSAKeyGenerator.generateKeyPair();
break;
}
case DSA:
{
if (mDSAKeyGenerator == null)
{
mDSAKeyGenerator = KeyPairGenerator.getInstance("DSA");
}
mDSAKeyGenerator.initialize(keysize);
pair = mDSAKeyGenerator.generateKeyPair();
break;
}
case ECC_GOST:
{
if (mECGOSTKeyGenerator == null)
{
mECGOSTKeyGenerator = KeyPairGenerator.getInstance("ECGOST3410");
}
ECParameterSpec ec_spec = getEllipticCurveParams(algorithm);
try
{
mECGOSTKeyGenerator.initialize(ec_spec);
}
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 = mECGOSTKeyGenerator.generateKeyPair();
break;
}
case ECDSA:
{
if (mECKeyGenerator == null)
{
mECKeyGenerator = KeyPairGenerator.getInstance("EC");
}
ECParameterSpec ec_spec = getEllipticCurveParams(algorithm);
try
{
mECKeyGenerator.initialize(ec_spec);
}
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 = mECKeyGenerator.generateKeyPair();
break;
}
case EDDSA:
{
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;
}
public KeyPair generateKeyPair(int algorithm, int keysize)
throws NoSuchAlgorithmException
{
return generateKeyPair(algorithm, keysize, false);
}
public static DnsKeyAlgorithm getInstance()
{
if (mInstance == null) mInstance = new DnsKeyAlgorithm();
return mInstance;
}
}

View File

@@ -27,15 +27,8 @@ import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.interfaces.DSAParams; import java.security.interfaces.*;
import java.security.interfaces.DSAPrivateKey; import java.security.spec.*;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import javax.crypto.interfaces.DHPrivateKey; import javax.crypto.interfaces.DHPrivateKey;
@@ -43,7 +36,13 @@ 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.DNSSECException; import org.xbill.DNS.DNSSEC.DNSSECException;
import org.xbill.DNS.Name; import org.xbill.DNS.Name;
import org.xbill.DNS.utils.base64; import org.xbill.DNS.utils.base64;
@@ -51,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$
@@ -61,14 +60,18 @@ public class DnsKeyConverter
private KeyFactory mRSAKeyFactory; private KeyFactory mRSAKeyFactory;
private KeyFactory mDSAKeyFactory; private KeyFactory mDSAKeyFactory;
private KeyFactory mDHKeyFactory; private KeyFactory mDHKeyFactory;
private KeyFactory mECKeyFactory;
private KeyFactory mEdKeyFactory;
private DnsKeyAlgorithm mAlgorithms;
public DnsKeyConverter() public DnsKeyConverter()
{ {
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)
@@ -76,28 +79,36 @@ public class DnsKeyConverter
{ {
if (pKeyRecord.getKey() == null) return null; if (pKeyRecord.getKey() == null) return null;
// For now, instead of re-implementing parseRecord (or adding this stuff // Because we have arbitrarily aliased algorithms, we need to possibly
// to DNSjava), we will just translate the algorithm back to a standard // translate the aliased algorithm back to the actual algorithm.
// algorithm. Note that this will unnecessarily convert RSAMD5 to RSASHA1.
DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance(); int originalAlgorithm = mAlgorithms.originalAlgorithm(pKeyRecord.getAlgorithm());
int standard_alg = algs.standardAlgorithm(pKeyRecord.getAlgorithm());
if (standard_alg <= 0) if (originalAlgorithm <= 0) throw new NoSuchAlgorithmException("DNSKEY algorithm "
throw new NoSuchAlgorithmException("DNSKEY algorithm " + pKeyRecord.getAlgorithm() + " is unrecognized");
+ pKeyRecord.getAlgorithm() + " is unrecognized");
if (pKeyRecord.getAlgorithm() != standard_alg) if (pKeyRecord.getAlgorithm() != originalAlgorithm)
{ {
pKeyRecord = new DNSKEYRecord(pKeyRecord.getName(), pKeyRecord = new DNSKEYRecord(pKeyRecord.getName(), pKeyRecord.getDClass(),
pKeyRecord.getDClass(),
pKeyRecord.getTTL(), pKeyRecord.getFlags(), pKeyRecord.getTTL(), pKeyRecord.getFlags(),
pKeyRecord.getProtocol(), standard_alg, pKeyRecord.getProtocol(), originalAlgorithm,
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)
@@ -106,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.
*/ */
@@ -114,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);
} }
@@ -124,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
/** /**
@@ -132,11 +169,9 @@ public class DnsKeyConverter
public PrivateKey convertEncodedPrivateKey(byte[] key, int algorithm) public PrivateKey convertEncodedPrivateKey(byte[] key, int algorithm)
{ {
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(key); PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(key);
DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance();
try try
{ {
switch (algs.baseType(algorithm)) switch (mAlgorithms.baseType(algorithm))
{ {
case DnsKeyAlgorithm.RSA: case DnsKeyAlgorithm.RSA:
return mRSAKeyFactory.generatePrivate(spec); return mRSAKeyFactory.generatePrivate(spec);
@@ -146,12 +181,17 @@ public class DnsKeyConverter
} }
catch (GeneralSecurityException e) catch (GeneralSecurityException e)
{ {
e.printStackTrace();
} }
return null; return null;
} }
private int parseInt(String s, int def) /**
* A simple wrapper for parsing integers; parse failures result in the
* supplied default.
*/
private static int parseInt(String s, int def)
{ {
try try
{ {
@@ -195,9 +235,8 @@ public class DnsKeyConverter
String[] toks = val.split("\\s", 2); String[] toks = val.split("\\s", 2);
val = toks[0]; val = toks[0];
int alg = parseInt(val, -1); int alg = parseInt(val, -1);
DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance();
switch (algs.baseType(alg)) switch (mAlgorithms.baseType(alg))
{ {
case DnsKeyAlgorithm.RSA: case DnsKeyAlgorithm.RSA:
return parsePrivateRSA(lines); return parsePrivateRSA(lines);
@@ -205,6 +244,12 @@ public class DnsKeyConverter
return parsePrivateDSA(lines); return parsePrivateDSA(lines);
case DnsKeyAlgorithm.DH: case DnsKeyAlgorithm.DH:
return parsePrivateDH(lines); return parsePrivateDH(lines);
case DnsKeyAlgorithm.ECC_GOST:
return parsePrivateECDSA(lines, alg);
case DnsKeyAlgorithm.ECDSA:
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);
} }
@@ -216,7 +261,7 @@ public class DnsKeyConverter
/** /**
* @return the value part of an "attribute:value" pair. The value is trimmed. * @return the value part of an "attribute:value" pair. The value is trimmed.
*/ */
private String value(String av) private static String value(String av)
{ {
if (av == null) return null; if (av == null) return null;
@@ -231,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.
*/ */
@@ -320,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.
*/ */
@@ -376,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.
*/ */
@@ -434,6 +479,114 @@ 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 parsePrivateECDSA(StringTokenizer lines, int algorithm)
throws NoSuchAlgorithmException
{
BigInteger s = 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: "))
{
s = new BigInteger(1, data);
}
}
if (mECKeyFactory == null)
{
mECKeyFactory = KeyFactory.getInstance("EC");
}
ECParameterSpec ec_spec = mAlgorithms.getEllipticCurveParams(algorithm);
if (ec_spec == null)
{
throw new NoSuchAlgorithmException("DNSSEC algorithm " + algorithm +
" is not a recognized Elliptic Curve algorithm");
}
KeySpec spec = new ECPrivateKeySpec(s, ec_spec);
try
{
return mECKeyFactory.generatePrivate(spec);
}
catch (InvalidKeySpecException e)
{
e.printStackTrace();
return null;
}
}
/**
* 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.
@@ -452,6 +605,14 @@ public class DnsKeyConverter
{ {
return generatePrivateDH((DHPrivateKey) priv, (DHPublicKey) pub, alg); return generatePrivateDH((DHPrivateKey) priv, (DHPublicKey) pub, alg);
} }
else if (priv instanceof ECPrivateKey && pub instanceof ECPublicKey)
{
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;
} }
@@ -459,7 +620,7 @@ public class DnsKeyConverter
/** /**
* Convert from 'unsigned' big integer to original 'signed format' in Base64 * Convert from 'unsigned' big integer to original 'signed format' in Base64
*/ */
private String b64BigInt(BigInteger i) private static String b64BigInt(BigInteger i)
{ {
byte[] orig_bytes = i.toByteArray(); byte[] orig_bytes = i.toByteArray();
@@ -482,10 +643,9 @@ public class DnsKeyConverter
{ {
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw); PrintWriter out = new PrintWriter(sw);
DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance();
out.println("Private-key-format: v1.2"); out.println("Private-key-format: v1.2");
out.println("Algorithm: " + algorithm + " (" + algs.algToString(algorithm) out.println("Algorithm: " + algorithm + " (" + mAlgorithms.algToString(algorithm)
+ ")"); + ")");
out.print("Modulus: "); out.print("Modulus: ");
out.println(b64BigInt(key.getModulus())); out.println(b64BigInt(key.getModulus()));
@@ -513,12 +673,11 @@ public class DnsKeyConverter
{ {
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw); PrintWriter out = new PrintWriter(sw);
DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance();
DHParameterSpec p = key.getParams(); DHParameterSpec p = key.getParams();
out.println("Private-key-format: v1.2"); out.println("Private-key-format: v1.2");
out.println("Algorithm: " + algorithm + " (" + algs.algToString(algorithm) out.println("Algorithm: " + algorithm + " (" + mAlgorithms.algToString(algorithm)
+ ")"); + ")");
out.print("Prime(p): "); out.print("Prime(p): ");
out.println(b64BigInt(p.getP())); out.println(b64BigInt(p.getP()));
@@ -538,12 +697,11 @@ public class DnsKeyConverter
{ {
StringWriter sw = new StringWriter(); StringWriter sw = new StringWriter();
PrintWriter out = new PrintWriter(sw); PrintWriter out = new PrintWriter(sw);
DnsKeyAlgorithm algs = DnsKeyAlgorithm.getInstance();
DSAParams p = key.getParams(); DSAParams p = key.getParams();
out.println("Private-key-format: v1.2"); out.println("Private-key-format: v1.2");
out.println("Algorithm: " + algorithm + " (" + algs.algToString(algorithm) out.println("Algorithm: " + algorithm + " (" + mAlgorithms.algToString(algorithm)
+ ")"); + ")");
out.print("Prime(p): "); out.print("Prime(p): ");
out.println(b64BigInt(p.getP())); out.println(b64BigInt(p.getP()));
@@ -558,4 +716,41 @@ public class DnsKeyConverter
return sw.toString(); return sw.toString();
} }
/**
* Given an elliptic curve key pair, and the actual algorithm (which will
* describe the curve used), return the BIND9-style text encoding.
*/
private String generatePrivateEC(ECPrivateKey priv, ECPublicKey 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(b64BigInt(priv.getS()));
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

@@ -211,6 +211,13 @@ public class DnsSecVerifier
} }
} }
if (rrset.getTTL() > sigrec.getOrigTTL())
{
log.fine("RRset's TTL is greater than the Signature's orignal TTL");
if (reasons != null) reasons.add("RRset TTL greater than RRSIG origTTL");
return false;
}
return true; return true;
} }
@@ -256,6 +263,12 @@ public class DnsSecVerifier
sig = SignUtils.convertDSASignature(sig); sig = SignUtils.convertDSASignature(sig);
} }
if (sigrec.getAlgorithm() == DNSSEC.Algorithm.ECDSAP256SHA256 ||
sigrec.getAlgorithm() == DNSSEC.Algorithm.ECDSAP384SHA384)
{
sig = SignUtils.convertECDSASignature(sig);
}
if (!signer.verify(sig)) if (!signer.verify(sig))
{ {
if (reasons != null) reasons.add("Signature failed to verify cryptographically"); if (reasons != null) reasons.add("Signature failed to verify cryptographically");
@@ -283,7 +296,6 @@ public class DnsSecVerifier
* *
* @return true if the set verified, false if it did not. * @return true if the set verified, false if it did not.
*/ */
@SuppressWarnings("unchecked")
public boolean verify(RRset rrset) public boolean verify(RRset rrset)
{ {
boolean result = mVerifyAllSigs ? true : false; boolean result = mVerifyAllSigs ? true : false;

View File

@@ -33,21 +33,16 @@ import java.util.List;
import java.util.ListIterator; import java.util.ListIterator;
import java.util.logging.Logger; import java.util.logging.Logger;
import org.xbill.DNS.DNSKEYRecord; import org.xbill.DNS.*;
import org.xbill.DNS.Name;
import org.xbill.DNS.RRSIGRecord;
import org.xbill.DNS.RRset;
import org.xbill.DNS.Record;
import org.xbill.DNS.Type;
import org.xbill.DNS.utils.hexdump; 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$
@@ -58,7 +53,7 @@ public class JCEDnsSecSigner
private DnsKeyConverter mKeyConverter; private DnsKeyConverter mKeyConverter;
private boolean mVerboseSigning = false; private boolean mVerboseSigning = false;
private Logger log; private Logger log = Logger.getLogger(this.getClass().toString());
public JCEDnsSecSigner() public JCEDnsSecSigner()
{ {
@@ -74,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
@@ -119,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
@@ -197,6 +192,12 @@ public class JCEDnsSecSigner
DSAPublicKey pk = (DSAPublicKey) pair.getPublic(); DSAPublicKey pk = (DSAPublicKey) pair.getPublic();
sig = SignUtils.convertDSASignature(pk.getParams(), sig); sig = SignUtils.convertDSASignature(pk.getParams(), sig);
} }
// Convert to RFC 6605, etc format
if (pair.getDNSKEYAlgorithm() == DNSSEC.Algorithm.ECDSAP256SHA256 ||
pair.getDNSKEYAlgorithm() == DNSSEC.Algorithm.ECDSAP384SHA384)
{
sig = SignUtils.convertECDSASignature(pair.getDNSKEYAlgorithm(), sig);
}
RRSIGRecord sigrec = SignUtils.generateRRSIG(sig, presig); RRSIGRecord sigrec = SignUtils.generateRRSIG(sig, presig);
if (mVerboseSigning) if (mVerboseSigning)
{ {
@@ -210,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
@@ -243,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
@@ -262,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")
@@ -323,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
@@ -362,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
*/ */
@@ -458,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
@@ -477,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.
*/ */
@@ -493,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
@@ -528,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
*/ */
@@ -557,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

@@ -429,6 +429,137 @@ public class SignUtils
return sig; return sig;
} }
// Given one of the ECDSA algorithms determine the "length", which is the
// length, in bytes, of both 'r' and 's' in the ECDSA signature.
private static int ecdsaLength(int algorithm) throws SignatureException
{
switch (algorithm)
{
case DNSSEC.Algorithm.ECDSAP256SHA256: return 32;
case DNSSEC.Algorithm.ECDSAP384SHA384: return 48;
default:
throw new SignatureException("Algorithm " + algorithm +
" is not a supported ECDSA signature algorithm.");
}
}
/**
* Convert a JCE standard ECDSA signature (which is a ASN.1 encoding) into a
* standard DNS signature.
*
* The format of the ASN.1 signature is
*
* ASN1_SEQ . seq_length . ASN1_INT . r_length . R . ANS1_INT . s_length . S
*
* where R and S may have a leading zero byte if without it the values would
* be negative.
*
* The format of the DNSSEC signature is just R . S where R and S are both
* exactly "length" bytes.
*
* @param signature
* The output of a ECDSA signature object.
* @return signature data formatted for use in DNSSEC.
* @throws SignatureException if the ASN.1 encoding appears to be corrupt.
*/
public static byte[] convertECDSASignature(int algorithm, byte[] signature)
throws SignatureException
{
int exp_length = ecdsaLength(algorithm);
byte[] sig = new byte[exp_length * 2];
if (signature[0] != ASN1_SEQ || signature[2] != ASN1_INT)
{
throw new SignatureException("Invalid ASN.1 signature format: expected SEQ, INT");
}
int r_len = signature[3];
int r_pos = 4;
if (signature[r_pos + r_len] != ASN1_INT)
{
throw new SignatureException("Invalid ASN.1 signature format: expected SEQ, INT, INT");
}
int s_pos = r_pos + r_len + 2;
int s_len = signature[r_pos + r_len + 1];
// Adjust for leading zeros on both R and S
if (signature[r_pos] == 0) {
r_pos++;
r_len--;
}
if (signature[s_pos] == 0) {
s_pos++;
s_len--;
}
System.arraycopy(signature, r_pos, sig, 0 + (exp_length - r_len), r_len);
System.arraycopy(signature, s_pos, sig, exp_length + (exp_length - s_len), s_len);
return sig;
}
/**
* Convert a DNS standard ECDSA signature (defined in RFC 6605) into a
* JCE standard ECDSA signature, which is encoded in ASN.1.
*
* The format of the ASN.1 signature is
*
* ASN1_SEQ . seq_length . ASN1_INT . r_length . R . ANS1_INT . s_length . S
*
* where R and S may have a leading zero byte if without it the values would
* be negative.
*
* The format of the DNSSEC signature is just R . S where R and S are both
* exactly "length" bytes.
*
* @param signature
* The binary signature data from an RRSIG record.
* @return signature data that may be used in a JCE Signature object for
* verification purposes.
*/
public static byte[] convertECDSASignature(byte[] signature)
{
byte r_src_pos, r_src_len, r_pad, s_src_pos, s_src_len, s_pad, len;
r_src_len = s_src_len = (byte) (signature.length / 2);
r_src_pos = 0; r_pad = 0;
s_src_pos = (byte) (r_src_pos + r_src_len); s_pad = 0;
len = (byte) (6 + r_src_len + s_src_len);
// leading zeroes are forbidden
while (signature[r_src_pos] == 0 && r_src_len > 0) {
r_src_pos++; r_src_len--; len--;
}
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++;
}
byte[] sig = new byte[len];
byte pos = 0;
sig[pos++] = ASN1_SEQ;
sig[pos++] = (byte) (len - 2);
sig[pos++] = ASN1_INT;
sig[pos++] = (byte) (r_src_len + r_pad);
pos += r_pad;
System.arraycopy(signature, r_src_pos, sig, pos, r_src_len);
pos += r_src_len;
sig[pos++] = ASN1_INT;
sig[pos++] = (byte) (s_src_len + s_pad);
pos += s_pad;
System.arraycopy(signature, s_src_pos, sig, pos, s_src_len);
return sig;
}
/** /**
* This is a convenience routine to help us classify records/RRsets. * This is a convenience routine to help us classify records/RRsets.
* *

View File

@@ -136,7 +136,8 @@ public class ZoneVerifier
return true; return true;
} }
for (Iterator i = rrset.rrs(); i.hasNext(); ) Iterator i = (rr instanceof RRSIGRecord) ? rrset.sigs() : rrset.rrs();
for ( ; i.hasNext(); )
{ {
Record record = (Record) i.next(); Record record = (Record) i.next();
if (rr.equals(record)) return false; if (rr.equals(record)) return false;
@@ -276,6 +277,11 @@ public class ZoneVerifier
// All RRs at the zone apex are normal // All RRs at the zone apex are normal
if (n.equals(mZoneName)) return NodeType.NORMAL; if (n.equals(mZoneName)) return NodeType.NORMAL;
// If the node is not below the zone itself, we will treat it as glue (it is really junk).
if (!n.subdomain(mZoneName))
{
return NodeType.GLUE;
}
// If the node is below a zone cut (either a delegation or DNAME), it is // If the node is below a zone cut (either a delegation or DNAME), it is
// glue. // glue.
if (last_cut != null && n.subdomain(last_cut) && !n.equals(last_cut)) if (last_cut != null && n.subdomain(last_cut) && !n.equals(last_cut))