Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add PCLI command to sign account balance files (#6264)
Signed-off-by: Iris Simon <iris.simon@swirldslabs.com> Signed-off-by: Lev Povolotsky <lev@swirldslabs.com> Signed-off-by: Lev Povolotsky <16233475+povolev15@users.noreply.github.com> Co-authored-by: Lev Povolotsky <lev@swirldslabs.com> Co-authored-by: Lev Povolotsky <16233475+povolev15@users.noreply.github.com> Co-authored-by: Quan Nguyen <quan@swirldslabs.com>
- Loading branch information
1 parent
dfba915
commit 1a0303f
Showing
8 changed files
with
291 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
...ra-node/cli-clients/src/main/java/com/hedera/services/cli/sign/AccountBalanceCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
* Copyright (C) 2016-2023 Hedera Hashgraph, LLC | ||
* | ||
* 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 com.hedera.services.cli.sign; | ||
|
||
import com.swirlds.cli.PlatformCli; | ||
import com.swirlds.cli.utility.AbstractCommand; | ||
import com.swirlds.cli.utility.SubcommandOf; | ||
import picocli.CommandLine; | ||
|
||
/** | ||
* A subcommand of the {@link PlatformCli}, for account balance files | ||
*/ | ||
@CommandLine.Command( | ||
name = "account-balance", | ||
mixinStandardHelpOptions = true, | ||
description = "Operations on account balance files.") | ||
@SubcommandOf(PlatformCli.class) | ||
public final class AccountBalanceCommand extends AbstractCommand { | ||
|
||
private AccountBalanceCommand() {} | ||
} |
49 changes: 49 additions & 0 deletions
49
...ode/cli-clients/src/main/java/com/hedera/services/cli/sign/AccountBalanceSignCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* Copyright (C) 2023 Hedera Hashgraph, LLC | ||
* | ||
* 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 com.hedera.services.cli.sign; | ||
|
||
import com.swirlds.cli.utility.SubcommandOf; | ||
import com.swirlds.platform.cli.SignCommand; | ||
import edu.umd.cs.findbugs.annotations.NonNull; | ||
import java.nio.file.Path; | ||
import java.security.KeyPair; | ||
import picocli.CommandLine; | ||
|
||
/** | ||
* A subcommand of the {@link SignCommand}, for signing account balance files | ||
*/ | ||
@CommandLine.Command(name = "sign", mixinStandardHelpOptions = true, description = "Sign account balance files") | ||
@SubcommandOf(AccountBalanceCommand.class) | ||
public final class AccountBalanceSignCommand extends SignCommand { | ||
/** | ||
* {@inheritDoc} | ||
*/ | ||
@Override | ||
public boolean generateSignatureFile( | ||
@NonNull Path signatureFileDestination, @NonNull Path fileToSign, @NonNull KeyPair keyPair) { | ||
|
||
return AccountBalanceSigningUtils.signAccountBalanceFile(signatureFileDestination, fileToSign, keyPair); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
*/ | ||
@Override | ||
public boolean isFileSupported(@NonNull final Path path) { | ||
return AccountBalanceType.getInstance().isCorrectFile(path.toFile().getName()); | ||
} | ||
} |
98 changes: 98 additions & 0 deletions
98
...de/cli-clients/src/main/java/com/hedera/services/cli/sign/AccountBalanceSigningUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* | ||
* Copyright (C) 2023 Hedera Hashgraph, LLC | ||
* | ||
* 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 com.hedera.services.cli.sign; | ||
|
||
import static com.hedera.services.cli.sign.SignUtils.TYPE_FILE_HASH; | ||
import static com.hedera.services.cli.sign.SignUtils.TYPE_SIGNATURE; | ||
import static com.hedera.services.cli.sign.SignUtils.integerToBytes; | ||
import static com.swirlds.common.stream.LinkedObjectStreamUtilities.computeEntireHash; | ||
import static com.swirlds.platform.util.FileSigningUtils.signData; | ||
|
||
import com.swirlds.common.crypto.Hash; | ||
import edu.umd.cs.findbugs.annotations.NonNull; | ||
import java.io.BufferedOutputStream; | ||
import java.io.File; | ||
import java.io.FileOutputStream; | ||
import java.io.IOException; | ||
import java.nio.file.Path; | ||
import java.security.InvalidKeyException; | ||
import java.security.KeyPair; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.NoSuchProviderException; | ||
import java.security.SignatureException; | ||
import java.util.Objects; | ||
|
||
/** | ||
* Utility class for signing account balance files | ||
*/ | ||
public class AccountBalanceSigningUtils { | ||
|
||
/** | ||
* Hidden constructor | ||
*/ | ||
private AccountBalanceSigningUtils() {} | ||
|
||
/** | ||
* Generates a signature file for the account balance file | ||
* | ||
* @param signatureFileDestination the full path where the signature file will be generated | ||
* @param streamFileToSign the stream file to be signed | ||
* @param keyPair the keyPair used for signing | ||
* @return true if the signature file was generated successfully, false otherwise | ||
*/ | ||
public static boolean signAccountBalanceFile( | ||
@NonNull final Path signatureFileDestination, | ||
@NonNull final Path streamFileToSign, | ||
@NonNull final KeyPair keyPair) { | ||
|
||
Objects.requireNonNull(signatureFileDestination, "signatureFileDestination must not be null"); | ||
Objects.requireNonNull(streamFileToSign, "streamFileToSign must not be null"); | ||
Objects.requireNonNull(keyPair, "keyPair must not be null"); | ||
|
||
try { | ||
final Hash entireHash = computeEntireHash(streamFileToSign.toFile()); | ||
final byte[] fileHashByte = entireHash.getValue(); | ||
final byte[] signature = signData(fileHashByte, keyPair); | ||
|
||
generateSigBalanceFile(signatureFileDestination.toFile(), signature, fileHashByte); | ||
|
||
System.out.println("Generated signature file: " + signatureFileDestination); | ||
|
||
return true; | ||
} catch (final SignatureException | IOException e) { | ||
System.err.println("Failed to sign file " + streamFileToSign.getFileName() + ". Exception: " + e); | ||
return false; | ||
} catch (final InvalidKeyException | NoSuchAlgorithmException | NoSuchProviderException e) { | ||
System.err.println("Irrecoverable error encountered: " + e); | ||
throw new RuntimeException("Irrecoverable error encountered", e); | ||
} | ||
} | ||
|
||
private static void generateSigBalanceFile(final File filePath, final byte[] signature, final byte[] fileHash) { | ||
try (final BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(filePath))) { | ||
output.write(TYPE_FILE_HASH); | ||
output.write(fileHash); | ||
output.write(TYPE_SIGNATURE); | ||
output.write(integerToBytes(signature.length)); | ||
output.write(signature); | ||
output.flush(); | ||
} catch (final IOException e) { | ||
System.err.println("generateSigBalanceFile :: Fail to generate signature file for " + filePath | ||
+ " with exception :" + e); | ||
} | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
hedera-node/cli-clients/src/main/java/com/hedera/services/cli/sign/AccountBalanceType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* Copyright (C) 2020-2023 Hedera Hashgraph, LLC | ||
* | ||
* 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 com.hedera.services.cli.sign; | ||
|
||
/** | ||
* Contains properties related to Account Balance file type; | ||
* Its constructor is private. Users need to use the singleton to denote this type | ||
*/ | ||
public final class AccountBalanceType { | ||
/** | ||
* description of the streamType, used for logging | ||
*/ | ||
private static final String ACCOUNT_BALANCE_DESCRIPTION = "account balance"; | ||
/** | ||
* file name extension | ||
*/ | ||
private static final String ACCOUNT_BALANCE_EXTENSION = "pb"; | ||
/** | ||
* file name extension of signature file | ||
*/ | ||
private static final String ACCOUNT_BALANCE_SIG_EXTENSION = "pb_sig"; | ||
/** | ||
* a singleton denotes AccountBalanceType | ||
*/ | ||
private static final AccountBalanceType INSTANCE = new AccountBalanceType(); | ||
|
||
private AccountBalanceType() {} | ||
|
||
public static AccountBalanceType getInstance() { | ||
return INSTANCE; | ||
} | ||
|
||
public String getDescription() { | ||
return ACCOUNT_BALANCE_DESCRIPTION; | ||
} | ||
|
||
public String getExtension() { | ||
return ACCOUNT_BALANCE_EXTENSION; | ||
} | ||
|
||
public String getSigExtension() { | ||
return ACCOUNT_BALANCE_SIG_EXTENSION; | ||
} | ||
|
||
public boolean isCorrectFile(final String fileName) { | ||
return fileName.endsWith(ACCOUNT_BALANCE_EXTENSION); | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
hedera-node/cli-clients/src/main/java/com/hedera/services/cli/sign/SignUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
* Copyright (C) 2023 Hedera Hashgraph, LLC | ||
* | ||
* 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 com.hedera.services.cli.sign; | ||
|
||
import java.nio.ByteBuffer; | ||
|
||
public class SignUtils { | ||
/** | ||
* next bytes are signature | ||
*/ | ||
public static final byte TYPE_SIGNATURE = 3; | ||
/** | ||
* next 48 bytes are hash384 of content of the file to be signed | ||
*/ | ||
public static final byte TYPE_FILE_HASH = 4; | ||
|
||
private static final int BYTES_COUNT_IN_INT = 4; | ||
|
||
private SignUtils() {} | ||
|
||
public static byte[] integerToBytes(final int number) { | ||
final ByteBuffer b = ByteBuffer.allocate(BYTES_COUNT_IN_INT); | ||
b.putInt(number); | ||
return b.array(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters