Skip to content

Conversation

@nb-tech5
Copy link

@nb-tech5 nb-tech5 commented Aug 1, 2025

According to the PKCS#11 spec, all key objects have defined a semantic for CKA_START_DATE and CKA_END_DATE, although, for key objects that are private (e.g. CKO_PRIVATE_KEY, CKO_SECRET_KEY), the retrieval of their values fail.

This is happening when an attribute with a specialized class, e.g. P11AttrStartDate, gets added to a private object, its value is always written in clear, due to the updateAttr method overload, although, upon retrieving the value, due to the retrieve method not being symmetrically overloaded, and because the object is private, the attribute value is decrypted and fails.

This change adds protected virtual method retrieveAttrByteString to allow overloading the default behavior, namely for public attributes (written in clear), from private object.
Also add a base class P11NonPrivateAttribute to be extended by public attributes specializations

Fixes #804

Summary by CodeRabbit

  • New Features

    • RSA key objects now include start and end date attributes for keys (CKA_START_DATE / CKA_END_DATE).
  • Refactor

    • Centralized byte-string attribute retrieval and decryption for consistent, safer handling of encrypted attribute values.
  • Tests

    • Unit tests updated to create and validate RSA keys with the new start/end date attributes.

✏️ Tip: You can customize this high-level summary in your review settings.

@nb-tech5 nb-tech5 requested a review from a team as a code owner August 1, 2025 10:48
@coderabbitai
Copy link

coderabbitai bot commented Aug 1, 2025

Walkthrough

Adds virtual helpers to centralize ByteString attribute retrieval and conditional decryption, introduces P11NonPrivateAttribute, updates start/end date attributes to inherit from it, refactors P11Attribute::retrieve to use the new helpers, and extends RSA object tests to include CKA_START_DATE and CKA_END_DATE.

Changes

Cohort / File(s) Change Summary
ByteString retrieval & decryption centralization
src/lib/P11Attributes.cpp
Added P11Attribute::retrieveAttrByteString(Token*, bool, OSAttribute*, ByteString&) and P11NonPrivateAttribute::retrieveAttrByteString(...); refactored retrieve to call these helpers and removed duplicated decryption branches.
Header — class & API changes
src/lib/P11Attributes.h
Declared virtual retrieveAttrByteString on P11Attribute; added P11NonPrivateAttribute subclass; changed P11AttrStartDate/P11AttrEndDate to inherit from P11NonPrivateAttribute and updated constructors.
Tests — include start/end dates
src/lib/test/ObjectTests.cpp
Added CKA_START_DATE and CKA_END_DATE to RSA key templates and validations; replaced emptyDate placeholders with explicit startDate/endDate.

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant P11Attribute
    participant P11NonPrivateAttribute
    participant Token
    participant OSAttribute

    Caller->>P11Attribute: retrieve(token, isPrivate, attr, ...)
    alt attr type == ByteString
        P11Attribute->>P11Attribute: retrieveAttrByteString(token,isPrivate,attr,value)
        alt attr is instance of P11NonPrivateAttribute (overridden)
            P11NonPrivateAttribute-->>P11Attribute: return raw ByteString (no decrypt)
        else isPrivate and value non-empty
            P11Attribute->>Token: decrypt(value)
            Token-->>P11Attribute: decrypted bytes or CKR_GENERAL_ERROR
        end
        P11Attribute-->>Caller: return value (size) or CK_RV error
    else
        P11Attribute-->>Caller: handle other attribute types
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay attention to: retrieveAttrByteString error paths and propagated CK_RV values in P11Attributes.cpp.
  • Verify P11NonPrivateAttribute correctly prevents decryption for non-private attributes.
  • Confirm P11AttrStartDate/P11AttrEndDate constructor changes and test updates in ObjectTests.cpp.

Suggested labels

bug

Suggested reviewers

  • jschlyter
  • bjosv
  • bukka

"I hop through bytes and keys at dawn,
I swap the decrypt when privacy's gone.
Start and end dates now behave,
No broken reads from private cave.
A rabbit's patch — quick and strong." 🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.36% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'fix: fixes attribute reading on private objects' accurately describes the main change—adding symmetric retrieval behavior for public attributes stored on private objects.
Linked Issues check ✅ Passed The PR fully addresses issue #804 by adding retrieveAttrByteString virtual method and P11NonPrivateAttribute base class to enable proper retrieval of public attributes on private objects, with test coverage for CKA_START_DATE and CKA_END_DATE.
Out of Scope Changes check ✅ Passed All changes are directly related to resolving the symmetric attribute read/write behavior for public attributes on private objects as specified in issue #804; no out-of-scope modifications detected.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/lib/P11Attributes.h (2)

