Example #1
0
    def __load_cert(self):
        """Recovery the website certificate and its public key"""
        conn = ssl.create_connection((self.hostname, self.port_number))
        context = ssl.SSLContext(ssl.PROTOCOL_TLS)
        sock = context.wrap_socket(conn, server_hostname=self.hostname)

        self.pem_data = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True))
        self.certOpenSSL = crypto.load_certificate(crypto.FILETYPE_PEM, self.pem_data)
        
        self.certificate = self.certOpenSSL.to_cryptography()

        self.pubKey = self.certificate.public_key()
Example #2
0
def x5c_to_pems(x5c):
    """
    Takes a x5c value from a JWK and converts it into a list of PEM formated certificates.

    :param x5c: List of strings
    :return:
    """

    return [
        ssl.DER_cert_to_PEM_cert(d)
        for d in [base64.b64decode(x) for x in [as_bytes(y) for y in x5c]]
    ]
Example #3
0
    def handleEvent(self, event):
        eventName = event.eventType
        srcModuleName = event.module
        eventData = event.data

        self.sf.debug("Received event, " + eventName + ", from " +
                      srcModuleName)

        if eventName == "LINKED_URL_INTERNAL":
            fqdn = self.sf.urlFQDN(eventData.lower())
        else:
            fqdn = eventData

        if fqdn not in self.results:
            self.results[fqdn] = True
        else:
            return None

        if not eventData.lower().startswith(
                "https://") and not self.opts['tryhttp']:
            return None

        self.sf.debug("Testing SSL for: " + eventData)
        # Re-fetch the certificate from the site and process
        try:
            s = socket.socket()
            s.settimeout(int(self.opts['ssltimeout']))
            s.connect((fqdn, 443))
            sock = ssl.wrap_socket(s)
            sock.do_handshake()
            rawcert = sock.getpeercert(True)
            cert = ssl.DER_cert_to_PEM_cert(rawcert)
            m2cert = M2Crypto.X509.load_cert_string(
                str(cert).replace('\r', ''))
        except BaseException as x:
            self.sf.info("Unable to SSL-connect to " + fqdn)
            return None

        # Generate the event for the raw cert (in text form)
        # Cert raw data text contains a lot of gems..
        rawevt = SpiderFootEvent("SSL_CERTIFICATE_RAW",
                                 m2cert.as_text().encode('raw_unicode_escape'),
                                 self.__name__, event)
        self.notifyListeners(rawevt)

        # Generate events for other cert aspects
        self.getIssued(m2cert, event)
        self.getIssuer(m2cert, event)
        self.checkHostMatch(m2cert, fqdn, event)
        try:
            self.checkExpiry(m2cert, event)
        except M2Crypto.X509.X509Error as e:
            self.sf.error("Error processing certificate: " + str(e), False)
Example #4
0
    def _dump_ssl_info(self, cert, cert_der, cipher):
        '''Dump X509 certificate.'''

        res = '\n== Certificate information ==\n'
        res += pformat(cert)
        res += '\n\n== Used cipher ==\n' + pformat(cipher)
        res += '\n\n== Certificate dump ==\n' + \
            ssl.DER_cert_to_PEM_cert(cert_der)
        # Indent
        res = res.replace('\n', '\n    ')
        res = '    ' + res
        return res
