summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorMatthew Newhook <matthew@zeroc.com>2006-07-25 09:01:18 +0000
committerMatthew Newhook <matthew@zeroc.com>2006-07-25 09:01:18 +0000
commitcb18ffc0216bc1f7e68ce7cebc5cd5def243457e (patch)
tree55cafaece214cee2253300b44a442377270b4946 /cpp/src
parentFixed bug 1248. (diff)
downloadice-cb18ffc0216bc1f7e68ce7cebc5cd5def243457e.tar.bz2
ice-cb18ffc0216bc1f7e68ce7cebc5cd5def243457e.tar.xz
ice-cb18ffc0216bc1f7e68ce7cebc5cd5def243457e.zip
http://bugzilla.zeroc.com/bugzilla/show_bug.cgi?id=1189
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Makefile3
-rw-r--r--cpp/src/ca/ImportKey.classbin0 -> 3040 bytes
-rw-r--r--cpp/src/ca/ImportKey.java130
-rw-r--r--cpp/src/ca/Makefile23
-rw-r--r--cpp/src/ca/README6
-rwxr-xr-xcpp/src/ca/iceca640
6 files changed, 801 insertions, 1 deletions
diff --git a/cpp/src/Makefile b/cpp/src/Makefile
index cb23f84b9ab..ebec27a9331 100644
--- a/cpp/src/Makefile
+++ b/cpp/src/Makefile
@@ -33,7 +33,8 @@ SUBDIRS = IceUtil \
IceStorm \
Glacier2 \
IcePatch2 \
- IceGrid
+ IceGrid \
+ ca
$(EVERYTHING)::
@for subdir in $(SUBDIRS); \
diff --git a/cpp/src/ca/ImportKey.class b/cpp/src/ca/ImportKey.class
new file mode 100644
index 00000000000..a7ddfa8b442
--- /dev/null
+++ b/cpp/src/ca/ImportKey.class
Binary files differ
diff --git a/cpp/src/ca/ImportKey.java b/cpp/src/ca/ImportKey.java
new file mode 100644
index 00000000000..2169bea9cc2
--- /dev/null
+++ b/cpp/src/ca/ImportKey.java
@@ -0,0 +1,130 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+//
+// Java's keytool program does not provide any way to import a private
+// key, so this simple utility imports a private key and certificate
+// chain from a PKCS12 file into a Java keystore.
+//
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+
+public class ImportKey
+{
+ static private char[]
+ readPassword(String f)
+ {
+ try
+ {
+ java.io.InputStream s = new java.io.FileInputStream(f);
+ int n = s.available();
+ byte[] raw = new byte[n];
+ s.read(raw);
+ s.close();
+
+ return (new String(raw)).toCharArray();
+ }
+ catch(Exception ex)
+ {
+ ex.printStackTrace();
+ System.exit(1);
+ }
+ return null;
+ }
+
+ public static void
+ main(String[] args)
+ {
+ if(args.length < 5)
+ {
+ //
+ // Arguments:
+ //
+ // pkcs12-file A file in PKCS12 format that contains the
+ // private key and certificate chain.
+ //
+ // alias The key's friendly name in pkcs12-file and the
+ // alias for the key in the new keystore.
+ //
+ // cert-file The CA certificate file in DER format.
+ //
+ // keystore-file The name of the keystore file to update
+ // or create.
+ //
+ // store-password The file containing the password to use
+ // for the keystore.
+ //
+ // key-password The file containing the password to use
+ // for the key.
+ //
+ // kstore-password The file containing the password to use
+ // to store the key. If this isn't provided the
+ // key-password is used. This is used to import an
+ // unprotected private key.
+ //
+ System.err.println("Usage: ImportKey pkcs12-file alias cert-file " +
+ "keystore-file store-password key-password [kstore-password]");
+ System.exit(1);
+ }
+
+ final String pkcs12File = args[0];
+ final String alias = args[1];
+ final String certFile = args[2];
+ final String keystoreFile = args[3];
+ final char[] storePassword = readPassword(args[4]);
+ final char[] keyPassword = readPassword(args[5]);
+ char[] kstorePassword = readPassword(args[5]);
+ if(args.length > 6)
+ {
+ kstorePassword = readPassword(args[5]);
+ }
+ else
+ {
+ kstorePassword = keyPassword;
+ }
+
+ try
+ {
+ KeyStore src = KeyStore.getInstance("PKCS12");
+ src.load(new java.io.FileInputStream(pkcs12File), keyPassword);
+
+ KeyStore dest = KeyStore.getInstance("JKS");
+ java.io.File f = new java.io.File(keystoreFile);
+ if(f.exists())
+ {
+ dest.load(new java.io.FileInputStream(f), storePassword);
+ }
+ else
+ {
+ dest.load(null, null);
+ }
+ Certificate[] chain = src.getCertificateChain(alias);
+ Key key = src.getKey(alias, keyPassword);
+
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ X509Certificate cert = (X509Certificate)
+ cf.generateCertificate(new java.io.FileInputStream(certFile));
+
+ dest.setKeyEntry(alias, key, kstorePassword, chain);
+ dest.setCertificateEntry("cacert", cert);
+
+ dest.store(new java.io.FileOutputStream(keystoreFile), storePassword);
+ }
+ catch(Exception ex)
+ {
+ ex.printStackTrace();
+ System.exit(1);
+ }
+
+ System.exit(0);
+ }
+}
diff --git a/cpp/src/ca/Makefile b/cpp/src/ca/Makefile
new file mode 100644
index 00000000000..ade4975208f
--- /dev/null
+++ b/cpp/src/ca/Makefile
@@ -0,0 +1,23 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+include $(top_srcdir)/config/Make.rules
+
+CA_FILES = iceca \
+ ImportKey.class
+
+install::
+ @for i in $(CA_FILES) ; \
+ do \
+ echo "Installing $$i" ; \
+ $(INSTALL_PROGRAM) $$i $(install_bindir) ;\
+ chmod a+x $(install_bindir)/$$i ;\
+ done
diff --git a/cpp/src/ca/README b/cpp/src/ca/README
new file mode 100644
index 00000000000..21d80094033
--- /dev/null
+++ b/cpp/src/ca/README
@@ -0,0 +1,6 @@
+The Python script in this directory is a wrapper around OpenSSL's
+tools to simplify the process of setting up a private certificate
+authority and generating certificates.
+
+
+See the IceSSL chapter of the Ice manual for usage instructions.
diff --git a/cpp/src/ca/iceca b/cpp/src/ca/iceca
new file mode 100755
index 00000000000..abc03a4ec03
--- /dev/null
+++ b/cpp/src/ca/iceca
@@ -0,0 +1,640 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import os
+import sys
+import getopt
+import tempfile
+import getpass
+import shutil
+import socket
+
+home = os.getenv("ICE_CA_HOME")
+if home is None:
+ # The substring on sys.platform is required because some cygwin
+ # versions return variations like "cygwin_nt-4.01".
+ if sys.platform == "win32" or sys.platform[:6] == "cygwin":
+ home = os.path.dirname(sys.argv[0])
+ home = os.path.join(home, "config", "ca")
+ else:
+ home = os.getenv('HOME')
+ if home is None:
+ print "Environment variable HOME is not set."
+ sys.exit(1)
+ home = os.path.join(home, ".iceca")
+home = os.path.normpath(home)
+os.putenv("ICE_CA_HOME", home)
+
+caroot = os.path.join(home, "ca")
+cadb = os.path.join(caroot, "db")
+
+def usage():
+ print "usage: " + sys.argv[0] + " import sign request init"
+ sys.exit(1)
+
+if len(sys.argv) == 1:
+ usage()
+
+if sys.argv[1] == "import":
+ #
+ # dirname handles finding the .py under Windows since it will
+ # contain the location of the script. ICE_HOME handles the case
+ # where the install is in a non-standard location. "." handles
+ # development. "/usr/bin" handles RPM installs and "/opt/..."
+ # handles standard tarball installs.
+ #
+ for bindir in [os.path.dirname(sys.argv[0]), os.path.join(os.getenv("ICE_HOME"), "bin"), ".", "/usr/bin", \
+ "/opt/Ice-3.2.0/bin"]:
+ bindir = os.path.normpath(bindir)
+ if os.path.exists(os.path.join(bindir, "ImportKey.class")):
+ break
+ else:
+ raise "can't locate simple CA package"
+
+ def usage():
+ print "usage: " + sys.argv[1] + " [--overwrite] [--java alias cert key keystore] [--cs cert key out-file]"
+ sys.exit(1)
+
+ try:
+ opts, args = getopt.getopt(sys.argv[2:], "", [ "overwrite", "java", "cs"])
+ except getopt.GetoptError:
+ usage()
+
+ java = False
+ cs = False
+ overwrite = False
+ for o, a in opts:
+ if o == "--overwrite":
+ overwrite = True
+ if o == "--java":
+ java = True
+ if o == "--cs":
+ cs = True
+
+ if not java and not cs:
+ print sys.argv[1] + ": one of --java or --cs must be provided"
+ usage()
+
+ if java:
+ if len(args) != 4:
+ usage()
+
+ alias = args[0]
+ cert = args[1]
+ key = args[2]
+ store = args[3]
+
+ keyPass = getpass.getpass("Enter private key passphrase:")
+
+ storePass = ""
+ while len(storePass) == 0:
+ storePass = getpass.getpass("Enter keystore password:")
+
+ #
+ # We use secure temporary files to transfer the password to openssl
+ # and the ImportKey java tool. Its necessary to create 2 files for the
+ # key password because openssl craps out if you use the same password
+ # file twice.
+ #
+ keypassfile1 = None
+ keypassfile2 = None
+
+ if len(keyPass) > 0:
+ temp, keypassfile1 = tempfile.mkstemp("keypass1")
+ os.write(temp, keyPass)
+ os.close(temp)
+
+ temp, keypassfile2 = tempfile.mkstemp("keypass2")
+ os.write(temp, keyPass)
+ os.close(temp)
+ else:
+ # Java can't deal with unencrypted keystores, so we use a
+ # temporary one.
+ temp, keypassfile1 = tempfile.mkstemp("keypass1")
+ os.write(temp, "password")
+ os.close(temp)
+
+ # We create a file with an empty password to store the results
+ # in the keystore.
+ temp, keypassfile2 = tempfile.mkstemp("keypass2")
+ os.close(temp)
+
+ temp, storepassfile = tempfile.mkstemp("storepass3")
+ os.write(temp, storePass)
+ os.close(temp)
+
+ temp, pkcs12cert = tempfile.mkstemp(".p12", "pkcs12")
+ os.close(temp)
+
+ if len(keyPass) > 0:
+ cmd = "openssl pkcs12 -in " + cert + " -inkey " + key + " -export -out " + pkcs12cert + " -name " + \
+ alias + " -passin file:" + keypassfile1 + " -passout file:" + keypassfile2 + " -certfile " + \
+ os.path.join(home, "ca_cert.pem")
+ else:
+ cmd = "openssl pkcs12 -in " + cert + " -inkey " + key + " -export -out " + pkcs12cert + " -name " + \
+ alias + " -passout file:" + keypassfile1 + " -certfile " + os.path.join(home, "ca_cert.pem")
+
+ #print cmd
+ print "converting to pkcs12 format... ",
+ status = os.system(cmd)
+ if status != 0:
+ print "openssl command failed"
+ os.remove(keypassfile1)
+ os.remove(keypassfile2)
+ os.remove(storepassfile)
+ sys.exit(1)
+ print "ok"
+
+ # Use java to import the cert into the keystore.
+ cmd = "java -classpath " + bindir + " ImportKey " + pkcs12cert + " " + alias + " " \
+ + os.path.join(home, "ca_cert.pem") + " " + store + " " + storepassfile + " " + keypassfile1
+ if len(keyPass) == 0:
+ cmd = cmd + " " + keypassfile2
+
+ #print cmd
+ print "importing into the keystore...",
+ status = os.system(cmd)
+ if status != 0:
+ print "java command failed"
+ else:
+ print "ok"
+
+ # Cleanup.
+ os.remove(pkcs12cert)
+ os.remove(keypassfile1)
+ os.remove(keypassfile2)
+ os.remove(storepassfile)
+
+ if cs:
+ if len(args) != 3:
+ usage()
+
+ cert = args[0]
+ key = args[1]
+ pkcs12cert = args[2]
+ if not overwrite and os.path.exists(pkcs12cert):
+ print pkcs12cert + ": file exists"
+ sys.exit(1)
+
+ keyPass = getpass.getpass("Enter private key passphrase:")
+
+ #
+ # We use secure temporary files to transfer the password to
+ # openssl Its necessary to create 2 files for the key password
+ # because openssl craps out if you use the same password file
+ # twice.
+ #
+ keypassfile1 = None
+ keypassfile2 = None
+
+ if len(keyPass) > 0:
+ temp, keypassfile1 = tempfile.mkstemp("keypass1")
+ os.write(temp, keyPass)
+ os.close(temp)
+
+ temp, keypassfile2 = tempfile.mkstemp("keypass2")
+ os.write(temp, keyPass)
+ os.close(temp)
+
+ cmd = "openssl pkcs12 -in " + cert + " -inkey " + key + " -export -out " + pkcs12cert + \
+ " -passin file:" + keypassfile1 + " -passout file:" + keypassfile2
+ else:
+ cmd = "openssl pkcs12 -in " + cert + " -inkey " + key + " -export -out " + pkcs12cert + " -passout pass:"
+
+ #print cmd
+ print "converting to pkcs12 format...",
+ status = os.system(cmd)
+ if keypassfile1 != None:
+ os.remove(keypassfile1)
+ if keypassfile2 != None:
+ os.remove(keypassfile2)
+ if status != 0:
+ print "openssl command failed"
+ sys.exit(1)
+ print "ok"
+
+ sys.exit(0)
+
+if sys.argv[1] == "init":
+ def usage():
+ print "usage: " + sys.argv[1] + " [--no-password] [--overwrite]"
+ sys.exit(1)
+
+ try:
+ opts, args = getopt.getopt(sys.argv[2:], "", [ "no-password", "overwrite"])
+ except getopt.GetoptError:
+ usage()
+
+ if args:
+ usage()
+
+ print "This script will initialize your organization's Certificate Authority (CA)."
+ print "The CA database will be created in " + caroot
+
+ nopassphrase = False
+ for o, a in opts:
+ if o == "--no-password":
+ nopassphrase = True
+ if o == "--overwrite":
+ # If the CA exists then destroy it.
+ if os.path.exists(os.path.join(home, caroot)):
+ print "Warning: running this command will destroy your existing CA setup!"
+ choice = raw_input("Do you want to continue? (y/n)")
+ if choice != 'y' and choice != 'Y':
+ sys.exit(1)
+ shutil.rmtree(os.path.join(home, caroot))
+
+ #
+ # Check that the caroot isn't already populated.
+ #
+ if os.path.exists(os.path.join(cadb, "ca_key.pem")):
+ print cadb + ": CA has already been initialized."
+ print "Use the --overwrite option to re-initialize the database."
+ sys.exit(1)
+
+ try:
+ os.makedirs(cadb)
+ except OSError:
+ pass
+
+ #
+ # Initialize the CA serial and index.
+ #
+ serial = open(os.path.join(cadb, "serial"), "w" )
+ serial.write("01\n")
+ serial.close()
+
+ index = open(os.path.join(cadb, "index.txt"), "w")
+ index.close()
+
+ # Construct the DN for the CA certificate.
+ DNelements = { \
+ 'C':['countryName', "Country name", "", 'match'], \
+ 'ST':['stateOfProviceName', "State or province name", "", 'match'], \
+ 'L':['localityName', "Locality", "", 'match'], \
+ 'O':['organizationName', "Organization name", "GridCA-" + socket.gethostname(), 'match'], \
+ 'OU':['organizationUnitName', "Organization unit name", "", 'optional'], \
+ 'CN':['commonName', "Common name", "Grid CA", 'supplied'] \
+ }
+
+ while True:
+ print "The subject name for your CA will be "
+
+ first = True
+ for k,v in DNelements.iteritems():
+ if len(v[2]) > 0:
+ if not first:
+ print ", ",
+ print k + "=" + v[2],
+ first = False
+ print
+
+ input = raw_input("Do you want to keep this as the CA subject name? (y/n) [y]")
+ if input == 'n':
+ for v in DNelements.values():
+ v[2] = raw_input(v[1] + ":")
+ else:
+ break
+
+ while True:
+ DNelements['emailAddress'] = ['emailAddress', '', raw_input("Enter the email address of the CA: "), 'optional']
+ if DNelements['emailAddress'][2] and len(DNelements['emailAddress'][2]) > 0:
+ break
+
+ #
+ # Static configuration file data. This avoids locating template files
+ # and such.
+ #
+ config = {\
+"ca.cnf":"\
+# **********************************************************************\n\
+#\n\
+# Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved.\n\
+#\n\
+# This copy of Ice is licensed to you under the terms described in the\n\
+# ICE_LICENSE file included in this distribution.\n\
+#\n\
+# **********************************************************************\n\
+\n\
+# Configuration file for the CA. This file is generated by iceca init.\n\
+# DO NOT EDIT!\n\
+\n\
+###############################################################################\n\
+### Self Signed Root Certificate\n\
+###############################################################################\n\
+\n\
+[ ca ]\n\
+default_ca = ice\n\
+\n\
+[ ice ]\n\
+default_days = 1825 # How long certs are valid.\n\
+default_md = md5 # The Message Digest type.\n\
+preserve = no # Keep passed DN ordering?\n\
+\n\
+[ req ]\n\
+default_bits = 2048\n\
+default_keyfile = $ENV::ICE_CA_HOME/ca/db/ca_key.pem\n\
+default_md = md5\n\
+prompt = no\n\
+distinguished_name = dn\n\
+x509_extensions = extensions\n\
+\n\
+[ extensions ]\n\
+basicConstraints = CA:true\n\
+\n\
+# PKIX recommendation.\n\
+subjectKeyIdentifier = hash\n\
+authorityKeyIdentifier = keyid:always,issuer:always\n\
+\n\
+[dn]\n\
+",\
+"sign.cnf":"\
+# **********************************************************************\n\
+#\n\
+# Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved.\n\
+#\n\
+# This copy of Ice is licensed to you under the terms described in the\n\
+# ICE_LICENSE file included in this distribution.\n\
+#\n\
+# **********************************************************************\n\
+\n\
+# Configuration file to sign a certificate. This file is generated by iceca init.\n\
+# DO NOT EDIT!!\n\
+\n\
+[ ca ]\n\
+default_ca = ice\n\
+\n\
+[ ice ]\n\
+dir = $ENV::ICE_CA_HOME/ca/db # Where everything is kept.\n\
+private_key = $dir/ca_key.pem # The CA Private Key.\n\
+certificate = $dir/ca_cert.pem # The CA Certificate.\n\
+database = $dir/index.txt # Database index file.\n\
+new_certs_dir = $dir # Default loc for new certs.\n\
+serial = $dir/serial # The current serial number.\n\
+certs = $dir # Where issued certs are kept.\n\
+RANDFILE = $dir/.rand # Private random number file.\n\
+default_days = 1825 # How long certs are valid.\n\
+default_md = md5 # The Message Digest type.\n\
+preserve = yes # Keep passed DN ordering?\n\
+\n\
+policy = ca_policy\n\
+x509_extensions = certificate_extensions\n\
+\n\
+[ certificate_extensions ]\n\
+basicConstraints = CA:false\n\
+\n\
+# PKIX recommendation.\n\
+subjectKeyIdentifier = hash\n\
+authorityKeyIdentifier = keyid:always,issuer:always\n\
+\n\
+# ca_policy is generated by the initca script.\n\
+",\
+"req.cnf":"\
+# **********************************************************************\n\
+#\n\
+# Copyright (c) 2003-2006 ZeroC, Inc. All rights reserved.\n\
+#\n\
+# This copy of Ice is licensed to you under the terms described in the\n\
+# ICE_LICENSE file included in this distribution.\n\
+#\n\
+# **********************************************************************\n\
+\n\
+# Configuration file to request a node, registry or service\n\
+# certificate. This file is generated by iceca init.\n\
+# DO NOT EDIT!\n\
+\n\
+[ req ]\n\
+default_bits = 1024\n\
+default_md = md5\n\
+prompt = no\n\
+distinguished_name = dn\n\
+x509_extensions = extensions\n\
+\n\
+[ extensions ]\n\
+basicConstraints = CA:false\n\
+\n\
+# PKIX recommendation.\n\
+subjectKeyIdentifier = hash\n\
+authorityKeyIdentifier = keyid:always,issuer:always\n\
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment\n\
+\n\
+# The dn section is added by the initca script.\n\
+\n\
+[dn]\n\
+"\
+ }
+
+ #
+ # It is necessary to generate configuration files because the
+ # openssl configuration files do not permit empty values.
+ #
+ print "Generating configuration files... ",
+
+ print "ca.cnf",
+ temp, cacnfname = tempfile.mkstemp(".cnf", "ca")
+ os.write(temp, config["ca.cnf"])
+ for k,v in DNelements.iteritems():
+ if len(v[2]) > 0:
+ os.write(temp, v[0] + "=" + v[2] + "\n")
+ os.close(temp)
+
+ file = 'sign.cnf'
+ print " " + file,
+ cnf = open(os.path.join(caroot, file), "w")
+ cnf.write(config[file])
+ cnf.write("[ ca_policy ]\n");
+ for k,v in DNelements.iteritems():
+ if len(v[2]) > 0:
+ cnf.write(v[0] + "=" + v[3] + "\n")
+ cnf.close()
+
+ # Don't want these RDNs in req.cnf
+ del DNelements['emailAddress']
+ del DNelements['CN']
+
+ file = "req.cnf"
+ print file,
+ cnf = open(os.path.join(home, file), "w")
+ cnf.write(config[file])
+ for k,v in DNelements.iteritems():
+ if len(v[2]) > 0:
+ cnf.write(v[0] + "=" + v[2] + "\n")
+ cnf.close()
+
+ print "ok"
+
+ cmd = "openssl req -config " + cacnfname + " -x509 -days 1825 -newkey rsa:2048 -out " + \
+ os.path.join(cadb, "ca_cert.pem") + " -outform PEM"
+
+ if nopassphrase:
+ cmd += " -nodes"
+
+ #print cmd
+ status = os.system(cmd)
+ os.remove(cacnfname)
+ if status != 0:
+ print "openssl command failed"
+ sys.exit(1)
+
+ # Copy in the new ca certificate and private key.
+ shutil.copy(os.path.join(cadb, "ca_cert.pem"), os.path.join(home))
+
+ print
+ print "The CA is initialized."
+ print
+ print "You need to distribute the following files to all machines that can"
+ print "request certificates:"
+ print
+ print os.path.join(home, "req.cnf")
+ print os.path.join(home, "ca_cert.pem")
+ print
+ print "These files should be placed in the user's home directory in"
+ print "~/.iceca. On Windows, place these files in <ice-install>/config."
+
+ sys.exit(0)
+
+if sys.argv[1] == "request":
+ def usage():
+ print "usage: " + sys.argv[1] + " [--overwrite] [--node|--registry|--server|--user] [--no-password]"
+ sys.exit(1)
+
+ def setType(type):
+ keyfile = type + "_key.pem"
+ reqfile = type + "_req.pem"
+ if not overwrite:
+ if os.path.exists(keyfile):
+ print keyfile + ": exists"
+ sys.exit(1)
+ if os.path.exists(reqfile):
+ print reqfile + ": exists"
+ sys.exit(1)
+ return type, keyfile, reqfile
+
+ try:
+ opts, args = getopt.getopt(sys.argv[2:], "", \
+ [ "overwrite", "node", "registry", "server", "user", "no-password" ])
+ except getopt.GetoptError:
+ usage()
+
+ if args:
+ usage()
+
+ type = None
+ commonName = None
+ email = None
+ nopassphrase = False
+ overwrite = False
+ for o, a in opts:
+ if o == "--overwrite":
+ overwrite = True
+ if o == "--node":
+ if type != None:
+ usage()
+ type, keyfile, reqfile = setType("node")
+ while not commonName or len(commonName) == 0:
+ commonName = raw_input("Enter the node name: ")
+ commonName = "IceGrid Node " + commonName
+ elif o == "--registry":
+ if type != None:
+ usage()
+ type, keyfile, reqfile = setType("registry")
+ commonName = "IceGrid Registry"
+ elif o == "--server":
+ if type != None:
+ usage()
+ type, keyfile, reqfile = setType("server")
+ while not commonName or len(commonName) == 0:
+ commonName = raw_input("Enter the server name: ")
+ commonName = "Ice Server " + commonName
+ elif o == "--user":
+ if type != None:
+ usage()
+ type, keyfile, reqfile = setType("user")
+ while not commonName or len(commonName) == 0:
+ commonName = raw_input("Enter the user's full name: ")
+ while not email or len(email) == 0:
+ email = raw_input("Enter the user's email address: ")
+ elif o == "--no-password":
+ nopassphrase = True
+
+ if not type:
+ usage()
+
+ #
+ # Create a temporary configuration file.
+ #
+ template = open(os.path.join(home, "req.cnf"), "r")
+ if not template:
+ print "cannot open " + os.path.join(home, "req.cnf")
+ sys.exit(1)
+
+ data = template.read()
+ template.close()
+ temp, tempname = tempfile.mkstemp(".cnf", "req")
+ os.write(temp, data)
+ os.write(temp, "commonName=" + commonName + "\n")
+ if email:
+ os.write(temp, "emailAddress=" + email + "\n")
+ os.close(temp)
+
+ cmd = "openssl req -config " + tempname + " -new -keyout '" + keyfile + "' -out '" + reqfile + "'"
+ if nopassphrase:
+ cmd += " -nodes"
+
+ #print cmd
+ status = os.system(cmd)
+ os.remove(tempname)
+ if status != 0:
+ print "openssl command failed"
+ sys.exit(1)
+
+ print
+ print "Created key: " + keyfile
+ print "Created certificate request: " + reqfile
+ print
+ print "The certificate request must be signed by the CA. Send the certificate"
+ print "request file to the CA at the following email address:"
+ os.system("openssl x509 -in " + os.path.join(home, "ca_cert.pem") + " -email -noout")
+
+ sys.exit(0)
+
+if sys.argv[1] == "sign":
+ def usage():
+ print "usage: " + sys.argv[1] + " --in <req> --out <cert>"
+ sys.exit(1)
+
+ try:
+ opts, args = getopt.getopt(sys.argv[2:], "", [ "in=", "out=" ])
+ except getopt.GetoptError:
+ usage()
+
+ if args:
+ usage()
+
+ infile = None
+ outfile = None
+ for o, a in opts:
+ if o == "--in":
+ infile = a
+ elif o == "--out":
+ outfile = a
+
+ if infile == None or outfile == None:
+ usage()
+
+ cmd = "openssl ca -config " + os.path.join(caroot, "sign.cnf") + " -in " + infile + " -out " + outfile
+ status = os.system(cmd)
+ if status != 0:
+ print "openssl command failed"
+ sys.exit(1)
+
+ sys.exit(0)
+
+usage()