def genPrivateCaKey(password, d, verbosity=0, forceYN=0): """ private CA key generation """ gendir(d['--dir']) ca_key = os.path.join(d['--dir'], os.path.basename(d['--ca-key'])) if not forceYN and os.path.exists(ca_key): sys.stderr.write("""\ ERROR: a CA private key already exists: %s If you wish to generate a new one, use the --force option. """ % ca_key) sys.exit(errnoGeneralError) args = ("/usr/bin/openssl genrsa -passout pass:%s %s -out %s 2048" % ('%s', CRYPTO, repr(cleanupAbsPath(ca_key)))) if verbosity >= 0: print "Generating private CA key: %s" % ca_key if verbosity > 1: print "Commandline:", args % "PASSWORD" try: rotated = rotateFile(filepath=ca_key, verbosity=verbosity) if verbosity >= 0 and rotated: print "Rotated: %s --> %s" \ % (d['--ca-key'], os.path.basename(rotated)) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args % repr(password)) finally: chdir(cwd) out = out_stream.read() out_stream.close() err = err_stream.read() err_stream.close() if ret: raise GenPrivateCaKeyException("Certificate Authority private SSL " "key generation failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print "STDOUT:", out if err: print "STDERR:", err # permissions: os.chmod(ca_key, 0600)
def updateDir(self, newdir=None, verbosity=0): """ changes the CA configuration file's directory setting (if need be) in place. Touches nothing else. """ if self.updateLegacy(newdir): return try: fo = open(self.filename, 'r') except: return olddir = '' if newdir is None: newdir = os.path.dirname(self.filename) newfile = "" hit_CA_defaultYN = 0 line = fo.readline() while line: if string.strip(line) == '[ CA_default ]': # we don't care much until we hit this label hit_CA_defaultYN = 1 if hit_CA_defaultYN: vector = string.split(line, '=') if len(vector) == 2: key, value = vector if string.strip(key) == 'dir': value = string.strip(value) olddir = value line = '%s= %s\n' % (key, newdir) hit_CA_defaultYN = 0 if newdir == olddir: # nothing to do return newfile = newfile + line line = fo.readline() try: rotated = rotateFile(filepath=self.filename, verbosity=verbosity) if verbosity>=0 and rotated: print "Rotated: %s --> %s" % (os.path.basename(self.filename), os.path.basename(rotated)) except ValueError: pass fo = open(self.filename, 'w') fo.write(newfile) fo.close() os.chmod(self.filename, 0600)
def genPrivateCaKey(password, d, verbosity=0, forceYN=0): """ private CA key generation """ gendir(d['--dir']) ca_key = os.path.join(d['--dir'], os.path.basename(d['--ca-key'])) if not forceYN and os.path.exists(ca_key): sys.stderr.write("""\ ERROR: a CA private key already exists: %s If you wish to generate a new one, use the --force option. """ % ca_key) sys.exit(errnoGeneralError) args = ("/usr/bin/openssl genrsa -passout pass:%s %s -out %s 2048" % ('%s', CRYPTO, repr(cleanupAbsPath(ca_key)))) if verbosity >= 0: print "Generating private CA key: %s" % ca_key if verbosity > 1: print "Commandline:", args % "PASSWORD" try: rotated = rotateFile(filepath=ca_key, verbosity=verbosity) if verbosity>=0 and rotated: print "Rotated: %s --> %s" \ % (d['--ca-key'], os.path.basename(rotated)) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args % repr(password)) finally: chdir(cwd) out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret: raise GenPrivateCaKeyException("Certificate Authority private SSL " "key generation failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print "STDOUT:", out if err: print "STDERR:", err # permissions: os.chmod(ca_key, 0600)
def genServerKey(d, verbosity=0): """ private server key generation """ serverKeyPairDir = os.path.join(d['--dir'], getMachineName(d['--set-hostname'])) gendir(serverKeyPairDir) server_key = os.path.join(serverKeyPairDir, os.path.basename(d['--server-key'])) args = ("/usr/bin/openssl genrsa -out %s 2048" % (repr(cleanupAbsPath(server_key)))) # generate the server key if verbosity >= 0: print "\nGenerating the web server's SSL private key: %s" % server_key if verbosity > 1: print "Commandline:", args try: rotated = rotateFile(filepath=server_key, verbosity=verbosity) if verbosity >= 0 and rotated: print "Rotated: %s --> %s" % (d['--server-key'], os.path.basename(rotated)) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args) finally: chdir(cwd) out = out_stream.read() out_stream.close() err = err_stream.read() err_stream.close() if ret: raise GenServerKeyException( "web server's SSL key generation failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print "STDOUT:", out if err: print "STDERR:", err # permissions: os.chmod(server_key, 0600)
def genServerKey(d, verbosity=0): """ private server key generation """ serverKeyPairDir = os.path.join(d['--dir'], getMachineName(d['--set-hostname'])) gendir(serverKeyPairDir) server_key = os.path.join(serverKeyPairDir, os.path.basename(d['--server-key'])) args = ("/usr/bin/openssl genrsa -out %s 2048" % (repr(cleanupAbsPath(server_key)))) # generate the server key if verbosity >= 0: print "\nGenerating the web server's SSL private key: %s" % server_key if verbosity > 1: print "Commandline:", args try: rotated = rotateFile(filepath=server_key, verbosity=verbosity) if verbosity>=0 and rotated: print "Rotated: %s --> %s" % (d['--server-key'], os.path.basename(rotated)) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args) finally: chdir(cwd) out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret: raise GenServerKeyException("web server's SSL key generation failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print "STDOUT:", out if err: print "STDERR:", err # permissions: os.chmod(server_key, 0600)
def save(self, d, caYN=0, verbosity=0): """ d == commandline dictionary """ mapping = { '--set-country' : 'C', '--set-state' : 'ST', '--set-city' : 'L', '--set-org' : 'O', '--set-org-unit' : 'OU', '--set-common-name' : 'CN', # these two will never occur at the '--set-hostname' : 'CN', # same time '--set-email' : 'emailAddress', } rdn = {} for k in d.keys(): if mapping.has_key(k): rdn[mapping[k]] = string.strip(d[k]) openssl_cnf = '' if caYN: openssl_cnf = CONF_TEMPLATE_CA % ( os.path.dirname(self.filename)+'/', gen_req_distinguished_name(rdn), ) else: openssl_cnf = CONF_TEMPLATE_SERVER \ % (gen_req_distinguished_name(rdn), gen_req_alt_names(d, rdn['CN'])) try: rotated = rotateFile(filepath=self.filename,verbosity=verbosity) if verbosity>=0 and rotated: print "Rotated: %s --> %s" % (os.path.basename(self.filename), os.path.basename(rotated)) except ValueError: pass fo = open(self.filename, 'w') fo.write(openssl_cnf) fo.close() os.chmod(self.filename, 0600) return openssl_cnf
def genServerCert(password, d, verbosity=0): """ server cert generation and signing """ serverKeyPairDir = os.path.join(d['--dir'], d['--set-hostname']) genServerCert_dependencies(password, d) ca_key = os.path.join(d['--dir'], os.path.basename(d['--ca-key'])) ca_cert = os.path.join(d['--dir'], os.path.basename(d['--ca-cert'])) server_cert_req = os.path.join(serverKeyPairDir, os.path.basename(d['--server-cert-req'])) server_cert = os.path.join(serverKeyPairDir, os.path.basename(d['--server-cert'])) ca_openssl_cnf = os.path.join(d['--dir'], CA_OPENSSL_CNF_NAME) index_txt = os.path.join(d['--dir'], 'index.txt') serial = os.path.join(d['--dir'], 'serial') purpose = d['--purpose'] try: os.unlink(index_txt) except: pass # figure out the serial file and truncate the index.txt file. ser = figureSerial(ca_cert, serial, index_txt) # need to insure the directory declared in the ca_openssl.cnf # file is current: configFile = ConfigFile(ca_openssl_cnf) configFile.updateDir() args = ( "/usr/bin/openssl ca -extensions req_%s_x509_extensions -passin pass:%s -outdir ./ -config %s " "-in %s -batch -cert %s -keyfile %s -startdate %s -days %s " "-md %s -out %s" % (purpose, '%s', repr(cleanupAbsPath(ca_openssl_cnf)), repr(cleanupAbsPath(server_cert_req)), repr(cleanupAbsPath(ca_cert)), repr(cleanupAbsPath(ca_key)), d['--startdate'], repr(d['--cert-expiration']), MD, repr(cleanupAbsPath(server_cert)))) if verbosity >= 0: print "\nGenerating/signing web server's SSL certificate: %s" % d[ '--server-cert'] if verbosity > 1: print "Commandline:", args % 'PASSWORD' try: rotated = rotateFile(filepath=server_cert, verbosity=verbosity) if verbosity >= 0 and rotated: print "Rotated: %s --> %s" % (d['--server-cert'], os.path.basename(rotated)) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args % repr(password)) finally: chdir(cwd) out = out_stream.read() out_stream.close() err = err_stream.read() err_stream.close() if ret: # signature for a mistyped CA password if string.find(err, "unable to load CA private key") != -1 \ and string.find(err, "error:0906A065:PEM routines:PEM_do_header:bad decrypt:pem_lib.c") != -1 \ and string.find(err, "error:06065064:digital envelope routines:EVP_DecryptFinal:bad decrypt:evp_enc.c") != -1: raise GenServerCertException( "web server's SSL certificate generation/signing " "failed:\nDid you mistype your CA password?") else: raise GenServerCertException( "web server's SSL certificate generation/signing " "failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print "STDOUT:", out if err: print "STDERR:", err # permissions: os.chmod(server_cert, 0644) # cleanup duplicate XX.pem file: pemFilename = os.path.basename(string.upper(ser) + '.pem') if pemFilename != server_cert and os.path.exists(pemFilename): os.unlink(pemFilename) # cleanup the old index.txt file try: os.unlink(index_txt + '.old') except: pass # cleanup the old serial file try: os.unlink(serial + '.old') except: pass
def genServerCertReq(d, verbosity=0): """ private server cert request generation """ serverKeyPairDir = os.path.join(d['--dir'], d['--set-hostname']) server_key = os.path.join(serverKeyPairDir, os.path.basename(d['--server-key'])) server_cert_req = os.path.join(serverKeyPairDir, os.path.basename(d['--server-cert-req'])) server_openssl_cnf = os.path.join(serverKeyPairDir, SERVER_OPENSSL_CNF_NAME) genServerCertReq_dependencies(d) # XXX: hmm.. should private_key, etc. be set for this before the write? # either that you pull the key/certs from the files all together? configFile = ConfigFile(server_openssl_cnf) configFile.save(d, caYN=0, verbosity=verbosity) ## generate the server cert request args = ("/usr/bin/openssl req -%s -text -config %s -new -key %s -out %s " % (MD, repr(cleanupAbsPath( configFile.filename)), repr(cleanupAbsPath(server_key)), repr(cleanupAbsPath(server_cert_req)))) if verbosity >= 0: print "\nGenerating web server's SSL certificate request: %s" % server_cert_req print "Using distinguished names:" for k in ('--set-country', '--set-state', '--set-city', '--set-org', '--set-org-unit', '--set-hostname', '--set-email'): print ' %s%s = "%s"' % (k, ' ' * (18 - len(k)), d[k]) if verbosity > 1: print "Commandline:", args try: rotated = rotateFile(filepath=server_cert_req, verbosity=verbosity) if verbosity >= 0 and rotated: print "Rotated: %s --> %s" % (d['--server-cert-req'], os.path.basename(rotated)) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args) finally: chdir(cwd) out = out_stream.read() out_stream.close() err = err_stream.read() err_stream.close() if ret: raise GenServerCertReqException( "web server's SSL certificate request generation " "failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print "STDOUT:", out if err: print "STDERR:", err # permissions: os.chmod(server_cert_req, 0600)
def genPublicCaCert(password, d, verbosity=0, forceYN=0): """ public CA certificate (client-side) generation """ ca_key = os.path.join(d['--dir'], os.path.basename(d['--ca-key'])) ca_cert_name = os.path.basename(d['--ca-cert']) ca_cert = os.path.join(d['--dir'], ca_cert_name) ca_openssl_cnf = os.path.join(d['--dir'], CA_OPENSSL_CNF_NAME) genPublicCaCert_dependencies(password, d, forceYN) configFile = ConfigFile(ca_openssl_cnf) if d.has_key('--set-hostname'): del d['--set-hostname'] configFile.save(d, caYN=1, verbosity=verbosity) args = ("/usr/bin/openssl req -passin pass:%s -text -config %s " "-new -x509 -days %s -%s -key %s -out %s" % ('%s', repr(cleanupAbsPath(configFile.filename)), repr(d['--cert-expiration']), MD, repr( cleanupAbsPath(ca_key)), repr(cleanupAbsPath(ca_cert)))) if verbosity >= 0: print "\nGenerating public CA certificate: %s" % ca_cert print "Using distinguishing variables:" for k in ('--set-country', '--set-state', '--set-city', '--set-org', '--set-org-unit', '--set-common-name', '--set-email'): print ' %s%s = "%s"' % (k, ' ' * (18 - len(k)), d[k]) if verbosity > 1: print "Commandline:", args % "PASSWORD" try: rotated = rotateFile(filepath=ca_cert, verbosity=verbosity) if verbosity >= 0 and rotated: print "Rotated: %s --> %s" \ % (d['--ca-cert'], os.path.basename(rotated)) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args % repr(password)) finally: chdir(cwd) out = out_stream.read() out_stream.close() err = err_stream.read() err_stream.close() if ret: raise GenPublicCaCertException( "Certificate Authority public " "SSL certificate generation failed:\n%s\n" "%s" % (out, err)) if verbosity > 2: if out: print "STDOUT:", out if err: print "STDERR:", err latest_txt = os.path.join(d['--dir'], 'latest.txt') fo = open(latest_txt, 'wb') fo.write('%s\n' % ca_cert_name) fo.close() # permissions: os.chmod(ca_cert, 0644) os.chmod(latest_txt, 0644)
def updateLegacy(self, newdir=None, verbosity=1): """ in slightly older formatted ca_openssl.cnf files, there was no dir setting seperate from the database and serial settings. This function fixes that setup. Most of the time this function short-circuits early. """ try: fo = open(self.filename, 'r') except: return if newdir is None: newdir = os.path.dirname(self.filename) newfile = "" in_CA_defaultYN = 0 dirSetYN = 0 line = fo.readline() while line: cleanLine = string.strip(line) # is this a label? isLabelYN = 0 if cleanLine \ and (cleanLine[0], cleanLine[-1]) == ('[',']'): isLabelYN = 1 if cleanLine == '[ CA_default ]': # we don't care much until we hit this label in_CA_defaultYN = 1 elif isLabelYN: in_CA_defaultYN = 0 # hit another label if in_CA_defaultYN: vector = string.split(line, '=') if len(vector) == 2: key = string.strip(vector[0]) if key == 'dir': # we should be OK - short-circuit return if key in ('database', 'serial'): # we never hit a "dir" key if not dirSetYN: newfile = newfile + """\ dir = %s database = $dir/index.txt serial = $dir/serial """ % newdir dirSetYN = 1 line = fo.readline() continue newfile = newfile + line line = fo.readline() try: rotated = rotateFile(filepath=self.filename, verbosity=verbosity) if verbosity>=0 and rotated: print "Rotated: %s --> %s" % (os.path.basename(self.filename), os.path.basename(rotated)) except ValueError: pass fo = open(self.filename, 'w') fo.write(newfile) fo.close() os.chmod(self.filename, 0600) return dirSetYN
def genServerCert(password, d, verbosity=0): """ server cert generation and signing """ serverKeyPairDir = os.path.join(d['--dir'], getMachineName(d['--set-hostname'])) genServerCert_dependencies(password, d) ca_key = os.path.join(d['--dir'], os.path.basename(d['--ca-key'])) ca_cert = os.path.join(d['--dir'], os.path.basename(d['--ca-cert'])) server_cert_req = os.path.join(serverKeyPairDir, os.path.basename(d['--server-cert-req'])) server_cert = os.path.join(serverKeyPairDir, os.path.basename(d['--server-cert'])) ca_openssl_cnf = os.path.join(d['--dir'], CA_OPENSSL_CNF_NAME) index_txt = os.path.join(d['--dir'], 'index.txt') serial = os.path.join(d['--dir'], 'serial') try: os.unlink(index_txt) except: pass # figure out the serial file and truncate the index.txt file. ser = figureSerial(ca_cert, serial, index_txt) # need to insure the directory declared in the ca_openssl.cnf # file is current: configFile = ConfigFile(ca_openssl_cnf) configFile.updateDir() args = ("/usr/bin/openssl ca -extensions req_server_x509_extensions -passin pass:%s -outdir ./ -config %s " "-in %s -batch -cert %s -keyfile %s -startdate %s -days %s " "-md %s -out %s" % ('%s', repr(cleanupAbsPath(ca_openssl_cnf)), repr(cleanupAbsPath(server_cert_req)), repr(cleanupAbsPath(ca_cert)), repr(cleanupAbsPath(ca_key)), d['--startdate'], repr(d['--cert-expiration']), MD, repr(cleanupAbsPath(server_cert)))) if verbosity >= 0: print "\nGenerating/signing web server's SSL certificate: %s" % d['--server-cert'] if verbosity > 1: print "Commandline:", args % 'PASSWORD' try: rotated = rotateFile(filepath=server_cert, verbosity=verbosity) if verbosity>=0 and rotated: print "Rotated: %s --> %s" % (d['--server-cert'], os.path.basename(rotated)) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args % repr(password)) finally: chdir(cwd) out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret: # signature for a mistyped CA password if string.find(err, "unable to load CA private key") != -1 \ and string.find(err, "error:0906A065:PEM routines:PEM_do_header:bad decrypt:pem_lib.c") != -1 \ and string.find(err, "error:06065064:digital envelope routines:EVP_DecryptFinal:bad decrypt:evp_enc.c") != -1: raise GenServerCertException( "web server's SSL certificate generation/signing " "failed:\nDid you mistype your CA password?") else: raise GenServerCertException( "web server's SSL certificate generation/signing " "failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print "STDOUT:", out if err: print "STDERR:", err # permissions: os.chmod(server_cert, 0644) # cleanup duplicate XX.pem file: pemFilename = os.path.basename(string.upper(ser)+'.pem') if pemFilename != server_cert and os.path.exists(pemFilename): os.unlink(pemFilename) # cleanup the old index.txt file try: os.unlink(index_txt + '.old') except: pass # cleanup the old serial file try: os.unlink(serial + '.old') except: pass
def genServerCertReq(d, verbosity=0): """ private server cert request generation """ serverKeyPairDir = os.path.join(d['--dir'], getMachineName(d['--set-hostname'])) server_key = os.path.join(serverKeyPairDir, os.path.basename(d['--server-key'])) server_cert_req = os.path.join(serverKeyPairDir, os.path.basename(d['--server-cert-req'])) server_openssl_cnf = os.path.join(serverKeyPairDir, SERVER_OPENSSL_CNF_NAME) genServerCertReq_dependencies(d) # XXX: hmm.. should private_key, etc. be set for this before the write? # either that you pull the key/certs from the files all together? configFile = ConfigFile(server_openssl_cnf) if d.has_key('--set-common-name'): del d['--set-common-name'] configFile.save(d, caYN=0, verbosity=verbosity) ## generate the server cert request args = ("/usr/bin/openssl req -%s -text -config %s -new -key %s -out %s " % (MD, repr(cleanupAbsPath(configFile.filename)), repr(cleanupAbsPath(server_key)), repr(cleanupAbsPath(server_cert_req)))) if verbosity >= 0: print "\nGenerating web server's SSL certificate request: %s" % server_cert_req print "Using distinguished names:" for k in ('--set-country', '--set-state', '--set-city', '--set-org', '--set-org-unit', '--set-hostname', '--set-email'): print ' %s%s = "%s"' % (k, ' '*(18-len(k)), d[k]) if verbosity > 1: print "Commandline:", args try: rotated = rotateFile(filepath=server_cert_req, verbosity=verbosity) if verbosity>=0 and rotated: print "Rotated: %s --> %s" % (d['--server-cert-req'], os.path.basename(rotated)) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args) finally: chdir(cwd) out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret: raise GenServerCertReqException( "web server's SSL certificate request generation " "failed:\n%s\n%s" % (out, err)) if verbosity > 2: if out: print "STDOUT:", out if err: print "STDERR:", err # permissions: os.chmod(server_cert_req, 0600)
def genPublicCaCert(password, d, verbosity=0, forceYN=0): """ public CA certificate (client-side) generation """ ca_key = os.path.join(d['--dir'], os.path.basename(d['--ca-key'])) ca_cert_name = os.path.basename(d['--ca-cert']) ca_cert = os.path.join(d['--dir'], ca_cert_name) ca_openssl_cnf = os.path.join(d['--dir'], CA_OPENSSL_CNF_NAME) genPublicCaCert_dependencies(password, d, forceYN) configFile = ConfigFile(ca_openssl_cnf) if d.has_key('--set-hostname'): del d['--set-hostname'] configFile.save(d, caYN=1, verbosity=verbosity) args = ("/usr/bin/openssl req -passin pass:%s -text -config %s " "-new -x509 -days %s -%s -key %s -out %s" % ('%s', repr(cleanupAbsPath(configFile.filename)), repr(d['--cert-expiration']), MD, repr(cleanupAbsPath(ca_key)), repr(cleanupAbsPath(ca_cert)))) if verbosity >= 0: print "\nGenerating public CA certificate: %s" % ca_cert print "Using distinguishing variables:" for k in ('--set-country', '--set-state', '--set-city', '--set-org', '--set-org-unit', '--set-common-name', '--set-email'): print ' %s%s = "%s"' % (k, ' '*(18-len(k)), d[k]) if verbosity > 1: print "Commandline:", args % "PASSWORD" try: rotated = rotateFile(filepath=ca_cert, verbosity=verbosity) if verbosity>=0 and rotated: print "Rotated: %s --> %s" \ % (d['--ca-cert'], os.path.basename(rotated)) except ValueError: pass cwd = chdir(_getWorkDir()) try: ret, out_stream, err_stream = rhn_popen(args % repr(password)) finally: chdir(cwd) out = out_stream.read(); out_stream.close() err = err_stream.read(); err_stream.close() if ret: raise GenPublicCaCertException("Certificate Authority public " "SSL certificate generation failed:\n%s\n" "%s" % (out, err)) if verbosity > 2: if out: print "STDOUT:", out if err: print "STDERR:", err latest_txt = os.path.join(d['--dir'], 'latest.txt') fo = open(latest_txt, 'wb') fo.write('%s\n' % ca_cert_name) fo.close() # permissions: os.chmod(ca_cert, 0644) os.chmod(latest_txt, 0644)