Example #5
0
def pair_client(clientsocket, q):
    print "wants to pair"
    mycert = open(os.path.join(configmanager.keydir, "server.crt"), "r").read()
    secure_port = str(configmanager.secure_port)

    myder_cert = ssl.PEM_cert_to_DER_cert(mycert)
    m = hashlib.sha256(myder_cert)
    myfp = m.hexdigest().upper()
    myfp = " ".join(myfp[i:i + 4] for i in range(0, len(myfp), 4))
    print "\nMy SHA256: " + myfp
    #send my certiuficate
    clientsocket.sendall(myder_cert.encode('base64'))

    #receive client Certificate
    clientcert = clientsocket.recv(2048)

    m = hashlib.sha256(clientcert)
    devicefp = m.hexdigest().upper()
    devicefp = " ".join(devicefp[i:i + 4] for i in range(0, len(devicefp), 4))
    print "\nClient SHA256: " + devicefp

    if (q):  #GUI
        q.put([myfp, devicefp])
        vout = q.get(True)
    else:  #CMDLine only
        vout = raw_input("Do they match?(yes/no)\n")

    if (vout.strip().lower() == "yes"):
        clientsocket.sendall(secure_port + "\n")
    else:
        clientsocket.sendall("0\n")
        pass

    print "wait for Device..."
    ack = clientsocket.recv(2)

    if (ack == "OK"):
        #save pub key
        with open(os.path.join(configmanager.keydir, "cas.pem"),
                  'a') as the_file:
            the_file.write(ssl.DER_cert_to_PEM_cert(clientcert))

        if (q):
            q.put(1)

        restart_server()
        print "Successfully paired the Device!"

    else:
        if (q):
            q.put(0)
        print "Failed to pair Device."
Example #6
0
    def start_tcp(self):

        self.connection_msg = self.host + ':%d' % self.port

        if self.proxy is not None:

            socks.setdefaultproxy(self.proxy_mode, self.proxy["host"],
                                  int(self.proxy["port"]))
            socket.socket = socks.socksocket

            # prevent dns leaks, see http://stackoverflow.com/questions/13184205/dns-over-proxy
            def getaddrinfo(*args):
                return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (args[0],
                                                                     args[1]))]

            socket.getaddrinfo = getaddrinfo

        if self.use_ssl:
            cert_path = os.path.join(self.config.path, 'certs', self.host)

            if not os.path.exists(cert_path):
                is_new = True
                # get server certificate.
                # Do not use ssl.get_server_certificate because it does not work with proxy
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                try:
                    s.connect((self.host, self.port))
                except:
                    # print_error("failed to connect", self.host, self.port)
                    return

                try:
                    s = ssl.wrap_socket(s,
                                        ssl_version=ssl.PROTOCOL_SSLv3,
                                        cert_reqs=ssl.CERT_NONE,
                                        ca_certs=None)
                except ssl.SSLError, e:
                    print_error("SSL error:", self.host, e)
                    return
                dercert = s.getpeercert(True)
                s.close()
                cert = ssl.DER_cert_to_PEM_cert(dercert)
                # workaround android bug
                cert = re.sub("([^\n])-----END CERTIFICATE-----",
                              "\\1\n-----END CERTIFICATE-----", cert)
                temporary_path = cert_path + '.temp'
                with open(temporary_path, "w") as f:
                    f.write(cert)

            else:
                is_new = False
Example #7
0
def test_crl_distribution_list(website_addr,
                               crl_distribution_list,
                               HTTPS_PORT=443,
                               crl_failure_is_invalid=False):
    '''
    There can be multiple crls for a cert
    we should check at least one that works
    if one fails move on to the next if none work
    we return True or False based on value of
    crl_distribution_list
    '''
    hostname = extract_hostname(website_addr)
    CRL_DISTRIBUTION_SUCCESS = False

    for crl_distribution in crl_distribution_list:
        try:
            raw_crl = urllib.request.urlopen(crl_distribution, timeout=5)
            if raw_crl.status != 200:
                raise
            else:
                with open('.crl_file.pem', 'w') as crl_file:
                    crl_file.write(
                        ssl.DER_cert_to_PEM_cert(raw_crl.read()).replace(
                            'CERTIFICATE', 'X509 CRL'))
                    CRL_DISTRIBUTION_SUCCESS = True
                break
        except Exception:
            logging.Warning(
                f'issue with {crl_distribution} trying next distribution')
    if not CRL_DISTRIBUTION_SUCCESS and crl_failure_is_invalid:
        return False
    ssl_context = ssl.create_default_context()
    ssl_context.load_verify_locations(cafile='.crl_file.pem')
    os.remove('.crl_file.pem')
    '''
    VERIFY_CRL_CHECK_LEAF means we only check the first CRL
    We dont go all the way down the chain and check the CRL
    on each link. Its slow enough with just the leaf. 
    '''
    ssl_context.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF
    sock = ssl_context.wrap_socket(socket.socket(),
                                   server_hostname=hostname,
                                   do_handshake_on_connect=False)
    sock.connect((hostname, HTTPS_PORT))
    try:
        sock.do_handshake()
    except ssl.SSLError:
        return False
    except ssl.CertificateError:
        return False
    return True
