mirror of
https://github.com/certbot/certbot.git
synced 2026-06-08 00:02:14 -04:00
Added in filename support because configuration files still need to reference the correct place
This commit is contained in:
parent
9581c363b1
commit
d2a1c969e4
5 changed files with 50 additions and 26 deletions
|
|
@ -13,6 +13,7 @@ from Crypto import Random
|
|||
from letsencrypt.client import augeas_configurator
|
||||
from letsencrypt.client import CONFIG
|
||||
from letsencrypt.client import crypto_util
|
||||
from letsencrypt.client import errors
|
||||
from letsencrypt.client import le_util
|
||||
from letsencrypt.client import logger
|
||||
|
||||
|
|
@ -1536,7 +1537,7 @@ LogLevel warn \n\
|
|||
self.add_dir("/files" + mainConfig,
|
||||
"Include", CONFIG.APACHE_CHALLENGE_CONF)
|
||||
|
||||
def dvsni_create_chall_cert(self, name, ext, nonce, key):
|
||||
def dvsni_create_chall_cert(self, name, ext, nonce, key_file):
|
||||
"""Creates DVSNI challenge certifiate.
|
||||
|
||||
Certificate created at dvsni_get_cert_file(nonce)
|
||||
|
|
@ -1544,14 +1545,20 @@ LogLevel warn \n\
|
|||
:param nonce: hex form of nonce
|
||||
:type nonce: str
|
||||
|
||||
:param key: file path to key
|
||||
:param key_file: absolute path to key file
|
||||
:type key: str
|
||||
|
||||
"""
|
||||
try:
|
||||
with open(key_file, 'r') as key_fd:
|
||||
key_str = key_fd.read()
|
||||
except IOError:
|
||||
raise LetsEncryptDvsniError("Unable to load key file: %s" % key)
|
||||
|
||||
self.register_file_creation(True, self.dvsni_get_cert_file(nonce))
|
||||
|
||||
cert_pem = crypto_util.make_ss_cert(
|
||||
key, [nonce + CONFIG.INVALID_EXT, name, ext])
|
||||
key_str, [nonce + CONFIG.INVALID_EXT, name, ext])
|
||||
|
||||
with open(self.dvsni_get_cert_file(nonce), 'w') as f:
|
||||
f.write(cert_pem)
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class Client(object):
|
|||
"""ACME protocol client."""
|
||||
|
||||
def __init__(self, ca_server, cert_signing_request=None,
|
||||
private_key=None, use_curses=True):
|
||||
private_key=None, private_key_file=None, use_curses=True):
|
||||
"""
|
||||
|
||||
:param ca_server: Certificate authority server
|
||||
|
|
@ -45,6 +45,9 @@ class Client(object):
|
|||
:param private_key: Contents of the private key
|
||||
:type private_key: str
|
||||
|
||||
:param private_key_file: absolute path to private_key
|
||||
:type private_key_file: str
|
||||
|
||||
:param use_curses: Use curses UI
|
||||
:type use_curses: bool
|
||||
|
||||
|
|
@ -61,6 +64,7 @@ class Client(object):
|
|||
self.server = ca_server
|
||||
self.csr = cert_signing_request
|
||||
self.privkey = private_key
|
||||
self.privkey_file = private_key_file
|
||||
|
||||
# TODO: Figure out all exceptions from this function
|
||||
try:
|
||||
|
|
@ -396,7 +400,6 @@ class Client(object):
|
|||
else:
|
||||
self.choose_certs(certs)
|
||||
elif code == display.HELP:
|
||||
print code, tag, cert
|
||||
display.more_info_cert(cert)
|
||||
self.choose_certs(certs)
|
||||
else:
|
||||
|
|
@ -431,7 +434,7 @@ class Client(object):
|
|||
for host in vhost:
|
||||
self.config.deploy_cert(host,
|
||||
os.path.abspath(cert_file),
|
||||
os.path.abspath(self.privkey),
|
||||
os.path.abspath(self.privkey_file),
|
||||
cert_chain_abspath)
|
||||
# Enable any vhost that was issued to, but not enabled
|
||||
if not host.enabled:
|
||||
|
|
@ -542,17 +545,17 @@ class Client(object):
|
|||
for row in csvreader:
|
||||
idx = int(row[0]) + 1
|
||||
csvwriter = csv.writer(csvfile)
|
||||
csvwriter.writerow([str(idx), cert_file, self.privkey])
|
||||
csvwriter.writerow([str(idx), cert_file, self.privkey_file])
|
||||
|
||||
else:
|
||||
with open(list_file, 'wb') as csvfile:
|
||||
csvwriter = csv.writer(csvfile)
|
||||
csvwriter.writerow(["0", cert_file, self.privkey])
|
||||
csvwriter.writerow(["0", cert_file, self.privkey_file])
|
||||
|
||||
shutil.copy2(self.privkey,
|
||||
shutil.copy2(self.privkey_file,
|
||||
os.path.join(
|
||||
CONFIG.CERT_KEY_BACKUP,
|
||||
os.path.basename(self.privkey) + "_" + str(idx)))
|
||||
os.path.basename(self.privkey_file) + "_" + str(idx)))
|
||||
shutil.copy2(cert_file,
|
||||
os.path.join(
|
||||
CONFIG.CERT_KEY_BACKUP,
|
||||
|
|
@ -628,7 +631,7 @@ class Client(object):
|
|||
challenge_objs.append({
|
||||
"type": "dvsni",
|
||||
"listSNITuple": sni_todo,
|
||||
"dvsni_key": os.path.abspath(self.privkey),
|
||||
"dvsni_key": os.path.abspath(self.privkey_file),
|
||||
})
|
||||
challenge_obj_indices.append(sni_satisfies)
|
||||
logger.debug(sni_todo)
|
||||
|
|
@ -663,7 +666,9 @@ class Client(object):
|
|||
os.path.join(CONFIG.KEY_DIR, "key-letsencrypt.pem"), 0o600)
|
||||
key_f.write(key_pem)
|
||||
key_f.close()
|
||||
logger.info("Generating key: %s" % key_filename)
|
||||
|
||||
self.privkey_file = key_filename
|
||||
logger.info("Generating key: %s" % self.privkey_file)
|
||||
else:
|
||||
key_pem = self.privkey
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ def b64_cert_to_pem(b64_der_cert):
|
|||
le_util.jose_b64decode(b64_der_cert)).as_pem()
|
||||
|
||||
|
||||
def create_sig(msg, key_file, nonce=None, nonce_len=CONFIG.NONCE_SIZE):
|
||||
def create_sig(msg, key_str, nonce=None, nonce_len=CONFIG.NONCE_SIZE):
|
||||
"""Create signature with nonce prepended to the message.
|
||||
|
||||
TODO: Change this over to M2Crypto... PKey
|
||||
|
|
@ -32,9 +32,9 @@ def create_sig(msg, key_file, nonce=None, nonce_len=CONFIG.NONCE_SIZE):
|
|||
:param msg: Message to be signed
|
||||
:type msg: Anything with __str__ method
|
||||
|
||||
:param key_file: Path to a file containing RSA key. Accepted formats
|
||||
:param key_str: Key in string form. Accepted formats
|
||||
are the same as for `Crypto.PublicKey.RSA.importKey`.
|
||||
:type key_file: str
|
||||
:type key_str: str
|
||||
|
||||
:param nonce: Nonce to be used. If None, nonce of `nonce_len` size
|
||||
will be randomly genereted.
|
||||
|
|
@ -48,7 +48,7 @@ def create_sig(msg, key_file, nonce=None, nonce_len=CONFIG.NONCE_SIZE):
|
|||
|
||||
"""
|
||||
msg = str(msg)
|
||||
key = Crypto.PublicKey.RSA.importKey(open(key_file).read())
|
||||
key = Crypto.PublicKey.RSA.importKey(key_str)
|
||||
nonce = Random.get_random_bytes(nonce_len) if nonce is None else nonce
|
||||
|
||||
msg_with_nonce = nonce + msg
|
||||
|
|
@ -96,12 +96,12 @@ def make_key(bits=CONFIG.RSA_KEY_SIZE):
|
|||
return key.exportKey(format='PEM')
|
||||
|
||||
|
||||
def make_csr(key_file, domains):
|
||||
def make_csr(key_str, domains):
|
||||
"""
|
||||
Returns new CSR in PEM and DER form using key_file containing all domains
|
||||
"""
|
||||
assert domains, "Must provide one or more hostnames for the CSR."
|
||||
rsa_key = M2Crypto.RSA.load_key(key_file)
|
||||
rsa_key = M2Crypto.RSA.load_key_string(key_str)
|
||||
pubkey = M2Crypto.EVP.PKey()
|
||||
pubkey.assign_rsa(rsa_key)
|
||||
|
||||
|
|
@ -128,13 +128,14 @@ def make_csr(key_file, domains):
|
|||
return csr.as_pem(), csr.as_der()
|
||||
|
||||
|
||||
def make_ss_cert(key_file, domains):
|
||||
def make_ss_cert(key_str, domains):
|
||||
"""Returns new self-signed cert in PEM form.
|
||||
|
||||
Uses key_file and contains all domains.
|
||||
Uses key_str and contains all domains.
|
||||
"""
|
||||
assert domains, "Must provide one or more hostnames for the CSR."
|
||||
rsa_key = M2Crypto.RSA.load_key(key_file)
|
||||
|
||||
rsa_key = M2Crypto.RSA.load_key_string(key_str)
|
||||
pubkey = M2Crypto.EVP.PKey()
|
||||
pubkey.assign_rsa(rsa_key)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,3 +3,7 @@
|
|||
|
||||
class LetsEncryptClientError(Exception):
|
||||
"""Generic Let's Encrypt client error."""
|
||||
|
||||
|
||||
class LetsEncryptDvsniError(Exception):
|
||||
"""Let's Encrypt DVSNI error."""
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ def main():
|
|||
nargs="+")
|
||||
parser.add_argument("-s", "--server", dest="server",
|
||||
help="The ACME CA server address.")
|
||||
parser.add_argument("-p", "--privkey", dest="privkey", type=read_file,
|
||||
parser.add_argument("-p", "--privkey", dest="privkey_tup", type=read_file,
|
||||
help="Path to the private key file for certificate "
|
||||
"generation.")
|
||||
parser.add_argument("-c", "--csr", dest="csr", type=read_file,
|
||||
parser.add_argument("-c", "--csr", dest="csr_tup", type=read_file,
|
||||
help="Path to the certificate signing request file "
|
||||
"corresponding to the private key file. The "
|
||||
"private key file argument is required if this "
|
||||
|
|
@ -63,7 +63,7 @@ def main():
|
|||
args = parser.parse_args()
|
||||
|
||||
# Enforce '--privkey' is set along with '--csr'.
|
||||
if args.csr and not args.privkey:
|
||||
if args.csr_tup and not args.privkey_tup:
|
||||
parser.error("private key file (--privkey) must be specified along{0} "
|
||||
"with the certificate signing request file (--csr)"
|
||||
.format(os.linesep))
|
||||
|
|
@ -83,7 +83,14 @@ def main():
|
|||
|
||||
server = args.server is None and CONFIG.ACME_SERVER or args.server
|
||||
|
||||
acme = client.Client(server, args.csr, args.privkey, args.curses)
|
||||
# Prepare for init of Client
|
||||
if args.privkey_tup is None:
|
||||
args.privkey_tup = (None, None)
|
||||
if args.csr_tup is None:
|
||||
args.csr_tup = (None, None)
|
||||
|
||||
acme = client.Client(server, args.csr_tup[1], args.privkey_tup[1],
|
||||
args.privkey_tup[0], args.curses)
|
||||
if args.revoke:
|
||||
acme.list_certs_keys()
|
||||
else:
|
||||
|
|
@ -103,7 +110,7 @@ def read_file(filename):
|
|||
|
||||
"""
|
||||
try:
|
||||
return file(filename, 'rU').read()
|
||||
return filename, file(filename, 'rU').read()
|
||||
except IOError as exc:
|
||||
raise argparse.ArgumentTypeError(exc.strerror)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue