def add_new_channel(self, nA, nB): a_signkey = SigningKey.generate() a_chankey = PrivateKey.generate() a_CIDkey = os.urandom(32) a_transports = nA.agent.individualize_transports(nA.agent.get_transports()) b_signkey = SigningKey.generate() b_chankey = PrivateKey.generate() b_CIDkey = os.urandom(32) b_transports = nB.agent.individualize_transports(nB.agent.get_transports()) a_rec = { "channel_pubkey": a_chankey.public_key.encode().encode("hex"), "CID_key": a_CIDkey.encode("hex"), "transports": a_transports.values(), } b_rec = { "channel_pubkey": b_chankey.public_key.encode().encode("hex"), "CID_key": b_CIDkey.encode("hex"), "transports": b_transports.values(), } q = ("INSERT INTO addressbook" " (petname, acked, next_outbound_seqnum," " my_signkey," " their_channel_record_json," " my_CID_key, next_CID_token," " highest_inbound_seqnum," " my_old_channel_privkey, my_new_channel_privkey," " they_used_new_channel_key, their_verfkey)" " VALUES(?,?,?,?,?,?,?,?,?,?,?,?)") vA=("petname-from-A", 1, 1, a_signkey.encode().encode("hex"), json.dumps(b_rec), a_CIDkey.encode("hex"), None, 0, a_chankey.encode().encode("hex"), a_chankey.encode().encode("hex"), 0, b_signkey.verify_key.encode().encode("hex"), ) vB=("petname-from-A", 1, 1, b_signkey.encode().encode("hex"), json.dumps(a_rec), b_CIDkey.encode("hex"), None, 0, b_chankey.encode().encode("hex"), b_chankey.encode().encode("hex"), 0, a_signkey.verify_key.encode().encode("hex"), ) nA.db.execute(q, vA) nA.db.commit() nB.db.execute(q, vB) nA.db.commit() entA = nA.db.execute("SELECT * FROM addressbook").fetchone() entB = nB.db.execute("SELECT * FROM addressbook").fetchone() return entA, entB
def test_worker_key_pair_tool(): key_file = "gen_pair_test" private_key, public_key = gen_pair(key_file) test_phrase = b"Test phrase" try: public_key.verify(private_key.sign(test_phrase)) except BadSignatureError as bse: assert False # load the generated keys from the file with open(key_file, 'r') as f: loaded_private_key = SigningKey(f.read().encode(), encoder=HexEncoder) with open(key_file + '.pub', 'r') as f: loaded_public_key = VerifyKey(f.read().encode(), encoder=HexEncoder) # test the try: loaded_public_key.verify(loaded_private_key.sign(test_phrase)) except BadSignatureError as bse: assert False assert verify_pair(key_file) # test that a bad signature is detected with open(key_file, 'w') as f: f.write( SigningKey.generate().encode(encoder=HexEncoder).decode('utf-8')) assert not verify_pair(key_file) # clean up os.remove(key_file) os.remove(key_file + '.pub')
def __init__(self): self.signing_key = SigningKey.generate() self.verify_key = self.signing_key.verify_key self.sealed_votes = {} # user token -> sealed_vote self.unsealed_votes = {} # user token -> vote self._sealed_vote_cache = {} # commitment -> user token
def test_verify_with_prefix(self): sk = SigningKey.generate() vk = sk.verify_key m = "body" prefix = "prefix:" sk2 = SigningKey.generate() sm1 = sk.sign(prefix+m) sm2 = sk.sign("not the prefix"+m) sm3 = sk2.sign(prefix+m) self.failUnlessEqual(util.verify_with_prefix(vk, sm1, prefix), m) self.failUnlessRaises(errors.BadSignatureError, util.verify_with_prefix, vk, sm2, prefix) self.failUnlessRaises(CryptoError, util.verify_with_prefix, vk, sm3, prefix)
def __init__( self, credentials: Dict, url: str, conn_type: Type[ClientConnection], client_type: Type[Client], ) -> None: # Use Server metadata # to build client route self.conn = conn_type(url=url) # type: ignore self.client_type = client_type if credentials: metadata, _user_key = self.conn.login(credentials=credentials) # type: ignore _user_key = SigningKey(_user_key.encode("utf-8"), encoder=HexEncoder) else: metadata = self.conn._get_metadata() # type: ignore if not user_key: _user_key = SigningKey.generate() else: _user_key = user_key ( spec_location, name, client_id, ) = self.client_type.deserialize_client_metadata_from_node( metadata=metadata ) # Create a new Solo Route using the selected connection type route = SoloRoute(destination=spec_location, connection=self.conn) location_args = self.__route_client_location( client_type=self.client_type, location=spec_location ) self.proxy_address: Optional[Address] = None # Create a new client using the selected client type super().__init__( network=location_args[NetworkClient], domain=location_args[DomainClient], device=location_args[DeviceClient], vm=location_args[VirtualMachineClient], name=name, routes=[route], signing_key=_user_key, ) self.groups = GroupRequestAPI(send=self.__perform_grid_request) self.users = UserRequestAPI(send=self.__perform_grid_request) self.roles = RoleRequestAPI(send=self.__perform_grid_request) self.workers = WorkerRequestAPI( send=self.__perform_grid_request, domain_client=self ) self.association_requests = AssociationRequestAPI( send=self.__perform_grid_request )
def __init__(self, url: str, conn_type: type, client_type: Type[NetworkClient]) -> None: # Load an Signing Key instance signing_key = SigningKey.generate() verify_key = signing_key.verify_key # Use Signaling Server metadata # to build client route conn = conn_type(url=url) ( spec_location, name, client_id, ) = client_type.deserialize_client_metadata_from_node( metadata=conn._get_metadata()) # Create a new Solo Route using the selected connection type route = SoloRoute(destination=spec_location, connection=conn) # Create a new signaling client using the selected client type signaling_client = client_type( network=spec_location, name=name, routes=[route], signing_key=signing_key, verify_key=verify_key, ) self.__client = signaling_client self.__register()
def signup_user(email, password, role=None, private_key=None): user_role = None user = None try: user, user_role = identify_user(private_key) except Exception as e: logging.warning("Existing user could not be linked") if private_key is not None and (user is None or user_role is None): raise InvalidCredentialsError # generate a signing key private_key = SigningKey.generate() salt, hashed = salt_and_hash_password(password, 12) no_user = len(db.session.query(User).all()) == 0 if no_user: role = db.session.query(Role.id).filter_by(name="Owner").first() if role is None: raise RoleNotFoundError role = role[0] new_user = User( email=email, hashed_password=hashed, salt=salt, private_key=node.signing_key.encode( encoder=HexEncoder).decode("utf-8"), role=role, ) elif role is not None and user_role is not None and user_role.can_create_users: if db.session.query(Role).get(role) is None: raise RoleNotFoundError new_user = User( email=email, hashed_password=hashed, salt=salt, private_key=private_key.encode(encoder=HexEncoder).decode("utf-8"), role=role, ) else: role = db.session.query(Role.id).filter_by(name="User").first() if role is None: raise RoleNotFoundError role = role[0] new_user = User( email=email, hashed_password=hashed, salt=salt, private_key=private_key.encode(encoder=HexEncoder).decode("utf-8"), role=role, ) db.session.add(new_user) db.session.commit() # Add the new key in verify_key_registry node.guest_verify_key_registry.add(private_key.verify_key) user = expand_user_object(new_user) return {"user": user}
def big_store(omq, random_sn, exclude): sk = SigningKey.generate() swarm = ss.get_swarm(omq, random_sn, sk) sn = ss.random_swarm_members(swarm, 1, exclude)[0] conn = omq.connect_remote(sn_address(sn)) pk = '03' + sk.verify_key.encode().hex() hashes = [] for x in range(12): s = [] for y in range(10): ts = int(time.time() * 1000) exp = ts + ttl msg = nacl.utils.random(msg_size) s.append(omq.request_future(conn, 'storage.store', [json.dumps({ "pubkey": pk, "timestamp": ts, "ttl": ttl, "data": base64.b64encode(msg).decode()}).encode()])) for si in s: si = si.get() assert len(si) == 1 si = json.loads(si[0]) assert 'hash' in si hashes.append(si['hash']) return { 'conn': conn, 'sk': sk, 'pk': pk, 'hashes': hashes }
def test_verify_with_prefix(self): sk = SigningKey.generate() vk = sk.verify_key m = "body" prefix = "prefix:" sk2 = SigningKey.generate() sm1 = sk.sign(prefix + m) sm2 = sk.sign("not the prefix" + m) sm3 = sk2.sign(prefix + m) self.failUnlessEqual(util.verify_with_prefix(vk, sm1, prefix), m) self.failUnlessRaises(errors.BadSignatureError, util.verify_with_prefix, vk, sm2, prefix) self.failUnlessRaises(CryptoError, util.verify_with_prefix, vk, sm3, prefix)
def route_logic(message_class, current_user, msg_content): # grid relative from .node import get_node # TODO: fix circular import if current_user: user_key = SigningKey(current_user.private_key.encode("utf-8"), encoder=HexEncoder) msg_content["internal_key"] = current_user.private_key msg_content["current_user"] = current_user.id else: user_key = SigningKey.generate() content = { "address": get_node().address, "content": msg_content, "reply_to": get_node().address, } syft_message = {} syft_message["message_class"] = message_class syft_message["message_content"] = content syft_message["sign_key"] = user_key # Execute task response_msg = task_handler( route_function=process_as_syft_message, data=syft_message, mandatory={ "message_class": MissingRequestKeyError, "message_content": MissingRequestKeyError, "sign_key": MissingRequestKeyError, }, ) return response_msg
def __init__( self, instr: StreamReader, outstr: StreamWriter, *, encoding: str = "utf-8", ): self.instr: StreamReader = instr self.outstr: StreamWriter = outstr self.encoding: str = encoding self.can_encrypt: bool = can_encrypt self.open: bool = True self._key_priv: PrivateKey = PrivateKey.generate( ) if self.can_encrypt else None self._key_sign: SigningKey = SigningKey.generate( ) if self.can_encrypt else None self.key_other_pub: PublicKey = None self.key_other_ver: VerifyKey = None self._box: Box = None self.box: Box = None self.total_sent: int = 0 self.total_recv: int = 0
def load_or_create_key(path): if not os.path.exists(path): signing_key = SigningKey.generate() save_key(path, signing_key) else: signing_key = load_key(path) return signing_key
def __init__( self, identifier, seed=None, rpc_server_addr="devnet-seed-0001.nkn.org:30003", reconnect_interval_min=100, reconnect_interval_max=64000, response_timeout_secs=5, msg_holding_secs=3600, **kwargs ): key = Key.generate() if seed is not None: key = Key.from_seed(seed, Encoder) self._key = key pubkey = self._key.verify_key # NKN client address. self._addr = ".".join([ identifier, str(pubkey.encode(Encoder)) ]) # JSON-RPC API client. self._jsonrpc = NknJsonRpcApi(rpc_server_addr) # Websocket API client. self._ws = NknWebsocketApiClient()
def __init__( self, name: Optional[str], routes: List[Route], network: Optional[Location] = None, domain: Optional[Location] = None, device: Optional[Location] = None, vm: Optional[Location] = None, signing_key: Optional[SigningKey] = None, verify_key: Optional[VerifyKey] = None, ): name = f"{name} Client" if name is not None else None super().__init__( name=name, network=network, domain=domain, device=device, vm=vm ) self.routes = routes self.default_route_index = 0 # create a signing key if one isn't provided if signing_key is None: self.signing_key = SigningKey.generate() else: self.signing_key = signing_key # if verify key isn't provided, get verify key from signing key if verify_key is None: self.verify_key = self.signing_key.verify_key else: self.verify_key = verify_key self.install_supported_frameworks() self.store = StoreClient(client=self)
def test_wrong_types(): sk = SigningKey.generate() check_type_error("SigningKey must be created from a 32 byte seed", SigningKey, 12) check_type_error("SigningKey must be created from a 32 byte seed", SigningKey, sk) check_type_error("SigningKey must be created from a 32 byte seed", SigningKey, sk.verify_key) check_type_error("VerifyKey must be created from 32 bytes", VerifyKey, 13) check_type_error("VerifyKey must be created from 32 bytes", VerifyKey, sk) check_type_error("VerifyKey must be created from 32 bytes", VerifyKey, sk.verify_key) def verify_detached_signature(x): sk.verify_key.verify(b"", x) check_type_error("Verification signature must be created from 64 bytes", verify_detached_signature, 13) check_type_error("Verification signature must be created from 64 bytes", verify_detached_signature, sk) check_type_error("Verification signature must be created from 64 bytes", verify_detached_signature, sk.verify_key)
def gen_pair(filename): """ Function to generate a public/private key pair using digital signing. Parameters ---------- filename: str Name of the files to write the public and private key to. Returns ------- SigningKey, VerifyKey: The public, private key generated. """ with open(filename, 'w') as f: sk = SigningKey.generate() hex_seed = sk.encode(encoder=HexEncoder) f.write(hex_seed.decode('utf-8')) print(f'Wrote private key to {filename}') pub_filename = filename + '.pub' with open(pub_filename, 'w') as f: vk = sk.verify_key hex_seed = vk.encode(encoder=HexEncoder) f.write(hex_seed.decode('utf-8')) print(f'Wrote public key to {pub_filename}') return sk, vk
def _make_keys(self): # Makes a set of private and public keys privkey = SigningKey.generate() pubkey = privkey.verify_key pri = privkey.encode(self.key_encoder) pub = pubkey.encode(self.key_encoder) return pri, pub
def create_key_pair(): """ Create and return private_key, public_key """ private_key = SigningKey.generate() public_key = private_key.verify_key return private_key, public_key
def __init__(self): self.signing_key = SigningKey.generate() self.verify_key = self.signing_key.verify_key # self.pk_to_db = {} self.db_to_pk = {} self._cached_voting_group = None self._cached_voting_group_hash = None
def create_dual_keys(self): """Call only when fresh node. These keys _are_ the node.""" # Used only to sign self.signing_key = SigningKey.generate() # For the key exchange for individual-to-individual encryption self.private_key = PrivateKey.generate()
def __init__(self, store=None): self.key = SigningKey.generate() self.public = bytes(self.key.verify_key) self.genesis = self.tail = bytes(self.key.sign(self.public)) log_genesis(self.genesis) self.counter = 0 self.store = (DummyStore() if store is None else store) self.store.write(self.genesis)
async def main(): server_pub_key = b64decode(config['public'][:-8]) client = SHSClient('localhost', 8008, SigningKey.generate(), server_pub_key) await client.open() async for msg in client: print(msg)
def create_account(): """ Create a new account Return signing_key, account_number """ signing_key = SigningKey.generate() account_number = signing_key.verify_key return signing_key, account_number
def test_isvalid(self): sk = SigningKey.generate() pubkey = bytes(sk.verify_key) for length in [0, 1, 2]: msg = os.urandom(length) signed = bytes(sk.sign(pubkey + msg)) self.assertIs(verify.isvalid(signed), True) for bad in iter_permutations(signed): self.assertIs(verify.isvalid(bad), False)
def main(args, conf): log.info('client') sk = SigningKey.generate() req = AccountReq("Matt", Pubkey(bytes(sk.verify_key))) log.info(req.to_dict()) log.info(req) req = Message.from_dict(req.to_dict()) log.info(req) return 0
def test_retrieve_subkey(omq, random_sn, sk, exclude): swarm = ss.get_swarm(omq, random_sn, sk, 3) sn = ss.random_swarm_members(swarm, 1, exclude)[0] conn = omq.connect_remote(sn_address(sn)) ts = int(time.time() * 1000) ttl = 86400000 exp = ts + ttl # Store a message for myself, using master key s = omq.request_future(conn, 'storage.store', [ json.dumps({ "pubkey": '03' + sk.verify_key.encode().hex(), 'namespace': 42, "timestamp": ts, "ttl": ttl, "data": base64.b64encode(b"abc 123").decode(), "signature": sk.sign(f"store42{ts}".encode(), encoder=Base64Encoder).signature.decode(), }).encode() ]).get() assert len(s) == 1 s = json.loads(s[0]) hash = blake2b("{}{}".format(ts, exp).encode() + b'\x03' + sk.verify_key.encode() + b'42' + b'abc 123', encoder=Base64Encoder).decode().rstrip('=') for k, v in s['swarm'].items(): assert hash == v['hash'] # Retrieve it using a subkey dude_sk = SigningKey.generate() c, d, D = make_subkey(sk, dude_sk.verify_key) to_sign = f"retrieve42{ts}".encode() sig = blinded_ed25519_signature(to_sign, dude_sk, d, D) r = omq.request_future(conn, 'storage.retrieve', [ json.dumps({ "pubkey": '03' + sk.verify_key.encode().hex(), "namespace": 42, "timestamp": ts, "signature": base64.b64encode(sig).decode(), "subkey": base64.b64encode(c).decode(), }).encode() ]).get() assert len(r) == 1 r = json.loads(r[0]) assert r["hf"] >= [19, 0] assert len(r["messages"]) == 1 assert r["messages"][0]["hash"] == hash
def generate_sign_key(): """ Generate Ed25519 keypair. :returns: a private key, usable for signing, encoded in base64 :rtype: str: """ sk = SigningKey.generate() return sk.encode(encoder=Base64StringEncoder)
def test_add_verifying_key_as_bytes(self): sk = SigningKey.generate() self.s.add_verifying_key(sk.verify_key.encode()) self.assertTrue( os.path.exists( os.path.join(self.s.cert_dir, f'{sk.verify_key.encode().hex()}.key')))
def generate_sign_keypair(): """ Generate Ed25519 keypair. :returns: a pair containing the signing key and the verifying key. :rtype: bytes """ sk = SigningKey.generate() return sk.verify_key.encode(), sk.encode()
def generate_sign_keypair(): """ Generate Ed25519 keypair. :returns: a pair containing the verifying (public) key and the signing (private) key. :rtype: (bytes, bytes) """ sk = SigningKey.generate() return sk.verify_key.encode(), sk.encode()
def dispike_object(): _generated_signing_key = SigningKey.generate() verification_key = _generated_signing_key.verify_key.encode( encoder=HexEncoder) return Dispike( client_public_key=verification_key.decode(), bot_token="BOTTOKEN", application_id="APPID", )
def test_wrong_types(): sk = SigningKey.generate() check_type_error("SigningKey must be created from a 32 byte seed", SigningKey, 12) check_type_error("SigningKey must be created from a 32 byte seed", SigningKey, sk) check_type_error("SigningKey must be created from a 32 byte seed", SigningKey, sk.verify_key) check_type_error("VerifyKey must be created from 32 bytes", VerifyKey, 13) check_type_error("VerifyKey must be created from 32 bytes", VerifyKey, sk) check_type_error("VerifyKey must be created from 32 bytes", VerifyKey, sk.verify_key)
def test_invalid_signed_message(self): skey = SigningKey.generate() smessage = skey.sign(b"A Test Message!") signature, message = smessage.signature, b"A Forged Test Message!" # Small sanity check assert skey.verify_key.verify(smessage) with pytest.raises(BadSignatureError): skey.verify_key.verify(message, signature) with pytest.raises(BadSignatureError): forged = SignedMessage(signature + message) skey.verify_key.verify(forged)
def test_hex_smessage_with_detached_sig_matches_with_attached_sig(self): sk = SigningKey.generate() vk = sk.verify_key smsg = sk.sign(b"Hello World in hex", encoder=HexEncoder) msg = smsg.message hexsig = smsg.signature sig = HexEncoder.decode(hexsig) assert vk.verify(msg, sig, encoder=HexEncoder) == \ vk.verify(smsg, encoder=HexEncoder) assert HexEncoder.decode(msg) == b"Hello World in hex"
def test_base64_smessage_with_detached_sig_matches_with_attached_sig(self): sk = SigningKey.generate() vk = sk.verify_key smsg = sk.sign(b"Hello World in base64", encoder=Base64Encoder) msg = smsg.message b64sig = smsg.signature sig = Base64Encoder.decode(b64sig) assert vk.verify(msg, sig, encoder=Base64Encoder) == \ vk.verify(smsg, encoder=Base64Encoder) assert Base64Encoder.decode(msg) == b"Hello World in base64"
def startInvitation(self, petname, code, transports): #print "invite", petname, code.encode("hex") stretched = stretch(code) inviteKey = SigningKey(stretched) inviteID = inviteKey.verify_key.encode(Hex) mySigningKey = SigningKey.generate() myCIDkey = os.urandom(32) myTempPrivkey = PrivateKey.generate() # create my channel record tids = ",".join([str(tid) for tid in sorted(transports.keys())]) channel_key = PrivateKey.generate() pub_crec = { "channel_pubkey": channel_key.public_key.encode(Hex), "CID_key": myCIDkey.encode("hex"), "transports": transports.values(), } priv_data = { "my_signkey": mySigningKey.encode(Hex), "my_CID_key": myCIDkey.encode("hex"), "my_old_channel_privkey": channel_key.encode(Hex), "my_new_channel_privkey": channel_key.encode(Hex), "transport_ids": tids, } db = self.db c = db.execute("SELECT inviteID FROM invitations") if inviteID in [str(row[0]) for row in c.fetchall()]: raise CommandError("invitation code already in use") iid = db.insert("INSERT INTO `invitations`" " (code, petname, inviteKey," " inviteID," " myTempPrivkey, mySigningKey," " my_channel_record, my_private_channel_data," " myMessages, theirMessages, nextExpectedMessage)" " VALUES (?,?,?, ?, ?,?, ?,?, ?,?,?)", (code.encode("hex"), petname, stretched.encode("hex"), inviteID, myTempPrivkey.encode(Hex), mySigningKey.encode(Hex), json.dumps(pub_crec), json.dumps(priv_data), "", "", 1), "invitations") self.subscribe(inviteID) i = Invitation(iid, self.db, self) i.sendFirstMessage() self.db.commit()
def test_initialize_with_generate(self): SigningKey.generate()
def maybe_generate_key(self, cbdir, privkey_path=u'key.priv', pubkey_path=u'key.pub'): privkey_path = os.path.join(cbdir, privkey_path) pubkey_path = os.path.join(cbdir, pubkey_path) if os.path.exists(privkey_path): # node private key seems to exist already .. check! priv_tags = _parse_keyfile(privkey_path, private=True) for tag in [u'creator', u'created-at', u'machine-id', u'public-key-ed25519', u'private-key-ed25519']: if tag not in priv_tags: raise Exception("Corrupt node private key file {} - {} tag not found".format(privkey_path, tag)) privkey_hex = priv_tags[u'private-key-ed25519'] privkey = SigningKey(privkey_hex, encoder=HexEncoder) pubkey = privkey.verify_key pubkey_hex = pubkey.encode(encoder=HexEncoder).decode('ascii') if priv_tags[u'public-key-ed25519'] != pubkey_hex: raise Exception( ("Inconsistent node private key file {} - public-key-ed25519 doesn't" " correspond to private-key-ed25519").format(pubkey_path) ) if os.path.exists(pubkey_path): pub_tags = _parse_keyfile(pubkey_path, private=False) for tag in [u'creator', u'created-at', u'machine-id', u'public-key-ed25519']: if tag not in pub_tags: raise Exception("Corrupt node public key file {} - {} tag not found".format(pubkey_path, tag)) if pub_tags[u'public-key-ed25519'] != pubkey_hex: raise Exception( ("Inconsistent node public key file {} - public-key-ed25519 doesn't" " correspond to private-key-ed25519").format(pubkey_path) ) else: self.log.info( "Node public key file {pub_path} not found - re-creating from node private key file {priv_path}", pub_path=pubkey_path, priv_path=privkey_path, ) pub_tags = OrderedDict([ (u'creator', priv_tags[u'creator']), (u'created-at', priv_tags[u'created-at']), (u'machine-id', priv_tags[u'machine-id']), (u'public-key-ed25519', pubkey_hex), ]) msg = u'Crossbar.io node public key\n\n' _write_node_key(pubkey_path, pub_tags, msg) self.log.debug("Node key already exists (public key: {hex})", hex=pubkey_hex) else: # node private key does not yet exist: generate one privkey = SigningKey.generate() privkey_hex = privkey.encode(encoder=HexEncoder).decode('ascii') pubkey = privkey.verify_key pubkey_hex = pubkey.encode(encoder=HexEncoder).decode('ascii') # first, write the public file tags = OrderedDict([ (u'creator', _creator()), (u'created-at', utcnow()), (u'machine-id', _machine_id()), (u'public-key-ed25519', pubkey_hex), ]) msg = u'Crossbar.io node public key\n\n' _write_node_key(pubkey_path, tags, msg) # now, add the private key and write the private file tags[u'private-key-ed25519'] = privkey_hex msg = u'Crossbar.io node private key - KEEP THIS SAFE!\n\n' _write_node_key(privkey_path, tags, msg) self.log.info("New node key pair generated!") # fix file permissions on node public/private key files # note: we use decimals instead of octals as octal literals have changed between Py2/3 # if os.stat(pubkey_path).st_mode & 511 != 420: # 420 (decimal) == 0644 (octal) os.chmod(pubkey_path, 420) self.log.info("File permissions on node public key fixed!") if os.stat(privkey_path).st_mode & 511 != 384: # 384 (decimal) == 0600 (octal) os.chmod(privkey_path, 384) self.log.info("File permissions on node private key fixed!") self._node_key = cryptosign.SigningKey(privkey) return pubkey_hex
def init(server, username, keydir, action, message, recipients): """ SHSM CLI client. """ global serverurl serverurl = server if action == "register": master_signing_key = SigningKey.generate() device_signing_key = SigningKey.generate() device_private_key = PrivateKey.generate() enc_master_verify_key = master_signing_key.verify_key.encode(encoder=HexEncoder) register(username, enc_master_verify_key) # TODO: make sure keydir exists save_key(master_signing_key.encode(encoder=HexEncoder), keydir + "/master_signing_key") save_key(device_signing_key.encode(encoder=HexEncoder), keydir + "/device_signing_key") save_key(device_private_key.encode(encoder=HexEncoder), keydir + "/device_private_key") else: try: master_signing_key = SigningKey(load_key(keydir + "/master_signing_key"), encoder=HexEncoder) device_signing_key = SigningKey(load_key(keydir + "/device_signing_key"), encoder=HexEncoder) device_private_key = PrivateKey(load_key(keydir + "/device_private_key"), encoder=HexEncoder) except TypeError: print "bad key, exiting." exit() if action == "add-device": enc_device_verify_key = device_signing_key.verify_key.encode(encoder=HexEncoder) enc_signed_device_verify_key = b64encode(master_signing_key.sign(enc_device_verify_key)) enc_device_public_key = device_private_key.public_key.encode(encoder=HexEncoder) enc_signed_device_public_key = b64encode(master_signing_key.sign(enc_device_public_key)) add_device(username, enc_signed_device_verify_key, enc_signed_device_public_key) if action == "send-message": ephemeral_key = PrivateKey.generate() enc_ephemeral_public_key = b64encode( device_signing_key.sign(ephemeral_key.public_key.encode(encoder=HexEncoder)) ) # TODO:: should sign binary text, no? b"bob" destination_usernames = recipients.split(",") enc_dest_usernames = b64encode( device_signing_key.sign(json.dumps({"destination_usernames": destination_usernames})) ) symmetric_key = random(SecretBox.KEY_SIZE) symmetric_box = SecretBox(symmetric_key) nonce = random(SecretBox.NONCE_SIZE) msg_manifest = {} msg_manifest["recipients"] = {} msg_manifest["msg"] = b64encode(symmetric_box.encrypt(str(message), nonce)) for dest_user in destination_usernames: msg_manifest["recipients"][dest_user] = {} for recipient_key in get_recipient_keys( device_signing_key.verify_key.encode(encoder=HexEncoder), b64encode(device_signing_key.sign(str(dest_user))), ): # TODO:: should sign binary text, no? crypt_box = Box(ephemeral_key, recipient_key) nonce = random(Box.NONCE_SIZE) crypt_key = b64encode(crypt_box.encrypt(symmetric_key, nonce)) dest_key = recipient_key.encode(encoder=HexEncoder) msg_manifest["recipients"][dest_user][dest_key] = crypt_key enc_signed_crypt_msg = b64encode(device_signing_key.sign(json.dumps(msg_manifest))) send_message( device_signing_key.verify_key.encode(encoder=HexEncoder), enc_dest_usernames, enc_signed_crypt_msg, enc_ephemeral_public_key, ) if action == "get-messages": enc_device_verify_key = device_signing_key.verify_key.encode(encoder=HexEncoder) enc_signed_device_verify_key = b64encode(device_signing_key.sign(enc_device_verify_key)) messages = get_messages(enc_device_verify_key, enc_signed_device_verify_key) for message_public_key in messages["messages"].keys(): try: crypto_box = Box(device_private_key, PublicKey(b64decode(message_public_key), encoder=HexEncoder)) except TypeError: print "not a valid public key" exit() packed_msg = json.loads(messages["messages"][message_public_key]) msg_manifest = json.loads(b64decode(packed_msg["message_manifest"])) dest_pub_key = device_private_key.public_key.encode(encoder=HexEncoder) symmetric_key = crypto_box.decrypt(b64decode(msg_manifest["recipients"][username][dest_pub_key])) symmetric_box = SecretBox(symmetric_key) print ("From: %s\nMessage: %s") % ( packed_msg["reply_to"], symmetric_box.decrypt(b64decode(msg_manifest["msg"])), )
def command_invite(self, petname, maybe_code=None, reqid=None, override_transports=None, offer_mailbox=False, accept_mailbox_offer=False, _debug_when_done=None): #if offer_mailbox: # code = "mailbox-" + code if maybe_code: count = self.db.execute("SELECT COUNT(*) FROM addressbook" " WHERE invitation_state != ?" " AND invitation_code=?", (invitation.INVITE_COMPLETE, maybe_code) ).fetchone()[0] if count: raise CommandError("invitation code already in use") my_signkey = SigningKey.generate() channel_key = PrivateKey.generate() my_CID_key = os.urandom(32) base_transports = self.get_transports() if override_transports: base_transports = override_transports transports = self.individualize_transports(base_transports) channel = { "channel_pubkey": channel_key.public_key.encode(Hex), "CID_key": my_CID_key.encode("hex"), "transports": transports.values(), } payload = { "channel": channel } if offer_mailbox: tid = self.mailbox_server.allocate_transport(remote=True) payload["mailbox"] = self.mailbox_server.get_mailbox_record(tid) encoded_payload = json.dumps(payload).encode("utf-8") sigkeypayload = (b"i0:" + my_signkey.verify_key.encode() + my_signkey.sign(encoded_payload)) cid = self.db.insert( "INSERT INTO addressbook" " (petname, accept_mailbox_offer," " invitation_state, when_invited, invitation_code," " wormhole_payload," " next_outbound_seqnum, my_signkey," " my_CID_key, next_CID_token," " highest_inbound_seqnum," " my_old_channel_privkey," " my_new_channel_privkey)" " VALUES (?,?, ?,?,?, ?, ?,?, ?,?, ?, ?, ?)", (petname, accept_mailbox_offer, invitation.INVITE_WAITING_FOR_CODE, time.time(), maybe_code, sigkeypayload.encode("hex"), 1, my_signkey.encode(Hex), my_CID_key.encode("hex"), None, 0, channel_key.encode(Hex), channel_key.encode(Hex), # at beginning, old=new ), "addressbook", {"reqid": reqid}) i = self.im.create_invitation(cid) self.db.commit() self._activate_invitation(i, cid, _debug_when_done) return {"contact-id": cid, "petname": petname, "ok": "invitation for %s started: cid=%d" % (petname, cid)}
def _prepare_node_keys(self): from nacl.signing import SigningKey from nacl.encoding import HexEncoder # make sure CBDIR/.cdc exists # cdc_dir = os.path.join(self._cbdir, '.cdc') if os.path.isdir(cdc_dir): pass elif os.path.exists(cdc_dir): raise Exception(".cdc exists, but isn't a directory") else: os.mkdir(cdc_dir) self.log.info("CDC directory created") # load node ID, either from .cdc/node.id or from CDC_NODE_ID # def split_nid(nid_s): nid_c = nid_s.strip().split('@') if len(nid_c) != 2: raise Exception("illegal node principal '{}' - must follow the form <node id>@<management realm>".format(nid_s)) node_id, realm = nid_c # FIXME: regex check node_id and realm return node_id, realm nid_file = os.path.join(cdc_dir, 'node.id') node_id, realm = None, None if os.path.isfile(nid_file): with open(nid_file, 'r') as f: node_id, realm = split_nid(f.read()) elif os.path.exists(nid_file): raise Exception("{} exists, but isn't a file".format(nid_file)) else: if 'CDC_NODE_ID' in os.environ: node_id, realm = split_nid(os.environ['CDC_NODE_ID']) else: raise Exception("Neither node ID file {} exists nor CDC_NODE_ID environment variable set".format(nid_file)) # Load the node key, either from .cdc/node.key or from CDC_NODE_KEY. # The node key is a Ed25519 key in either raw format (32 bytes) or in # hex-encoded form (64 characters). # # Actually, what's loaded is not the secret Ed25519 key, but the _seed_ # for that key. Private keys are derived from this 32-byte (256-bit) # random seed value. It is thus the seed value which is sensitive and # must be protected. # skey_file = os.path.join(cdc_dir, 'node.key') skey = None if os.path.isfile(skey_file): # FIXME: check file permissions are 0600! # This value is read in here. skey_len = os.path.getsize(skey_file) if skey_len in (32, 64): with open(skey_file, 'r') as f: skey_seed = f.read() encoder = None if skey_len == 64: encoder = HexEncoder skey = SigningKey(skey_seed, encoder=encoder) self.log.info("Existing CDC node key loaded from {skey_file}.", skey_file=skey_file) else: raise Exception("invalid node key length {} (key must either be 32 raw bytes or hex encoded 32 bytes, hence 64 byte char length)") elif os.path.exists(skey_file): raise Exception("{} exists, but isn't a file".format(skey_file)) else: skey = SigningKey.generate() skey_seed = skey.encode(encoder=HexEncoder) with open(skey_file, 'w') as f: f.write(skey_seed) # set file mode to read only for owner # 384 (decimal) == 0600 (octal) - we use that for Py2/3 reasons os.chmod(skey_file, 384) self.log.info("New CDC node key {skey_file} generated.", skey_file=skey_file) return realm, node_id, skey
def maybe_generate_key(log, cbdir, privkey_path=u'key.priv', pubkey_path=u'key.pub'): if not HAS_NACL: log.warn("Skipping node key generation - NaCl package not installed!") return from nacl.signing import SigningKey from nacl.encoding import HexEncoder privkey = None pubkey = None privkey_path = os.path.join(cbdir, privkey_path) pubkey_path = os.path.join(cbdir, pubkey_path) if os.path.exists(privkey_path): # node private key seems to exist already .. check! tags = _parse_keyfile(privkey_path, private=True) if u'private-key-ed25519' not in tags: raise Exception("Node private key file lacks a 'private-key-ed25519' tag!") privkey = tags[u'private-key-ed25519'] # recreate a signing key from the base64 encoding privkey_obj = SigningKey(privkey, encoder=HexEncoder) pubkey = privkey_obj.verify_key.encode(encoder=HexEncoder).decode('ascii') # confirm we have the public key in the file, and that it is # correct if u'public-key-ed25519' in tags: if tags[u'public-key-ed25519'] != pubkey: raise Exception( ("Inconsistent key file '{}': 'public-key-ed25519' doesn't" " correspond to private-key-ed25519").format(privkey_path) ) log.debug("Node key already exists (public key: {})".format(pubkey)) if os.path.exists(pubkey_path): pubtags = _parse_keyfile(pubkey_path, private=False) if u'public-key-ed25519' not in pubtags: raise Exception( ("Pubkey file '{}' exists but lacks 'public-key-ed25519'" " tag").format(pubkey_path) ) if pubtags[u'public-key-ed25519'] != pubkey: raise Exception( ("Inconsistent key file '{}': 'public-key-ed25519' doesn't" " correspond to private-key-ed25519").format(pubkey_path) ) else: log.info("'{}' not found; re-creating from '{}'".format(pubkey_path, privkey_path)) tags = OrderedDict([ (u'creator', _creator()), (u'created-at', utcnow()), (u'machine-id', _machine_id()), (u'public-key-ed25519', pubkey), ]) msg = u'Crossbar.io public key for node authentication\n\n' _write_node_key(pubkey_path, tags, msg) else: # node private key does NOT yet exist: generate one privkey_obj = SigningKey.generate() privkey = privkey_obj.encode(encoder=HexEncoder).decode('ascii') pubkey = privkey_obj.verify_key.encode(encoder=HexEncoder).decode('ascii') # first, write the public file tags = OrderedDict([ (u'creator', _creator()), (u'created-at', utcnow()), (u'machine-id', _machine_id()), (u'public-key-ed25519', pubkey), ]) msg = u'Crossbar.io public key for node authentication\n\n' _write_node_key(pubkey_path, tags, msg) # now, add the private key and write the private file tags[u'private-key-ed25519'] = privkey msg = u'Crossbar.io private key for node authentication - KEEP THIS SAFE!\n\n' _write_node_key(privkey_path, tags, msg) log.info("New node key generated!") return pubkey
def key_generate(): return SigningKey.generate() def key_test( msg='test',
def create_new_key(): # We use a signkey to get a 64bit key, instead of a 32bit key... # because nacl? key = SigningKey.generate() return str(key._signing_key)
def maybe_generate_key(log, cbdir, privkey_path=u'node.key'): if not HAS_NACL: log.warn("Skipping node key generation - NaCl package not installed!") return from nacl.signing import SigningKey from nacl.encoding import HexEncoder privkey = None privkey_path = os.path.join(cbdir, privkey_path) if os.path.exists(privkey_path): # node private key seems to exist already .. check! if os.path.isfile(privkey_path): with open(privkey_path, 'r') as privkey_file: privkey = None # parse key file lines, looking for tag "ed25519-privkey" got_blankline = False for line in privkey_file.read().splitlines(): if line.strip() == '': got_blankline = True elif got_blankline: tag, value = line.split(':', 1) tag = tag.strip().lower() value = value.strip() if tag not in [u'private-key-ed25519', u'public-key-ed25519', u'machine-id', u'created-at', u'creator']: raise Exception("Invalid tag '{}' in node private key file {}".format(tag, privkey_path)) if tag == u'private-key-ed25519': privkey = value break if not privkey: raise Exception("Node private key file lacks a 'ed25519-privkey' tag!") # recreate a signing key from the base64 encoding privkey_obj = SigningKey(privkey, encoder=HexEncoder) pubkey = privkey_obj.verify_key.encode(encoder=HexEncoder).decode('ascii') log.debug("Node key already exists (public key: {})".format(pubkey)) else: raise Exception("Node private key path '{}' exists, but isn't a file".format(privkey_path)) else: # node private key does NOT yet exist: generate one privkey_obj = SigningKey.generate() privkey = privkey_obj.encode(encoder=HexEncoder).decode('ascii') privkey_created_at = utcnow() pubkey = privkey_obj.verify_key.encode(encoder=HexEncoder).decode('ascii') # for informational purposes, try to get a machine unique id thing .. machine_id = None try: # why this? see: http://0pointer.de/blog/projects/ids.html with open('/var/lib/dbus/machine-id', 'r') as f: machine_id = f.read().strip() except: pass # for informational purposes, try to identify the creator (user@hostname) creator = None try: creator = u'{}@{}'.format(getpass.getuser(), socket.gethostname()) except: pass # write out the private key file with open(privkey_path, 'w') as privkey_file: privkey_file.write(u'Crossbar.io private key for node authentication - KEEP THIS SAFE!\n\n') if creator: privkey_file.write(u'creator: {}\n'.format(creator)) privkey_file.write(u'created-at: {}\n'.format(privkey_created_at)) if machine_id: privkey_file.write(u'machine-id: {}\n'.format(machine_id)) privkey_file.write(u'public-key-ed25519: {}\n'.format(pubkey)) privkey_file.write(u'private-key-ed25519: {}\n'.format(privkey)) # set file mode to read only for owner # 384 (decimal) == 0600 (octal) - we use that for Py2/3 reasons os.chmod(privkey_path, 384) log.info("New node key generated!") return pubkey