PKI-PYTHON-CLIENT(1)
π PKI-PYTHON-CLIENT(1) β Dogtag Python Client API π
This is the Dogtag Certificate System page for pki-python-client, aka the Dogtag Python Client API. Bestie, we're going full group-chat mode, but every fact stays exactly where it belongs π
πΈ NAME πΈ
pki-python-client β Dogtag Python Client API
Dogtag is an enterprise software system designed to manage enterprise Public Key Infrastructure (PKI) deployments. These pages document the Python client API that can be used to interact with Dogtag's REST API to request and issue certificates, store secrets in the KRA etc. β¨
π PKI PACKAGE π
π§ pki Package π§
This module contains top-level classes and functions used by the Dogtag project.
π class pki.Attribute(name, value) π
Bases: object
Class representing a key/value pair.
This object is the basis of the representation of a ResourceMessage. It's giving foundational, lowkey important. π
π§Ί class pki.AttributeList π§Ί
Bases: object
Class representing a list of attributes.
This class is needed because of a JavaMapper used in the REST API.
π₯ exception pki.BadRequestException(message, exception=None, code=None, class_name=None) π₯
Bases: pki.PKIException
Bad Request Exception: return code = 400
π¦ exception pki.CertNotFoundException(message, exception=None, code=None, class_name=None) π¦
Bases: pki.ResourceNotFoundException
Cert Not Found Exception: return code = 404
βοΈ exception pki.ConflictingOperationException(message, exception=None, code=None, class_name=None) βοΈ
Bases: pki.PKIException
Conflicting Operation Exception: return code = 409
π class pki.FIPS π
Bases: object
static is_enabled()
π« exception pki.ForbiddenException(message, exception=None, code=None, class_name=None) π«
Bases: pki.PKIException
Forbidden Exception: return code = 403
π₯ exception pki.GroupNotFoundException(message, exception=None, code=None, class_name=None) π₯
Bases: pki.ResourceNotFoundException
Group Not Found Exception: return code = 404
π¨ exception pki.HTTPGoneException(message, exception=None, code=None, class_name=None) π¨
Bases: pki.PKIException
Gone Exception: return code = 410
π exception pki.KeyNotFoundException(message, exception=None, code=None, class_name=None) π
Bases: pki.ResourceNotFoundException
Key Not Found Exception: return code 404
π class pki.Link π
Bases: object
Stores the information of the resteasy's Link object sent by the server for a resource.
classmethod from_json(attr_list)β GenerateLinkfrom JSON- Parameters:
attr_list(str) β JSON representation ofLink - Returns:
pki.Link
- Parameters:
𧨠exception pki.PKIException(message, exception=None, code=None, class_name=None) π§¨
Bases: Exception, pki.ResourceMessage
Base exception class for REST Interface. Main character energy, honestly. π
classmethod from_json(json_value)β ConstructPKIExceptionfrom JSON.:param json_value:JSON representation of the exception.:type json_value:str:return:pki.PKIException
πͺͺ exception pki.ProfileNotFoundException(message, exception=None, code=None, class_name=None) πͺͺ
Bases: pki.ResourceNotFoundException
Profile Not Found Exception: return code = 404
π class pki.PropertyFile(filename, delimiter='=') π
Bases: object
Class to manage property files. The contents of the property file are maintained internally as a list of properties.
Properties are strings of the format <name> <delimiter> <value> where '=' is the default delimiter.
get(name)β Get the value of the specified property.- Parameters:
name(str) β name of property to be fetched. - Returns:
strβ value of property
- Parameters:
index(name)β Find the index (position) of a property in a property file.- Parameters:
name(str) β name of property - Returns:
intβ index of property.
- Parameters:
insert_line(index, line)β Insert property into the list of properties maintained by this object at the specified location (index).- Parameters:
index(int) β point at which to insert value.line(str) β value to be inserted.
- Returns:
None
- Parameters:
read()β Read from property file into the list of properties maintained by this object.- Returns:
None
- Returns:
remove(name)β Remove property from list of properties maintained by this object.- Parameters:
name(str) β name of property to be removed. - Returns:
None
- Parameters:
remove_line(index)β Remove property at specified index from the properties list.- Parameters:
index(int) β location of property to be removed. - Returns:
None
- Parameters:
set(name, value, index=None)β Set value of specified property.- Parameters:
name(str) β name of property to set.value(str) β value to setindex(int) β (optional) position of property
- Returns:
None
- Parameters:
show()β Print the contents of the list of properties maintained by this object toSTDOUT.- Returns:
None
- Returns:
write()β Write the list of properties maintained by this object to the property file.- Returns:
None
- Returns:
π¨ exception pki.RequestNotFoundException(message, exception=None, code=None, class_name=None) π¨
Bases: pki.ResourceNotFoundException
Request Not Found Exception: return code = 404
ποΈ class pki.ResourceMessage(class_name) ποΈ
Bases: object
This class is the basis for the various types of key requests. It is essentially a list of attributes.
add_attribute(name, value)β Add an attribute to the list.- Parameters:
name(str) β name of attribute to addvalue(str) β value to add
- Returns:
None
- Parameters:
get_attribute_value(name)β Get the value of a given attribute.- Parameters:
name(str) β name of attribute to retrieve - Returns:
strβ value of parameter
- Parameters:
π³οΈ exception pki.ResourceNotFoundException(message, exception=None, code=None, class_name=None) π³οΈ
Bases: pki.PKIException
Not Found Exception: return code = 404
π exception pki.UnauthorizedException(message, exception=None, code=None, class_name=None) π
Bases: pki.PKIException
Unauthorized Exception: return code = 401
π€ exception pki.UserNotFoundException(message, exception=None, code=None, class_name=None) π€
Bases: pki.ResourceNotFoundException
User Not Found Exception: return code = 404
πͺ pki.convert_x509_name_to_dn(name) πͺ
Convert X.509 Name into NSS-style DN string.
See also:
https://cryptography.io/en/latest/x509/reference.html#cryptography.x509.Namehttps://cryptography.io/en/latest/x509/reference.html#cryptography.x509.RelativeDistinguishedNamehttps://cryptography.io/en/latest/x509/reference.html#cryptography.x509.NameAttributehttps://cryptography.io/en/latest/x509/reference.html#cryptography.x509.ObjectIdentifier- Parameters:
name(cryptography.x509.Name) β X.509 Name - Returns:
strβ DN string.
π pki.generate_password π
pki.generate_password(charset='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!#*+,-./:;^_|~', length=12)
This function generates FIPS-compliant password.
See sftk_newPinCheck() in the following file: https://dxr.mozilla.org/nss/source/nss/lib/softoken/fipstokn.c
The minimum password length is FIPS_MIN_PIN Unicode characters.
The password must contain at least 3 character classes:
- digits (
string.digits) - ASCII lowercase letters (
string.ascii_lowercase) - ASCII uppercase letters (
string.ascii_uppercase) - ASCII non-alphanumeric characters (
PUNCTUATIONS) - non-ASCII characters
If an ASCII uppercase letter is the first character of the password, the uppercase letter is not counted toward its character class.
If a digit is the last character of the password, the digit is not counted toward its character class.
The FIPS_MIN_PIN is defined in the following file: https://dxr.mozilla.org/nss/source/nss/lib/softoken/pkcs11i.h
#define FIPS_MIN_PIN 7
π§Ύ pki.get_info(name) π§Ύ
π‘οΈ pki.handle_exceptions() π‘οΈ
Decorator handling exceptions from REST methods.
π·οΈ pki.implementation_version() π·οΈ
Return implementation version.
- Returns:
strβ implementation version
π pki.specification_version() π
Return specification version.
- Returns:
strβ specification version
π«Ά account Module π«Ά
class pki.account.AccountClient(connection, subsystem=None)
Bases: object
Class used to associate an authentication session variable with a connection.
To use this class:
- set the authentication credentials with the connection,
- create an
AccountClientand then calllogin(). - further operations in this session will use the same authentication credentials without re-authentication.
- call
logout()to invalidate the session. login()β Login to account REST interface. If login is successful, an authentication session variable is associated with the connection.- Returns:
None
- Returns:
logout()β Logs out of the session. Authentication session variables are invalidated for the connection- Returns:
None
- Returns:
π¦ cert Module π¦
class pki.cert.CertClient(connection)
Bases: object
okay so this class is literally the mirror image of the CertResource Java interface, the one that defines the REST API for Certificate resources π
everything you can do to a cert over REST, you can do from here.
approve_request(request_id, cert_review_response=None)β approves a certificate enrollment request β¨ ifcert_review_responseisNone, it does a review request operation to go fetch theCertReviewResponseobject for you. needs agent-level authentication, no cap.assign_request(request_id, cert_review_response)β assigns a certificate enrollment request. same deal: ifcert_review_responseisNone, a review request operation happens to fetch theCertReviewResponseobject. agent-level auth required π«Άcancel_request(request_id, cert_review_response=None)β cancels a certificate enrollment request.cert_review_responsebeingNoneagain triggers the review request operation to fetch theCertReviewResponse. agent-level authentication, always πΈcreate_enrollment_request(profile_id, inputs)β fetches the enrollment request object for the profile you passed and sets values on its attributes using the values in theinputsdictionary. returns theCertEnrollmentRequestobject, which you can then submit to enroll a cert πenroll_cert(profile_id, inputs, authority=None)β the convenience queen π enrolls a cert for a given profile id.inputsshould be a dictionary with values for the profile attributes of an enrollment request.
call it with valid arguments and it creates an enrollment request, submits it to the server, approves the certificate requests generated for the enrollment, and returns a list of CertData objects for all the certificates generated as part of this enrollment. literally the whole pipeline in one call.
β οΈ Note: this method supports only certificate enrollment where only one agent approval is sufficient. so if your setup needs more than one, this isn't the one bestie π
requires agent-level authentication. returns a list of CertEnrollmentResult objects.
get_cert(cert_serial_number)β returns aCertDataobject for a particular certificate π₯get_enrollment_template(profile_id)β fetches the enrollment template for the given profile id. first time around, the request actually goes to the server; the retrievedCertEnrollmentRequestobject then gets cached locally for future requests. returns aCerEnrollmentRequestobject (yes, that's how it's spelled on the page, i'm not fixing it π).get_request(request_id)β gets info on a certificate request with the given request ID. returns aCertRequestInfoobject β¨hold_cert(cert_serial_number, comments=None, authority=None)β puts a certificate on-hold. it calls therevoke_certmethod with reasonCertRevokeRequest.REASON_CERTIFICATE_HOLD. returns aCertRequestInfoobject. this one needs an agent's authentication cert in the connection object πlist_certs(max_results=None, max_time=None, start=None, size=None, **cert_search_params)β returns aCertDataInfoCollectionobject with information about all the certificates that satisfy the search criteria. ifcert_search_request=None, you get all the certificates. everything. the whole shelf πlist_enrollment_templates(start=None, size=None)β gets the list of profile templates the CA supports.startandsizedecide where the list starts and how long it is. returns aProfileDataInfoCollectionobject π¦list_requests(request_status=None, request_type=None, from_request_id=None, size=None, max_results=None, max_time=None)β queries for a list of certificates using the arguments you passed. returns aCertRequestInfoCollectionobject πΈreject_request(request_id, cert_review_response=None)β rejects a certificate enrollment request.cert_review_response=Noneβ review request operation to fetch theCertReviewResponseobject. agent-level auth required πreview_cert(cert_serial_number)β reviews a certificate. returns aCertDataobject with a nonce. needs an agent's authentication cert in the connection object β¨review_request(request_id)β reviews a certificate enrollment request. returns aCertReviewResponseobject, which has the nonce from the server that you need to actually perform an action on the request πrevoke_ca_cert(cert_serial_number, revocation_reason=None, invalidity_date=None, comments=None, nonce=None, authority=None)β revokes a CA certificate. returns aCertRequestInfoobject with info about the request. requires an agent's authentication cert in the connection object π«Άrevoke_cert(cert_serial_number, revocation_reason=None, invalidity_date=None, comments=None, nonce=None, authority=None)β revokes a certificate. returns aCertRequestInfoobject with info about the request. same requirement: an agent's authentication cert in the connection object π₯submit_enrollment_request(enrollment_request, authority=None)β submits theCertEnrollmentRequestobject to the server. returns aCertRequestInfoCollectionobject with info about the certificate requests enrolled at the CA π¬unassign_request(request_id, cert_review_response)β un-assigns a certificate enrollment request.cert_review_response=Noneβ review request operation to fetch theCertReviewResponseobject. agent-level authentication required πunrevoke_cert(cert_serial_number, authority=None)β un-revokes a revoked certificate. returns aCertRequestInfoobject. needs an agent's authentication cert in the connection object πupdate_request(request_id, cert_review_response)β updates a certificate enrollment request.cert_review_response=Noneβ review request operation to fetch theCertReviewResponseobject. agent-level auth, as always πvalidate_request(request_id, cert_review_response)β validates a certificate enrollment request. and yeah,cert_review_response=Noneβ review request operation to fetch theCertReviewResponseobject. agent-level authentication β¨
π¦ class pki.cert.CertData
Bases: object
the class holding certificate data, exactly as it comes back from getCert() π
classmethod from_json(attr_list)β returns aCertDataobject from a JSON dict.- the attribute map, verbatim because this is load-bearing:
json_attribute_names = {'Encoded': 'encoded', 'IssuerDN':
'issuer_dn', 'Link': 'link', 'Nonce': 'nonce', 'NotAfter':
'not_after', 'NotBefore': 'not_before', 'PKCS7CertChain':
'pkcs7_cert_chain', 'PrettyPrint': 'pretty_repr', 'Status':
'status', 'SubjectDN': 'subject_dn', 'id': 'serial_number'}
π class pki.cert.CertDataInfo
Bases: object
the class with the info that lives inside a CertRecord on the CA β this is the stuff you get back when you search or list certificate records π
classmethod from_json(attr_list)β returns aCertDataInfoobject from a JSON dict.- the attribute map, again verbatim:
json_attribute_names = {'IssuedBy': 'issued_by', 'IssuedOn':
'issued_on', 'KeyAlgorithmOID': 'key_algorithm_oid', 'KeyLength':
'key_length', 'Link': 'link', 'NotValidAfter': 'not_valid_after',
'NotValidBefore': 'not_valid_before', 'Status': 'status',
'SubjectDN': 'subject_dn', 'Type': 'type', 'Version': 'version',
'id': 'serial_number'}
π§ class pki.cert.CertDataInfoCollection
Bases: object
a class holding a list of CertDataInfo objects plus their respective link objects π«Ά this is what comes back when you search/list certificate records in the CA.
classmethod from_json(json_value)β populates the object from JSON input β¨
π class pki.cert.CertEnrollmentRequest(profile_id=None, renewal=False, serial_number=None, remote_host=None, remote_address=None, inputs=None, outputs=None)
Bases: object
this class encapsulates the parameters required for a certificate enrollment request. all the knobs, one box π
add_input(profile_input)β the page just drops this one on the list, no blurb, iykyk.add_output(profile_output)β same energy, listed with no description.classmethod from_json(attr_list)β listed, no description on the page.get_input(profile_input_name)β listed, no description.get_output(profile_output_name)β listed, no description.json_attribute_namesβ the mapping, verbatim:
json_attribute_names = {'Input': 'inputs', 'Output': 'outputs',
'ProfileID': 'profile_id', 'RemoteAddress': 'remote_address',
'RemoteHost': 'remote_host', 'Renewal': 'renewal',
'SerialNumber': 'serial_number'}
remove_input(profile_input_name)β listed, no description.remove_output(profile_output_name)β listed, no description.
π class pki.cert.CertEnrollmentResult(request, cert)
Bases: object
the class containing results of an enrollment request πΈ this structure holds info about the cert request that got generated plus any certificates that got issued.
π class pki.cert.CertRequestInfo
Bases: object
an object of this class represents a certificate request, periodt.
classmethod from_json(attr_list)β listed, no description.- the attribute map, verbatim:
json_attribute_names = {'certId': 'cert_id', 'certRequestType':
'cert_request_type', 'certURL': 'cert_url', 'errorMessage':
'error_message', 'operationResult': 'operation_result',
'requestStatus': 'request_status', 'requestType': 'request_type',
'requestURL': 'request_url'}
π class pki.cert.CertRequestInfoCollection
Bases: object
a class holding a list of CertRequestInfo objects π this is what comes back when you list certificate request records in the CA.
classmethod from_json(json_value)β populates the object from JSON input.
β class pki.cert.CertRequestStatus
Bases: object
the class containing all the valid cert statuses β that's it, that's the whole class. iconic minimalism.
CANCELED = 'canceled'
COMPLETE = 'complete'
PENDING = 'pending'
REJECTED = 'rejected'
okay so those four are literally just the status strings, lowercase, that's the whole vibe π no cap, that's it.
class pki.cert.CertReviewResponse(profile_id=None, renewal=False, serial_number=None, remote_host=None, remote_address=None, inputs=None, outputs=None, nonce=None, request_id=None, request_type=None, request_status=None, request_owner=None, request_creation_time=None, request_modification_time=None, request_notes=None, profile_approval_by=None, profile_set_id=None, profile_is_visible=None, profile_name=None, profile_description=None, profile_remote_host=None, profile_remote_address=None, policy_sets=None)
Bases: pki.cert.CertEnrollmentRequest
So an object of this class is literally the response the server hands you back when you're reviewing a certificate enrollment request π and it carries a nonce with it β and bestie, you need that nonce to actually perform an action on the request. No nonce, no slay.
classmethod from_json(attr_list) β yeah, it builds one of these out of a JSON attribute list, iconic.
json_attribute_names = {'Input': 'inputs', 'Output': 'outputs',
'ProfileID': 'profile_id', 'ProfilePolicySet': 'policy_sets',
'RemoteAddress': 'remote_address', 'RemoteHost': 'remote_host',
'Renewal': 'renewal', 'SerialNumber': 'serial_number',
'profileApprovedBy': 'profile_approved_by', 'profileDescription':
'profile_description', 'profileIsVisible': 'profile_is_visible',
'profileName': 'profile_name', 'profileRemoteAddr':
'profile_remote_address', 'profileRemoteHost':
'profile_remote_host', 'profileSetId': 'profile_set_id',
'requestCreationTime': 'request_creation_time', 'requestId':
'request_id', 'requestModificationTime':
'request_modification_time', 'requestNotes': 'request_notes',
'requestOwner': 'request_owner', 'requestStatus':
'request_status', 'requestType': 'request_type'}
That's the whole server-name-to-python-name translation map, fr fr β capital letters on the left, snake_case on the right, every single pair present and accounted for π
class pki.cert.CertRevokeRequest(nonce, reason=None, invalidity_date=None, comments=None)
Bases: object
This one's the little container for every parameter you need when you're revoking a certificate π«Ά like it holds all the stuff the server needs so you can yeet that cert into the void.
Valid values for the reasons for revoking a request are:
'Unspecified', 'Key_Compromise', 'CA_Compromise',
'Affiliation_Changed', 'Superseded',
'Cessation_of_Operation', 'Certificate_Hold',
'Remove_from_CRL', 'Privilege_Withdrawn', 'AA_Compromise'
And here's the same list as the actual attribute, so you can peek at reasons programmatically instead of typing them from memory like a menace:
reasons = ['Unspecified', 'Key_Compromise', 'CA_Compromise',
'Affiliation_Changed', 'Superseded', 'Cessation_of_Operation',
'Certificate_Hold', 'Remove_from_CRL', 'Privilege_Withdrawn',
'AA_Compromise']
note that the underscores are real β Key_Compromise not Key Compromise, Cessation_of_Operation not Cessation of Operation β type it wrong and the server will simply not be having it π
class pki.cert.CertSearchRequest(**cert_search_params)
Bases: object
An object of this class is where you stash your search parameters before shipping them off to the server π so it's basically the little search-query bag you carry around.
search_params = {'cert_type_secure_email': 'certTypeSecureEmail',
'cert_type_ssl_client': 'certTypeSSLClient',
'cert_type_ssl_server': 'certTypeSSLServer',
'cert_type_sub_email_ca': 'certTypeSubEmailCA',
'cert_type_sub_ssl_ca': 'certTypeSubSSLCA', 'common_name':
'commonName', 'country': 'country', 'email': 'eMail',
'issued_by': 'issuedBy', 'issued_on_from': 'issuedOnFrom',
'issued_on_to': 'issuedOnTo', 'locality': 'locality',
'match_exactly': 'matchExactly', 'org': 'org', 'org_unit':
'orgUnit', 'revocation_reason': 'revocationReason', 'revoked_by':
'revokedBy', 'revoked_on_from': 'revokedOnFrom', 'revoked_on_to':
'revokedOnTo', 'serial_from': 'serialFrom', 'serial_to':
'serialTo', 'state': 'state', 'status': 'status', 'user_id':
'userID', 'valid_not_after_from': 'validNotAfterFrom',
'valid_not_after_to': 'validNotAfterTo', 'valid_not_before_from':
'validNotBeforeFrom', 'valid_not_before_to': 'validNotBeforeTo',
'validity_count': 'validityCount', 'validity_operation':
'validityOperation', 'validity_unit': 'validityUnit'}
and yes β 'email': 'eMail' β that capital M is not a typo, it's the actual wire name, please don't come for me π also 'user_id': 'userID', 'match_exactly': 'matchExactly' β the camelCase to snake_case pipeline is doing the absolute most here and we respect it π§
pki.cert.main() β that's the module's entry point, right there.
π¦ client Module π¦
class pki.client.PKIConnection(protocol='http', hostname='localhost', port='8080', subsystem=None, accept='application/json', trust_env=None, verify=True, cert_paths=None)
Bases: object
This is the class that wraps up the whole entire connection between you, the client, and a Dogtag subsystem π like it's the friend who handles all the talking to the server so you don't have to.
authenticate(username=None, password=None)
Sets the parameters used for authentication if you're going the username/password route. Both username and password must not be None β one without the other is giving nothing, bestie π Also super important: this method only sets the parameters. The actual authentication happens when the connection is attempted. So don't panic if nothing seems to happen right away.
Parameters:
usernameβ username to authenticate the connectionpasswordβ password to authenticate the connection
Returns: None
delete(path, headers=None, use_root_uri=False)
Uses python-requests to fire off a DEL request at the server. bye-bye π
Parameters:
path(str) β path URI for theDELrequestheaders(dict) β headers for theDELrequestuse_root_uri(boolean) β use the root URI instead of the subsystem URI as the base
Returns: request.response β the response from the server
Raises: Exception from python-requests in case the DEL was not successful, or returns an error code.
get(path, headers=None, params=None, payload=None, use_root_uri=False, timeout=None)
Uses python-requests to fire off a GET request at the server π
Parameters:
path(str) β path URI for theGETrequestheaders(dict) β headers for theGETrequestparams(dict or bytes) β query parameters for theGETrequestpayload(dict, bytes, file-like object) β data to be sent in the body of the requestuse_root_uri(boolean) β use the root URI instead of the subsystem URI as the base
Returns: request.response β the response from the server
Raises: Exception from python-requests in case the GET was not successful, or returns an error code.
heads up: timeout is right there in the signature, bestie β it's in the original signature so it's in mine, don't come for me about it β¨
post(path, payload, headers=None, params=None, use_root_uri=False)
Uses python-requests to fire off a POST request at the server π₯ note that payload is the second positional here β not headers, not params β payload. Do not get it twisted.
Parameters:
path(str) β path URI for thePOSTrequestpayload(dict, bytes, file-like object) β data to be sent in the body of the requestheaders(dict) β headers for thePOSTrequestparams(dict or bytes) β query parameters for thePOSTrequestuse_root_uri(boolean) β use the root URI instead of the subsystem URI as the base
Returns: request.response β the response from the server
Raises: Exception from python-requests in case the POST was not successful, or returns an error code.
put(path, payload, headers=None, use_root_uri=False)
Uses python-requests to fire off a PUT request at the server π
Parameters:
path(str) β path URI for thePUTrequestpayload(dict, bytes, file-like object) β data to be sent in the body of the requestheaders(dict) β headers for thePUTrequestuse_root_uri(boolean) β use the root URI instead of the subsystem URI as the base
Returns: request.response β the response from the server
Raises: Exception from python-requests in case the PUT was not successful, or returns an error code.
set_authentication_cert(pem_cert_path, pem_key_path=None)
Points this thing at the PEM file holding the certificate and the private key for the client certificate you're using to authenticate to the server β this is for when client certificate auth is what's required π The private key can optionally live at a completely different path, which is why pem_key_path exists. You're welcome.
Parameters:
pem_cert_path(str) β path to the PEM filepem_key_path(str) β path to the PEM-formatted private key file
Returns: None
Raises: Exception if the path is empty or None β so like, actually give it a path, bestie π«
class pki.client.SSLContextAdapter(pool_connections=10, pool_maxsize=10, max_retries=0, pool_block=False, verify=True, cert_paths=None)
Bases: requests.adapters.HTTPAdapter
A custom SSLContext Adapter for requests β¨ the upgrade you didn't know you needed.
init_poolmanager(connections, maxsize, block=False, **pool_kwargs)
Initializes a urllib3 PoolManager πΈ
Fair warning, bestie: this method should not be called from user code β it's only exposed for use when you're subclassing HTTPAdapter. So unless you're out here doing the subclass thing, hands off π
Parameters:
connectionsβ the number of urllib3 connection pools to cache.maxsizeβ the maximum number of connections to save in the pool.blockβ block when no free connections are available.pool_kwargsβ extra keyword arguments used to initialize thePool Manager.
pki.client.catch_insecure_warning(func)
Temporarily silences InsecureRequestWarning π
The deal here: PKIConnection is not able to verify HTTPS connections yet, so this decorator catches that warning for you. It's a whole thing.
See https://fedorahosted.org/pki/ticket/1253
pki.client.main()
Test code for the PKIConnection class. :return: None
π crypto Module π
Module containing crypto classes.
class pki.crypto.CryptoProvider
Bases: object
An abstract class containing methods to do cryptographic operations π₯ like it's the blueprint, not the building.
abstract asymmetric_wrap(data, wrapping_cert, mechanism=None)
Encrypts a symmetric key using the public key of a transport cert π and the mechanism here is the type of symmetric key β which defaults to a 56 bit DES3 key. Fifty-six. Bit. DES3. That's the default, no cap β
and the abstract methods keep coming, bestie:
abstract generate_nonce_iv(mechanism)β Create a random initialization vectorabstract generate_session_key()β Generate a session key to be used for wrapping data to the DRM This must return a 3DES 168 bit keyabstract generate_symmetric_key(mechanism=None, size=0)β Generate and return a symmetric keyabstract get_cert(cert_nick)β Get the certificate for the specifiedcert_nick.abstract get_supported_algorithm_keyset()β returns highest supported algorithm keysetabstract initialize()β Initialization codeabstract key_unwrap(mechanism, data, wrapping_key, nonce_iv)β Unwrap data that has been key wrapped using AES KeyWrapabstract set_algorithm_keyset(level)β sets required keysetabstract symmetric_unwrap(data, wrapping_key, mechanism=None, nonce_iv=None)β decrypt data originally encrypted with symmetric key (wrapping key). We expect thedataandnonce_ivvalues to be base64 encoded. Themechanismis the type of key used to do the wrapping. It defaults to a 56 bit DES3 key.abstract symmetric_wrap(data, wrapping_key, mechanism=None, nonce_iv=None)β encrypt data using a symmetric key (wrapping key)
π pki.crypto.CryptographyCryptoProvider π
class pki.crypto.CryptographyCryptoProvider(transport_cert_nick, transport_cert, backend=<OpenSSLBackend(version: OpenSSL 3.0.1 14 Dec 2021, FIPS: False)>)
Bases: pki.crypto.CryptoProvider
Class that defines python-cryptography implementation of CryptoProvider. Requires a PEM file containing the agent cert to be initialized.
Note that all inputs and outputs are unencoded.
asymmetric_wrap(data, wrapping_cert, mechanism=None)β Wrap (encrypt) data using the supplied asymmetric keydataβ Data to be wrappedwrapping_certβ Public key to wrap datamechanismβ algorithm of symmetric key to be wrapped
generate_nonce_iv(mechanism='AES')β Create a random initialization vectorgenerate_session_key()β Returns a session key to be used when wrapping secrets for the DRM.generate_symmetric_key(mechanism=None, size=0)β Returns a symmetric key.get_cert(cert_nick)βcert_nickβ Nickname for the certificate to be returned.
get_supported_algorithm_keyset()β returns highest supported algorithm keysetinitialize()β Any operations here that need to be performed before crypto operations.key_unwrap(mechanism, data, wrapping_key, nonce_iv)β Unwrap the encrypted data which has been wrapped using a KeyWrap mechanism.mechanismβ key wrapping mechanismdataβ data to unwrapwrapping_keyβ AES key used to wrap datanonce_ivβ Nonce datareturnβ unwrapped data
set_algorithm_keyset(level)β sets required keysetsymmetric_unwrap(data, wrapping_key, mechanism=None, nonce_iv=None)β Unwrap (decrypt) data using the supplied symmetric keydataβ Data to be unwrappedwrapping_keyβ Symmetric key to unwrap datamechanismβ Mechanism to use when unwrappingnonce_ivβ iv data
symmetric_wrap(data, wrapping_key, mechanism=None, nonce_iv=None)β Wrap (encrypt) data using the supplied symmetric keydataβ Data to be wrappedwrapping_keyβ Symmetric key to wrap datamechanismβ Mechanism to use for wrapping keynonce_ivβ Nonce for initialization vector
π encoder Module π
pki.encoder.CustomTypeDecoder(dct)β just a little decoder helper, no extra description given
πΈ pki.encoder.CustomTypeEncoder πΈ
class pki.encoder.CustomTypeEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)
Bases: json.encoder.JSONEncoder
A custom JSONEncoder class that knows how to encode core custom objects.
Custom objects are encoded as JSON object literals (ie, dicts) with one key, 'TypeName' where 'TypeName' is the actual name of the type to which the object belongs. That single key maps to another object literal which is just the __dict__ of the object encoded.
Reason for ignoring the error: E0202 - An attribute affected injson.encoderline 157 hide this method reported by pylint: The error is injson.encoder.JSONEncoderclass. There is adefaultmethod (which is overridden here) and also a class attributeself.defaultinitialized in theinitmethod of the class. The intention of such usage being that a customdefaultmethod object can be passed toinitwhen creating an instance ofJSONEncoder, which is then assigned to class'sdefaultmethod. (which is valid) But pylint raises an issue due to the usage of same name for a method and an attribute in which case the attribute definition hides the method. The reason and example for the issue: (top rated comment)http://stackoverflow.com/questions/12949064/python-what-happens-when-instance-variable-name-is-same-as-method-name
static attr_name_conversion(attr_dict, object_class)β no description, it's just vibing heredefault(o)β Implement this method in a subclass such that it returns a serializable object foro, or calls the base implementation (to raise aTypeError).
For example, to support arbitrary iterators, you could implement default like this:
def default(self, o):
try:
iterable = iter(o)
except TypeError:
pass
else:
return list(iterable)
# Let the base class default method raise the TypeError
return JSONEncoder.default(self, o)
pki.encoder.decode_cert(data)β base64 decode X.509 certificate- Parameters:
data(str,bytes) -- data as bytes or ASCII text - Return type:
bytes
- Parameters:
pki.encoder.encode_cert(data)β base64 encode X.509 certificate
Python 3's base64.b64encode() doesn't support ASCII text.
- Parameters:
data(str,bytes) -- data as bytes or ASCII text - Return type:
bytes
π key Module π
Module containing the Python client classes for the KeyClient and KeyRequestClient REST API on a DRM
π pki.key.AsymKeyGenerationRequest π
class pki.key.AsymKeyGenerationRequest(client_key_id=None, key_size=None, key_algorithm=None, key_usages=None, trans_wrapped_session_key=None, realm=None)
Bases: pki.ResourceMessage
Class representing the data sent to the DRM when generating and archiving asymmetric keys in the DRM.
DECRYPT_USAGE = 'decrypt'DERIVE_USAGE = 'derive'ENCRYPT_USAGE = 'encrypt'SIGN_RECOVER_USAGE = 'sign_recover'SIGN_USAGE = 'sign'UNWRAP_USAGE = 'unwrap'VERIFY_RECOVER_USAGE = 'verify_recover'VERIFY_USAGE = 'verify'WRAP_USAGE = 'wrap'
π¦ pki.key.Key π¦
class pki.key.Key(key_data)
Bases: object
An instance of this class stores the decoded encrypted secret present in the KeyData object passed in the constructor. All the key retrieval requests return this object.
π pki.key.KeyArchivalRequest π
class pki.key.KeyArchivalRequest(client_key_id=None, data_type=None, wrapped_private_data=None, trans_wrapped_session_key=None, pki_archive_options=None, algorithm_oid=None, symkey_params=None, key_algorithm=None, key_size=None, realm=None)
Bases: pki.ResourceMessage
Class representing the object sent to the DRM when archiving a secret.
π pki.key.KeyClient π
class pki.key.KeyClient(connection, crypto, transport_cert_nick=None, info_client=None)
Bases: object
Class that encapsulates and mirrors the functions in the KeyResource and KeyRequestResource Java classes in the DRM REST API.
AES_ALGORITHM = 'AES'ASYMMETRIC_KEY_TYPE = 'asymmetricKey'DES3_ALGORITHM = 'DES3'DESEDE_ALGORITHM = 'DESede'DES_ALGORITHM = 'DES'DSA_ALGORITHM = 'DSA'KEY_STATUS_ACTIVE = 'active'KEY_STATUS_INACTIVE = 'inactive'PASS_PHRASE_TYPE = 'passPhrase'RC2_ALGORITHM = 'RC2'RC4_ALGORITHM = 'RC4'RSA_ALGORITHM = 'RSA'SYMMETRIC_KEY_TYPE = 'symmetricKey'approve_request(request_id)β Approve a secret recovery requestarchive_encrypted_data(client_key_id, data_type, encrypted_data, wrapped_session_key, algorithm_oid=None, nonce_iv=None, key_algorithm=None, key_size=None, realm=None)β Archive a secret (symmetric key or passphrase) on the DRM.
Refer to archive_key() comments for a description of client_key_id, data_type, key_algorithm and key_size.
The following parameters are also required:
encrypted_data- which is the data encrypted by a session key (168 bit 3DES symmetric key)wrapped_session_key- the above session key wrapped by the DRM transport certificate public key.- the
algorithm_oidstring for the symmetric key wrap - the
nonce_ivfor the symmetric key wrap
This function is useful if the caller wants to do their own wrapping of the secret, or if the secret was generated on a separate client machine and the wrapping was done there.
The function returns a KeyRequestResponse object containing a KeyRequestInfo object with details about the archival request and key archived.
archive_key(client_key_id, data_type, private_data, key_algorithm=None, key_size=None, realm=None) π
Okay so this one archives a secret on the DRM β and by secret we mean a symmetric key or a passphrase, no biggie. π
It needs a user-supplied client ID, and here's the thing: there can be only one active key with a given client ID. So if a record for a duplicate active key already exists? Boom, BadRequestException gets thrown at you. Not cute, but that's the rule. π
data_type can be one of these three besties:
KeyClient.SYMMETRIC_KEY_TYPEKeyClient.ASYMMETRIC_KEY_TYPEKeyClient.PASS_PHRASE_TYPE
key_algorithm and key_size only apply to symmetric keys β like, only. If you're archiving a symmetric key, these params are required, periodt.
private_data is the raw secret being archived. It gets wrapped and yeeted off to the DRM. β¨
Returns a KeyRequestResponse object holding a KeyRequestInfo object with all the deets about the archival request and the key that got archived. π«Ά
archive_pki_options(client_key_id, data_type, pki_archive_options, key_algorithm=None, key_size=None, realm=None) πΈ
Same vibe as above β archives a secret (symmetric key or passphrase) on the DRM. π
For client_key_id, data_type, key_algorithm and key_size, just go read the archive_key() comments, bestie, they're right there.
pki_archive_options is the data to be archived, wrapped in a PKIArchiveOptions structure.
Returns a KeyRequestResponse object containing a KeyRequestInfo object with the details about the archival request and key archived. π¦
cancel_request(request_id) π«
Cancels a secret recovery request. That's it. That's the whole thing. Short and iconic.
generate_asymmetric_key(client_key_id, algorithm=None, key_size=None, usages=None, trans_wrapped_session_key=None, realm=None) π
Generates and archives asymmetric keys in the DRM. Supports the algorithms RSA and DSA. π
Valid key sizes:
- RSA =
256 + (16 * n), wheren:0-496 - DSA =
512,768,1024
Also, p,q,g params are not supported β don't come for me, that's just how it is. π
Returns a KeyRequestResponse which contains a KeyRequestInfo object describing the URL for the request and the generated keys. π
generate_symmetric_key(client_key_id, algorithm=None, size=None, usages=None, trans_wrapped_session_key=None, realm=None) β¨
Generates and archives a symmetric key on the DRM. Simple, clean, slays.
Returns a KeyRequestResponse which contains a KeyRequestInfo object describing the URL for the request and the generated key. π
get_active_key_info(client_key_id) π
Gets the info in the KeyRecord for the active secret in the DRM. That's the tea. β
get_client_keyset() π§
Yep, that's it β no description in the original, so I'm not gonna make one up. It's giving mysterious main character energy. π
get_key_info(key_id) π
Gets the info in the KeyRecord for a specific secret in the DRM. Specificity is key, iykyk. π
get_request_info(request_id) π
Returns a KeyRequestInfo object for a specific request. Clean, useful, we love her.
get_server_keyset() π
Again β no description given. She's enigmatic, she's lowkey, she's not telling us anything. β
list_keys(client_key_id=None, status=None, max_results=None, max_time=None, start=None, size=None, realm=None) π
Lists/searches archived secrets in the DRM. π¦
For the valid values of status, check out KRAClient.list_keys. Returns a KeyInfoCollection object. π
list_requests(request_state=None, request_type=None, client_key_id=None, start=None, page_size=None, max_results=None, max_time=None, realm=None) ποΈ
Lists/searches key requests in the DRM.
For the valid values of request_state and request_type, look at KRAClient.list_requests. Returns a KeyRequestInfoCollection object. β¨
modify_key_status(key_id, status) π
Modifies the status of a key. Short, sweet, does what it says on the tin. π
process_returned_key(key, session_key) π
Decrypts the returned key and places it in key.data. π«
So the data will either be encrypted using an encryption algorithm β in which case the key data will contain an encryption algorithm OID β or it will be key wrapped, in which case the key data contains a key wrap mechanism name.
Only one of those should be present at a time, ngl. And if we're talking to an older server and neither is present? We assume encryption. That's the fallback, don't @ me. π
recover_key(key_id, request_id=None, session_wrapped_passphrase=None, trans_wrapped_session_key=None, b64certificate=None, nonce_data=None) ποΈ
Creates a request to recover a secret. Let's get that key back, bestie. π
To retrieve a symmetric key or passphrase, the only parameter required is the keyId. It's possible (but not required!) to pass in the session keys/passphrase and nonceData for the retrieval at this time β those params are documented in the docstring for retrieve_key below. π
To retrieve an asymmetric key, you need the keyId and the base-64 encoded certificate. Both. No skipping. π
reject_request(request_id) β
Rejects a secret recovery request. Not today, request. π ββοΈ
retrieve_key(key_id=None, trans_wrapped_session_key=None, request_id=None) π
Retrieves a secret (passphrase or symmetric key) from the DRM. The moment we've all been waiting for. β¨
This method grabs a key from the KRA given the key_id or request_id β and yep, one of those must be specified. The data comes back as a KeyData object (which gets recast to a Key object).
If request_id is specified, then the value of key_id is straight-up ignored. Exceptions will be thrown if the caller isn't the originator of the request, or if the request isn't approved. So like, behave. π
If key_id is specified instead, here's the behavior:
- If the key can be retrieved synchronously β i.e. only one agent's approval is required β then the
KeyDatawill include the secret. π - If the key cannot be retrieved synchronously β i.e. if more than one approval is needed β then the
KeyDataobject will include the request ID for a recovery request that was created on the server. When that request gets approved, callers can retrieve the key usingretrieve_key()and setting therequest_id. π«Ά
To ensure data security in transit, the data is returned encrypted by a session key (a 168 bit 3DES symmetric key) β which is first wrapped (encrypted) by the public key of the DRM transport certificate before being sent to the DRM. The parameter trans_wrapped_session_key refers to this wrapped session key. π
If trans_wrapped_session_key is not provided by the caller, the method calls CryptoProvider methods to generate and wrap the session key. The function returns the KeyData object with a private_data attribute which stores the unwrapped key information. π
If trans_wrapped_session_key is provided by the caller, the method will just pass the data straight to the KRA, and returns the secret wrapped in the session key. The secret still needs to be unwrapped by the caller. The function returns the KeyData object, where the KeyData structure includes the wrapped secret and some nonce data to be used as a salt when unwrapping. π§
retrieve_key_by_passphrase(key_id=None, request_id=None, passphrase=None, trans_wrapped_session_key=None, session_wrapped_passphrase=None, nonce_data=None) π
Retrieves a secret (passphrase or symmetric key) from the DRM using a passphrase. Fancy, right? π
This function generates a key recovery request, approves it, and retrieves the secret referred to by key_id. It assumes only one approval is required to authorize the recovery. β¨
The secret is secured in transit by wrapping the secret with a passphrase using PBE encryption. π
There are two ways to use this function:
- A passphrase is provided by the caller.
In this case, CryptoProvider methods get called to create the data to securely send the passphrase to the DRM. Basically, three pieces of data get sent:
- the passphrase wrapped by a 168 bit 3DES symmetric key (the session key). This is referred to as the parameter
session_wrapped_passphrase. - the session key wrapped with the public key in the DRM transport certificate. This is referred to as the
trans_wrapped_session_key. - ivps nonce data, referred to as
nonce_data.
The function returns the tuple (KeyData, unwrapped_secret). π¦
- The caller provides the
trans_wrapped_session_key,session_wrapped_passphraseandnonce_data.
In this case, the data simply gets passed to the DRM. The function returns the secret encrypted by the passphrase using PBE Encryption. The secret will still need to be decrypted by the caller.
The function returns the tuple (KeyData, None). πΈ
retrieve_key_by_pkcs12(key_id, certificate, passphrase) π
Retrieves an asymmetric private key and returns it as PKCS12 data.
This function generates a key recovery request, approves it, and retrieves the secret referred to by key_id in a PKCS12 file. It assumes only one approval is required to authorize the recovery. π«
Required parameters:
key_idβ the ID of the keycertificateβ the certificate associated with the private keypassphraseβ a passphrase for the pkcs12 file
Returns a KeyData object. π
retrieve_key_data(data) π¦
Retrieves a secret from the DRM. That's the whole description β she's concise, she's efficient, she ate. π β¨
@param: data β a KeyRecoveryRequest that's holding onto the keyId of the secret you're grabbing, the request_id of the approved recovery request, and a wrapping mechanism. Bestie, there are more details at KRAClient.retrieve_key, so go look π.
Returns a KeyData object that's carrying the wrapped secret. π
set_crypto_algorithms()β sets the crypto algorithms, that's it, that's the whole vibe.set_transport_cert(transport_cert_nick)β set the transport certificate for crypto operations. πsubmit_request(request)β submit an archival, recovery or key generation request to the DRM.
@param: request is either a KeyArchivalRequest, KeyRecoverRequest, SymKeyGenerationRequest or AsymKeyGenerationRequest.
Returns a KeyRequestResponse object. β¨
class pki.key.KeyData
Bases: object
OK so this is the object that holds the encoded wrapped secret once that secret has actually been retrieved. The DRM uses it to send key info along in the key retrieval requests. It's giving very "delivery girl" energy π¦.
classmethod from_json(attr_list)β return aKeyDataobject from a JSON dict.json_attribute_namesβ literally this exact mapping, do not touch:
{'encryptAlgorithmOID': 'encrypt_algorithm_oid', 'nonceData': 'nonce_data', 'publicKey': 'public_key', 'requestID': 'request_id', 'wrapAlgorithm': 'wrap_algorithm', 'wrappedPrivateData': 'wrapped_private_data'}
class pki.key.KeyInfo
Bases: object
This one contains the info stored in the database record for an archived secret. Read that again β it does not contain the secret itself. No secret here, just the metadata, iykyk π.
classmethod from_json(attr_list)β returnKeyInfofrom a JSON dict.get_key_id()β return the key ID as parsed from the key URL. πjson_attribute_namesβ exact mapping, keep it character for character:
{'clientKeyID': 'client_key_id', 'keyURL': 'key_url', 'ownerName': 'owner_name', 'publicKey': 'public_key'}
class pki.key.KeyInfoCollection
Bases: object
This class represents the data you get back when you go searching the DRM for archived secrets. Essentially it's just a list of KeyInfo objects β a little squad of them π«Ά.
classmethod from_json(json_value)β return aKeyInfoCollectionobject from its JSON representation.
class pki.key.KeyRecoveryRequest
KeyRecoveryRequest(key_id=None, request_id=None, trans_wrapped_session_key=None, session_wrapped_passphrase=None, nonce_data=None, certificate=None, passphrase=None, payload_wrapping_name=None, payload_encryption_oid=None)
Bases: pki.ResourceMessage
Class representing the data that gets sent to the DRM when you're either (a) creating a request for the recovery of a secret, or (b) retrieving the secret once that request is approved. Two moods, one class π«.
class pki.key.KeyRequestInfo
Bases: object
This class represents data about key requests in the DRM β archival, recovery, key generation, the whole lineup.
classmethod from_json(attr_list)β return aKeyRequestInfoobject from a JSON dict.get_key_id()β return the ID of the secret that this request is referring to. π―get_request_id()β return the request ID by parsing the request URL.json_attribute_namesβ exact mapping, no cap:
{'keyURL': 'key_url', 'requestStatus': 'request_status', 'requestType': 'request_type', 'requestURL': 'request_url'}
class pki.key.KeyRequestInfoCollection
Bases: object
This is the data returned when you search the key requests in the DRM. Essentially, it's a list of KeyRequestInfo objects. A little collection, a little roster, we love a list πΈ.
classmethod from_json(json_value)β return aKeyRequestInfoCollectionobject from its JSON representation.
class pki.key.KeyRequestResponse
Bases: object
This is what comes back when an archival, recovery or key generation request gets created. It's packing a KeyRequestInfo object with the deets about the created request, plus a KeyData structure holding the wrapped secret (but only if that operation is supported β vibe check on that one π).
classmethod from_json(json_value)β return aKeyRequestResponseobject from its JSON representation.get_key_id()β return the id for the key that was archived, recovered or generated.get_request_id()β return the id for the created request.
class pki.key.RequestId(req_id)
Bases: object
Class representing a Request ID. Short, sweet, iconic. π
class pki.key.SymKeyGenerationRequest
SymKeyGenerationRequest(client_key_id=None, key_size=None, key_algorithm=None, key_usages=None, trans_wrapped_session_key=None, realm=None)
Bases: pki.ResourceMessage
Class representing the data sent to the DRM when you're generating and archiving a symmetric key in the DRM. Double duty, main character energy π.
The usage constants, exact values, no editing:
DECRYPT_USAGE='decrypt'ENCRYPT_USAGE='encrypt'SIGN_USAGE='sign'UNWRAP_USAGE='unwrap'VERIFY_USAGE='verify'WRAP_USAGE='wrap'
pki.key.main()
Some unit tests β basically it just prints out different types of requests. Not deep, but it ate. π
π kra Module
Module containing the KRAClient class. Python clients should use this class to interact with the DRM to expose the functionality of the KeyClient and KeyRequestResource REST APIs. It's the little bridge between you and the DRM π«Ά.
class pki.kra.KRAClient(connection, crypto, transport_cert_nick=None)
Bases: object
Client class that models interactions with a KRA using the Key and KeyRequest REST APIs. Yes bestie, this is the one that does the talking. β¨
π¦ profile Module
class pki.profile.Descriptor(syntax=None, constraint=None, description=None, default_value=None)
Bases: object
This class represents the description of a ProfileAttribute. It stores the info like the syntax, constraint and default value of a profile attribute. Basically a little info card for your attribute π.
classmethod from_json(attr_list)β from JSON, as the name so obviously says.json_attribute_namesβ exact mapping, copy it right:
{'Constraint': 'constraint', 'DefaultValue': 'default_value', 'Description': 'description', 'Syntax': 'syntax'}
class pki.profile.PolicyConstraint(name=None, description=None, class_id=None, policy_constraint_values=None)
Bases: object
An object of this class contains the policy constraints applied to a ProfileInput used by a certificate enrollment request. Very much giving "the rules" energy π.
add_constraint_value(policy_constraint_value)β add aPolicyConstraintValueto thepolicy_constraint_valueslist.classmethod from_json(attr_list)β from JSON.get_constraint_value(policy_constraint_value_name)β returns aPolicyConstraintValueobject with the given name. ReturnsNoneif there's no match. π«json_attribute_namesβ exact:
{'classId': 'class_id', 'constraint': 'policy_constraint_values', 'id': 'name'}
remove_constraint_value(policy_constraint_value_name)β removes aPolicyConstraintValuewith the given name form thepolicy_constraint_valueslist. (Yes, "form" β that's the original's typo, I'm not fixing it, I'm just a girl π«Ά.)
class pki.profile.PolicyConstraintValue(name=None, value=None, descriptor=None)
Bases: object
Represents a PolicyConstraintValue. That's the whole job description π
.
classmethod from_json(attr_list)β from JSON.property nameβ it's a property. That's... the name. πΈ
class pki.profile.PolicyDefault(name=None, class_id=None, description=None, policy_attributes=None, policy_params=None)
Bases: object
An object of this class contains info about the default usage of a specific ProfileInput. Like, the fallback vibe β¨.
add_attribute(policy_attribute)β add a policy attribute to the attribute list. @param:policy_attributeβ aProfileAttributeobject.add_parameter(policy_parameter)β add a profile parameter to the parameters list. @param:policy_parameterβ aProfileParameterobject.classmethod from_json(attr_list)β from JSON.get_attribute(policy_attribute_name)β fetch the policy attribute with the given name from the attributes list.get_parameter(profile_parameter_name)β fetch a profile parameter with the given name from the parameters list.json_attribute_namesβ exact, bestie:
{'classId': 'class_id', 'id': 'name', 'params': 'policy_params', 'policyAttribute': 'policy_attributes'}
remove_attribute(policy_attribute_name)β remove a policy attribute with the given name from the attributes list.remove_parameter(profile_parameter_name)β remove a profile parameter with the given name from the parameters list.
class pki.profile.PolicySet(name=None, policy_list=None)
Bases: object
An object of this class contains a name-value pair situation β the policy name, and the ProfilePolicy object. π―
add_policy(profile_policy)β add aProfilePolicyobject to thepolicy_list.classmethod from_json(attr_list)β from JSON.get_policy(policy_id)β returns aProfilePolicyobject with the given profile id.json_attribute_namesβ exact:
{'id': 'name', 'value': 'policy_list'}
remove_policy(policy_id)β removes aProfilePolicywith the given ID from thePolicySet.
class pki.profile.PolicySetList(policy_sets=None)
Bases: object
An object of this class stores a list of ProfileSet objects. (Yep, ProfileSet, that's what it says β hold that thought π«Ά.)
add_policy_set(policy_set)β add aPolicySetobject to thepolicy_setslist.classmethod from_json(attr_list)β from JSON.get_policy_set(policy_set_name)β fetch thePolicySetobject for the given name. ReturnsNoneif it's not found. πproperty policy_setsβ the property itself, living its life.remove_policy_set(policy_set_name)β remove aPolicySetobject with the given name from thepolicy_setslist.
class pki.profile.Profile
Profile(profile_id=None, class_id=None, name=None, description=None, enabled=None, visible=None, enabled_by=None, authenticator_id=None, authorization_acl=None, renewal=None, xml_output=None, inputs=None, outputs=None, policy_set_list=None, link=None)
Bases: object
This class represents an enrollment profile. Main character of the profile module, honestly π.
add_input(profile_input)β add aProfileInputobject to theinputslist of theProfile.add_output(profile_output)β add aProfileOutputobject to theoutputslist of theProfile.add_policy_set(policy_set)β add aPolicySetobject to thepolicy_setslist of theProfile.classmethod from_json(attr_list)β
okay bestie, back to the Profile class methods β these are the ones that actually do stuff π
get_input(profile_input_id)β Fetches aProfileInputwith the givenProfileInputid. ReturnsNoneif thereβs no matching input. (so if it ghosts you, thatβs why π)get_output(profile_output_id)β Fetches aProfileOutputwith the givenProfileOutputid. ReturnsNoneif thereβs no matching output.get_policy_set(policy_set_name)β Fetches aProfileInputwith the givenProfileInputid. ReturnsNoneif thereβs no matching input. (yes, the original saysProfileInputhere β lowkey a copy-paste moment, but weβre keeping it fr fr π«Ά)static get_profile_data_from_file(path_to_file)β Reads the file for the serializedProfileobject. Currently supports only data format in json. No cap, json only β¨
Then thereβs this mapping of json attribute names β keep it close, itβs important:
json_attribute_names = {'Input': 'inputs', 'Output': 'outputs',
'PolicySets': 'policy_set_list', 'authenticatorId':
'authenticator_id', 'authzAcl': 'authorization_acl', 'classId':
'class_id', 'enabledBy': 'enabled_by', 'id': 'profile_id',
'xmlOutput': 'xml_output'}
remove_input(profile_input_id)β Remove aProfileInputfrom the inputs list of theProfile.remove_output(profile_output_id)β Remove aProfileOutputfrom the outputs list of theProfile.remove_policy_set(policy_set_name)β Remove aPolicySetfrom thepolicy_setslist of theProfile.
π class pki.profile.ProfileAttribute(name=None, value=None, descriptor=None)
Bases: object
Represents a profile attribute of a ProfileInput. Itβs giving βone little detail that mattersβ energy π
classmethod from_json(attr_list)
The mapping:
json_attribute_names = {'Descriptor': 'descriptor', 'Value': 'value'}
π class pki.profile.ProfileClient(connection)
Bases: object
This class consists of methods for accessing the ProfileResource. Basically your main character for talking to profiles π₯
create_profile(profile_data)β Create a new profile for the givenProfileobject.create_profile_from_file(path_to_file)β Reads the file for the serializedProfileobject. Performs the profile create operation. Currently supports only data format in json.delete_profile(profile_id)β Delete a profile with the givenProfileId.disable_profile(profile_id)β Disables a profile.enable_profile(profile_id)β Enables a profile.get_profile(profile_id)β Fetches information for the profile for the given profile id. Returns aProfileDataobject.list_profiles(start=None, size=None)β Fetches the list of profiles. Thestartandsizearguments provide pagination support. Returns aProfileDataInfoCollectionobject.modify_profile(profile_data)β Modify an existing profile with the givenProfileobject.modify_profile_from_file(path_to_file)β Reads the file for the serializedProfileobject. Performs the profile modify operation. Currently supports only data format in json.
πΈ class pki.profile.ProfileDataInfo
Bases: object
Stores information about a profile. Like a little info card, but make it secure π
classmethod from_json(attr_list)
The mapping:
json_attribute_names = {'profileDescription':
'profile_description', 'profileId': 'profile_id', 'profileName':
'profile_name', 'profileURL': 'profile_url'}
π¦ class pki.profile.ProfileDataInfoCollection
Bases: object
Represents a collection of ProfileDataInfo objects. Also encapsulates the links for the list of the objects stored. Itβs giving βorganized queenβ energy π
classmethod from_json(attr_list)
π class pki.profile.ProfileInput(profile_input_id=None, class_id=None, name=None, text=None, attributes=None, config_attributes=None)
Bases: object
This class encapsulates all the attributes of a profile to generate a specific property of a certificate. Ex. Subject name, Requestor Information etc. So itβs the blueprint for cert details β¨
add_attribute(profile_attribute)β Add aProfileAttributeobject to theattributeslist.add_config_attribute(profile_attribute)β Add aProfileAttributeobject to theconfig_attributeslist.classmethod from_json(attr_list)get_attribute(profile_attribute_name)β Returns aProfileAttributeobject for the given name.Noneif no match.get_config_attribute(config_attribute_name)β Returns aProfileAttributeobject with the given name.Noneif there is no match in theconfig_attributeslist.
The mapping:
json_attribute_names = {'Attribute': 'attributes', 'ClassID':
'class_id', 'ConfigAttribute': 'config_attributes', 'Name':
'name', 'Text': 'text', 'id': 'profile_input_id'}
remove_attribute(profile_attribute_name)β Remove aProfileAttributeobject with the given name from theattributeslist.remove_config_attribute(config_attribute_name)β Remove aProfileAttributeobject with the given name from theconfig_attributeslist.
π§ class pki.profile.ProfileOutput(profile_output_id=None, name=None, text=None, class_id=None, attributes=None)
Bases: object
This class defines the output of a certificate enrollment request using a profile. Itβs the βwhat you actually getβ vibe π
add_attribute(profile_attribute)β Add aProfileAttributeobject to theattributeslist.classmethod from_json(attr_list)get_attribute(profile_attribute_name)β Returns aProfileAttributeobject for the given name.Noneif no match.
The mapping:
json_attribute_names = {'classId': 'class_id', 'id':
'profile_output_id'}
remove_attribute(profile_attribute_name)β Remove aProfileAttributeobject with the given name from theattributeslist.
π class pki.profile.ProfileParameter(name=None, value=None)
Bases: object
classmethod from_json(attr_list)
β class pki.profile.ProfilePolicy(policy_id=None, policy_default=None, policy_constraint=None)
Bases: object
This class represents the policy a profile adheres to. An object of this class stores the default values for profile and the constraints present on the values of the attributes of the profile submitted for an enrollment request. Itβs giving βrules but make them cuteβ πβ¨
classmethod from_json(attr_list)
The mapping:
json_attribute_names = {'constraint': 'policy_constraint', 'def':
'policy_default', 'id': 'policy_id'}
π class pki.profile.ProfilePolicySet
Bases: object
Stores a list of ProfilePolicy objects. A little squad of policies, no cap π«Ά
classmethod from_json(attr_list)
β¨ pki.profile.main()
π system Module
π» class pki.system.AdminSetupRequest
Bases: object
π» class pki.system.AdminSetupResponse
Bases: object
π» class pki.system.CertificateSetupRequest
Bases: object
π» class pki.system.CertificateSetupResponse
Bases: object
π class pki.system.DomainInfo
Bases: object
Class representing the entire security domain. This is essentially a list of SecurityDomainSubsystem components. Itβs the whole map, bestie πΊοΈ
classmethod from_json(json_value)β Create aDomainInfoobject from JSON.- Parameters:
json_value(str) β JSON representation of a security domain. - Returns:
DomainInfo
- Parameters:
property systems
π class pki.system.InstallToken
Bases: object
classmethod from_json(json_value)
π‘οΈ class pki.system.SecurityDomainClient(connection)
Bases: object
Client used to get the security domain from a security domain CA. The connection details for the security domain CA are specified in a PKIConnection object used to construct this client. So youβre basically sliding into the CAβs DMs π
get_domain_info()β Contact the security domain CA specified in the connection object used to construct this client and get the security domain using the REST API.- Returns:
pki.system.DomainInfo
- Returns:
get_install_token(hostname, subsystem)- Returns:
pki.system.InstallToken
- Returns:
get_old_domain_info()β Contact the security domain CA specified in the connection object used to construct this client and get the security domain using the old servlet-based interface. This method is useful when contacting old servers which do not provide the REST API. (for the vintage servers, we still love them π)- Returns:
pki.system.DomainInfo
- Returns:
get_security_domain_info()
π class pki.system.SecurityDomainHost
Bases: object
Class representing a security domain host. Like a little address book entry but for security π‘
classmethod from_json(json_value)β Constructs aSecurityDomainHostobject from JSON.- Parameters:
json_value(str) β JSON string representing a security domain host. - Returns:
SecurityDomainHost
- Parameters:
π§© class pki.system.SecurityDomainSubsystem
Bases: object
Class representing a security domain subsystem. This is essentially a list of SecurityDomainHost objects of a particular subsystem type (ca, kra, tps, tks, ocsp). Itβs the group chat of hosts π¬
classmethod from_json(json_value)β Constructs aSecurityDomainSubsystemfrom a JSON representation.- Parameters:
json_value(str) β JSON representation of the Security Domain Subsystem - Returns:
SecurityDomainSubsystem
- Parameters:
get_host(hostname, secure_port)
π class pki.system.SystemCertData
Bases: object
Class used to represent the data for a system certificate, which is used in the data passed into and returned from the Java installation servlet during the execution of pkispawn.
This class is the python equivalent of the Java class: com.netscape.certsrv.system.SystemCertData
So itβs a little cross-language twin situation π―ββοΈ
βοΈ class pki.system.SystemConfigClient(connection, subsystem=None)
Bases: object
Client used to interact with the Java configuration servlet to configure a Dogtag subsystem during the execution of pkispawn.
The connection details for the system being configured are passed in the PKIConnection object used when constructing this object.
createCert(request)β Create certificate.
okay bestie, weβre picking up right in the middle of a method β the parameter tea is:
- Parameters:
request(CertificateSetupRequest) β Certificate setup request π«Ά - Returns:
SystemCertDataβ¨
then the next methods go:
createRequest(request)β Create certificate request. π- Parameters:
request(CertificateSetupRequest) β Certificate setup request - Returns:
SystemCertData
- Parameters:
createRequestID(request)β Create certificate request ID. π- Parameters:
request(CertificateSetupRequest) β Certificate setup request - Returns:
SystemCertData
- Parameters:
initSubsystem(request)β Initialize subsystem. πΈ- Parameters:
request(CertificateSetupRequest) β Certificate setup request
- Parameters:
still in the system zone, weβve got this absolute icon:
class pki.system.SystemStatusClient(connection, subsystem=None)
Bases: object
Client used to check the status of a Dogtag subsystem. π
get_status(timeout=None)β Checks the status of the subsystem by calling thegetStatus()servlet. This is used to determine if the server is up and ready to receive and process requests. π₯- Returns:
str- getStatus response
- Returns:
π¦ systemcert Module π¦
Module containing the Python client classes for the SystemCert REST API β¨
class pki.systemcert.SystemCertClient(connection, subsystem=None)
Bases: object
Class encapsulating and mirroring the functionality in the SystemCertResource Java interface class defining the REST API for system certificate resources. no cap, thatβs the whole vibe π
get_transport_cert()β Return transport certificate. π«- Returns:
pki.cert.CertData-- transport certificate data
- Returns:
π upgrade Module π
class pki.upgrade.PKIUpgradeScriptlet
Bases: object
backup(path)get_backup_dir()upgrade_system()
class pki.upgrade.PKIUpgradeTracker(name, filename, delimiter='=', version_key='PKI_VERSION', index_key='PKI_UPGRADE_INDEX')
Bases: object
get_index()get_version()remove()remove_index()remove_version()set(version)set_index(index)set_version(version)show()
class pki.upgrade.PKIUpgrader(upgrade_dir='/usr/share/pki/upgrade')
Bases: object
all_versions()backup(scriptlet, path)copydirs(source, dest, force=False)copyfile(source, dest, force=False)get_current_version()get_target_version()get_tracker()init_scriptlet(scriptlet)is_complete()makedirs(path, exist_ok=False)record(scriptlet, path)remove_tracker()reset_tracker()revert()revert_scriptlet(scriptlet)revert_version(version)run_scriptlet(scriptlet)scriptlets(version)set_tracker(version)show_tracker()status()touch(path)update_tracker(scriptlet)upgrade()upgrade_version(version)validate()version_dir(version)versions()
β¨ util Module β¨
Module containing utility functions and classes for the Dogtag python code π
class pki.util.Version(obj)
Bases: object
pki.util.chmod(path, mode) β Change permissions of a file, link, or folder recursively. π
pki.util.chown(path, uid, gid) β Change ownership of a file, link, or folder recursively. π
pki.util.copy(source, dest, uid=- 1, gid=- 1, dir_mode=None, file_mode=None, force=False) β Copy a file or a folder and its contents. π
pki.util.copydirs(source, dest, uid=- 1, gid=- 1, mode=None, force=False) β Copy a folder and its parents (without the contents) while preserving their attributes. π«Ά
pki.util.copyfile(source, dest, slots=None, params=None, uid=None, gid=None, mode=None, force=False) β Copy a file or link while preserving its attributes. π
pki.util.copytree(src, dst, symlinks=False, ignore=None)
Recursively copy a directory tree using copy2(). π³
PATCH: This code was copied from shutil.py and patched to allow βThe destination directory to already exist.β
If exception(s) occur, an Error is raised with a list of reasons. π
If the optional symlinks flag is true, symbolic links in the source tree result in symbolic links in the destination tree; if it is false, the contents of the files pointed to by symbolic links are copied.
The optional ignore argument is a callable. If given, it is called with the src parameter, which is the directory being visited by copytree(), and names which is the list of src contents, as returned by os.listdir():
callable(src, names) -> ignored_names
Since copytree() is called recursively, the callable will be called once for each directory that is copied. It returns a list of names relative to the src directory that should not be copied.
Consider this example code rather than the ultimate tool. π
pki.util.customize_file(input_file, output_file, params) β Customize a file with specified parameters. β¨
pki.util.load_properties(filename, properties)
pki.util.makedirs(path, mode=511, exist_ok=False, uid=- 1, gid=- 1, force=False)
pki.util.read_environment_files(env_file_list=None)
pki.util.read_text(message, options=None, default=None, delimiter=':', case_sensitive=True, password=False, required=False)
Get an input from the user. This is used, for example, in pkispawn and pkidestroy to obtain user input. π«Ά
Parameters
message(str) β prompt to display to the useroptions(list) β list of possible inputs by the user.default(str) β default value of parameter being prompted.delimiter(str) β delimiter to be used at the end of the prompt.case_sensitive(boolean -- True/False) β Allow input to be case sensitive.password(boolean -- True/False) β Input is a password. Don't show the value.required(boolean -- True/False) β Input must be non-empty.
Returns: str -- value obtained from user input.
pki.util.remove(path, force=False)
pki.util.replace_params(line, params=None) β Replace all occurrences of [param] in the line with the value of the parameter. π
pki.util.rmtree(path, force=False)
pki.util.set_property(properties, name, value)
pki.util.store_properties(filename, properties)
pki.util.symlink(source, dest, uid=- 1, gid=- 1, force=False)
pki.util.unlink(link, force=False)
and the lil index links are still here, iconic:
genindexmodindexsearch
π«Ά AUTHOR π«Ά
Dogtag PKI Project Team
π COPYRIGHT π
2022, Dogtag PKI Team
and thatβs the whole page, bestie β footer tea is source/version @APPLICATION_VERSION@ and date Apr 18, 2022, all wrapped up for PKI-PYTHON-CLIENT(1) πβ¨
π¦ where this page comes from
- centos-stream 9: pki-base 11.2.0-0.2.beta1.el9 Β· GPLv2 and LGPLv2
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms