示例#1
0
文件: password.py 项目: olcf/pkpass
    def decrypt_entry(self, identity=None, passphrase=None, card_slot=None):
        ####################################################################
        """Decrypt this password entry for a particular identity
        (usually the user)"""
        ####################################################################
        try:
            recipient_entry = self.recipients[identity["name"]]
        except KeyError as err:
            raise NotARecipientError(
                f"Identity '{identity}' is not on the recipient list for password '{self.metadata['name']}'"
            ) from err

        try:
            # support old yaml format
            return pk_decrypt_string(
                recipient_entry["encrypted_secret"],
                recipient_entry["derived_key"],
                identity,
                passphrase,
                card_slot,
            )
        except KeyError:
            try:
                # support rsa
                if "key" in identity and identity["key"]:
                    for _, value in recipient_entry["encrypted_secrets"].items():
                        return pk_decrypt_string(
                            value["encrypted_secret"],
                            value["derived_key"],
                            identity,
                            passphrase,
                        )
                else:
                    cert_key = get_card_fingerprint(card_slot=card_slot)
                    return pk_decrypt_string(
                        recipient_entry["encrypted_secrets"][cert_key][
                            "encrypted_secret"
                        ],
                        recipient_entry["encrypted_secrets"][cert_key]["derived_key"],
                        identity,
                        passphrase,
                        card_slot,
                    )
            except DecryptionError as err:
                msg = create_error_message(recipient_entry["timestamp"], card_slot)
                raise DecryptionError(
                    f"Error decrypting password named '{self.metadata['name']}'. {msg}"
                ) from err
            except KeyError as err:
                raise DecryptionError(
                    f"Error decrypting password named '{self.metadata['name']}'. Appropriate private key not found"
                ) from err
        except DecryptionError as err:
            msg = create_error_message(recipient_entry["timestamp"], card_slot)
            raise DecryptionError(
                f"Error decrypting password named '{self.metadata['name']}'. {msg}"
            ) from err
示例#2
0
    def decrypt_entry(self, identity=None, passphrase=None, card_slot=None):
        """ Decrypt this password entry for a particular identity
        (usually the user) """
        #######################################################################
        try:
            recipient_entry = self.recipients[identity['uid']]
        except KeyError:
            raise NotARecipientError(
                "Identity '%s' is not on the recipient list for password '%s'" %
                (identity['uid'], self.metadata['name']))

        try:
            # support old yaml format
            return crypto.pk_decrypt_string(
                recipient_entry['encrypted_secret'],
                recipient_entry['derived_key'],
                identity,
                passphrase,
                card_slot)
        except KeyError:
            try:
                # support rsa
                if 'key_path' in identity.keys():
                    for _, value in recipient_entry['encrypted_secrets'].items():
                        return crypto.pk_decrypt_string(
                            value['encrypted_secret'],
                            value['derived_key'],
                            identity,
                            passphrase
                        )
                else:
                    cert_key = crypto.get_card_fingerprint()
                    return crypto.pk_decrypt_string(
                        recipient_entry['encrypted_secrets'][cert_key]['encrypted_secret'],
                        recipient_entry['encrypted_secrets'][cert_key]['derived_key'],
                        identity,
                        passphrase,
                        card_slot)
            except DecryptionError:
                msg = create_error_message(recipient_entry['timestamp'], card_slot)
                raise DecryptionError(
                    "Error decrypting password named '%s'. %s" %
                    (self.metadata['name'], msg))
            except KeyError:
                raise DecryptionError(
                    "Error decrypting password named '%s'. Appropriate private key not found" %
                    self.metadata['name'])
        except DecryptionError:
            msg = create_error_message(recipient_entry['timestamp'], card_slot)
            raise DecryptionError("Error decrypting password named '%s'. %s" %
                                  (self.metadata['name'], msg))
示例#3
0
文件: crypto.py 项目: olcf/pkpass
def pk_decrypt_string(ciphertext_string,
                      ciphertext_derived_key,
                      identity,
                      passphrase,
                      card_slot=None):
    ####################################################################
    """Decrypt a base64 encoded string for the provided identity"""
    ####################################################################
    ciphertext_derived_key = handle_python_strings(ciphertext_derived_key)
    if "key" in identity and identity["key"]:
        command = [
            "openssl", "rsautl", "-inkey", identity["key"], "-decrypt", "-pkcs"
        ]
        with Popen(command, stdout=PIPE, stdin=PIPE, stderr=STDOUT) as proc:
            stdout, _ = proc.communicate(
                input=urlsafe_b64decode(ciphertext_derived_key))
            returncode = proc.returncode
        plaintext_derived_key = stdout
    else:
        # We've got to use pkcs15-crypt for PIV cards, and it only supports pin on
        # command line (insecure) or via stdin.  So, we have to put ciphertext into
        # a file for pkcs15-crypt to read.  YUCK!
        with NamedTemporaryFile(delete=False) as fname:
            fname.write(urlsafe_b64decode(ciphertext_derived_key))
        command = [
            "pkcs15-crypt",
            "--decipher",
            "--raw",
            "--pkcs",
            "--input",
            fname.name,
        ]
        if card_slot is not None:
            command.extend(["--reader", str(card_slot)])
        command.extend(["--pin", "-"])
        with Popen(command, stdout=PIPE, stdin=PIPE, stderr=DEVNULL) as proc:
            stdout, _ = proc.communicate(input=passphrase.encode("UTF-8"))
            unlink(fname.name)
            try:
                plaintext_derived_key = stdout
            except IndexError as err:
                raise DecryptionError(stdout) from err
            returncode = proc.returncode

    if returncode != 0:
        raise DecryptionError(stdout)

    return (Fernet(plaintext_derived_key).decrypt(
        handle_python_strings(ciphertext_string)).decode("UTF-8"))
