示例#1
0
def wildcard_revoke(cert_pem,account):

		#Check if registrar exists
		if account not in os.listdir(REG_DIRECTORY):
			print "This account does not exists, register it first with new_account.py"
			sys.exit(1)

		#Load files from disk
		with open(REG_DIRECTORY + "/" + account + "/private.key", "rb") as key_file:
			privkey = serialization.load_pem_private_key(
				key_file.read(),
				password=None,
				backend=default_backend()
			)
		with open(REG_DIRECTORY + "/" + account + "/reguri.txt", "r") as reguri_file:
			reg_uri = reguri_file.read()

		#Compose registration resource (regr)
		key = jose.JWKRSA(key=privkey)
		regr = messages.RegistrationResource(
			body=messages.Registration(
				key=key.public_key()),
			uri = reg_uri)

		#Init ACME
		net = ClientNetwork(key)
		directory = net.get(DIRECTORY_URL).json()

		acme = client.ClientV2(directory, net)


		#Check if registration is valid
		if acme.query_registration(regr).body.status == u'valid':
			print "Registration valid"
		else:
			print "Registration invalid"
			sys.exit(1)

		#Deserialize key from variable
		cert = jose.ComparableX509(OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert_pem))

		#Try to revoke cert, return false on error or revoked-already state
		try:
			revokation = acme.revoke(cert,1)
		except messages.Error,acme_exc:
			if str(acme_exc) == str("urn:ietf:params:acme:error:alreadyRevoked :: Certificate already revoked"):
				return ["Certificate already revoked",False]
			else:
				return [acme_exc, False]
示例#2
0
def create_registration():
    global privkey, regr
    privkey = rsa.generate_private_key(public_exponent=65537,
                                       key_size=BITS,
                                       backend=default_backend())
    key = jose.JWKRSA(key=privkey)
    net = ClientNetwork(key)
    directory = net.get(DIRECTORY_URL).json()
    acme = client.ClientV2(directory, net)
    regbody = dict(
        messages.Registration(contact=('mailto:[email protected]', ),
                              terms_of_service_agreed=True,
                              key=key.public_key()))
    #NEED TO SAVE REGBODY VARIABLE TO FILE
    regr = acme.new_account(messages.NewRegistration(**regbody))
