Beispiel #1
0
    def __init__(self, name, secret="", sshkeyname=""):
        """
        is secret == "" then will use the ssh-agent to generate a secret
        """
        JSBASE.__init__(self)
        if sshkeyname:
            self.logger.debug("sshkeyname for nacl:%s"%sshkeyname)
            pass
        elif j.tools.configmanager.keyname:
            self.logger.debug("get config from git repo, keyname='%s'"% j.tools.configmanager.keyname)
            sshkeyname = j.tools.configmanager.keyname
        else:
            sshkeyname = j.core.state.configGetFromDict("myconfig", "sshkeyname")
            self.logger.debug("get config from system, keyname:'%s'"%sshkeyname)
            

        self.sshkeyname = sshkeyname
        self._agent = None

        if isinstance(secret, str):
            secret = secret.encode()

        self.name = name

        self.path = j.tools.configmanager.path
        self.logger.debug("NACL uses path:'%s'"%self.path)

        # get/create the secret seed
        self.path_secretseed = "%s/%s.seed" % (self.path, self.name)

        if not j.sal.fs.exists(self.path_secretseed):
            secretseed = self.hash32(nacl.utils.random(
                nacl.secret.SecretBox.KEY_SIZE))
            self.file_write_hex(self.path_secretseed, secretseed)
        else:
            secretseed = self.file_read_hex(self.path_secretseed)

        # this creates a unique encryption box
        # the secret needs 3 components: the passphrase(secret), the
        # secretseed means the repo & a loaded ssh-agent with your ssh key
        secret2 = self.hash32(secretseed + secret +
                              self.sign_with_ssh_key(secretseed + secret))
        # self._box is a temp encryption box which only exists while this
        # process runs
        # create temp box encrypt/decr (this to not keep secret in mem)
        self._box = nacl.secret.SecretBox(
            nacl.utils.random(nacl.secret.SecretBox.KEY_SIZE))
        self.secret = self._box.encrypt(
            secret2, nacl.utils.random(nacl.secret.SecretBox.NONCE_SIZE))
        secret = ""
        secret2 = ""
        secretseed = ""

        self.path_privatekey = "%s/%s.priv" % (self.path, self.name)
        if not j.sal.fs.exists(self.path_privatekey):
            self._keys_generate()
        self._privkey = ""
        self._pubkey = ""
        self._signingkey = ""
        self._signingkey_pub = ""
Beispiel #2
0
def _get_nacl_secret_box(secret, hmac_secret):
    if isinstance(secret, text_type):
        secret = secret.encode("utf-8")

    if isinstance(hmac_secret, text_type):
        hmac_secret = hmac_secret.encode("utf-8")

    secret_key = Hkdf(b"", hmac_secret).expand(secret)
    box = nacl.secret.SecretBox(secret_key)
    return box
Beispiel #3
0
    def configure(self,
                  privkey_words=None,
                  secret=None,
                  sshagent_use=None,
                  interactive=False,
                  generate=False):
        """

        secret is used to encrypt/decrypt the private key when stored on local filesystem
        privkey_words is used to put the private key back

        will ask for the details of the configuration
        :param: sshagent_use is True, will derive the secret from the private key of the ssh-agent if only 1 ssh key loaded
                                secret needs to be None at that point
        :param: secret only used when sshagent not used, will be stored encrypted in redis
                sha256 is used on the secret as specified above before storing/encrypting/decrypting the private key

        :param: generate if True and interactive is False then will autogenerate a key

        :return: None
        """
        self._log_debug("NACL uses path:'%s'" % self._path)

        self.privkey = None

        j.application.interactive = j.application.interactive or interactive

        # create dir where the secret will be to encrypt the secret
        j.sal.fs.createDir(j.core.tools.text_replace("{DIR_VAR}/logs"))

        j.sal.fs.remove(self._path_encryptor_for_secret)

        redis_key = "secret_%s" % self.name

        if j.core.db is None:
            j.clients.redis.core_get()

        j.core.db.delete(redis_key)

        if j.application.interactive and sshagent_use is None:
            sshagent_use = j.tools.console.askYesNo(
                "do you want to use ssh-agent for secret key in jumpscale?")

        if sshagent_use is False:
            if secret is None:
                secret = j.tools.console.askPassword(
                    "Provide a strong secret which will be used to encrypt/decrypt your private key"
                )
                if secret.strip() in [""]:
                    self._error_raise("Secret cannot be empty")
                secret = self._hash(secret)
            # will create a dummy file with a random key which will encrypt the secret
            key = nacl.utils.random(nacl.secret.SecretBox.KEY_SIZE)
            j.sal.fs.writeFile(self._path_encryptor_for_secret, key)
            self._box = nacl.secret.SecretBox(key)
            if isinstance(secret, str):
                secret = secret.encode()
            r = self._box.encrypt(secret)
            j.core.db.set(redis_key, r)

        # create path where the files for nacl will be
        j.sal.fs.createDir(self._path)

        self.load(die=False)

        if self.privkey is None:
            if j.application.interactive:
                # means we did not find a priv key yet
                self._ask_privkey_words()
            elif generate:
                self._keys_generate()

            self.load(die=False)

        if self.privkey is None:
            # none of the methods worked
            self._error_raise(
                "could not generate/load a private key, please use 'kosmos --init' to fix."
            )