def load_der_x509_certificate(self, data): mem_bio = self._bytes_to_bio(data) x509 = self._lib.d2i_X509_bio(mem_bio.bio, self._ffi.NULL) if x509 == self._ffi.NULL: self._consume_errors() raise ValueError("Unable to load certificate") x509 = self._ffi.gc(x509, self._lib.X509_free) return _Certificate(self, x509)
def get_subj_alt_name(peer_cert): """ Given an PyOpenSSL certificate, provides all the subject alternative names. """ # Pass the cert to cryptography, which has much better APIs for this. if hasattr(peer_cert, "to_cryptography"): cert = peer_cert.to_cryptography() else: # This is technically using private APIs, but should work across all # relevant versions before PyOpenSSL got a proper API for this. cert = _Certificate(openssl_backend, peer_cert._x509) # We want to find the SAN extension. Ask Cryptography to locate it (it's # faster than looping in Python) try: ext = cert.extensions.get_extension_for_class( x509.SubjectAlternativeName ).value except x509.ExtensionNotFound: # No such extension, return the empty list. return [] except (x509.DuplicateExtension, UnsupportedExtension, x509.UnsupportedGeneralNameType, UnicodeError) as e: # A problem has been found with the quality of the certificate. Assume # no SAN field is present. log.warning( "A problem was encountered with the certificate that prevented " "urllib3 from finding the SubjectAlternativeName field. This can " "affect certificate validation. The error was %s", e, ) return [] # We want to return dNSName and iPAddress fields. We need to cast the IPs # back to strings because the match_hostname function wants them as # strings. # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8 # decoded. This is pretty frustrating, but that's what the standard library # does with certificates, and so we need to attempt to do the same. # We also want to skip over names which cannot be idna encoded. names = [ ('DNS', name) for name in map(_dnsname_to_stdlib, ext.get_values_for_type(x509.DNSName)) if name is not None ] names.extend( ('IP Address', str(name)) for name in ext.get_values_for_type(x509.IPAddress) ) return names
def get_subj_alt_name(peer_cert): """ Given an PyOpenSSL certificate, provides all the subject alternative names. """ # Pass the cert to cryptography, which has much better APIs for this. if hasattr(peer_cert, "to_cryptography"): cert = peer_cert.to_cryptography() else: # This is technically using private APIs, but should work across all # relevant versions before PyOpenSSL got a proper API for this. cert = _Certificate(openssl_backend, peer_cert._x509) # We want to find the SAN extension. Ask Cryptography to locate it (it's # faster than looping in Python) try: ext = cert.extensions.get_extension_for_class( x509.SubjectAlternativeName).value except x509.ExtensionNotFound: # No such extension, return the empty list. return [] except ( x509.DuplicateExtension, UnsupportedExtension, x509.UnsupportedGeneralNameType, UnicodeError, ) as e: # A problem has been found with the quality of the certificate. Assume # no SAN field is present. log.warning( "A problem was encountered with the certificate that prevented " "urllib3 from finding the SubjectAlternativeName field. This can " "affect certificate validation. The error was %s", e, ) return [] # We want to return dNSName and iPAddress fields. We need to cast the IPs # back to strings because the match_hostname function wants them as # strings. # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8 # decoded. This is pretty frustrating, but that's what the standard library # does with certificates, and so we need to attempt to do the same. # We also want to skip over names which cannot be idna encoded. names = [("DNS", name) for name in map( _dnsname_to_stdlib, ext.get_values_for_type(x509.DNSName)) if name is not None] names.extend(("IP Address", str(name)) for name in ext.get_values_for_type(x509.IPAddress)) return names
def certificates(self): sk_x509 = self._backend._lib.OCSP_resp_get0_certs(self._basic) num = self._backend._lib.sk_X509_num(sk_x509) certs = [] for i in range(num): x509 = self._backend._lib.sk_X509_value(sk_x509, i) self._backend.openssl_assert(x509 != self._backend._ffi.NULL) cert = _Certificate(self._backend, x509) # We need to keep the OCSP response that the certificate came from # alive until the Certificate object itself goes out of scope, so # we give it a private reference. cert._ocsp_resp = self certs.append(cert) return certs
def certificates(self): sk_x509 = self._backend._lib.OCSP_resp_get0_certs(self._basic) num = self._backend._lib.sk_X509_num(sk_x509) certs = [] for i in range(num): x509 = self._backend._lib.sk_X509_value(sk_x509, i) self._backend.openssl_assert(x509 != self._backend._ffi.NULL) cert = _Certificate(self._backend, x509) # We need to keep the OCSP response that the certificate came from # alive until the Certificate object itself goes out of scope, so # we give it a private reference. cert._ocsp_resp = self certs.append(cert) return certs
def get_subj_alt_name(peer_cert): """ Given an PyOpenSSL certificate, provides all the subject alternative names. """ # Pass the cert to cryptography, which has much better APIs for this. if hasattr(peer_cert, "to_cryptography"): cert = peer_cert.to_cryptography() else: # This is technically using private APIs, but should work across all # relevant versions before PyOpenSSL got a proper API for this. cert = _Certificate(openssl_backend, peer_cert._x509) # We want to find the SAN extension. Ask Cryptography to locate it (it's # faster than looping in Python) try:
def certificates(self) -> typing.List[x509.Certificate]: self._requires_successful_response() sk_x509 = self._backend._lib.OCSP_resp_get0_certs(self._basic) num = self._backend._lib.sk_X509_num(sk_x509) certs: typing.List[x509.Certificate] = [] for i in range(num): x509_ptr = self._backend._lib.sk_X509_value(sk_x509, i) self._backend.openssl_assert(x509_ptr != self._backend._ffi.NULL) cert = _Certificate(self._backend, x509_ptr) # We need to keep the OCSP response that the certificate came from # alive until the Certificate object itself goes out of scope, so # we give it a private reference. cert._ocsp_resp_ref = self certs.append(cert) return certs
def create_x509_certificate(self, builder, private_key, algorithm): if not isinstance(builder, x509.CertificateBuilder): raise TypeError('Builder type mismatch.') if not isinstance(algorithm, hashes.HashAlgorithm): raise TypeError('Algorithm must be a registered hash algorithm.') if ( isinstance(algorithm, hashes.MD5) and not isinstance(private_key, rsa.RSAPrivateKey) ): raise ValueError( "MD5 is not a supported hash algorithm for EC/DSA certificates" ) # Resolve the signature algorithm. evp_md = self._lib.EVP_get_digestbyname( algorithm.name.encode('ascii') ) self.openssl_assert(evp_md != self._ffi.NULL) # Create an empty certificate. x509_cert = self._lib.X509_new() x509_cert = self._ffi.gc(x509_cert, backend._lib.X509_free) # Set the x509 version. res = self._lib.X509_set_version(x509_cert, builder._version.value) self.openssl_assert(res == 1) # Set the subject's name. res = self._lib.X509_set_subject_name( x509_cert, _encode_name_gc(self, builder._subject_name) ) self.openssl_assert(res == 1) # Set the subject's public key. res = self._lib.X509_set_pubkey( x509_cert, builder._public_key._evp_pkey ) self.openssl_assert(res == 1) # Set the certificate serial number. serial_number = _encode_asn1_int_gc(self, builder._serial_number) res = self._lib.X509_set_serialNumber(x509_cert, serial_number) self.openssl_assert(res == 1) # Set the "not before" time. if isinstance(builder, ExtBuilder): time_str = _format_asn1_time_str(builder._not_valid_before, builder._not_valid_before_format) else: time_str = _format_asn1_time_str(builder._not_valid_before) res = self._lib.ASN1_TIME_set_string( self._lib.X509_get_notBefore(x509_cert), time_str ) if res == self._ffi.NULL: self._raise_time_set_error() # Set the "not after" time. if isinstance(builder, ExtBuilder): time_str = _format_asn1_time_str(builder._not_valid_after, builder._not_valid_after_format) else: time_str = _format_asn1_time_str(builder._not_valid_after) res = self._lib.ASN1_TIME_set_string( self._lib.X509_get_notAfter(x509_cert), time_str ) if res == self._ffi.NULL: self._raise_time_set_error() # Add extensions. self._create_x509_extensions( extensions=builder._extensions, handlers=_EXTENSION_ENCODE_HANDLERS, x509_obj=x509_cert, add_func=self._lib.X509_add_ext, gc=True ) # Set the issuer name. res = self._lib.X509_set_issuer_name( x509_cert, _encode_name_gc(self, builder._issuer_name) ) self.openssl_assert(res == 1) # Sign the certificate with the issuer's private key. res = self._lib.X509_sign( x509_cert, private_key._evp_pkey, evp_md ) if res == 0: errors = self._consume_errors() self.openssl_assert( errors[0]._lib_reason_match( self._lib.ERR_LIB_RSA, self._lib.RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY ) ) raise ValueError("Digest too big for RSA key") return _Certificate(self, x509_cert)