From 7af9263e4adeec82d8a588a60f093e9a008ad54a Mon Sep 17 00:00:00 2001 From: James Kasten Date: Wed, 19 Nov 2014 15:34:54 -0800 Subject: [PATCH] Remove jose dependency, convert display code to use dialog from setup --- letsencrypt/client/client.py | 17 +++++------------ letsencrypt/client/crypto_util.py | 15 +++++++-------- letsencrypt/client/display.py | 14 ++++++++------ letsencrypt/client/le_util.py | 23 ++++++++++++++++++++++- letsencrypt/client/sni_challenge.py | 11 +++++------ requirements.txt | 1 - setup.py | 1 - 7 files changed, 47 insertions(+), 35 deletions(-) diff --git a/letsencrypt/client/client.py b/letsencrypt/client/client.py index c608d96fa..95e4d9e87 100755 --- a/letsencrypt/client/client.py +++ b/letsencrypt/client/client.py @@ -4,14 +4,7 @@ import M2Crypto import json import os, time, sys, shutil -# This line suppresses the no logging found for module 'jose' warning -# TODO: Check out this module and see if we should be using it for our -# logging features -import logging -logging.basicConfig(filename="/dev/null", level=logging.ERROR) - - -import jose, csv +import csv import requests @@ -118,7 +111,7 @@ class Client(object): # Perform optimal config changes self.optimize_config(vhost) - self.config.save("Completed Augeas Authentication") + self.config.save("Completed Let's Encrypt Authentication") self.store_cert_key(False) @@ -250,7 +243,7 @@ class Client(object): def revocation_request(self, key_file, cert_der): return {"type":"revocationRequest", - "certificate":jose.b64encode_url(cert_der), + "certificate":le_util.b64_url_enc(cert_der), "signature":crypto_util.create_sig(cert_der, key_file)} @@ -313,7 +306,7 @@ class Client(object): def certificate_request(self, csr_der, key): logger.info("Preparing and sending CSR..") return {"type":"certificateRequest", - "csr":jose.b64encode_url(csr_der), + "csr":le_util.b64_url_enc(csr_der), "signature":crypto_util.create_sig(csr_der, self.key_file)} def cleanup_challenges(self, challenge_objs): @@ -354,7 +347,7 @@ class Client(object): "nonce":server_nonce} auth_req["signature"] = crypto_util.create_sig( - name + jose.b64decode_url(server_nonce), self.key_file) + name + le_util.b64_url_dec(server_nonce), self.key_file) auth_req["responses"] = responses return auth_req diff --git a/letsencrypt/client/crypto_util.py b/letsencrypt/client/crypto_util.py index 6924fbe0c..3ad7ff6a3 100644 --- a/letsencrypt/client/crypto_util.py +++ b/letsencrypt/client/crypto_util.py @@ -1,5 +1,5 @@ import M2Crypto -import time, jose, binascii +import time, binascii import hashlib from Crypto.Random import get_random_bytes from Crypto.PublicKey import RSA @@ -7,12 +7,11 @@ from Crypto.Signature import PKCS1_v1_5 from Crypto.Hash import SHA256 from M2Crypto import EVP, X509, ASN1 - from letsencrypt.client.CONFIG import NONCE_SIZE, RSA_KEY_SIZE - +from letsencrypt.client import le_util def b64_cert_to_pem(b64_der_cert): - x = M2Crypto.X509.load_cert_der_string(jose.b64decode_url(b64_der_cert)) + x = M2Crypto.X509.load_cert_der_string(le_util.b64_url_dec(b64_der_cert)) return x.as_pem() def create_sig(msg, key_file, signer_nonce = None, signer_nonce_len = NONCE_SIZE): @@ -31,10 +30,10 @@ def create_sig(msg, key_file, signer_nonce = None, signer_nonce_len = NONCE_SIZE n, e = key.n, key.e n_bytes = binascii.unhexlify(leading_zeros(hex(n)[2:].replace("L", ""))) e_bytes = binascii.unhexlify(leading_zeros(hex(e)[2:].replace("L", ""))) - n_encoded = jose.b64encode_url(n_bytes) - e_encoded = jose.b64encode_url(e_bytes) - signer_nonce_encoded = jose.b64encode_url(signer_nonce) - sig_encoded = jose.b64encode_url(signature) + n_encoded = le_util.b64_url_enc(n_bytes) + e_encoded = le_util.b64_url_enc(e_bytes) + signer_nonce_encoded = le_util.b64_url_enc(signer_nonce) + sig_encoded = le_util.b64_url_enc(signature) jwk = { "kty": "RSA", "n": n_encoded, "e": e_encoded } signature = { "nonce": signer_nonce_encoded, "alg": "RS256", "jwk": jwk, "sig": sig_encoded } # return json.dumps(signature) diff --git a/letsencrypt/client/display.py b/letsencrypt/client/display.py index 6c137e667..7099f4473 100644 --- a/letsencrypt/client/display.py +++ b/letsencrypt/client/display.py @@ -80,11 +80,13 @@ class NcursesDisplay(Display): def generic_notification(self, message, w = WIDTH, h = HEIGHT): self.d.msgbox(message, width = w, height = h) - def generic_menu(self, message, choices, input_text = "", width = WIDTH, height = HEIGHT): + def generic_menu(self, message, choices, input_text = "", width = WIDTH, + height = HEIGHT): # Can accept either tuples or just the actual choices if choices and isinstance(choices[0], tuple): - return self.d.menu(message, choices = choices, + c, selection = self.d.menu(message, choices = choices, width = WIDTH, height = HEIGHT) + return c, str(selection) else: choices = [((i + 1), c) for c in choices] code, s = self.d.menu(message, choices = choices, @@ -102,10 +104,10 @@ class NcursesDisplay(Display): def filter_names(self, names): choices = [(n, "", 0) for n in names] - c, s = self.d.checklist("Which names would you like to activate \ + c, names = self.d.checklist("Which names would you like to activate \ HTTPS for?", choices=choices) - return c, s + return c, [str(s) for s in names] def success_installation(self, domains): @@ -259,8 +261,8 @@ class FileDisplay(Display): self.outfile.write(self.cert_info_frame(cert)) display = None -OK = 0 -CANCEL = 1 +OK = "ok" +CANCEL = "cancel" HELP = "help" diff --git a/letsencrypt/client/le_util.py b/letsencrypt/client/le_util.py index 252ea739b..fbe7fb53e 100644 --- a/letsencrypt/client/le_util.py +++ b/letsencrypt/client/le_util.py @@ -2,8 +2,8 @@ import errno import stat import os, pwd, grp -import M2Crypto import time +import base64 from letsencrypt.client import logger #import logger @@ -49,3 +49,24 @@ def drop_privs(): os.setgid(nogroup) os.setgroups([]) os.setuid(nobody) + +# Quick implementations of b64 url safe encode/decode +# We will include a proper library in the future if the library +# doesn't conflict with our existing dependencies +def b64_url_enc(s): + try: + s = s.encode("utf8") + except: + pass + + i = base64.urlsafe_b64encode(s) + return i.rstrip("=") + +def b64_url_dec(s): + try: + s = s.encode("utf8") + except: + pass + + pad = '=' * (4 - (len(s) % 4)) + return base64.urlsafe_b64decode(s + pad) diff --git a/letsencrypt/client/sni_challenge.py b/letsencrypt/client/sni_challenge.py index 6947cef75..de0746fa9 100755 --- a/letsencrypt/client/sni_challenge.py +++ b/letsencrypt/client/sni_challenge.py @@ -6,14 +6,13 @@ import hashlib from os import path import sys import binascii -import jose from letsencrypt.client import configurator from letsencrypt.client.CONFIG import CONFIG_DIR, WORK_DIR, SERVER_ROOT from letsencrypt.client.CONFIG import OPTIONS_SSL_CONF, APACHE_CHALLENGE_CONF, INVALID_EXT from letsencrypt.client.CONFIG import S_SIZE -from letsencrypt.client import logger, crypto_util +from letsencrypt.client import logger, crypto_util, le_util from letsencrypt.client.challenge import Challenge # import configurator @@ -251,7 +250,7 @@ DocumentRoot " + CONFIG_DIR + "challenge_page/ \n \ # Create all of the challenge certs for tup in self.listSNITuple: # Need to decode from base64 - r = jose.b64decode_url(tup[1]) + r = le_util.b64_url_dec(tup[1]) ext = self.generateExtension(r, s) self.createChallengeCert(tup[0], ext, tup[2], self.key) @@ -260,7 +259,7 @@ DocumentRoot " + CONFIG_DIR + "challenge_page/ \n \ self.configurator.save("SNI Challenge", True) self.configurator.restart(quiet) - self.s = jose.b64encode_url(s) + self.s = le_util.b64_url_enc(s) return self.s # This main function is just used for testing @@ -279,8 +278,8 @@ def main(): r2 = "testValueForR2" nonce2 = "nonce2" - r = jose.b64encode_url(r) - r2 = jose.b64encode_url(r2) + r = le_util.b64_url_enc(r) + r2 = le_util.b64_url_enc(r2) #ans = dns.resolver.query("google.com") #print ans.rrset diff --git a/requirements.txt b/requirements.txt index f38fbe085..d362c124d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ M2Crypto==0.22.3 python2-pythondialog -jose==0.1 jsonschema==2.4.0 #python-augeas==0.5.0 requests==2.4.3 diff --git a/setup.py b/setup.py index 4b1388cc8..3966bdccf 100755 --- a/setup.py +++ b/setup.py @@ -17,7 +17,6 @@ setup( install_requires=[ #'dialog', 'requests', - 'jose', 'jsonschema', 'M2Crypto', 'pycrypto',