diff --git a/harmony-signing/.gitignore b/harmony-signing/.gitignore new file mode 100644 index 0000000..f7275bb --- /dev/null +++ b/harmony-signing/.gitignore @@ -0,0 +1 @@ +venv/ diff --git a/harmony-signing/README.md b/harmony-signing/README.md new file mode 100644 index 0000000..329e99c --- /dev/null +++ b/harmony-signing/README.md @@ -0,0 +1,50 @@ +# Harmony Signing Tool + + Harmony releases various excutables (i.e. harmony block chain node code, command line tools etc) regularly through harmony S3 buckets and open to public. + For better safety, all the released binaries shall be signed by harmony siging key (a RSA 4096 asymmetric key). + The private siging key is maintained by amazon aws KMS(Key Management Service) and the key is not visible by anyone from Harmony. + + Only designated aws users (assigned by harmony aws administrator) with signing permission can use the private key to sign binary. + The public key of harmony signing key is open to public and anyone can use it to verify the authencity of the binary. + + +## Setup the tools + +### Install virtualenv +```bash +[sudo] pip install -U setuptools +[sudo] pip install virtualenv +``` + +### Install required packages in virtualenv +```bash +python3 -m virtualenv v +source venv/bin/activate +pip install -r requirement.txt +deactivate +``` + +## Sign binary before releasing binary (requires AWS account and harmony signing key permission) + + Now you can use the python script sign_binary.py to sign the executable. + Please note that this script has to be invoked inside the virtual environment (source venv/bin/activate). + As the script requires the Harmony signing key, please login to your aws account before signing. + + python signing_binary.py [binary_file] [signature_file] + An example signing session is shown below, where harmony is the executable and harmony.sig is the output signature. + +```bash +source venv/bin/activate +python sign_binary.py harmony harmony.sig +``` + +## Verify the signature on client side + + Both harmony binary and signature file can be downloaded publically on harmony S3 buckets. Once downloaded, the authenticity of harmony binary should be verified. + The verification can be done by using the open source tool openssl and the harmony public key harmony_pubkey.pem.. + +```bash +openssl dgst -sha256 -verify harmony_pubkey.pem -signature harmony.sig harmony +Verified OK +``` + The expected output from openssl should be "Verified OK". diff --git a/harmony-signing/harmony b/harmony-signing/harmony new file mode 100755 index 0000000..8993b9e Binary files /dev/null and b/harmony-signing/harmony differ diff --git a/harmony-signing/harmony.sig b/harmony-signing/harmony.sig new file mode 100644 index 0000000..3f90f72 Binary files /dev/null and b/harmony-signing/harmony.sig differ diff --git a/harmony-signing/harmony_pubkey.pem b/harmony-signing/harmony_pubkey.pem new file mode 100644 index 0000000..b90734b --- /dev/null +++ b/harmony-signing/harmony_pubkey.pem @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvYjTewj/rg9hxNnWUtca +kibSOgRMiFOa97iyilh+aRLnYHeCcBH3fWe3x7gUQFr1Tov8ge4zqmvDxXqlVxfX +Ml+gQNWnsEDu7kHsS9ObHT44na9ICEH5GJAVkZLn4WHkYy0JbDgGMwrOaprCBJG0 +yizlvBiEOSuleePTQhxdOBENSXJnUURspdqTi9yPKRXxgGrvMnnlG+c2GiUUHH9O +QrsnU73ZnF+QPFx3K9ZZTp7kqBgWb4W0R3ZJVQ12CdXG4pagZSjENhRUDkA3FruJ +Uqd3ohhmi92KIEyN4Y62u5c6SzZ1NlVrHCkIZFXECby0ArfwToQAT510NOeeDSyy +mpXg5XOGU2s5mSgi2TsiyelPzexKDXN5PD5C/F9kySZYgk2g94LZ88lfG0qdv2fF +o5p/XZEscANgAATqhc2m72ZQHGPcLqr3+/V+rMbJXtmkyYg+kzFf5QBeGNnOav4V +KDbXMG6yld4QDLfvOD7Rh/dT+Cha7fb51tvRY3++eE9LRgOMOD9aZwYCBpSSejOo +3Lho6dkJw69kw81dkTryUNJHMoksrmveuLuamZVB2VrmFADvceANvinb5zWA83ha +dvljR8EmPhTjv8SwSP3+27soYX1b/sHJoo52XDHjQRQp4WxrCP1nvxVK4hW8Ka3E +fYcZ6Brth39O8fhx2n8u2bcCAwEAAQ== +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/harmony-signing/requirement.txt b/harmony-signing/requirement.txt new file mode 100644 index 0000000..82ecea6 --- /dev/null +++ b/harmony-signing/requirement.txt @@ -0,0 +1,14 @@ +attrs==19.3.0 +aws-encryption-sdk==1.4.1 +boto3==1.11.3 +botocore==1.14.3 +cffi==1.13.2 +cryptography==2.8 +docutils==0.15.2 +jmespath==0.9.4 +pycparser==2.19 +python-dateutil==2.8.1 +s3transfer==0.3.0 +six==1.14.0 +urllib3==1.25.7 +wrapt==1.11.2 diff --git a/harmony-signing/sign_binary.py b/harmony-signing/sign_binary.py new file mode 100755 index 0000000..fdfda14 --- /dev/null +++ b/harmony-signing/sign_binary.py @@ -0,0 +1,53 @@ +import aws_encryption_sdk +import boto3 +import sys +import hashlib +import binascii + +#key ID for harmony signing key, created by aws, using aws KMS +harmonySigningKeyId = "arn:aws:kms:us-west-2:656503231766:key/370d45bb-d629-45d7-8d1c-db0560895690" +signingAlgorithm = "RSASSA_PKCS1_V1_5_SHA_256" + +def region_from_key_id(signingKeyId, default_region=None): + try: + region_name = signingKeyId.split(":", 4)[3] + except IndexError: + if default_region is None: + raise UnknownRegionError( + "No default region found and no region determinable from key id: {}".format(signingKeyId) + ) + region_name = default_region + return region_name + + +def sign_harmony_file(inputFile, sigFile, keyId = harmonySigningKeyId): + region_name = region_from_key_id(keyId) + kms_client = boto3.client('kms', region_name) + + data = open(inputFile, "rb").read() + digest = hashlib.sha256(data).digest() + + print("File Name : ", inputFile) + print("Digest : ", binascii.hexlify(digest)) + print("Sign Key ID : ", harmonySigningKeyId) + print("Algorithm : ", signingAlgorithm) + print("Signature : ", sigFile) + + response = kms_client.sign( + KeyId = keyId, + Message = digest, + MessageType = 'DIGEST', + GrantTokens=[ + 'string', + ], + SigningAlgorithm=signingAlgorithm + ) + #print(response) + + signature = response['Signature'] + open(sigFile,"wb").write(signature) + + return True + +if __name__ == '__main__': + sign_harmony_file(sys.argv[1], sys.argv[2], harmonySigningKeyId) diff --git a/harmony-signing/verify_binary.sh b/harmony-signing/verify_binary.sh new file mode 100755 index 0000000..98ba32e --- /dev/null +++ b/harmony-signing/verify_binary.sh @@ -0,0 +1,2 @@ +#!/bin/bash +openssl dgst -sha256 -verify harmony_pubkey.pem -signature harmony.sig harmony