From 1b3f9cbabdabe43588bcf8e3b92c89bd87272ef6 Mon Sep 17 00:00:00 2001 From: Michal Banka Date: Thu, 12 Mar 2020 14:00:51 +0100 Subject: Fixed sonar issues in Split class and refactor it Removed unnecesary conversion: bouncle castle RDN -> String -> CertService RDN. Now it's: Bouncle castle RDN -> CertService RDN. Class Split rewritten on streams, tested. Signed-off-by: Michal Banka Change-Id: I04e10fd6e4ab619124b93db7193c94f54b4b08ef Issue-ID: AAF-997 --- .../certification/adapter/CSRMetaBuilder.java | 17 +-- .../aaf/certservice/cmpv2client/external/RDN.java | 117 ++++++++++--------- .../certservice/cmpv2client/external/Split.java | 127 --------------------- .../certservice/cmpv2client/external/RDNTest.java | 95 +++++++++++++++ 4 files changed, 170 insertions(+), 186 deletions(-) delete mode 100644 certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/Split.java create mode 100644 certService/src/test/java/org/onap/aaf/certservice/cmpv2client/external/RDNTest.java diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilder.java b/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilder.java index f768dabb..1959d638 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilder.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/adapter/CSRMetaBuilder.java @@ -22,9 +22,10 @@ package org.onap.aaf.certservice.certification.adapter; import java.security.KeyPair; import java.util.Arrays; -import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; + +import org.bouncycastle.asn1.x500.AttributeTypeAndValue; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x500.style.IETFUtils; import org.bouncycastle.cert.CertException; @@ -69,19 +70,21 @@ class CSRMetaBuilder { csrModel.getSans().forEach(csrMeta::addSan); } - private String convertRDNToString(org.bouncycastle.asn1.x500.RDN rdn) { - return BCStyle.INSTANCE.oidToDisplayName(rdn.getFirst().getType()) + "=" + IETFUtils.valueToString( - rdn.getFirst().getValue()); - } - private Optional convertFromBcRDN(org.bouncycastle.asn1.x500.RDN rdn) { RDN result = null; try { - result = new RDN(convertRDNToString(rdn)); + result = convertRDN(rdn); } catch (CertException e) { LOGGER.error("Exception occurred during convert of RDN", e); } return Optional.ofNullable(result); } + private RDN convertRDN(org.bouncycastle.asn1.x500.RDN rdn) throws CertException { + AttributeTypeAndValue rdnData = rdn.getFirst(); + String tag = BCStyle.INSTANCE.oidToDisplayName(rdnData.getType()); + String value = IETFUtils.valueToString(rdnData.getValue()); + return new RDN(tag, value); + } + } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/RDN.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/RDN.java index 0e1ab25f..229fd76b 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/RDN.java +++ b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/RDN.java @@ -23,7 +23,10 @@ package org.onap.aaf.certservice.cmpv2client.external; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; + import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.cert.CertException; @@ -42,61 +45,32 @@ public class RDN { return aoi; } + public RDN(final String tag, final String value) throws CertException { + this.tag = tag; + this.value = value; + this.aoi = getAoi(tag); + } + public RDN(final String tagValue) throws CertException { - String[] tv = Split.splitTrim('=', tagValue); - switch (tv[0].toLowerCase()) { - case "cn": - aoi = BCStyle.CN; - break; - case "c": - aoi = BCStyle.C; - break; - case "st": - aoi = BCStyle.ST; - break; - case "l": - aoi = BCStyle.L; - break; - case "o": - aoi = BCStyle.O; - break; - case "ou": - aoi = BCStyle.OU; - break; - case "dc": - aoi = BCStyle.DC; - break; - case "gn": - aoi = BCStyle.GIVENNAME; - break; - case "sn": - aoi = BCStyle.SN; - break; - case "email": - case "e": - case "emailaddress": - aoi = BCStyle.EmailAddress; - break; // should be SAN extension - case "initials": - aoi = BCStyle.INITIALS; - break; - case "pseudonym": - aoi = BCStyle.PSEUDONYM; - break; - case "generationQualifier": - aoi = BCStyle.GENERATION; - break; - case "serialNumber": - aoi = BCStyle.SERIALNUMBER; - break; - default: - throw new CertException( - "Unknown ASN1ObjectIdentifier for " + tv[0] + " in " + tagValue); - } - tag = tv[0]; - value = tv[1]; + List tv = parseRDN("=", tagValue); + this.tag = tv.get(0); + this.value = tv.get(1); + this.aoi = getAoi(this.tag); } + /** + * Splits RDN as string by given delimiter, then trims every part. + * + * @param splitBy Delimiter which splits value + * @param value Value to be splitted + * @return List of splitted and trimmed strings + */ + public static List parseRDN(String splitBy, String value) { + String[] splitted = value.split(splitBy); + return Arrays.stream(splitted) + .map(String::trim) + .collect(Collectors.toList()); + } /** * Parse various forms of DNs into appropriate RDNs, which have the ASN1ObjectIdentifier * @@ -105,6 +79,7 @@ public class RDN { * @return * @throws CertException */ + public static List parse(final char delim, final String dnString) throws CertException { List lrnd = new ArrayList<>(); StringBuilder sb = new StringBuilder(); @@ -140,4 +115,42 @@ public class RDN { public String toString() { return tag + '=' + value; } + + ASN1ObjectIdentifier getAoi(String tag) throws CertException { + switch (tag.toLowerCase()) { + case "cn": + return BCStyle.CN; + case "c": + return BCStyle.C; + case "st": + return BCStyle.ST; + case "l": + return BCStyle.L; + case "o": + return BCStyle.O; + case "ou": + return BCStyle.OU; + case "dc": + return BCStyle.DC; + case "gn": + return BCStyle.GIVENNAME; + case "sn": + return BCStyle.SN; + case "email": + case "e": + case "emailaddress": + return BCStyle.EmailAddress; + case "initials": + return BCStyle.INITIALS; + case "pseudonym": + return BCStyle.PSEUDONYM; + case "generationqualifier": + return BCStyle.GENERATION; + case "serialnumber": + return BCStyle.SERIALNUMBER; + default: + throw new CertException( + "Unknown ASN1ObjectIdentifier for tag " + tag); + } + } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/Split.java b/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/Split.java deleted file mode 100644 index e531f2d2..00000000 --- a/certService/src/main/java/org/onap/aaf/certservice/cmpv2client/external/Split.java +++ /dev/null @@ -1,127 +0,0 @@ -/** - * ============LICENSE_START==================================================== org.onap.aaf - * =========================================================================== Copyright (c) 2018 - * AT&T Intellectual Property. All rights reserved. - * - * Modifications Copyright (C) 2019 IBM. =========================================================================== - * 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. ============LICENSE_END==================================================== - */ -package org.onap.aaf.certservice.cmpv2client.external; - -/** - * Split by Char, optional Trim - * - *

