Skip to content

Commit

Permalink
DSS-2466 : sonar code smells review
Browse files Browse the repository at this point in the history
  • Loading branch information
pvandenbroucke committed Jul 9, 2021
1 parent 4cc5717 commit 5bdc4f0
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 188 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.Security;
import java.security.Signature;
Expand Down Expand Up @@ -169,17 +168,10 @@ protected SignatureValue ensureSignatureValue(SignatureAlgorithm targetSignature
}

if (EncryptionAlgorithm.ECDSA.isEquivalent(targetSignatureAlgorithm.getEncryptionAlgorithm())) {
try {
SignatureValue newSignatureValue = DSSUtils.convertECSignatureValue(targetSignatureAlgorithm, signatureValue);
LOG.info("The algorithm '{}' has been obtained from the SignatureValue. The SignatureValue converted to " +
"the expected algorithm '{}'.", signatureValue.getAlgorithm(), targetSignatureAlgorithm);
return newSignatureValue;

} catch (IOException e) {
throw new DSSException(String.format(
"An error occurred during the SignatureValue conversion. Reason : %s", e.getMessage()), e);
}

SignatureValue newSignatureValue = DSSUtils.convertECSignatureValue(targetSignatureAlgorithm, signatureValue);
LOG.info("The algorithm '{}' has been obtained from the SignatureValue. The SignatureValue converted to " +
"the expected algorithm '{}'.", signatureValue.getAlgorithm(), targetSignatureAlgorithm);
return newSignatureValue;
}
throw new DSSException(String.format("The SignatureAlgorithm within the SignatureValue '%s' " +
"does not match the expected value : '%s'. Conversion is not supported!",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ public class DSSJsonUtils {

/** Format date-time as specified in RFC 3339 5.6 */
private static final String DATE_TIME_FORMAT_RFC3339 = "yyyy-MM-dd'T'HH:mm:ss'Z'";

/** The URN OID prefix (RFC 3061) */
public static final String OID_NAMESPACE_PREFIX = "urn:oid:";

/**
* Copied from org.jose4j.base64url.internal.apache.commons.codec.binary.Base64
Expand Down Expand Up @@ -367,10 +370,43 @@ public static Digest getDigest(Map<?, ?> digestValueAndAlgo) {
* @return 'oid' {@link JsonObject}
*/
public static JsonObject getOidObject(ObjectIdentifier objectIdentifier) {
return getOidObject(DSSUtils.getUriOrUrnOid(objectIdentifier), objectIdentifier.getDescription(),
return getOidObject(getUriOrUrnOid(objectIdentifier), objectIdentifier.getDescription(),
objectIdentifier.getDocumentationReferences());
}

/**
* Returns URI if present, otherwise URN encoded OID (see RFC 3061)
* Returns NULL if non of them is present
*
* @param objectIdentifier {@link ObjectIdentifier} used to build an object of 'oid' type
* @return {@link String} URI
*/
public static String getUriOrUrnOid(ObjectIdentifier objectIdentifier) {
/*
* TS 119 182-1 : 5.4.1 The oId data type
* If both an OID and a URI exist identifying one object, the URI value should be used in the id member.
*/
String uri = objectIdentifier.getUri();
if (uri == null && objectIdentifier.getOid() != null) {
uri = toUrnOid(objectIdentifier.getOid());
}
return uri;
}

/**
* Returns a URN URI generated from the given OID:
*
* Ex.: OID = 1.2.4.5.6.8 becomes URI = urn:oid:1.2.4.5.6.8
*
* Note: see RFC 3061 "A URN Namespace of Object Identifiers"
*
* @param oid {@link String} to be converted to URN URI
* @return URI based on the algorithm's OID
*/
public static String toUrnOid(String oid) {
return OID_NAMESPACE_PREFIX + oid;
}

/**
* Creates an 'oid' JsonObject according to EN 119-182 ch. 5.4.1 The oId data type
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,16 @@
import eu.europa.esig.dss.service.http.commons.TimestampDataLoader;
import eu.europa.esig.dss.spi.DSSUtils;
import eu.europa.esig.dss.spi.client.http.NativeHTTPDataLoader;
import eu.europa.esig.dss.spi.exception.DSSExternalResourceException;
import eu.europa.esig.dss.spi.x509.tsp.CompositeTSPSource;
import eu.europa.esig.dss.spi.x509.tsp.TSPSource;
import eu.europa.esig.dss.utils.Utils;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import java.util.HashMap;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
Expand All @@ -41,6 +47,7 @@ public class OnlineTSPSourceTest {

private static final String TSA_URL = "http://dss.nowina.lu/pki-factory/tsa/good-tsa";
private static final String ED25519_TSA_URL = "http://dss.nowina.lu/pki-factory/tsa/Ed25519-good-tsa";
private static final String ERROR_500_TSA_URL = "http://dss.nowina.lu/pki-factory/tsa/error-500/good-tsa";

@Test
public void testWithoutNonce() {
Expand All @@ -52,6 +59,22 @@ public void testWithoutNonce() {
assertTrue(Utils.isArrayNotEmpty(timeStampResponse.getBytes()));
}

@Test
public void error500() {
OnlineTSPSource tspSource = new OnlineTSPSource(ERROR_500_TSA_URL);

byte[] digest = DSSUtils.digest(DigestAlgorithm.SHA1, "Hello world".getBytes());
assertThrows(DSSExternalResourceException.class, () -> tspSource.getTimeStampResponse(DigestAlgorithm.SHA1, digest));

Map<String, TSPSource> tspSources = new HashMap<>();
tspSources.put("A", tspSource);
tspSources.put("B", tspSource);

CompositeTSPSource compositeTSPSource = new CompositeTSPSource();
compositeTSPSource.setTspSources(tspSources);
assertThrows(DSSExternalResourceException.class, () -> compositeTSPSource.getTimeStampResponse(DigestAlgorithm.SHA1, digest));
}

@Test
public void testEd25519WithoutNonce() {
OnlineTSPSource tspSource = new OnlineTSPSource(ED25519_TSA_URL, new TimestampDataLoader());
Expand All @@ -77,7 +100,9 @@ public void testWithCommonDataLoader() {
public void testWithTimestampDataLoader() {
OnlineTSPSource tspSource = new OnlineTSPSource("http://demo.sk.ee/tsa/");
tspSource.setPolicyOid("0.4.0.2023.1.1");
tspSource.setDataLoader(new TimestampDataLoader()); // content-type is different
TimestampDataLoader dataLoader = new TimestampDataLoader();
assertThrows(UnsupportedOperationException.class, () -> dataLoader.setContentType("application/ocsp-request"));
tspSource.setDataLoader(dataLoader); // content-type is different

byte[] digest = DSSUtils.digest(DigestAlgorithm.SHA512, "Hello world".getBytes());
TimestampBinary timeStampResponse = tspSource.getTimeStampResponse(DigestAlgorithm.SHA512, digest);
Expand Down
80 changes: 0 additions & 80 deletions dss-spi/src/main/java/eu/europa/esig/dss/spi/DSSASN1Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.naming.ldap.Rdn;
import javax.security.auth.x500.X500Principal;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
Expand Down Expand Up @@ -971,85 +970,6 @@ public static Map<String, String> get(final X500Principal x500Principal) {
return treeMap;
}

/**
* This method normalizes the X500Principal object
*
* @param x500Principal
* to be normalized
* @return {@code X500Principal} normalized
*/
public static X500Principal getNormalizedX500Principal(final X500Principal x500Principal) {
final String utf8Name = DSSASN1Utils.getUtf8String(x500Principal);
return new X500Principal(utf8Name);
}

/**
* Gets the UTF-8 distinguished names of {@code X500Principal}
*
* @param x500Principal {@link X500Principal}
* @return {@link String} utf-8
*/
public static String getUtf8String(final X500Principal x500Principal) {

final byte[] encoded = x500Principal.getEncoded();
final ASN1Sequence asn1Sequence = ASN1Sequence.getInstance(encoded);
final ASN1Encodable[] asn1Encodables = asn1Sequence.toArray();
final StringBuilder stringBuilder = new StringBuilder();
/**
* RFC 4514 LDAP: Distinguished Names
* 2.1. Converting the RDNSequence
*
* If the RDNSequence is an empty sequence, the result is the empty or
* zero-length string.
*
* Otherwise, the output consists of the string encodings of each
* RelativeDistinguishedName in the RDNSequence (according to Section
* 2.2), starting with the last element of the sequence and moving
* backwards toward the first.
* ...
*/
for (int ii = asn1Encodables.length - 1; ii >= 0; ii--) {

final ASN1Encodable asn1Encodable = asn1Encodables[ii];

final DLSet dlSet = (DLSet) asn1Encodable;
for (int jj = 0; jj < dlSet.size(); jj++) {

final DLSequence dlSequence = (DLSequence) dlSet.getObjectAt(jj);
if (dlSequence.size() != 2) {

throw new DSSException("The DLSequence must contains exactly 2 elements.");
}
final ASN1Encodable attributeType = dlSequence.getObjectAt(0);
final ASN1Encodable attributeValue = dlSequence.getObjectAt(1);
String string = getString(attributeValue);

/**
* RFC 4514 LDAP: Distinguished Names
* ...
* Other characters may be escaped.
*
* Each octet of the character to be escaped is replaced by a backslash
* and two hex digits, which form a single octet in the code of the
* character. Alternatively, if and only if the character to be escaped
* is one of
*
* ' ', '"', '#', '+', ',', ';', '<', '=', '>', or '\'
* (U+0020, U+0022, U+0023, U+002B, U+002C, U+003B,
* U+003C, U+003D, U+003E, U+005C, respectively)
*
* it can be prefixed by a backslash ('\' U+005C).
*/
string = Rdn.escapeValue(string);
if (stringBuilder.length() != 0) {
stringBuilder.append(',');
}
stringBuilder.append(attributeType).append('=').append(string);
}
}
return stringBuilder.toString();
}

/**
* Reads the value
*
Expand Down
55 changes: 1 addition & 54 deletions dss-spi/src/main/java/eu/europa/esig/dss/spi/DSSUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,13 @@

import eu.europa.esig.dss.enumerations.DigestAlgorithm;
import eu.europa.esig.dss.enumerations.EncryptionAlgorithm;
import eu.europa.esig.dss.enumerations.ObjectIdentifier;
import eu.europa.esig.dss.enumerations.SignatureAlgorithm;
import eu.europa.esig.dss.enumerations.X520Attributes;
import eu.europa.esig.dss.model.DSSDocument;
import eu.europa.esig.dss.model.DSSException;
import eu.europa.esig.dss.model.Digest;
import eu.europa.esig.dss.model.InMemoryDocument;
import eu.europa.esig.dss.model.SignatureValue;
import eu.europa.esig.dss.model.identifier.EntityIdentifier;
import eu.europa.esig.dss.model.identifier.TokenIdentifier;
import eu.europa.esig.dss.model.x509.CertificateToken;
import eu.europa.esig.dss.utils.Utils;
Expand Down Expand Up @@ -83,7 +81,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
Expand All @@ -105,9 +102,6 @@ public final class DSSUtils {
/** Empty byte array */
public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];

/** The URN OID prefix (RFC 3061) */
public static final String OID_NAMESPACE_PREFIX = "urn:oid:";

/** The UTF-8 encoding name string */
public static final String UTF8_ENCODING = "UTF-8";

Expand Down Expand Up @@ -1086,19 +1080,6 @@ public static boolean isUrnOid(String id) {
return id != null && id.matches("^(?i)urn:oid:.*$");
}

/**
* Returns a URN URI generated from the given OID:
*
* Ex.: OID = 1.2.4.5.6.8 becomes URI = urn:oid:1.2.4.5.6.8
*
* Note: see RFC 3061 "A URN Namespace of Object Identifiers"
*
* @param oid {@link String} to be converted to URN URI
* @return URI based on the algorithm's OID
*/
public static String toUrnOid(String oid) {
return OID_NAMESPACE_PREFIX + oid;
}

/**
* Checks if the given {@code oid} is a valid OID
Expand Down Expand Up @@ -1128,25 +1109,6 @@ public static String getOidCode(String urnOid) {
return urnOid.substring(urnOid.lastIndexOf(':') + 1);
}

/**
* Returns URI if present, otherwise URN encoded OID (see RFC 3061)
* Returns NULL if non of them is present
*
* @param objectIdentifier {@link ObjectIdentifier} used to build an object of 'oid' type
* @return {@link String} URI
*/
public static String getUriOrUrnOid(ObjectIdentifier objectIdentifier) {
/*
* TS 119 182-1 : 5.4.1 The oId data type
* If both an OID and a URI exist identifying one object, the URI value should be used in the id member.
*/
String uri = objectIdentifier.getUri();
if (uri == null && objectIdentifier.getOid() != null) {
uri = DSSUtils.toUrnOid(objectIdentifier.getOid());
}
return uri;
}

/**
* Normalizes and retrieves a {@code String} identifier
* Examples:
Expand Down Expand Up @@ -1246,30 +1208,15 @@ public static <T extends Object> void enrichCollection(Collection<T> currentColl
}
}

/**
* Returns a collection of public key identifiers from the given collection of certificate tokens
*
* @param certificateTokens a collection of {@link CertificateToken}s to get public keys from
* @return a collection of {@link EntityIdentifier}s
*/
public static Collection<EntityIdentifier> getEntityIdentifierList(Collection<CertificateToken> certificateTokens) {
final Set<EntityIdentifier> entityIdentifiers = new HashSet<>();
for (CertificateToken certificateToken : certificateTokens) {
entityIdentifiers.add(certificateToken.getEntityKey());
}
return entityIdentifiers;
}

/**
* This method ensures the {@code SignatureValue} has an expected format and converts it when required
*
* @param expectedAlgorithm {@link SignatureAlgorithm} the target SignatureAlgorithm
* @param signatureValue {@link SignatureValue} the obtained SignatureValue
* @return {@link SignatureValue} with the target {@link SignatureAlgorithm}
* @throws IOException if an exception occurs
*/
public static SignatureValue convertECSignatureValue(SignatureAlgorithm expectedAlgorithm,
SignatureValue signatureValue) throws IOException {
SignatureValue signatureValue) {
SignatureValue newSignatureValue = new SignatureValue();
newSignatureValue.setAlgorithm(expectedAlgorithm);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,7 @@ private static List<PdsLocation> getQcEuPDS(ASN1Encodable statementInfo) {
final ASN1Encodable e1 = sequence.getObjectAt(i);
if (e1 instanceof ASN1Sequence) {
ASN1Sequence seq = (ASN1Sequence) e1;
PdsLocation pds = getPdsLocation(seq);
if (pds != null) {
result.add(pds);
}
result.add(getPdsLocation(seq));
} else {
LOG.warn("ASN1Sequence in QcEuPDS does not contain ASN1Sequence, but {}",
e1.getClass().getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,13 @@
*/
package eu.europa.esig.dss.spi.x509;

import eu.europa.esig.dss.model.DSSException;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import eu.europa.esig.dss.model.DSSException;
import eu.europa.esig.dss.model.x509.CertificateToken;

/**
* This class holds the list of the candidates for the signing certificate of the main signature.
*/
Expand Down Expand Up @@ -62,20 +61,6 @@ public boolean isEmpty() {
return certificateValidityList.isEmpty();
}

/**
* @return the list of candidates for the signing certificate.
*/
public List<CertificateToken> getSigningCertificateTokenList() {
final List<CertificateToken> signCertificateTokenList = new ArrayList<>();
for (final CertificateValidity certificateValidity : certificateValidityList) {
final CertificateToken certificateToken = certificateValidity.getCertificateToken();
if (certificateToken != null) {
signCertificateTokenList.add(certificateToken);
}
}
return signCertificateTokenList;
}

/**
* This method allows to add a candidate for the signing certificate.
*
Expand Down
Loading

0 comments on commit 5bdc4f0

Please sign in to comment.