Home | History | Annotate | Download | only in cros
      1 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import tempfile
      6 
      7 from autotest_lib.client.bin import utils
      8 
      9 class PEMCertificate(object):
     10     """Object enclosing a PEM certificate.
     11 
     12     Uses the "openssl" utility to report various properties of a certificate.
     13 
     14     """
     15     OPENSSL_COMMAND = 'openssl'
     16     ATTRIBUTE_SUBJECT = 'subject'
     17     ATTRIBUTE_FINGERPRINT = 'fingerprint'
     18 
     19     def __init__(self, pem_contents):
     20         self._pem_contents = pem_contents
     21         self._fingerprint = None
     22         self._subject = None
     23         self._subject_dict = None
     24 
     25 
     26     def get_attribute(self, attribute):
     27         """Returns the named attribute of the certificate.
     28 
     29         @param attribute string referring to the attribute to retrieve.
     30         @return string containing the retrieved attribute value.
     31 
     32         """
     33         with tempfile.NamedTemporaryFile() as temp:
     34             temp.write(self._pem_contents)
     35             temp.flush()
     36             output = utils.system_output(
     37                 '%s x509 -noout -%s -in %s' %
     38                 (self.OPENSSL_COMMAND, attribute, temp.name))
     39         # Output is of the form "name=value..."
     40         return output.split('=', 1)[1]
     41 
     42 
     43     @property
     44     def fingerprint(self):
     45         """Returns the SHA-1 fingerprint of a certificate."""
     46         if self._fingerprint is None:
     47             self._fingerprint = self.get_attribute(self.ATTRIBUTE_FINGERPRINT)
     48         return self._fingerprint
     49 
     50 
     51     @property
     52     def subject(self):
     53         """Returns the subject DN of the certificate as a list of name=value"""
     54         if self._subject is None:
     55             subject = self.get_attribute(self.ATTRIBUTE_SUBJECT)
     56             # OpenSSL returns a form of:
     57             #   " /C=US/ST=CA/L=Mountain View/CN=chromelab..."
     58             # but we want to return something like:
     59             #   [ "C=US", "ST=CA", "L=Mountain View", "CN=chromelab..." ]
     60             self._subject = subject.lstrip(' /').split('/')
     61         return self._subject
     62 
     63 
     64     @property
     65     def subject_dict(self):
     66         """Returns the subject DN of the certificate as a dict of name:value"""
     67         if self._subject_dict is None:
     68           # Convert the list [ 'A=B', ... ] into a dict { 'A': 'B',  ... }
     69           self._subject_dict = dict(map(lambda x: x.split('=', 1),
     70                                         self.subject))
     71         return self._subject_dict
     72