def __init__(self, verifying_key, encryption_key): """ initialize the object :param verifying_key: PEM encoded ECDSA verifying key :param encryption_key: PEM encoded RSA encryption key """ self._verifying_key = crypto.SIG_PublicKey(verifying_key) self._encryption_key = crypto.PKENC_PublicKey(encryption_key)
try: res = epk.VerifySignature(msg, bytes("invalid signature", 'ascii')) except Exception as exc: logger.error("ERROR: Invalid signature detection test failed: ", exc) sys.exit(-1) if (res != 1): logger.debug("Invalid signature detection test successful!") else: logger.error("ERROR: Invalid signature detection test failed.") exit(-1) # TEST RSA try: rsk = crypto.PKENC_PrivateKey() rsk.Generate() rpk = crypto.PKENC_PublicKey(rsk) except Exception as exc: logger.error( "ERROR: Asymmetric encryption Private and Public keys generation test failed: ", exc) sys.exit(-1) logger.debug( "Asymmetric encryption Private and Public keys generation test successful!" ) try: rskString = rsk.Serialize() rpkString = rpk.Serialize() rsk1 = crypto.PKENC_PrivateKey(rskString) rpk1 = crypto.PKENC_PublicKey(rpkString) rskString1 = rsk1.Serialize() rpkString1 = rpk1.Serialize()
def _secretreq(self, minfo): # unpack the request try: enclave_id = minfo['enclave_id'] contract_id = minfo['contract_id'] opk = minfo['opk'] signature = minfo['signature'] except KeyError as ke: raise Error(http.BAD_REQUEST, 'missing required field {0}'.format(ke)) logger.debug('request for key for contract %s, enclave %s', contract_id, enclave_id) # verify the signature, that is, make sure that the request was really signed by opk try: opkkey = pcrypto.SIG_PublicKey(opk) opkkey.VerifySignature( pcrypto.string_to_byte_array(enclave_id + contract_id), pcrypto.hex_to_byte_array(signature)) except: logger.warn("Signature verification failed") raise Error(http.BAD_REQUEST, 'Signature Mismatch') # Get enclave state try: logger.debug('retrieve information for enclave %s', enclave_id) enclave_info = self.__registry_helper.get_enclave_dict(enclave_id) logger.debug("enclave information retrieved: %s", enclave_info) except BaseException as err: logger.warn( 'exception occurred when getting ledger information for enclave %s; %s', enclave_id, str(err)) raise Error(http.BAD_REQUEST, 'could not retrieve enclave state; {0}'.format(err)) except ClientConnectException as err: logger.warn( 'client exception occurred when getting ledger information for enclave %s; %s', enclave_id, str(err)) raise Error(http.BAD_REQUEST, 'could not retrieve enclave state; {0}'.format(err)) # Get contract state try: logger.debug('retrieve information for contract <%s>', contract_id) contract_info = self.__registry_helper.get_contract_dict( contract_id) logger.debug("contract_info from ledger: %s", contract_info) except BaseException as err: logger.warn( 'exception occurred when getting ledger information for contract %s; %s', contract_id, str(err)) raise Error(http.BAD_REQUEST, 'could not retrieve contract state; {0}'.format(err)) except ClientConnectException as err: logger.warn( 'client exception occurred when getting ledger information for contract %s; %s', contract_id, str(err)) raise Error(http.BAD_REQUEST, 'could not retrieve contract state; {0}'.format(err)) # make sure that the signer of this request is really the owner of the contract try: # make sure that the signer of this request is really the owner of the contract # PdoContractInfo.pdo_contract_creator_pem_key is the VerifyingKey logger.debug("Contract creator's public key: %s", contract_info['pdo_contract_creator_pem_key']) logger.debug("Expected public key: %s", opk) assert contract_info['pdo_contract_creator_pem_key'] == opk except: logger.error( 'request to create secret did not come from the contract owner; %s != %s', contracttxn.OriginatorID, opk) raise Error(http.NOT_ALLOWED, 'operation not allowed for {0}'.format(opk)) # make sure the provisioning service is allowed to access contract by the checking the list of allowed provisioning services try: logger.debug("Contract allowed service ids: %s", contract_info['provisioning_service_ids']) logger.debug("Expected provisioning service id: %s", self.PSPK.Serialize()) assert self.PSPK.Serialize( ) in contract_info['provisioning_service_ids'] except: logger.error( 'This Pservice is not the list of allowed provisioning services, PSerivce ID: %s', self.PSPK.Serialize()) raise Error( http.NOT_ALLOWED, 'operation not allowed for {0}'.format(self.PSPK.Serialize())) # retrieve the secret secret = self._GetContractSecret(contract_id) # create the signature message = secret + enclave_id + contract_id + opk secretsig = pcrypto.byte_array_to_hex( self.SigningKey.SignMessage(pcrypto.string_to_byte_array(message))) # pad secret to required max size # TODO: Eventually this requirement needs to be fixed in the crypto library itself required_padding = 2 * pcrypto.MAX_SIG_SIZE - len(secretsig) secretsig = secretsig + ('0' * required_padding) enclavekey = pcrypto.PKENC_PublicKey(enclave_info['encryption_key']) esecret = pcrypto.byte_array_to_base64( enclavekey.EncryptMessage( pcrypto.string_to_byte_array(secret + secretsig))) logger.debug("Encrypted secret for contract %s: %s", contract_id, esecret) # create the response response = dict() response['pspk'] = self.PSPK.Serialize() response['encrypted_secret'] = esecret logger.info('created secret for contract %s and enclave %s', contract_id, enclave_id) return response