File: //proc/self/root/proc/self/root/var/opt/nydus/ops/oscrypto/_linux_bsd/trust_list.py
# coding: utf-8
from __future__ import unicode_literals, division, absolute_import, print_function
import os
from .._asn1 import Certificate, TrustedCertificate, unarmor
from .._errors import pretty_message
__all__ = [
'extract_from_system',
'system_path',
]
def system_path():
"""
Tries to find a CA certs bundle in common locations
:raises:
OSError - when no valid CA certs bundle was found on the filesystem
:return:
The full filesystem path to a CA certs bundle file
"""
ca_path = None
# Common CA cert paths
paths = [
'/usr/lib/ssl/certs/ca-certificates.crt',
'/etc/ssl/certs/ca-certificates.crt',
'/etc/ssl/certs/ca-bundle.crt',
'/etc/pki/tls/certs/ca-bundle.crt',
'/etc/ssl/ca-bundle.pem',
'/usr/local/share/certs/ca-root-nss.crt',
'/etc/ssl/cert.pem'
]
# First try SSL_CERT_FILE
if 'SSL_CERT_FILE' in os.environ:
paths.insert(0, os.environ['SSL_CERT_FILE'])
for path in paths:
if os.path.exists(path) and os.path.getsize(path) > 0:
ca_path = path
break
if not ca_path:
raise OSError(pretty_message(
'''
Unable to find a CA certs bundle in common locations - try
setting the SSL_CERT_FILE environmental variable
'''
))
return ca_path
def extract_from_system(cert_callback=None, callback_only_on_failure=False):
"""
Extracts trusted CA certs from the system CA cert bundle
:param cert_callback:
A callback that is called once for each certificate in the trust store.
It should accept two parameters: an asn1crypto.x509.Certificate object,
and a reason. The reason will be None if the certificate is being
exported, otherwise it will be a unicode string of the reason it won't.
:param callback_only_on_failure:
A boolean - if the callback should only be called when a certificate is
not exported.
:return:
A list of 3-element tuples:
- 0: a byte string of a DER-encoded certificate
- 1: a set of unicode strings that are OIDs of purposes to trust the
certificate for
- 2: a set of unicode strings that are OIDs of purposes to reject the
certificate for
"""
all_purposes = '2.5.29.37.0'
ca_path = system_path()
output = []
with open(ca_path, 'rb') as f:
for armor_type, _, cert_bytes in unarmor(f.read(), multiple=True):
# Without more info, a certificate is trusted for all purposes
if armor_type == 'CERTIFICATE':
if cert_callback:
cert_callback(Certificate.load(cert_bytes), None)
output.append((cert_bytes, set(), set()))
# The OpenSSL TRUSTED CERTIFICATE construct adds OIDs for trusted
# and rejected purposes, so we extract that info.
elif armor_type == 'TRUSTED CERTIFICATE':
cert, aux = TrustedCertificate.load(cert_bytes)
reject_all = False
trust_oids = set()
reject_oids = set()
for purpose in aux['trust']:
if purpose.dotted == all_purposes:
trust_oids = set([purpose.dotted])
break
trust_oids.add(purpose.dotted)
for purpose in aux['reject']:
if purpose.dotted == all_purposes:
reject_all = True
break
reject_oids.add(purpose.dotted)
if reject_all:
if cert_callback:
cert_callback(cert, 'explicitly distrusted')
continue
if cert_callback and not callback_only_on_failure:
cert_callback(cert, None)
output.append((cert.dump(), trust_oids, reject_oids))
return output