Skip to content

Commit

Permalink
Add logic for rendering certificates in registrar API responses
Browse files Browse the repository at this point in the history
Signed-off-by: Jean Snyman <git@jsnyman.com>
  • Loading branch information
stringlytyped committed Mar 20, 2024
1 parent 282071c commit 2f7095d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 5 deletions.
14 changes: 11 additions & 3 deletions keylime/models/base/basic_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,10 +194,18 @@ def __repr__(self):
return repr

def render(self, only=None):
data = {name: getattr(self, name) for name in self.__class__.fields.keys()}
data = {}

if only:
data = {name: data[name] for name in only}
for name, field in self.__class__.fields.items():
if only and name not in only:
continue

value = getattr(self, name)

if hasattr(field.type, "render_object") and callable(getattr(field.type, "render_object")):
value = field.type.render_object(value)

data[name] = value

return data

Expand Down
19 changes: 19 additions & 0 deletions keylime/models/base/types/certificate.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,25 @@ def process_result_value(self, value, dialect):

# Cast outgoing value from DB to Certificate object
return Certificate.cast(value)

def render_object(self, value):
"""Prepares certificate object for output (typically in an HTTP response). This method is called with a
``cryptography.x509.Certificate`` object as argument whenever a call is made to ``record.render()`` where
``record`` has a field of type Certificate.
:raises: :class:`TypeError`: ``value`` is not of type ``str``, ``bytes`` or ``cryptography.x509.Certificate``
:raises: :class:`ValueError`: ``value`` does not contain data which is interpretable as a certificate
:returns: A string containing the certificate in PEM format
"""

if not value:
return None

# Cast value to Certificate object
cert = Certificate.cast(value)
# Render certificate in PEM format
return cert.public_bytes(Encoding.PEM).decode("utf-8")

@property
def type_mismatch_msg(self):
Expand Down
10 changes: 8 additions & 2 deletions keylime/models/registrar/registrar_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,9 +236,15 @@ def verify_ak_response(self, response):

def render(self, only=None):
if not only:
only = ["agent_id", "ek_tpm", "ekcert", "aik_tpm", "mtls_cert", "ip", "port", "regcount"]
only = ["agent_id", "ek_tpm", "aik_tpm", "mtls_cert", "ip", "port", "regcount"]

if self.virtual:
only.append("provider_keys")

return super().render(only)
output = super().render(only)

# When operating in pull mode, ekcert is encoded as Base64 instead of PEM
if self.ekcert:
output["ekcert"] = base64.b64encode(self.ekcert.public_bytes(Encoding.DER)).decode("utf-8")

return output

0 comments on commit 2f7095d

Please sign in to comment.