Example #8
0
def main():
    log('Type hostname to scan that hostname (example: goo.gl fb.me etc)')
    log('Type exit to exit\n')

    host = str('74.125.24.100')
    port = int('443')

    while True:
        server_name_indications = re.sub(r'\s+', ' ',
                                         str(input(':: '))).split(' ')
        print()

        if len(server_name_indications) == 1 and app.xstrip(
                server_name_indications[0]) == '':
            continue

        if len(server_name_indications) == 1 and app.xstrip(
                server_name_indications[0]) == 'exit':
            break

        for i in range(len(server_name_indications)):
            try:
                server_name_indication = app.xstrip(server_name_indications[i])
                if not server_name_indication: continue
                socket_tunnel = socket.socket(socket.AF_INET,
                                              socket.SOCK_STREAM)
                socket_tunnel.settimeout(3)
                log('Connecting to {host} port {port}'.format(host=host,
                                                              port=port))
                socket_tunnel.connect((host, port))
                log('Server name indication: {server_hostname}'.format(
                    server_hostname=server_name_indication))
                socket_tunnel = ssl.SSLContext(
                    ssl.PROTOCOL_TLSv1_2).wrap_socket(
                        socket_tunnel,
                        server_hostname=server_name_indication,
                        do_handshake_on_connect=True)
                certificate = ssl.DER_cert_to_PEM_cert(
                    socket_tunnel.getpeercert(True)).splitlines()
                certificate = '\n'.join(certificate[:13] + certificate[-13:])
                log('Certificate: \n\n{}\n'.format(certificate))
                log('Connection established')
                log('[Y1]Connected', status_color='[Y1]')
            except socket.timeout:
                log('[R1]Connection timeout', status_color='[R1]')
            except socket.error:
                log('[R1]Connection closed', status_color='[R1]')
            finally:
                socket_tunnel.close()
                print()
Example #9
0
 def stream_state_changed(self, state, arg):
     """This one is called when the state of stream connecting the component
     to a server changes. This will usually be used to let the user
     know what is going on."""
     if state == 'fully connected':
         self.disconnect()
     if state != 'tls connected':
         return
     cert = self.stream.tls.getpeercert(True)
     pem_cert = ssl.DER_cert_to_PEM_cert(cert).strip()
     if pem_cert[-len(ssl.PEM_FOOTER) - 1:len(ssl.PEM_FOOTER)] != '\n':
         # Python 2.6.4 but workaround
         pem_cert = pem_cert[:-len(ssl.PEM_FOOTER)] + "\n" + ssl.PEM_FOOTER
     print pem_cert
