def do_keygen(args): if args.key_name is not None: key_name = args.key_name else: key_name = getpass.getuser() if args.key_dir is not None: key_dir = args.key_dir if not os.path.exists(key_dir): raise CliException('no such directory: {}'.format(key_dir)) else: key_dir = os.path.join(os.path.expanduser('~'), '.sawtooth', 'keys') if not os.path.exists(key_dir): if not args.quiet: print('creating key directory: {}'.format(key_dir)) try: os.makedirs(key_dir) except IOError as e: raise CliException('IOError: {}'.format(str(e))) wif_filename = os.path.join(key_dir, key_name + '.wif') addr_filename = os.path.join(key_dir, key_name + '.addr') if not args.force: file_exists = False for filename in [wif_filename, addr_filename]: if os.path.exists(filename): file_exists = True print('file exists: {}'.format(filename), file=sys.stderr) if file_exists: raise CliException( 'files exist, rerun with --force to overwrite existing files') privkey = signing.generate_privkey() encoded = signing.encode_privkey(privkey) pubkey = signing.generate_pubkey(privkey) addr = signing.generate_identifier(pubkey) try: wif_exists = os.path.exists(wif_filename) with open(wif_filename, 'w') as wif_fd: if not args.quiet: if wif_exists: print('overwriting file: {}'.format(wif_filename)) else: print('writing file: {}'.format(wif_filename)) wif_fd.write(encoded) wif_fd.write('\n') addr_exists = os.path.exists(addr_filename) with open(addr_filename, 'w') as addr_fd: if not args.quiet: if addr_exists: print('overwriting file: {}'.format(addr_filename)) else: print('writing file: {}'.format(addr_filename)) addr_fd.write(addr) addr_fd.write('\n') except IOError as ioe: raise CliException('IOError: {}'.format(str(ioe)))
def test_valid_signature(self): signing_key = SigObj.generate_signing_key() pub_key = signing.generate_pubkey(signing_key) temp = SignedObject({"PublicKey": pub_key}) # test valid signature temp.sign_object(signing_key) self.assertTrue(temp.is_valid("valid"))
def test_libor_update_invalid_value_one_year(self): key = signed_object.generate_signing_key() store = ObjectStore() libor_key = TestCreateLIBORUpdate.libor_key libor_public_key = signing.generate_pubkey(libor_key) update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='2016-05-24', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 'invalid rate' }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction = BondTransaction() transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass
def test_register_validator_re_register(self): key = signed_object.generate_signing_key() public_key_hash = \ hashlib.sha256( signing.encode_pubkey( signing.generate_pubkey(key), 'hex')).hexdigest() validator_id = signed_object.generate_identifier(key) name = 'DasValidator' signup_info = \ SignupInfo.create_signup_info( originator_public_key_hash=public_key_hash, most_recent_wait_certificate_id='0' * 16) store = ObjectStore() transaction = \ ValidatorRegistryTransaction.register_validator( name, validator_id, signup_info) transaction.sign_object(key) try: transaction.check_valid(store) transaction.apply(store) except InvalidTransactionError as e: self.fail('Failed valid transaction: {}'.format(e)) try: # check if valid to register again transaction.check_valid(store) except InvalidTransactionError as e: self.fail('Failure: Double registered validator: {}'.format(e))
def test_register_validator_key_mismatch(self): key = signed_object.generate_signing_key() public_key_hash = \ hashlib.sha256( signing.encode_pubkey( signing.generate_pubkey(key), 'hex')).hexdigest() key2 = signed_object.generate_signing_key() validator_id = signed_object.generate_identifier(key) name = 'DasValidator' signup_info = \ SignupInfo.create_signup_info( originator_public_key_hash=public_key_hash, most_recent_wait_certificate_id='0' * 16) store = ObjectStore() transaction = \ ValidatorRegistryTransaction.register_validator( name, validator_id, signup_info) transaction.sign_object(key2) with self.assertRaises(InvalidTransactionError): transaction.check_valid(store) self.fail("Failure: Verified an invalid transaction")
def setUp(self): self.private_key = signing.generate_privkey() self.public_key = signing.encode_pubkey( signing.generate_pubkey(self.private_key), "hex") self._out = queue.Queue() self._in = queue.Queue() self._in_condition = Condition() self._out_condition = Condition() self.verifier = SignatureVerifier(self._in, self._out, self._in_condition, self._out_condition)
def generate_identifier(signingkey): """Generates encoded version of the public key associated with signingkey. Args: signingkey (str): A private key. Returns: str: An encoded 'address' associated with the public key. """ return signing.generate_identifier(signing.generate_pubkey(signingkey))
def __init__(self, base_url, keyfile): self._base_url = base_url try: with open(keyfile) as fd: self._private_key = fd.read().strip() fd.close() except: raise IOError("Failed to read keys.") self._public_key = signing.generate_pubkey(self._private_key)
def _sign_block(self, block): """ The block should be complete and the final signature from the publishing validator(this validator) needs to be added. """ # Temp signature creation to use as identifier temp_key = signing.generate_privkey() public_key = signing.encode_pubkey(signing.generate_pubkey(temp_key), "hex") block.block_header.signer_pubkey = public_key block_header = block.block_header header_bytes = block_header.SerializeToString() signature = signing.sign(header_bytes, temp_key) block.set_signature(signature) return block
def __init__(self, base_url, store_name=None, name='SawtoothClient', txntype_name=None, msgtype_name=None, keystring=None, keyfile=None, disable_client_validation=False): self._base_url = base_url self._message_type = msgtype_name self._transaction_type = txntype_name # an explicit store name takes precedence over a store name # implied by the transaction type self._store_name = None if store_name is not None: self._store_name = store_name.strip('/') elif txntype_name is not None: self._store_name = txntype_name.strip('/') self._communication = _Communication(base_url) self._last_transaction = None self._signing_key = None self._identifier = None self._update_batch = None self._disable_client_validation = disable_client_validation if keystring: LOGGER.debug("set signing key from string\n%s", keystring) self._signing_key = signing.encode_privkey( signing.decode_privkey(keystring, 'wif'), 'hex') elif keyfile: LOGGER.debug("set signing key from file %s", keyfile) try: self._signing_key = signing.encode_privkey( signing.decode_privkey( open(keyfile, "r").read().strip(), 'wif'), 'hex') except IOError as ex: raise ClientException("Failed to load key file: {}".format( str(ex))) if self._signing_key is not None: self._identifier = signing.generate_identifier( signing.generate_pubkey(self._signing_key))
def sign_object(self, signingkey): """Generates a string signature for the object using the signing key. Args: signingkey (str): hex encoded private key """ if self.public_key is None: self.public_key = signing.encode_pubkey( signing.generate_pubkey(signingkey), "hex") self._originator_id = None self._originator_public_key = None serialized = self.serialize(signable=True) self.Signature = signing.sign(serialized, signingkey) self._recover_verifying_address() self._identifier = hashlib.sha256(self.Signature).hexdigest()
def do_init(args, config): username = config.get('DEFAULT', 'username') if args.username is not None: username = args.username url = config.get('DEFAULT', 'url') if args.url is not None: url = args.url config.set('DEFAULT', 'username', username) print("set username: {}".format(username)) config.set('DEFAULT', 'url', url) print("set url: {}".format(url)) save_config(config) wif_filename = config.get('DEFAULT', 'key_file') if wif_filename.endswith(".wif"): addr_filename = wif_filename[0:-len(".wif")] + ".addr" else: addr_filename = wif_filename + ".addr" if not os.path.exists(wif_filename): try: if not os.path.exists(os.path.dirname(wif_filename)): os.makedirs(os.path.dirname(wif_filename)) privkey = signing.generate_privkey() encoded = signing.encode_privkey(privkey, 'wif') pubkey = signing.generate_pubkey(privkey) addr = signing.generate_identifier(pubkey) with open(wif_filename, "w") as wif_fd: print("writing file: {}".format(wif_filename)) wif_fd.write(encoded) wif_fd.write("\n") with open(addr_filename, "w") as addr_fd: print("writing file: {}".format(addr_filename)) addr_fd.write(addr) addr_fd.write("\n") except IOError as ioe: raise XoException("IOError: {}".format(str(ioe)))
def find_or_create_test_key(key_base_name, key_dir=None, quiet=True): ''' Interface to sawtooth cli: creates .wif key file if it does not exist, and returns a tupple containing all pertinent information. Useful for testing. Args: key_base_name: (str) key_dir: (str) Returns: (tupple) key_file: (str) private_key: (str) public_key: (str) ''' use_key_dir = key_dir is not None and not os.path.isabs(key_base_name) key_file = key_base_name if not key_file.endswith('.wif'): key_file += '.wif' if use_key_dir: key_file = os.path.join(key_dir, key_file) if not os.path.isfile(key_file): if key_base_name.endswith('.wif'): key_base_name = ''.join(key_base_name.split('.')[:-1]) cmd = 'keygen %s' % key_base_name if use_key_dir: cmd += ' --key-dir %s' % key_dir if quiet is True: cmd += ' -q' sawtooth_cli_intercept(cmd) assert os.path.exists(key_file) with open(key_file, 'r') as f: key_str = f.read() signing_key = key_str.split('\n')[0] identifier = signing.generate_identifier( signing.generate_pubkey(signing_key)) addr_file = '.'.join(key_file.split('.')[:-1]) + '.addr' if not os.path.exists(addr_file): with open(addr_file, 'w') as f: f.write('{}\n'.format(identifier)) return key_file, signing_key, identifier
def test_is_valid_pub_key(self): pubkey = signing.generate_pubkey("5KQ4iQQGgbQX9MmfiPUwwHBL1R" "GPa86NwFbqrWoodjuzruqFVDd") pub = signing.encode_pubkey(pubkey, "hex") minfo = { 'Nonce': 100, 'PublicKey': pub, 'TransactionType': '/Transaction', 'Dependencies': [] } sig = signing.sign( signed_object.dict2cbor(minfo), "5KQ4iQQGgbQX9MmfiPUwwHBL1RGPa86NwFbqrWoodjuzruqFVDd") # Create valid transaction minfo["Signature"] = sig temp = Transaction(minfo) self.assertTrue(temp.is_valid("unused")) # Change transaction after it was signed minfo["Nonce"] = time.time() temp = Transaction(minfo) self.assertFalse(temp.is_valid("unused"))
def submit_rates(self, effective_date, rates): """Submit a set of rates to the blockchain. Args: effective_date: The date the rates were published. This may be provided as either a string in ISO-8601 format ("YYYY-MM-DD"), a datetime, or a date object. rate: A dictionary mapping maturity periods to rate values. The following keys must be present: Overnight, OneWeek, OneMonth, TwoMonth, ThreeMonth, SixMonth, OneYear """ if self._libor_key_file is None: raise LIBORClientException( "Submitting LIBOR data requires a LIBOR signing key") # If we have a datetime or date object, get the ISO-8601 format string if isinstance(effective_date, datetime): effective_date = effective_date.date().isoformat() elif isinstance(effective_date, date): effective_date = effective_date.isoformat() signing_key = \ signed_object.generate_signing_key( wifstr=open(self._libor_key_file, "r").read().strip()) libor_public_key = signing.generate_pubkey(signing_key) # Add a signature to the actual update to simulate having a verified # source of information signed_update = LIBORObject(date=effective_date, rates=rates, libor_public_key=libor_public_key) signed_update.sign_object(signing_key) # Create the update and the submit the transaction update = {'UpdateType': 'CreateLIBOR'} update.update(signed_update.dump()) return self.sendtxn(BondTransaction, BondTransaction.MessageType, {'Updates': [update]})
def _sign_message_with_transaction(transaction, message_type, key): """ Signs a transaction message or transaction :param transaction (dict): :param key (str): A signing key returns message, txnid (tuple): The first 16 characters of a sha256 hexdigest. """ transaction['Nonce'] = time.time() pub = signing.encode_pubkey(signing.generate_pubkey(key), "hex") transaction["public_key"] = pub sig = signing.sign(_dict2cbor(transaction), key) transaction['Signature'] = sig txnid = hashlib.sha256(transaction['Signature']).hexdigest()[:16] message = { 'Transaction': transaction, '__TYPE__': message_type, '__NONCE__': time.time(), } cbor_serialized_message = _dict2cbor(message) signature = signing.sign(cbor_serialized_message, key) message['__SIGNATURE__'] = signature return message, txnid
def __init__(self): self.SigningKey = signing.generate_privkey() self.Address = signing.generate_identifier( signing.generate_pubkey(self.SigningKey))
def create_signup_info(cls, originator_public_key_hash, most_recent_wait_certificate_id): with cls._lock: # First we need to create a public/private key pair for the PoET # enclave to use. cls._poet_private_key = signing.generate_privkey() cls._poet_public_key = \ signing.generate_pubkey(cls._poet_private_key) cls._active_wait_timer = None # We are going to fake out the sealing the signup data. signup_data = { 'poet_public_key': signing.encode_pubkey(cls._poet_public_key, 'hex'), 'poet_private_key': signing.encode_privkey(cls._poet_private_key, 'hex') } sealed_signup_data = \ base64.b64encode(dict2json(signup_data)) # Create a fake report report_data = '{0}{1}'.format( originator_public_key_hash.upper(), signing.encode_pubkey(cls._poet_public_key, 'hex').upper()) quote = { 'report_body': hashlib.sha256(dict2json(report_data)).hexdigest() } # Fake our "proof" data. verification_report = { 'id': base64.b64encode( hashlib.sha256( datetime.datetime.now().isoformat()).hexdigest()), 'isvEnclaveQuoteStatus': 'OK', 'isvEnclaveQuoteBody': base64.b64encode(dict2json(quote)), 'pseManifestStatus': 'OK', 'pseManifestHash': base64.b64encode( hashlib.sha256(b'Do you believe in ' 'manifest destiny?').hexdigest()), 'nonce': most_recent_wait_certificate_id } proof_data_dict = { 'verification_report': dict2json(verification_report), 'signature': signing.sign(dict2json(verification_report), cls._report_private_key) } proof_data = dict2json(proof_data_dict) return \ EnclaveSignupInfo( poet_public_key=signup_data['poet_public_key'], proof_data=proof_data, anti_sybil_id=originator_public_key_hash, sealed_signup_data=sealed_signup_data)
class _PoetEnclaveSimulator(object): # A lock to protect threaded access _lock = threading.Lock() # The WIF-encoded enclave private seal key. From it, we will create # private and public keys we can use for sealing and unsealing signup # info. __SEAL_PRIVATE_KEY_WIF = \ '5KYsbooGBg51Gohakgq45enpXvCXmEBed1JivFfUZskmjLegHBG' _seal_private_key = \ signing.decode_privkey(__SEAL_PRIVATE_KEY_WIF, 'wif') _seal_public_key = signing.generate_pubkey(_seal_private_key) # The WIF-encoded private report key. From it, we will create private # key we can use for signing attestation verification reports. __REPORT_PRIVATE_KEY_WIF = \ '5Jz5Kaiy3kCiHE537uXcQnJuiNJshf2bZZn43CrALMGoCd3zRuo' _report_private_key = \ signing.decode_privkey(__REPORT_PRIVATE_KEY_WIF, 'wif') _report_public_key = signing.generate_pubkey(_report_private_key) # Minimum duration for PoET 1 simulator is 30 seconds __MINIMUM_DURATTION = 30.0 # The anti-sybil ID for this particular validator. This will get set when # the enclave is initialized _anti_sybil_id = None # The PoET keys will remain unset until signup info is either created or # unsealed _poet_public_key = None _poet_private_key = None _active_wait_timer = None @classmethod def initialize(cls, **kwargs): # Create an anti-Sybil ID that is unique for this validator cls._anti_sybil_id = \ hashlib.sha256( kwargs.get('NodeName', 'validator')).hexdigest() @classmethod def create_signup_info(cls, originator_public_key_hash, most_recent_wait_certificate_id): with cls._lock: # First we need to create a public/private key pair for the PoET # enclave to use. cls._poet_private_key = signing.generate_privkey() cls._poet_public_key = \ signing.generate_pubkey(cls._poet_private_key) cls._active_wait_timer = None # We are going to fake out the sealing the signup data. signup_data = { 'poet_public_key': signing.encode_pubkey(cls._poet_public_key, 'hex'), 'poet_private_key': signing.encode_privkey(cls._poet_private_key, 'hex') } sealed_signup_data = \ base64.b64encode(dict2json(signup_data)) # Create a fake report report_data = '{0}{1}'.format( originator_public_key_hash.upper(), signing.encode_pubkey(cls._poet_public_key, 'hex').upper()) quote = { 'report_body': hashlib.sha256(dict2json(report_data)).hexdigest() } # Fake our "proof" data. verification_report = { 'id': base64.b64encode( hashlib.sha256( datetime.datetime.now().isoformat()).hexdigest()), 'isvEnclaveQuoteStatus': 'OK', 'isvEnclaveQuoteBody': base64.b64encode(dict2json(quote)), 'pseManifestStatus': 'OK', 'pseManifestHash': base64.b64encode( hashlib.sha256(b'Do you believe in ' 'manifest destiny?').hexdigest()), 'nonce': most_recent_wait_certificate_id } proof_data_dict = { 'verification_report': dict2json(verification_report), 'signature': signing.sign(dict2json(verification_report), cls._report_private_key) } proof_data = dict2json(proof_data_dict) return \ EnclaveSignupInfo( poet_public_key=signup_data['poet_public_key'], proof_data=proof_data, anti_sybil_id=originator_public_key_hash, sealed_signup_data=sealed_signup_data) @classmethod def deserialize_signup_info(cls, serialized_signup_info): return \ EnclaveSignupInfo.signup_info_from_serialized( serialized_signup_info=serialized_signup_info) @classmethod def unseal_signup_data(cls, sealed_signup_data): """ Args: sealed_signup_data: Sealed signup data that was returned previously in a EnclaveSignupInfo object from a call to create_signup_info Returns: A string The hex encoded PoET public key that was extracted from the sealed data """ # Reverse the process we used in creating "sealed" signup info. # Specifically, we will do a base 32 decode, which gives us json # we can convert back to a dictionary we can use to get the # data we need signup_data = \ json2dict(base64.b64decode(sealed_signup_data)) with cls._lock: cls._poet_public_key = \ signing.decode_pubkey( signup_data.get('poet_public_key'), 'hex') cls._poet_private_key = \ signing.decode_privkey( signup_data.get('poet_private_key'), 'hex') cls._active_wait_timer = None return signup_data.get('poet_public_key') @classmethod def verify_signup_info(cls, signup_info, originator_public_key_hash, most_recent_wait_certificate_id): # Verify the attestation verification report signature proof_data_dict = json2dict(signup_info.proof_data) verification_report = proof_data_dict.get('verification_report') if verification_report is None: raise \ SignupInfoError( 'Verification report is missing from proof data') signature = proof_data_dict.get('signature') if signature is None: raise \ SignupInfoError( 'Signature is missing from proof data') if not signing.verify(verification_report, signature, cls._report_public_key): raise \ SignupInfoError('Verification report signature is invalid') verification_report_dict = json2dict(verification_report) # Verify that the verification report contains a PSE manifest status # and it is OK pse_manifest_status = \ verification_report_dict.get('pseManifestStatus') if pse_manifest_status is None: raise \ SignupInfoError( 'Verification report does not contain a PSE manifest ' 'status') if pse_manifest_status != 'OK': raise \ SignupInfoError( 'PSE manifest status is {} (i.e., not OK)'.format( pse_manifest_status)) # Verify that the verification report contains a PSE manifest hash # and it is the value we expect pse_manifest_hash = \ verification_report_dict.get('pseManifestHash') if pse_manifest_hash is None: raise \ SignupInfoError( 'Verification report does not contain a PSE manifest ' 'hash') expected_pse_manifest_hash = \ base64.b64encode( hashlib.sha256( b'Do you believe in manifest destiny?').hexdigest()) if pse_manifest_hash != expected_pse_manifest_hash: raise \ SignupInfoError( 'PSE manifest hash {0} does not match {1}'.format( pse_manifest_hash, expected_pse_manifest_hash)) # Verify that the verification report contains an enclave quote and # that its status is OK enclave_quote_status = \ verification_report_dict.get('isvEnclaveQuoteStatus') if enclave_quote_status is None: raise \ SignupInfoError( 'Verification report does not contain an enclave quote ' 'status') if enclave_quote_status != 'OK': raise \ SignupInfoError( 'Enclave quote status is {} (i.e., not OK)'.format( enclave_quote_status)) enclave_quote = verification_report_dict.get('isvEnclaveQuoteBody') if enclave_quote is None: raise \ SignupInfoError( 'Verification report does not contain an enclave quote') # Verify that the enclave quote contains a report body with the value # we expect (i.e., SHA256(SHA256(OPK)|PPK) report_data = '{0}{1}'.format(originator_public_key_hash.upper(), signup_info.poet_public_key.upper()) expected_report_body = hashlib.sha256( dict2json(report_data)).hexdigest() enclave_quote_dict = \ json2dict(base64.b64decode(enclave_quote)) report_body = enclave_quote_dict.get('report_body') if report_body is None: raise \ SignupInfoError( 'Enclave quote does not contain a report body') if report_body != expected_report_body: raise \ SignupInfoError( 'Enclave quote report body {0} does not match {1}'.format( report_body, expected_report_body)) # Verify that the wait certificate ID in the verification report # matches the provided wait certificate ID. The wait certificate ID # is stored in the nonce field. nonce = verification_report_dict.get('nonce') if nonce is None: raise \ SignupInfoError( 'Verification report does not have a nonce') # NOTE - this check is currently not performed as a transaction # does not have a good way to obtaining the most recent # wait certificate ID. # # if nonce != most_recent_wait_certificate_id: # raise \ # SignupInfoError( # 'Attestation evidence payload nonce {0} does not match ' # 'most-recently-committed wait certificate ID {1}'.format( # nonce, # most_recent_wait_certificate_id)) @classmethod def create_wait_timer(cls, previous_certificate_id, local_mean): with cls._lock: # If we don't have a PoET private key, then the enclave has not # been properly initialized (either by calling create_signup_info # or unseal_signup_data) if cls._poet_private_key is None: raise \ WaitTimerError( 'Enclave must be initialized before attempting to ' 'create a wait timer') # Create some value from the cert ID. We are just going to use # the seal key to sign the cert ID. We will then use the # low-order 64 bits to change that to a number [0, 1] tag = \ base64.b64decode( signing.sign( previous_certificate_id, cls._seal_private_key)) tagd = float(struct.unpack('L', tag[-8:])[0]) / (2**64 - 1) # Now compute the duration duration = cls.__MINIMUM_DURATTION - local_mean * math.log(tagd) # Create and sign the wait timer wait_timer = \ EnclaveWaitTimer( duration=duration, previous_certificate_id=previous_certificate_id, local_mean=local_mean) wait_timer.signature = \ signing.sign( wait_timer.serialize(), cls._poet_private_key) # Keep track of the active wait timer cls._active_wait_timer = wait_timer return wait_timer @classmethod def deserialize_wait_timer(cls, serialized_timer, signature): with cls._lock: # Verify the signature before trying to deserialize if not signing.verify(serialized_timer, signature, cls._poet_public_key): return None return \ EnclaveWaitTimer.wait_timer_from_serialized( serialized_timer=serialized_timer, signature=signature) @classmethod def create_wait_certificate(cls, block_digest): with cls._lock: # If we don't have a PoET private key, then the enclave has not # been properly initialized (either by calling create_signup_info # or unseal_signup_data) if cls._poet_private_key is None: raise \ WaitCertificateError( 'Enclave must be initialized before attempting to ' 'create a wait certificate') # Several criteria need to be met before we can create a wait # certificate: # 1. We have an active timer # 2. The active timer has expired # 3. The active timer has not timed out # # Note - we make a concession for the genesis block (i.e., a wait # timer for which the previous certificate ID is the Null # identifier) in that we don't require the timer to have expired # and we don't worry about the timer having timed out. if cls._active_wait_timer is None: raise \ WaitCertificateError( 'Enclave active wait timer has not been initialized') is_not_genesis_block = \ (cls._active_wait_timer.previous_certificate_id != NullIdentifier) now = time.time() expire_time = \ cls._active_wait_timer.request_time + \ cls._active_wait_timer.duration if is_not_genesis_block and now < expire_time: raise \ WaitCertificateError( 'Cannot create wait certificate because timer has ' 'not expired') time_out_time = \ cls._active_wait_timer.request_time + \ cls._active_wait_timer.duration + \ TIMER_TIMEOUT_PERIOD if is_not_genesis_block and time_out_time < now: raise \ WaitCertificateError( 'Cannot create wait certificate because timer ' 'has timed out') # Create a random nonce for the certificate. For our "random" # nonce we will take the timer signature, concat that with the # current time, JSON-ize it and create a SHA-256 hash over it. # Probably not considered random by security professional # standards, but it is good enough for the simulator. random_string = \ dict2json({ 'wait_timer_signature': cls._active_wait_timer.signature, 'now': datetime.datetime.utcnow().isoformat() }) nonce = hashlib.sha256(random_string).hexdigest() # First create a new enclave wait certificate using the data # provided and then sign the certificate with the PoET private key wait_certificate = \ EnclaveWaitCertificate.wait_certificate_with_wait_timer( wait_timer=cls._active_wait_timer, nonce=nonce, block_digest=block_digest) wait_certificate.signature = \ signing.sign( wait_certificate.serialize(), cls._poet_private_key) # Now that we have created the certificate, we no longer have an # active timer cls._active_wait_timer = None return wait_certificate @classmethod def deserialize_wait_certificate(cls, serialized_certificate, signature): return \ EnclaveWaitCertificate.wait_certificate_from_serialized( serialized_certificate=serialized_certificate, signature=signature) @classmethod def verify_wait_certificate(cls, certificate, poet_public_key): # Reconstitute the PoET public key and check the signature over the # serialized wait certificate. decoded_poet_public_key = \ signing.decode_pubkey(poet_public_key, 'hex') return \ signing.verify( certificate.serialize(), certificate.signature, decoded_poet_public_key)
def test_libor_update(self): key = signed_object.generate_signing_key() store = ObjectStore() libor_key = TestCreateLIBORUpdate.libor_key libor_public_key = signing.generate_pubkey(libor_key) update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='2016-05-24', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction = BondTransaction() transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) except InvalidTransactionError as e: self.fail('This transaction should be valid\n error:' + str(e)) try: store.lookup('libor:date', '2016-05-24') self.fail('LIBOR data for 2016-05-24 should not be in store') except KeyError: pass transaction.apply(store) self.assertIsNotNone(store.lookup('libor:date', '2016-05-24')) update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='2016-05-25', rates={ 'Overnight': '0.1', 'OneWeek': '-0.1', 'OneMonth': '0', 'TwoMonth': 0.1, 'ThreeMonth': -0.1, 'SixMonth': 0, 'OneYear': 1 }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) except InvalidTransactionError as e: self.fail('This transaction should be valid\n error: ' + str(e)) try: store.lookup('libor:date', '2016-05-25') self.fail('LIBOR data for 2016-05-25 should not be in store') except KeyError: pass transaction.apply(store) self.assertIsNotNone(store.lookup('libor:date', '2016-05-25'))
def test_libor_update_invalid_date(self): key = signed_object.generate_signing_key() store = ObjectStore() libor_key = TestCreateLIBORUpdate.libor_key libor_public_key = signing.generate_pubkey(libor_key) update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='2016-01-32', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction = BondTransaction() transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='2016-12-32', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, signature='HG/+Byml9CU13jdMD9TvOtlNlLvAO5jzBGUqoJGSng2ksojoh8' 'mUxYKJ4rTE5pZ4Q1S+lHRLuQLVgprhQkY25eQ=') transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='2015-02-29', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='2016-02-30', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='2016-13-30', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, signature='G4JyMWYLEWwwSQlOLHWDclAKB2kXersC/cuc3VbzyRTJ92Nj' 'e2nGPgSIsQzQ4uR94r9pYi1S6E4z7zQrdwCCKlg=') transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='2016-00-15', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='2016-01-00', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass
def test_libor_update_invalid_date_format(self): key = signed_object.generate_signing_key() store = ObjectStore() libor_key = TestCreateLIBORUpdate.libor_key libor_public_key = signing.generate_pubkey(libor_key) update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='05/24/2016', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction = BondTransaction() transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='05-24-2016', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, signature='G7OL7YDOVHzOevEaGgg1PvnpxiRhws7vdut3F1RUdMXDNH6gH' 'sY9nk/Zt+WwQYo/4QhZOY6CO0Inv5HUi8MyrPo=') transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='May 24, 2016', rates={ 'OneWeek': 0.1, 'Overnight': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='24-May-2016', rates={ 'OneWeek': 0.1, 'Overnight': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='May 24 2016', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='24 May 2016', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1 }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass update = \ CreateLIBORUpdate( update_type='CreateLIBOR', date='', rates={ 'Overnight': 0.1, 'OneWeek': 0.1, 'OneMonth': 0.1, 'TwoMonth': 0.1, 'ThreeMonth': 0.1, 'SixMonth': 0.1, 'OneYear': 0.1, }, libor_public_key=libor_public_key) update.sign_update_object(libor_key) transaction._updates = [update] transaction.sign_object(key) try: transaction.check_valid(store) self.fail('This transaction should be invalid') except InvalidTransactionError: pass
wif_filename = os.path.join(key_dir, key_name + '.wif') addr_filename = os.path.join(key_dir, key_name + '.addr') if not args.force: file_exists = False for filename in [wif_filename, addr_filename]: if os.path.exists(filename): file_exists = True print >> sys.stderr, 'file exists: {}'.format(filename) if file_exists: raise ClientException( 'files exist, rerun with --force to overwrite existing files') privkey = signing.generate_privkey() encoded = signing.encode_privkey(privkey) pubkey = signing.generate_pubkey(privkey) addr = signing.generate_identifier(pubkey) try: wif_exists = os.path.exists(wif_filename) with open(wif_filename, 'w') as wif_fd: if not args.quiet: if wif_exists: print 'overwriting file: {}'.format(wif_filename) else: print 'writing file: {}'.format(wif_filename) wif_fd.write(encoded) wif_fd.write('\n') addr_exists = os.path.exists(addr_filename) with open(addr_filename, 'w') as addr_fd:
def get_address_from_private_key_wif(key): return signing.generate_identifier( signing.generate_pubkey(signing.decode_privkey(key, 'wif')))
def create_random_public_key(): return signing.generate_pubkey(create_random_private_key())