示例#3
0
class ClientNetworkWithMockedResponseTest(unittest.TestCase):
    """Tests for acme.client.ClientNetwork which mock out response."""

    # pylint: disable=too-many-instance-attributes

    def setUp(self):
        from acme.client import ClientNetwork
        self.net = ClientNetwork(key=None, alg=None)

        self.response = mock.MagicMock(ok=True, status_code=http_client.OK)
        self.response.headers = {}
        self.response.links = {}
        self.checked_response = mock.MagicMock()
        self.obj = mock.MagicMock()
        self.wrapped_obj = mock.MagicMock()
        self.content_type = mock.sentinel.content_type

        self.all_nonces = [
            jose.b64encode(b'Nonce'),
            jose.b64encode(b'Nonce2'),
            jose.b64encode(b'Nonce3')
        ]
        self.available_nonces = self.all_nonces[:]

        def send_request(*args, **kwargs):
            # pylint: disable=unused-argument,missing-docstring
            if self.available_nonces:
                self.response.headers = {
                    self.net.REPLAY_NONCE_HEADER:
                    self.available_nonces.pop().decode()
                }
            else:
                self.response.headers = {}
            return self.response

        # pylint: disable=protected-access
        self.net._send_request = self.send_request = mock.MagicMock(
            side_effect=send_request)
        self.net._check_response = self.check_response
        self.net._wrap_in_jws = mock.MagicMock(return_value=self.wrapped_obj)

    def check_response(self, response, content_type):
        # pylint: disable=missing-docstring
        self.assertEqual(self.response, response)
        self.assertEqual(self.content_type, content_type)
        return self.checked_response

    def test_head(self):
        self.assertEqual(
            self.response,
            self.net.head('http://example.com/', 'foo', bar='baz'))
        self.send_request.assert_called_once_with('HEAD',
                                                  'http://example.com/',
                                                  'foo',
                                                  bar='baz')

    def test_get(self):
        self.assertEqual(
            self.checked_response,
            self.net.get('http://example.com/',
                         content_type=self.content_type,
                         bar='baz'))
        self.send_request.assert_called_once_with('GET',
                                                  'http://example.com/',
                                                  bar='baz')

    def test_post_no_content_type(self):
        self.content_type = self.net.JOSE_CONTENT_TYPE
        self.assertEqual(self.checked_response, self.net.post('uri', self.obj))

    def test_post(self):
        # pylint: disable=protected-access
        self.assertEqual(
            self.checked_response,
            self.net.post('uri', self.obj, content_type=self.content_type))
        self.net._wrap_in_jws.assert_called_once_with(
            self.obj, jose.b64decode(self.all_nonces.pop()))

        self.available_nonces = []
        self.assertRaises(errors.MissingNonce,
                          self.net.post,
                          'uri',
                          self.obj,
                          content_type=self.content_type)
        self.net._wrap_in_jws.assert_called_with(
            self.obj, jose.b64decode(self.all_nonces.pop()))

    def test_post_wrong_initial_nonce(self):  # HEAD
        self.available_nonces = [b'f', jose.b64encode(b'good')]
        self.assertRaises(errors.BadNonce,
                          self.net.post,
                          'uri',
                          self.obj,
                          content_type=self.content_type)

    def test_post_wrong_post_response_nonce(self):
        self.available_nonces = [jose.b64encode(b'good'), b'f']
        self.assertRaises(errors.BadNonce,
                          self.net.post,
                          'uri',
                          self.obj,
                          content_type=self.content_type)

    def test_post_failed_retry(self):
        check_response = mock.MagicMock()
        check_response.side_effect = messages.Error.with_code('badNonce')

        # pylint: disable=protected-access
        self.net._check_response = check_response
        self.assertRaises(messages.Error,
                          self.net.post,
                          'uri',
                          self.obj,
                          content_type=self.content_type)

    def test_post_not_retried(self):
        check_response = mock.MagicMock()
        check_response.side_effect = [
            messages.Error.with_code('malformed'), self.checked_response
        ]

        # pylint: disable=protected-access
        self.net._check_response = check_response
        self.assertRaises(messages.Error,
                          self.net.post,
                          'uri',
                          self.obj,
                          content_type=self.content_type)

    def test_post_successful_retry(self):
        check_response = mock.MagicMock()
        check_response.side_effect = [
            messages.Error.with_code('badNonce'), self.checked_response
        ]

        # pylint: disable=protected-access
        self.net._check_response = check_response
        self.assertEqual(
            self.checked_response,
            self.net.post('uri', self.obj, content_type=self.content_type))

    def test_head_get_post_error_passthrough(self):
        self.send_request.side_effect = requests.exceptions.RequestException
        for method in self.net.head, self.net.get:
            self.assertRaises(requests.exceptions.RequestException, method,
                              'GET', 'uri')
        self.assertRaises(requests.exceptions.RequestException,
                          self.net.post,
                          'uri',
                          obj=self.obj)
示例#4
0
class ClientNetworkWithMockedResponseTest(unittest.TestCase):
    """Tests for acme.client.ClientNetwork which mock out response."""
    # pylint: disable=too-many-instance-attributes

    def setUp(self):
        from acme.client import ClientNetwork
        self.net = ClientNetwork(key=None, alg=None)

        self.response = mock.MagicMock(ok=True, status_code=http_client.OK)
        self.response.headers = {}
        self.response.links = {}
        self.checked_response = mock.MagicMock()
        self.obj = mock.MagicMock()
        self.wrapped_obj = mock.MagicMock()
        self.content_type = mock.sentinel.content_type

        self.all_nonces = [jose.b64encode(b'Nonce'), jose.b64encode(b'Nonce2')]
        self.available_nonces = self.all_nonces[:]

        def send_request(*args, **kwargs):
            # pylint: disable=unused-argument,missing-docstring
            if self.available_nonces:
                self.response.headers = {
                    self.net.REPLAY_NONCE_HEADER:
                    self.available_nonces.pop().decode()}
            else:
                self.response.headers = {}
            return self.response

        # pylint: disable=protected-access
        self.net._send_request = self.send_request = mock.MagicMock(
            side_effect=send_request)
        self.net._check_response = self.check_response
        self.net._wrap_in_jws = mock.MagicMock(return_value=self.wrapped_obj)

    def check_response(self, response, content_type):
        # pylint: disable=missing-docstring
        self.assertEqual(self.response, response)
        self.assertEqual(self.content_type, content_type)
        return self.checked_response

    def test_head(self):
        self.assertEqual(self.response, self.net.head('url', 'foo', bar='baz'))
        self.send_request.assert_called_once_with(
            'HEAD', 'url', 'foo', bar='baz')

    def test_get(self):
        self.assertEqual(self.checked_response, self.net.get(
            'url', content_type=self.content_type, bar='baz'))
        self.send_request.assert_called_once_with('GET', 'url', bar='baz')

    def test_post(self):
        # pylint: disable=protected-access
        self.assertEqual(self.checked_response, self.net.post(
            'uri', self.obj, content_type=self.content_type))
        self.net._wrap_in_jws.assert_called_once_with(
            self.obj, jose.b64decode(self.all_nonces.pop()))

        assert not self.available_nonces
        self.assertRaises(errors.MissingNonce, self.net.post,
                          'uri', self.obj, content_type=self.content_type)
        self.net._wrap_in_jws.assert_called_with(
            self.obj, jose.b64decode(self.all_nonces.pop()))

    def test_post_wrong_initial_nonce(self):  # HEAD
        self.available_nonces = [b'f', jose.b64encode(b'good')]
        self.assertRaises(errors.BadNonce, self.net.post, 'uri',
                          self.obj, content_type=self.content_type)

    def test_post_wrong_post_response_nonce(self):
        self.available_nonces = [jose.b64encode(b'good'), b'f']
        self.assertRaises(errors.BadNonce, self.net.post, 'uri',
                          self.obj, content_type=self.content_type)

    def test_head_get_post_error_passthrough(self):
        self.send_request.side_effect = requests.exceptions.RequestException
        for method in self.net.head, self.net.get:
            self.assertRaises(
                requests.exceptions.RequestException, method, 'GET', 'uri')
        self.assertRaises(requests.exceptions.RequestException,
                          self.net.post, 'uri', obj=self.obj)
