remove ECC-GOST, add new DS algorithms (#18)
This commit is contained in:
parent
1727d7c7d8
commit
1406cd2e68
@ -1,3 +1,12 @@
|
||||
2024-04-13 David Blacka <david@blacka.com>
|
||||
|
||||
* Remove support for ECC_GOST
|
||||
* Create a new DSAlgorithm class, move DS creation into that
|
||||
* Add support for DS algorithms 3 and 4 -- bouncycastle crypto
|
||||
provider used for DS algoirthm 3 (GOST R 34.11-94)
|
||||
* Moved support for loading the bouncycastle provider to the new
|
||||
DSAlgorithm class
|
||||
|
||||
2024-04-07 David Blacka <david@blacka.com>
|
||||
|
||||
* Released version 0.20
|
||||
|
@ -22,16 +22,14 @@ import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
import org.apache.commons.cli.Option;
|
||||
import org.xbill.DNS.CDSRecord;
|
||||
import org.xbill.DNS.DLVRecord;
|
||||
import org.xbill.DNS.DNSKEYRecord;
|
||||
import org.xbill.DNS.DNSSEC;
|
||||
import org.xbill.DNS.DSRecord;
|
||||
import org.xbill.DNS.Record;
|
||||
|
||||
import com.verisignlabs.dnssec.security.BINDKeyUtils;
|
||||
import com.verisignlabs.dnssec.security.DSAlgorithm;
|
||||
import com.verisignlabs.dnssec.security.DnsKeyPair;
|
||||
import com.verisignlabs.dnssec.security.SignUtils;
|
||||
|
||||
/**
|
||||
* This class forms the command line implementation of a DNSSEC DS/DLV generator
|
||||
@ -59,7 +57,6 @@ public class DSTool extends CLBase {
|
||||
* state.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Set up the command line options.
|
||||
*
|
||||
@ -68,8 +65,11 @@ public class DSTool extends CLBase {
|
||||
protected void setupOptions() {
|
||||
opts.addOption(Option.builder("D").longOpt("dlv").desc("Generate a DLV record instead.").build());
|
||||
opts.addOption(Option.builder("C").longOpt("cds").desc("Generate a CDS record instead").build());
|
||||
String[] algStrings = DSAlgorithm.getInstance().supportedAlgorithmMnemonics();
|
||||
String algStringSet = String.join(" | ", algStrings);
|
||||
opts.addOption(
|
||||
Option.builder("d").hasArg().argName("id").longOpt("digest").desc("The digest algorithm to use").build());
|
||||
Option.builder("d").hasArg().argName("id").longOpt("digest").desc(algStringSet + ": default is SHA256")
|
||||
.build());
|
||||
opts.addOption(Option.builder("f").hasArg().argName("file").longOpt("output").desc("output to file").build());
|
||||
opts.addOption(Option.builder("T").longOpt("ttl").hasArg().desc("TTL to use for generated DS/CDS record").build());
|
||||
}
|
||||
@ -99,6 +99,7 @@ public class DSTool extends CLBase {
|
||||
}
|
||||
|
||||
public void createDS(String keyname) throws IOException {
|
||||
DSAlgorithm dsAlgorithm = DSAlgorithm.getInstance();
|
||||
DnsKeyPair key = BINDKeyUtils.loadKey(keyname, null);
|
||||
DNSKEYRecord dnskey = key.getDNSKEYRecord();
|
||||
|
||||
@ -107,21 +108,17 @@ public class DSTool extends CLBase {
|
||||
}
|
||||
|
||||
long ttl = dsTTL < 0 ? dnskey.getTTL() : dsTTL;
|
||||
DSRecord ds = SignUtils.calculateDSRecord(dnskey, digestId, ttl);
|
||||
DSRecord ds = dsAlgorithm.calculateDSRecord(dnskey, digestId, ttl);
|
||||
Record res;
|
||||
|
||||
switch (createType) {
|
||||
case DLV:
|
||||
log.fine("creating DLV.");
|
||||
DLVRecord dlv = new DLVRecord(ds.getName(), ds.getDClass(), ds.getTTL(), ds.getFootprint(), ds.getAlgorithm(),
|
||||
ds.getDigestID(), ds.getDigest());
|
||||
res = dlv;
|
||||
res = dsAlgorithm.dsToDLV(ds);
|
||||
break;
|
||||
case CDS:
|
||||
log.fine("creating CDS.");
|
||||
CDSRecord cds = new CDSRecord(ds.getName(), ds.getDClass(), ds.getTTL(), ds.getFootprint(), ds.getAlgorithm(),
|
||||
ds.getDClass(), ds.getDigest());
|
||||
res = cds;
|
||||
res = dsAlgorithm.dstoCDS(ds);
|
||||
break;
|
||||
default:
|
||||
res = ds;
|
||||
@ -138,7 +135,7 @@ public class DSTool extends CLBase {
|
||||
}
|
||||
|
||||
public void execute() throws Exception {
|
||||
for (String keyname : keynames){
|
||||
for (String keyname : keynames) {
|
||||
createDS(keyname);
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ public class KeyGen extends CLBase {
|
||||
String[] algStrings = DnsKeyAlgorithm.getInstance().supportedAlgMnemonics();
|
||||
String algStringSet = String.join(" | ", algStrings);
|
||||
opts.addOption(Option.builder("a").hasArg().argName("algorithm")
|
||||
.desc(algStringSet + " | alias, ECDSAP256SHA256 is default.").build());
|
||||
.desc(algStringSet + " | aliases, ECDSAP256SHA256 is default.").build());
|
||||
|
||||
opts.addOption(Option.builder("b").hasArg().argName("size").desc(
|
||||
"key size, in bits (default 2048). RSA: [512..4096], DSA: [512..1024], DH: [128..4096], ECDSA: ignored, EdDSA: ignored")
|
||||
|
@ -134,8 +134,7 @@ public class BINDKeyUtils {
|
||||
public static DnsKeyPair loadKeyPair(String keyFileBasePath, File inDirectory)
|
||||
throws IOException {
|
||||
keyFileBasePath = fixKeyFileBasePath(keyFileBasePath);
|
||||
// FIXME: should we throw the IOException when one of the files
|
||||
// cannot be found, or just when both cannot be found?
|
||||
|
||||
File publicKeyFile = new File(inDirectory, keyFileBasePath + ".key");
|
||||
File privateKeyFile = new File(inDirectory, keyFileBasePath + ".private");
|
||||
|
||||
@ -251,8 +250,6 @@ public class BINDKeyUtils {
|
||||
if (privateKeyString == null)
|
||||
return null;
|
||||
|
||||
// FIXME: should this swallow exceptions or actually propagate
|
||||
// them?
|
||||
try {
|
||||
DnsKeyConverter conv = new DnsKeyConverter();
|
||||
return conv.parsePrivateKeyString(privateKeyString);
|
||||
|
167
src/main/java/com/verisignlabs/dnssec/security/DSAlgorithm.java
Normal file
167
src/main/java/com/verisignlabs/dnssec/security/DSAlgorithm.java
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2022 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.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.xbill.DNS.CDSRecord;
|
||||
import org.xbill.DNS.DLVRecord;
|
||||
import org.xbill.DNS.DNSKEYRecord;
|
||||
import org.xbill.DNS.DNSOutput;
|
||||
import org.xbill.DNS.DNSSEC;
|
||||
import org.xbill.DNS.DSRecord;
|
||||
|
||||
/**
|
||||
* This class handles the implementation behind converting DNSKEYs into
|
||||
* DSRecords. It primarily exists to bootstrap whatever crypto libraries we
|
||||
* might need to do so.
|
||||
*
|
||||
* @author David Blacka
|
||||
*/
|
||||
public class DSAlgorithm {
|
||||
|
||||
private Logger log = Logger.getLogger(this.getClass().toString());
|
||||
|
||||
HashSet<Integer> mSupportedAlgorithms = null;
|
||||
|
||||
private static DSAlgorithm mInstance = null;
|
||||
|
||||
public DSAlgorithm() {
|
||||
mSupportedAlgorithms = new HashSet<>();
|
||||
mSupportedAlgorithms.add(DNSSEC.Digest.SHA1);
|
||||
mSupportedAlgorithms.add(DNSSEC.Digest.SHA256);
|
||||
mSupportedAlgorithms.add(DNSSEC.Digest.SHA384);
|
||||
// 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<?> bcProviderClass = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider");
|
||||
Provider bcProvider = (Provider) bcProviderClass.getDeclaredConstructor().newInstance();
|
||||
Security.addProvider(bcProvider);
|
||||
log.fine("bouncycastle crypto provider loaded");
|
||||
mSupportedAlgorithms.add(DNSSEC.Digest.GOST3411);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
// do nothing, this is the normal case
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String[] supportedAlgorithmMnemonics() {
|
||||
ArrayList<String> algs = new ArrayList<>();
|
||||
|
||||
for (int digestId : mSupportedAlgorithms) {
|
||||
algs.add(DNSSEC.Digest.string(digestId));
|
||||
}
|
||||
|
||||
String[] result = new String[algs.size()];
|
||||
return algs.toArray(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a DNSKEY record, generate the DS record from it.
|
||||
*
|
||||
* @param keyrec the KEY record in question.
|
||||
* @param digestAlg The digest algorithm (SHA-1, SHA-256, etc.).
|
||||
* @param ttl the desired TTL for the generated DS record. If zero, or
|
||||
* negative, the original KEY RR's TTL will be used.
|
||||
* @return the corresponding {@link org.xbill.DNS.DSRecord}
|
||||
*/
|
||||
public DSRecord calculateDSRecord(DNSKEYRecord keyrec, int digestAlg, long ttl) {
|
||||
if (keyrec == null)
|
||||
return null;
|
||||
|
||||
if (ttl <= 0)
|
||||
ttl = keyrec.getTTL();
|
||||
|
||||
DNSOutput os = new DNSOutput();
|
||||
|
||||
os.writeByteArray(keyrec.getName().toWireCanonical());
|
||||
os.writeByteArray(keyrec.rdataToWireCanonical());
|
||||
|
||||
try {
|
||||
byte[] digest;
|
||||
MessageDigest md;
|
||||
|
||||
switch (digestAlg) {
|
||||
case DNSSEC.Digest.SHA1:
|
||||
md = MessageDigest.getInstance("SHA");
|
||||
digest = md.digest(os.toByteArray());
|
||||
break;
|
||||
case DNSSEC.Digest.SHA256:
|
||||
md = MessageDigest.getInstance("SHA-256");
|
||||
digest = md.digest(os.toByteArray());
|
||||
break;
|
||||
case DNSSEC.Digest.GOST3411:
|
||||
// The standard Java crypto providers don't have this, but bouncycastle does
|
||||
if (java.security.Security.getProviders("MessageDigest.GOST3411") != null) {
|
||||
md = MessageDigest.getInstance("GOST3411");
|
||||
digest = md.digest(os.toByteArray());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported digest id: " + digestAlg);
|
||||
}
|
||||
break;
|
||||
case DNSSEC.Digest.SHA384:
|
||||
md = MessageDigest.getInstance("SHA-384");
|
||||
digest = md.digest(os.toByteArray());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown digest id: " + digestAlg);
|
||||
}
|
||||
|
||||
return new DSRecord(keyrec.getName(), keyrec.getDClass(), ttl,
|
||||
keyrec.getFootprint(), keyrec.getAlgorithm(), digestAlg,
|
||||
digest);
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
log.severe(e.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public DLVRecord dsToDLV(DSRecord ds) {
|
||||
return new DLVRecord(ds.getName(), ds.getDClass(), ds.getTTL(), ds.getFootprint(), ds.getAlgorithm(),
|
||||
ds.getDigestID(), ds.getDigest());
|
||||
}
|
||||
|
||||
public CDSRecord dstoCDS(DSRecord ds) {
|
||||
return new CDSRecord(ds.getName(), ds.getDClass(), ds.getTTL(), ds.getFootprint(), ds.getAlgorithm(),
|
||||
ds.getDClass(), ds.getDigest());
|
||||
}
|
||||
|
||||
public static DSAlgorithm getInstance() {
|
||||
if (mInstance == null) {
|
||||
mInstance = new DSAlgorithm();
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
}
|
@ -27,20 +27,14 @@
|
||||
|
||||
package com.verisignlabs.dnssec.security;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.security.Signature;
|
||||
import java.security.spec.ECFieldFp;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.security.spec.ECParameterSpec;
|
||||
import java.security.spec.ECPoint;
|
||||
import java.security.spec.EllipticCurve;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import java.security.spec.NamedParameterSpec;
|
||||
import java.security.spec.RSAKeyGenParameterSpec;
|
||||
@ -73,7 +67,6 @@ public class DnsKeyAlgorithm {
|
||||
RSA,
|
||||
DH,
|
||||
DSA,
|
||||
ECC_GOST,
|
||||
ECDSA,
|
||||
EDDSA;
|
||||
}
|
||||
@ -129,12 +122,8 @@ public class DnsKeyAlgorithm {
|
||||
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());
|
||||
|
||||
@ -142,17 +131,6 @@ public class DnsKeyAlgorithm {
|
||||
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<?> bcProviderClass = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider");
|
||||
Provider bcProvider = (Provider) bcProviderClass.getDeclaredConstructor().newInstance();
|
||||
Security.addProvider(bcProvider);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
log.fine("Unable to load BC provider");
|
||||
}
|
||||
|
||||
initialize();
|
||||
}
|
||||
|
||||
@ -189,14 +167,6 @@ public class DnsKeyAlgorithm {
|
||||
addAlgorithm(DNSSEC.Algorithm.RSASHA512, "SHA512withRSA", BaseAlgorithm.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", BaseAlgorithm.ECC_GOST, null);
|
||||
addMnemonic("ECCGOST", DNSSEC.Algorithm.ECC_GOST);
|
||||
addMnemonic("ECC-GOST", DNSSEC.Algorithm.ECC_GOST);
|
||||
|
||||
addAlgorithm(DNSSEC.Algorithm.ECDSAP256SHA256, "SHA256withECDSA", BaseAlgorithm.ECDSA, "secp256r1");
|
||||
addMnemonic("ECDSAP256SHA256", DNSSEC.Algorithm.ECDSAP256SHA256);
|
||||
addMnemonic("ECDSA-P256", DNSSEC.Algorithm.ECDSAP256SHA256);
|
||||
@ -226,9 +196,7 @@ public class DnsKeyAlgorithm {
|
||||
* library (SunEC).
|
||||
*/
|
||||
private void addECDSAAlgorithm(int algorithm, String sigName, String curveName) {
|
||||
ECParameterSpec ecSpec = ECSpecFromAlgorithm(algorithm);
|
||||
if (ecSpec == null)
|
||||
ecSpec = ECSpecFromName(curveName);
|
||||
ECParameterSpec ecSpec = ECSpecFromName(curveName);
|
||||
if (ecSpec == null)
|
||||
return;
|
||||
|
||||
@ -278,10 +246,15 @@ public class DnsKeyAlgorithm {
|
||||
* @param curveName the name of the curve.
|
||||
*/
|
||||
private void addAlgorithm(int algorithm, String sigName, BaseAlgorithm baseType, String curveName) {
|
||||
if (baseType == BaseAlgorithm.ECDSA) {
|
||||
addECDSAAlgorithm(algorithm, sigName, curveName);
|
||||
} else if (baseType == BaseAlgorithm.EDDSA) {
|
||||
addEdDSAAlgorithm(algorithm, sigName, curveName);
|
||||
switch (baseType) {
|
||||
case ECDSA:
|
||||
addECDSAAlgorithm(algorithm, sigName, curveName);
|
||||
break;
|
||||
case EDDSA:
|
||||
addEdDSAAlgorithm(algorithm, sigName, curveName);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Non-Ellipic curve algorithm passed.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,25 +297,6 @@ public class DnsKeyAlgorithm {
|
||||
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) {
|
||||
if (algorithm == 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);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Fetch the curve parameters from a named ECDSA curve.
|
||||
private ECParameterSpec ECSpecFromName(String stdName) {
|
||||
try {
|
||||
@ -529,22 +483,6 @@ public class DnsKeyAlgorithm {
|
||||
pair = mDSAKeyGenerator.generateKeyPair();
|
||||
break;
|
||||
}
|
||||
case ECC_GOST: {
|
||||
if (mECGOSTKeyGenerator == null) {
|
||||
mECGOSTKeyGenerator = KeyPairGenerator.getInstance("ECGOST3410");
|
||||
}
|
||||
|
||||
ECParameterSpec ecSpec = getEllipticCurveParams(algorithm);
|
||||
try {
|
||||
mECGOSTKeyGenerator.initialize(ecSpec);
|
||||
} 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");
|
||||
@ -563,9 +501,9 @@ public class DnsKeyAlgorithm {
|
||||
}
|
||||
case EDDSA: {
|
||||
EdAlgEntry entry = (EdAlgEntry) getEntry(algorithm);
|
||||
mEdKeyGenerator = KeyPairGenerator.getInstance(entry.curveName);
|
||||
KeyPairGenerator edKeyGenerator = KeyPairGenerator.getInstance(entry.curveName);
|
||||
|
||||
pair = mEdKeyGenerator.generateKeyPair();
|
||||
pair = edKeyGenerator.generateKeyPair();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -201,8 +201,6 @@ public class DnsKeyConverter {
|
||||
return parsePrivateDSA(lines);
|
||||
case DH:
|
||||
return parsePrivateDH(lines);
|
||||
case ECC_GOST:
|
||||
return parsePrivateECDSA(lines, alg);
|
||||
case ECDSA:
|
||||
return parsePrivateECDSA(lines, alg);
|
||||
case EDDSA:
|
||||
|
@ -1317,6 +1317,8 @@ public class SignUtils {
|
||||
*/
|
||||
public static void generateDSRecords(Name zonename, List<Record> records, int digestAlg) {
|
||||
|
||||
DSAlgorithm dsAlgorithm = DSAlgorithm.getInstance();
|
||||
|
||||
for (ListIterator<Record> i = records.listIterator(); i.hasNext();) {
|
||||
Record r = i.next();
|
||||
if (r == null)
|
||||
@ -1328,7 +1330,7 @@ public class SignUtils {
|
||||
|
||||
// Convert non-zone level KEY records into DS records.
|
||||
if (r.getType() == Type.DNSKEY && !rName.equals(zonename)) {
|
||||
DSRecord ds = calculateDSRecord((DNSKEYRecord) r, digestAlg, r.getTTL());
|
||||
DSRecord ds = dsAlgorithm.calculateDSRecord((DNSKEYRecord) r, digestAlg, r.getTTL());
|
||||
|
||||
i.set(ds);
|
||||
}
|
||||
@ -1376,53 +1378,6 @@ public class SignUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a DNSKEY record, generate the DS record from it.
|
||||
*
|
||||
* @param keyrec the KEY record in question.
|
||||
* @param digestAlg The digest algorithm (SHA-1, SHA-256, etc.).
|
||||
* @param ttl the desired TTL for the generated DS record. If zero, or
|
||||
* negative, the original KEY RR's TTL will be used.
|
||||
* @return the corresponding {@link org.xbill.DNS.DSRecord}
|
||||
*/
|
||||
public static DSRecord calculateDSRecord(DNSKEYRecord keyrec, int digestAlg, long ttl) {
|
||||
if (keyrec == null)
|
||||
return null;
|
||||
|
||||
if (ttl <= 0)
|
||||
ttl = keyrec.getTTL();
|
||||
|
||||
DNSOutput os = new DNSOutput();
|
||||
|
||||
os.writeByteArray(keyrec.getName().toWireCanonical());
|
||||
os.writeByteArray(keyrec.rdataToWireCanonical());
|
||||
|
||||
try {
|
||||
byte[] digest;
|
||||
MessageDigest md;
|
||||
|
||||
switch (digestAlg) {
|
||||
case DNSSEC.Digest.SHA1:
|
||||
md = MessageDigest.getInstance("SHA");
|
||||
digest = md.digest(os.toByteArray());
|
||||
break;
|
||||
case DNSSEC.Digest.SHA256:
|
||||
md = MessageDigest.getInstance("SHA-256");
|
||||
digest = md.digest(os.toByteArray());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown digest id: " + digestAlg);
|
||||
}
|
||||
|
||||
return new DSRecord(keyrec.getName(), keyrec.getDClass(), ttl,
|
||||
keyrec.getFootprint(), keyrec.getAlgorithm(), digestAlg,
|
||||
digest);
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
log.severe(e.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate an NSEC3 hash based on a DNS name and NSEC3 hash parameters.
|
||||
|
Loading…
Reference in New Issue
Block a user