Example #1
0
    def parse(self, x509_obj):
        extensions = []
        seen_oids = set()
        for i in range(self.ext_count(x509_obj)):
            ext = self.get_ext(x509_obj, i)
            self._backend.openssl_assert(ext != self._backend._ffi.NULL)
            crit = self._backend._lib.X509_EXTENSION_get_critical(ext)
            critical = crit == 1
            oid = x509.ObjectIdentifier(
                _obj2txt(self._backend,
                         self._backend._lib.X509_EXTENSION_get_object(ext)))
            if oid in seen_oids:
                raise x509.DuplicateExtension(
                    "Duplicate {} extension found".format(oid), oid)

            # These OIDs are only supported in OpenSSL 1.1.0+ but we want
            # to support them in all versions of OpenSSL so we decode them
            # ourselves.
            if oid == ExtensionOID.TLS_FEATURE:
                # The extension contents are a SEQUENCE OF INTEGERs.
                data = self._backend._lib.X509_EXTENSION_get_data(ext)
                data_bytes = _asn1_string_to_bytes(self._backend, data)
                features = DERReader(data_bytes).read_single_element(SEQUENCE)
                parsed = []
                while not features.is_empty():
                    parsed.append(features.read_element(INTEGER).as_integer())
                # Map the features to their enum value.
                value = x509.TLSFeature(
                    [_TLS_FEATURE_TYPE_TO_ENUM[x] for x in parsed])
                extensions.append(x509.Extension(oid, critical, value))
                seen_oids.add(oid)
                continue
            elif oid == ExtensionOID.PRECERT_POISON:
                data = self._backend._lib.X509_EXTENSION_get_data(ext)
                # The contents of the extension must be an ASN.1 NULL.
                reader = DERReader(_asn1_string_to_bytes(self._backend, data))
                reader.read_single_element(NULL).check_empty()
                extensions.append(
                    x509.Extension(oid, critical, x509.PrecertPoison()))
                seen_oids.add(oid)
                continue

            try:
                handler = self.handlers[oid]
            except KeyError:
                # Dump the DER payload into an UnrecognizedExtension object
                data = self._backend._lib.X509_EXTENSION_get_data(ext)
                self._backend.openssl_assert(data != self._backend._ffi.NULL)
                der = self._backend._ffi.buffer(data.data, data.length)[:]
                unrecognized = x509.UnrecognizedExtension(oid, der)
                extensions.append(x509.Extension(oid, critical, unrecognized))
            else:
                ext_data = self._backend._lib.X509V3_EXT_d2i(ext)
                if ext_data == self._backend._ffi.NULL:
                    self._backend._consume_errors()
                    raise ValueError(
                        "The {} extension is invalid and can't be "
                        "parsed".format(oid))

                value = handler(self._backend, ext_data)
                extensions.append(x509.Extension(oid, critical, value))

            seen_oids.add(oid)

        return x509.Extensions(extensions)
Example #2
0
  def parse(self, backend, x509_obj):
    extensions = []
    seen_oids = set()
    for i in range(self.ext_count(backend, x509_obj)):
      ext = self.get_ext(backend, x509_obj, i)
      backend.openssl_assert(ext != backend._ffi.NULL)
      crit = backend._lib.X509_EXTENSION_get_critical(ext)
      critical = crit == 1
      oid = x509.ObjectIdentifier(
        _obj2txt(backend, backend._lib.X509_EXTENSION_get_object(ext))        
      )
      if oid in seen_oids:
        raise x509.DuplicateExtension(
          "Duplicate {} extension found".format(oid), oid        
        )

      if oid == ExtensionOID.TLS_FEATURE:
        data = backend._lib.X509_EXTENSION_get_data(ext)
        data_bytes = _asn1_string_to_bytes(backend, data)
        features = DERReader(data_bytes).read_single_element(SEQUENCE)
        parsed = []
        while not features.is_empty():
          parsed.append(features.read_element(INTEGER).as_integer())

        value = x509.TLSFeature(
          [_TLS_FEATURE_TYPE_TO_ENUM[x] for x in parsed]        
        )
        extensions.append(x509.Extension(oid, critical, value))
        seen_oids.add(oid)
        continue
      elif oid == ExtensionOID.PRECERT_POSION:
        data = backend._lib.X509_EXTENSION_get_data(ext)
        reader = DERReader(_asn1_string_to_bytes(backend, data))
        reader.read_single_element(NULL).check_empty()
        extensions.append(x509.Extension(
          oid, critical, x509.PrecertPoison()    
        ))
        seen_oids.add(oid)
        continue
      elif oid == ExtensionOID.PRECERT_POISON:
        data = backend._lib.X509_EXTENSION_get_data(ext)
        reader = DERReader(_asn1_string_to_bytes(backend, data))
        reader.read_single_element(NULL).check_empty()
        extensions.append(x509.Extension(
          oid, critical, x509.PrecertPoison()    
        ))
        seen_oids.add(oid)
        continue

      try:
        handler = self.handlers[oid]
      except KeyError:
        data = backend._lib.X509_EXTENSION_get_data(ext)
        backend.openssl_assert(data != backend._ffi.NULL)
        der = backend._ffi.buffer(data.data, data.length)[:]
        unrecognized = x509.UnrecognizedExtension(oid, der)
        extensions.append(
          x509.Extension(oid, critical, unrecognized)        
        )
      else:
        ext_data = backend._lib.X509V3_EXT_d2i(ext)
        if ext_data == backend._ffi.NULL:
          backend._consume_errors()
          raise ValueError(
            "The {} extension is invalid and can't be "
            "parsed".format(oid)
          )

        value = handler(backend, ext_data)
        extensions.append(x509.Extension(oid, critical, value))

      seen_oids.add(oid)

    return x509.Extensions(extenions)