125-126: Fix typo in comment.

There's a typo in the comment: "Retrie" should be "Retrieve".

The method signature and design look good for addressing the asymmetric attribute handling issue.

-	// Retrie the value if allowed
+	// Retrieve the value if allowed
	virtual CK_RV retrieveAttrByteString(Token *token, bool isPrivate, OSAttribute *attr, ByteString &value);

135-143: Fix typo in comment.

Same typo here: "Retrie" should be "Retrieve".

The class design is well-structured for providing non-private attribute behavior.

-	// Retrie the value if allowed
+	// Retrieve the value if allowed
	virtual CK_RV retrieveAttrByteString(Token *token, bool isPrivate, OSAttribute *attr, ByteString &value);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ebf6ff7 and 1f16b44.

📒 Files selected for processing (2)
  • src/lib/P11Attributes.cpp (4 hunks)
  • src/lib/P11Attributes.h (3 hunks)
🔇 Additional comments (5)
src/lib/P11Attributes.h (2)

471-475: Good design choice for start date attributes.

Changing P11AttrStartDate to inherit from P11NonPrivateAttribute is appropriate since start dates are typically not sensitive data requiring encryption. This should resolve the retrieval failures on private objects mentioned in the PR.


489-493: Consistent and appropriate change for end date attributes.

Like the start date change, moving P11AttrEndDate to inherit from P11NonPrivateAttribute is consistent and appropriate since end dates don't typically require encryption.

src/lib/P11Attributes.cpp (3)

72-87: Well-implemented centralized retrieval method.

The implementation correctly handles both private and non-private attributes:

  • Attempts decryption for private, non-empty attributes
  • Includes proper error handling with logging
  • Falls back to raw value for non-private or empty attributes

This centralizes the logic that was previously duplicated in the retrieve method.


503-507: Correct implementation for non-private attributes.

The P11NonPrivateAttribute::retrieveAttrByteString implementation correctly bypasses decryption and always returns the raw byte string value, which is appropriate for attributes that are never encrypted.


293-299: Excellent refactoring that centralizes retrieval logic.

The modifications to the retrieve method successfully replace inline decryption logic with calls to the new retrieveAttrByteString method in both the size calculation and value copying sections. This:

  1. Eliminates code duplication
  2. Enables polymorphic behavior through virtual method overrides
  3. Fixes the asymmetric handling issue described in the PR
  4. Maintains consistent error handling

The refactoring is clean and preserves the original functionality while enabling the fix.

Also applies to: 347-357

@nb-tech5
Copy link
Author

nb-tech5 commented Aug 5, 2025

Hi @bellgrim, would you kindly let me know what could be the time frame to push this change (if accepted) into a release version?
Am I missing something for that to be able to happen?

Thanks.

Copy link
Contributor

@jschlyter jschlyter left a comment

Choose a reason for hiding this comment

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

Please check test results and fix.

@bukka
Copy link
Contributor

bukka commented Aug 12, 2025

It would be nice to include a test for this.

@bukka
Copy link
Contributor

bukka commented Aug 12, 2025

Also it would be good to rebase it so the Linux test runs.

@nb-tech5 nb-tech5 force-pushed the fix-fixes-reading-public-attribute-from-private-object branch from a197069 to 44f941e Compare August 18, 2025 11:32
@nb-tech5
Copy link
Author

nb-tech5 commented Aug 18, 2025

Rebased and changed the RSA private key to use a non-empty start and end dates.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/lib/test/ObjectTests.cpp (2)

1789-1797: Consider adding equivalent coverage for secret keys

Since the issue applies to private key and secret key objects, a small additional test that creates a CKO_SECRET_KEY with CKA_START_DATE/CKA_END_DATE and verifies retrieval would broaden regression coverage for the new retrieval hook.

I can draft a minimal extension to testCreateSecretKey that adds start/end dates and validates C_GetAttributeValue; let me know if you want that patch.


1814-1814: Nit: fix the comment to say “private key”

This function tests a private key; the comment mentions “public key”.

Apply this diff:

-    // Create minimal RSA public key object
+    // Create minimal RSA private key object
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a197069 and 44f941e.

