Skip to content

Instantly share code, notes, and snippets.

@jpopesculian
Last active March 10, 2020 15:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpopesculian/ac1621587eb25223e0e03a7d52094c6e to your computer and use it in GitHub Desktop.
Save jpopesculian/ac1621587eb25223e0e03a7d52094c6e to your computer and use it in GitHub Desktop.
Python SGX utils sample
py_sgx_utils-0.1.0-py2.py3-none-linux_x86_64.whl
Pipfile
FROM sconecuratedimages/apps:python-3.7-alpine
RUN apk add -U openssl-dev
RUN apk add --virtual builddeps git make autoconf automake libtool \
&& git clone https://github.com/bitcoin-core/secp256k1.git \
&& cd secp256k1 \
&& ./autogen.sh \
&& ./configure \
&& make \
&& make install \
&& cd ../ \
&& rm -rf secp256k1 \
&& apk del builddeps
RUN pip3 install requests pyjwt bigchaindb_driver secp256k1
COPY ./py_sgx_utils-0.1.0-py2.py3-none-linux_x86_64.whl .
RUN pip3 install py_sgx_utils-0.1.0-py2.py3-none-linux_x86_64.whl
COPY ./sample.py .
ENV SCONE_VERSION=1
ENV SCONE_LOG=7
ENV SCONE_MODE=hw
ENV RUST_LOG=info
CMD ["python", "sample.py"]
.PHONY: build
build:
docker build -t attestation-python-samples .
.PHONY: run
run:
docker run -it --rm --device /dev/isgx --network host attestation-python-samples
from bigchaindb_driver import BigchainDB
from bigchaindb_driver.crypto import generate_keypair
import secp256k1
import binascii
import json
bdb = BigchainDB("https://ipdb-eu1.riddleandcode.com")
releaser = generate_keypair()
def create_product():
tx = bdb.transactions.prepare(
operation='CREATE',
signers=releaser.public_key,
asset={'data': {
'product': 'DAMS'
}},
metadata=build_version("root", "", ""))
signed_tx = bdb.transactions.fulfill(
tx,
private_keys=releaser.private_key)
return bdb.transactions.send_commit(signed_tx)
def build_version(component, version, measurement):
return {
'component': component,
'measurement': measurement,
'version': version,
}
def add_version(asset_id, last_tx, metadata):
output_index = 0
output = last_tx['outputs'][output_index]
transfer_input = {
'fulfillment': output['condition']['details'],
'fulfills': {
'output_index': output_index,
'transaction_id': last_tx['id'],
},
'owners_before': output['public_keys']
}
transfer_asset = { 'id': asset_id }
tx = bdb.transactions.prepare(
operation="TRANSFER",
asset=transfer_asset,
metadata=metadata,
inputs=transfer_input,
recipients=releaser.public_key,
)
signed_tx = bdb.transactions.fulfill(
tx,
private_keys=releaser.private_key)
return bdb.transactions.send_commit(signed_tx)
if __name__ == "__main__":
print("Signer Public Key: %s" % releaser.public_key)
last_tx = create_product()
asset_id = last_tx['id']
print("AssetID: %s" % asset_id)
last_tx = add_version(asset_id, last_tx, build_version("test_service", "0.1.0", "0000000000000000000000000000000000000000000000000000000000000000"))
print("Test Service v0.1.0 added: %s" % last_tx['id'])
import requests
import jwt
from bigchaindb_driver import BigchainDB
import secp256k1
import array
import binascii
import base64
import re
import json
from py_sgx_utils import rand_secret, LocalAttestationChallenge, LocalAttestationResponse
PUBKEY = secp256k1.PublicKey()
PUBKEY.deserialize(binascii.unhexlify("043a4452a2dea2889cb8fc9d5dc5cd0b406f2028668be915ffd83a9e98d6a1fcd6539db23c4599c4bd07fb3139b15d4513005c680acb2d559894109bf53295930b"))
BDB = BigchainDB("https://ipdb-eu1.riddleandcode.com")
HOST = "https://localhost:8000"
VERSION_ASSET = "335b00ab65407784a4edb082f587690034f0c737e9f59707f8f51ea71979d600"
def version_payload(version_dict):
version_dict["signature"] = None
payload = json.dumps(version_dict, sort_keys=True, separators=(',',':'))
return payload.encode('utf-8')
def check_measurement(measurement):
for transaction in BDB.transactions.get(asset_id=VERSION_ASSET):
if transaction['metadata']['measurement'] == measurement:
signature = PUBKEY.ecdsa_deserialize(binascii.unhexlify(transaction['metadata']['signature']))
if PUBKEY.ecdsa_verify(version_payload(transaction['metadata']), signature):
return True
return False
print("STARTED!\n")
APPLICATION_SECRET = base64.b64encode(rand_secret(32))
print("SECRET: %s\n" % APPLICATION_SECRET)
# create challenge
challenge = LocalAttestationChallenge.rand().dump()
print("CLIENT CHALLENGE: %s\n" % challenge)
# get response
payload = {'challenge': challenge}
res = requests.post(HOST + "/api/attestation/local/challenge", json=payload, verify=False).json()
# validate response
print("SERVER RESPONSE: %s\n" % res['response'])
server_response = LocalAttestationResponse.load(res['response'])
if server_response.is_valid():
print("SERVER RESPONSE VALID!\n")
# should check if mrenclave is in whitelist
mrenclave = array.array('B', server_response.data().report.mrenclave)
measurement = binascii.hexlify(mrenclave).decode('utf-8')
print("SERVER MEASUREMENT: %s\n" % measurement)
if check_measurement(measurement):
print("SERVER MEASUREMENT VALID!\n")
else:
print("SERVER MEASUREMENT NOT VALID!\n")
# create token for server
token = jwt.encode({'service_id': HOST}, APPLICATION_SECRET, algorithm='HS256')
print("TOKEN FOR SERVER: %s\n" % token.decode('utf-8'))
# respond to challenge
print("SERVER CHALLENGE: %s\n" % res['challenge'])
server_challenge = LocalAttestationChallenge.load(res['challenge'])
response = LocalAttestationResponse(server_challenge).dump()
print("CLIENT RESPONSE: %s\n" % response)
# validate response with server and send authorizing token (optional)
payload = {'response': response, 'token': token.decode('utf-8')}
res = requests.post(HOST + "/api/attestation/local/respond", json=payload, verify=False).json()
print("CLIENT RESPONSE VALIDATED!\n")
# a token is received from server for future requests
server_token = res['token']
print("TOKEN FROM SERVER: %s\n" % server_token)
# ping server with token
res = requests.post(HOST + "/api/attestation/local/echo", json={'ping': 'cool'}, headers={'x-local-attestation-token': server_token}, verify=False)
token = res.headers['x-local-attestation-token']
print("TOKEN RECEIVED FROM PING: %s\n" % token)
decoded = jwt.decode(token, APPLICATION_SECRET, algorithms=['HS256'])
print("DECODED TOKEN: %s\n" % json.dumps(decoded))
print("FINISHED!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment