diff --git a/lib/bootstrap.py b/lib/bootstrap.py
index a162897e493c9809e44d707d43c1867152accc58..1d462a39b22365573518d4605c7a0d2e5a8d0e09 100644
--- a/lib/bootstrap.py
+++ b/lib/bootstrap.py
@@ -27,7 +27,6 @@ import os
 import os.path
 import re
 import logging
-import tempfile
 import time
 
 from ganeti import rpc
@@ -66,40 +65,6 @@ def _InitSSHSetup():
   utils.AddAuthorizedKey(auth_keys, utils.ReadFile(pub_key))
 
 
-def GenerateSelfSignedSslCert(file_name, validity=(365 * 5)):
-  """Generates a self-signed SSL certificate.
-
-  @type file_name: str
-  @param file_name: Path to output file
-  @type validity: int
-  @param validity: Validity for certificate in days
-
-  """
-  (fd, tmp_file_name) = tempfile.mkstemp(dir=os.path.dirname(file_name))
-  try:
-    try:
-      # Set permissions before writing key
-      os.chmod(tmp_file_name, 0600)
-
-      result = utils.RunCmd(["openssl", "req", "-new", "-newkey", "rsa:1024",
-                             "-days", str(validity), "-nodes", "-x509",
-                             "-keyout", tmp_file_name, "-out", tmp_file_name,
-                             "-batch"])
-      if result.failed:
-        raise errors.OpExecError("Could not generate SSL certificate, command"
-                                 " %s had exitcode %s and error message %s" %
-                                 (result.cmd, result.exit_code, result.output))
-
-      # Make read-only
-      os.chmod(tmp_file_name, 0400)
-
-      os.rename(tmp_file_name, file_name)
-    finally:
-      utils.RemoveFile(tmp_file_name)
-  finally:
-    os.close(fd)
-
-
 def GenerateHmacKey(file_name):
   """Writes a new HMAC key.
 
@@ -117,11 +82,11 @@ def _InitGanetiServerSetup(master_name):
   the cluster and also generates the SSL certificate.
 
   """
-  GenerateSelfSignedSslCert(constants.SSL_CERT_FILE)
+  utils.GenerateSelfSignedSslCert(constants.SSL_CERT_FILE)
 
   # Don't overwrite existing file
   if not os.path.exists(constants.RAPI_CERT_FILE):
-    GenerateSelfSignedSslCert(constants.RAPI_CERT_FILE)
+    utils.GenerateSelfSignedSslCert(constants.RAPI_CERT_FILE)
 
   if not os.path.exists(constants.HMAC_CLUSTER_KEY):
     GenerateHmacKey(constants.HMAC_CLUSTER_KEY)
diff --git a/lib/utils.py b/lib/utils.py
index 438a1203578ac8aaf4b4f9a43766dbebb4f91baf..1a4011ee1a67d2344e8c730efff385d06bb75121 100644
--- a/lib/utils.py
+++ b/lib/utils.py
@@ -2258,6 +2258,40 @@ def Retry(fn, delay, timeout, args=None, wait_fn=time.sleep,
         wait_fn(current_delay)
 
 
+def GenerateSelfSignedSslCert(file_name, validity=(365 * 5)):
+  """Generates a self-signed SSL certificate.
+
+  @type file_name: str
+  @param file_name: Path to output file
+  @type validity: int
+  @param validity: Validity for certificate in days
+
+  """
+  (fd, tmp_file_name) = tempfile.mkstemp(dir=os.path.dirname(file_name))
+  try:
+    try:
+      # Set permissions before writing key
+      os.chmod(tmp_file_name, 0600)
+
+      result = RunCmd(["openssl", "req", "-new", "-newkey", "rsa:1024",
+                       "-days", str(validity), "-nodes", "-x509",
+                       "-keyout", tmp_file_name, "-out", tmp_file_name,
+                       "-batch"])
+      if result.failed:
+        raise errors.OpExecError("Could not generate SSL certificate, command"
+                                 " %s had exitcode %s and error message %s" %
+                                 (result.cmd, result.exit_code, result.output))
+
+      # Make read-only
+      os.chmod(tmp_file_name, 0400)
+
+      os.rename(tmp_file_name, file_name)
+    finally:
+      RemoveFile(tmp_file_name)
+  finally:
+    os.close(fd)
+
+
 class FileLock(object):
   """Utility class for file locks.
 
diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py
index f0763550d12f16031d0f1715933509107d35e0f9..15ff1362e17672d5f582b6f035e6d9a80101d874 100755
--- a/test/ganeti.utils_unittest.py
+++ b/test/ganeti.utils_unittest.py
@@ -1085,5 +1085,33 @@ class TestUnescapeAndSplit(unittest.TestCase):
       self.failUnlessEqual(UnescapeAndSplit(sep.join(a), sep=sep), b)
 
 
+class TestGenerateSelfSignedSslCert(unittest.TestCase):
+  def setUp(self):
+    self.tmpdir = tempfile.mkdtemp()
+
+  def tearDown(self):
+    shutil.rmtree(self.tmpdir)
+
+  def _checkPrivateRsaKey(self, key):
+    lines = key.splitlines()
+    self.assert_("-----BEGIN RSA PRIVATE KEY-----" in lines)
+    self.assert_("-----END RSA PRIVATE KEY-----" in lines)
+
+  def _checkRsaCertificate(self, cert):
+    lines = cert.splitlines()
+    self.assert_("-----BEGIN CERTIFICATE-----" in lines)
+    self.assert_("-----END CERTIFICATE-----" in lines)
+
+  def testSingleFile(self):
+    cert1_filename = os.path.join(self.tmpdir, "cert1.pem")
+
+    utils.GenerateSelfSignedSslCert(cert1_filename, validity=1)
+
+    cert1 = utils.ReadFile(cert1_filename)
+
+    self._checkPrivateRsaKey(cert1)
+    self._checkRsaCertificate(cert1)
+
+
 if __name__ == '__main__':
   testutils.GanetiTestProgram()
diff --git a/tools/cfgupgrade b/tools/cfgupgrade
index e7be5911ebc8f0df3fcadf15fc8cde437485c785..38e577c8d045f747d54217125dc51ba24c34ea73 100755
--- a/tools/cfgupgrade
+++ b/tools/cfgupgrade
@@ -176,7 +176,7 @@ def main():
     if not options.dry_run:
       if not os.path.exists(options.RAPI_CERT_FILE):
         logging.debug("Writing RAPI certificate to %s", options.RAPI_CERT_FILE)
-        bootstrap.GenerateSelfSignedSslCert(options.RAPI_CERT_FILE)
+        utils.GenerateSelfSignedSslCert(options.RAPI_CERT_FILE)
 
       if not os.path.exists(options.HMAC_CLUSTER_KEY):
         logging.debug("Writing HMAC key to %s", options.HMAC_CLUSTER_KEY)