Example #10
0
def is_cert_cn_not_equal_to_site(site: str, port: int = PORT) -> bool:
    """
    Check if certificate Common Name (CN) is different from given sitename.

    Name in certificate should be coherent with organization name, see
    `REQ. 093 <https://fluidattacks.com/web/rules/093/>`_

    :param site: Site address.
    :param port: Port to connect to.
    """
    result = True
    try:
        with connect(site, port=port) as conn:
            __cert = conn.session.serverCertChain.x509List[0].bytes
            cert = ssl.DER_cert_to_PEM_cert(__cert)
    except socket.error:
        show_unknown('Port closed', details=dict(site=site, port=port))
        return False
    except tlslite.errors.TLSRemoteAlert as exc:
        show_unknown('Could not connect',
                     details=dict(site=site,
                                  port=port,
                                  error=str(exc).replace(':', ',')))
        return False
    except (tlslite.errors.TLSLocalAlert):
        show_unknown('Port doesn\'t support SSL',
                     details=dict(site=site, port=port))
        return False
    cert_obj = load_pem_x509_certificate(cert.encode('utf-8'),
                                         default_backend())
    cert_cn = \
        cert_obj.subject.get_attributes_for_oid(NameOID.COMMON_NAME)[
            0].value.lower()

    wc_cert = '*.' + site.lower()

    domain = 'NONE'
    if cert_cn.startswith('*.'):
        domain = '.' + cert_cn.split('*.')[1].lower()

    if (site.lower() != cert_cn and wc_cert != cert_cn
            and not site.endswith(domain)):
        show_open('{} CN not equals to site'.format(cert_cn),
                  details=dict(site=site, port=port, cn=cert_cn))
        result = True
    else:
        show_close('{} CN equals to site'.format(cert_cn),
                   details=dict(site=site, port=port, cn=cert_cn))
        result = False
    return result
Example #11
0
 def ssl_coro():
     try:
         transp, prot = yield from ssl_connect_routine
     except ssl.SSLError as e:
         log.debug('SSL: Unable to connect', exc_info=True)
         log.error('CERT: Invalid certificate trust chain.')
         if not self.event_handled('ssl_invalid_chain'):
             self.disconnect()
         else:
             self.event('ssl_invalid_chain', e)
     else:
         der_cert = transp.get_extra_info("socket").getpeercert(True)
         pem_cert = ssl.DER_cert_to_PEM_cert(der_cert)
         self.event('ssl_cert', pem_cert)
Example #12
0
def ssl_verify():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    wrappedSocket = ssl.wrap_socket(
        sock,
        cert_reqs=ssl.CERT_REQUIRED,
        ca_certs='/etc/ssl/certs/ca-certificates.crt')
    try:
        wrappedSocket.connect((sys.argv[1], 443))
    except:
        response = False
    else:
        pem_cert = ssl.DER_cert_to_PEM_cert(wrappedSocket.getpeercert(True))
    wrappedSocket.close()
    print '-----------------ssl--------------------'
Example #13
0
    def _process_input(self, address):
        '''Processing address'''
        result = {
            'address': address,
            'cert_pem': None,
            'cert_data': None,
            'not_after': None,
            'errors': [],
        }

        try:
            # Canary request the server certificate in PEM and ensure host is ok
            # TODO: that will be better to decode the cert and show info for the user
            # but looks like it's hard without the additional (not-builtin) modules
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            ssl_sock = self._ctx_canary.wrap_socket(sock,
                                                    server_hostname=address[0])
            ssl_sock.connect(address)
            # Getting only PEM, because data requires validation of the cert
            result['cert_pem'] = ssl.DER_cert_to_PEM_cert(
                ssl_sock.getpeercert(True))
            ssl_sock.close()

            # Connect using socket to validate cert and get parsed cert
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            ssl_sock = self._ctx.wrap_socket(sock, server_hostname=address[0])
            try:
                ssl_sock.connect(address)
                result['cert_data'] = ssl_sock.getpeercert()
                result['not_after'] = datetime.strptime(
                    result['cert_data']['notAfter'], self._dtformat)
            except ssl.SSLError as e:
                # In case the certificate is invalid
                if self._cfg.verbose:
                    eprint('DEBUG: SSL error for address', address, e)
                result['errors'].append(e)
            finally:
                ssl_sock.close()
        except IOError as e:
            # Catch timeout or dns resolution error
            if self._cfg.verbose:
                eprint('DEBUG: Connection issue to', address, e)
            result['errors'].append(e)
        except Exception as e:
            if self._cfg.verbose:
                eprint('DEBUG: Unknown exception during connection', address,
                       e)
            result['errors'].append(e)

        return result