示例#5
0
def wildcard_request(cn, account):
    def dns_check_ns1():
        recieved_data_dup = []
        recieved_data = []

        ns1_resolver = dns.resolver.Resolver()
        #ns1_resolver.nameservers = ['130.193.8.82','2a03:b780::1:1']
        ns1_resolver.nameservers = ['173.245.58.51']

        for data in validation_data:
            domainname = data[1]
            #challenge = data[0]
            answers = ns1_resolver.query(domainname, 'txt')
            for rdata in answers:
                recieved_data_dup.append(
                    [str(rdata).replace('"', ''), domainname])

        #Deduplication of ns records (in case of more cnames)
        for i in recieved_data_dup:
            if i not in recieved_data:
                recieved_data.append(i)

        # print sorted(recieved_data)
        # print sorted(validation_data)
        if sorted(validation_data) == sorted(recieved_data):
            return True
        else:
            return False

    #Check if CN is valid domain
    domain_regex = re.compile(
        "^([a-zA-Z0-9]([\-a-zA-Z0-9]{0,61}[a-zA-Z0-9])?\.)*([a-zA-Z0-9]([\-a-zA-Z0-9]{0,61}[a-zA-Z0-9])+\.)([a-zA-Z0-9]+([\-a-zA-Z0-9]{0,61}[a-zA-Z])+)$"
    )
    if not domain_regex.match(cn):
        print 'First argument is not valid CN'
        sys.exit(1)

    #Check if registrar exists
    if account not in os.listdir(REG_DIRECTORY):
        print "This account does not exists, register it first with new_account.py"
        sys.exit(1)

    #Load files from disk
    with open(REG_DIRECTORY + "/" + account + "/private.key",
              "rb") as key_file:
        privkey = serialization.load_pem_private_key(key_file.read(),
                                                     password=None,
                                                     backend=default_backend())
    with open(REG_DIRECTORY + "/" + account + "/reguri.txt",
              "r") as reguri_file:
        reg_uri = reguri_file.read()

    #Compose regr
    key = jose.JWKRSA(key=privkey)
    regr = messages.RegistrationResource(
        body=messages.Registration(key=key.public_key()), uri=reg_uri)

    #Init ACME
    net = ClientNetwork(key)
    directory = net.get(DIRECTORY_URL).json()

    acme = client.ClientV2(directory, net)

    #Check if registration is valid
    if acme.query_registration(regr).body.status == u'valid':
        print "Registration valid"
    else:
        print "Registration invalid"
        sys.exit(1)

    #Generate private key for certificate
    pkey = OpenSSL.crypto.PKey()
    pkey.generate_key(OpenSSL.crypto.TYPE_RSA, BITS)

    #Serialize key for output
    pkey_printable = OpenSSL.crypto.dump_privatekey(
        OpenSSL.crypto.FILETYPE_PEM, pkey, cipher=None, passphrase=None)

    #Compose request for acme
    req = crypto_util.make_csr(
        OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, pkey),
        [cn, '*.' + cn])

    #begin order
    orderr = acme.new_order(req)

    validation_data = []

    for authr in orderr.authorizations:
        for chalr in authr.body.challenges:
            if type(chalr.chall) == type(challenges.DNS01()):
                validation_data.append([
                    str(chalr.chall.validation(key)),
                    chalr.chall.validation_domain_name(cn)
                ])
    #print validation_data
    #Now, call DNS writing function to apply challenges
    dns_apply(cn, validation_data)

    #Check if DNS is valid on our server
    sys.stdin.readline()  #DEBUG: wait for manual DNS input
    limiter = 2
    while not dns_check_ns1():
        if limiter != 0:
            print "DNS records are not correct, trying again in few seconds"
            limiter = limiter - 1
            time.sleep(5)
        else:
            print "DNS are not correct even after several tries. Aborting"
            sys.exit(1)

    for authr in orderr.authorizations:
        for chalr in authr.body.challenges:
            if type(chalr.chall) == type(challenges.DNS01()):
                try:
                    acme.answer_challenge(chalr, challenges.DNS01Response())
                except:
                    print chalr.chall.encode(
                        'token'
                    ) + " already answered (challenge failed, you have to generate new one)"

    #After filling DNS and waiting for propagation, finalize order
    try:
        res = acme.poll_and_finalize(orderr)
    finally:
        dns_remove(cn)
    #logging.info(res)

    cert = x509.load_pem_x509_certificate(str(res.fullchain_pem),
                                          default_backend())

    output_data = {
        'wildcard': {
            'cn': cn,
            'private_key': str(pkey_printable),
            'certificate': str(res.fullchain_pem),
            'expiration': cert.not_valid_after.strftime(
                "%x %X"
            )  #Locale-specific time+date representation. Edit to your need
        }
    }

    print json.dumps(output_data)
示例#6
0
 def build_sync(cls, directory_url, account_key, **kw):
     net = ClientNetwork(account_key, user_agent=USER_AGENT, **kw)
     directory = Directory.from_json(net.get(directory_url).json())
     return cls(_ClientV2PlusPlus(directory, net=net))