From 9b4eb496011f0321545af9971910719c9f48da0f Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Wed, 17 Jun 2020 08:00:08 -0400 Subject: [PATCH 1/5] Add symlink to /usr/local/bin/rim during rpm install --- tools/tcg_rim_tool/package.sh | 2 +- tools/tcg_rim_tool/scripts/rimtool.sh | 8 ++++++++ tools/tcg_rim_tool/tcg_rim_tool.spec | 9 ++++++--- 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 tools/tcg_rim_tool/scripts/rimtool.sh diff --git a/tools/tcg_rim_tool/package.sh b/tools/tcg_rim_tool/package.sh index a84faf85..b3ac6c3f 100755 --- a/tools/tcg_rim_tool/package.sh +++ b/tools/tcg_rim_tool/package.sh @@ -6,7 +6,7 @@ pushd $SCRIPT_DIR name="tcg_rim_tool" -tar -cf $name.tar build.gradle gradle* src/ docs/ rim_fields.json keystore.jks +tar -cf $name.tar build.gradle gradle* src/ docs/ rim_fields.json keystore.jks scripts/ gzip $name.tar if [ -d rpmbuild ]; then rm -rf rpmbuild diff --git a/tools/tcg_rim_tool/scripts/rimtool.sh b/tools/tcg_rim_tool/scripts/rimtool.sh new file mode 100644 index 00000000..30e731c1 --- /dev/null +++ b/tools/tcg_rim_tool/scripts/rimtool.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Calls the the_tcg_rim_tool and passes in parameters +scriptDir=$(dirname -- "$(readlink -f -- "${BASH_SOURCE[0]}")") +baseDir=${scriptDir%/*} +jar="tcg_rim_tool-1.0.jar"; +java -jar $baseDir/$jar "$@" + diff --git a/tools/tcg_rim_tool/tcg_rim_tool.spec b/tools/tcg_rim_tool/tcg_rim_tool.spec index 8ffc676a..379d8e4d 100644 --- a/tools/tcg_rim_tool/tcg_rim_tool.spec +++ b/tools/tcg_rim_tool/tcg_rim_tool.spec @@ -10,8 +10,7 @@ Source0: %{name}.tar.gz BuildRequires: java-headless >= 1:1.8.0 %description -This tool will generate a root RIM file for PC clients in accordance with the schema located at http://standards.iso.org/iso/19770/-2/2015/schema.xsd. The generated RIM can either be empty if no arguments are given, or contain a payload if an input file is provided. The tool can also verify a given RIMfile against the schema. Use -h or --help to see a list of commands and uses. - +This tool will generate a base RIM file for PC clients in accordance with the schema located at http://standards.iso.org/iso/19770/-2/2015/schema.xsd. The generated RIM can either be empty if no arguments are given, or contain a payload if an input file is provided. The tool can also verify a given RIMfile against the schema. Use -h or --help to see a list of commands and uses. %prep %setup -q -c -n %{name} @@ -23,15 +22,19 @@ rm -f /opt/hirs/rimtool/%{name}*.jar ./gradlew build %install -mkdir -p %{buildroot}/opt/hirs/rimtool/ +mkdir -p %{buildroot}/opt/hirs/rimtool/ %{buildroot}/usr/local/bin/rim/ cp build/libs/%{name}-%{version}.jar %{buildroot}/opt/hirs/rimtool/ cp ./rim_fields.json %{buildroot}/opt/hirs/rimtool/ cp ./keystore.jks %{buildroot}/opt/hirs/rimtool/ +cp -r ./scripts/ %{buildroot}/opt/hirs/rimtool/ +ln -sf /opt/hirs/rimtool/scripts/rimtool.sh %{buildroot}/usr/local/bin/rim %files /opt/hirs/rimtool/%{name}-%{version}.jar /opt/hirs/rimtool/rim_fields.json /opt/hirs/rimtool/keystore.jks +/opt/hirs/rimtool/scripts/rimtool.sh +/usr/local/bin/rim/ %changelog * Mon Jun 15 2020 chubtub From a4e3fb38def3490444b04996baa5a2d4f839f6f3 Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Wed, 17 Jun 2020 08:50:46 -0400 Subject: [PATCH 2/5] Fixed unit test --- .../test/java/hirs/swid/TestSwidTagGateway.java | 7 +++---- .../src/test/resources/generated_no_cert.swidtag | 16 ++++++++-------- .../test/resources/generated_with_cert.swidtag | 16 ++++++++-------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java b/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java index 5088f876..9976d4b1 100644 --- a/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java +++ b/tools/tcg_rim_tool/src/test/java/hirs/swid/TestSwidTagGateway.java @@ -39,7 +39,7 @@ public class TestSwidTagGateway { /** * This test corresponds to the arguments: - * -c base -k privateRimKey.pem -p RimSignCert.pem + * -c base -l TpmLog.bin -k privateRimKey.pem -p RimSignCert.pem */ @Test public void testCreateBaseWithCert() throws URISyntaxException { @@ -53,8 +53,7 @@ public class TestSwidTagGateway { /** * This test corresponds to the arguments: - * -c base - * -c base -a + * -c base -l TpmLog.bin */ @Test public void testCreateBaseWithoutCert() { @@ -66,7 +65,7 @@ public class TestSwidTagGateway { /** * This test corresponds to the arguments: - * -v -p RimSignCert.pem + * -v */ @Test public void testValidateSwidTag() { diff --git a/tools/tcg_rim_tool/src/test/resources/generated_no_cert.swidtag b/tools/tcg_rim_tool/src/test/resources/generated_no_cert.swidtag index 8ae83f21..96a73c73 100644 --- a/tools/tcg_rim_tool/src/test/resources/generated_no_cert.swidtag +++ b/tools/tcg_rim_tool/src/test/resources/generated_no_cert.swidtag @@ -1,11 +1,11 @@ - + - + @@ -17,14 +17,14 @@ - h/jXVVy84NklF+ym8qeNfDEohLKKNLhr35iZ6vage7M= + jpPZu16C8KjtwY2JpJuyR3SBc2XclVEaVsv/DgyZKTM= - huu759PPTMaugu+6/c3JAv/Cb6eCiRxK5i5Mx2IpptDDjbDh9P1931KPEivmG8eZHgbGRFDgUviB -qHcvd4A8KpIdx1GfebPBGBVqnAHvIgAQp1ZOMFIjtYsJTFKrwG12Yc7uA8qdGLCXZ8OlEvim3P/9 -VECXziVXAaEdC4IlaAt86XfbK+z5r2hFKSErYJZws45x1oZcBVXo9wZd7x0EyU0rMTGQbV5QbDsP -LOuWmG2t9jlR7Yu7gxJbhFrPJdI/Q6+JsmsnqKB47dVtXCp84lrlZg48S/nZ0OC62EmEHvzilx4C -y2fM/M0LbkZc5Ms8HD92YBsNF3UL3bHxnJT+YQ== + pWPozFWH2oytfgZse1Ai769c/cBFS/vapKj27asI8XDLdK8FkNs2K/+OTf4lScBiPLTCvWPIihoe +hielmV8dWZqvR2z09pr+yCF7q/E8sCGhQXSsVlNZjElMXk2Qz2c6C9XtRk4UNmSfTSYsKEm2AST4 +oh6da+x1CeSHipALfuZZrXwa2AMtc9yTNfqaQFBxRqEDeTypLwNQqdr9va2T8C9ZNnEzooTf5FWw +OUqc+Ewk5V9ZyOJ/0UdUxs40mGPpsIG90ikx59eu1A4qP4BzjHR3vrNbYDA4hBeIpDHC4vzwJrR4 +xqXw1SLqAm8ngL9Haj2Ww+y0PEZfo++JlOMZuQ== 2fdeb8e7d030a2209daa01861a964fedecf2bcc1 diff --git a/tools/tcg_rim_tool/src/test/resources/generated_with_cert.swidtag b/tools/tcg_rim_tool/src/test/resources/generated_with_cert.swidtag index 72e8e2f8..19468ee3 100644 --- a/tools/tcg_rim_tool/src/test/resources/generated_with_cert.swidtag +++ b/tools/tcg_rim_tool/src/test/resources/generated_with_cert.swidtag @@ -1,11 +1,11 @@ - + - + @@ -17,14 +17,14 @@ - h/jXVVy84NklF+ym8qeNfDEohLKKNLhr35iZ6vage7M= + jpPZu16C8KjtwY2JpJuyR3SBc2XclVEaVsv/DgyZKTM= - huu759PPTMaugu+6/c3JAv/Cb6eCiRxK5i5Mx2IpptDDjbDh9P1931KPEivmG8eZHgbGRFDgUviB -qHcvd4A8KpIdx1GfebPBGBVqnAHvIgAQp1ZOMFIjtYsJTFKrwG12Yc7uA8qdGLCXZ8OlEvim3P/9 -VECXziVXAaEdC4IlaAt86XfbK+z5r2hFKSErYJZws45x1oZcBVXo9wZd7x0EyU0rMTGQbV5QbDsP -LOuWmG2t9jlR7Yu7gxJbhFrPJdI/Q6+JsmsnqKB47dVtXCp84lrlZg48S/nZ0OC62EmEHvzilx4C -y2fM/M0LbkZc5Ms8HD92YBsNF3UL3bHxnJT+YQ== + pWPozFWH2oytfgZse1Ai769c/cBFS/vapKj27asI8XDLdK8FkNs2K/+OTf4lScBiPLTCvWPIihoe +hielmV8dWZqvR2z09pr+yCF7q/E8sCGhQXSsVlNZjElMXk2Qz2c6C9XtRk4UNmSfTSYsKEm2AST4 +oh6da+x1CeSHipALfuZZrXwa2AMtc9yTNfqaQFBxRqEDeTypLwNQqdr9va2T8C9ZNnEzooTf5FWw +OUqc+Ewk5V9ZyOJ/0UdUxs40mGPpsIG90ikx59eu1A4qP4BzjHR3vrNbYDA4hBeIpDHC4vzwJrR4 +xqXw1SLqAm8ngL9Haj2Ww+y0PEZfo++JlOMZuQ== CN=example.RIM.signer,OU=PCClient,O=Example,ST=VA,C=US From 3babe6cc2f3a084c620693fe9862e0528cc34224 Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Wed, 17 Jun 2020 08:51:13 -0400 Subject: [PATCH 3/5] Revert changes to HashSwid class --- .../main/java/hirs/swid/SwidTagGateway.java | 24 +++++++++---- .../main/java/hirs/swid/utils/HashSwid.java | 36 +++++++++++++++---- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java index f57e875d..17adfd94 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java @@ -428,7 +428,11 @@ public class SwidTagGateway { File rimEventLogFile = new File(rimEventLog); file.setSize(new BigInteger(Long.toString(rimEventLogFile.length()))); Map attributes = file.getOtherAttributes(); - addNonNullAttribute(attributes, _SHA256_HASH, HashSwid.get256Hash(rimEventLog)); + try { + addNonNullAttribute(attributes, _SHA256_HASH, HashSwid.getHashValue(Files.readAllBytes(Paths.get(rimEventLog)))); + } catch (IOException e) { + System.out.println("Error hashing support RIM: " + e.getMessage()); + } return file; } @@ -439,13 +443,19 @@ public class SwidTagGateway { private boolean validateFile(Element file) { String filepath = file.getAttribute(SwidTagConstants.NAME); System.out.println("Support rim found at " + filepath); - if (HashSwid.get256Hash(filepath).equals(file.getAttribute(_SHA256_HASH.getPrefix() + ":" + _SHA256_HASH.getLocalPart()))) { - System.out.println("Support RIM hash verified!"); - return true; - } else { - System.out.println("Support RIM hash does not match Base RIM!"); - return false; + byte[] bytes = new byte[]{}; + try { + bytes = Files.readAllBytes(Paths.get(filepath)); + } catch (IOException e) { + System.out.println("Error while hashing support RIM to verify: " + e.getMessage()); } + if (HashSwid.getHashValue(bytes).equals(file.getAttribute(_SHA256_HASH.getPrefix() + ":" + _SHA256_HASH.getLocalPart()))) { + System.out.println("Support RIM hash verified!"); + return true; + } else { + System.out.println("Support RIM hash does not match Base RIM!"); + return false; + } } /** diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/HashSwid.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/HashSwid.java index 1b33f6bf..62995ad5 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/HashSwid.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/HashSwid.java @@ -52,10 +52,6 @@ public class HashSwid { * This method creates the hash based on the provided algorithm and salt * only accessible through helper methods. * - * This method assumes an input file that is small enough to read in its - * entirety. Large files should be handled similarly to the public static - * getHashValue() below. - * * @param filepath file contents to hash * @param salt random value to make the hash stronger * @param sha the algorithm to use for the hash @@ -65,7 +61,7 @@ public class HashSwid { String resultString = null; try { MessageDigest md = MessageDigest.getInstance(sha); - byte[] bytes = md.digest(Files.readAllBytes(Paths.get(filepath))); + byte[] bytes = md.digest(filepath.getBytes(ENCODING)); StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { @@ -74,8 +70,34 @@ public class HashSwid { resultString = sb.toString(); } catch (UnsupportedEncodingException | NoSuchAlgorithmException grex) { System.out.println(grex.getMessage()); - } catch (IOException e) { - System.out.println("Error reading in file to hash: " + e.getMessage()); + } + + return resultString; + } + + /** + * This method creates a hash based on the provided algorithm and salt + * only accessible through helper methods. + * + * This method assumes an input file that is small enough to read in its + * entirety. Large files should be handled similarly to the public static + * getHashValue() below. + * + * This method is also largely redundant and should be refactored after 2.0. + */ + public static String getHashValue(byte[] content) { + String resultString = null; + try { + MessageDigest md = MessageDigest.getInstance(SHA256); + byte[] bytes = md.digest(content); + StringBuilder sb = new StringBuilder(); + + for (int i = 0; i < bytes.length; i++) { + sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); + } + resultString = sb.toString(); + } catch (NoSuchAlgorithmException grex) { + System.out.println(grex.getMessage()); } return resultString; From 4404d25f2046ed9276a29ecb4c907b0997787553 Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Fri, 19 Jun 2020 07:24:11 -0400 Subject: [PATCH 4/5] Revert "Revert changes to HashSwid class" This reverts commit d850d69b1e8b14367b25c075dd8f61b30e558c02. --- .../main/java/hirs/swid/SwidTagGateway.java | 24 ++++--------- .../main/java/hirs/swid/utils/HashSwid.java | 36 ++++--------------- 2 files changed, 14 insertions(+), 46 deletions(-) diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java index 17adfd94..f57e875d 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/SwidTagGateway.java @@ -428,11 +428,7 @@ public class SwidTagGateway { File rimEventLogFile = new File(rimEventLog); file.setSize(new BigInteger(Long.toString(rimEventLogFile.length()))); Map attributes = file.getOtherAttributes(); - try { - addNonNullAttribute(attributes, _SHA256_HASH, HashSwid.getHashValue(Files.readAllBytes(Paths.get(rimEventLog)))); - } catch (IOException e) { - System.out.println("Error hashing support RIM: " + e.getMessage()); - } + addNonNullAttribute(attributes, _SHA256_HASH, HashSwid.get256Hash(rimEventLog)); return file; } @@ -443,19 +439,13 @@ public class SwidTagGateway { private boolean validateFile(Element file) { String filepath = file.getAttribute(SwidTagConstants.NAME); System.out.println("Support rim found at " + filepath); - byte[] bytes = new byte[]{}; - try { - bytes = Files.readAllBytes(Paths.get(filepath)); - } catch (IOException e) { - System.out.println("Error while hashing support RIM to verify: " + e.getMessage()); + if (HashSwid.get256Hash(filepath).equals(file.getAttribute(_SHA256_HASH.getPrefix() + ":" + _SHA256_HASH.getLocalPart()))) { + System.out.println("Support RIM hash verified!"); + return true; + } else { + System.out.println("Support RIM hash does not match Base RIM!"); + return false; } - if (HashSwid.getHashValue(bytes).equals(file.getAttribute(_SHA256_HASH.getPrefix() + ":" + _SHA256_HASH.getLocalPart()))) { - System.out.println("Support RIM hash verified!"); - return true; - } else { - System.out.println("Support RIM hash does not match Base RIM!"); - return false; - } } /** diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/HashSwid.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/HashSwid.java index 62995ad5..1b33f6bf 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/HashSwid.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/HashSwid.java @@ -52,6 +52,10 @@ public class HashSwid { * This method creates the hash based on the provided algorithm and salt * only accessible through helper methods. * + * This method assumes an input file that is small enough to read in its + * entirety. Large files should be handled similarly to the public static + * getHashValue() below. + * * @param filepath file contents to hash * @param salt random value to make the hash stronger * @param sha the algorithm to use for the hash @@ -61,7 +65,7 @@ public class HashSwid { String resultString = null; try { MessageDigest md = MessageDigest.getInstance(sha); - byte[] bytes = md.digest(filepath.getBytes(ENCODING)); + byte[] bytes = md.digest(Files.readAllBytes(Paths.get(filepath))); StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { @@ -70,34 +74,8 @@ public class HashSwid { resultString = sb.toString(); } catch (UnsupportedEncodingException | NoSuchAlgorithmException grex) { System.out.println(grex.getMessage()); - } - - return resultString; - } - - /** - * This method creates a hash based on the provided algorithm and salt - * only accessible through helper methods. - * - * This method assumes an input file that is small enough to read in its - * entirety. Large files should be handled similarly to the public static - * getHashValue() below. - * - * This method is also largely redundant and should be refactored after 2.0. - */ - public static String getHashValue(byte[] content) { - String resultString = null; - try { - MessageDigest md = MessageDigest.getInstance(SHA256); - byte[] bytes = md.digest(content); - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < bytes.length; i++) { - sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1)); - } - resultString = sb.toString(); - } catch (NoSuchAlgorithmException grex) { - System.out.println(grex.getMessage()); + } catch (IOException e) { + System.out.println("Error reading in file to hash: " + e.getMessage()); } return resultString; From c9c40e9bac0c8184b59c850073814927b8ea329d Mon Sep 17 00:00:00 2001 From: chubtub <43381989+chubtub@users.noreply.github.com> Date: Fri, 19 Jun 2020 07:25:23 -0400 Subject: [PATCH 5/5] Install link to /usr/local/bin --- .gitignore | 4 ++++ tools/tcg_rim_tool/package.sh | 2 +- .../src/main/java/hirs/swid/utils/HashSwid.java | 3 +-- tools/tcg_rim_tool/tcg_rim_tool.spec | 8 +++++--- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index dcea8476..b468183f 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,7 @@ SPECS/ RPM/ SRPM/ PLUGIN_SOURCE/ +*.tar.gz # C++ Files # *.o @@ -131,3 +132,6 @@ HIRS_AttestationCA/src/main/java/hirs/attestationca/configuration/provisionerTpm # these files are copied over by ProvisionerTPM2 CMake build HIRS_ProvisionerTPM2/config/logging.properties HIRS_ProvisionerTPM2/scripts/tpm_aca_provision + +# tcg_rim_tool files +tools/tcg_rim_tool/generated_swidTag.swidtag diff --git a/tools/tcg_rim_tool/package.sh b/tools/tcg_rim_tool/package.sh index b3ac6c3f..d4636949 100755 --- a/tools/tcg_rim_tool/package.sh +++ b/tools/tcg_rim_tool/package.sh @@ -7,7 +7,7 @@ pushd $SCRIPT_DIR name="tcg_rim_tool" tar -cf $name.tar build.gradle gradle* src/ docs/ rim_fields.json keystore.jks scripts/ -gzip $name.tar +gzip -f $name.tar if [ -d rpmbuild ]; then rm -rf rpmbuild fi diff --git a/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/HashSwid.java b/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/HashSwid.java index 1b33f6bf..ca366f6a 100644 --- a/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/HashSwid.java +++ b/tools/tcg_rim_tool/src/main/java/hirs/swid/utils/HashSwid.java @@ -49,7 +49,7 @@ public class HashSwid { } /** - * This method creates the hash based on the provided algorithm and salt + * This method creates the hash based on the provided algorithm * only accessible through helper methods. * * This method assumes an input file that is small enough to read in its @@ -57,7 +57,6 @@ public class HashSwid { * getHashValue() below. * * @param filepath file contents to hash - * @param salt random value to make the hash stronger * @param sha the algorithm to use for the hash * @return */ diff --git a/tools/tcg_rim_tool/tcg_rim_tool.spec b/tools/tcg_rim_tool/tcg_rim_tool.spec index 379d8e4d..84230204 100644 --- a/tools/tcg_rim_tool/tcg_rim_tool.spec +++ b/tools/tcg_rim_tool/tcg_rim_tool.spec @@ -22,7 +22,7 @@ rm -f /opt/hirs/rimtool/%{name}*.jar ./gradlew build %install -mkdir -p %{buildroot}/opt/hirs/rimtool/ %{buildroot}/usr/local/bin/rim/ +mkdir -p %{buildroot}/opt/hirs/rimtool/ %{buildroot}/usr/local/bin cp build/libs/%{name}-%{version}.jar %{buildroot}/opt/hirs/rimtool/ cp ./rim_fields.json %{buildroot}/opt/hirs/rimtool/ cp ./keystore.jks %{buildroot}/opt/hirs/rimtool/ @@ -33,8 +33,10 @@ ln -sf /opt/hirs/rimtool/scripts/rimtool.sh %{buildroot}/usr/local/bin/rim /opt/hirs/rimtool/%{name}-%{version}.jar /opt/hirs/rimtool/rim_fields.json /opt/hirs/rimtool/keystore.jks -/opt/hirs/rimtool/scripts/rimtool.sh -/usr/local/bin/rim/ +/opt/hirs/rimtool/scripts +/usr/local/bin/rim + +%attr(755, root, root) /opt/hirs/rimtool/scripts/rimtool.sh %changelog * Mon Jun 15 2020 chubtub