Example #14
0
    def validatecertificatesignature(self, signed_cert, signing_cert):
        """Given a cert signed by another cert, validates the signature."""
        # First the naive way -- note this does not check expiry / use etc.

        cert_signing = x509.load_pem_x509_certificate(
            ssl.DER_cert_to_PEM_cert(
                der_encoder.encode(signing_cert)).encode(), default_backend())

        public_key = cert_signing.public_key()

        der_cert = der_encoder.encode(signed_cert)
        cert_signed = x509.load_pem_x509_certificate(
            ssl.DER_cert_to_PEM_cert(der_cert).encode(), default_backend())

        data = cert_signed.tbs_certificate_bytes
        signature = cert_signed.signature

        new_api = hasattr(public_key, "verify")
        if not new_api:
            verifier = public_key.verifier(
                signature, padding.PKCS1v15(),
                cert_signed.signature_hash_algorithm)
            try:
                verifier.update(data)
                verifier.verify()
            except:
                raise Asn1Error('1: Validation of cert signature failed.')
        else:
            try:
                verifier = public_key.verify(
                    signature, data, padding.PKCS1v15(),
                    cert_signed.signature_hash_algorithm)
                # verifier.update(data)
                # verifier.verify()
            except:
                raise Asn1Error('1: Validation of cert signature failed.')
def authSession(connection, code):
    cert = str(
        ssl.DER_cert_to_PEM_cert(
            connection.handler.socket.getpeercert(True))).rstrip()

    #Some machines already have the \n.. I can't even...wha??
    if '\n-----END CERTIFICATE-----' not in cert:
        cert = cert.replace('-----END CERTIFICATE-----',
                            '\n-----END CERTIFICATE-----')

    signature = hmac.new(code, cert, hashlib.sha1).hexdigest()
    authCommand = "SESSION|AUTH|%s|END" % signature

    print "SENDING:", authCommand
    connection.handler.push(authCommand)
Example #16
0
    def verify(self, der_cert):
        pem_cert = ssl.DER_cert_to_PEM_cert(der_cert)
        pk = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                             pem_cert).get_pubkey()
        pk_str = OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM, pk)

        # pk_str will look like
        # b'-----BEGIN PUBLIC KEY-----\n
        #   MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEWa0bWGpCinC/A7QIh/nF8dTlyL/r\nrmv4mYE8PJu3M8rsmZPzjSburX/I9wRL9rQGqotM9M0nJkjv3pkAVyptuA==\n
        #   -----END PUBLIC KEY-----\n'
        pk_str_base64 = b''.join(pk_str.splitlines()[1:-1])
        pk_bytes = base64.b64decode(pk_str_base64)
        if self.public_key != pk_bytes:
            raise SiipCertError(
                f'Invalid SIIP Certificate {self._pk_str(pk_bytes)}')
Example #17
0
def get_server_certificate(addr,
                           ssl_version=ssl.PROTOCOL_SSLv3,
                           ca_certs=None):
    if (ca_certs is not None):
        cert_reqs = CERT_REQUIRED
    else:
        cert_reqs = CERT_NONE
    s = wrap_socket(gsock.Socket(),
                    ssl_version=ssl_version,
                    cert_reqs=cert_reqs,
                    ca_certs=ca_certs)
    s.connect(addr)
    dercert = s.getpeercert(True)
    s.close()
    return ssl.DER_cert_to_PEM_cert(dercert)
