001/*
002 * Copyright 2015-2024 the original author or authors
003 *
004 * This software is licensed under the Apache License, Version 2.0,
005 * the GNU Lesser General Public License version 2 or later ("LGPL")
006 * and the WTFPL.
007 * You may choose either license to govern your use of this software only
008 * upon the condition that you accept all of the terms of either
009 * the Apache License 2.0, the LGPL 2.1+ or the WTFPL.
010 */
011package org.minidns.dnssec.algorithms;
012
013import org.minidns.constants.DnssecConstants.DigestAlgorithm;
014import org.minidns.constants.DnssecConstants.SignatureAlgorithm;
015import org.minidns.dnssec.DnssecValidatorInitializationException;
016import org.minidns.dnssec.DigestCalculator;
017import org.minidns.dnssec.SignatureVerifier;
018import org.minidns.record.NSEC3.HashAlgorithm;
019
020import java.security.NoSuchAlgorithmException;
021import java.util.HashMap;
022import java.util.Map;
023import java.util.logging.Level;
024import java.util.logging.Logger;
025
026public final class AlgorithmMap {
027    private Logger LOGGER = Logger.getLogger(AlgorithmMap.class.getName());
028
029    public static final AlgorithmMap INSTANCE = new AlgorithmMap();
030
031    private final Map<DigestAlgorithm, DigestCalculator> dsDigestMap = new HashMap<>();
032    private final Map<SignatureAlgorithm, SignatureVerifier> signatureMap = new HashMap<>();
033    private final Map<HashAlgorithm, DigestCalculator> nsecDigestMap = new HashMap<>();
034
035    @SuppressWarnings("deprecation")
036    private AlgorithmMap() {
037        try {
038            dsDigestMap.put(DigestAlgorithm.SHA1, new JavaSecDigestCalculator("SHA-1"));
039            nsecDigestMap.put(HashAlgorithm.SHA1, new JavaSecDigestCalculator("SHA-1"));
040        } catch (NoSuchAlgorithmException e) {
041            // SHA-1 is MANDATORY
042            throw new DnssecValidatorInitializationException("SHA-1 is mandatory", e);
043        }
044        try {
045            dsDigestMap.put(DigestAlgorithm.SHA256, new JavaSecDigestCalculator("SHA-256"));
046        } catch (NoSuchAlgorithmException e) {
047            // SHA-256 is MANDATORY
048            throw new DnssecValidatorInitializationException("SHA-256 is mandatory", e);
049        }
050
051        try {
052            dsDigestMap.put(DigestAlgorithm.SHA384, new JavaSecDigestCalculator("SHA-384"));
053        } catch (NoSuchAlgorithmException e) {
054            // SHA-384 is OPTIONAL
055            LOGGER.log(Level.FINE, "Platform does not support SHA-384", e);
056        }
057
058        try {
059            signatureMap.put(SignatureAlgorithm.RSAMD5, new RsaSignatureVerifier("MD5withRSA"));
060        } catch (NoSuchAlgorithmException e) {
061            // RSA/MD5 is DEPRECATED
062            LOGGER.log(Level.FINER, "Platform does not support RSA/MD5", e);
063        }
064        try {
065            DsaSignatureVerifier sha1withDSA = new DsaSignatureVerifier("SHA1withDSA");
066            signatureMap.put(SignatureAlgorithm.DSA, sha1withDSA);
067            signatureMap.put(SignatureAlgorithm.DSA_NSEC3_SHA1, sha1withDSA);
068        } catch (NoSuchAlgorithmException e) {
069            // DSA/SHA-1 is OPTIONAL
070            LOGGER.log(Level.FINE, "Platform does not support DSA/SHA-1", e);
071        }
072        try {
073            RsaSignatureVerifier sha1withRSA = new RsaSignatureVerifier("SHA1withRSA");
074            signatureMap.put(SignatureAlgorithm.RSASHA1, sha1withRSA);
075            signatureMap.put(SignatureAlgorithm.RSASHA1_NSEC3_SHA1, sha1withRSA);
076        } catch (NoSuchAlgorithmException e) {
077            throw new DnssecValidatorInitializationException("Platform does not support RSA/SHA-1", e);
078        }
079        try {
080            signatureMap.put(SignatureAlgorithm.RSASHA256, new RsaSignatureVerifier("SHA256withRSA"));
081        } catch (NoSuchAlgorithmException e) {
082            // RSA/SHA-256 is RECOMMENDED
083            LOGGER.log(Level.INFO, "Platform does not support RSA/SHA-256", e);
084        }
085        try {
086            signatureMap.put(SignatureAlgorithm.RSASHA512, new RsaSignatureVerifier("SHA512withRSA"));
087        } catch (NoSuchAlgorithmException e) {
088            // RSA/SHA-512 is RECOMMENDED
089            LOGGER.log(Level.INFO, "Platform does not support RSA/SHA-512", e);
090        }
091        try {
092            signatureMap.put(SignatureAlgorithm.ECC_GOST, new EcgostSignatureVerifier());
093        } catch (NoSuchAlgorithmException e) {
094            // GOST R 34.10-2001 is OPTIONAL
095            LOGGER.log(Level.FINE, "Platform does not support GOST R 34.10-2001", e);
096        }
097        try {
098            signatureMap.put(SignatureAlgorithm.ECDSAP256SHA256, new EcdsaSignatureVerifier.P256SHA256());
099        } catch (NoSuchAlgorithmException e) {
100            // ECDSA/SHA-256 is RECOMMENDED
101            LOGGER.log(Level.INFO, "Platform does not support ECDSA/SHA-256", e);
102        }
103        try {
104            signatureMap.put(SignatureAlgorithm.ECDSAP384SHA384, new EcdsaSignatureVerifier.P384SHA284());
105        } catch (NoSuchAlgorithmException e) {
106            // ECDSA/SHA-384 is RECOMMENDED
107            LOGGER.log(Level.INFO, "Platform does not support ECDSA/SHA-384", e);
108        }
109    }
110
111    public DigestCalculator getDsDigestCalculator(DigestAlgorithm algorithm) {
112        return dsDigestMap.get(algorithm);
113    }
114
115    public SignatureVerifier getSignatureVerifier(SignatureAlgorithm algorithm) {
116        return signatureMap.get(algorithm);
117    }
118
119    public DigestCalculator getNsecDigestCalculator(HashAlgorithm algorithm) {
120        return nsecDigestMap.get(algorithm);
121    }
122}