GordianSignatureAlgId.java
/*
* GordianKnot: Security Suite
* Copyright 2012-2026. Tony Washer
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package io.github.tonywasher.joceanus.gordianknot.impl.core.sign;
import io.github.tonywasher.joceanus.gordianknot.api.base.GordianLength;
import io.github.tonywasher.joceanus.gordianknot.api.digest.GordianDigestSpec;
import io.github.tonywasher.joceanus.gordianknot.api.digest.GordianDigestSpecBuilder;
import io.github.tonywasher.joceanus.gordianknot.api.digest.GordianDigestSubSpec.GordianDigestState;
import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianFalconSpec;
import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianKeyPair;
import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianKeyPairSpecBuilder;
import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianKeyPairType;
import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianMLDSASpec;
import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianMayoSpec;
import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianRSAModulus;
import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianSLHDSASpec;
import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianSnovaSpec;
import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianXMSSKeySpec;
import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianXMSSKeySpec.GordianXMSSDigestType;
import io.github.tonywasher.joceanus.gordianknot.api.sign.GordianSignatureFactory;
import io.github.tonywasher.joceanus.gordianknot.api.sign.GordianSignatureSpec;
import io.github.tonywasher.joceanus.gordianknot.api.sign.GordianSignatureSpecBuilder;
import io.github.tonywasher.joceanus.gordianknot.api.sign.GordianSignatureType;
import io.github.tonywasher.joceanus.gordianknot.impl.core.base.GordianASN1Util;
import io.github.tonywasher.joceanus.gordianknot.impl.core.base.GordianBaseFactory;
import io.github.tonywasher.joceanus.gordianknot.impl.core.keypair.GordianCompositeKeyPair;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
import org.bouncycastle.asn1.edec.EdECObjectIdentifiers;
import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
import org.bouncycastle.asn1.misc.MiscObjectIdentifiers;
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.RSASSAPSSparams;
import org.bouncycastle.asn1.rosstandart.RosstandartObjectIdentifiers;
import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* OID Manager for Signatures.
*/
public class GordianSignatureAlgId {
/**
* SignatureOID branch.
*/
private static final ASN1ObjectIdentifier SIGOID = GordianASN1Util.ASYMOID.branch("1");
/**
* Map of SignatureSpec to Identifier.
*/
private final Map<GordianSignatureSpec, AlgorithmIdentifier> theSpecMap;
/**
* Map of SignatureSpec to subTypeMap.
*/
private final Map<GordianSignatureSpec, Map<Object, AlgorithmIdentifier>> theSpecSubTypeMap;
/**
* Map of Identifier to SignatureSpec.
*/
private final Map<AlgorithmIdentifier, GordianSignatureSpec> theIdentifierMap;
/**
* The factory.
*/
private final GordianSignatureFactory theFactory;
/**
* Constructor.
*
* @param pFactory the factory
*/
GordianSignatureAlgId(final GordianBaseFactory pFactory) {
/* Create the maps */
theSpecMap = new HashMap<>();
theSpecSubTypeMap = new HashMap<>();
theIdentifierMap = new HashMap<>();
/* Access the asymFactory and digests */
theFactory = pFactory.getAsyncFactory().getSignatureFactory();
/* Populate with the public standards */
addRSASignatures();
addDSASignatures();
addECSignatures();
addSM2Signatures();
addGOSTSignatures();
addEdDSASignatures();
addPostQuantumSignatures();
/* Loop through the possible AsymKeys */
for (GordianKeyPairType myKeyType : GordianKeyPairType.values()) {
/* Ignore keyType if subTypes are used */
if (myKeyType.subTypeForSignatures()) {
continue;
}
/* Add any non-standard signatureSpecs */
addSignatures(myKeyType);
}
}
/**
* Obtain Identifier for SignatureSpec.
*
* @param pSpec the signatureSpec.
* @param pKeyPair the keyPair
* @return the Identifier
*/
AlgorithmIdentifier getIdentifierForSpecAndKeyPair(final GordianSignatureSpec pSpec,
final GordianKeyPair pKeyPair) {
/* Handle Composite keyPairs specially */
if (pSpec.getKeyPairType() == GordianKeyPairType.COMPOSITE) {
final GordianCompositeKeyPair myCompPair = (GordianCompositeKeyPair) pKeyPair;
final Iterator<GordianKeyPair> pairIterator = myCompPair.iterator();
final Iterator<GordianSignatureSpec> sigIterator = pSpec.signatureSpecIterator();
final ASN1EncodableVector ks = new ASN1EncodableVector();
while (sigIterator.hasNext()) {
ks.add(getIdentifierForSpecAndKeyPair(sigIterator.next(), pairIterator.next()));
}
return new AlgorithmIdentifier(MiscObjectIdentifiers.id_alg_composite, new DERSequence(ks));
}
/* If we need to use the subType */
if (pSpec.getKeyPairType().subTypeForSignatures()) {
/* Look up in the subKey map */
final Map<Object, AlgorithmIdentifier> myMap = theSpecSubTypeMap.get(pSpec);
return myMap == null
? null
: myMap.get(pKeyPair.getKeyPairSpec().getSubKeyType());
}
/* Look up in the standard map */
return theSpecMap.get(pSpec);
}
/**
* Obtain SignatureSpec for Identifier.
*
* @param pIdentifier the identifier.
* @return the signatureSpec (or null if not found)
*/
public GordianSignatureSpec getSpecForIdentifier(final AlgorithmIdentifier pIdentifier) {
/* Handle Composite keyPairs specially */
if (MiscObjectIdentifiers.id_alg_composite.equals(pIdentifier.getAlgorithm())) {
final List<GordianSignatureSpec> myList = new ArrayList<>();
final ASN1Sequence myAlgs = ASN1Sequence.getInstance(pIdentifier.getParameters());
final Enumeration<?> en = myAlgs.getObjects();
while (en.hasMoreElements()) {
myList.add(getSpecForIdentifier(AlgorithmIdentifier.getInstance(en.nextElement())));
}
return GordianSignatureSpecBuilder.composite(myList);
}
return theIdentifierMap.get(pIdentifier);
}
/**
* Add pair to maps.
*
* @param pSpec the signatureSpec
* @param pIdentifier the identifier
*/
private void addToMaps(final GordianSignatureSpec pSpec,
final AlgorithmIdentifier pIdentifier) {
theSpecMap.put(pSpec, pIdentifier);
theIdentifierMap.put(pIdentifier, pSpec);
}
/**
* Add pair to maps.
*
* @param pSpec the signatureSpec
* @param pSubType the subType
* @param pIdentifier the identifier
*/
private void addToMaps(final GordianSignatureSpec pSpec,
final Object pSubType,
final AlgorithmIdentifier pIdentifier) {
/* Access the relevant map */
final Map<Object, AlgorithmIdentifier> myMap = theSpecSubTypeMap.computeIfAbsent(pSpec, p -> new HashMap<>());
myMap.put(pSubType, pIdentifier);
theIdentifierMap.put(pIdentifier, pSpec);
}
/**
* Add RSA signatures.
*/
private void addRSASignatures() {
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PSSMGF1, GordianDigestSpecBuilder.sha1()),
new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS,
createPSSParams(OIWObjectIdentifiers.idSHA1, GordianLength.LEN_160)));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PSSMGF1, GordianDigestSpecBuilder.sha2(GordianLength.LEN_224)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS,
createPSSParams(NISTObjectIdentifiers.id_sha224, GordianLength.LEN_224)));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PSSMGF1, GordianDigestSpecBuilder.sha2(GordianLength.LEN_256)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS,
createPSSParams(NISTObjectIdentifiers.id_sha256, GordianLength.LEN_256)));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PSSMGF1, GordianDigestSpecBuilder.sha2(GordianLength.LEN_384)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS,
createPSSParams(NISTObjectIdentifiers.id_sha384, GordianLength.LEN_384)));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PSSMGF1, GordianDigestSpecBuilder.sha2(GordianLength.LEN_512)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS,
createPSSParams(NISTObjectIdentifiers.id_sha512, GordianLength.LEN_512)));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PSSMGF1, GordianDigestSpecBuilder.sha3(GordianLength.LEN_224)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS,
createPSSParams(NISTObjectIdentifiers.id_sha3_224, GordianLength.LEN_224)));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PSSMGF1, GordianDigestSpecBuilder.sha3(GordianLength.LEN_256)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS,
createPSSParams(NISTObjectIdentifiers.id_sha3_256, GordianLength.LEN_256)));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PSSMGF1, GordianDigestSpecBuilder.sha3(GordianLength.LEN_384)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS,
createPSSParams(NISTObjectIdentifiers.id_sha3_384, GordianLength.LEN_384)));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PSSMGF1, GordianDigestSpecBuilder.sha3(GordianLength.LEN_512)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS,
createPSSParams(NISTObjectIdentifiers.id_sha3_512, GordianLength.LEN_512)));
addPSS128Algorithms(GordianDigestSpecBuilder.sha2(GordianLength.LEN_224),
NISTObjectIdentifiers.id_sha224, GordianLength.LEN_224);
addPSS128Algorithms(GordianDigestSpecBuilder.sha2(GordianLength.LEN_256),
NISTObjectIdentifiers.id_sha256, GordianLength.LEN_256);
addPSS128Algorithms(GordianDigestSpecBuilder.sha2(GordianLength.LEN_384),
NISTObjectIdentifiers.id_sha384, GordianLength.LEN_384);
addPSS128Algorithms(GordianDigestSpecBuilder.sha2(GordianLength.LEN_512),
NISTObjectIdentifiers.id_sha512, GordianLength.LEN_512);
addPSS128Algorithms(GordianDigestSpecBuilder.sha3(GordianLength.LEN_224),
NISTObjectIdentifiers.id_sha3_224, GordianLength.LEN_224);
addPSS128Algorithms(GordianDigestSpecBuilder.sha3(GordianLength.LEN_256),
NISTObjectIdentifiers.id_sha3_256, GordianLength.LEN_256);
addPSS128Algorithms(GordianDigestSpecBuilder.sha3(GordianLength.LEN_384),
NISTObjectIdentifiers.id_sha3_384, GordianLength.LEN_384);
addPSS128Algorithms(GordianDigestSpecBuilder.sha3(GordianLength.LEN_512),
NISTObjectIdentifiers.id_sha3_512, GordianLength.LEN_512);
addPSS128Algorithms(GordianDigestSpecBuilder.shake128(),
NISTObjectIdentifiers.id_shake128_len, GordianLength.LEN_256);
addPSS256Algorithms(GordianDigestSpecBuilder.sha2(GordianLength.LEN_224),
NISTObjectIdentifiers.id_sha224, GordianLength.LEN_224);
addPSS256Algorithms(GordianDigestSpecBuilder.sha2(GordianLength.LEN_256),
NISTObjectIdentifiers.id_sha256, GordianLength.LEN_256);
addPSS256Algorithms(GordianDigestSpecBuilder.sha2(GordianLength.LEN_384),
NISTObjectIdentifiers.id_sha384, GordianLength.LEN_384);
addPSS256Algorithms(GordianDigestSpecBuilder.sha2(GordianLength.LEN_512),
NISTObjectIdentifiers.id_sha512, GordianLength.LEN_512);
addPSS256Algorithms(GordianDigestSpecBuilder.sha3(GordianLength.LEN_224),
NISTObjectIdentifiers.id_sha3_224, GordianLength.LEN_224);
addPSS256Algorithms(GordianDigestSpecBuilder.sha3(GordianLength.LEN_256),
NISTObjectIdentifiers.id_sha3_256, GordianLength.LEN_256);
addPSS256Algorithms(GordianDigestSpecBuilder.sha3(GordianLength.LEN_384),
NISTObjectIdentifiers.id_sha3_384, GordianLength.LEN_384);
addPSS256Algorithms(GordianDigestSpecBuilder.sha3(GordianLength.LEN_512),
NISTObjectIdentifiers.id_sha3_512, GordianLength.LEN_512);
addPSS256Algorithms(GordianDigestSpecBuilder.shake256(),
NISTObjectIdentifiers.id_shake256_len, GordianLength.LEN_512);
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.md2()),
new AlgorithmIdentifier(PKCSObjectIdentifiers.md2WithRSAEncryption, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.md4()),
new AlgorithmIdentifier(PKCSObjectIdentifiers.md4WithRSAEncryption, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.md5()),
new AlgorithmIdentifier(PKCSObjectIdentifiers.md5WithRSAEncryption, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.sha1()),
new AlgorithmIdentifier(PKCSObjectIdentifiers.sha1WithRSAEncryption, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.sha2(GordianLength.LEN_224)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.sha224WithRSAEncryption, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.sha2(GordianLength.LEN_256)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.sha256WithRSAEncryption, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.sha2(GordianLength.LEN_384)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.sha384WithRSAEncryption, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.sha2(GordianLength.LEN_512)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.sha512WithRSAEncryption, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.sha2(GordianDigestState.STATE512, GordianLength.LEN_224)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.sha512_224WithRSAEncryption, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.sha2(GordianDigestState.STATE512, GordianLength.LEN_256)),
new AlgorithmIdentifier(PKCSObjectIdentifiers.sha512_256WithRSAEncryption, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.sha3(GordianLength.LEN_224)),
new AlgorithmIdentifier(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_224, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.sha3(GordianLength.LEN_256)),
new AlgorithmIdentifier(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_256, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.sha3(GordianLength.LEN_384)),
new AlgorithmIdentifier(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_384, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.sha3(GordianLength.LEN_512)),
new AlgorithmIdentifier(NISTObjectIdentifiers.id_rsassa_pkcs1_v1_5_with_sha3_512, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.ripemd(GordianLength.LEN_128)),
new AlgorithmIdentifier(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.ripemd(GordianLength.LEN_160)),
new AlgorithmIdentifier(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PREHASH, GordianDigestSpecBuilder.ripemd(GordianLength.LEN_256)),
new AlgorithmIdentifier(TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256, DERNull.INSTANCE));
}
/**
* Add DSA signatures.
*/
private void addDSASignatures() {
addToMaps(GordianSignatureSpecBuilder.dsa(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha1()),
new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa_with_sha1, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.dsa(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha2(GordianLength.LEN_224)),
new AlgorithmIdentifier(NISTObjectIdentifiers.dsa_with_sha224, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.dsa(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha2(GordianLength.LEN_256)),
new AlgorithmIdentifier(NISTObjectIdentifiers.dsa_with_sha256, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.dsa(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha2(GordianLength.LEN_384)),
new AlgorithmIdentifier(NISTObjectIdentifiers.dsa_with_sha384, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.dsa(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha2(GordianLength.LEN_512)),
new AlgorithmIdentifier(NISTObjectIdentifiers.dsa_with_sha512, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.dsa(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha3(GordianLength.LEN_224)),
new AlgorithmIdentifier(NISTObjectIdentifiers.id_dsa_with_sha3_224, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.dsa(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha3(GordianLength.LEN_256)),
new AlgorithmIdentifier(NISTObjectIdentifiers.id_dsa_with_sha3_256, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.dsa(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha3(GordianLength.LEN_384)),
new AlgorithmIdentifier(NISTObjectIdentifiers.id_dsa_with_sha3_384, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.dsa(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha3(GordianLength.LEN_512)),
new AlgorithmIdentifier(NISTObjectIdentifiers.id_dsa_with_sha3_512, DERNull.INSTANCE));
}
/**
* Add EC signatures.
*/
private void addECSignatures() {
addToMaps(GordianSignatureSpecBuilder.ec(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha1()),
new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA1, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.ec(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha2(GordianLength.LEN_224)),
new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA224, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.ec(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha2(GordianLength.LEN_256)),
new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA256, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.ec(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha2(GordianLength.LEN_384)),
new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA384, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.ec(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha2(GordianLength.LEN_512)),
new AlgorithmIdentifier(X9ObjectIdentifiers.ecdsa_with_SHA512, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.ec(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha3(GordianLength.LEN_224)),
new AlgorithmIdentifier(NISTObjectIdentifiers.id_ecdsa_with_sha3_224, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.ec(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha3(GordianLength.LEN_256)),
new AlgorithmIdentifier(NISTObjectIdentifiers.id_ecdsa_with_sha3_256, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.ec(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha3(GordianLength.LEN_384)),
new AlgorithmIdentifier(NISTObjectIdentifiers.id_ecdsa_with_sha3_384, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.ec(GordianSignatureType.DSA, GordianDigestSpecBuilder.sha3(GordianLength.LEN_512)),
new AlgorithmIdentifier(NISTObjectIdentifiers.id_ecdsa_with_sha3_512, DERNull.INSTANCE));
}
/**
* Add SM2 signatures.
*/
private void addSM2Signatures() {
addToMaps(GordianSignatureSpecBuilder.sm2(GordianDigestSpecBuilder.sm3()),
new AlgorithmIdentifier(GMObjectIdentifiers.sm2sign_with_sm3, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.sm2(GordianDigestSpecBuilder.sha2(GordianLength.LEN_256)),
new AlgorithmIdentifier(GMObjectIdentifiers.sm2sign_with_sha256, DERNull.INSTANCE));
}
/**
* Add GOST signatures.
*/
private void addGOSTSignatures() {
addToMaps(GordianSignatureSpecBuilder.gost2012(GordianLength.LEN_256),
new AlgorithmIdentifier(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_256, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.gost2012(GordianLength.LEN_512),
new AlgorithmIdentifier(RosstandartObjectIdentifiers.id_tc26_signwithdigest_gost_3410_12_512, DERNull.INSTANCE));
}
/**
* Add EdDSA signatures.
*/
private void addEdDSASignatures() {
addToMaps(GordianSignatureSpecBuilder.edDSA(), GordianKeyPairSpecBuilder.ed25519(),
new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.edDSA(), GordianKeyPairSpecBuilder.ed448(),
new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448, DERNull.INSTANCE));
}
/**
* Add postQuantum signatures.
*/
private void addPostQuantumSignatures() {
/* Add Picnic signatures */
addToMaps(GordianSignatureSpecBuilder.picnic(),
new AlgorithmIdentifier(BCObjectIdentifiers.picnic_signature, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.picnic(GordianDigestSpecBuilder.sha2(GordianLength.LEN_512)),
new AlgorithmIdentifier(BCObjectIdentifiers.picnic_with_sha512, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.picnic(GordianDigestSpecBuilder.sha3(GordianLength.LEN_512)),
new AlgorithmIdentifier(BCObjectIdentifiers.picnic_with_sha3_512, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.picnic(GordianDigestSpecBuilder.shake256()),
new AlgorithmIdentifier(BCObjectIdentifiers.picnic_with_shake256, DERNull.INSTANCE));
/* Add LMS signatures */
addToMaps(GordianSignatureSpecBuilder.lms(),
new AlgorithmIdentifier(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig, DERNull.INSTANCE));
/* Add signatures that use keyPair id */
addMLDSASignatures();
addSLHDSASignatures();
addFalconSignatures();
addMayoSignatures();
addSnovaSignatures();
/* Add XMSS signatures */
addXMSSSignatures();
}
/**
* Add SLHDSA signatures.
*/
private void addMLDSASignatures() {
for (GordianMLDSASpec mySpec : GordianMLDSASpec.values()) {
addToMaps(GordianSignatureSpecBuilder.mldsa(), GordianKeyPairSpecBuilder.mldsa(mySpec).getSubKeyType(),
new AlgorithmIdentifier(mySpec.getIdentifier(), DERNull.INSTANCE));
}
}
/**
* Add SLHDSA signatures.
*/
private void addSLHDSASignatures() {
for (GordianSLHDSASpec mySpec : GordianSLHDSASpec.values()) {
addToMaps(GordianSignatureSpecBuilder.slhdsa(), GordianKeyPairSpecBuilder.slhdsa(mySpec).getSubKeyType(),
new AlgorithmIdentifier(mySpec.getIdentifier(), DERNull.INSTANCE));
}
}
/**
* Add Falcon signatures.
*/
private void addFalconSignatures() {
for (GordianFalconSpec mySpec : GordianFalconSpec.values()) {
addToMaps(GordianSignatureSpecBuilder.falcon(), GordianKeyPairSpecBuilder.falcon(mySpec).getSubKeyType(),
new AlgorithmIdentifier(mySpec.getIdentifier(), DERNull.INSTANCE));
}
}
/**
* Add Mayo signatures.
*/
private void addMayoSignatures() {
for (GordianMayoSpec mySpec : GordianMayoSpec.values()) {
addToMaps(GordianSignatureSpecBuilder.mayo(), GordianKeyPairSpecBuilder.mayo(mySpec).getSubKeyType(),
new AlgorithmIdentifier(mySpec.getIdentifier(), DERNull.INSTANCE));
}
}
/**
* Add Snova signatures.
*/
private void addSnovaSignatures() {
for (GordianSnovaSpec mySpec : GordianSnovaSpec.values()) {
addToMaps(GordianSignatureSpecBuilder.snova(), GordianKeyPairSpecBuilder.snova(mySpec).getSubKeyType(),
new AlgorithmIdentifier(mySpec.getIdentifier(), DERNull.INSTANCE));
}
}
/**
* Add XMSS signatures.
*/
private void addXMSSSignatures() {
/* List XMSS Sha256 signatures */
for (GordianXMSSKeySpec mySpec : GordianXMSSKeySpec.listPossibleKeySpecs(GordianXMSSDigestType.SHA256)) {
/* If this is an XMSSMT spec */
if (mySpec.isMT()) {
addToMaps(GordianSignatureSpecBuilder.xmss(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_mt_SHA256, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.xmssph(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_mt_SHA256ph, DERNull.INSTANCE));
} else {
addToMaps(GordianSignatureSpecBuilder.xmss(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_SHA256, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.xmssph(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_SHA256ph, DERNull.INSTANCE));
}
}
/* List XMSS Sha512 signatures */
for (GordianXMSSKeySpec mySpec : GordianXMSSKeySpec.listPossibleKeySpecs(GordianXMSSDigestType.SHA512)) {
/* If this is an XMSSMT spec */
if (mySpec.isMT()) {
addToMaps(GordianSignatureSpecBuilder.xmss(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_mt_SHA512, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.xmssph(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_mt_SHA512ph, DERNull.INSTANCE));
} else {
addToMaps(GordianSignatureSpecBuilder.xmss(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_SHA512, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.xmssph(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_SHA512ph, DERNull.INSTANCE));
}
}
/* List XMSS Shake128 signatures */
for (GordianXMSSKeySpec mySpec : GordianXMSSKeySpec.listPossibleKeySpecs(GordianXMSSDigestType.SHAKE128)) {
/* If this is an XMSSMT spec */
if (mySpec.isMT()) {
addToMaps(GordianSignatureSpecBuilder.xmss(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_mt_SHAKE128, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.xmssph(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_mt_SHAKE128ph, DERNull.INSTANCE));
} else {
addToMaps(GordianSignatureSpecBuilder.xmss(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_SHAKE128, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.xmssph(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_SHAKE128ph, DERNull.INSTANCE));
}
}
/* List XMSS Shake128 signatures */
for (GordianXMSSKeySpec mySpec : GordianXMSSKeySpec.listPossibleKeySpecs(GordianXMSSDigestType.SHAKE256)) {
/* If this is an XMSSMT spec */
if (mySpec.isMT()) {
addToMaps(GordianSignatureSpecBuilder.xmss(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_mt_SHAKE256, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.xmssph(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_mt_SHAKE256ph, DERNull.INSTANCE));
} else {
addToMaps(GordianSignatureSpecBuilder.xmss(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_SHAKE256, DERNull.INSTANCE));
addToMaps(GordianSignatureSpecBuilder.xmssph(), mySpec,
new AlgorithmIdentifier(BCObjectIdentifiers.xmss_SHAKE256ph, DERNull.INSTANCE));
}
}
}
/**
* Create PSS Parameters.
*
* @param pHash the hash algorithmId
* @param pSaltSize the saltSize
* @return the params
*/
private static RSASSAPSSparams createPSSParams(final ASN1ObjectIdentifier pHash,
final GordianLength pSaltSize) {
final AlgorithmIdentifier myId = new AlgorithmIdentifier(pHash, DERNull.INSTANCE);
return new RSASSAPSSparams(myId,
new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, myId),
new ASN1Integer(pSaltSize.getByteLength()),
new ASN1Integer(1));
}
/**
* Add PSS SHAKE128 Algorithms.
*
* @param pSpec the digestSpec
* @param pHash the hash algorithmId
* @param pSaltSize the saltSize
*/
private void addPSS128Algorithms(final GordianDigestSpec pSpec,
final ASN1ObjectIdentifier pHash,
final GordianLength pSaltSize) {
/* Loop through the RSAModulii */
for (GordianRSAModulus myModulus : GordianRSAModulus.values()) {
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PSS128, pSpec),
myModulus, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS,
createPSS128Params(pHash, myModulus, pSaltSize)));
}
}
/**
* Create PSS SHAKE128 Parameters.
*
* @param pHash the hash algorithmId
* @param pModulus the RSA modulus
* @param pSaltSize the saltSize
* @return the params
*/
private static RSASSAPSSparams createPSS128Params(final ASN1ObjectIdentifier pHash,
final GordianRSAModulus pModulus,
final GordianLength pSaltSize) {
final AlgorithmIdentifier myId = NISTObjectIdentifiers.id_shake128_len.equals(pHash)
? new AlgorithmIdentifier(pHash, new ASN1Integer(GordianLength.LEN_256.getByteLength()))
: new AlgorithmIdentifier(pHash, DERNull.INSTANCE);
final int myShakeLen = GordianLength.LEN_256.getLength();
final int myLen = (pModulus.getLength() - myShakeLen - Byte.SIZE) / Byte.SIZE;
return new RSASSAPSSparams(myId,
new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake128, new ASN1Integer(myLen)),
new ASN1Integer(pSaltSize.getByteLength()),
new ASN1Integer(1));
}
/**
* Add PSS SHAKE256 Algorithms.
*
* @param pSpec the digestSpec
* @param pHash the hash algorithmId
* @param pSaltSize the saltSize
*/
private void addPSS256Algorithms(final GordianDigestSpec pSpec,
final ASN1ObjectIdentifier pHash,
final GordianLength pSaltSize) {
/* Loop through the RSAModulii */
for (GordianRSAModulus myModulus : GordianRSAModulus.values()) {
addToMaps(GordianSignatureSpecBuilder.rsa(GordianSignatureType.PSS256, pSpec),
myModulus, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_RSASSA_PSS,
createPSS256Params(pHash, myModulus, pSaltSize)));
}
}
/**
* Create PSS SHAKE256 Parameters.
*
* @param pHash the hash algorithmId
* @param pModulus the RSA modulus
* @param pSaltSize the saltSize
* @return the params
*/
private static RSASSAPSSparams createPSS256Params(final ASN1ObjectIdentifier pHash,
final GordianRSAModulus pModulus,
final GordianLength pSaltSize) {
final AlgorithmIdentifier myId = NISTObjectIdentifiers.id_shake256_len.equals(pHash)
? new AlgorithmIdentifier(pHash, new ASN1Integer(GordianLength.LEN_512.getByteLength()))
: new AlgorithmIdentifier(pHash, DERNull.INSTANCE);
final int myShakeLen = GordianLength.LEN_512.getLength();
final int myLen = (pModulus.getLength() - myShakeLen - Byte.SIZE) / Byte.SIZE;
return new RSASSAPSSparams(myId,
new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256, new ASN1Integer(myLen)),
new ASN1Integer(pSaltSize.getByteLength()),
new ASN1Integer(1));
}
/**
* Create Identifiers for all valid SignatureTypes/DigestSpecs.
*
* @param pKeyType the keyType
*/
private void addSignatures(final GordianKeyPairType pKeyType) {
for (GordianSignatureSpec mySpec : theFactory.listAllSupportedSignatures(pKeyType)) {
ensureSignature(mySpec);
}
}
/**
* Add sigSpec to map if supported and not already present.
*
* @param pSigSpec the signatureSpec
*/
private void ensureSignature(final GordianSignatureSpec pSigSpec) {
/* If the signature is not already known */
if (!theSpecMap.containsKey(pSigSpec)) {
addSignature(pSigSpec);
}
}
/**
* Create Identifier for a signatureSpec.
*
* @param pSigSpec the signatureSpec
*/
private void addSignature(final GordianSignatureSpec pSigSpec) {
/* Create a branch for signatures based on the AsymKeyType */
final GordianKeyPairType myKeyType = pSigSpec.getKeyPairType();
ASN1ObjectIdentifier myId = SIGOID.branch(Integer.toString(myKeyType.ordinal() + 1));
/* Create a branch for signatures based on the SignatureType */
final GordianSignatureType mySigType = pSigSpec.getSignatureType();
myId = myId.branch(Integer.toString(mySigType.ordinal() + 1));
/* If we have a digestSpec */
if (pSigSpec.getSignatureSpec() instanceof GordianDigestSpec) {
/* Create a branch for digest based on the DigestType/Length/State */
final GordianDigestSpec myDigestSpec = pSigSpec.getDigestSpec();
myId = myId.branch(Integer.toString(myDigestSpec.getDigestType().ordinal() + 1));
myId = myId.branch(Integer.toString(myDigestSpec.getDigestLength().ordinal() + 1));
/* Add a branch if there is a state */
final GordianDigestState myState = myDigestSpec.getDigestState();
if (myState != null) {
myId = myId.branch(Integer.toString(myState.ordinal() + 1));
}
/* Add Xof indication */
myId = myId.branch(myDigestSpec.isXofMode() ? "1" : "2");
}
/* Add the id to the maps */
addToMaps(pSigSpec, new AlgorithmIdentifier(myId, DERNull.INSTANCE));
}
}