Example #18
0
    def test_wincertstore(self):
        store = wincertstore.CertSystemStore("ROOT")
        try:
            for cert in store.itercerts():
                pem = cert.get_pem()
                enc = cert.get_encoded()
                name = cert.get_name()
                trust = cert.enhanced_keyusage_names()
                self.assertEqual(ssl.DER_cert_to_PEM_cert(enc), pem)
                self.assertEqual(ssl.PEM_cert_to_DER_cert(pem), enc)

            for crl in store.itercrls():
                pem = cert.get_pem()
        finally:
            store.close()
def certificate_expiry(hostname):
    context = ssl.create_default_context()

    try:
        with socket.create_connection((hostname, 443)) as sock:
            with context.wrap_socket(sock,
                                     server_hostname=hostname) as sslsock:
                der_cert = sslsock.getpeercert(True)
                pem_cert = ssl.DER_cert_to_PEM_cert(der_cert)
                x509_cert = OpenSSL.crypto.load_certificate(
                    OpenSSL.crypto.FILETYPE_PEM, pem_cert)
                notAfter_str = x509_cert.get_notAfter().decode('UTF-8')
                return datetime.datetime.strptime(notAfter_str, cert_date_fmt)
    except (OSError, ssl.CertificateError):
        return None
Example #20
0
def is_cert_inactive(site: str, port: int = PORT) -> bool:
    """
    Check if certificate is no longer valid.

    Fails if end of validity date obtained from certificate
    is beyond the time of execution.

    :param site: Site address.
    :param port: Port to connect to.
    """
    result = True
    try:
        with connect(site, port=port) as conn:
            __cert = conn.session.serverCertChain.x509List[0].bytes
            cert = ssl.DER_cert_to_PEM_cert(__cert)
    except socket.error:
        show_unknown('Port closed', details=dict(site=site, port=port))
        return False
    except tlslite.errors.TLSRemoteAlert as exc:
        show_unknown('Could not connect',
                     details=dict(site=site,
                                  port=port,
                                  error=str(exc).replace(':', ',')))
        return False
    except (tlslite.errors.TLSLocalAlert):
        show_unknown('Port doesn\'t support SSL',
                     details=dict(site=site, port=port))
        return False
    cert_obj = load_pem_x509_certificate(cert.encode('utf-8'),
                                         default_backend())

    if cert_obj.not_valid_after > datetime.datetime.now():
        show_close('Certificate is still valid',
                   details=dict(
                       site=site,
                       port=port,
                       not_valid_after=cert_obj.not_valid_after.isoformat(),
                       current_time=datetime.datetime.now().isoformat()))
        result = False
    else:
        show_open('Certificate is expired',
                  details=dict(
                      site=site,
                      port=port,
                      not_valid_after=cert_obj.not_valid_after.isoformat(),
                      current_time=datetime.datetime.now().isoformat()))
        result = True
    return result
Example #21
0
def cert_lookup(hostname):
    port = 443

    context = ssl.create_default_context()
    # Used for SNI
    with socket.create_connection((hostname, port)) as sock:
        with context.wrap_socket(sock, server_hostname=hostname) as sslsock:
            der_cert = sslsock.getpeercert(True)
            cert = ssl.DER_cert_to_PEM_cert(der_cert)
            x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
            x509info = x509.get_notAfter()
            ssl_date_fmt = r'%Y%m%d%H%M%SZ'
            expires = datetime.datetime.strptime(str(x509info)[2:-1], ssl_date_fmt)
            remaining = (expires - datetime.datetime.utcnow()).days
            reply = "{} expires in {} days, ({})".format(hostname, remaining, expires)
            return reply
Example #22
0
def get_thumbprint(ip):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(1)
    wrappedSocket = ssl.wrap_socket(sock)

    try:
        wrappedSocket.connect((ip, 443))
    except:
        response = False
    else:
        der_cert_bin = wrappedSocket.getpeercert(True)
        pem_cert = ssl.DER_cert_to_PEM_cert(wrappedSocket.getpeercert(True))
        # Thumbprint
        thumb_sha256 = hashlib.sha256(der_cert_bin).hexdigest()
        wrappedSocket.close()
        return ':'.join(map(''.join, zip(*[iter(thumb_sha256)] * 2)))
