diff --git a/README.md b/README.md index a60d85f..a394221 100755 --- a/README.md +++ b/README.md @@ -319,26 +319,26 @@ byte[] buf = idlArgs.toBytes(); To add IC4J Agent library to your Java project use Maven or Gradle import from Maven Central. - -https://search.maven.org/artifact/org.ic4j/ic4j-agent/0.7.1/jar + +https://search.maven.org/artifact/org.ic4j/ic4j-agent/0.7.4/jar ``` org.ic4j ic4j-agent - 0.7.1 + 0.7.4 org.ic4j ic4j-candid - 0.7.1 + 0.7.4 ``` ``` -implementation 'org.ic4j:ic4j-agent:0.7.1' -implementation 'org.ic4j:ic4j-candid:0.7.1' +implementation 'org.ic4j:ic4j-agent:0.7.4' +implementation 'org.ic4j:ic4j-candid:0.7.4' ``` diff --git a/build.gradle b/build.gradle index 1993277..c5bb1b5 100755 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,6 @@ version '0.0.1' repositories { - mavenLocal() mavenCentral() } @@ -54,19 +53,19 @@ test { } dependencies { - implementation group: 'org.ic4j', name: 'ic4j-candid', version: '0.7.1' - - // https://mvnrepository.com/artifact/commons-codec/commons-codec - implementation group: 'commons-codec', name: 'commons-codec', version: '1.17.0' - - // https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 - implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.14.0' + // https://mvnrepository.com/artifact/org.slf4j/slf4j-api + compileOnly group: 'org.slf4j', name: 'slf4j-api', version: '2.0.16' // https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 - implementation group: 'org.apache.httpcomponents.client5', name: 'httpclient5', version: '5.3.1' + compileOnly group: 'org.apache.httpcomponents.client5', name: 'httpclient5', version: '5.3.1' // https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp - implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.12.0' + compileOnly group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.12.0' + + implementation group: 'org.ic4j', name: 'ic4j-candid', version: '0.7.4' + + // https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 + implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.17.0' // https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.17.2' @@ -82,21 +81,27 @@ dependencies { // https://mvnrepository.com/artifact/org.bouncycastle/bcpkix-jdk18on implementation group: 'org.bouncycastle', name: 'bcpkix-jdk18on', version: '1.78.1' - - // https://mvnrepository.com/artifact/org.slf4j/slf4j-simple - implementation group: 'org.slf4j', name: 'slf4j-simple', version: '2.0.13' // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api - testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.10.0' + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.11.0' // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine - testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.10.0' + testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.11.0' // https://mvnrepository.com/artifact/org.junit.platform/junit-platform-launcher - testImplementation group: 'org.junit.platform', name: 'junit-platform-launcher', version: '1.10.0' + testImplementation group: 'org.junit.platform', name: 'junit-platform-launcher', version: '1.11.0' + + // https://mvnrepository.com/artifact/org.slf4j/slf4j-simple + testImplementation group: 'org.slf4j', name: 'slf4j-simple', version: '2.0.16' + + // https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 + testImplementation group: 'org.apache.httpcomponents.client5', name: 'httpclient5', version: '5.3.1' + + // https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp + testImplementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.12.0' // https://mvnrepository.com/artifact/org.skyscreamer/jsonassert - testImplementation group: 'org.skyscreamer', name: 'jsonassert', version: '1.5.1' + testImplementation group: 'org.skyscreamer', name: 'jsonassert', version: '1.5.3' // https://mvnrepository.com/artifact/org.mock-server/mockserver-netty testImplementation group: 'org.mock-server', name: 'mockserver-netty', version: '5.11.2' diff --git a/src/main/java/org/ic4j/agent/Agent.java b/src/main/java/org/ic4j/agent/Agent.java index 93b0907..d84c03c 100644 --- a/src/main/java/org/ic4j/agent/Agent.java +++ b/src/main/java/org/ic4j/agent/Agent.java @@ -39,7 +39,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; -import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang3.ArrayUtils; import org.bouncycastle.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; @@ -101,7 +100,7 @@ public final class Agent { static { try { BLS_VERIFY = Boolean.parseBoolean(System.getProperty(BLS_VERIFY_PROPERTY, "true")); - IC_ROOT_KEY = Hex.decodeHex("308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100814c0e6ec71fab583b08bd81373c255c3c371b2e84863c98a4f1e08b74235d14fb5d9c0cd546d9685f913a0c0b2cc5341583bf4b4392e467db96d65b9bb4cb717112f8472e0d5a4d14505ffd7484b01291091c5f87b98883463f98091a0baaae".toCharArray()); + IC_ROOT_KEY = Hex.decodeHex("308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100814c0e6ec71fab583b08bd81373c255c3c371b2e84863c98a4f1e08b74235d14fb5d9c0cd546d9685f913a0c0b2cc5341583bf4b4392e467db96d65b9bb4cb717112f8472e0d5a4d14505ffd7484b01291091c5f87b98883463f98091a0baaae"); } catch (Exception e) { throw AgentError.create(AgentError.AgentErrorCode.CUSTOM_ERROR, e); } diff --git a/src/main/java/org/ic4j/agent/DigestUtils.java b/src/main/java/org/ic4j/agent/DigestUtils.java new file mode 100644 index 0000000..3c95faf --- /dev/null +++ b/src/main/java/org/ic4j/agent/DigestUtils.java @@ -0,0 +1,43 @@ +/* + * Copyright 2024 Exilor Inc. + * + * 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 org.ic4j.agent; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import javax.xml.bind.DatatypeConverter; + +public class DigestUtils { + + public static MessageDigest getSha256Digest() { + MessageDigest messageDigest; + try { + messageDigest = MessageDigest.getInstance("SHA-256"); + + return messageDigest; + } catch (NoSuchAlgorithmException e) { + throw AgentError.create(AgentError.AgentErrorCode.CUSTOM_ERROR, e); + } + } + + // Compute SHA-256 hash + public static byte[] sha256(byte[] bytes) { + MessageDigest digest = getSha256Digest(); + return digest.digest(bytes); + } + +} diff --git a/src/main/java/org/ic4j/agent/Hex.java b/src/main/java/org/ic4j/agent/Hex.java new file mode 100644 index 0000000..cc2bea4 --- /dev/null +++ b/src/main/java/org/ic4j/agent/Hex.java @@ -0,0 +1,43 @@ +/* + * Copyright 2024 Exilor Inc. + * + * 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 org.ic4j.agent; + +public class Hex { + // Convert hexadecimal string to byte array + public static byte[] decodeHex(String s) { + int len = s.length(); + if (len % 2 != 0) { + throw new IllegalArgumentException("Hexadecimal string must have an even length"); + } + byte[] data = new byte[len / 2]; + for (int i = 0; i < len; i += 2) { + data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + + Character.digit(s.charAt(i+1), 16)); + } + return data; + } + + + // Convert byte array to hexadecimal string manually + public static String encodeHexString(byte[] bytes) { + StringBuilder sb = new StringBuilder(); + for (byte b : bytes) { + sb.append(String.format("%02x", b)); + } + return sb.toString(); + } +} diff --git a/src/main/java/org/ic4j/agent/ResponseAuthentication.java b/src/main/java/org/ic4j/agent/ResponseAuthentication.java index 9b8ea6c..a9f4b0e 100644 --- a/src/main/java/org/ic4j/agent/ResponseAuthentication.java +++ b/src/main/java/org/ic4j/agent/ResponseAuthentication.java @@ -24,8 +24,6 @@ import java.util.List; import java.util.Map; -import org.apache.commons.codec.DecoderException; -import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang3.ArrayUtils; import org.ic4j.agent.certification.Certificate; import org.ic4j.agent.certification.hashtree.HashTree; @@ -45,274 +43,247 @@ public final class ResponseAuthentication { static final byte[] DER_PREFIX; static final int KEY_LENGTH = 96; - + static { - try { - DER_PREFIX = Hex.decodeHex("308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100".toCharArray()); - } catch (DecoderException e) { - throw AgentError.create(AgentError.AgentErrorCode.CUSTOM_ERROR, e); - } + DER_PREFIX = Hex.decodeHex("308182301d060d2b0601040182dc7c0503010201060c2b0601040182dc7c05030201036100"); } - - static byte[] extractDer(byte[] buf) throws AgentError - { + + static byte[] extractDer(byte[] buf) throws AgentError { int expectedLength = DER_PREFIX.length + KEY_LENGTH; - - if(buf.length != expectedLength) - throw AgentError.create(AgentError.AgentErrorCode.DER_KEY_LENGTH_MISMATCH,expectedLength,buf.length); - - byte[] prefix = ArrayUtils.subarray(buf, 0 , DER_PREFIX.length); - - if(!Arrays.equals(DER_PREFIX, prefix)) - throw AgentError.create(AgentError.AgentErrorCode.DER_PREFIX_MISMATCH,expectedLength,buf.length); - - return ArrayUtils.subarray(buf, DER_PREFIX.length , buf.length); + + if (buf.length != expectedLength) + throw AgentError.create(AgentError.AgentErrorCode.DER_KEY_LENGTH_MISMATCH, expectedLength, buf.length); + + byte[] prefix = ArrayUtils.subarray(buf, 0, DER_PREFIX.length); + + if (!Arrays.equals(DER_PREFIX, prefix)) + throw AgentError.create(AgentError.AgentErrorCode.DER_PREFIX_MISMATCH, expectedLength, buf.length); + + return ArrayUtils.subarray(buf, DER_PREFIX.length, buf.length); } - - static RequestStatusResponse lookupRequestStatus(Certificate certificate, RequestId requestId) throws AgentError - { + + static RequestStatusResponse lookupRequestStatus(Certificate certificate, RequestId requestId) throws AgentError { List