📒 Files selected for processing (3)
  • src/lib/P11Attributes.cpp (4 hunks)
  • src/lib/P11Attributes.h (3 hunks)
  • src/lib/test/ObjectTests.cpp (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/P11Attributes.h
  • src/lib/P11Attributes.cpp
🔇 Additional comments (3)
src/lib/test/ObjectTests.cpp (3)

1785-1786: Good addition: concrete CK_DATE values exercise the new non-private retrieval path

The CK_DATE initializers are well-formed and will effectively validate the symmetric read path on private key objects.


1789-1797: Including CKA_START_DATE/CKA_END_DATE in the RSA private key template is correct and aligned with PKCS#11

Placing the date attributes in the creation template ensures they are persisted and subsequently retrievable without decryption. This directly covers the regression described in the linked issue.


1821-1821: Verification step correctly asserts date presence and length

Passing sizeof(CK_DATE) into checkCommonKeyAttributes ensures both value and length are checked post-retrieval. This should catch any inadvertent decryption attempts.

@nb-tech5 nb-tech5 force-pushed the fix-fixes-reading-public-attribute-from-private-object branch from 44f941e to 54eee02 Compare August 19, 2025 10:16
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/lib/test/ObjectTests.cpp (2)

1794-1797: Including CKA_START_DATE/CKA_END_DATE in the private RSA key template is appropriate

This exercises the new retrieval path on private objects where these attributes are public. Nice.

Optional enhancements:

  • Extend coverage to RSA public keys and secret keys to prove symmetry across key classes (PKCS#11 defines these attributes for all key objects). This helps prevent regressions limited to one class.

If you want, I can draft a follow-up patch that:

  • Adds start/end dates to testDefaultRSAPubAttributes’ creation template and updates its checkCommonKeyAttributes call accordingly.
  • Adds a small secret-key test that sets CKA_START_DATE/CKA_END_DATE and verifies retrieval via checkCommonKeyAttributes.

1821-1821: Asserting CKA_START_DATE/CKA_END_DATE retrieval on a private key — LGTM

The updated checkCommonKeyAttributes invocation validates both length and value for start/end dates on a private key, aligning with the PR goals.

Consider adding a companion scenario where the private key remains sensitive (CKA_SENSITIVE = CK_TRUE) to demonstrate that start/end dates are still retrievable even when other key material is not. This isolates the intended “public on private objects” behavior from sensitivity of key material.
I can provide a minimal test function (e.g., testStartEndDateOnSensitiveRSAPriv) that creates a sensitive private RSA key with dates set and asserts:

  • CKA_START_DATE/CKA_END_DATE: CKR_OK with expected bytes
  • CKA_PRIVATE_EXPONENT: CKR_ATTRIBUTE_SENSITIVE
    Would you like me to draft it?
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 44f941e and 54eee02.

📒 Files selected for processing (3)
  • src/lib/P11Attributes.cpp (4 hunks)
  • src/lib/P11Attributes.h (3 hunks)
  • src/lib/test/ObjectTests.cpp (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/lib/P11Attributes.cpp
  • src/lib/P11Attributes.h
🔇 Additional comments (1)
src/lib/test/ObjectTests.cpp (1)

1785-1786: CK_DATE test vectors for private RSA key look correct

Year/month/day are set as ASCII digits per PKCS#11 and the struct layout matches CK_DATE. Good choice of distinct values to assert roundtrip.

@nb-tech5
Copy link
Author

@jschlyter, I've already pressed Re-request review last week, but since I didn't got any further feedback from the UI that you have been notified, I'm just notifying you directly.

Thanks.

@nb-tech5 nb-tech5 force-pushed the fix-fixes-reading-public-attribute-from-private-object branch from 54eee02 to 7ab2b97 Compare September 22, 2025 09:03
@antoinelochet
Copy link
Contributor

Hello,
Could you please rebase on main again ?
It has moved quite a bit lately and it should run tests

According to the PKCS#11 spec, all key objects have defined a semantic
for CKA_START_DATE and CKA_END_DATE, although, for key objects that are
private (e.g. CKO_PRIVATE_KEY, CKO_SECRET_KEY), the retrieval of their
values fail.

This is happening when an attribute with a specialized class, e.g.
P11AttrStartDate, gets added to a private object, its value is always
written in clear, due to the updateAttr method overload, although, upon
retrieving the value, due to the retrieve method not being symmetrically
overloaded, and because the object is private, the attribute value is
decrypted and fails.

This change adds protected virtual method `retrieveAttrByteString` to
allow overloading the default behavior, namely for public attributes
(written in clear), from private object.
Also add a base class `P11NonPrivateAttribute` to be extended by public
attributes specializations.
@nb-tech5 nb-tech5 force-pushed the fix-fixes-reading-public-attribute-from-private-object branch from 7ab2b97 to 70c7e94 Compare December 10, 2025 17:48
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/lib/P11Attributes.h (1)

125-143: Virtual ByteString retrieval hook and non‑private base are well‑factored

Introducing retrieveAttrByteString on P11Attribute and the P11NonPrivateAttribute override cleanly separates “decrypt if private” from “always return raw value”, which is exactly what’s needed for public attributes stored on private objects. The signatures and access levels look consistent with existing style, and the override correctly ignores isPrivate while still going through the usual access checks in retrieve(). Only a tiny nit: the comment “Retrie the value if allowed” has a typo if you ever touch this again.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 54eee02 and 70c7e94.

📒 Files selected for processing (3)
  • src/lib/P11Attributes.cpp (4 hunks)
  • src/lib/P11Attributes.h (3 hunks)
  • src/lib/test/ObjectTests.cpp (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/P11Attributes.cpp
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: bukka
Repo: softhsm/SoftHSMv2 PR: 815
File: src/lib/SoftHSM.cpp:6543-6546
Timestamp: 2025-09-11T16:54:00.370Z
Learning: SoftHSM PR #815 (pkcs11.h 3.1.0 update, CK_RSA_AES_KEY_WRAP_PARAMS fix): Maintainer bukka prefers to keep scope minimal (header sync and param rename only); broader OAEP parameter enforcement or backend plumbing is out of scope for this PR and should be handled in a follow-up issue.
📚 Learning: 2025-09-11T16:54:00.370Z
Learnt from: bukka
Repo: softhsm/SoftHSMv2 PR: 815
File: src/lib/SoftHSM.cpp:6543-6546
Timestamp: 2025-09-11T16:54:00.370Z
Learning: SoftHSM PR #815 (pkcs11.h 3.1.0 update, CK_RSA_AES_KEY_WRAP_PARAMS fix): Maintainer bukka prefers to keep scope minimal (header sync and param rename only); broader OAEP parameter enforcement or backend plumbing is out of scope for this PR and should be handled in a follow-up issue.

Applied to files:

  • src/lib/P11Attributes.h
🧬 Code graph analysis (1)
src/lib/P11Attributes.h (1)
src/lib/P11Attributes.cpp (8)
  • retrieveAttrByteString (72-87)
  • retrieveAttrByteString (72-72)
  • retrieveAttrByteString (503-507)
  • retrieveAttrByteString (503-503)
  • attr (2315-2315)
  • attr (2414-2414)
  • P11Attribute (43-49)
  • P11Attribute (52-54)
🔇 Additional comments (3)
src/lib/test/ObjectTests.cpp (2)

1785-1796: Good coverage of non‑empty CK_DATE on private RSA key

Defining concrete startDate / endDate values and wiring them into the private key template via CKA_START_DATE / CKA_END_DATE looks correct and matches CK_DATE layout. This should reliably exercise the new retrieval path on private key objects (and fail if the dates are incorrectly decrypted or treated as private).


1819-1822: checkCommonKeyAttributes invocation correctly validates stored dates

Passing startDate, sizeof(startDate) and endDate, sizeof(endDate) into checkCommonKeyAttributes aligns with how that helper reads and compares the corresponding attributes. This will assert both length and content of CKA_START_DATE/CKA_END_DATE on the private key, which is exactly what’s needed to guard the new retrieval behavior.

src/lib/P11Attributes.h (1)

471-493: Start/end date attributes correctly switched to non‑private retrieval semantics

Having P11AttrStartDate and P11AttrEndDate derive from P11NonPrivateAttribute and call its constructor ensures these date attributes are retrieved as plain ByteStrings even for private/secret key objects, while write behavior remains unchanged. This aligns with PKCS#11 semantics for CKA_START_DATE/CKA_END_DATE and matches the new tests that assert non‑empty dates on a private RSA key.

@nb-tech5
Copy link
Author

@antoinelochet, done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Attributes with specialized classes aren't support on private objects

4 participants