Example #23
0
def servercert_get(logger, hostname, port=443):
    """ get server certificate from an ssl connection """
    logger.debug('servercert_get({0}:{1})'.format(hostname, port))

    pem_cert = None
    context = ssl.create_default_context()
    # disable cert validation
    context.check_hostname = False
    context.verify_mode = ssl.CERT_NONE
    with socket.create_connection((hostname, port)) as sock:
        with context.wrap_socket(sock, server_hostname=hostname) as sslsock:
            der_cert = sslsock.getpeercert(True)
            # from binary DER format to PEM
            pem_cert = ssl.DER_cert_to_PEM_cert(der_cert)

    return pem_cert
    def fetch_certificate(domain):
        try:
            # Get the certificate
            context = ssl._create_unverified_context()
            sock = socket.socket(socket.AF_INET)
            sock.settimeout(5)
            conn = context.wrap_socket(sock, server_hostname=domain)
            conn.connect((domain, 443))
            der_cert = conn.getpeercert(True)

            # Convert the certificate from DER to PEM
            raw_data = str(ssl.DER_cert_to_PEM_cert(der_cert))
        except Exception as e:
            raw_data = None

        return raw_data
Example #25
0
def certfetch_into_cache(sitename, force=False):
    " expects either 'hostname' or 'hostname:portnum' "
    global CACHEDIR
    if os.path.sep in sitename:
        raise TypeError("bad hostname \"{}\"".format(sitename))
    if ':' in sitename:
        hostname, port = sitename.split(':', 1)
        port = int(port)
    else:
        hostname, port = sitename, 443
    certname = CACHEDIR + os.path.sep + sitename + '.pem'
    certname = certname.replace(':', '.')
    tmpname = certname + ".tmp"
    cert = None
    try:
        # cert = ssl.get_server_certificate((hostname, port))   # doesn't do SNI
        context = ssl.create_default_context()
        context.verify_mode = ssl.CERT_REQUIRED
        context.check_hostname = False
        conn = context.wrap_socket(socket.socket(socket.AF_INET),
                                   server_hostname=hostname)
        conn.connect((hostname, port))
        cert = conn.getpeercert(binary_form=True)
        # cert is a DER-encoded blob
        cert = ssl.DER_cert_to_PEM_cert(cert)
        # cert is now a PEM-encoded ascii string
    except Exception as err:
        print("* {} failed: {}".format(sitename, err), file=sys.stderr)
    if not cert:
        # try the method that doesn't do SNI
        try:
            cert = ssl.get_server_certificate(
                (hostname, port))  # doesn't do SNI
        except Exception as err:
            print("* {} failed: {}".format(sitename, err), file=sys.stderr)
    if cert:
        with open(tmpname, 'wb') as tmpfile:
            tmpfile.write(bytes(cert, 'ascii'))
        if force or (not os.path.exists(certname)):
            bark("... " + site + " updated")
            os.rename(tmpname, certname)
        elif filecmp.cmp(certname, tmpname):
            os.remove(tmpname)
        else:
            bark("... " + site + " updated")
            os.rename(tmpname, certname)
    return cert