示例#4
0
def pk_decrypt_string(ciphertext_string,
                      ciphertext_derived_key,
                      identity,
                      passphrase,
                      card_slot=None):
    """ Decrypt a base64 encoded string for the provided identity"""
    ##############################################################################

    ciphertext_derived_key = handle_python_strings(ciphertext_derived_key)
    if 'key_path' in identity:
        command = [
            'openssl', 'rsautl', '-inkey', identity['key_path'], '-decrypt',
            '-pkcs'
        ]
        proc = Popen(command, stdout=PIPE, stdin=PIPE, stderr=STDOUT)
        stdout, _ = proc.communicate(
            input=base64.urlsafe_b64decode(ciphertext_derived_key))
        plaintext_derived_key = stdout
    else:
        # We've got to use pkcs15-crypt for PIV cards, and it only supports pin on
        # command line (insecure) or via stdin.  So, we have to put ciphertext into
        # a file for pkcs15-crypt to read.  YUCK!
        with tempfile.NamedTemporaryFile(delete=False) as fname:
            fname.write(base64.urlsafe_b64decode(ciphertext_derived_key))
        command = [
            'pkcs15-crypt', '--decipher', '--raw', '--pkcs', '--input',
            fname.name
        ]
        if card_slot is not None:
            command.extend(['--reader', str(card_slot)])
        command.extend(['--pin', '-'])
        #subprocess.DEVNULL doesn't exist in python2 so...
        with open(os.devnull, 'w') as devnull:
            proc = Popen(command, stdout=PIPE, stdin=PIPE, stderr=devnull)
        stdout, _ = proc.communicate(input=passphrase.encode('ASCII'))
        os.unlink(fname.name)
        try:
            plaintext_derived_key = stdout
        except IndexError:
            raise DecryptionError(stdout)

    if proc.returncode != 0:
        raise DecryptionError(stdout)

    fern = Fernet(plaintext_derived_key)

    plaintext_string = fern.decrypt(handle_python_strings(ciphertext_string))
    return plaintext_string.decode("ASCII")
示例#5
0
def sk_decrypt_string(ciphertext_string, key):
    """ Symmetrically Decrypt a base64 encoded string using the provided key"""
    ##############################################################################

    fern = Fernet(hash_password(key))
    ciphertext_string = handle_python_strings(ciphertext_string)
    try:
        plaintext_string = fern.decrypt(
            base64.urlsafe_b64decode(handle_python_strings(ciphertext_string)))
        return plaintext_string.decode("ASCII")
    except InvalidToken:
        raise DecryptionError("Incorrect Password")
示例#6
0
文件: crypto.py 项目: olcf/pkpass
def sk_decrypt_string(ciphertext_string, key):
    ####################################################################
    """Symmetrically Decrypt a base64 encoded string using the provided key"""
    ####################################################################
    fern = Fernet(hash_password(key))
    ciphertext_string = handle_python_strings(ciphertext_string)
    try:
        plaintext_string = fern.decrypt(
            urlsafe_b64decode(handle_python_strings(ciphertext_string)))
        return plaintext_string.decode("UTF-8")
    except InvalidToken:
        # handle some legacy stuff from NCCS
        try:
            plaintext_string = fern.decrypt(ciphertext_string)
            return plaintext_string.decode("UTF-8")
        except InvalidToken as err:
            raise DecryptionError("Incorrect Password") from err
示例#7
0
    def decrypt_entry(self, identity=None, passphrase=None, card_slot=None):
        """ Decrypt this password entry for a particular identity (usually the user) """
        #######################################################################
        try:
            recipient_entry = self.recipients[identity['uid']]
        except KeyError:
            raise NotARecipientError(
                "Identity '%s' is not on the recipient list for password '%s'"
                % (identity['uid'], self.metadata['name']))

        try:
            return crypto.pk_decrypt_string(
                recipient_entry['encrypted_secret'],
                recipient_entry['derived_key'], identity, passphrase,
                card_slot)
        except DecryptionError:
            raise DecryptionError(
                "Error decrypting password named '%s'.  Perhaps a bad pin/passphrase?"
                % self.metadata['name'])