Note: Copied from Inno to avoid linking issues. Note: I read the String split and Pattern - * split code, and we can do this more efficiently for a single Character - * - *

8/20/2015 - */ -public class Split { - - private static final String[] EMPTY = new String[0]; - - public static String[] split(char c, String value) { - if (value == null) { - return EMPTY; - } - - return split(c, value, 0, value.length()); - } - - public static String[] split(char c, String value, int start, int end) { - if (value == null) { - return EMPTY; - } - - // Count items to preallocate Array (memory alloc is more expensive than counting twice) - int count, idx; - for (count = 1, idx = value.indexOf(c, start); - idx >= 0 && idx < end; - idx = value.indexOf(c, ++idx), ++count) { - ; - } - String[] rv = new String[count]; - if (count == 1) { - rv[0] = value.substring(start, end); - } else { - int last = 0; - count = -1; - for (idx = value.indexOf(c, start); idx >= 0 && idx < end; - idx = value.indexOf(c, idx)) { - rv[++count] = value.substring(last, idx); - last = ++idx; - } - rv[++count] = value.substring(last, end); - } - return rv; - } - - public static String[] splitTrim(char c, String value, int start, int end) { - if (value == null) { - return EMPTY; - } - - // Count items to preallocate Array (memory alloc is more expensive than counting twice) - int count, idx; - for (count = 1, idx = value.indexOf(c, start); - idx >= 0 && idx < end; - idx = value.indexOf(c, ++idx), ++count) { - ; - } - String[] rv = new String[count]; - if (count == 1) { - rv[0] = value.substring(start, end).trim(); - } else { - int last = start; - count = -1; - for (idx = value.indexOf(c, start); idx >= 0 && idx < end; - idx = value.indexOf(c, idx)) { - rv[++count] = value.substring(last, idx).trim(); - last = ++idx; - } - rv[++count] = value.substring(last, end).trim(); - } - return rv; - } - - public static String[] splitTrim(char c, String value) { - if (value == null) { - return EMPTY; - } - return splitTrim(c, value, 0, value.length()); - } - - public static String[] splitTrim(char c, String value, int size) { - if (value == null) { - return EMPTY; - } - - int idx; - String[] rv = new String[size]; - if (size == 1) { - rv[0] = value.trim(); - } else { - int last = 0; - int count = -1; - size -= 2; - for (idx = value.indexOf(c); idx >= 0 && count < size; idx = value.indexOf(c, idx)) { - rv[++count] = value.substring(last, idx).trim(); - last = ++idx; - } - if (idx > 0) { - rv[++count] = value.substring(last, idx).trim(); - } else { - rv[++count] = value.substring(last).trim(); - } - } - return rv; - } -} diff --git a/certService/src/test/java/org/onap/aaf/certservice/cmpv2client/external/RDNTest.java b/certService/src/test/java/org/onap/aaf/certservice/cmpv2client/external/RDNTest.java new file mode 100644 index 00000000..7a1f8be4 --- /dev/null +++ b/certService/src/test/java/org/onap/aaf/certservice/cmpv2client/external/RDNTest.java @@ -0,0 +1,95 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.aaf.certservice.cmpv2client.external; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.x500.style.BCStyle; +import org.bouncycastle.cert.CertException; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class RDNTest { + + @Test + public void shouldCreateCorrectRDN() throws CertException { + //when + RDN rdn1 = new RDN("CN=ManagmentCA"); + RDN rdn2 = new RDN("CN = ManagmentCA "); + RDN rdn3 = new RDN("CN", "ManagmentCA"); + + //then + String expectedValue = "ManagmentCA"; + ASN1ObjectIdentifier expectedAoi = BCStyle.CN; + + assertEquals(expectedValue, rdn1.getValue()); + assertEquals(expectedValue, rdn2.getValue()); + assertEquals(expectedValue, rdn3.getValue()); + assertEquals(expectedAoi, rdn1.getAoi()); + assertEquals(expectedAoi, rdn2.getAoi()); + assertEquals(expectedAoi, rdn3.getAoi()); + } + + @Test + public void shouldCorrectlySplitAndTrimString() { + //given + String value1 = " T = Test"; + List expected1 = Arrays.asList("T", "Test"); + + String value2 = "This 123 is 99 tested 12345 string"; + List expected2 = Arrays.asList("This", "is 99 tested", "string"); + + //when + List actual1 = RDN.parseRDN("=", value1); + List actual2 = RDN.parseRDN("[0-9]{3,}", value2); + + //then + assertEquals(expected1, actual1); + assertEquals(expected2, actual2); + } + + @Test + public void shouldConvertAoiStringToEnum() throws CertException { + RDN rdn = new RDN("CN", "ManagmentCA"); + + assertEquals(BCStyle.CN, rdn.getAoi("CN")); + assertEquals(BCStyle.C, rdn.getAoi("C")); + assertEquals(BCStyle.ST, rdn.getAoi("ST")); + assertEquals(BCStyle.L, rdn.getAoi("L")); + assertEquals(BCStyle.O, rdn.getAoi("O")); + assertEquals(BCStyle.OU, rdn.getAoi("OU")); + assertEquals(BCStyle.DC, rdn.getAoi("DC")); + assertEquals(BCStyle.GIVENNAME, rdn.getAoi("GN")); + assertEquals(BCStyle.SN, rdn.getAoi("SN")); + assertEquals(BCStyle.E, rdn.getAoi("E")); + assertEquals(BCStyle.E, rdn.getAoi("EMAIL")); + assertEquals(BCStyle.E, rdn.getAoi("EMAILADDRESS")); + assertEquals(BCStyle.INITIALS, rdn.getAoi("INITIALS")); + assertEquals(BCStyle.PSEUDONYM, rdn.getAoi("PSEUDONYM")); + assertEquals(BCStyle.GENERATION, rdn.getAoi("GENERATIONQUALIFIER")); + assertEquals(BCStyle.SERIALNUMBER, rdn.getAoi("SERIALNUMBER")); + assertThrows(CertException.class, () -> rdn.getAoi("INVALIDTAG")); + } +} \ No newline at end of file -- cgit 1.2.3-korg