Example #26
0
    def validate_certificate_chain(self, der_certs):
        """
        Validate a given certificate chain which should be full,
        as a list of DER (binary) certificates from leaf to root
        (in this order and including both),
        raising an ``ssl.SSLError`` when the chain isn't valid.

        This method requires OpenSSL,
        which should be available from the command line.
        """
        with ExitStack() as stack:

            def new_pem_file(data):
                pf = stack.enter_context(
                    NamedTemporaryFile("wb", suffix=".pem"), )
                pf.write(data.encode("ascii"))
                pf.flush()
                return pf

            pem_certs = [ssl.DER_cert_to_PEM_cert(dc) for dc in der_certs]
            target_pem = new_pem_file(pem_certs[0])
            intermediary_pem = new_pem_file("".join(pem_certs[1:-1]))
            root_pem = new_pem_file(pem_certs[-1])

            command_line = [
                "openssl",
                "verify",
                "-CAfile",
                root_pem.name,
                "-untrusted",
                intermediary_pem.name,
                target_pem.name,
            ]
            openssl_proc = Popen(command_line, stdout=PIPE, stderr=PIPE)
            openssl_proc.wait()

            # Logs the OpenSSL results
            logger.debug("OpenSSL certificate chain validation results:")
            for stream_name in ["stdout", "stderr"]:
                msg = getattr(openssl_proc, stream_name).read()
                if msg.strip():
                    for line in msg.decode("ascii").splitlines():
                        logger.debug(f"[{stream_name}] {line}")
            logger.debug(f"[return code] {openssl_proc.returncode}")

            if openssl_proc.returncode != 0:
                raise ssl.SSLError("Certificate chain verification failed")
Example #27
0
        def checkCertificate(_):
            domain = re.match(r"https:\/\/(.*)\/", _.TARGET).group(1)
            query = (domain, 443)

            try:
                # SNI traceable here
                connection = ssl.create_connection(query)
                context = ssl.SSLContext(ssl.PROTOCOL_TLS)
                sock = context.wrap_socket(connection, server_hostname=domain)
                certificate = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True))
            except:
                e = sys.exc_info()[0]
                certificate = ssl.get_server_certificate(query)
            x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
                                                   certificate)
            _.NOT_AFTER = datetime.strptime(x509.get_notAfter().decode(),
                                            "%Y%m%d%H%M%SZ")
def get_certificate(endpoint: str, port: str) -> str:
    """Download certificate from remote server.

    Args:
        endpoint: url to get certificate from.
        port: endpoint port.

    Returns:
        str: certificate string in PEM format.
    """
    hostname = endpoint
    conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
    sock = context.wrap_socket(conn, server_hostname=hostname)
    sock.connect((hostname, int(port)))

    return ssl.DER_cert_to_PEM_cert(sock.getpeercert(True))  # type: ignore
Example #29
0
def get_thumb(module):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(10)
    wrappedSocket = ssl.wrap_socket(sock)
    try:
      wrappedSocket.connect((module.params['server'], 443))
    except:
      module.fail_json(msg='Connection error while fatching thumbprint for server [%s].' % module.params['server'])
    else:
      der_cert_bin = wrappedSocket.getpeercert(True)
      pem_cert = ssl.DER_cert_to_PEM_cert(wrappedSocket.getpeercert(True))
      print(pem_cert)

      #Thumbprint
      thumb_sha256 = hashlib.sha256(der_cert_bin).hexdigest()
      wrappedSocket.close()
      return ':'.join(a+b for a,b in zip(thumb_sha256[::2], thumb_sha256[1::2]))
Example #30
0
async def _cert_values(ip: str, port: int) -> Dict[str, str]:
    reader, writer = await asyncio.open_connection(ip, port, ssl=TLS)
    der_cert = writer.transport._ssl_protocol._sslpipe.ssl_object.getpeercert(True)
    writer.close()
    await writer.wait_closed()

    pem_cert = ssl.DER_cert_to_PEM_cert(der_cert).encode("ascii")
    cert     = x509.load_pem_x509_certificate(pem_cert, default_backend())

    values: Dict[str, str] = {}
    cns = cert.subject.get_attributes_for_oid(x509.oid.NameOID.COMMON_NAME)
    if cns:
        values["cn"] = cns[0].value
    ons = cert.subject.get_attributes_for_oid(x509.oid.NameOID.ORGANIZATION_NAME)
    if ons:
        values["on"] = ons[0].value
    return values