Merge pull request #1 from coolcottontail/harmony_signing
added harmony-signing for signing harmony binariespull/2/head
commit
968b5714a2
@ -0,0 +1 @@ |
||||
venv/ |
@ -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". |
@ -0,0 +1,2 @@ |
||||
#!/bin/bash |
||||
openssl dgst -sha256 -verify harmony_pubkey.pem -signature harmony.sig harmony |
Binary file not shown.
@ -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----- |
@ -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 |
@ -0,0 +1,55 @@ |
||||
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) |
||||
|
||||
signature = '' |
||||
with open(inputFile, "rb") as f: |
||||
data = f.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', |
||||
SigningAlgorithm=signingAlgorithm |
||||
) |
||||
|
||||
signature = response['Signature'] |
||||
|
||||
if signature != '': |
||||
with open(sigFile,"wb") as of: |
||||
of.write(signature) |
||||
|
||||
if __name__ == '__main__': |
||||
if len(sys.argv) != 4: |
||||
print("Usage: python3 sign_harmony_file [aws_key_id] [input_file] [output_signature]") |
||||
else: |
||||
sign_harmony_file(sys.argv[2], sys.argv[3], sys.argv[1]) |
Loading…
Reference in new issue