Skip to content

MINIFICPP-2749 Add EncryptContentPGP and DecryptContentPGP - #2225

Open
martinzink wants to merge 20 commits into
mainfrom
minifi_rust_pgp
Open

martinzink wants to merge 20 commits into
mainfrom
minifi_rust_pgp

Conversation

@martinzink

Copy link
Copy Markdown
Member

Thank you for submitting a contribution to Apache NiFi - MiNiFi C++.

In order to streamline the review of the contribution we ask you to ensure the following steps have been taken:

For all changes:

  • Is there a JIRA ticket associated with this PR? Is it referenced in the commit message?

  • Does your PR title start with MINIFICPP-XXXX where XXXX is the JIRA number you are trying to resolve? Pay particular attention to the hyphen "-" character.

  • Has your PR been rebased against the latest commit within the target branch (typically main)?

  • Is your initial contribution a single, squashed commit?

For code changes:

  • If adding new dependencies to the code, are these dependencies licensed in a way that is compatible for inclusion under ASF 2.0?
  • If applicable, have you updated the LICENSE file?
  • If applicable, have you updated the NOTICE file?

For documentation related changes:

  • Have you ensured that format looks appropriate for the output in which it is rendered?

Note:

Please ensure that once the PR is submitted, you check GitHub Actions CI results for build issues and submit an update to your PR as soon as possible.

@martinzink martinzink assigned martinzink and unassigned martinzink Aug 4, 2026
@martinzink
martinzink force-pushed the minifi_rust_pgp branch 3 times, most recently from 0727d82 to 2ba9029 Compare August 13, 2026 16:22
@martinzink
martinzink changed the base branch from minifi_rust_impr to minifi_rust_impr_2 August 13, 2026 16:23
@martinzink
martinzink force-pushed the minifi_rust_pgp branch 2 times, most recently from 75e1bf9 to beb4e74 Compare August 17, 2026 12:43
@martinzink
martinzink force-pushed the minifi_rust_pgp branch 2 times, most recently from b913bef to b632b71 Compare August 26, 2026 11:39
@martinzink martinzink added the priority Review these first label Sep 3, 2026

@szaszm szaszm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's great to see the new Rust API working beautifully in practice, I really like the API design. A few minor comments below. I'm about halfway through, and will finish with a more thorough review next week.

| Name | Default Value | Allowable Values | Description |
|--------------------|---------------|------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **File Encoding** | BINARY | ASCII<br/>BINARY | File Encoding for encryption |
| Symmetric Password | | | Password used for encrypting data with Password-Based Encryption<br/>**Sensitive Property: true** |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename this to Passphrase to match NiFi?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

passphrase for me signals its used to decrypt the private key, but i can change it if we want to be more in line with nifi

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather be matching NiFi even if it's at a slight cost to clarity. Password and passphrase are used similarly, passphrase just signals that it can (and should) be longer than a word.


| Name | Default Value | Allowable Values | Description |
|---------------------|---------------|------------------|-------------------------------------------------------------------------------------------------------------|
| Symmetric Password | | | Password used for decrypting data encrypted with Password-Based Encryption<br/>**Sensitive Property: true** |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we rename this to Passphrase to match NiFi?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed the properties to match nifi in review changes and review changes 2

Comment thread minifi_rust/extensions/minifi_pgp/src/test_utils/mod.rs

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd keep all of the processor-related metadata in the same file as the processor implementation

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still unsure which looks better
move defs into super files

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you prefer them separate, then it's ultimately your call as the author. I prefer them in a single file.

Base automatically changed from minifi_rust_impr_2 to main September 14, 2026 11:50
Comment thread minifi_rust/extensions/minifi_pgp/features/steps/steps.py Outdated
Comment thread minifi_rust/extensions/minifi_pgp/features/encrypt_decrypt.feature Outdated
Comment thread minifi_rust/extensions/minifi_pgp/features/encrypt_decrypt.feature
Comment thread minifi_rust/extensions/minifi_pgp/minifi_pgp.md
Comment thread minifi_rust/extensions/minifi_pgp/features/steps/steps.py

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is an easy way to reduce the code duplication without unifying public and private key types, and without exploding code complexity, it might be worth exploring.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since they are completely different types, its either this or macros or add our own trait which we would have to implement twice so not much better. I've tried it originally but didnt like it, feel free to play with it, maybe you can come up with something better.

Comment thread minifi_rust/extensions/minifi_pgp/src/controller_services/public_key_service.rs Outdated
Comment on lines +69 to +71
if let Some(sym_passwd) = &self.symmetric_password {
ring.message_password.push(sym_passwd);
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if both a private key and a symmetric passphrase are used? How does that work? Does it work at all? Does it double encrypt and decrypt the message, once with asymmetric and once with symmetric encryption? Does roundtrip with EncryptContent work in that case? If not, should we disable that and exforce an exclusive-OR relationship between the different key types, in schedule?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it can be decrypted with either, its quite smart, pgp generates a single session token it uses that to encrypt the message/file symmetrically and then it encrypts the session token twice, once with public key, once with the configured symmetric key, then saves both results, during decrypiption if it can decrypt the sesion key with either private or symmetric key it can decrypt the file.

pub(super) const LITERAL_DATA_FILENAME: OutputAttribute = OutputAttribute {
name: "pgp.literal.data.filename",
relationships: &["success"],
description: "Filename from decrypted Literal Data (Note that OpenPGP signatures do not include the formatting octet, the file name, and the date field of the Literal Data packet in a signature hash; therefore, those fields are not protected against tampering in a signed document. Therefore a lot of implementations omit these inherently malleable metadata)",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we ignore the unprotected metadata instead of using them when they're present? As a defense-in-depth measure, I think we should protect flowfile attributes from untrusted values, as some of our processors treat them as trusted data, opening attack vectors.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pub(super) const LITERAL_DATA_MODIFIED: OutputAttribute = OutputAttribute {
name: "pgp.literal.data.modified",
relationships: &["success"],
description: "Modified Date from decrypted Literal Data (Note that OpenPGP signatures do not include the formatting octet, the file name, and the date field of the Literal Data packet in a signature hash; therefore, those fields are not protected against tampering in a signed document. Therefore a lot of implementations omit these inherently malleable metadata)",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread minifi_rust/extensions/minifi_pgp/src/processors/encrypt_content.rs Outdated
Comment thread minifi_rust/extensions/minifi_pgp/src/utils.rs
Comment thread CONTROLLERS.md Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority Review these first rust

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants