Friday, June 24, 2011

step 3 of check ca chains

Step 3 of a 3 part series. Step 1 and Step 2 will be put up by the end of July 2011.
If you need it sooner, pm me.

------- Step 1: Validating certificate matches url hostname ----

------- Step 2: Verify that the certificate is not expired  --------------

**------- Step 3: Validating the chain of CAs  --------------**

Needs OpenSSL

Needs <a href="https://github.com/haoqili/MozSecWorld/blob/master/apps/msw/files/cacerts.txt">cacerts.txt</a>

Looks long, but actually quite short, just lots of print statements.  Feel free to ask for help! I spent way too long on this. :P


    import socket
    from OpenSSL import SSL

    print "\n------------ Validating the chain of CAs  --------------"
    # crucially MODIFIED from: http://wiki.python.org/moin/SSL
    PORT = 443

    host = "www.google.com" # PUT YOUR HOST NAME HERE
    print "For host = " + str(host)

    # special callback function, cannot change format
    def verify_cb(conn, x509, errno, errdepth, retcode):
        """
        callback for certificate validation
        should return true if verification passes and false otherwise
        """
        print "   CA = " + str( x509.get_subject() )

        if errno == 0:
            if errdepth != 0:
                # don't validate names of root certificates
                print "\t---> GOOD (root certificate)"
                certValid[0] = True
                return True
            else:
                if x509.get_subject().commonName == host:
                    print "\t---> GOOD (cert commonName matched host name)"
                    certValid[0] = True
                    return True
                else:
                    print "\tcertCommonName: \t" + str(x509.get_subject().commonName)
                    print "\thostName: \t\t" + str(host)
                    print "\t---> FAILED (cert commonName did not match host name)"
                    certValid[0] = False
                    return False
        else:
            print "\t---> FAILED"
            certValid[0] = False
            return False

    context = SSL.Context(SSL.SSLv23_METHOD)
    context.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb)
    context.load_verify_locations("cacerts.txt") #or CHANGE TO YOUR CACERTS location!

    # create socket and connect to server
    sock = socket.socket()
    sock = SSL.Connection(context, sock)
    sock.connect((host, PORT))
    try:
        sock.do_handshake()
    except Exception as ec:
        print ec

    print "Disregard if you see 'certificate verify failed' on the line above,
    print "the actual result is below:"

    if certValid[0]:
        print "\r\n Certificate Check: PASSED -- Chain of CAs is VALID"
    else:
        print "\r\n Certificate Check: FAILD -- Chain of CAs is INVALID"

    print "\n------------- End Validating the Certificate of URL = " + str(url) + "\n"



Sample result:



   <!-- language: lang-none -->

    ------------ Validating the chain of CAs  --------------
    For host = www.google.com
       CA = <X509Name object '/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority'>
            ---> GOOD (root certificate)
       CA = <X509Name object '/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA'>
            ---> GOOD (root certificate)
       CA = <X509Name object '/C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com'>
            ---> GOOD (cert commonName matched host name)
    Disregard if you see 'certificate verify failed' on the line above,
    the actual result is below:

     Certificate Check: PASSED -- Chain of CAs is VALID

    ------------- End Validating the Certificate of URL = www.google.com

No comments:

Post a Comment