-----------------------------
#!/usr/local/bin python
"""
Create a certificate with Python.
"""
import urllib, sys, getopt, os, shutil
from M2Crypto import SSL, httpslib
from M2Crypto import RSA, X509, EVP, m2, Rand, Err
keystorepass = 'secret'
def passphrase_callback(v):
  return keystorepass
def generateRSAKey():
  return RSA.gen_key(1024, m2.RSA_F4)
def makePKey(key):
  pkey = EVP.PKey()
  pkey.assign_rsa(key)
  return pkey
def makeRequest(pkey, server_dns):
  req = X509.Request()
  # Seems to default to 0, but we can now set it as well, so just API test
  req.set_version(req.get_version())
  req.set_pubkey(pkey)
  name = X509.X509_Name()
  name.CN = server_dns
  name.OU = 'My Unit'
  name.O = 'My Company'
  name.L = 'My City'
  name.ST = 'My State'
  name.C = 'US'
  req.set_subject_name(name)
  ext1 = X509.new_extension('Comment', 'Auto Generated')
  extstack = X509.X509_Extension_Stack()
  extstack.push(ext1)
  req.add_extensions(extstack)
  req.sign(pkey, 'md5')
  return req
def sendRequest(crtreq):
  # send to a web service to sign the certificate
  return crtresp
def extractCert(crtresp):
  crt = ''
  # extract crt from the response
  return crt
def createJKS(fqdn):
  java_home = os.environ['JAVA_HOME']
  if java_home is None:
      raise 'JAVA_HOME needs to be set.'
  # an empty Java keystore         
  jks_template = 'template.jks'
  jksfile = ''.join([fqdn, '.jks'])
  certfile = ''.join([fqdn, '.crt'])
  keyfile = ''.join([fqdn, '.der'])
  shutil.copyfile(jks_template, jksfile)
  os.spawnl(os.P_WAIT, ''.join([java_home, '/bin/java.exe']), 'java', '-cp', '.', 'KeyStoreImport', jksfile, keystorepass, fqdn, certfile, keyfile, keystorepass)
def createPFX(fqdn):
  openssl_home = "c:/tools/openssl"
  if openssl_home is None:
      raise 'openssl needs to be installed.'
  certfile = ''.join([fqdn, '.crt'])
  keyfile = ''.join([fqdn, '.key'])
  pfxfile = ''.join([fqdn, '.pfx'])
  inpass = ":".join(['pass', keystorepass])
  outpass = ":".join(['pass', keystorepass])
  os.spawnl(os.P_WAIT, ''.join([openssl_home, '/bin/openssl.exe']), 'openssl', 'pkcs12', '-export', '-inkey', keyfile, \
            '-in', certfile, '-out', pfxfile, '-passin', inpass, '-passout', outpass)
def moveFiles(fqdn):
  if os.path.isdir(fqdn):
      os.rmdir(fqdn)
  os.mkdir(fqdn)
  shutil.move(''.join([fqdn, '.key']), fqdn)
  shutil.move(''.join([fqdn, '.der']), fqdn)
  shutil.move(''.join([fqdn, '.crt']), fqdn)
  shutil.move(''.join([fqdn, '.jks']), fqdn)
  shutil.move(''.join([fqdn, '.pfx']), fqdn)
def makeCert(fqdn):
  print '####### Generate RSA Key #######'
  rsa = generateRSAKey()
  rsa.save_key(''.join([fqdn, '.key']), cipher='aes_256_cbc', callback=passphrase_callback)
  rsa.save_key_der(''.join([fqdn, '.der']))
  print '####### Generate Pub/Pri Keys #######'
  pkey = makePKey(rsa)
  print '####### Generate Certificate Request #######'
  req = makeRequest(pkey, fqdn)
  print '####### Generate Certificate Request PEM #######'
  crtreq = req.as_pem()
  print '####### Certificate Request #######'
  print crtreq
  print '####### Certificate Request #######', '\n'
  crtresp = sendRequest(crtreq, fqdn)
  # print '####### Certificate Response #######'
  # print crtresp
  # print '####### Certificate Response #######', '\n'
  crtfile = open(''.join([fqdn, '.crt']), 'w')
  crtfile.write(crtresp)
  crtfile.close()
  crtfile = open(''.join([fqdn, '.crt']), 'r')
  crt = extractCert(crtfile)
  print '####### Certificate #######'
  print crt
  print '####### Certificate #######', '\n'
  crtfile.close()
  crtfile = open(''.join([fqdn, '.crt']), 'w')
  crtfile.write(crt)
  crtfile.close()
  print '####### Generate JKS #######'
  createJKS(fqdn)
  print '####### Generate PFX #######'
  createPFX(fqdn)
  print '####### Move Files #######'
  moveFiles(fqdn)
  print "Certificate generated"
def usage():
  print "Usage:"
  print "python gencrt.py -n <fqdn>"
if __name__ == '__main__':
  try:                             
      opts, args = getopt.getopt(sys.argv[1:], "hn:", ["help", "fqdn="])
  except getopt.GetoptError:
      usage()
      sys.exit(2)                  
  fqdn = None
  for opt, arg in opts:
      if opt in ("-h", "--help"):
          usage()  
          sys.exit()
      elif opt in ("-n", "--fqdn"):
          fqdn = arg
  if fqdn == None:
      usage()  
      sys.exit(2)
       
  makeCert(fqdn)</fqdn>