Beispiel #1
0
    def sign(self, key, md="sha1"):
        """Sign the current object."""
        md = md.upper()
        if key is None:
            raise errors.X509Error("Key required")

        if isinstance(key, rsa.RSAPrivateKey):
            encryption = 'RSA'
        elif isinstance(key, dsa.DSAPrivateKey):
            encryption = 'DSA'
        else:
            raise errors.X509Error("Unknown key type: %s" % (key.__class__, ))

        signature_type = SIGNING_ALGORITHMS.get((encryption, md))
        if signature_type is None:
            raise errors.X509Error(
                "Unknown encryption/hash combination %s/%s" % (encryption, md))

        algo_id = rfc2459.AlgorithmIdentifier()
        algo_id['algorithm'] = signature_type
        algo_params = ALGORITHM_PARAMETERS[signature_type]
        if algo_params is not None:
            algo_id['parameters'] = algo_params

        self._embed_signature_algorithm(algo_id)
        to_sign = self._get_bytes_to_sign()
        signer = SIGNER_CONSTRUCTION[signature_type](key)
        signer.update(to_sign)
        signature = signer.finalize()

        self._embed_signature(algo_id, signature)
Beispiel #2
0
 def __init__(self, ext=None):
     if ext is None:
         if self.spec is None:
             raise errors.X509Error("cannot create generic extension")
         self._ext = rfc5280.Extension()
         self._ext['extnID'] = self._oid
         self._set_value(self._get_default_value())
     else:
         if not isinstance(ext, rfc5280.Extension):
             raise errors.X509Error("extension has incorrect type")
         self._ext = ext
Beispiel #3
0
 def __init__(self, name_obj=None):
     self._lib = backend._lib
     self._ffi = backend._ffi
     if name_obj is not None:
         self._name_obj = self._lib.X509_NAME_dup(name_obj)
         if self._name_obj == self._ffi.NULL:
             raise errors.X509Error("Failed to copy X509_NAME "
                                    "object.")  # pragma: no cover
     else:
         self._name_obj = self._lib.X509_NAME_new()
         if self._name_obj == self._ffi.NULL:
             raise errors.X509Error("Failed to create "
                                    "X509_NAME object.")  # pragma: no cover
Beispiel #4
0
    def _get_signing_algorithm(self):
        tbs_signature = self._cert['tbsCertificate']['signature']
        cert_signature = self._cert['signatureAlgorithm']
        if tbs_signature != cert_signature:
            raise errors.X509Error("algorithms mismatch")

        return tbs_signature['algorithm']
Beispiel #5
0
    def verify(self, key=None):
        algo_id = self._get_signing_algorithm()
        if algo_id not in SIGNING_ALGORITHMS_INV:
            LOG.warning("Signature algorithm %s is unknown, cannot verify",
                        algo_id)
            return False

        if key is None:
            key = self._get_public_key()

        encryption, hash_algo = SIGNING_ALGORITHMS_INV[algo_id]
        to_sign = self._get_bytes_to_sign()
        signature = self._get_signature()
        if ((encryption == 'RSA' and not isinstance(key, rsa.RSAPublicKey)) or
            (encryption == 'DSA' and not isinstance(key, dsa.DSAPublicKey))):
            raise errors.X509Error("Key type mismatch: object %s, key %s" %
                                   (encryption, key.__class__))
        verifier = VERIFIER_CONSTRUCTION[algo_id](key, signature)

        verifier.update(to_sign)
        try:
            verifier.verify()
            return True
        except cio_exceptions.InvalidSignature:
            return False
Beispiel #6
0
    def add_extension(self, new_ext):
        """Add a new extension or replace existing one."""
        if not isinstance(new_ext, extension.X509Extension):
            raise errors.X509Error("ext is not an anchor X509Extension")
        attributes = self.get_attributes()
        ext_attrs = [a for a in attributes
                     if a['attrType'] == OID_extensionRequest]
        if not ext_attrs:
            new_attr_index = len(attributes)
            attributes[new_attr_index] = None
            ext_attr = attributes[new_attr_index]
            ext_attr['attrType'] = OID_extensionRequest
            ext_attr['attrValues'] = None
            exts = rfc5280.Extensions()
        else:
            ext_attr = ext_attrs[0]
            exts = decoder.decode(ext_attr['attrValues'][0].asOctets(),
                                  asn1Spec=rfc5280.Extensions())[0]

        # the end is the default position
        new_ext_index = len(exts)
        # unless there's an existing extension with the same OID
        for i, ext_i in enumerate(exts):
            if ext_i['extnID'] == new_ext.get_oid():
                new_ext_index = i
                break

        exts[new_ext_index] = new_ext._ext

        ext_attr['attrValues'][0] = encoder.encode(exts)
Beispiel #7
0
 def add_ip(self, ip, ext_value=None):
     if not isinstance(ip, netaddr.IPAddress):
         raise errors.X509Error("not a real ip address provided")
     new_pos = len(ext_value)
     ext_value[new_pos] = None
     ext_value[new_pos]['iPAddress'] = utils.netaddr_to_asn1(ip)
     return ext_value
Beispiel #8
0
 def add_name_entry(self, oid, text):
     if not isinstance(oid, asn1_univ.ObjectIdentifier):
         raise errors.X509Error("oid '%s' is not valid" % (oid, ))
     entry = rfc2459.RelativeDistinguishedName()
     entry[0] = rfc2459.AttributeTypeAndValue()
     entry[0]['type'] = oid
     name_type = name_oids[oid]
     try:
         if name_type in (rfc2459.X520countryName, rfc2459.Pkcs9email):
             val = name_type(text)
         else:
             val = name_type()
             val['utf8String'] = text
     except asn1_error.ValueConstraintError:
         raise errors.X509Error("Name '%s' is not valid" % text)
     entry[0]['value'] = rfc2459.AttributeValue(encoder.encode(val))
     self._name_obj[len(self)] = entry
