Skip to content

Conversation

@krishnavema
Copy link
Contributor

Implement certificate authority for AD

Copy link
Contributor

@spoore1 spoore1 left a comment

Choose a reason for hiding this comment

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

This is a great start and as I mentioned earlier my main initial concern is around the request()/request_smartcard() methods.

My main thought here is to make request() align more closely with what you wrote for the IPA one so we can abstract it out to the GenericProvider later. I think the current request() could be made request_enrollment() and request_smartcard() renamed to request with some minor changes.

You might also consider a method to generate the INF file based on some basic input like template, subject, keysize. Then use template to select which set of configs to use for the INF based on that.

@krishnavema krishnavema force-pushed the ad-certificate-management branch 2 times, most recently from eedd166 to bec5310 Compare October 18, 2025 15:08
@krishnavema krishnavema requested a review from danlavu October 18, 2025 15:08
@krishnavema krishnavema force-pushed the ad-certificate-management branch from bec5310 to fc5e3ee Compare November 4, 2025 02:09
@krishnavema krishnavema force-pushed the ad-certificate-management branch from fc5e3ee to e3824a9 Compare November 4, 2025 02:22
@krishnavema krishnavema requested a review from spoore1 November 4, 2025 05:38
Copy link
Contributor

@danlavu danlavu left a comment

Choose a reason for hiding this comment

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

Overall, this looks great, with a few minor nitpicks and a couple of larger requested changes.

self.ca = ADCertificateAuthority(self.host)
"""
AD Certificate Authority management.
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick, one blank line.

Provides certificate operations:
Copy link
Contributor

Choose a reason for hiding this comment

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

nitpick, indentation, no blank lines needed.

- Retrieve certificate and template details
Example:
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick, code implies it's an example; this line can be removed.

I like consistency, especially within the same file, to avoid these nitpicks. Follow the format as another docstring within the same file.

cert, key, csr = ad.ca.request_smartcard(
template="SmartcardLogon",
subject="CN=Smartcard User",
enrollment_agent_cert_hash="thumbprint_here",
Copy link
Contributor

Choose a reason for hiding this comment

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

The thumbprint hash?


class ADCertificateAuthority:
"""
Provides helper methods for Active Directory Certificate Authority operations.
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick, Certificate Authority server management.

This class allows requesting, revoking, placing/removing certificate holds,
and retrieving certificate information via certreq and certutil commands.
.. code-block:: python
Copy link
Contributor

Choose a reason for hiding this comment

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

We have an example from when the object is created, which is sufficient.

:type host: ADHost
"""
self.host = host
self.cli = host.cli
Copy link
Contributor

Choose a reason for hiding this comment

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

We need to clean up the folder on teardown. The easiest thing to do, I think would be to rename the directory to something unique c:\pki then in hosts\ad.py, delete the directory in def restore

req_path = os.path.join(self.temp_dir, f"{base}.req")
cert_path = os.path.join(self.temp_dir, f"{base}.cer")

inf_content = f"""[NewRequest]
Copy link
Contributor

Choose a reason for hiding this comment

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

PSIni 3.1.4 is installed, so you can use that to make the construction of the inf content easier. You can checkout line 2114, creating the gpt.ini file.

}
return reason_map[reason]

def _parse_cert_info(self, output: str) -> dict[str, list[str]]:
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the parsers should go in misc/init.py

@danlavu
Copy link
Contributor

danlavu commented Nov 10, 2025

@krishnavema I'm sorry, I did review this before I left for PTO but I didn't click submit review.

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.

4 participants