Changeset 868


Ignore:
Timestamp:
07/20/06 13:22:07 (7 years ago)
Author:
mglb1
Message:
  • Added support for revoking certificates
  • Removed crl/ directory - not required
  • Added findByCN function to search for a certificate
File:
1 edited

Legend:

Unmodified
Added
Removed
  • ccsd/trunk/crcnetd/_utils/ccsd_ca.py

    r866 r868  
    4949CERT_PARAM_NAMES = ["C", "ST", "L", "O", "OU", "CN", "emailAddress"] 
    5050 
     51REVOKE_UNSPECIFIED = "unspecified" 
     52REVOKE_COMPROMISED = "keyCompromise" 
     53REVOKE_SUPERSEDED = "superseded" 
     54REVOKE_OBSOLETE = "cessationOfOperation" 
     55 
    5156certParams = {} 
    5257 
     
    6368    global certParams 
    6469    return certParams 
     70 
     71def emptyCertParameters(): 
     72    """Helper function returns a empty set of certificate parameters""" 
     73    global CERT_PARAM_NAMES 
     74    params = {} 
     75    for param in CERT_PARAM_NAMES: 
     76        params[param] = "" 
     77    return params 
    6578 
    6679@exportViaXMLRPC(SESSION_RO, AUTH_USER) 
     
    191204            s+=1 
    192205            log_info("CA: Certificate storage directory created") 
    193         if not os.path.exists("%s/crl" % self.rDir): 
    194             # Storage directory for CRLs needs creating 
    195             ensureDirExists("%s/crl" % self.rDir) 
    196             self.mSvn.add("%s/crl" % self.rDir, False) 
    197             s+=1 
    198             log_info("CA: CRL storage directory created") 
    199206 
    200207        # Check for required files 
     
    245252            return 
    246253         
    247         if s>0 and s!=5: 
     254        if s>0 and s!=4: 
    248255            # Warn if only partial changes were made 
    249256            log_warn("CA: Initialised from incomplete state!") 
     
    545552                    "%s/index.txt.attr" % self.rDir, certfile] 
    546553            self.checkin("Signed new certificate for %s" % cn, paths) 
     554            log_info("CA: Signed new certificate (0x%s) for %s" % (serial, cn)) 
    547555        finally: 
    548556            os.unlink(filename) 
     
    551559        cert = open(certfile, "r").read() 
    552560        return cert 
     561     
     562    def revoke(self, serial, reasonCode=REVOKE_UNSPECIFIED, reasonText=""): 
     563        """Revokes the specified certificate optionally giving a reason 
     564         
     565        This function will revoke the key, giving the reason specified, the 
     566        certificate will be moved from certs/XX.pem to certs/XX-revoked.pem 
     567        and a new CRL will be issued. This function will commit changes to  
     568        index.txt. To be safe it is best to ensure that there are no other 
     569        pending changes before calling this method. 
     570        """ 
     571         
     572        # Sign the key 
     573        os.environ["CCS_CA_DIR"] = self.rDir 
     574        (fdi, fdo) = os.popen2("openssl ca -config %s/ca.cnf -revoke " \ 
     575                "%s/certs/%s.pem -crl_reason %s 2>&1" % \ 
     576                (self.rDir, self.rDir, serial, reasonCode)) 
     577        fdi.close() 
     578        lines = fdo.readlines() 
     579        fdo.close() 
     580        (fdi, fdo) = os.popen2("openssl ca -config %s/ca.cnf -gencrl -out " \ 
     581                "%s/crl.pem 2>&1" % (self.rDir, self.rDir)) 
     582        fdi.close() 
     583        rlines = fdo.readlines() 
     584        fdo.close() 
     585        del os.environ["CCS_CA_DIR"] 
     586         
     587        # Find the works "Revoking Certificate" in the output 
     588        try: 
     589            ok = False 
     590            for line in lines: 
     591                if line.strip().startswith("Revoking Certificate"): 
     592                    ok=True 
     593                    break 
     594            if not ok: 
     595                raise ccs_ca_error() 
     596        except: 
     597            log_debug("".join(lines)) 
     598            raise ccs_ca_error("Could not validate certificate revocation!") 
     599 
     600        # Move the certificate 
     601        try: 
     602            self.mSvn.move("%s/certs/%s.pem" % (self.rDir, serial), \ 
     603                    "%s/certs/%s-revoked.pem" % (self.rDir, serial)) 
     604        except: 
     605            log_error("Could not move revoked certificate to new name!", \ 
     606                    sys.exc_info()) 
     607 
     608        # Commit the changes 
     609        message = "Revoked (%s) certificate 0x%s: %s" % \ 
     610                (reasonCode, serial, reasonText) 
     611        self.checkin(message) 
     612        log_info("CA: %s" % message) 
     613         
     614    def findByCN(self, desiredCN): 
     615        """Searches the certificate database for records with matching CNs""" 
     616        certs = [] 
     617         
     618        # Read the database  
     619        try: 
     620            fd = open("%s/index.txt" % self.rDir, "r") 
     621            lines = fd.readlines() 
     622            fd.close() 
     623        except: 
     624            raise ccs_ca_error("Unable to read certificate database!") 
     625 
     626        # Parse the database 
     627        n=0 
     628        for line in lines: 
     629            n+=1 
     630            parts = line.split("\t") 
     631            if len(parts) != 6: 
     632                log_warn("Skipping malformed line %s in certificate DB" % \ 
     633                        n) 
     634                continue 
     635            # Look for the CN 
     636            if parts[5].find("CN=%s" % desiredCN) == -1: 
     637                continue 
     638            # Certificate parameters 
     639            t = parts[5][1:].split("/") 
     640            params = emptyCertParameters() 
     641            for p in t: 
     642                pp = p.split("=") 
     643                params[pp[0]] = pp[1] 
     644            # Store the match 
     645            cert = {"state":parts[0], "exp_date":parts[1], \ 
     646                    "rev_date":parts[2], "serial":parts[3], "file":parts[4], \ 
     647                    "params":params} 
     648            # Add to the list 
     649            certs.append(cert) 
     650 
     651        # Return results 
     652        return certs 
    553653 
    554654##################################################################### 
Note: See TracChangeset for help on using the changeset viewer.