Beispiel #9
0
    def __str__(self):
        # NOTE(tkelsey): we need to pass in a max size, so why not 1024
        val = self._lib.X509_NAME_oneline(self._name_obj, self._ffi.NULL, 1024)
        if val == self._ffi.NULL:
            raise errors.X509Error("Could not convert"
                                   " X509_NAME to string.")  # pragma: no cover

        val = self._ffi.gc(val, self._lib.OPENSSL_free)
        return self._ffi.string(val).decode('ascii')
Beispiel #10
0
    def add_name_entry(self, nid, text):
        """Add a name entry by its NID name."""
        ret = self._lib.X509_NAME_add_entry_by_NID(self._name_obj, nid,
                                                   self._lib.MBSTRING_UTF8,
                                                   text.encode('utf8'), -1, -1,
                                                   0)

        if ret != 1:
            raise errors.X509Error("Failed to add name entry: '%s' '%s'" %
                                   (nid, text))
Beispiel #11
0
 def add_dns_id(self, dns_id, validate=True, ext_value=None):
     if validate:
         try:
             a_utils.verify_domain(dns_id, allow_wildcards=True)
         except ValueError as e:
             raise errors.X509Error("invalid domain provided: %s" % str(e))
     new_pos = len(ext_value)
     ext_value[new_pos] = None
     ext_value[new_pos]['dNSName'] = dns_id
     return ext_value
Beispiel #12
0
    def add_extension(self, ext, index):
        """Add an X509 V3 Certificate extension.

        :param ext: An X509Extension instance
        :param index: The index of the extension
        """
        if not isinstance(ext, extension.X509Extension):
            raise errors.X509Error("ext needs to be a pyasn1 extension")

        extensions = self._get_extensions()
        extensions[index] = ext.as_asn1()
Beispiel #13
0
        def get_name(self):
            """Get the name of this entry.

            :return: entry name as a python string
            """
            asn1_obj = self._lib.X509_NAME_ENTRY_get_object(self._entry)
            buf = self._ffi.new('char[]', 1024)
            ret = self._lib.OBJ_obj2txt(buf, 1024, asn1_obj, 0)
            if ret == 0:
                raise errors.X509Error("Could not convert ASN1_OBJECT to "
                                       "string.")  # pragma: no cover
            return self._ffi.string(buf).decode('ascii')
Beispiel #14
0
def construct_extension(ext):
    """Construct an extension object of the right type.

    While X509Extension can provide basic access to the extension elements,
    it cannot parse details of extensions. This function detects which type
    should be used based on the extension id.
    If the type is unknown, generic X509Extension is used instead.
    """
    if not isinstance(ext, rfc5280.Extension):
        raise errors.X509Error("extension has incorrect type")
    ext_class = EXTENSION_CLASSES.get(ext['extnID'], X509Extension)
    return ext_class(ext)
Beispiel #15
0
    def get_fingerprint(self, md='sha256'):
        """Get the fingerprint of this X509 certificate.

        :param md: The message digest algorthim used to compute the fingerprint
        :return: The fingerprint encoded as a hex string
        """
        hash_class = utils.get_hash_class(md)
        if hash_class is None:
            raise errors.X509Error("Unknown hash %s" % (md, ))
        hasher = hashes.Hash(hash_class(),
                             backend=cio_backends.default_backend())
        hasher.update(self.as_der())
        return binascii.hexlify(hasher.finalize()).upper().decode('ascii')
Beispiel #16
0
    def sign(self, encryption, md, signer):
        """Sign the current object."""
        md = md.upper()

        signature_type = SIGNING_ALGORITHMS.get((encryption, md))
        if signature_type is None:
            raise errors.X509Error(
                "Unknown encryption/hash combination %s/%s" % (encryption, md))

        algo_id = rfc5280.AlgorithmIdentifier()
        algo_id['algorithm'] = signature_type
        algo_params = ALGORITHM_PARAMETERS[signature_type]
        if algo_params is not None:
            algo_id['parameters'] = algo_params

        self._embed_signature_algorithm(algo_id)
        to_sign = self._get_bytes_to_sign()
        signature = signer(to_sign)

        self._embed_signature(algo_id, signature)
Beispiel #17
0
    def add_extension(self, ext):
        if not isinstance(ext, extension.X509Extension):
            raise errors.X509Error("ext is not an anchor X509Extension")
        attributes = self.get_attributes()
        ext_attrs = [
            a for a in attributes if a['type'] == OID_extensionRequest
        ]
        if not ext_attrs:
            new_attr_index = len(attributes)
            attributes[new_attr_index] = None
            ext_attr = attributes[new_attr_index]
            ext_attr['type'] = OID_extensionRequest
            ext_attr['vals'] = None
            exts = rfc2459.Extensions()
        else:
            ext_attr = ext_attrs[0]
            exts = decoder.decode(ext_attr['vals'][0].asOctets(),
                                  asn1Spec=rfc2459.Extensions())[0]

        new_ext_index = len(exts)
        exts[new_ext_index] = ext._ext

        ext_attr['vals'][0] = encoder.encode(exts)
Beispiel #18
0
 def _set_value(self, value):
     if not isinstance(value, self.spec):
         raise errors.X509Error("extension value has incorrect type")
     self._ext['extnValue'] = encoder.encode(value)
Beispiel #19
0
def netaddr_to_asn1(ip):
    """Translate the netaddr object to ASN1 IP format."""
    if not isinstance(ip, netaddr.IPAddress):
        raise errors.X509Error("not a real ip address provided")

    return bytes(ip.packed)